/* ============================================================
   Super-Shiritori game site — shared styles
   Landing / Lobby / Room. House palette (dark + orange, pink /
   purple accent). Three-state theme tokens (bare :root = light,
   prefers-color-scheme dark, explicit [data-theme]).
   ============================================================ */

:root {
  color-scheme: light;
  --orange: #F19000;
  --orange-bright: #ff9d1c;
  --orange-ink: #ffffff;
  --pink: #d94f81;
  --purple: #7b4bc4;
  --ai: #3b4a7a;
  --safe: #1f9d57;
  --shu: #d8452f;

  --bg: #f6f1e8;
  --bg-soft: #efe6d6;
  --surface: #ffffff;
  --surface-2: #fbf4e8;
  --surface-3: #f4ead7;
  --border: #e7d8bf;
  --border-2: #dcc8a6;

  --fg: #2c2418;
  --fg-muted: #7a6a51;
  --fg-faint: #a7967b;

  --shadow-sm: 0 1px 2px rgba(80, 50, 10, .06);
  --shadow: 0 2px 6px rgba(80, 50, 10, .08), 0 16px 40px rgba(80, 50, 10, .10);
  --ring: 0 0 0 3px rgba(241, 144, 0, .30);
  --paper-line: rgba(120, 90, 40, .05);
  --petal: rgba(217, 79, 129, .30);
  --seigaiha: rgba(123, 75, 196, .12);
  --font-word: "Kaisei Decol", "Zen Kaku Gothic New", Georgia, serif;
  --bg-decor-opacity: 1;
}

/* Word-display font (see the Settings page's Font picker) - scoped to the
   played-word chip only, not a site-wide font swap, so picking a fun font
   can't break layout elsewhere. */
:root[data-font="rounded"] { --font-word: "M PLUS Rounded 1c", "Zen Kaku Gothic New", sans-serif; }
:root[data-font="handwritten"] { --font-word: "Klee One", "Zen Kaku Gothic New", sans-serif; }
:root[data-font="pixel"] { --font-word: "DotGothic16", "Zen Kaku Gothic New", monospace; }

:root[data-lowercase="true"] .move .word { text-transform: lowercase; }
/* The word bubble already hugs its own text tightly, so aligning text
   inside it was invisible - what actually needs to move is the whole row
   (avatar + bubble + name) over to the right side of the log. */
:root[data-right-align="true"] .move { justify-content: flex-end; }
:root[data-focus-mode="true"] .chat,
:root[data-focus-mode="true"] #specWrap { display: none !important; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --orange: #F19000; --orange-bright: #ffb04a; --orange-ink: #1a1206;
    --pink: #ff8fb5; --purple: #b98cf0; --ai: #8fa6e0;
    --safe: #6fcf97; --shu: #ff6f59;
    --bg: #14100c; --bg-soft: #1b1610;
    --surface: #1e1913; --surface-2: #262019; --surface-3: #2f2619;
    --border: #372b1d; --border-2: #46371f;
    --fg: #f4efe6; --fg-muted: #b3a48f; --fg-faint: #7e7059;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 2px 6px rgba(0, 0, 0, .4), 0 22px 55px rgba(0, 0, 0, .55);
    --ring: 0 0 0 3px rgba(241, 144, 0, .32);
    --paper-line: rgba(255, 220, 160, .035);
    --petal: rgba(255, 143, 181, .22);
    --seigaiha: rgba(185, 140, 240, .10);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --orange: #F19000; --orange-bright: #ffb04a; --orange-ink: #1a1206;
  --pink: #ff8fb5; --purple: #b98cf0; --ai: #8fa6e0;
  --safe: #6fcf97; --shu: #ff6f59;
  --bg: #14100c; --bg-soft: #1b1610;
  --surface: #1e1913; --surface-2: #262019; --surface-3: #2f2619;
  --border: #372b1d; --border-2: #46371f;
  --fg: #f4efe6; --fg-muted: #b3a48f; --fg-faint: #7e7059;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 2px 6px rgba(0, 0, 0, .4), 0 22px 55px rgba(0, 0, 0, .55);
  --ring: 0 0 0 3px rgba(241, 144, 0, .32);
  --paper-line: rgba(255, 220, 160, .035);
  --petal: rgba(255, 143, 181, .22);
  --seigaiha: rgba(185, 140, 240, .10);
}

/* Colour Blind Mode: swaps the red/green pair (--shu/--safe) for a blue/
   orange pair that reads distinctly under the common deuteranopia/
   protanopia confusions - one override block for both themes, so it must
   come after both theme blocks above to win at equal specificity. Remaps
   every accent role (not just the life-pip red/green) to the Okabe-Ito
   palette - a real research-backed colorblind-safe 8-colour set, chosen so
   every role stays visually distinct under protanopia/deuteranopia/
   tritanopia, not just a single red/green swap. */
:root[data-colorblind="true"] {
  --safe: #009e73;         /* was green - bluish green */
  --shu: #d55e00;          /* was red - vermillion */
  --orange: #e69f00;       /* brand accent - Okabe-Ito orange, close to the real one already */
  --orange-bright: #f0c04a;
  --pink: #cc79a7;         /* was pink - reddish purple */
  --purple: #56b4e9;       /* was purple - sky blue */
  --ai: #56b4e9;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; min-height: 100vh; position: relative;
  background: var(--bg);
  color: var(--fg);
  font-family: "Zen Kaku Gothic New", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
  line-height: 1.6; -webkit-font-smoothing: antialiased;
}
/* Decorative layer split out from the solid --bg colour so Background
   Opacity (Settings > Display) can fade the texture without ever fading
   actual page content/contrast. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(1200px 520px at 50% -10%, var(--bg-soft), transparent 60%),
    repeating-linear-gradient(0deg, transparent 0 27px, var(--paper-line) 27px 28px);
  opacity: var(--bg-decor-opacity);
}
/* Paper grain - was landing-page-only (.lwrap::before), now everywhere the
   ruled lines/glow above are, so every page reads as the same textured
   paper instead of just the hero. Same opacity slider, same reasoning. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: calc(var(--bg-decor-opacity) * .09); mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .9 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}
h1, h2, h3, .display { font-family: "Kaisei Decol", "Zen Kaku Gothic New", Georgia, serif; }
a { color: var(--pink); text-underline-offset: 3px; }
a.external { color: var(--purple); }
button { font-family: inherit; }
img { max-width: 100%; }
.tnums { font-variant-numeric: tabular-nums; }
[hidden] { display: none !important; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 22px; }

/* ---- mascot logo (bot avatar / og-image.png) ---- */
.tile-logo { display: block; border-radius: 22%; object-fit: cover; }

/* ---- wordmark ---- */
.wordmark { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--fg); }
.wordmark .txt { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.06rem; letter-spacing: -.01em; white-space: nowrap; }
.wordmark .txt .x { color: var(--orange); }
.wordmark.mini { gap: 9px; }
.wordmark.mini .mark { width: 30px; height: 30px; }
.wordmark.mini .leave { font-weight: 800; font-size: .86rem; color: var(--fg-muted); }
.wordmark.mini:hover .leave { color: var(--fg); }

/* ---- theme toggle ---- */
.theme-toggle {
  appearance: none; border: 1px solid var(--border-2); background: var(--surface); color: var(--fg);
  width: 38px; height: 38px; border-radius: 999px; cursor: pointer; font-size: 1rem;
  display: grid; place-items: center; flex-shrink: 0;
  transition: transform .15s ease, border-color .15s ease;
}
.theme-toggle:hover { transform: translateY(-1px); border-color: var(--purple); }
.theme-toggle:focus-visible { outline: none; box-shadow: var(--ring); }
.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }
:root[data-theme="dark"] .theme-toggle .sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .sun { display: none; }
}

/* ================================================================
   Landing
   ================================================================ */
.lwrap {
  position: relative; overflow: hidden; min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 64px 22px;
}
.landing-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; justify-content: flex-end; padding: 16px 22px;
}

