:root {
  --bg: #0f1b23;
  --panel-bg: #16262f;
  --panel-bg-2: #1d3340;
  --border: #2c4353;
  --text: #eaf1f5;
  --text-dim: #9db2bf;
  --accent: #4fb0d6;
  --accent-2: #f2b134;
  /* Vivid "azure blue" - the home page's title text and its four main
     boxes (Start Game, Leaderboard, Elo Ranking, the account bar) - kept
     distinct from --accent above, which is a softer blue used throughout
     the rest of the UI (buttons, highlights). */
  --azure: #007fff;
  /* Mint green - only used by the home page's decorative background
     zigzags (see .zigzag-mint), alongside --accent-2's gold/orange and
     --azure's blue above. */
  --mint: #2fd9a8;
  --water: #1c4e6b;
  --danger: #d9534f;
  --success: #4caf50;
  /* Plain tan for the pre-game screens (start menu, create-game setup,
     waiting-for-host) - see .pre-game-screen below. The actual game board
     screen keeps the dark theme above (var(--bg)/--panel-bg etc.) - this
     variable is deliberately scoped to only those three screens rather
     than replacing --bg globally. */
  --tan-bg: #d2b48c;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* min-height (not height) so a page taller than the viewport - like
     /rules, whose body carries .pre-game-screen's tan background directly
     with no #screen wrapper of its own - lets the background grow to
     cover the actual scrollable content instead of stopping at exactly
     one viewport tall and leaving the overflow area bare. The SPA's own
     screens are unaffected: .screen/#game-screen already size themselves
     with their own min-height/height: 100vh regardless of body's height. */
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
}

.hidden { display: none !important; }

button {
  font-family: inherit;
  cursor: pointer;
}

.btn {
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 600;
  transition: transform 0.05s ease, opacity 0.15s ease;
}
.btn:hover { opacity: 0.9; }
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.35; cursor: not-allowed; }
/* .btn is also used on the odd <a> (the start menu's Rules link, and
   rules.html's Back link) instead of a real <button>, since they're plain
   page navigations rather than JS actions - strip the browser's default
   link underline/inline display so they read identically to a button. */
a.btn { display: inline-block; text-decoration: none; }

