/* Shared base styles + the profile/game-history component styles, used by
   both index.html (the main app) and profile.html (the standalone player
   profile page) so the two don't drift out of visual sync. */

:root {
  --ink: #16130f;
  --ink-2: #221d17;
  --ink-3: #2b2419;
  --paper: #ece4d3;
  --paper-dim: #a89a82;
  --wood: #c89a5c;
  --wood-hi: #dcb877;
  --wood-dark: #8a6236;
  --seal: #b04432;
  --seal-hi: #cf5940;
  --focus: #e0a94f;
  --paper-faint: #7d715e;
  --good: #5fbf6f;
  --line: #3a2f1e;
  --border: #4a3c26;
  --hover-bg: #362c1c;
  --border-hover: #5c4a2e;
  --time-warn: #ffb199;
}

:root[data-theme="light"] {
  /* A second, deeper pass at "too bright" after the first #ffffff -> warm-
     white fix wasn't enough on its own — every surface here is a notch
     darker/more muted (closer to a sepia reading theme than a bright
     white one), AND --paper backs off from near-black to a softer dark
     brown, so the whole page reads lower-contrast/lower-glare rather than
     just the panels alone. Still comfortably above WCAG AA's 4.5:1 body-
     text contrast ratio (--paper on --ink-2 here is ~8.6:1). */
  --ink: #e6dcc4;
  --ink-2: #f2e9d4;
  --ink-3: #ddd0b0;
  --paper: #453a2a;
  --paper-dim: #6b5d47;
  --paper-faint: #8a7c61;
  --seal: #a8432f;
  --seal-hi: #8f3722;
  --focus: #b87d28;
  --good: #2f8f45;
  --line: #d4c6a0;
  --border: #c2b088;
  --hover-bg: #e0d3ae;
  --border-hover: #a8926a;
  --time-warn: #a8382a;
}

/* Third theme option — a moody, rainy-evening blue-gray palette. --wood*
   (the goban itself) stays the same warm wood across every theme, same as
   the light theme above never redefines it — a wooden board doesn't change
   color just because the weather outside the window did. --seal/--seal-hi
   (the site's primary accent, used on every button) DO shift here, to a
   cool blue instead of the usual warm red, so this reads as a genuinely
   different mood rather than just a dimmed copy of the dark theme. */
:root[data-theme="rain"] {
  --ink: #171f27;
  --ink-2: #202b35;
  --ink-3: #29343f;
  --paper: #d7e0e6;
  --paper-dim: #8fa2b0;
  --paper-faint: #6c7f8d;
  --seal: #4a7ba6;
  --seal-hi: #5f92c2;
  --focus: #6fa8dc;
  --good: #4fb0a5;
  --line: #2f3c47;
  --border: #3c4c58;
  --hover-bg: #2a3844;
  --border-hover: #4c6070;
  --time-warn: #ff9a7a;
}

/* Falling-rain animation, only shown while the rain theme is active — see
   initThemeToggle() in shared.js, which builds #rainOverlay's .raindrop
   children once and leaves visibility entirely to this selector, so
   switching themes doesn't need any extra JS wiring beyond the existing
   data-theme attribute swap. display:none also pauses the animation while
   hidden, which is both what we want for perf and harmless to restart from
   frame zero the next time the theme switches back to rain.
   prefers-reduced-motion is already handled globally with `* { animation-
   duration: 0.001ms !important }` above, so no extra opt-out needed here. */
#rainOverlay { position: fixed; inset: 0; z-index: 5; overflow: hidden; pointer-events: none; display: none; }
:root[data-theme="rain"] #rainOverlay { display: block; }
.raindrop {
  position: absolute;
  top: -8%;
  width: 1px;
  background: linear-gradient(to bottom, transparent, rgba(160,200,225,0.5));
  animation: rain-fall linear infinite;
}
@keyframes rain-fall {
  to { transform: translateY(115vh); }
}