.seigaiha {
  position: absolute; left: 0; right: 0; bottom: 0; height: 46%; pointer-events: none; opacity: .9;
  background:
    radial-gradient(circle at 20px 40px, transparent 12px, var(--seigaiha) 13px 14px, transparent 15px),
    radial-gradient(circle at 40px 40px, transparent 12px, var(--seigaiha) 13px 14px, transparent 15px),
    radial-gradient(circle at 0px 40px, transparent 12px, var(--seigaiha) 13px 14px, transparent 15px);
  background-size: 40px 40px;
  -webkit-mask-image: linear-gradient(to top, #000, transparent);
          mask-image: linear-gradient(to top, #000, transparent);
}
.petals { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.petals i {
  position: absolute; top: -8vh; width: 12px; height: 10px;
  background: var(--petal); border-radius: 12px 1px 12px 1px; animation: fall linear infinite;
}
.petals i:nth-child(3n) { width: 9px; height: 8px; opacity: .7; }
.petals i:nth-child(1){left:5%;animation-duration:15s;animation-delay:-1s}
.petals i:nth-child(2){left:14%;animation-duration:19s;animation-delay:-6s}
.petals i:nth-child(3){left:24%;animation-duration:13s;animation-delay:-3s}
.petals i:nth-child(4){left:33%;animation-duration:21s;animation-delay:-9s}
.petals i:nth-child(5){left:44%;animation-duration:16s;animation-delay:-2s}
.petals i:nth-child(6){left:54%;animation-duration:18s;animation-delay:-11s}
.petals i:nth-child(7){left:63%;animation-duration:14s;animation-delay:-5s}
.petals i:nth-child(8){left:72%;animation-duration:20s;animation-delay:-8s}
.petals i:nth-child(9){left:81%;animation-duration:15s;animation-delay:-13s}
.petals i:nth-child(10){left:89%;animation-duration:17s;animation-delay:-4s}
.petals i:nth-child(11){left:95%;animation-duration:22s;animation-delay:-15s}
.petals i:nth-child(12){left:38%;animation-duration:23s;animation-delay:-18s}
@keyframes fall {
  0% { transform: translateY(0) translateX(0) rotate(0); }
  50% { transform: translateY(52vh) translateX(34px) rotate(180deg); }
  100% { transform: translateY(108vh) translateX(-14px) rotate(360deg); }
}

.ticker {
  position: absolute; left: 0; right: 0; top: 7%; z-index: 1; pointer-events: none;
  display: flex; align-items: center; gap: 18px; padding: 12px clamp(14px, 4vw, 60px);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  background: linear-gradient(to bottom, rgba(241, 144, 0, .06), transparent);
}
.ticker-label {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px; text-transform: uppercase;
  letter-spacing: .12em; font-size: .64rem; font-weight: 800; color: var(--fg-muted);
}
.ticker-label i { width: 7px; height: 7px; border-radius: 50%; background: var(--safe); animation: blink 1.6s steps(1) infinite; }
.ticker-label b { color: var(--orange); font-family: "Kaisei Decol", serif; font-size: .95rem; letter-spacing: 0; }
.ticker-view {
  flex: 1; min-width: 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8% 92%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 8% 92%, transparent);
}
.ticker-tape {
  display: inline-block; white-space: nowrap; will-change: transform;
  font-family: "Kaisei Decol", serif; font-size: clamp(1.1rem, 2.6vw, 1.7rem);
  color: var(--fg-muted);
}
.ticker-tape .w b { color: var(--orange); font-weight: 700; }
.ticker-tape .w .t { color: var(--pink); }
.ticker-tape .arr { color: var(--border-2); margin: 0 .5em; }
.ticker-tape .cursor { color: var(--orange); font-weight: 700; animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.l-card {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 20px; max-width: 380px; width: 100%;
}
.l-card .mark { width: 62px; height: 62px; }
.l-card h1 {
  margin: 0; font-size: clamp(2rem, 7.5vw, 2.9rem); line-height: 1.02;
  letter-spacing: -.03em; font-weight: 700; white-space: nowrap;
}
.l-card h1 .x { color: var(--orange); }
.l-card .tag { margin: 0; color: var(--fg-muted); font-size: 1.02rem; }
.l-card .tag .jp { color: var(--fg-faint); margin-left: .3em; }

.btn-play {
  width: 100%; border: 0; border-radius: 15px; cursor: pointer; padding: 1.05rem 1.4rem;
  font-size: 1.15rem; font-weight: 900; color: var(--orange-ink); background: var(--orange);
  box-shadow: 0 4px 0 rgba(120, 60, 10, .3); transition: transform .12s ease;
  text-decoration: none; text-align: center;
}
.btn-play:hover { transform: translateY(-2px); background: var(--orange-bright); }
/* Pressed = pushed down INTO its own flat shadow, not just a hover lift -
   every other button on the web lifts on hover and nothing ever reacts to
   an actual click. This one does: the shadow visibly compresses as you
   press it, like a real paper tab. */
.btn-play:active { transform: translateY(3px); box-shadow: none; }

/* Landing revamp: warm glow, edge kanji, ornament, button sheen */
.l-kanji {
  position: absolute; top: 50%; z-index: 1; pointer-events: none; user-select: none;
  writing-mode: vertical-rl; font-family: "Kaisei Decol", serif; font-weight: 700;
  font-size: clamp(2.4rem, 6vw, 4.6rem); letter-spacing: .3em; color: var(--fg-faint); opacity: .13;
  transform: translateY(-50%);
}
.l-kanji-l { left: clamp(14px, 5vw, 80px); }
.l-kanji-r { right: clamp(14px, 5vw, 80px); }
.l-orn { display: flex; align-items: center; gap: 10px; width: 150px; margin: -6px 0; }
.l-orn i { flex: 1; height: 1px; background: linear-gradient(to right, transparent, var(--border-2)); }
.l-orn i:last-child { background: linear-gradient(to left, transparent, var(--border-2)); }
.l-orn b { width: 7px; height: 7px; background: var(--orange); transform: rotate(45deg); border-radius: 1px; }
.l-card .mark { animation: markFloat 5s ease-in-out infinite; filter: drop-shadow(0 5px 0 rgba(120, 60, 10, .28)); }
@keyframes markFloat { 50% { transform: translateY(-5px) rotate(-2deg); } }
.btn-play { position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; gap: .6rem; }
.btn-play::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg); transition: left .55s ease;
}
.btn-play:hover::after { left: 130%; }
.btn-play .arr { transition: transform .15s ease; }
.btn-play:hover .arr { transform: translateX(4px); }
/* Texture: ink enso ring, mirrored waves along the top - the paper grain
   itself now lives on body::after (site-wide), see near the top of this file. */

.seigaiha.top {
  top: 0; bottom: auto; height: 26%; opacity: .5; transform: scaleY(-1);
}
@media (max-width: 760px) { .l-kanji { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .l-card .mark { animation: none; }
}

.l-auth {
  width: 100%; background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: var(--shadow); padding: 18px; display: flex; flex-direction: column; gap: 9px;
}
.l-auth .head {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .11em; color: var(--purple);
  font-weight: 800; margin: 2px 0 4px;
}
.authbtn {
  width: 100%; border-radius: 11px; padding: .7rem 1rem; cursor: pointer; font-size: .95rem;
  font-weight: 700; color: var(--fg); border: 1px solid var(--border-2); background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  transition: transform .12s ease, border-color .12s ease; text-decoration: none;
}
.authbtn:hover { transform: translateY(-1px); border-color: var(--purple); }
.authbtn .ico { width: 18px; height: 18px; flex: 0 0 auto; display: block; }
.authbtn .ico-slot { display: contents; }
.authbtn[disabled] { opacity: .5; pointer-events: none; }
.authbtn.guest { background: none; border-style: dashed; color: var(--fg-muted); font-weight: 600; }
.divider { display: flex; align-items: center; gap: 10px; color: var(--fg-faint); font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.auth-error { font-size: .82rem; color: var(--shu); margin: 0; }

.auth-toggle {
  background: none; border: 0; cursor: pointer; color: var(--fg-muted);
  font-size: .88rem; font-weight: 700; padding: 2px 4px;
  display: inline-flex; align-items: center; gap: 3px;
}
.auth-toggle:hover { color: var(--purple); }
.auth-toggle span { transition: transform .12s ease; }
.auth-toggle:hover span { transform: translateX(2px); }

.l-auth { animation: authIn .16s ease; }
@keyframes authIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

.landing-foot {
  position: absolute; left: 0; right: 0; bottom: 18px; z-index: 3;
  display: flex; flex-flow: row wrap; align-items: center; justify-content: center; gap: 6px 18px; padding: 0 16px;
}
.ai-note {
  background: none; border: 0; cursor: pointer; color: var(--fg-faint);
  font-size: .76rem; text-decoration: underline dotted; text-underline-offset: 3px;
}
.ai-note:hover { color: var(--fg-muted); }
.other-projects { font-size: .76rem; font-weight: 600; text-decoration: none; }
.other-projects:hover { text-decoration: underline; }

.drawer.ai-modal { max-width: 560px; }
.ai-body p { margin: 0 0 12px; line-height: 1.55; font-size: .88rem; color: var(--fg-muted); }
.ai-body p:last-child { margin-bottom: 0; }
.ai-agree {
  display: flex; align-items: center; gap: 8px; margin: 16px 0 4px;
  font-size: .85rem; font-weight: 700; color: var(--fg); cursor: pointer;
}
.ai-agree input { width: 17px; height: 17px; accent-color: var(--orange); cursor: pointer; }
.drawer.ai-modal .actions .btn-create[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }

/* ================================================================
   Top bar (lobby + room)
   ================================================================ */
.topbar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(8px); border-bottom: 1px solid var(--border);
}
.topbar .row { max-width: 1180px; margin: 0 auto; padding: 10px 22px; display: flex; align-items: center; gap: 16px; }
.topbar .mark { width: 34px; height: 34px; flex: 0 0 auto; }
/* the match bar sits above the wider room grid, so it gets the same cap */
.match-bar .row { max-width: 1680px; justify-content: space-between; }

.nav { display: flex; gap: 2px; margin-left: 8px; }
.nav a, .nav button, .nav .wip {
  border: 0; background: none; cursor: pointer; color: var(--fg-muted); font-size: .9rem;
  font-weight: 700; padding: 8px 13px; border-radius: 9px; text-decoration: none;
  display: inline-flex; align-items: center; gap: 7px;
}
.nav a:hover, .nav button:hover { color: var(--fg); background: var(--surface-2); }
.nav .on { color: var(--orange); background: color-mix(in srgb, var(--orange) 14%, transparent); }
.nav .wip { color: var(--fg-faint); cursor: not-allowed; }
.nav .wip:hover { background: none; color: var(--fg-faint); }
.wip-tag {
  font-size: .58rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--purple); border: 1px solid var(--border-2); border-radius: 999px; padding: 1px 5px;
}
.wip-tag + .wip-tag { margin-left: 3px; }

.tb-right { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.currency {
  display: flex; align-items: center; gap: 6px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 0 12px 0 10px; height: 38px; flex-shrink: 0; font-weight: 800; font-size: .86rem;
}
.currency svg { width: 15px; height: 15px; display: block; }
.currency.bump { animation: currency-bump .32s ease; }
@keyframes currency-bump {
  0% { transform: scale(1); }
  35% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Coin/petal pop: spawned at a fixed viewport position (see SS.popCurrency),
   glides a soft two-segment arc up into the topbar pill, then removes
   itself. --mx/--my is the arc's midpoint (offset from the start point),
   --dx/--dy is the final offset (the pill's centre) - both set per-call in
   JS from the actual on-screen distance, so the curve always lands exactly
   on the pill no matter where the action happened. */
.currency-pop {
  position: fixed; z-index: 90; width: 16px; height: 16px; pointer-events: none;
  transform: translate(-50%, -50%);
  animation-name: currency-pop;
  animation-timing-function: cubic-bezier(.22, .61, .36, 1);
  animation-fill-mode: forwards;
}
.currency-pop svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 1px 3px rgba(0,0,0,.4)); }
@keyframes currency-pop {
  0%   { transform: translate(-50%, -50%) scale(.3) rotate(0deg); opacity: 0; }
  10%  { transform: translate(-50%, -50%) scale(1) rotate(20deg); opacity: 1; }
  60%  { transform: translate(calc(-50% + var(--mx)), calc(-50% + var(--my))) scale(.85) rotate(200deg); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.25) rotate(340deg); opacity: 0; }
}

/* The "+n" badge - always shown once, a beat behind the glyphs, so the
   actual amount earned stays legible regardless of the (capped) glyph
   count riding alongside it. Rides the same arc shape, no spin (text
   spinning is just noise), settling in with a light overshoot. */
.currency-pop-label {
  position: fixed; z-index: 91; pointer-events: none; transform: translate(-50%, -50%);
  font-weight: 900; font-size: 1rem; text-shadow: 0 1px 4px rgba(0,0,0,.45);
  white-space: nowrap;
  animation-name: currency-pop-label;
  animation-timing-function: cubic-bezier(.22, .61, .36, 1);
  animation-fill-mode: forwards;
}
@keyframes currency-pop-label {
  0%   { transform: translate(-50%, -50%) scale(.7); opacity: 0; }
  14%  { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  60%  { transform: translate(calc(-50% + var(--mx)), calc(-50% + var(--my))) scale(1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.55); opacity: 0; }
}

/* Discovery celebration: a ring of stars bursting outward from where the
   word landed, plus a held label - rarer and bigger than the coin/petal
   pop, since a Discovery is a one-time-ever record, not a per-word grind. */
.discovery-star {
  position: fixed; z-index: 95; width: 20px; height: 20px; pointer-events: none;
  transform: translate(-50%, -50%);
  animation: discovery-burst 1.1s cubic-bezier(.2, .8, .3, 1) forwards;
}
.discovery-star svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 2px 5px rgba(0,0,0,.4)); }
@keyframes discovery-burst {
  0%   { transform: translate(-50%, -50%) scale(.2) rotate(0deg); opacity: 0; }
  15%  { transform: translate(-50%, -50%) scale(1.3) rotate(60deg); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.3) rotate(420deg); opacity: 0; }
}
.discovery-label {
  position: fixed; z-index: 96; pointer-events: none; text-align: center;
  transform: translate(-50%, -50%); white-space: nowrap;
  animation: discovery-label-pop 1.6s cubic-bezier(.2, .8, .3, 1) forwards;
}
.discovery-label .big {
  display: block; font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.3rem;
  color: var(--orange); text-shadow: 0 2px 10px rgba(0,0,0,.5);
}
.discovery-label .small {
  display: block; font-size: .85rem; font-weight: 700; color: var(--fg); text-transform: capitalize;
  margin-top: 2px; text-shadow: 0 2px 8px rgba(0,0,0,.5);
}
@keyframes discovery-label-pop {
  0%   { transform: translate(-50%, -40%) scale(.5); opacity: 0; }
  15%  { transform: translate(-50%, -65%) scale(1.08); opacity: 1; }
  25%  { transform: translate(-50%, -65%) scale(1); opacity: 1; }
  80%  { transform: translate(-50%, -85%) scale(1); opacity: 1; }
  100% { transform: translate(-50%, -105%) scale(.9); opacity: 0; }
}

/* Category-hit toast: small and ambient, unlike the discovery burst above -
   a played word counting toward a Dictionaries category is common, not a
   one-time record, so this stays a quick, non-blocking pill. */
.cat-toast { display: flex; align-items: center; gap: 6px; pointer-events: none; }
.cat-toast-who {
  font-size: .74rem; font-weight: 700; color: var(--fg-muted);
  opacity: 0; transition: opacity .2s ease;
}
.cat-toast.in .cat-toast-who { opacity: 1; }
.cat-toast-pill {
  display: inline-flex; align-items: center; gap: 6px; background: var(--surface);
  border: 1px solid var(--border-2); border-radius: 999px; padding: 5px 12px 5px 6px;
  font-size: .8rem; font-weight: 700; color: var(--fg); box-shadow: var(--shadow-sm);
  opacity: 0; transform: translateY(6px) scale(.94); transition: opacity .2s ease, transform .2s ease;
}
.cat-toast.in .cat-toast-pill { opacity: 1; transform: translateY(0) scale(1); }
.cat-toast-icon { width: 18px; height: 18px; color: var(--orange); flex: 0 0 auto; }
.cat-toast-icon svg { width: 100%; height: 100%; display: block; }
.cat-toast-new {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--orange-ink);
  background: var(--orange); border-radius: 999px; padding: 1px 6px; margin-left: 2px;
}