.btn.primary { background: var(--accent); color: #04222e; }
.btn.secondary { background: var(--panel-bg-2); color: var(--text); border: 1px solid var(--border); }
.btn.danger { background: var(--danger); color: white; }
.btn.small { padding: 6px 10px; font-size: 12px; border-radius: 6px; }
/* Marks an action that's free this click (a banked free-road credit, or
   the Road Building card) - declared after .primary so it still reads as
   green even while selected (class order on the element doesn't matter;
   stylesheet order does for equal-specificity rules). */
.btn.free-action { background: var(--success); color: #04220a; border: none; }

/* ---------- setup screen ---------- */

.screen { width: 100%; min-height: 100vh; }

#start-menu-screen, #setup-screen, #waiting-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* Overrides the shared centering above just for the home screen, so its
   new top-level title (see #home-title) sits at the top of the page with
   the row of cards below it, rather than everything being centered as one
   vertically-centered block. Harmless for setup-screen/waiting-screen's
   own single .setup-card child, which is why it's split out instead of
   changed in the shared rule above. */
#start-menu-screen {
  flex-direction: column;
  justify-content: flex-start;
  /* Back to the original 28px (was briefly widened to 64px to keep the
     leaderboard/Elo cards clear of the oval while the title band sat much
     lower on the page) - now that padding-top below is small again, this
     smaller gap is enough on its own to keep .start-menu-layout's cards
     (see .home-card-left/.home-card-right) just clear of .home-title-oval
     without pushing them nearly as far down the page as before. */
  gap: 28px;
  /* About 1/3 of the 64px this briefly held - leaves a bit of breathing
     room above the oval (rather than sitting flush with the very top of
     the page) without pushing the title, and everything below it, nearly
     as far down as before. See .home-title-wrap's own fixed height, which
     makes exactly how far down the oval itself ends up landing
     predictable regardless of the title text's own line-height. */
  padding-top: 22px;
  position: relative;
}

/* Purely decorative background layer - see the SVG markup in index.html.
   Absolutely filling #start-menu-screen (its nearest positioned ancestor,
   set above) and pinned behind every other child via z-index:0, the same
   layering idea as #board-svg's own layered <g> groups elsewhere in this
   file. pointer-events:none keeps it from ever intercepting clicks meant
   for the cards drawn on top of it. */
.home-bg-zigzags {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}
.zigzag-line {
  fill: none;
  stroke-width: 16;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.zigzag-gold { stroke: var(--accent-2); opacity: 0.55; }
.zigzag-azure { stroke: var(--azure); opacity: 0.5; }
.zigzag-mint { stroke: var(--mint); opacity: 0.5; }

/* Home page title, and the azure oval behind it - a plain wrapper just to
   give the absolutely-positioned oval something to center against (see
   .home-title-oval). Stays in #start-menu-screen's normal document flow
   (unlike the 3 cards below), so the whole page's vertical rhythm still
   flows title -> cards top-to-bottom; its own position within that flow is
   controlled via padding-top above. z-index:1 keeps it (and the oval)
   above .home-bg-zigzags. Fixed height matching .home-title-oval's own
   130px so the oval - centered vertically against THIS box - lands
   exactly at padding-top with no overflow above it, rather than being
   centered against a shorter box sized only to the title text's own
   line-height (which used to let it poke out above the top padding). */
.home-title-wrap {
  position: relative;
  z-index: 1;
  height: 130px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.home-title-oval {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 440px;
  height: 130px;
  max-width: 92vw;
  background: var(--azure);
  border-radius: 50%;
  z-index: 0;
}

/* Home page title - moved out of the "Start Game" card so it reads as a
   page-level banner across the top rather than belonging to one card. */
#home-title {
  position: relative;
  z-index: 1;
  margin: 0;
  text-align: center;
  color: var(--accent-2);
  font-size: 34px;
}

/* Plain tan background for every pre-game screen (start menu, the
   create-game setup form, and the "waiting for host" screen a remote
   invite link lands on) - see --tan-bg above. Deliberately not applied to
   #game-screen, which keeps its existing dark theme. */
.pre-game-screen {
  background: var(--tan-bg);
}

/* Centers a single primary action (the start menu's lone "Create Game"
   button) instead of .setup-actions' default flex-end, which is meant for
   the setup form's own trailing "Start Game" button alongside other
   controls. */
.setup-actions.centered {
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Live "N of 4 players in queue" readout on #queue-screen - see
   main.js's updateQueueCount. */
.queue-count {
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-dim);
  margin: -8px 0 16px 0;
}

/* Fixed top-right pill, shown on every pre-game screen (see main.js's
   showAccountBar/hideAccountBar) - deliberately outside .pre-game-screen's
   own centered card so it doesn't shift layout on any of them. */
#account-bar {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--azure);
  color: #000;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 13px;
}
#account-bar-user { display: flex; align-items: center; gap: 8px; }
#account-bar-username { font-weight: 600; color: #000; }

.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-form label { font-size: 13px; color: var(--text-dim); display: flex; flex-direction: column; gap: 4px; }
.auth-form input {
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 14px;
}
.auth-switch { font-size: 12.5px; color: var(--text-dim); margin-top: 4px; }
.auth-switch a { color: var(--accent); cursor: pointer; text-decoration: underline; }

.history-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.history-table th, .history-table td {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.history-table th { color: var(--text-dim); font-weight: 600; }
.history-empty { color: var(--text-dim); font-size: 13.5px; }

.invite-link-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.invite-link-row .invite-name {
  min-width: 80px;
  flex-shrink: 0;
  font-size: 13px;
}
.invite-link-row input {
  flex: 1;
  min-width: 0;
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 12px;
}

.setup-card {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  width: 480px;
  max-width: 100%;
}

.setup-card h1 { margin: 0 0 4px 0; font-size: 26px; }
.setup-card h2 { margin: 0 0 4px 0; font-size: 20px; }
.subtitle { color: var(--text-dim); margin-top: 0; margin-bottom: 24px; font-size: 14px; }

/* Fills all the vertical space #start-menu-screen's flex column has left
   after .home-title-wrap above it (flex:1 - the only other in-flow child,
   since #discord-panel/.home-actions-card are position:fixed and don't
   participate) - this gives the leaderboard/Elo cards inside a real,
   fully-sized box spanning down to the bottom of the screen to position
   themselves against, rather than collapsing to zero height once they
   became position:absolute below (an absolutely-positioned child
   contributes nothing to its parent's own auto height). position:relative
   makes it the positioning root for both of them (see .home-card-left/
   .home-card-right) - #start-menu-screen itself is the nearer positioned
   ancestor otherwise, which would ignore the title's own space and
   position against the WHOLE screen instead of just the room below it.
   .home-actions-card no longer positions against this box at all (see its
   own comment) - it needs to read as centered on the whole page, not just
   the leftover space below the title band. */
.start-menu-layout {
  position: relative;
  flex: 1;
  width: 100%;
}

/* Create-game card - centered on the actual viewport (fixed, not absolute
   against .start-menu-layout) so it reads as truly "center of the page"
   regardless of how tall the title band above or the leaderboard cards
   beside it happen to be - same fixed-positioning approach as
   #discord-panel/#account-bar elsewhere on this screen. */
.home-actions-card {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
}

/* Leaderboard (right) and Elo Ranking (left) - pinned to the same top
   offset within .start-menu-layout, so both sit at the same height.
   Horizontal: each was 5vw from its own page edge - halved to 2.5vw so
   each edge is now halfway between where it used to be and the actual
   edge of the page. Vertical: the card's full on-page distance from the
   very top of the viewport used to be ~196px (screen's own 22px
   padding-top + .home-title-wrap's 130px + the 28px gap after it + this
   16px) - moved up to about 2/3 of that (~131px), which works out to a
   negative top here since .start-menu-layout itself already starts 180px
   down (22+130+28) before this card's own top offset is even added:
   131 - 180 = -49px. Pulls the cards up into the same horizontal band as
   the title/oval, but since they're now shifted outward too (2.5vw vs.
   the oval's fixed, centered 440px width) there's no actual overlap at
   any reasonable page width. */
.home-card-right {
  position: absolute;
  top: -49px;
  right: 2.5vw;
  z-index: 1;
}
.home-card-left {
  position: absolute;
  top: -49px;
  left: 2.5vw;
  z-index: 1;
}

/* Home page's 3 cards (Start Game, Leaderboard, Elo Ranking) - scoped to
   .start-menu-layout specifically so setup-screen/waiting-screen's own
   .setup-card (a different screen reusing the same class) keeps its
   normal dark theme. Sub-boxes that already carry their own background -
   the leaderboard filter <select> and every .btn - are left alone (they
   already declare their own explicit background/color, so they're
   unaffected by this card-level override); .subtitle and the table's
   dimmed labels don't have a background of their own, so they're called
   out explicitly below to keep them legible against azure instead of
   their old low-contrast gray. */
.start-menu-layout .setup-card {
  background: var(--azure);
  color: #000;
}
.start-menu-layout .setup-card .subtitle,
.start-menu-layout .setup-card .leaderboard-table th,
.start-menu-layout .setup-card .leaderboard-rank,
.start-menu-layout .setup-card .leaderboard-empty {
  color: #000;
}

.leaderboard-card { width: 420px; }

/* Caps how tall the Leaderboard/Elo Ranking listings can grow - without
   this, a long enough list (either panel can hold up to 100 rows) would
   keep stretching .home-card-left/.home-card-right's height past the
   bottom of the viewport, and since nothing was clipping that overflow the
   WHOLE PAGE would grow scrollable instead of just the panel. The budget
   subtracted from 100vh is a rough (deliberately generous/conservative)
   allowance for everything else stacked above the listing within its own
   card - screen padding-top + the title/oval band + this card's own top
   offset (see .home-card-left/.home-card-right) + its own heading/
   subtitle/filter-select/padding - so the card's TOTAL height (this capped
   listing plus that fixed chrome above it) never exceeds one viewport.
   Both cards share the same budget now that both have a civ/leader filter
   <select> above their listing (see #elo-leaderboard-filter). Trimmed down
   further (was 380px, then 300px) now that .home-card-left/
   .home-card-right sit higher on the page (own top offset moved from
   16px to -49px - see their own comment) - the listing itself now
   stretches down even closer to the bottom of the page. */
#leaderboard-body,
#elo-leaderboard-body {
  max-height: max(160px, calc(100vh - 235px));
  overflow-y: auto;
}
/* Keeps the column headers visible while a long list scrolls underneath
   them - needs its own explicit background (matching the card's own azure
   - see .start-menu-layout .setup-card) since sticky content otherwise
   paints over whatever scrolls past behind it with no fill of its own. */
.leaderboard-table thead th {
  position: sticky;
  top: 0;
  background: var(--azure);
}

/* Fixed bottom-center panel on the home screen only, so it stays put
   regardless of how tall the leaderboard cards above grow - same
   fixed-positioning approach as #account-bar's top-right pill, just
   centered horizontally (left:50% + translateX(-50%)) instead of pinned
   to a corner. */
#discord-panel {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  width: auto;
  padding: 14px 20px;
  text-align: center;
}
#discord-panel p { margin: 0 0 6px 0; font-weight: 600; }
#discord-panel a { color: var(--accent); word-break: break-all; }
.leaderboard-card select#leaderboard-filter,
.leaderboard-card select#elo-leaderboard-filter {
  width: 100%;
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 14px;
  margin-bottom: 16px;
}
.leaderboard-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.leaderboard-table th, .leaderboard-table td {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.leaderboard-table th { color: var(--text-dim); font-weight: 600; }
.leaderboard-table td.wins-col, .leaderboard-table th.wins-col { text-align: right; }
.leaderboard-rank { color: var(--text-dim); width: 28px; }
.leaderboard-empty { color: var(--text-dim); font-size: 13.5px; }

/* Standalone /rules page (templates/rules.html) - a real page navigation
   rather than an SPA screen swap, so it gets its own small set of layout
   classes instead of reusing .screen's fixed 100vh flex-centering, which
   doesn't work for a page long enough to scroll. */
.rules-page {
  min-height: 100vh;
  padding: 32px 16px;
  display: flex;
  justify-content: center;
}
.rules-card {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  width: 720px;
  max-width: 100%;
}
.rules-back-btn { display: inline-block; text-decoration: none; margin-bottom: 16px; }
.rules-card h1 { margin: 0 0 4px 0; font-size: 26px; }
.rules-card h2 { margin: 32px 0 12px 0; font-size: 20px; border-top: 1px solid var(--border); padding-top: 20px; }
.rules-intro { color: var(--text); font-size: 14px; line-height: 1.6; }
/* Same accent color as .rules-entry-name (the civilization/leader names
   below) - highlights this one sentence within the otherwise plain-white
   intro paragraph without changing its size/weight. */
.rules-vp-note { color: var(--accent-2); }
/* Same white as .rules-intro above it - this list is a continuation of
   that intro paragraph, just broken into bullets. */
.rules-clarifications-header { color: var(--text); font-size: 14px; line-height: 1.6; margin: 16px 0 6px 0; font-weight: 700; }
.rules-clarifications { color: var(--text); font-size: 14px; line-height: 1.6; margin: 0; padding-left: 22px; }
.rules-clarifications li { margin-bottom: 6px; }
.rules-clarifications li:last-child { margin-bottom: 0; }
.rules-entry-list { display: flex; flex-direction: column; gap: 14px; }
.rules-entry-name { font-size: 15px; font-weight: 700; color: var(--accent-2); margin-bottom: 4px; }
.rules-entry-text { margin: 0; font-size: 14px; color: var(--text-dim); line-height: 1.5; }
/* Same dim color as .rules-entry-text - these are supplementary
   clarification bullets for a specific civilization/leader, shown right
   below that entry's own ability text. */
.rules-entry-clarifications { margin: 6px 0 0 0; padding-left: 20px; font-size: 14px; color: var(--text-dim); line-height: 1.5; }
.rules-entry-clarifications li { margin-bottom: 4px; }
.rules-entry-clarifications li:last-child { margin-bottom: 0; }
.rules-loading { color: var(--text-dim); font-size: 13.5px; }

.player-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.player-row input[type="text"] {
  flex: 1;
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 14px;
}

.player-row select {
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 8px 6px;
  font-size: 13px;
}

.player-color-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
}