/* Fourth theme option — bright, cold, icy-white winter palette. Unlike
   "rain" (a dark mood shift) this is a light theme, but a cool blue-gray
   one rather than the sepia-warm light theme above, so the three light-
   ish/dark-ish themes all read distinctly: dark, warm-light, cold-light,
   cold-dark. --wood* still untouched, same reasoning as the other themes. */
:root[data-theme="snow"] {
  --ink: #e8eff3;
  --ink-2: #f7fafb;
  --ink-3: #e1eaf0;
  --paper: #2c3e4a;
  --paper-dim: #5a6f7a;
  --paper-faint: #7c8f99;
  --seal: #3b7ea1;
  --seal-hi: #2f6a89;
  --focus: #5a9bc4;
  --good: #2f8f6f;
  --line: #d3e0e8;
  --border: #bcd0db;
  --hover-bg: #dce8ee;
  --border-hover: #a8c2d0;
  --time-warn: #c0392b;
}

/* Premium themes, unlocked via the shop (see SHOP_THEMES in server.js) —
   not part of THEME_CYCLE, only reachable by players who've bought them
   (see setUnlockedThemes() in shared.js). --wood* untouched, same
   reasoning as every other theme above. */
:root[data-theme="gold"] {
  /* A dark, opulent palette — same structural role as the default dark
     theme, just warmer/richer with gold standing in for the usual seal
     red. */
  --ink: #1a1408;
  --ink-2: #241c0d;
  --ink-3: #2e2410;
  --paper: #f0e6c8;
  --paper-dim: #b8a878;
  --paper-faint: #8a7c52;
  --seal: #d4af37;
  --seal-hi: #e8c458;
  --focus: #ffd700;
  --good: #7fbf5f;
  --line: #4a3c14;
  --border: #5c4a1a;
  --hover-bg: #3a2e10;
  --border-hover: #6c5820;
  --time-warn: #ff8a5c;
}
:root[data-theme="sakura"] {
  /* A light, warm-pink spring palette — distinct from both the sepia
     "light" theme and the cold-blue "snow" theme. */
  --ink: #fdf0f2;
  --ink-2: #fff7f8;
  --ink-3: #fbe4e8;
  --paper: #4a2e35;
  --paper-dim: #8a6068;
  --paper-faint: #a8828a;
  --seal: #d6708a;
  --seal-hi: #c25a76;
  --focus: #e0899f;
  --good: #4a9e6f;
  --line: #f0c8d0;
  --border: #e8b0bc;
  --hover-bg: #f8dce2;
  --border-hover: #dca0ae;
  --time-warn: #c23a3a;
}

/* Falling-snow animation — same show/hide-via-CSS-selector approach as
   #rainOverlay above, just its own container/element/keyframes so the two
   never fight over the same DOM nodes if a caller somehow enabled both
   (they can't — themes are mutually exclusive — but keeping them fully
   separate avoids any doubt). Snow drifts side to side each fall using
   percentage keyframes on the same transform (a second, separately-
   animated transform property isn't possible — the later animation would
   just override the first's transform outright, not combine with it). */
#snowOverlay { position: fixed; inset: 0; z-index: 5; overflow: hidden; pointer-events: none; display: none; }
:root[data-theme="snow"] #snowOverlay { display: block; }
.snowflake {
  position: absolute;
  top: -5%;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  animation: snow-fall linear infinite;
}
@keyframes snow-fall {
  0% { transform: translate(0, -10%); }
  50% { transform: translate(var(--drift, 20px), 55vh); }
  100% { transform: translate(0, 115vh); }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(ellipse 900px 500px at 50% -10%, var(--ink-2) 0%, transparent 60%),
    var(--ink);
  color: var(--paper);
  font-family: "Noto Sans Thai", -apple-system, "Segoe UI", system-ui, sans-serif;
  line-height: 1.6;
  padding: 14px 20px 20px;
}

.shell { max-width: 1400px; margin: 0 auto; }

