.screen--centered {
  align-items: center;
  justify-content: center;
}

.auth-box {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

/* Round accent badge with a ship inside — the app's mark, shown once at the
   top of every pre-login screen (splash, login, register, verify) instead of
   scattering ship art around the page background. */
.app-emblem {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  margin: 0 auto 2px;
  background: radial-gradient(circle at 35% 30%, #a8ffa0, var(--color-accent) 60%, var(--color-accent-dim) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px rgba(124, 255, 107, 0.25);
  position: relative;
}

.app-emblem::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1.5px solid rgba(124, 255, 107, 0.3);
}

.app-emblem img {
  width: 46px;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.3));
}

/* Same mark, small and unmargined, for the header row of a real content
   screen (menu) rather than centered above a login-style form. */
.app-emblem--small {
  width: 40px;
  height: 40px;
  margin: 0;
}

.app-emblem--small img {
  width: 22px;
}

.auth-box h1 {
  font-size: 26px;
  text-align: center;
  margin-bottom: 4px;
}

.auth-box .subtitle {
  text-align: center;
  color: var(--color-text-dim);
  font-size: 14px;
  margin-bottom: 8px;
}

.auth-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.auth-switch {
  text-align: center;
  margin-top: 4px;
}

.profile-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  line-height: 1.3;
  background: none;
  border: none;
  padding: 0;
  text-align: left;
}

.profile-name {
  color: var(--color-text);
  font-size: 14px;
  font-weight: 600;
}

.profile-age {
  color: var(--color-text-dim);
  font-size: 12px;
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: max(12px, env(safe-area-inset-top)) 16px 12px;
  background: var(--color-bg-deep);
  border-bottom: 1px solid var(--color-panel-border);
}

/* Icon buttons directly in the header on a screen wide enough to fit them;
   below the breakpoint they fold into the existing "☰" dropdown instead
   of getting cramped or wrapping onto a second line. */
.header-actions-wide {
  display: flex;
  gap: 8px;
}

.header-icon-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 8px 14px;
  background: transparent;
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
}

.header-icon-btn-emoji {
  font-size: 16px;
  line-height: 1;
}

.header-icon-btn:active {
  background: var(--color-panel);
}

.header-menu {
  position: relative;
  display: none;
}

@media (max-width: 760px) {
  .header-actions-wide {
    display: none;
  }

  .header-menu {
    display: block;
  }
}

.header-menu-toggle {
  width: 40px;
  min-height: 40px;
  font-size: 18px;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}

.header-menu-toggle:active {
  background: var(--color-panel);
}

.header-menu-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  /* Wide enough that the Armenian labels ("Իմ առաջադիմությունը", "Խաղացողների
     վարկանիշ" — routinely longer than their Russian originals) sit on one
     line instead of wrapping and looking cramped. */
  width: 280px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 70px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  background: var(--color-panel);
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 6;
}

.header-menu-item {
  min-height: var(--tap-min);
  padding: 0 16px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-panel-border);
  color: var(--color-text);
  text-align: left;
}

.header-menu-item:last-child {
  border-bottom: none;
}

.header-menu-item:active {
  background: var(--color-bg);
}

/* Named grid areas (not DOM order) decide where Tips sits — on a narrow
   screen it's just another block, last in the stack, so it never bumps the
   invites/online lists down. On a wide screen the exact same markup (Tips
   stays last in the DOM, only the grid placement changes) becomes a sidebar
   next to everything else, no JS reordering needed. */
#screen-menu {
  display: grid;
  grid-template-areas: "top" "play" "status" "invites" "online" "tips";
  grid-template-columns: 1fr;
  /* Without this, the grid (a flex-column .screen child with min-height:
     100dvh from the base rule) stretched its auto-sized rows to fill any
     leftover height below the natural content — on a short/wide window that
     showed up as big dead gaps between "top"/"play"/"invites", not just
     trailing space after everything. Rows now stay their natural size and
     any leftover space collects once, after the last row. */
  align-content: start;
  max-width: 480px;
  margin: 0 auto;
  width: 100%;
  gap: var(--gap);
}

.menu-top {
  grid-area: top;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

.menu-title {
  font-size: 26px;
  margin: 0;
}

.menu-cards { grid-area: play; }
#menu-status { grid-area: status; }
.menu-section--invites { grid-area: invites; }
.menu-section--online { grid-area: online; }
.tips-card { grid-area: tips; }

@media (min-width: 760px) {
  #screen-menu {
    grid-template-areas:
      "top    top"
      "play   tips"
      "status tips"
      "invites tips"
      "online tips";
    grid-template-columns: 1fr 300px;
    max-width: 900px;
    align-items: start;
  }
}