.player-row .remove-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 16px;
  padding: 2px 6px;
}

/* Per-row invite link (see renderSetupRows/updateInviteInfoUI) - every
   non-host human row's #invite-info-<seatKey> placeholder becomes one of
   these once real lobby data exists for it. Forced onto its own full-width
   line below the name/type/remove controls (flex-basis: 100%, relying on
   .player-row's flex-wrap: wrap) rather than squeezed into that same row -
   cramming a link input + Copy button + status text into whatever narrow
   sliver was left over there made the link input collapse to near-nothing
   and pushed the status text past the setup card's right edge, out onto
   the page background behind it. */
.player-row span[id^="invite-info-"] {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-basis: 100%;
  min-width: 0;
  margin: 2px 0 4px 22px;
}
.player-row span[id^="invite-info-"] input[type="text"] {
  flex: 1;
  min-width: 0;
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 12px;
}
.invite-status {
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  flex-shrink: 0;
}
.invite-status.invite-joined {
  color: var(--success);
}

.setup-actions { margin-top: 20px; display: flex; justify-content: flex-end; }
.error-text { color: var(--danger); font-size: 13px; min-height: 18px; margin-top: 10px; }

/* Casual create-game screen's optional turn-timer checkbox (see
   main.js's enterSetupScreen, which hides this whole row for Ranked -
   that mode always has the timer on, no choice to make). */