/* ---- "Now Playing" widget (Settings > Audio > Music Source: YouTube/custom) ---- */
.music-widget {
  position: fixed; right: 16px; bottom: 16px; z-index: 70; width: 220px; min-width: 150px; max-width: 480px;
  background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: var(--shadow); overflow: hidden; touch-action: none;
}
.mw-head {
  display: flex; align-items: center; justify-content: space-between; padding: 6px 10px;
  background: var(--surface-2); border-bottom: 1px solid var(--border); cursor: move;
  font-size: .74rem; font-weight: 800; color: var(--fg-muted); text-transform: uppercase; letter-spacing: .03em;
  user-select: none;
}
.mw-resize {
  position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize;
  background:
    linear-gradient(135deg, transparent 0 40%, var(--border-2) 40% 46%, transparent 46% 60%, var(--border-2) 60% 66%, transparent 66%);
}
.mw-min {
  all: unset; cursor: pointer; width: 18px; height: 18px; display: grid; place-items: center;
  border-radius: 5px; color: var(--fg-muted); font-weight: 900; line-height: 1;
}
.mw-min:hover { background: var(--surface); color: var(--fg); }
.mw-body { padding: 8px; }
.music-widget.mw-collapsed .mw-body { display: none; }
.music-widget #mwYtHost { width: 100%; aspect-ratio: 200 / 113; border-radius: 8px; overflow: hidden; }
.music-widget iframe { display: block; width: 100%; height: 100%; border: 0; }
.mw-track {
  font-size: .76rem; color: var(--fg-muted); margin-bottom: 8px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.mw-controls { display: flex; align-items: center; justify-content: center; gap: 10px; }
.mw-controls button {
  all: unset; cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 999px; background: var(--surface-2); color: var(--fg); font-size: .7rem;
}
.mw-controls button:hover { background: var(--orange); color: var(--orange-ink); }
.mw-controls .mw-play { width: 36px; height: 36px; font-size: .8rem; }

.profile-chip {
  display: flex; align-items: center; gap: 8px; cursor: pointer; border: 1px solid var(--border-2);
  background: var(--surface); border-radius: 999px; padding: 0 12px 0 3px; height: 38px; flex-shrink: 0;
  font-weight: 700; font-size: .88rem; color: var(--fg); text-decoration: none;
}
/* A long display name has nowhere to go in this fixed-height pill - it was
   wrapping onto a second line instead (the "Guest-
A36C" bug), stretching
   the pill taller than every other topbar control next to it. One line,
   cut off with an ellipsis past a sensible width, same as everywhere else
   a name is shown in a tight space. */
.profile-chip #profileName {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px;
}
.profile-chip:hover { border-color: var(--purple); }
.avatar {
  width: 30px; height: 30px; border-radius: 999px; flex: 0 0 auto; display: grid; place-items: center;
  font-weight: 900; font-size: .82rem; color: var(--orange-ink); background: var(--orange);
  object-fit: cover; overflow: visible; position: relative;
}
.avatar img { border-radius: 999px; }
.crown-badge {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  width: 15px; height: 12px; fill: #f4c430; stroke: #b8860b; stroke-width: 1; stroke-linejoin: round;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.55)); pointer-events: none;
}
.prof-head .avatar .crown-badge { width: 28px; height: 22px; top: -17px; }
.user-card .uc-av .crown-badge { width: 21px; height: 17px; top: -13px; }
.pm-head .avatar .crown-badge { width: 18px; height: 14px; top: -11px; }
.move .avatar .crown-badge { width: 14px; height: 11px; top: -8px; }
.avatar.gld { background: var(--orange); color: var(--orange-ink); }
.avatar.pnk { background: var(--pink); color: #2c1220; }
.avatar.ind { background: var(--ai); color: #fff; }
.avatar.grn { background: var(--safe); color: #06301c; }
.avatar.prp { background: var(--purple); color: #1c1030; }

/* ---- profile dropdown (mounts on #profileChip) ---- */
.profile-menu {
  position: fixed; z-index: 80; width: 220px; background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 14px; box-shadow: var(--shadow); padding: 6px; font-size: .88rem;
}
.pm-head { display: flex; align-items: center; gap: 10px; padding: 8px 8px 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.pm-head .avatar { width: 36px; height: 36px; font-size: .92rem; }
.pm-name { font-weight: 800; color: var(--fg); }
.pm-kind { font-size: .72rem; color: var(--fg-muted); }
.pm-row {
  display: flex; align-items: center; gap: 6px; padding: 8px; border-radius: 9px; color: var(--fg);
  text-decoration: none; font-weight: 700; cursor: pointer; background: none; border: 0; width: 100%; text-align: left;
}
.pm-row:hover { background: var(--surface-2); }
.pm-row.pm-static { color: var(--fg-muted); font-weight: 600; cursor: default; }
.pm-row.pm-static:hover { background: none; }
.pm-row.pm-wip { color: var(--fg-faint); cursor: not-allowed; }
.pm-row.pm-wip:hover { background: none; }
.pm-row.pm-complain { color: var(--shu); }
.pm-row.pm-danger { color: var(--shu); border-top: 1px solid var(--border); margin-top: 4px; border-radius: 0 0 9px 9px; }
.pm-row.pm-danger:hover { background: color-mix(in srgb, var(--shu) 12%, transparent); }

/* ---- other-player mini-card (SS.showUserCard) ---- */
.user-card {
  position: fixed; z-index: 85; width: 220px; background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 14px; box-shadow: var(--shadow); padding: 16px 14px 14px; text-align: center;
}
.user-card .uc-close {
  position: absolute; top: 8px; right: 8px; width: 22px; height: 22px; border-radius: 999px; border: 0;
  background: var(--surface-2); color: var(--fg-muted); cursor: pointer; font-size: 1rem; line-height: 1;
}
.user-card .uc-close:hover { color: var(--fg); }
.user-card .uc-av { width: 52px; height: 52px; font-size: 1.2rem; margin: 0 auto 8px; }
.user-card .uc-name { font-weight: 800; font-size: 1rem; color: var(--fg); }
.user-card .uc-kind { font-size: .74rem; color: var(--fg-muted); margin-top: 2px; }
.user-card .uc-actions { display: flex; gap: 6px; margin: 12px 0; }
.uc-btn {
  flex: 1; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 9px; padding: 7px 6px; font-size: .76rem; font-weight: 700; cursor: pointer;
}
.uc-btn:hover { border-color: var(--purple); }
.uc-btn.on { background: color-mix(in srgb, var(--shu) 16%, transparent); border-color: var(--shu); color: var(--shu); }
.uc-btn.wip, .uc-btn:disabled { opacity: .5; cursor: not-allowed; }
.uc-view {
  display: block; text-align: center; border: 0; border-radius: 10px; padding: 8px; font-weight: 800;
  font-size: .86rem; color: var(--orange-ink); background: var(--orange); text-decoration: none;
}
.uc-view:hover { background: var(--orange-bright); }

/* ---- profile page ---- */
.prof-head { display: flex; align-items: flex-start; gap: 16px; padding-top: 26px; }
.prof-head .avatar { width: 72px; height: 72px; font-size: 1.6rem; flex: 0 0 auto; }
.prof-id { flex: 1; min-width: 0; }
.prof-name { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.5rem; color: var(--fg); }
.prof-bio { margin-top: 8px; color: var(--fg-muted); font-size: .92rem; max-width: 480px; }
.prof-bio-edit { margin-top: 8px; max-width: 480px; }
.prof-bio-edit textarea {
  width: 100%; min-height: 60px; resize: vertical; border: 1px solid var(--border-2); background: var(--surface-2);
  color: var(--fg); border-radius: 10px; padding: .6rem .7rem; font: inherit; font-size: .9rem;
}
.prof-bio-edit textarea:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.prof-bio-actions { display: flex; gap: 8px; margin-top: 8px; }
.bio-editable {
  width: 100%; min-height: 60px; border: 1px solid var(--border-2); background: var(--surface-2);
  color: var(--fg); border-radius: 10px; padding: .6rem .7rem; font: inherit; font-size: .9rem;
  white-space: pre-wrap; word-break: break-word;
}
.bio-editable:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.bio-editable:empty:before { content: attr(data-placeholder); color: var(--fg-faint); }
.bio-hint { margin: 6px 0 0; font-size: .74rem; color: var(--fg-faint); }
.prof-bio-edit .swatches { margin-top: 6px; }
.prof-head-actions { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.prof-meta { display: flex; gap: 16px; flex-wrap: wrap; color: var(--fg-muted); font-size: .82rem; margin: 14px 0 22px; }

.prof-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 20px; flex-wrap: wrap; }
.prof-tabs button {
  border: 0; background: none; cursor: pointer; color: var(--fg-muted); font-size: .9rem; font-weight: 700;
  padding: 10px 14px; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.prof-tabs button:hover { color: var(--fg); }
.prof-tabs button.on { color: var(--orange); border-bottom-color: var(--orange); }

.prof-panel.wip-panel {
  text-align: center; color: var(--fg-faint); font-size: .95rem;
  border: 1px dashed var(--border-2); border-radius: 14px; padding: 48px 22px; background: var(--surface);
}

/* ================================================================
   Lobby
   ================================================================ */
.lobby-wrap { padding-top: 26px; padding-bottom: 56px; }
.lobby-head { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 18px; }
.lobby-head h2 { margin: 0; font-size: 1.7rem; letter-spacing: -.02em; }
.lobby-head p { margin: 3px 0 0; color: var(--fg-muted); font-size: .92rem; }

.btn-create {
  border: 0; cursor: pointer; border-radius: 12px; padding: .8rem 1.3rem; font-weight: 900; font-size: 1rem;
  color: var(--orange-ink); background: var(--orange); box-shadow: 0 3px 0 rgba(120, 60, 10, .3);
  display: inline-flex; gap: .5rem; align-items: center; transition: transform .12s ease; text-decoration: none;
}
.btn-create:hover { transform: translateY(-2px); background: var(--orange-bright); }
.btn-create:active { transform: translateY(3px); box-shadow: none; }
.btn-create[disabled] { opacity: .55; pointer-events: none; box-shadow: none; }
.btn-secondary {
  border: 1px solid var(--border-2); cursor: pointer; border-radius: 12px; padding: .8rem 1.3rem; font-weight: 900; font-size: 1rem;
  color: var(--fg); background: var(--surface); display: inline-flex; gap: .5rem; align-items: center;
  transition: transform .12s ease, border-color .12s ease; text-decoration: none;
}
.btn-secondary:hover { transform: translateY(-2px); border-color: var(--orange); color: var(--orange); }
.lobby-head-actions { display: flex; gap: 10px; flex: 0 0 auto; }

.list-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 2px 10px; color: var(--fg-muted); font-size: .82rem; font-weight: 700; }
.btn-refresh {
  border: 1px solid var(--border-2); background: var(--surface); color: var(--fg-muted);
  font-size: .78rem; font-weight: 700; padding: 5px 12px; border-radius: 999px; cursor: pointer;
}
.btn-refresh:hover { color: var(--fg); border-color: var(--purple); }

.rooms { display: flex; flex-direction: column; gap: 10px; }
.room {
  display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 12px 14px;
  box-shadow: var(--shadow-sm); transition: transform .1s ease, border-color .12s ease;
  text-decoration: none; color: var(--fg);
}
.room:hover { transform: translateY(-1px); border-color: var(--border-2); }
.room .host-av { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; font-weight: 900; font-size: 1rem; color: #fff; background: var(--ai); overflow: hidden; object-fit: cover; }
.room .rtitle { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.room .rtitle .rn { font-weight: 800; font-size: 1rem; }
.room .rsub { display: flex; align-items: center; gap: 7px; margin-top: 5px; flex-wrap: wrap; }
.chip { font-size: .72rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; background: var(--surface-3); color: var(--fg-muted); }
.chip.mode-c { background: color-mix(in srgb, var(--orange) 15%, transparent); color: var(--orange); }
.chip.mode-o { background: color-mix(in srgb, var(--purple) 18%, transparent); color: var(--purple); }
.chip.live { background: color-mix(in srgb, var(--safe) 16%, transparent); color: var(--safe); }
.chip .live-dot { display: inline-block; width: 6px; height: 6px; border-radius: 999px; background: currentColor; margin-right: 4px; vertical-align: 1px; }
.room .count { font-weight: 800; font-size: .82rem; color: var(--fg-muted); }
.room .count b { color: var(--fg); }
.room .rcta { display: flex; gap: 7px; align-items: center; }
.btn-join { border: 0; cursor: pointer; border-radius: 10px; padding: .58rem 1.3rem; font-weight: 900; font-size: .88rem; color: var(--orange-ink); background: var(--orange); box-shadow: 0 2px 0 rgba(120, 60, 10, .3); transition: transform .1s ease, box-shadow .1s ease; text-decoration: none; }
.btn-join:hover { transform: translateY(-1px); background: var(--orange-bright); }
.btn-join:active { transform: translateY(2px); box-shadow: none; }
.btn-spec { border: 1px solid var(--border-2); cursor: pointer; border-radius: 10px; padding: .58rem 1rem; font-weight: 800; font-size: .84rem; color: var(--fg-muted); background: var(--surface-2); display: inline-flex; align-items: center; gap: 5px; text-decoration: none; }
.btn-spec:hover { color: var(--fg); border-color: var(--purple); }
.btn-join[disabled], .btn-spec[disabled] { opacity: .5; pointer-events: none; }

.empty-state {
  text-align: center; color: var(--fg-muted); font-size: .95rem;
  border: 1px dashed var(--border-2); border-radius: 14px; padding: 40px 22px; background: var(--surface);
}

.foot { text-align: center; color: var(--fg-faint); font-size: .78rem; padding: 28px 0 8px; }

/* ---- Info tooltip (reusable anywhere - SS.wireInfoTips() wires it up) ---- */
.info-wrap { position: relative; display: inline-flex; vertical-align: middle; }
.info-btn {
  width: 15px; height: 15px; border-radius: 999px; border: 1px solid var(--border-2);
  background: var(--surface-2); color: var(--fg-muted); font-size: .66rem; font-weight: 800; font-style: italic;
  font-family: Georgia, "Times New Roman", serif; line-height: 1; cursor: pointer; display: grid; place-items: center;
  padding: 0;
}
.info-btn:hover, .info-wrap.open .info-btn { color: var(--fg); border-color: var(--purple); }
.info-tip {
  /* left is set in px by SS.wireInfoTips (clamped to the viewport) - no
     CSS transform/centering here, so a horizontally-clamped tip never
     fights a translateX(-50%) trying to re-center it off-screen. */
  position: absolute; z-index: 70; bottom: calc(100% + 8px);
  width: max-content; max-width: 240px; background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 10px; box-shadow: var(--shadow); padding: 9px 11px; font-size: .78rem; font-weight: 500;
  color: var(--fg-muted); text-align: left; line-height: 1.35; opacity: 0; pointer-events: none;
  transition: opacity .12s ease;
}
.info-wrap.open .info-tip { opacity: 1; pointer-events: auto; }
/* Flipped when there isn't room above (SS.wireInfoTips checks on open). */
.info-wrap.flip-down .info-tip { bottom: auto; top: calc(100% + 8px); }

/* ---- Words page ---- */
/* minmax(0, 1fr), not plain 1fr: a plain 1fr track grows to fit its widest
   unbroken content, so one very long word (the Longest Word tile) stretched
   the whole grid past the screen. */
.wstats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }
.wstats .card { min-width: 0; }
.wstats .card .v { overflow-wrap: anywhere; }
/* A long word gets its own full-width tile (see SS.fitLongWord) and wraps
   inside it instead of forcing the layout wider. */
.wstats .card.longword { grid-column: 1 / -1; }
.wstats .card.longword .v { line-height: 1.3; }
.wstats .card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 14px; text-align: center; box-shadow: var(--shadow-sm);
}
.wstats .card .v { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.5rem; color: var(--orange); }
.wstats .card .k { margin-top: 4px; font-size: .72rem; color: var(--fg-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }

/* Its own full-width bar, not a box - a "word" here can run 300+ characters
   (WORD_MAX = 500), which doesn't fit a narrow stat card. overflow-wrap
   lets a single unbroken run of characters wrap mid-word instead of
   overflowing or forcing a horizontal scroll. */
.wlongest {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 16px; margin-bottom: 22px; box-shadow: var(--shadow-sm);
}
.wlongest .k { flex: 0 0 auto; font-size: .72rem; color: var(--fg-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; display: flex; align-items: center; gap: 5px; }
.wlongest .v {
  flex: 1; min-width: 0; font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.1rem;
  color: var(--orange); text-transform: capitalize; overflow-wrap: anywhere;
}

.wtools { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.wtools input[type="search"] {
  flex: 1; min-width: 180px; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 10px; padding: .58rem .8rem; font: inherit; font-size: .9rem;
}
.wtools input[type="search"]:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.wtools select { border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px; padding: .58rem .7rem; font: inherit; font-size: .88rem; }

.wrows { display: flex; flex-direction: column; gap: 8px; }
.wrow {
  display: flex; align-items: center; gap: 14px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 12px 14px; box-shadow: var(--shadow-sm);
}
.wrow .wn { font-weight: 800; font-size: 1rem; text-transform: capitalize; display: flex; align-items: center; gap: 6px; }
.wrow .wn .star { color: var(--orange); font-size: .9rem; }
.wrow .wdates { flex: 1; display: flex; gap: 16px; color: var(--fg-muted); font-size: .78rem; flex-wrap: wrap; }
.wrow .wuses { font-weight: 800; font-size: .9rem; color: var(--fg); white-space: nowrap; }
.wrow .wuses b { color: var(--orange); font-family: "Kaisei Decol", serif; font-size: 1.05rem; }

/* ---- Dictionaries page ---- */
.dict-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 10px; }
.dict-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 14px; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; align-items: center; text-align: center;
}

.dict-ring {
  width: 68px; height: 68px; border-radius: 999px; margin-bottom: 10px;
  background: conic-gradient(var(--dict-ring-color, var(--orange)) calc(var(--pct, 0) * 1%), var(--border-2) 0);
  display: grid; place-items: center; position: relative; flex: 0 0 auto;
}
.dict-ring::before { content: ""; position: absolute; inset: 5px; border-radius: 999px; background: var(--surface); }
.dict-ring.complete { --dict-ring-color: var(--safe); }
.dict-ring-icon { position: relative; z-index: 1; width: 30px; height: 30px; color: var(--orange); }
.dict-ring-icon svg { width: 100%; height: 100%; display: block; }
.dict-ring-check {
  position: absolute; top: -3px; right: -3px; z-index: 2; width: 20px; height: 20px; border-radius: 999px;
  background: var(--safe); color: #fff; font-size: .68rem; font-weight: 900; display: grid; place-items: center;
  border: 2px solid var(--surface);
}

.dict-name { font-weight: 800; font-size: .9rem; line-height: 1.25; margin-bottom: 2px; }
.dict-pct { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.3rem; color: var(--orange); }
.dict-frac { font-size: .72rem; color: var(--fg-faint); margin-bottom: 12px; }
.dict-actions { display: flex; gap: 6px; width: 100%; margin-top: auto; }
.dict-progress-btn {
  flex: 1; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 10px; padding: .5rem .4rem; font-weight: 800; font-size: .8rem; cursor: pointer;
}
.dict-progress-btn:hover { border-color: var(--orange); color: var(--orange); }
.dict-trophy-btn {
  flex: 0 0 auto; width: 34px; border: 1px solid var(--border-2); background: var(--surface-2);
  border-radius: 10px; cursor: pointer; font-size: .95rem; display: grid; place-items: center; color: var(--fg-muted);
}

/* Credits page */
.cred-h { font-size: 1rem; margin: 26px 0 10px; }
.cred-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
.cred-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 14px; box-shadow: var(--shadow-sm); text-decoration: none; color: inherit;
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px;
  transition: border-color .15s ease, transform .15s ease;
}
.cred-card:hover { border-color: var(--purple); transform: translateY(-2px); }
.cred-icon-wrap {
  width: 40px; height: 40px; border-radius: 999px; margin-bottom: 6px; overflow: hidden;
  background: var(--surface-2); display: grid; place-items: center; flex: 0 0 auto;
}
.cred-icon { width: 100%; height: 100%; object-fit: cover; display: block; }
.cred-icon-fallback { font-weight: 800; font-size: 1.1rem; color: var(--orange); }
.cred-name { font-weight: 800; font-size: .88rem; }
.cred-note { font-size: .74rem; color: var(--fg-muted); line-height: 1.35; }
.cred-note-block {
  margin-top: 28px; padding: 18px 20px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px;
}
.cred-note-block p { color: var(--fg-muted); font-size: .88rem; line-height: 1.6; margin: 0; }
.dict-trophy-btn:hover { border-color: var(--purple); color: var(--purple); }

/* ---- Dictionaries: View Progress modal ---- */
.pg-summary { background: var(--surface-2); border: 1px solid var(--border); border-radius: 14px; padding: 12px 14px; margin: 4px 0 16px; }
.pg-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pg-pct { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.9rem; color: var(--orange); line-height: 1; }
.pg-frac { font-size: .82rem; color: var(--fg-muted); }
.pg-frac b { color: var(--fg); font-weight: 800; }
.pg-bar { height: 8px; border-radius: 999px; background: var(--border-2); overflow: hidden; margin: 10px 0 8px; }
.pg-bar i { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--orange), var(--orange-bright)); transition: width .4s ease; }
.pg-sub { font-size: .76rem; color: var(--fg-muted); }
.pg-sub b { color: var(--fg); }
.pg-sec { margin-bottom: 16px; }
.pg-sec h4 { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-muted); }
.pg-hint { font-size: .68rem; text-transform: none; letter-spacing: 0; color: var(--fg-faint); font-weight: 600; }
.word-sample.scrolly { max-height: 172px; overflow-y: auto; overflow-x: hidden; align-content: flex-start; padding-right: 2px; }
.progress-note { font-size: .82rem; color: var(--fg-muted); margin: 0 0 10px; }
.word-sample { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; min-height: 30px; }
.word-chip {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 14px;
  padding: 4px 11px; font-size: .8rem; font-weight: 700; text-transform: lowercase;
  max-width: 100%; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.word-chip.typed { background: color-mix(in srgb, var(--safe) 14%, transparent); border-color: color-mix(in srgb, var(--safe) 40%, transparent); }
.no-select { -webkit-user-select: none; -moz-user-select: none; user-select: none; }
.typed-search {
  width: 100%; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 10px; padding: .55rem .8rem; font: inherit; font-size: .9rem; margin-bottom: 10px;
}
.typed-search:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.progress-locked { text-align: center; color: var(--fg-muted); font-size: .9rem; padding: 10px 0 4px; }

/* ---- Dictionaries: leaderboard modal ---- */
.lb-rows { display: flex; flex-direction: column; min-height: 60px; }
.lb-row { display: flex; align-items: center; gap: 10px; padding: 9px 2px; border-top: 1px solid var(--border); }
.lb-row:first-child { border-top: 0; }
.lb-rank { width: 22px; flex: 0 0 auto; text-align: center; font-weight: 900; color: var(--fg-faint); font-size: .84rem; }
.lb-row:nth-child(1) .lb-rank { color: #f1c40f; }
.lb-row:nth-child(2) .lb-rank { color: #b0b8c1; }
.lb-row:nth-child(3) .lb-rank { color: #c9752f; }
.lb-name { flex: 1; min-width: 0; font-weight: 700; font-size: .88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-n { font-weight: 800; color: var(--orange); font-family: "Kaisei Decol", serif; font-size: .96rem; flex: 0 0 auto; }

.pager { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 18px; }
.pager button {
  border: 1px solid var(--border-2); background: var(--surface); color: var(--fg); border-radius: 999px;
  padding: .45rem 1rem; font-weight: 700; font-size: .84rem; cursor: pointer;
}
.pager button:disabled { opacity: .4; cursor: not-allowed; }
.pager button:not(:disabled):hover { border-color: var(--purple); }
.pager span { color: var(--fg-muted); font-size: .82rem; }

@media (max-width: 620px) {
  .wstats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wrow { flex-wrap: wrap; }
  .wrow .wdates { order: 3; width: 100%; }
}

/* ---- drawer (create room + host settings) ---- */
.drawer-scrim { position: fixed; inset: 0; z-index: 60; background: rgba(10, 7, 3, .5); display: flex; align-items: flex-start; justify-content: center; padding: 56px 20px; backdrop-filter: blur(2px); overflow-y: auto; }
.drawer { width: 100%; max-width: 460px; background: var(--surface); border: 1px solid var(--border-2); border-radius: 18px; box-shadow: var(--shadow); padding: 20px; }
.drawer-tabs { display: flex; gap: 6px; margin: -4px -4px 16px; border-bottom: 1px solid var(--border); }
.drawer-tabs button {
  flex: 1; border: 0; background: none; color: var(--fg-muted); font-weight: 800; font-size: .95rem;
  padding: 10px 6px 12px; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.drawer-tabs button.on { color: var(--orange); border-bottom-color: var(--orange); }
.drawer-tabs button:hover:not(.on) { color: var(--fg); }
.drawer h3 { margin: 0 0 3px; font-size: 1.25rem; }
.drawer .sub { margin: 0 0 16px; color: var(--fg-muted); font-size: .86rem; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: .74rem; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--fg-muted); margin-bottom: 6px; }
.field input, .field select { width: 100%; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px; padding: .6rem .7rem; font: inherit; font-size: .92rem; }
.field input:focus, .field select:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.seg { display: flex; gap: 6px; }
.seg button { flex: 1; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg-muted); border-radius: 10px; padding: .55rem; font-weight: 800; font-size: .82rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 5px; }
.seg button.on { background: color-mix(in srgb, var(--orange) 16%, transparent); color: var(--orange); border-color: var(--orange); }
.seg button.wip, .seg button:disabled { color: var(--fg-faint); cursor: not-allowed; opacity: .7; }
.seg button.wip .wip-tag, .seg button:disabled .wip-tag { vertical-align: 1px; }
.drawer .actions { display: flex; gap: 8px; margin-top: 4px; }
.drawer .actions .btn-create { flex: 1; justify-content: center; }
.drawer .actions .cancel { border: 1px solid var(--border-2); background: none; color: var(--fg-muted); border-radius: 12px; padding: .8rem 1.2rem; font-weight: 800; cursor: pointer; }
.drawer .err { color: var(--shu); font-size: .82rem; margin: 0 0 10px; }
.swatches { display: flex; gap: 8px; flex-wrap: wrap; }
.swatch {
  width: 30px; height: 30px; border-radius: 999px; cursor: pointer; padding: 0;
  border: 2px solid transparent; transition: transform .1s ease;
}
.swatch:hover { transform: scale(1.08); }
.swatch.on { border-color: var(--fg); box-shadow: var(--ring); }
.host-actions { display: flex; flex-direction: column; gap: 6px; }
.host-actions button {
  border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 10px; padding: .55rem .7rem; font-weight: 700; font-size: .85rem; cursor: pointer; text-align: left;
}
.host-actions button:hover { border-color: var(--purple); }
.host-actions button[disabled] { opacity: .5; pointer-events: none; }
.host-actions button.danger, .drawer .actions button.danger { color: var(--shu); border-color: color-mix(in srgb, var(--shu) 45%, var(--border-2)); }

/* ================================================================
   Room / match
   ================================================================ */
.m-grid {
  max-width: 1680px; margin: 0 auto; padding: 18px 22px 56px;
  display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 24px; align-items: start;
}
.board { background: var(--surface); border: 1px solid var(--border); border-radius: 18px; box-shadow: var(--shadow); overflow: hidden; }
.board-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface-2); flex-wrap: wrap; }
.board-top .round { font-weight: 900; font-size: .84rem; }
.board-top .round b { color: var(--orange); }
.board-top .bt-right { display: flex; align-items: center; gap: 12px; }
.board-top .rule { font-size: .76rem; color: var(--fg-muted); font-weight: 700; }
.host-btn {
  border: 1px solid var(--border-2); background: var(--surface); color: var(--fg-muted);
  font-weight: 800; font-size: .78rem; padding: 5px 11px; border-radius: 999px; cursor: pointer;
}
.host-btn:hover { color: var(--orange); border-color: var(--orange); }

.board-body { padding: 26px 18px; text-align: center; }
.waiting-note { color: var(--fg-muted); font-size: .95rem; margin: 0 auto; max-width: 34ch; }
.waiting-note .cue { font-family: "Kaisei Decol", serif; color: var(--orange); font-weight: 700; }

.recap-panel { width: 100%; max-width: 420px; margin: 18px auto 0; text-align: left; }
.recap-rows { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.recap-player {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 8px 12px; box-shadow: var(--shadow-sm);
}
.recap-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.recap-name { font-weight: 800; font-size: .88rem; margin-right: auto; }
.recap-stat { font-size: .76rem; color: var(--fg-muted); white-space: nowrap; }
.recap-stat b { color: var(--orange); font-family: "Kaisei Decol", serif; font-size: .92rem; }
/* Per-player, not shared - each player's own category hits only. */
.recap-cats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.recap-cat-chip {
  display: inline-flex; align-items: center; gap: 5px; background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 999px; padding: 4px 10px; font-size: .78rem; font-weight: 700; color: var(--fg);
}
.recap-cat-chip b { color: var(--orange); font-family: "Kaisei Decol", serif; }
.recap-cat-icon { width: 15px; height: 15px; color: var(--orange); flex: 0 0 auto; }
.recap-cat-icon svg { width: 100%; height: 100%; display: block; }

.share-row {
  display: flex; gap: 8px; align-items: center; margin: 18px 16px;
  border: 1px dashed var(--border-2); border-radius: 12px; padding: 10px 12px; background: var(--surface-2);
}
.share-row .lbl { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--fg-muted); }
.share-row code { flex: 1; font-family: "Kaisei Decol", serif; font-size: .95rem; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-row button { border: 0; background: var(--orange); color: var(--orange-ink); font-weight: 800; font-size: .82rem; border-radius: 9px; padding: .45rem .9rem; cursor: pointer; }

.rail { display: flex; flex-direction: column; gap: 12px; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); overflow: hidden; }
.panel > h4 { margin: 0; padding: 10px 14px; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-muted); border-bottom: 1px solid var(--border); font-family: "Zen Kaku Gothic New", sans-serif; display: flex; justify-content: space-between; align-items: center; }
.panel > h4 b { color: var(--fg); font-weight: 900; }
.panel .panel-empty { padding: 14px; color: var(--fg-faint); font-size: .84rem; }

/* Player cards - a click anywhere on the row (except a mod button inside
   its mini-card) opens SS.showUserCard, which is also where Kick/Ban now
   live for the host (folded in there instead of sitting as always-visible
   row buttons, so the row itself stays readable at a glance). */
.sp-row {
  display: flex; align-items: center; gap: 11px; padding: 10px 14px; cursor: pointer;
  border-left: 3px solid transparent; transition: background .12s ease, border-color .12s ease;
}
.sp-row:hover { background: var(--surface-2); }
.sp-row + .sp-row { border-top: 1px solid var(--border); }
.sp-row .avatar { width: 32px; height: 32px; font-size: .78rem; }
.sp-row .nm { flex: 1; min-width: 0; font-weight: 800; font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-row .tag {
  display: inline-flex; align-items: center; gap: 4px; font-size: .62rem; font-weight: 900;
  text-transform: uppercase; letter-spacing: .06em; color: var(--orange-ink); background: var(--orange);
  border-radius: 999px; padding: 3px 8px 3px 6px; flex: 0 0 auto;
}
.sp-row .tag svg { width: 10px; height: 8px; fill: var(--orange-ink); }
/* A real accent (left bar + tint + inset ring), not just a faint tint - the
   rail is a second glance-spot besides the turn-strip for whose go it is. */
.sp-row.turn {
  background: color-mix(in srgb, var(--orange) 10%, transparent); border-left-color: var(--orange);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange) 22%, transparent);
}
.sp-row.out { opacity: .45; }
.sp-row .lives { display: flex; gap: 4px; flex: 0 0 auto; }
.sp-row .lives span { width: 9px; height: 9px; border-radius: 50%; background: var(--shu); display: inline-block; }
.sp-row .lives span.lost { background: var(--border-2); }
.mod-btns { display: flex; gap: 4px; margin-top: 10px; }
.mod-btn {
  flex: 1; font-size: .78rem; font-weight: 800; padding: .5rem; border-radius: 8px;
  border: 1px solid var(--border-2); background: var(--surface-3); color: var(--fg-muted); cursor: pointer;
}
.mod-btn:hover { color: var(--fg); border-color: var(--purple); }
.mod-btn.danger { color: var(--shu); border-color: color-mix(in srgb, var(--shu) 40%, var(--border-2)); }
.mod-btn.danger:hover { border-color: var(--shu); }
.mod-btn:disabled { opacity: .5; pointer-events: none; }

/* ---- play state: move log, turn strip, word input ---- */
.log { padding: 16px 16px 6px; display: flex; flex-direction: column; gap: 9px; max-height: 340px; overflow-y: auto; }
.move { display: flex; align-items: center; gap: 11px; }
.move .avatar { width: 28px; height: 28px; font-size: .76rem; }
.move .word {
  font-family: var(--font-word); font-size: 1.3rem; font-weight: 700; white-space: nowrap;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px;
  padding: 6px 15px; display: inline-flex; align-items: center; box-shadow: var(--shadow-sm);
}
.move .word .join { color: var(--orange); }
.move .word .t { color: var(--pink); }

/* Word Shape (Settings > Display) - a handful of chip silhouettes for the
   played-word bubble. All pure CSS (border-radius/clip-path), no assets.
   A per-MOVE class (ws-<shape>), not a :root attribute: this is each
   player's own chosen skin, applied to their words on everyone's screen,
   not a viewer-side filter that reshapes the whole log uniformly. room.html
   sets the class per move from that player's own account data. */
.move .word.ws-pill { border-radius: 999px; padding-left: 20px; padding-right: 20px; }
.move .word.ws-bubble,
.move .word.ws-iphone,
.move .word.ws-android,
.move .word.ws-receiver { border-radius: 16px 16px 16px 4px; }
/* Hexagon and Banner were both dropped: clip-path rendered incorrectly in
   at least one real browser, and the border-triangle rebuild of Hexagon
   still didn't render correctly there either - not worth the fragility. */

.move .word.ws-rectangle { border-radius: 0; }
/* Wiki: a nod to MediaWiki talk-page reply indentation - a flat left-bordered
   strip instead of a rounded chip, serif body text like a wiki page. */
.move .word.ws-wiki {
  border-radius: 0; border-width: 1px 1px 1px 3px; font-family: Georgia, "Times New Roman", serif; font-weight: 400;
}

/* Phone-bubble colours - a nod to the iMessage "blue bubble / green bubble"
   texting-war meme. Same speech-bubble geometry as Bubble above, just
   recoloured like the real Messages apps (iMessage blue, SMS/Android green,
   the grey "received" bubble) with a fixed text colour per bubble so it
   stays readable regardless of light/dark theme. */
.move .word.ws-iphone { background: #0b84ff; border-color: #0b84ff; }
.move .word.ws-iphone, .move .word.ws-iphone .join, .move .word.ws-iphone .t { color: #fff; }
.move .word.ws-android { background: #23c15e; border-color: #23c15e; }
.move .word.ws-android, .move .word.ws-android .join, .move .word.ws-android .t { color: #fff; }
.move .word.ws-receiver { background: #e9e9eb; border-color: #d5d5d9; }
.move .word.ws-receiver, .move .word.ws-receiver .join, .move .word.ws-receiver .t { color: #1c1c1e; }
.move .nm { font-size: .74rem; color: var(--fg-faint); font-weight: 700; }
.move.turn .word { border-color: var(--orange); box-shadow: var(--ring); color: var(--fg-faint); }

.cat-toast-host { margin: 8px 16px 0; display: flex; flex-wrap: wrap; gap: 6px; min-height: 0; }
.turn-strip { margin: 8px 16px 0; padding: 13px 0; border-top: 1px dashed var(--border-2); display: flex; align-items: center; gap: 15px; }
.timer {
  width: 54px; height: 54px; flex: 0 0 auto; border-radius: 999px; display: grid; place-items: center;
  font-weight: 900; font-size: 1rem; color: var(--fg); font-variant-numeric: tabular-nums;
  background: radial-gradient(closest-side, var(--surface) 76%, transparent 77%), conic-gradient(var(--border-2) 0%, var(--border-2) 100%);
  transition: color .2s ease;
}
.timer.crit { animation: timerPulse .55s ease-in-out infinite; }
@keyframes timerPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.09); } }
@media (prefers-reduced-motion: reduce) { .timer.crit { animation: none; } }
.turn-strip .who { flex: 1; min-width: 0; }
.turn-strip .who .n { font-weight: 900; font-size: 1rem; }
.turn-strip .who .prompt { color: var(--fg-muted); font-size: .84rem; }
.turn-strip .who .prompt .cue { font-family: "Kaisei Decol", serif; font-weight: 700; color: var(--orange); font-size: 1rem; }

.input-row { display: flex; gap: 8px; padding: 12px 16px 16px; }
.input-row input {
  flex: 1; min-width: 0; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 12px; padding: .78rem 1rem; font: inherit; font-size: 1.1rem; font-family: "Kaisei Decol", serif;
}
.input-row input:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.input-row input:disabled { opacity: .55; }
.input-row .send { border: 0; cursor: pointer; border-radius: 12px; padding: 0 1.4rem; font-weight: 900; color: var(--orange-ink); background: var(--orange); font-size: 1rem; }
.input-row .send:disabled { opacity: .5; cursor: default; }

/* ---- chat ---- */
.chat { display: flex; flex-direction: column; min-height: 240px; }
.chat .msgs { flex: 1; overflow-y: auto; padding: 10px 14px; display: flex; flex-direction: column; gap: 7px; max-height: 300px; }
.chat .m { font-size: .86rem; line-height: 1.45; }
.chat .m .who { font-weight: 800; }
.chat .m.sys { color: var(--fg-faint); font-style: italic; font-size: .8rem; }
.chat .m.pending { opacity: .55; }
.move.pending { opacity: .55; }
.chat-note { padding: 0 12px; font-size: .78rem; color: var(--shu); font-weight: 700; }
.chat .cbar { display: flex; gap: 7px; padding: 10px 12px; border-top: 1px solid var(--border); }
.chat .cbar input { flex: 1; min-width: 0; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px; padding: .5rem .7rem; font: inherit; font-size: .88rem; }
.chat .cbar input:focus { outline: none; border-color: var(--purple); }
.chat .cbar button { border: 0; background: var(--surface-3); color: var(--fg-muted); font-weight: 800; border-radius: 10px; padding: 0 .9rem; cursor: pointer; font-size: .84rem; }
.chat .cbar input:disabled, .chat .cbar button:disabled { opacity: .5; }

.stat-nums { display: flex; }
.stat-nums div { flex: 1; text-align: center; padding: 12px 4px; }
.stat-nums div + div { border-left: 1px solid var(--border); }
.stat-nums .k { font-size: .68rem; color: var(--fg-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.stat-nums .v { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.1rem; margin-top: 2px; }

.chat-disabled { padding: 14px; color: var(--fg-faint); font-size: .84rem; font-style: italic; }

.room-missing {
  max-width: 460px; margin: 12vh auto; text-align: center; padding: 0 22px;
}
.room-missing h1 { font-size: 1.8rem; margin: 0 0 8px; }
.room-missing p { color: var(--fg-muted); }

@media (max-width: 940px) {
  /* minmax(0, ...) not plain 1fr: a plain 1fr column can grow to fit its widest
     content, which pushed the whole room wider than the phone screen. */
  .m-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 620px) {
  .room { grid-template-columns: 40px 1fr; }
  .room .rcta { grid-column: 2; justify-self: start; margin-top: 8px; }
  .lobby-head { flex-direction: column; align-items: flex-start; }
  .topbar .row { padding: 8px 12px; gap: 8px; flex-wrap: wrap; }
  .tb-right { gap: 6px; }
  .currency { padding: 4px 8px 4px 5px; font-size: .78rem; }
  .currency svg { width: 13px; height: 13px; }
  .profile-chip { padding: 3px; }
  .profile-chip #profileName { display: none; }
  /* Real nav links (Rooms/Words) still need to be reachable on mobile - the
     WIP placeholders don't, so they're dropped rather than shrunk further,
     and the links wrap to their own centered row under the main header
     instead of fighting the logo/currency/profile chip for one line. */
  .nav { flex-basis: 100%; order: 3; justify-content: center; margin: 2px 0 0; gap: 4px; }
  .nav .wip { display: none; }
  .nav a { padding: 6px 10px; font-size: .84rem; }
}
@media (prefers-reduced-motion: reduce) {
  .petals, .ticker { display: none; }
  * { transition: none !important; animation: none !important; }
}

/* ---------------- Settings page ---------------- */
.set-section { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 20px 22px; box-shadow: var(--shadow-sm); margin-bottom: 20px; }
.set-section h3 { margin: 0 0 4px; font-family: "Kaisei Decol", serif; }
.set-note { color: var(--fg-faint); font-size: .82rem; margin: 0 0 14px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 14px 0; border-top: 1px solid var(--border); }
.set-section h3 + .set-note + .set-row, .set-section h3 + .set-row { border-top: 0; }
.set-row-col { flex-direction: column; align-items: stretch; }
.set-label { display: flex; flex-direction: column; gap: 2px; }
.set-label b { font-size: .92rem; }
.set-label span { font-size: .78rem; color: var(--fg-faint); }

.set-toggle {
  flex: 0 0 auto; width: 46px; height: 26px; border-radius: 999px; border: 1px solid var(--border-2);
  background: var(--surface-3); position: relative; cursor: pointer; padding: 0; transition: background .15s ease;
}
.set-toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--fg-faint); transition: transform .15s ease, background .15s ease;
}
.set-toggle.on { background: color-mix(in srgb, var(--orange) 35%, var(--surface-3)); border-color: var(--orange); }
.set-toggle.on::after { transform: translateX(20px); background: var(--orange); }

.set-slider-wrap { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; width: 220px; }
.set-slider { flex: 1; accent-color: var(--orange); }
.set-slider-val { font-size: .8rem; color: var(--fg-muted); width: 38px; text-align: right; font-variant-numeric: tabular-nums; }
.set-select {
  border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px;
  padding: .5rem .7rem; font: inherit; font-size: .88rem;
}
.set-input, .set-textarea {
  border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px;
  padding: .55rem .7rem; font: inherit; font-size: .86rem; width: 100%; box-sizing: border-box; margin-top: 10px;
}
.set-textarea { resize: vertical; min-height: 74px; font-family: monospace; }
.set-hint { color: var(--fg-faint); font-size: .76rem; margin: 6px 2px 0; }

/* A number field + a range input side by side, right-aligned in a row -
   used where a plain slider isn't precise enough (turn duration, word
   length) but the row still needs to read at a glance like the rest. */
.set-numrange { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; width: 220px; }
.set-numrange input[type="number"] {
  width: 54px; flex: 0 0 auto; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 8px; padding: .4rem .3rem; font: inherit; font-size: .86rem; text-align: center;
}
.set-numrange input[type="range"] { flex: 1; accent-color: var(--orange); }

/* Small tinted category-icon beside a .set-label, so a settings panel reads
   at a glance the way jklm.fun's does - stays inside the existing chip
   colour language (orange/safe/ai/shu), no new palette. */
.set-row-icon { display: flex; align-items: center; gap: 12px; min-width: 0; }
.set-icon {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center;
  font-size: 1rem; background: color-mix(in srgb, var(--orange) 16%, transparent); color: var(--orange);
}
.set-icon.ic-safe { background: color-mix(in srgb, var(--safe) 18%, transparent); color: var(--safe); }
.set-icon.ic-ai { background: color-mix(in srgb, var(--ai) 20%, transparent); color: var(--ai); }
.set-icon.ic-shu { background: color-mix(in srgb, var(--shu) 16%, transparent); color: var(--shu); }

/* Close Room et al. - functionally separate (blocked mid-round) from the
   tunable settings above it, so it gets its own visually separate block
   instead of blending into the field stack. */
.danger-zone {
  margin-top: 18px; border: 1px solid color-mix(in srgb, var(--shu) 35%, var(--border-2));
  border-radius: 14px; padding: 14px 16px; background: color-mix(in srgb, var(--shu) 6%, transparent);
}
.danger-zone h4 { margin: 0 0 4px; font-size: .76rem; color: var(--shu); text-transform: uppercase; letter-spacing: .07em; font-weight: 800; }
.danger-zone p { margin: 0 0 10px; font-size: .78rem; color: var(--fg-muted); }
.danger-zone .danger {
  width: 100%; border-radius: 10px; padding: .6rem; font-weight: 800; cursor: pointer; background: none;
  border: 1px solid color-mix(in srgb, var(--shu) 45%, var(--border-2)); color: var(--shu);
}
.danger-zone .danger:hover { background: color-mix(in srgb, var(--shu) 12%, transparent); }
.danger-zone .danger:disabled { opacity: .5; pointer-events: none; }

.set-shapes { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.set-shape-opt {
  /* `all: unset` first, strips every inherited/default <button> style
     (including any OS/browser accent-colour focus ring or underline the
     next rule down couldn't otherwise override) before rebuilding from a
     clean slate. */
  all: unset; box-sizing: border-box; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 8px; border: 1px solid var(--border-2);
  background: var(--surface-2); border-radius: 12px; padding: 12px 14px; min-width: 92px;
}
.set-shape-opt:focus, .set-shape-opt:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
/* .shape-preview is deliberately its OWN class, not .move .word - it must
   never be affected by the page's actual current word-shape setting (that
   selector is keyed off data-word-shape on <html>, which would otherwise
   repaint every OTHER preview swatch on this page to match whatever shape
   is currently live - each swatch carries its own look inline instead). */
.shape-preview {
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
  font-family: var(--font-word); font-weight: 700; font-size: .8rem; line-height: 1.5; white-space: nowrap;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px;
  padding: 9px 10px; min-width: 84px; box-shadow: none; text-decoration: none; outline: none;
}
.set-shape-opt label { font-size: .74rem; color: var(--fg-muted); font-weight: 700; cursor: pointer; text-decoration: none; }
.set-shape-opt.on { border-color: var(--orange); box-shadow: var(--ring); }
.set-shapes-sub { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--border); }
.set-shapes-sub-label { font-size: .78rem; color: var(--fg-faint); margin: 0 0 10px; }
.set-shapes-sub[hidden] { display: none; }

/* ---- side rail collapse (room page) ---- */
.rail-toggle-btn {
  flex: 0 0 auto; border: 1px solid var(--border-2); background: var(--surface); color: var(--fg-muted);
  border-radius: 999px; width: 30px; height: 30px; display: grid; place-items: center; cursor: pointer;
  font-size: .8rem; line-height: 1; transition: transform .15s ease, color .15s ease, border-color .15s ease;
}
.rail-toggle-btn:hover { color: var(--fg); border-color: var(--orange); }
.rail-toggle-btn.collapsed { transform: rotate(180deg); }
.m-grid.rail-hidden { grid-template-columns: minmax(0, 1fr); }
.m-grid.rail-hidden .rail { display: none; }

/* ---- narrow-viewport fixes ----
   A .set-row's control (.set-numrange/.set-select/.seg) has a fixed width
   (220px) or just needs real room - on a ~375-430px phone that leaves the
   label almost nothing, so every word of a two/three-word label wraps onto
   its own line (the actual bug reported). Below this width every row
   stacks: label on top, full-width control underneath, same as .set-row-col
   already does deliberately for Mode/Who Can Join. */
@media (max-width: 560px) {
  .drawer-scrim { padding: 24px 10px; }
  .drawer { padding: 16px; max-width: 100%; }
  .set-row { flex-direction: column; align-items: stretch; gap: 10px; }
  .set-numrange, .set-slider-wrap { width: 100%; }
  .set-row .set-select { width: 100%; }
}

/* ================================================================
   Phone comfort pass
   ================================================================ */
button, a, input, select, label, summary { touch-action: manipulation; }
@media (max-width: 760px) {
  /* iOS Safari zooms the whole page when a focused field is under 16px. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea { font-size: 16px !important; }
  /* Thumb-sized tap targets */
  #leaveLink, .rail-toggle-btn, .share-row button, .theme-toggle, #refreshBtn { min-height: 40px; min-width: 40px; }
  .rail-toggle-btn { width: 40px; height: 40px; }
  .share-row button { padding-left: 16px; padding-right: 16px; }
  .info-btn { width: 24px; height: 24px; position: relative; }
  .info-btn::after { content: ""; position: absolute; inset: -10px; }
  .topbar .nav a, .nav a { padding-top: 10px; padding-bottom: 10px; }
  /* Keep the word box high and reachable while playing: the invite link is
     just clutter mid-round on a small screen. */
  #playBody:not([hidden]) ~ .share-row { display: none; }
  /* Respect notches / home bars */
  body { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
  .lwrap { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
  .drawer { max-height: 92dvh; overflow-y: auto; }
}

/* ================================================================
   In-round layout on phones: the word box is pinned to the bottom of the
   screen (so it stays above the keyboard), and everything above it is
   compact so the last word, whose turn it is and the timer all fit at once.
   ================================================================ */
@media (max-width: 620px) {
  .board { overflow: clip; } /* clip, not hidden: hidden would break the sticky word box */
  .board-top { padding: 8px 12px; gap: 8px; flex-wrap: wrap; }
  .board-top .rule { display: none; }
  .board-top .bt-right { gap: 8px; margin-left: auto; }
  .board-body { padding: 18px 14px; }

  #playBody { display: flex; flex-direction: column; }
  .log { padding: 10px 12px 2px; gap: 6px; max-height: 34dvh; }
  .move { gap: 8px; }
  .move .avatar { width: 24px; height: 24px; font-size: .68rem; }
  .move .word { font-size: 1.05rem; padding: 4px 12px; max-width: calc(100vw - 90px); overflow-wrap: anywhere; white-space: normal; }
  .move .nm { font-size: .68rem; }
  .cat-toast-host { margin: 4px 12px 0; }
  .turn-strip { margin: 4px 12px 0; padding: 8px 0; gap: 10px; }
  .timer { width: 44px; height: 44px; font-size: .9rem; }
  .turn-strip .who .n { font-size: .92rem; }
  .turn-strip .who .prompt { font-size: .78rem; }
  .turn-strip .who .prompt .cue { font-size: .95rem; }

  .input-row {
    position: sticky; bottom: 0; z-index: 6; background: var(--surface);
    border-top: 1px solid var(--border); padding: 8px 12px calc(10px + env(safe-area-inset-bottom));
  }
  .input-row input { padding: .62rem .85rem; font-size: 16px; }
  .input-row .send { padding: 0 1.1rem; }
  #wordErr { margin: 0 12px 8px !important; }

  .m-grid { gap: 10px; padding-left: 10px; padding-right: 10px; }
  .rail { gap: 10px; }
  .panel > h4 { padding: 8px 12px; }
  .sp-row { padding: 8px 12px; gap: 8px; }
  .sp-row .avatar { width: 28px; height: 28px; }
  .stat-nums div { padding: 8px 4px; }
  .stat-nums .v { font-size: 1rem; }
  .chat { min-height: 200px; }
  .chat .msgs { max-height: 240px; }
}

/* Short screens (small phones, or a phone with the keyboard up): trade a
   little more of the history for keeping the input and timer in view. */
@media (max-width: 620px) and (max-height: 640px) {
  .log { max-height: 22dvh; }
  .topbar .row { padding-top: 4px; padding-bottom: 4px; }
  .turn-strip { padding: 6px 0; }
}
@media (max-width: 360px) {
  .move .word { font-size: .98rem; padding: 3px 10px; }
  .board-top .round { font-size: .78rem; }
  .input-row .send { padding: 0 .9rem; }
}

/* Room page on phones: everything rem-sized shrinks with the root, and the
   px-sized bits (avatars, timer) are brought down to match. Inputs stay at
   16px (see the phone comfort pass) so iOS doesn't zoom on focus. */
@media (max-width: 620px) {
  html:has(.m-grid) { font-size: 85%; }
  .m-grid .move .avatar { width: 21px; height: 21px; }
  .m-grid .timer { width: 38px; height: 38px; }
  .m-grid .sp-row .avatar { width: 25px; height: 25px; }
  .m-grid .input-row .send { min-height: 40px; }
}

/* ================================================================
   Lives bar: everyone's hearts, inside the play area. A hollow dot (not
   just a dimmer one) marks a lost life, so it doesn't rely on colour alone.
   ================================================================ */
.lives-bar {
  display: flex; gap: 8px; padding: 10px 16px 6px; overflow-x: auto; scrollbar-width: none;
}
.lives-bar::-webkit-scrollbar { display: none; }
.life-chip {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 1px;
  min-width: 62px; max-width: 110px; padding: 5px 10px 4px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--border-2);
}
.life-chip .lc-name {
  font-size: .68rem; font-weight: 800; color: var(--fg-muted); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.life-chip .lc-hearts { display: flex; align-items: center; gap: 5px; height: 14px; }
.life-chip .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--shu); box-sizing: border-box; }
.life-chip .dot.lost { background: transparent; border: 1.5px solid var(--fg-faint); }
.life-chip.me { border-color: var(--orange); }
.life-chip.me .lc-name { color: var(--orange); }
.life-chip.turn { background: color-mix(in srgb, var(--orange) 14%, var(--surface-2)); box-shadow: var(--ring); }
.life-chip.turn .lc-name { color: var(--fg); }
.life-chip.out { opacity: .5; }
.life-chip.out .lc-name { text-decoration: line-through; }

/* Short screens at ANY width - a phone or tablet held sideways, or with the
   keyboard up - leave very little height. Keep the timer, word box and
   lives; drop the rest of the clutter while a round is live. */
@media (max-height: 560px) {
  .board { overflow: clip; } /* clip (not hidden) so the sticky word box works */
  #playBody:not([hidden]) ~ .share-row { display: none; }
  .board-top { padding: 6px 12px; }
  .board-top .rule { display: none; }
  .lives-bar { padding: 6px 12px 5px; }
  .life-chip { min-width: 54px; padding: 3px 8px 2px; }
  .log { padding: 8px 12px 2px; gap: 5px; max-height: 26dvh; }
  .move .avatar { width: 22px; height: 22px; }
  .move .word { font-size: 1.05rem; padding: 3px 11px; }
  .turn-strip { margin: 4px 12px 0; padding: 6px 0; gap: 10px; }
  .timer { width: 38px; height: 38px; font-size: .85rem; }
  .input-row { padding: 6px 12px 8px; position: sticky; bottom: 0; z-index: 6; background: var(--surface); border-top: 1px solid var(--border); }
  .input-row input { padding: .5rem .8rem; }
}
@media (max-width: 620px) {
  .lives-bar { padding: 8px 12px 6px; }
}

/* /check results in chat: private, coloured by outcome (the mark and the
   wording carry the meaning too, not just the colour). */
.chat .m.sys.check { font-style: normal; font-size: .84rem; font-weight: 700; }
.chat .m.check-ok { color: var(--safe); }
.chat .m.check-no { color: var(--shu); }
.chat .m .check-priv { color: var(--fg-faint); font-weight: 600; font-size: .72rem; font-style: italic; margin-left: 4px; }

/* Profile popup + anything that opens it */
[data-profile] { cursor: pointer; }
.chat .m .who[data-profile]:hover, .lb-row[data-profile]:hover .lb-name { text-decoration: underline; }
.lb-row[data-profile]:hover { background: var(--surface-2); border-radius: 10px; }
.prof-modal { max-width: 460px; max-height: 92dvh; overflow-y: auto; overflow-x: hidden; }
.prof-modal .pm-loading { text-align: center; color: var(--fg-muted); padding: 30px 0; }
.prof-modal .prof-head .avatar { width: 56px; height: 56px; font-size: 1.25rem; }
.prof-modal .prof-name { font-size: 1.25rem; }
.prof-modal .prof-bio { margin-top: 6px; font-size: .86rem; }
.prof-modal .wstats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 8px; }
.prof-modal .wstats .card { padding: 10px 6px; }
.prof-modal .wstats .card .v { font-size: 1.05rem; overflow-wrap: anywhere; }
.prof-modal .wstats .card .k { font-size: .62rem; }
.prof-modal .wstats .card { min-width: 0; }
.prof-modal .wstats .card.long .v { font-size: .78rem; line-height: 1.5; padding-top: 3px; }
.prof-modal .wstats .card .v small { font-size: .6rem; color: var(--fg-muted); font-weight: 600; }
.prof-modal .actions { display: flex; gap: 8px; margin-top: 12px; }
.prof-modal .actions > * { flex: 1; }

/* Inactivity warning */
.afk-banner {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  z-index: 9999; max-width: min(92vw, 440px); background: var(--surface); color: var(--fg);
  border: 1px solid var(--orange); border-radius: 14px; padding: 12px 16px; font-size: .88rem;
  line-height: 1.4; box-shadow: var(--shadow); text-align: center;
}
.afk-banner b { color: var(--orange); }

/* Word details popup */
[data-word] { cursor: pointer; }
.wrow[data-word]:hover { border-color: var(--orange); }
.wrow[data-word]:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.word-modal { max-width: 480px; max-height: 92dvh; overflow-y: auto; overflow-x: hidden; }
.word-modal .wm-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.word-modal .wm-word { font-family: "Kaisei Decol", serif; font-weight: 700; font-size: 1.7rem; color: var(--fg); overflow-wrap: anywhere; }
.word-modal .wm-len { font-size: .78rem; color: var(--fg-muted); font-weight: 700; }
.word-modal .wm-cats { margin: 0 0 12px; padding-top: 0; border-top: 0; }
.word-modal .wstats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 12px; }
.word-modal .wstats .card { padding: 10px 6px; min-width: 0; }
.word-modal .wstats .card .v { font-size: 1.2rem; }
.word-modal .wstats .card .k { font-size: .62rem; }
.word-modal .wm-sec { margin-bottom: 12px; }
.word-modal .wm-sec h4 { margin: 0 0 6px; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-muted); }
.word-modal .wm-you { background: var(--surface-2); border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px; font-size: .84rem; color: var(--fg-muted); margin-bottom: 12px; }
.word-modal .wm-you b { color: var(--fg); }
.word-modal .wm-empty { color: var(--fg-faint); font-size: .84rem; padding: 4px 0; }
.word-modal .wm-list { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; max-height: 240px; overflow-y: auto; overflow-x: hidden; }
.word-modal .wm-person { display: flex; align-items: center; gap: 9px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 12px; padding: 8px 10px; min-width: 0; }
.word-modal .wm-person:hover { border-color: var(--orange); }
.word-modal .wm-person .avatar { width: 30px; height: 30px; font-size: .74rem; flex: 0 0 auto; }
.word-modal .wm-pinfo { min-width: 0; }
.word-modal .wm-pname { font-weight: 800; font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.word-modal .wm-psub { font-size: .7rem; color: var(--fg-muted); }
.word-modal .actions { display: flex; margin-top: 4px; }
.word-modal .actions > * { flex: 1; }
@media (max-width: 460px) { .word-modal .wm-list { grid-template-columns: 1fr; } }

/* A tooltip bubble that's hidden (opacity 0) still takes up space, and one
   sitting near the right edge widened the whole page on phones (seen on the
   Words page). Clip anything that would spill past the page's side edge. */
body { overflow-x: clip; }

.word-chip[data-word]:hover { border-color: var(--orange); color: var(--orange); }

/* Leaderboard: word rows (Top Words tab) and three-tab layout */
.drawer-tabs button { flex: 1; min-width: 0; white-space: nowrap; }
.lb-row[data-word]:hover { background: var(--surface-2); border-radius: 10px; }
.lb-row[data-word]:hover .lb-word { color: var(--orange); }
.lb-word { display: flex; flex-direction: column; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-word small { font-size: .68rem; font-weight: 600; color: var(--fg-muted); }

/* Four leaderboard tabs: shrink on narrow screens rather than wrapping */
@media (max-width: 480px) {
  .drawer-tabs { gap: 2px; }
  .drawer-tabs button { font-size: .74rem; padding-left: 4px; padding-right: 4px; }
}

/* Solo practice notices */
.solo-note {
  margin: 0; padding: 9px 16px; font-size: .78rem; line-height: 1.4; color: var(--fg-muted);
  background: color-mix(in srgb, var(--orange) 8%, var(--surface)); border-bottom: 1px solid var(--border);
}
.solo-note b { color: var(--orange); }
.cat-toast.solo .cat-toast-pill { opacity: .75; border-style: dashed; }
.cat-toast-solo { align-self: center; font-size: .7rem; font-weight: 700; color: var(--fg-muted); font-style: italic; }

/* Leaderboard: three tabs plus a one-line description of what's ranked */
.lb-desc { margin: -4px 0 10px; font-size: .78rem; color: var(--fg-muted); line-height: 1.4; }

/* Scrambled dictionary words: text-transform must not touch the private-use
   characters, and they must never be selectable or draggable. */
.word-chip.scr { text-transform: none; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }

/* Nothing to select: no highlighting, no long-press callouts. Text fields you
   type in keep normal selection. Only active while the guard is (it adds
   .ss-guard to <html>; the owner's ss-dev switch turns it all off). */
.ss-guard, .ss-guard body { -webkit-user-select: none; -moz-user-select: none; user-select: none; -webkit-touch-callout: none; }
.ss-guard input, .ss-guard textarea, .ss-guard select, .ss-guard [contenteditable="true"] {
  -webkit-user-select: text; -moz-user-select: text; user-select: text; -webkit-touch-callout: default;
}
.ss-guard ::selection { background: transparent; color: inherit; }
.ss-guard input::selection, .ss-guard textarea::selection, .ss-guard [contenteditable="true"]::selection {
  background: rgba(241, 144, 0, .35); color: inherit;
}
.ss-guard img, .ss-guard svg { -webkit-user-drag: none; }

/* The dictionary card's "View Progress" is a link now (it opens the dictionary's own page). */
a.dict-progress-btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }

/* ================================================================
   Dictionary page (/dictionary?k=...)
   Styled after the game's own word log: played words are the same kind of
   bubble as in a room (first letter orange, last letter pink - the letters a
   shiritori chain links on); unplayed ones are redacted bars.
   ================================================================ */
.dp-back { display: inline-flex; align-items: center; gap: 6px; margin: 2px 0 12px; color: var(--fg-muted); font-weight: 700; font-size: .84rem; text-decoration: none; }
.dp-back:hover { color: var(--orange); }
.dp-locked { text-align: center; padding: 36px 16px; color: var(--fg-muted); background: var(--surface); border: 1px dashed var(--border-2); border-radius: 16px; }
.dp-locked p { margin: 0 0 14px; }

.dp-hero { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.dp-hero .dict-ring { margin: 0; flex: 0 0 auto; }
.dp-title { min-width: 0; flex: 1 1 200px; }
.dp-title h2 { margin: 0; font-family: "Kaisei Decol", serif; font-size: 1.7rem; line-height: 1.15; overflow-wrap: anywhere; }
.dp-title p { margin: 4px 0 0; color: var(--fg-muted); font-size: .86rem; }
.dp-actions { margin-left: auto; }

.dp-try { margin: 0 0 16px; }
.dp-try h4, .dp-info { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-muted); }
.dp-note { color: var(--fg-faint); font-size: .85rem; }

.dp-tools { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 0 0 10px; }
.dp-tools input[type="search"] {
  flex: 1 1 220px; min-width: 0; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 12px; padding: .62rem .9rem; font: inherit; font-size: .92rem;
}
.dp-tools input[type="search"]:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }
.dp-seg { display: inline-flex; border: 1px solid var(--border-2); border-radius: 12px; overflow: hidden; background: var(--surface-2); }
.dp-seg button { border: 0; background: none; color: var(--fg-muted); font-weight: 800; font-size: .82rem; padding: .6rem .95rem; cursor: pointer; }
.dp-seg button.on { background: var(--orange); color: var(--orange-ink); }

.dp-letters { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 12px; }
.dp-letters[hidden] { display: none; }
.dp-letters button {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border-2); background: var(--surface-2);
  color: var(--fg-muted); font-weight: 800; font-size: .76rem; cursor: pointer; padding: 0;
}
.dp-letters button:hover { border-color: var(--orange); color: var(--orange); }
.dp-letters button.on { background: var(--orange); border-color: var(--orange); color: var(--orange-ink); }

.dp-info { text-transform: none; letter-spacing: 0; font-size: .8rem; font-weight: 600; min-height: 1.2em; }
.dp-list {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr));
  gap: 7px 16px; margin: 0 0 16px;
}
.dp-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.dp-n { flex: 0 0 44px; text-align: right; font-size: .68rem; color: var(--fg-faint); font-variant-numeric: tabular-nums; }
.dp-word {
  font-family: var(--font-word); font-size: 1.02rem; font-weight: 700; line-height: 1.3;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px; padding: 5px 14px;
  display: inline-block; max-width: 100%; min-width: 0;
  white-space: normal; overflow-wrap: anywhere; box-shadow: var(--shadow-sm);
}
.dp-word.played { cursor: pointer; }
.dp-word.played:hover { border-color: var(--orange); }
.dp-word.played b { color: var(--orange); font-weight: 700; }
.dp-word.played i { color: var(--pink); font-style: normal; }
.dp-word.played em { margin-left: 8px; font-style: normal; font-size: .64rem; font-weight: 800; color: var(--fg-muted); letter-spacing: .02em; }
.dp-word.redacted {
  width: calc(var(--len, 6) * .6em + 30px); max-width: 100%; height: 33px; padding: 0; box-shadow: none;
  border-style: dashed; border-color: var(--border);
  background: repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--fg-faint) 15%, transparent) 6px 12px);
}
.dp-empty { padding: 28px 12px; text-align: center; color: var(--fg-muted); background: var(--surface); border: 1px dashed var(--border-2); border-radius: 14px; margin-bottom: 16px; }
.dp-empty[hidden] { display: none; }