/* ---- Header bar (brand + actions), same look on every page ---- */
#appHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 7px 16px;
  margin-bottom: 6px;
  background: linear-gradient(155deg, var(--ink-2) 0%, var(--ink) 100%);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.2);
}
.app-header-brand { display: flex; align-items: center; gap: 9px; min-width: 0; text-decoration: none; }
.app-header-brand svg { flex: none; display: block; }
.app-header-title {
  font-family: "Noto Serif Thai", Georgia, serif;
  font-weight: 600;
  font-size: 14px;
  color: var(--wood-hi);
  letter-spacing: 0.02em;
  flex: none;
}
.app-header-actions { display: flex; align-items: center; gap: 8px; flex: none; }

/* Narrow (mobile) viewports: the brand (logo/username) and the growing
   pile of action buttons (coins, shop, leaderboard, DM, theme, logout) no
   longer fit on one line without squeezing into each other — wrap onto
   two rows instead of shrinking. flex-wrap on .app-header-actions too, as
   a second line of defense on the narrowest phones where even that row
   alone might not fit. */
@media (max-width: 640px) {
  #appHeader { flex-wrap: wrap; }
  .app-header-brand { flex: 1 0 100%; }
  .app-header-actions { flex: 1 0 100%; flex-wrap: wrap; justify-content: flex-end; }
}

/* ---- Panel cards, same look on every page. Stacking spacing between
   panels is left to each page's own layout (index.html's lobby panels sit
   side by side in a grid; profile.html stacks two vertically) rather than
   assumed here via a sibling-margin rule that would misalign the grid. */