.timer-option-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-dim);
  margin-top: 14px;
  cursor: pointer;
}
.timer-ranked-note { color: var(--text-dim); font-size: 13px; margin-top: 14px; }
/* Shown in the action bar to a remote/invited player once their game ends
   - see renderActions' GAME_OVER branch. Only the host gets a Play Again
   button; everyone else just waits to be auto-followed into it (see
   pollForRematch). */
.waiting-rematch-text { color: var(--text-dim); font-size: 14px; }

/* ---------- game screen ---------- */

#game-screen {
  display: grid;
  grid-template-columns: 280px 1fr 340px;
  /* The board's row is the only flexible (1fr) one, so it always fills
     whatever's left after the topbar, hand bar, and action bar - which is
     exactly what keeps #board-area (a flex-centered box, see below)
     vertically centered between the top bar and the hand bar rather than
     between the top bar and the action bar. */
  grid-template-rows: auto 1fr auto auto;
  /* Column 1 of the hand-bar row used to belong to "handbar" (spanning all
     three columns) but only ever showed empty background there, since the
     hand cards are centered under the board/side columns. That slot now
     belongs to "logpanel" instead (same name repeated in rows 2 and 3 forms
     one tall rectangle spanning both rows in column 1), giving the log/chat
     column extra vertical room - and #chat-panel's flex:1 share (see
     #log-side-panel below) means that extra room goes to chat. "handbar"
     now only spans columns 2-3. */
  grid-template-areas:
    "topbar    topbar    topbar"
    "logpanel  board     side"
    "logpanel  handbar   handbar"
    "actionbar actionbar actionbar";
  height: 100vh;
}

#topbar {
  grid-area: topbar;
  position: relative;
  display: flex;
  align-items: center;
  /* #turn-indicator is centered via absolute positioning below (taking it
     out of normal flow), so the only flex child left here is #invite-btn -
     flex-end keeps it pinned to the right edge, same as before. */
  justify-content: flex-end;
  gap: 10px;
  padding: 10px 20px;
  background: var(--panel-bg);
  border-bottom: 1px solid var(--border);
}