.dp-pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; margin: 4px 0 30px; }
.dp-pager button {
  border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg); border-radius: 10px;
  min-width: 38px; height: 38px; padding: 0 12px; font-weight: 800; font-size: .84rem; cursor: pointer;
}
.dp-pager button:hover:not(:disabled):not(.on) { border-color: var(--orange); color: var(--orange); }
.dp-pager button.on { background: var(--orange); border-color: var(--orange); color: var(--orange-ink); }
.dp-pager button:disabled { opacity: .4; cursor: default; }
.dp-nums { display: inline-flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.dp-gap { color: var(--fg-faint); align-self: center; }
.dp-jump { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; font-size: .78rem; color: var(--fg-muted); font-weight: 700; }
.dp-jump input {
  width: 68px; height: 38px; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--fg);
  border-radius: 10px; text-align: center; font: inherit; font-size: .9rem;
}
.dp-jump input:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }

@media (max-width: 620px) {
  .dp-title h2 { font-size: 1.4rem; }
  .dp-actions { margin-left: 0; width: 100%; }
  .dp-actions .btn-create { width: 100%; justify-content: center; }
  .dp-seg { width: 100%; }
  .dp-seg button { flex: 1; }
  .dp-list { grid-template-columns: 1fr; }
  .dp-n { flex-basis: 38px; }
  .dp-jump { margin-left: 0; width: 100%; justify-content: center; }
}