.panel { background: var(--ink-2); border: 1px solid var(--line); border-radius: 12px; }
.panel-head { padding: 20px 22px 16px; border-bottom: 1px solid var(--line); }
.panel-head h2 {
  margin: 0; font-family: "Noto Serif Thai", Georgia, serif; font-weight: 600; font-size: 18.5px;
  border-bottom: none; padding-bottom: 0;
}
.panel-head .sub { margin: 4px 0 0; font-size: 14px; color: var(--paper-dim); }
.panel-body { padding: 20px 22px 22px; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

button {
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--paper);
  background: var(--ink-3);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 9px 14px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
button:hover:not(:disabled) { background: var(--hover-bg); border-color: var(--border-hover); }
button.primary { background: var(--seal); border-color: var(--seal); }
button.primary:hover:not(:disabled) { background: var(--seal-hi); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-sm { font-size: 14.5px; border-radius: 7px; padding: 8px 15px; }

select {
  background: var(--ink-3);
  color: var(--paper);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 9px 10px;
  font-size: 15.5px;
  font-family: inherit;
  cursor: pointer;
}
select:focus-visible, button:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
select:disabled { opacity: 0.5; cursor: not-allowed; }

.theme-toggle {
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17.5px;
  line-height: 1;
  flex: none;
}

a { color: inherit; }

.lobby-pagination {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 14.5px; color: var(--paper-dim);
}

/* ---- Player profile summary + stats + game history list/replay ---- */
.profile-summary { display: flex; align-items: center; gap: 14px; padding: 10px 6px 16px; }
.profile-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: linear-gradient(155deg, var(--seal-hi), var(--seal));
  color: #fff2ea;
  font-size: 20px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.profile-summary-main { flex: 1; min-width: 0; }
.profile-username-row { display: flex; align-items: center; gap: 7px; }
.profile-username { font-size: 17px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile-online-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--paper-faint); flex: none; }
.profile-online-dot.online { background: var(--good); box-shadow: 0 0 0 3px rgba(95,191,111,0.18); }
.profile-meta { font-size: 13px; color: var(--paper-dim); margin-top: 3px; }
.profile-stats { display: flex; gap: 8px; padding: 0 6px 16px; flex-wrap: wrap; }
.profile-stat-tile { flex: 1 1 70px; background: var(--ink-3); border-radius: 8px; padding: 9px 6px; text-align: center; }
.profile-stat-value { font-size: 16px; font-weight: 700; }
.profile-stat-label { font-size: 11.5px; color: var(--paper-dim); margin-top: 2px; }

/* Rating tier colors — bucketed by ratingTier() in shared.js, applied to
   .profile-stat-value (plain colored number, profile card already reads as
   a "tile") and .rating-pill (compact badge, used inline next to a name in
   tight spaces like the online-users list). Same colors either way so a
   player's tier reads consistently wherever their rating shows up. */
.profile-stat-value.tier-wood, .rating-pill.tier-wood { color: #9c7a4e; }
.profile-stat-value.tier-bronze, .rating-pill.tier-bronze { color: #c68a54; }
.profile-stat-value.tier-silver, .rating-pill.tier-silver { color: #a8b4c0; }
.profile-stat-value.tier-gold, .rating-pill.tier-gold { color: #e6b950; }
.profile-stat-value.tier-platinum, .rating-pill.tier-platinum { color: #6fd0c8; }
.profile-stat-value.tier-emerald, .rating-pill.tier-emerald { color: #4ade80; }
.profile-stat-value.tier-diamond, .rating-pill.tier-diamond { color: #6fa8ff; }
.profile-stat-value.tier-master, .rating-pill.tier-master { color: #c084fc; }
/* GM badge — shown instead of a rating tier for staff accounts, so it
   deliberately looks distinct (plain gold outline, no fill) from the tier
   colors above rather than fitting into that wood-to-master scale. */
.profile-stat-value.tier-gm, .rating-pill.tier-gm { color: #f0c05a; font-weight: 800; }
/* Top-3-of-server badge — shown instead of the tier badge for the highest
   3 rated accounts server-wide (see TOP_N_COUNT/TOP_N_THRESHOLD in
   server.js). Gold gradient so it visually outranks every tier above,
   including master. */
.profile-stat-value.tier-top3, .rating-pill.tier-top3 { color: #ffd76a; font-weight: 800; }
/* AI practice-bot marker — an additional tag alongside the normal rating
   tier (not a replacement for it, unlike GM/top3), so it's styled as its
   own distinct neutral/cool color rather than fitting the wood-to-master
   gold-ish scale. */
.profile-stat-value.tier-bot, .rating-pill.tier-bot { color: #8fb8ff; font-weight: 800; }
.rating-pill {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  margin-left: 2px;
  white-space: nowrap;
  flex-shrink: 0;
}
.rating-pill.tier-wood { background: rgba(156,122,78,0.16); border: 1px solid rgba(156,122,78,0.35); }
.rating-pill.tier-bronze { background: rgba(198,138,84,0.16); border: 1px solid rgba(198,138,84,0.35); }
.rating-pill.tier-silver { background: rgba(168,180,192,0.16); border: 1px solid rgba(168,180,192,0.35); }
.rating-pill.tier-gold { background: rgba(230,185,80,0.16); border: 1px solid rgba(230,185,80,0.35); }
.rating-pill.tier-platinum { background: rgba(111,208,200,0.16); border: 1px solid rgba(111,208,200,0.35); }
.rating-pill.tier-emerald { background: rgba(74,222,128,0.16); border: 1px solid rgba(74,222,128,0.35); }
.rating-pill.tier-diamond { background: rgba(111,168,255,0.16); border: 1px solid rgba(111,168,255,0.35); }
.rating-pill.tier-master { background: rgba(192,132,252,0.16); border: 1px solid rgba(192,132,252,0.35); }
.rating-pill.tier-gm { background: transparent; border: 1px solid #f0c05a; }
.rating-pill.tier-top3 { background: linear-gradient(135deg, rgba(255,215,106,0.28), rgba(255,255,255,0.1)); border: 1px solid rgba(255,215,106,0.65); }
.rating-pill.tier-bot { background: rgba(143,184,255,0.16); border: 1px solid rgba(143,184,255,0.45); }

.gh-section-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 6px 6px; flex-wrap: wrap; }
.gh-section-title { font-size: 13px; color: var(--paper-dim); font-weight: 600; }
.gh-per-page-label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--paper-dim); }
.gh-per-page-label select { padding: 5px 8px; font-size: 13.5px; }
.gh-list-row { display: flex; align-items: center; gap: 12px; padding: 12px 10px; border-radius: 8px; cursor: pointer; }
.gh-list-row:hover { background: var(--hover-bg); }
.gh-list-main { flex: 1; min-width: 0; }
.gh-list-opponent { font-weight: 600; font-size: 15px; }
.gh-list-meta { font-size: 13px; color: var(--paper-dim); margin-top: 2px; }
.gh-list-result { font-size: 13px; color: var(--paper-dim); text-align: right; flex: none; max-width: 42%; }
.gh-rating-delta { display: block; font-size: 12.5px; font-weight: 700; margin-top: 2px; }
.gh-rating-delta.positive { color: var(--good); }
.gh-rating-delta.negative { color: var(--seal-hi); }
.gh-empty { color: var(--paper-dim); text-align: center; padding: 30px 12px; font-size: 14.5px; }
.gh-replay { display: flex; gap: 20px; flex-wrap: wrap; }
.gh-replay-board { flex: 0 0 auto; max-width: 100%; }
.gh-replay-board canvas { display: block; background: var(--wood); border-radius: 6px; max-width: 100%; height: auto; }
.gh-replay-info { flex: 1 1 200px; min-width: 200px; font-size: 14.5px; }
.gh-replay-info .gh-result { font-weight: 600; margin-bottom: 10px; }
.gh-nav-row { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 10px; flex-wrap: wrap; }

footer.credit { max-width: 1400px; margin: 32px auto 0; color: var(--paper-dim); font-size: 14px; }

/* ---- Direct messages (1-1 chat) — same floating panel on every page ---- */
.dm-toggle-btn { position: relative; }
.dm-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  background: var(--seal);
  color: #fff2ea;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  min-width: 16px;
  height: 16px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 3px;
  box-shadow: 0 0 0 2px var(--ink-2);
}
.dm-panel {
  position: fixed;
  bottom: 16px;
  right: 16px;
  width: 320px;
  max-width: calc(100vw - 24px);
  height: 440px;
  max-height: calc(100vh - 32px);
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.45);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 150;
}
.dm-panel-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--line); flex: none; }
.dm-panel-head h3 { margin: 0; font-size: 15px; flex: 1; min-width: 0; font-family: "Noto Serif Thai", Georgia, serif; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-conv-list { flex: 1; overflow-y: auto; padding: 6px; }
.dm-conv-row { display: flex; align-items: center; gap: 10px; padding: 9px 8px; border-radius: 8px; cursor: pointer; }
.dm-conv-row:hover { background: var(--hover-bg); }
.dm-conv-text { flex: 1; min-width: 0; }
.dm-conv-name { font-weight: 600; font-size: 14.5px; }
.dm-conv-preview { font-size: 12.5px; color: var(--paper-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-conv-unread { background: var(--seal); color: #fff2ea; font-size: 11px; font-weight: 700; border-radius: 999px; min-width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; padding: 0 4px; flex: none; }
.dm-thread-log { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.dm-msg-sender { font-size: 11.5px; font-weight: 600; color: var(--paper-faint); margin: 4px 2px 0; }
.dm-msg-sender.mine { align-self: flex-end; }
.dm-msg-sender.theirs { align-self: flex-start; }
.dm-msg { max-width: 80%; padding: 7px 10px; border-radius: 10px; line-height: 1.4; word-break: break-word; }
.dm-msg.mine { align-self: flex-end; background: var(--seal); color: #fff2ea; border-bottom-right-radius: 3px; }
.dm-msg.theirs { align-self: flex-start; background: var(--ink-3); border-bottom-left-radius: 3px; }
.dm-read-receipt { align-self: flex-end; font-size: 11px; color: var(--paper-faint); margin: -2px 2px 0; }
.dm-thread-input-row { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--line); flex: none; }
.dm-thread-input-row input { flex: 1; min-width: 0; background: var(--ink-3); color: var(--paper); border: 1px solid var(--border); border-radius: 6px; padding: 9px 10px; font-family: inherit; font-size: 14.5px; }
.dm-empty { color: var(--paper-dim); text-align: center; padding: 24px 12px; font-size: 14px; }