/* Centered in the bar regardless of #invite-btn's width/visibility, same
   trick #dice-indicator uses on the board below - absolute + left:50% +
   translateX(-50%), so turn/victory text always reads as centered rather
   than just sitting at the flex layout's start. Wraps both #turn-indicator
   and #turn-timer (see below) so the optional turn-timer countdown sits
   directly next to the turn indicator as one centered unit, rather than
   needing its own separate positioning. */
#turn-status {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  white-space: nowrap;
}
#turn-indicator {
  font-size: 15px;
  font-weight: 600;
}
.player-chip { padding: 4px 10px; border-radius: 999px; font-size: 13px; }
#turn-indicator .player-chip { margin-left: 8px; }

/* Optional per-game turn timer (see GameState.timed) - sits right next to
   the turn indicator inside #turn-status above, hidden entirely (see
   main.js's updateTurnTimerDisplay) whenever this game isn't timed. */
#turn-timer {
  font-size: 14px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  color: var(--text);
}
/* Under ~30 seconds remaining on the main clock (or ~10 on a response
   countdown - see the matching class toggle in main.js) - a plain color
   swap, no animation, so it reads as urgent without being distracting. */
#turn-timer.turn-timer-urgent {
  color: #fff;
  background: #c0392b;
  border-color: #c0392b;
}

/* 40-second "respond to someone else" countdown shown inside the trade/
   port-trade/discard modals (see main.js's showResponseCountdown) - empty
   and takes up no visible space for an untimed game. */
.response-countdown {
  font-weight: 600;
  color: var(--text-dim);
}
.response-countdown.turn-timer-urgent {
  color: #e74c3c;
}

#dice-indicator {
  position: absolute;
  left: 50%;
  bottom: 4.5%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  color: #fff;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 1px;
  pointer-events: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  z-index: 1;
}
#dice-indicator .player-chip { text-shadow: none; }

#board-area {
  grid-area: board;
  background: var(--water);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

#board-svg { width: 100%; height: 100%; }

#side-panel {
  grid-area: side;
  background: var(--panel-bg);
  border-left: 1px solid var(--border);
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

#log-side-panel {
  grid-area: logpanel;
  background: var(--panel-bg);
  border-right: 1px solid var(--border);
  overflow: hidden;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#log-side-panel .panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* Log gets 3 parts of the shared vertical space to chat's 1 - i.e. the
   chat box's height is 1/4 of the total (log+chat) space, 1.25x its
   original 1/5 share (log:chat used to be 4:1) - desktop/non-mobile only,
   see the @media (max-width: 860px) override further down that puts this
   back to the original 4:1 split for narrow screens. Specificity has to
   beat #log-side-panel .panel's own shared "flex: 1" above (an id + a
   class), so these match on id + id rather than plain id alone. */
#log-side-panel #log-panel { flex: 3; }
#log-side-panel #chat-panel { flex: 1; }

/* The collapsed stand-in for #chat-panel (see main.js's chat
   hide/show toggle) - a slim fixed-height bar, NOT a flex:1 participant,
   so #log-panel (already the only other flex child once #chat-panel is
   display:none) expands to fill essentially all of the freed space. */
#chat-collapsed-bar {
  flex: none;
  display: flex;
  justify-content: center;
}
#chat-collapsed-bar .btn { width: 100%; }

/* Same idea, generalized for every OTHER panel's own Hide/Show toggle
   (Log, Players, Civilization & Leader, Bank, Build Costs - see
   main.js's setPanelCollapsed/initPanelToggles and index.html's
   #<name>-collapsed-bar elements). Chat keeps its own id-based rule above
   unchanged rather than being migrated onto this shared class - no reason
   to touch already-working code just to de-duplicate a few lines. */
.panel-collapsed-bar {
  flex: none;
  display: flex;
  justify-content: center;
}
.panel-collapsed-bar .btn { width: 100%; }

.panel-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.panel-header-row h3 { margin: 0; }
.panel-header-row .btn { flex-shrink: 0; }

#chat-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  font-size: 12px;
}
.chat-message .chat-sender { font-weight: 600; margin-right: 4px; }
.chat-message .chat-text { color: var(--text-dim); word-break: break-word; }
.chat-empty { color: var(--text-dim); font-size: 12px; font-style: italic; }

#chat-form {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex: none;
}
#chat-form input {
  flex: 1;
  min-width: 0;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
  color: var(--text);
  font-size: 12px;
}
#chat-form .btn { flex-shrink: 0; }

/* Own full-width bar sitting directly above the action bar, below the
   board/ocean background - moved out of #side-panel (see index.html) so a
   player's hand reads like cards held right in front of them at the table,
   rather than another stacked sidebar panel. Deliberately not a .panel -
   it's a horizontal strip the same shape as #action-bar, not a vertical
   card. */
#my-hand-panel {
  grid-area: handbar;
  background: var(--panel-bg);
  border-top: 1px solid var(--border);
  padding: 10px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 16px;
}
#my-hand-panel h3 {
  margin: 0;
  flex-shrink: 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
#my-hand-panel #my-resources,
#my-hand-panel #my-dev-cards {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