/* Dictionaries: weekly update countdown */
.dict-next { margin: 8px 0 0; font-size: .86rem; color: var(--fg-muted); }
.dict-next b { color: var(--orange); font-weight: 800; }
.dict-next-sub { color: var(--fg-faint); }

/* Music widget: this tab isn't the one playing */
.mw-controls button.mw-here {
  width: auto; height: auto; display: inline-block; white-space: nowrap;
  padding: 7px 16px; border-radius: 999px; border: 1px solid var(--orange);
  background: transparent; color: var(--orange); font-weight: 800; font-size: .8rem; line-height: 1;
}
.mw-controls button.mw-here:hover { background: var(--orange); color: var(--orange-ink); }

/* Custom played-word letter colours (Settings > Display). Only active when set;
   these sit last so they also beat the fixed colours of the chat-style shapes. */
:root[data-wc-start] .move .word .join,
:root[data-wc-start] .dp-word.played b,
:root[data-wc-start] .wc-preview .s { color: var(--wc-start); }
:root[data-wc-mid] .move .word,
:root[data-wc-mid] .wc-preview { color: var(--wc-mid); }
:root[data-wc-end] .move .word .t,
:root[data-wc-end] .dp-word.played i,
:root[data-wc-end] .wc-preview .e { color: var(--wc-end); }
.wc-preview { font-family: var(--font-word); font-size: 1.25rem; font-weight: 700; padding: 6px 15px;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 11px; }
.wc-preview .s { color: var(--orange); }
.wc-preview .e { color: var(--pink); }
.wc-pickers { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.wc-pickers label { display: flex; align-items: center; gap: 5px; font-size: .78rem; color: var(--fg-muted); font-weight: 700; }
.wc-pickers input[type=color] { width: 34px; height: 30px; padding: 0; border: 0; background: none; cursor: pointer; }
.dp-word.scr { text-transform: none; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }

/* Dictionary search: per-row played status + the exact-match banner */
.dp-word em.dp-yes { color: var(--safe); }
.dp-word em.dp-no { color: var(--fg-faint); font-weight: 700; }
.dp-exact { margin: 4px 0 10px; padding: 9px 14px; border-radius: 11px; font-weight: 700; font-size: .88rem;
  border: 1px solid var(--border-2); background: var(--surface-2); }
.dp-exact[hidden] { display: none; }
.dp-exact.yes { border-color: var(--safe); color: var(--safe); }
.dp-exact.no { border-color: var(--orange); color: var(--orange); }
.dp-exact.none { color: var(--fg-muted); }

/* Chat Name Colour row (Settings > Chat): a consistent square swatch instead
   of the browser's native <input type=color> pill shape, which read oddly
   on mobile - and lets the row wrap sanely on very narrow phones. */
.cc-row { flex-wrap: wrap; row-gap: 8px; }
.cc-swatch {
  -webkit-appearance: none; appearance: none; width: 34px; height: 34px; flex: 0 0 auto;
  padding: 0; border: 1px solid var(--border-2); border-radius: 9px; background: none; cursor: pointer;
}
.cc-swatch::-webkit-color-swatch-wrapper { padding: 2px; }
.cc-swatch::-webkit-color-swatch { border: 0; border-radius: 6px; }
.cc-swatch::-moz-color-swatch { border: 0; border-radius: 6px; }
.cc-hex { width: 96px; flex: 1 1 96px; min-width: 84px; }
.cc-reset { cursor: pointer; flex: 0 0 auto; }
@media (max-width: 560px) {
  .cc-row { width: 100%; }
}

/* ---- petal loading overlay (bridges the blank gap on a slow page-to-page
   navigation, e.g. entering a freshly-created room) ----
   Same 6-ellipses-around-a-center technique as SS.PETAL_SVG (the currency
   icon), just 6 petals instead of 5 and animated: the whole flower loses
   its petals then grows them back, on a loop, in a tight ripple rather than
   all six snapping at once. */
.petal-loader {
  position: fixed; inset: 0; z-index: 300; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 12px; background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(3px); opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.petal-loader.on { opacity: 1; pointer-events: all; }
.petal-loader svg { width: 60px; height: 60px; overflow: visible; }
.petal-loader .lp-petal {
  transform-box: fill-box; transform-origin: center; fill: var(--pink);
  animation: lp-cycle 3s ease-in-out infinite; animation-delay: calc(var(--i, 0) * .14s);
}
/* Each petal's own local "up" is "away from the flower's center" (the
   wrapping <g> already rotated it into place) - so a plain translateY here
   reads as the petal actually lifting off outward and flying back in, not
   just shrinking/growing in place like a time-lapse bloom. */
/* Mostly a whole flower - each petal only briefly plucks out and back
   around the 30% mark of its own (staggered) timeline, not gone for most
   of the loop. */
@keyframes lp-cycle {
  0%, 62%, 100% { transform: translateY(0) scale(1) rotate(0deg); opacity: 1; }
  31% { transform: translateY(-4px) scale(.55) rotate(-14deg); opacity: 0; }
}
.petal-loader .lp-word {
  font-size: .76rem; font-weight: 700; color: var(--fg-muted); letter-spacing: .03em;
}
@media (prefers-reduced-motion: reduce) {
  .petal-loader .lp-petal { animation: none; }
}

/* /complain page */
.cp-textarea {
  font: inherit; font-size: .95rem; line-height: 1.5; color: var(--fg); background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 12px; padding: 12px 14px; resize: vertical;
}
.cp-textarea:focus { outline: none; box-shadow: var(--ring); border-color: var(--orange); }

/* Pre-release countdown pill (see the end of ss-game.js) */
.ss-launch-pill {
  position: fixed; bottom: 10px; left: 50%; transform: translateX(-50%); z-index: 250; pointer-events: none;
  background: var(--orange); color: #1a1206; font-weight: 800; font-size: .78rem; padding: 5px 13px;
  border-radius: 999px; box-shadow: 0 2px 0 rgba(120, 60, 10, .3); white-space: nowrap;
}

/* Profile > Match History */
.mh-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px; margin-bottom: 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
}
.mh-res {
  flex: 0 0 auto; min-width: 52px; text-align: center; font-weight: 800; font-size: .72rem;
  text-transform: uppercase; letter-spacing: .06em; padding: 3px 10px; border-radius: 999px; border: 1px solid;
}
.mh-res.won { color: var(--safe); border-color: var(--safe); }
.mh-res.lost { color: var(--shu); border-color: color-mix(in srgb, var(--shu) 55%, transparent); }
.mh-meta { flex: 1; min-width: 0; color: var(--fg); font-weight: 700; font-size: .9rem; }
.mh-time { flex: 0 0 auto; color: var(--fg-faint); font-size: .78rem; }
.mh-empty { text-align: center; color: var(--fg-muted); padding: 22px 12px; margin: 0; }