.menu-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card--action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  text-align: left;
  background: var(--color-panel);
  border: 1px solid var(--color-panel-border);
  min-height: 64px;
}

.card--action:active {
  background: var(--color-bg);
}

.card-title {
  font-weight: 600;
  font-size: 16px;
}

.card-sub {
  color: var(--color-text-dim);
  font-size: 13px;
}

.menu-section h2 {
  font-size: 15px;
  color: var(--color-text-dim);
  margin-bottom: 10px;
  font-weight: 600;
}

/* A soft accent-tinted panel (not the plain --color-panel every other card
   uses) so it reads as "worth glancing at", not just another list section —
   same dark palette, just warmed slightly toward the accent green instead of
   introducing a new color. */
.tips-card {
  background: linear-gradient(160deg, rgba(124, 255, 107, 0.10), var(--color-panel) 65%);
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius);
  padding: 16px;
}

.tips-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.tips-header h2 {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text);
}

.tips-icon-emoji {
  font-size: 16px;
  line-height: 1;
  flex: 0 0 auto;
}

.tips-lede {
  color: var(--color-text-dim);
  font-size: 13px;
  margin-bottom: 12px;
}

.tips-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tips-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}

.tips-list .tips-icon-emoji {
  font-size: 18px;
}

/* Placement — board and tray share one grid, like the battle layout: on a
   narrow/portrait screen the tray sits under the board, on a wide screen it
   moves to the side, without duplicating any markup. */

#screen-placement {
  max-width: 480px;
  margin: 0 auto;
  width: 100%;
  gap: 14px;
}

#screen-placement h2 {
  font-size: 18px;
  text-align: center;
}

.placement-layout {
  display: grid;
  grid-template-areas: "board" "side";
  grid-template-columns: 1fr;
  gap: 14px;
  width: 100%;
}

.placement-layout .board {
  grid-area: board;
}

.placement-side {
  grid-area: side;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.placement-tray {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

@media (min-width: 700px) {
  #screen-placement {
    max-width: 760px;
  }

  .placement-layout {
    grid-template-areas: "board side";
    grid-template-columns: 1fr 260px;
    align-items: start;
  }
}

.placement-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

/* Battle — one grid, only the area assignment changes between portrait and
   landscape, so the own/enemy board + HUD markup never has to be duplicated. */

#screen-battle {
  padding-left: 0;
  padding-right: 0;
}

.battle-layout {
  display: grid;
  grid-template-areas: "mine" "hud" "enemy" "actions";
  grid-template-columns: 1fr;
  gap: 10px;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding: 0 16px;
}

/* Each board gets its own card boundary — a bare 1px board border plus the
   grid's own gap wasn't enough to keep "mine" and "enemy" from visually
   reading as one continuous field when they sit right next to each other. */
.board-panel {
  background: var(--color-panel);
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius);
  padding: 10px;
  /* Cancels .battle-layout's own 16px side padding so the board itself reaches
     the physical screen edges on a phone (bigger cells, easier taps) — the HUD
     and action buttons below keep their normal inset, only the boards bleed
     full-width. */
  margin: 0 -16px;
}

/* Side by side on a wide screen (desktop/tablet, landscape) — 700px keeps
   this off on phones. Phones were the whole source of trouble here: turning
   THIS on for phone-width landscape too (down to 480px) led to a chain of
   real-device-only bugs (a guessed height constant, then flex+aspect-ratio,
   then a JS measurement — each broke differently on different real phones,
   one confirmed cause being Opera Data Savings rendering the page at a fixed
   ~980px "desktop" width regardless of actual orientation). None of that
   instability showed up on an actual wide/desktop screen, so back to the
   original threshold — phones always get the portrait layout, wide screens
   in landscape get boards side by side.
   Must come AFTER the base .board-panel rule above: both set `margin` at
   equal specificity, and CSS breaks that tie by source order, not by which
   one is wrapped in a media query — placed before it, this override was
   silently losing to the base rule's `margin: 0 -16px`, so the two boards
   overlapped by 16px+16px instead of having a gap between them. */