#action-bar {
  grid-area: actionbar;
  background: var(--panel-bg);
  border-top: 1px solid var(--border);
  padding: 12px 20px;
}

/* Wraps #my-hand-panel/#action-bar/#side-panel (see index.html) - fully
   transparent here (display:contents removes it from the box-generation
   tree entirely), so on desktop each of those three children still places
   itself directly via its own grid-area (handbar/actionbar/side) on
   #game-screen exactly as if this wrapper didn't exist. The
   @media (max-width: 860px) override further down turns this into a real
   flex container instead, which is the whole point of having it - see
   that rule's own comment. */
#mobile-bottom-group {
  display: contents;
}

.panel {
  background: var(--panel-bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}

.panel h3 {
  margin: 0 0 10px 0;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.player-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 6px;
  border-radius: 8px;
  margin-bottom: 4px;
  font-size: 13px;
}
.player-card.active { background: rgba(79, 176, 214, 0.15); }
.player-card-left { display: flex; align-items: center; gap: 8px; }
.player-card-badges { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text-dim); }
.player-card-stats { display: flex; gap: 10px; font-size: 12px; color: var(--text-dim); }

/* Small clickable "?" badge next to a civ/leader combo (see
   renderPlayersPanel) - opens showCivLeaderInfoModal immediately, unlike
   the div's own native-title hover tooltip which needs a hover delay and
   doesn't work on touch devices at all. */
.info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid var(--text-dim);
  color: var(--text-dim);
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}
.info-icon:hover {
  border-color: var(--accent-2);
  color: var(--accent-2);
}

.resource-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.resource-chip {
  display: flex;
  align-items: center;
  gap: 4px;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 13px;
}
.resource-chip .count { font-weight: 700; }

/* Bank's row has the same 5 chips as the hand's, but the bank's starting
   quantities run to 2 digits, which was just wide enough to wrap onto a
   second line at the sidebar's width - force it to stay on one line like
   the hand's row, shaving down gap/padding/font-size slightly to make
   room rather than letting the chips overflow. */
.resource-row.compact {
  flex-wrap: nowrap;
  gap: 4px;
}
.resource-row.compact .resource-chip {
  padding: 3px 5px;
  gap: 2px;
  font-size: 12px;
}

/* Static reference panel below the Bank listing every build option's
   cost, so players can check prices during other players' turns instead
   of only when it's their own turn to build (see renderBuildCostsPanel). */
#build-costs-body { display: flex; flex-direction: column; gap: 8px; }
.build-cost-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.build-cost-label { font-size: 13px; color: var(--text-dim); }

.devcard-chip {
  display: inline-block;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 9px;
  font-size: 12px;
  margin: 3px 4px 0 0;
}
.devcard-chip.playable { border-color: var(--accent); cursor: pointer; }
.devcard-chip.disabled { opacity: 0.5; }

/* ---------- Civilization & Leader panel ---------- */

.civ-leader-block { margin-bottom: 10px; }
.civ-leader-block:last-child { margin-bottom: 0; }
.civ-leader-name { font-size: 13px; font-weight: 700; color: var(--accent-2); margin-bottom: 3px; }
.civ-leader-text { margin: 0 0 8px 0; font-size: 12px; color: var(--text-dim); line-height: 1.4; }

.tracker-block { display: flex; flex-direction: column; gap: 5px; }
.tracker-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
}
.tracker-label { color: var(--text-dim); }
.tracker-count { font-weight: 600; text-align: right; }
.tracker-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  color: var(--text-dim);
  white-space: nowrap;
}
/* A ready/completed ability state (used, active, drawn, etc.) - green like
   the free-action button treatment elsewhere, so a glance at the panel
   shows what's already been spent this game. */
.tracker-badge.active { background: var(--success); border-color: var(--success); color: #04220a; }

.tracker-chip-wrap { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.tracker-chip {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px 6px;
  font-size: 11px;
}
.tracker-chip.protected { border-color: var(--accent); }

#action-buttons { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; }
#action-buttons .btn { text-align: left; }

#log-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  font-size: 12px;
  color: var(--text-dim);
}

/* ---------- overlay / modal ---------- */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(4, 10, 14, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
.overlay-card {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px;
  text-align: center;
  max-width: 420px;
}
.overlay-card h2 { margin-top: 0; }

.select-card {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px;
  text-align: center;
  max-width: 760px;
  max-height: 90vh;
  overflow-y: auto;
}
.select-card h2 { margin-top: 0; }

.minimized-hidden { display: none !important; }

.modal-header, .select-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  text-align: left;
}
.modal-header h3 { margin: 0; }
.select-header { margin-bottom: 4px; }
.select-header h2 { margin: 0; }
.select-header .btn, .modal-header .btn { flex-shrink: 0; }

#restore-chip {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 60;
}
#restore-chip .btn { box-shadow: 0 4px 18px rgba(0, 0, 0, 0.4); }

.card-row {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 20px;
}

.pick-card {
  width: 190px;
  min-height: 220px;
  background: var(--panel-bg-2);
  border: 2px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  text-align: left;
  transition: border-color 0.15s ease, transform 0.05s ease;
}
.pick-card:hover { border-color: var(--accent-2); transform: translateY(-2px); }
.pick-card h4 { margin: 0 0 10px 0; font-size: 15px; color: var(--accent-2); }
.pick-card p { margin: 0; font-size: 12.5px; color: var(--text-dim); line-height: 1.4; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 10, 14, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 40;
}
.modal-box {
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  width: 420px;
  max-width: 92vw;
  max-height: 85vh;
  overflow-y: auto;
}
/* Extra-wide variant for modals with a button per adjacent player (e.g.
   Norway's steal modal) - the default 420px reads as cramped/cluttered
   once each row has 1-2 buttons alongside the player's name. */
.modal-box.wide {
  width: 560px;
}
.modal-box h3 { margin-top: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* The "Trade" button's first stop - a short menu of trade kinds (see
   showTradeOptionsModal) rather than one long combined form. Buttons
   stack full-width so each reads as its own tappable row. */
.trade-options-list { display: flex; flex-direction: column; gap: 10px; }
.trade-options-list .btn { width: 100%; text-align: center; }

.pick-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.stepper { display: flex; align-items: center; gap: 8px; }
.stepper button {
  width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--panel-bg-2); color: var(--text); font-size: 14px;
}

/* ---------- SVG board elements ---------- */