@media (orientation: landscape) and (min-width: 700px) {
  .battle-layout {
    grid-template-areas: "hud hud" "mine enemy" "actions actions";
    grid-template-columns: 1fr 1fr;
    max-width: 900px;
  }

  .board-panel {
    margin: 0;
  }
}

.board-panel--mine {
  grid-area: mine;
}

.board-panel--enemy {
  grid-area: enemy;
}

.board-panel h3 {
  font-size: 13px;
  color: var(--color-text-dim);
  font-weight: 600;
  margin-bottom: 6px;
  text-align: center;
}

.hud {
  grid-area: hud;
  background: var(--color-panel);
  border: 1px solid var(--color-panel-border);
  border-radius: var(--radius-sm);
  padding: 6px 14px;
}

/* Single row, badge centered between the two side blocks — named areas
   (not auto-placement) so a hidden badge (finished match) can't shift the
   right side out of place, it just leaves its own area empty. */
.hud-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "left badge right";
  align-items: center;
  gap: 8px;
}

.hud-row > .hud-side {
  grid-area: left;
}

.hud-row > .hud-side--right {
  grid-area: right;
}

.hud-row > .hud-turn-badge {
  grid-area: badge;
  justify-self: center;
}

/* .status-line normally reserves height even when empty, so an error message
   can appear without shifting layout — inside the HUD that reserved space was
   the biggest single source of "extra" height, since there's usually nothing
   to show there at all. */
#battle-status:empty {
  min-height: 0;
  margin-top: 0;
}

/* Sits between the two clocks instead of taking its own banner line above —
   always has its own explicit background/color (never relies on inherited or
   near-matching colors), so it can't blend into the panel behind it. Sized to
   its own content (not flex-grown) so space-between centers it naturally
   instead of stretching its background across the row. */
.hud-turn-badge {
  flex: 0 1 auto;
  max-width: 200px;
  text-align: center;
  font-weight: 700;
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: #06210a;
  background: var(--color-accent);
  border-radius: 999px;
  padding: 5px 16px;
  white-space: nowrap;
}

.hud-turn-badge.hud-turn--waiting {
  color: var(--color-text);
  background: var(--color-panel-border);
}

/* Full-sentence outcome once the match is finished — there's no live clock
   race to keep compact for anymore, so this gets its own line above the row. */
.hud-outcome {
  text-align: center;
  font-weight: 700;
  font-size: 16px;
  color: var(--color-warning);
  margin-bottom: 8px;
}

.hud-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
}

.hud-side--right {
  align-items: flex-end;
}

.hud-name {
  font-size: 13px;
  color: var(--color-text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.hud-points {
  font-size: 20px;
  font-weight: 700;
}

.hud-clock {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.hud-side.is-active .hud-clock {
  color: var(--color-accent);
}

.battle-actions {
  grid-area: actions;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.hud-actions {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
}

.stats-date {
  font-size: 12px;
  color: var(--color-text-dim);
  margin: 0 0 8px;
}

/* Classic underline tabs — a shared baseline, active tab picked out by its
   underline and brighter text, not a separate button box. */
.stats-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--color-panel-border);
  margin-bottom: 12px;
}

/* Full names, never truncated — a long subject name ("Английский язык")
   wraps onto a second line inside its own tab rather than being cut with an
   ellipsis, and if a whole tab doesn't fit the row, flex-wrap moves it down
   instead of squeezing everything into unreadable slivers. */
.stats-tab {
  flex: 1 1 auto;
  min-height: 40px;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;
  color: var(--color-text-dim);
  font-weight: 600;
  font-size: 13px;
  line-height: 1.25;
  text-align: center;
  white-space: normal;
  word-break: break-word;
}

.stats-tab.is-active {
  border-bottom-color: var(--color-accent);
  color: var(--color-text);
}

/* Fixed height (not just min-height) so switching tabs never resizes the
   modal — panels with fewer rows (e.g. a subject with only 2 ranked players)
   just leave blank space instead of shrinking the whole window. */
.stats-tab-panel {
  height: 220px;
  overflow-y: auto;
}

.stats-tab-panel p {
  font-size: 14px;
  color: var(--color-text-dim);
  margin: 2px 0;
}

.stats-name {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text);
  margin: 2px 0;
}

.stats-status {
  color: var(--color-accent);
  font-weight: 600;
}

.perf-chart {
  width: 100%;
  height: 160px;
  display: block;
}

.perf-point {
  cursor: pointer;
}

#match-stub-text {
  white-space: pre-line;
}