.tile-hex { stroke: #0a1a22; stroke-width: 1.2; }
.tile-label {
  font-size: 13.75px;
  fill: rgba(255,255,255,0.75);
  text-transform: uppercase;
  text-anchor: middle;
  pointer-events: none;
  text-shadow:
    -0.75px -0.75px 0 #f2e6c9,
     0.75px -0.75px 0 #f2e6c9,
    -0.75px  0.75px 0 #f2e6c9,
     0.75px  0.75px 0 #f2e6c9,
    -0.75px  0      0 #f2e6c9,
     0.75px  0      0 #f2e6c9,
     0      -0.75px 0 #f2e6c9,
     0       0.75px 0 #f2e6c9;
}
.number-token-bg { fill: #f2e6c9; stroke: #7a6a4a; stroke-width: 1; }
.number-token-text {
  font-size: 13px;
  font-weight: 800;
  text-anchor: middle;
  dominant-baseline: central;
  fill: #2a2116;
}
.number-token-text.hot { fill: #b3241d; }
/* Small diamond pips under each number token - one per dice-roll
   combination that produces it (see NUMBER_PIPS in main.js). */
.number-pip { fill: #2a2116; pointer-events: none; }
.number-pip.hot { fill: #b3241d; }

.robber {
  font-size: 22px;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}

.tile-clickable { cursor: pointer; }
.tile-clickable:hover .tile-hex { stroke: var(--accent-2); stroke-width: 2.5; }

.edge-hit { stroke: transparent; stroke-width: 10; cursor: pointer; }
.edge-line { stroke: #4a3521; stroke-width: 3; stroke-linecap: round; pointer-events: none; }
.edge-line.built { stroke-width: 5; }
.edge-line.legal { stroke: var(--accent-2); stroke-width: 4; stroke-dasharray: 3 3; opacity: 0.85; }
/* A legal road placement that won't cost resources (a banked free-road
   credit, or the Road Building card) - green instead of the normal
   legal-move orange, declared after .legal so it wins on equal specificity. */
.edge-line.legal.free { stroke: var(--success); }
.edge-line.mountain-road { stroke-dasharray: 5 4; }
.edge-line.mountain-road.built { stroke-dasharray: none; }

.vertex-dot {
  fill: rgba(255,255,255,0.08);
  stroke: rgba(255,255,255,0.25);
  stroke-width: 1;
  cursor: default;
}
.vertex-dot.legal {
  fill: var(--accent-2);
  stroke: #fff;
  stroke-width: 1.5;
  cursor: pointer;
}
.vertex-dot.legal:hover { fill: #fff; }
.vertex-building { pointer-events: none; }

.port-label {
  font-size: 9px;
  fill: #dff3ff;
  text-anchor: middle;
  pointer-events: none;
}
.port-line { stroke: #dff3ff; stroke-width: 1; stroke-dasharray: 2 2; opacity: 0.6; }

/* ---------- dice-roll resource-gain flight animation ---------- */

/* Sits above the board/panels but below the pass-device and modal overlays
   (those only ever appear once the roll has already fully resolved, so in
   practice this never has to compete with them - the z-index headroom is
   just cheap insurance). Never intercepts clicks. */
#resource-fly-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 55;
}
.resource-fly-icon {
  position: fixed;
  left: 0;
  top: 0;
  font-size: 22px;
  line-height: 1;
  pointer-events: none;
  will-change: transform, opacity;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55));
}

/* Floating marker used to animate the robber moving between tiles while
   replaying a computer player's turn (see playAiRevealEvents in main.js).
   Lives in the same fixed overlay layer as the resource-fly icons; the
   static SVG .robber ninja glyph is hidden for the duration of the replay
   so the two never show at once. Same emoji as the static board icon, so
   the token flying between tiles reads as the same piece. */
.robber-fly-token {
  position: fixed;
  left: 0;
  top: 0;
  font-size: 26px;
  line-height: 1;
  pointer-events: none;
  will-change: transform;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.6));
}

@media (max-width: 860px) {
  #game-screen {
    grid-template-columns: 1fr;
    /* Was 6 separate rows (...side, handbar, actionbar as 3 independent
       auto/1fr rows) - now just one "bottomgroup" row holding all three
       (see #mobile-bottom-group below and index.html's wrapper) so hand+
       action's own natural height and the side-panel menu's full content
       no longer fight each other for a shrinking 1fr slice. Whatever's
       left after topbar/board/logpanel goes entirely to bottomgroup,
       which scrolls internally if hand+action+side together still don't
       fit - see #mobile-bottom-group's own comment. */
    grid-template-rows: auto 45vh auto 1fr;
    grid-template-areas:
      "topbar"
      "board"
      "logpanel"
      "bottomgroup";
  }
  /* The real (non-transparent) mobile version of the wrapper from the base
     rules above - a flex column instead of display:contents, so
     #my-hand-panel/#action-bar/#side-panel (in that DOM order - see
     index.html) stack top to bottom inside it: hand and the action buttons
     show first/"on top", and #side-panel's players/civ/bank/build-costs
     menu follows right below, reachable by scrolling this group once its
     combined natural content is taller than the space left over from
     topbar/board/logpanel. min-height: 0 is required here - without it, a
     flex child inside a grid track won't actually shrink to the track's
     size and would just overflow the page instead of scrolling internally
     the way #side-panel used to on its own. */
  #mobile-bottom-group {
    grid-area: bottomgroup;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
  }
  #my-hand-panel, #action-bar { flex: none; }
  /* #side-panel no longer needs to be its own independent scroll container
     (see its base rule's overflow-y: auto) now that the group around it
     handles scrolling as a whole - overriding back to visible avoids a
     confusing nested scrollbar-within-a-scrollbar on top of whatever
     #mobile-bottom-group already shows once content overflows. */
  #side-panel { flex: none; overflow-y: visible; border-left: none; border-top: 1px solid var(--border); }
  /* Trimmed back down from 320px - Log and Chat both start collapsed by
     default on a screen this narrow anyway (see main.js's DOMContentLoaded
     handler), so this cap now only matters once someone manually shows
     one of them again. When that happens, this still leaves more of the
     remaining height to #mobile-bottom-group below it (the "1fr" row)
     rather than letting the log column eat into it as much as before. */
  #log-side-panel { border-right: none; border-top: 1px solid var(--border); max-height: 200px; }
  /* Puts the log:chat split back to its original 4:1 ratio on a narrow
     screen (see the base #log-side-panel #log-panel/#chat-panel rules
     above, now 3:1 i.e. 1.25x chat's original share) - mobile is already
     tight on room with #log-side-panel capped to max-height:200px just
     above, and Log/Chat both start collapsed there anyway (see main.js's
     DOMContentLoaded handler), so there's no reason to also give up more
     of that cramped space to a bigger chat box on this size screen. */
  #log-side-panel #log-panel { flex: 4; }
  #log-side-panel #chat-panel { flex: 1; }

  /* Shrunk from the base 20px and forced onto one line - on a narrow board
     the base size + gap between the player chip and roll text ("🎲 3 + 5 =
     8") could wrap on this size screen (no white-space rule previously
     existed at all), pushing a second line down over the board/port
     labels underneath since this element is position:absolute and doesn't
     take up layout space of its own. white-space:nowrap guarantees a
     single line at any width; the smaller font/gap just makes that single
     line short enough to comfortably fit within the narrower mobile board
     without crowding the port text near the edges. */
  #dice-indicator {
    font-size: 14px;
    gap: 4px;
    letter-spacing: 0.5px;
    white-space: nowrap;
  }

  /* ---- home page ---- */
  /* .home-actions-card/.home-card-right/.home-card-left are fixed/absolute
     and deliberately overlap each other above this width (see their own
     rules further up) - that's what lets them sit side by side around the
     title on a wide desktop screen, but on a narrow phone screen it piles
     all 3 directly on top of one another with no way to scroll to or even
     see whichever one ends up buried underneath (Create Game included).
     Below this width, drop them back into plain in-flow stacking instead -
     DOM order is Create Game, then Leaderboard, then Elo Ranking (see
     index.html) - so the page is just one normal, scrollable column and
     every card is reachable by scrolling. transform:none cancels
     .home-actions-card's centering translate, which would otherwise still
     shift it off-position even once it's no longer fixed. */
  .home-actions-card,
  .home-card-right,
  .home-card-left {
    position: static;
    transform: none;
  }
  .start-menu-layout {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: none;
    gap: 20px;
    padding-bottom: 20px;
  }
  /* Same idea as the cards above - a fixed corner/bottom-center panel only
     makes sense with a whole desktop viewport to spare. Let it flow after
     the cards instead so it can't end up overlapping the last one. */
  #discord-panel {
    position: static;
    transform: none;
    margin: 0 auto 24px auto;
  }
}
