/* RhymeRep — design system: pure black base + bold white type + gray grid + colored word blocks, with ico gold used only as an accent */
:root {
  --bg: #0a0a0a;
  --bg-card: #17171b;
  --bg-card-2: #1e1e24;
  --ink: #f4f2ec;
  --ink-soft: #9b978c;
  --accent: #f0ae30;
  --accent-2: #c98a1a;
  --good: #3ddc97;
  --bad: #ff5f5f;
  --gold: #ffd166;
  --line: #2e2e34;
  --line-2: #26262c;
  --bg-elevated: #15151a;
  --radius: 14px;
  --font-disp: 'Anton', 'Arial Black', sans-serif;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, "Segoe UI", system-ui, sans-serif;
  min-height: 100vh;
}
button { font-family: inherit; cursor: pointer; border: none; }
/* Inline SVG icons (replacing emoji): stroked icons use .ic, filled icons add .ic-fill */
.ic { width: 15px; height: 15px; vertical-align: -2px; margin-right: 6px; flex-shrink: 0; }
.ic-fill { fill: currentColor; stroke: none; }
.vs-badge { font-family: var(--font-disp); font-style: italic; font-size: .8em; color: var(--accent);
  border: 1.5px solid var(--accent); border-radius: 4px; padding: 1px 4px; margin-right: 6px; vertical-align: 1px; }

/* ---------- Header ---------- */
.site-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 24px; max-width: 960px; margin: 0 auto;
}
.brand { font-family: var(--font-disp); font-size: 1.25rem; letter-spacing: 1px; text-transform: uppercase; white-space: nowrap; color: inherit; text-decoration: none; }
.site-nav { white-space: nowrap; }
.site-nav a { color: var(--ink-soft); text-decoration: none; margin-left: 20px; font-size: .95rem; }
.site-nav a:hover { color: var(--ink); }

main { max-width: 960px; margin: 0 auto; padding: 0 20px 60px; }

/* ---------- Home hero / mode cards ---------- */
#home-screen { text-align: center; padding: 48px 0 24px; }
#home-screen h1 { font-size: clamp(2rem, 6vw, 3.4rem); font-weight: 800; letter-spacing: -.5px; }
.accent { color: var(--accent); }
.tagline { color: var(--ink-soft); margin: 0 auto 12px; max-width: 560px; font-size: 1.05rem; line-height: 1.6; }
/* ordinary-person CTA line under the tagline: the "never rapped before" on-ramp, small and dim so it never competes with the game */
.tagline-cta { color: var(--ink-soft); opacity: .8; margin: -6px auto 10px; max-width: 560px; font-size: .88rem; line-height: 1.5; }
.tagline-cta b { color: var(--accent); font-weight: 600; }

/* Home hero: compact H1 + tagline (above the game, so the game isn't pushed below the fold) */
.hero-head { text-align: center; padding: 10px 0 0; }
.hero-h1 { font-family: var(--font-disp); font-size: 1.9rem; text-transform: uppercase; letter-spacing: 1.5px; margin: 0 0 6px; }
.mode-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; max-width: 780px; margin: 0 auto; }
.mode-card {
  background: var(--bg-card); border-radius: var(--radius); padding: 24px 18px;
  display: flex; flex-direction: column; gap: 8px; align-items: center;
  border: 1px solid transparent; transition: transform .15s, border-color .15s;
  color: var(--ink);
}
.mode-card:hover { transform: translateY(-3px); border-color: var(--accent); background: var(--bg-card-2); }
.mode-emoji { font-size: 2rem; }
.mode-name { font-weight: 800; font-size: 1.1rem; }
.mode-desc { color: var(--ink-soft); font-size: .85rem; line-height: 1.5; }

/* ---------- Game area ---------- */
.play-topbar { display: flex; align-items: center; justify-content: space-between; padding: 18px 0 8px; }
#mode-badge {
  background: var(--bg-card); color: var(--accent); font-weight: 800;
  padding: 6px 14px; border-radius: 999px; font-size: .85rem;
}
#timer-wrap { font-size: 1.3rem; font-weight: 800; color: var(--gold); }
#timer-wrap.low { color: var(--bad); animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .5; } }

.target-wrap { text-align: center; padding: 28px 0 20px; }
.target-label { color: var(--ink-soft); text-transform: uppercase; letter-spacing: 2px; font-size: .75rem; }
#target-word {
  font-family: var(--font-disp); font-size: clamp(2.6rem, 9vw, 4.5rem); letter-spacing: 2px; text-transform: uppercase;
  color: var(--ink);
}
.target-hint { color: var(--ink-soft); margin-top: 8px; font-size: .9rem; }

#rhyme-form { display: flex; gap: 10px; max-width: 560px; margin: 0 auto; }
#rhyme-input {
  flex: 1; background: var(--bg-card); border: 2px solid var(--line-2); color: var(--ink);
  border-radius: 999px; padding: 16px 22px; font-size: 1.15rem; outline: none; transition: border-color .15s;
}
#rhyme-input:focus { border-color: var(--accent); }
#submit-btn {
  background: var(--accent); color: #101014;
  font-weight: 800; font-size: 1.05rem; padding: 0 26px; border-radius: 12px;
  box-shadow: 0 4px 18px rgba(240, 174, 48, .3); transition: transform .1s;
}
#submit-btn:active { transform: scale(.96); }

#judge-flash { text-align: center; min-height: 28px; margin-top: 10px; font-weight: 800; font-size: 1rem; }
#judge-flash.good { color: var(--good); }
#judge-flash.bad { color: var(--bad); }

#words-board { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 26px auto 10px; max-width: 720px; }
.word-chip {
  background: var(--bg-card); border-radius: 999px; padding: 8px 16px; font-size: .95rem;
  border: 1px solid var(--line-2); animation: pop .18s ease-out;
}
.word-chip b { color: var(--gold); font-weight: 800; margin-left: 6px; }
@keyframes pop { from { transform: scale(.6); opacity: 0; } }

.play-footer { display: flex; align-items: center; justify-content: center; gap: 26px; margin-top: 26px; color: var(--ink-soft); }
#score { color: var(--gold); font-size: 1.2rem; }
#progress-wrap { font-size: .9rem; }
.ghost-btn {
  background: transparent; color: var(--ink-soft); border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 18px; font-size: .9rem;
  display: inline-flex; align-items: center;
}
.ghost-btn:hover { color: var(--ink); border-color: var(--accent); }
.ghost-btn[hidden] { display: none; }

/* ---------- Results / share ---------- */
#result-screen { text-align: center; padding: 30px 0; }
#result-title { font-family: var(--font-disp); font-size: 2rem; letter-spacing: 1px; margin-bottom: 18px; }
#result-words { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 26px; max-width: 700px; }
#share-canvas {
  width: min(360px, 90vw); height: auto; border-radius: var(--radius);
  box-shadow: 0 12px 48px rgba(0, 0, 0, .5); display: block; margin: 0 auto;
}
.share-actions { display: flex; gap: 12px; justify-content: center; margin: 24px 0 14px; flex-wrap: wrap; }
.share-actions button {
  background: var(--bg-card); color: var(--ink); border-radius: 999px; padding: 13px 24px;
  font-weight: 800; font-size: .95rem; border: 1px solid var(--line); transition: border-color .15s;
}
.share-actions button:first-child { background: var(--accent); color: #101014; border: none; }
.share-actions #challenge-from-result { border-color: var(--accent); color: var(--accent); background: none; }
.share-actions button:hover { border-color: var(--accent); }
.share-actions #challenge-from-result:hover { background: rgba(240, 174, 48, .08); }

/* ---------- SEO content block ---------- */
.seo-block { max-width: 760px; margin: 36px auto 0; padding: 14px 22px; background: var(--bg-card); border-radius: var(--radius); }
.seo-block h2 { font-family: var(--font-disp); font-weight: 400; letter-spacing: 1px; font-size: 1.35rem; margin-bottom: 14px; }
.seo-block p, .seo-block li { color: var(--ink-soft); line-height: 1.8; font-size: .98rem; }
.quote-block { margin: 14px 0; padding: 12px 18px; border-left: 3px solid var(--accent); background: var(--bg-card-2); border-radius: 0 10px 10px 0; }
.quote-block p { color: var(--ink); font-style: italic; margin: 0; }
.quote-block cite { display: block; margin-top: 8px; font-style: normal; font-size: .85rem; color: var(--ink-soft); }
.seo-block details { border-top: 1px solid #232329; padding: 4px 0; }
.seo-block summary { cursor: pointer; font-weight: 700; color: var(--ink); }
.seo-block summary::marker { color: var(--accent); }
.seo-block details p { margin-top: 8px; }

/* ---------- Footer ---------- */
/* Two shapes share this class: legacy pages (two centered <span>s, ~114 generated pages) and the
   2026-10-09 redesign (index + ru/fr play: .footer-grid brand column + Play/Learn/More groups).
   The base rule below is the LEGACY look; redesign pages override it via :has(.footer-grid).
   Do not restyle the base rule for the redesign — every old page breaks (learned the hard way). */
.site-footer {
  border-top: 1px solid #1c1c22; padding: 26px 20px; text-align: center;
  color: var(--ink-soft); font-size: .85rem; display: flex; flex-direction: column; gap: 6px;
}
.site-footer:has(.footer-grid) {
  display: block; text-align: left; gap: 0; padding: 34px 24px 24px; max-width: 960px; margin: 0 auto;
}
.footer-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: 26px; }
.footer-brand-line { display: flex; align-items: center; font-family: var(--font-disp);
  font-size: 1.05rem; letter-spacing: 1px; text-transform: uppercase; color: var(--ink); white-space: nowrap; }
.footer-tag { display: block; margin-top: 8px; font-size: .8rem; line-height: 1.55; opacity: .75; }
.footer-col { display: flex; flex-direction: column; gap: 2px; }
.footer-h { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink); opacity: .55; margin-bottom: 8px; }
.footer-col a { color: var(--ink-soft); text-decoration: none; padding: 5px 0; }
.footer-col a:hover { color: var(--accent); }
.footer-base { display: flex; justify-content: space-between; align-items: baseline; gap: 8px 16px;
  flex-wrap: wrap; margin-top: 26px; padding-top: 16px; border-top: 1px solid #1c1c22; font-size: .78rem; }
.footer-note { opacity: .7; }
/* Body/footer links: ico gold everywhere on the black background (footer-col overrides to gray) */
.seo-block a, .site-footer a { color: var(--accent); }
.site-footer .footer-col a { color: var(--ink-soft); }
.site-footer .footer-col a:hover { color: var(--accent); }

@media (max-width: 600px) {
  .site-footer:has(.footer-grid) { padding: 28px 18px 20px; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 20px 18px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-col a { padding: 13px 0; } /* ~42px touch targets */
  .footer-base { flex-direction: column; align-items: flex-start; gap: 8px; }
}

@media (max-width: 600px) {
  #rhyme-form { flex-direction: column; }
  #submit-btn { padding: 14px; }
}

/* ---------- On Beat mode ---------- */
.mode-chips { display: flex; gap: 8px; }
.mode-chip {
  background: transparent; color: var(--ink-soft); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 14px; font-size: .85rem; font-weight: 700;
}
.mode-chip:hover { color: var(--ink); border-color: var(--accent); }
.mode-chip.active { background: var(--bg-card); color: var(--accent); border-color: var(--accent); }

.beat-stage { display: flex; align-items: center; justify-content: center; gap: 18px; padding: 14px 0 0; }
#beat-ball {
  font-size: 2.2rem; display: inline-block; filter: drop-shadow(0 0 12px rgba(240,174,48,.6));
  transition: transform .12s ease-out;
}
#beat-ball.pulsing { animation: beatPulse .18s ease-out; }
@keyframes beatPulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.45); }
  100% { transform: scale(1); }
}
#beat-select {
  background: var(--bg-card); color: var(--ink); border: 1px solid var(--line);
  border-radius: 999px; padding: 8px 16px; font-size: .9rem; font-weight: 700; font-family: inherit;
}

.loading-word { animation: loadPulse 1.2s ease-in-out infinite; font-size: clamp(1.8rem, 6vw, 3rem) !important; }
@keyframes loadPulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }

/* ---------- Bars mode ---------- */
.beat-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; max-width: 720px; margin: 20px auto 0; }
.beat-card {
  background: var(--bg-card); border: 1px solid var(--line-2); border-radius: var(--radius);
  padding: 18px 10px; display: flex; flex-direction: column; gap: 4px; align-items: center; color: var(--ink);
}
.beat-card:hover { border-color: var(--accent); }
.beat-card.active { border-color: var(--accent); background: var(--bg-card-2); }
.beat-emoji { font-size: 1.8rem; }
.beat-name { font-weight: 800; }
.beat-sub { color: var(--ink-soft); font-size: .75rem; }
.bars-opts { display: flex; flex-wrap: wrap; gap: 18px; justify-content: center; margin: 22px auto 0; max-width: 720px; }
.opt-group { display: flex; align-items: center; gap: 8px; }

/* Options panel rows: fixed-width label column + chips column, every row starts at the same x */
#flow-options { margin-top: 14px; }
#flow-options .opt-group { display: block; }
#flow-options .opt-group + .opt-group { margin-top: 14px; }
#flow-options .opt-label { display: block; margin: 0 0 8px; }
#flow-options .opt-chips { display: flex; flex-wrap: wrap; gap: 8px; }
#flow-options .opt-chip { padding: 6px 12px; }
.opt-label { color: var(--ink-soft); font-size: .85rem; margin-right: 4px; }
.opt-chip {
  background: transparent; color: var(--ink-soft); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 14px; font-size: .85rem; font-weight: 700;
}
.opt-chip.active { background: var(--bg-card); color: var(--accent); border-color: var(--accent); }
/* endless discovery pulse (2026-09-15): key held but chip never clicked — glow until first click.
   box-shadow pulse only, no transform: animating layout-adjacent properties would nudge the chips row */
@keyframes endlessNew { 0%, 100% { box-shadow: 0 0 0 0 rgba(240,174,48,.55); } 50% { box-shadow: 0 0 0 7px rgba(240,174,48,0); } }
.endless-chip.endless-new { animation: endlessNew 1.6s ease-in-out infinite; color: var(--accent); border-color: var(--accent); }
/* result-screen Try Endless CTA: gold like big-start, but slimmer — it sits under the score, not over it */
.endless-try {
  display: block; margin: 14px auto 0; background: var(--accent); color: #101014;
  font-weight: 800; font-size: .95rem; padding: 12px 22px; border-radius: 999px;
  box-shadow: 0 4px 18px rgba(240,174,48,.3);
}
.endless-try:hover { background: #ffc14d; }
.endless-try[hidden] { display: none; }
.big-start {
  display: block; margin: 28px auto 0; background: var(--accent);
  color: #101014; font-family: var(--font-disp); font-size: 1.25rem; letter-spacing: 2px; text-transform: uppercase;
  padding: 15px 44px; border-radius: 10px;
  box-shadow: 0 6px 24px rgba(240, 174, 48, .35);
}
.big-start:hover { background: #ffc14d; }
/* instant click ack: the mic-restore await (VAD/wasm load, 0.5-3s) sits between the Play click and
   the run start — the button must react in the same frame or the click reads as dead. Dark spinner
   on the gold face; class is cleared by flowSetState on any transition. Same treatment on the
   first-guide mic CTA (its Judge.enable path pays the same window). */
.big-start.starting, .fg-primary.starting { pointer-events:none; filter:brightness(.88); }
.big-start.starting::after, .fg-primary.starting::after {
  content:''; display:inline-block; width:.8em; height:.8em; margin-left:.45em; vertical-align:-.08em;
  border-radius:50%; border:2.5px solid rgba(16,16,20,.3); border-top-color:#101014;
  animation:startSpin .7s linear infinite;
}
@keyframes startSpin { to { transform:rotate(360deg); } }
.bars-hud { display: flex; justify-content: center; gap: 24px; color: var(--ink-soft); font-weight: 700; padding-top: 12px; }
#bars-combo { color: var(--gold); }
.bars-endword {
  font-size: clamp(2.4rem, 8vw, 4.2rem); font-weight: 800; letter-spacing: 2px; text-align: center;
  color: var(--ink-soft);
}
.bars-endword.revealed {
  color: var(--ink);
}
#beat-ball.landing { filter: drop-shadow(0 0 22px rgba(255, 209, 102, .95)); transform: scale(1.6); }

/* YouTube beat player */
#yt-player-wrap { display: flex; justify-content: center; margin: 8px auto 0; max-width: 380px; position: relative; }
#yt-player-wrap iframe { border-radius: 12px; width: 100%; height: auto; aspect-ratio: 16 / 9; } /* YT API 默认 640×360 固定像素会溢出容器；铺满并锁 16:9 */
/* iOS autoplay unblock hint (YTEngine._showArmHint): tap-through banner above the player, never intercepts the click */
.yt-arm-hint {
  position: absolute; top: -32px; left: 50%; transform: translateX(-50%);
  background: rgba(16, 16, 20, .92); color: var(--gold); font-weight: 800; font-size: .85rem;
  padding: 7px 15px; border-radius: 999px; pointer-events: none; z-index: 5; white-space: nowrap;
  border: 1px solid rgba(240, 174, 48, .45);
  animation: yt-arm-pulse 1.2s ease-in-out infinite;
}
@keyframes yt-arm-pulse { 50% { opacity: .5; } }
#yt-player-wrap iframe.sc-embed, #ab-preview-wrap iframe.sc-embed { aspect-ratio: auto; height: 166px; } /* SC classic widget 原生高度 166px，不走 16:9 */

/* ---------- Flow practice track ---------- */
#flow-road { position: relative; max-width: 620px; margin: 18px auto 0; padding: 8px 0; }
.flow-row {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
  opacity: .55; transition: opacity .2s, transform .2s;
}
.flow-row.active { opacity: 1; border-radius: 10px; outline: 1px solid rgba(240, 174, 48, .85); outline-offset: 1px; }
.flow-row.past { opacity: .3; }
.flow-row-num { width: 22px; text-align: center; color: var(--ink-soft); font-size: .75rem; }
.flow-cells { display: flex; gap: 6px; flex: 1; }
.flow-cell { flex: 1; height: 38px; background: #2a2a30; border-radius: 6px; border: 1px solid #3a3a42; }
.flow-row.active .flow-cell { background: #3d3d45; border-color: #55555f; }
.flow-word {
  position: relative; /* anchor for the overlay effects that must not mask the card's own box-shadow (verdict tints): timing-ring ::before, beat-cue ::after, hitwave spans */
  min-width: 108px; text-align: center; padding: 9px 14px; border-radius: 6px;
  font-weight: 800; font-size: 1rem; color: #101014; letter-spacing: .3px;
}
.flow-word-empty { background: var(--bg-card); color: #55555f; font-weight: 400; }
#flow-ball {
  position: absolute; left: 0; top: 0; width: 28px; height: 28px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #ffffff, #c9c9c9);
  box-shadow: 0 4px 14px rgba(255, 255, 255, .4);
  opacity: 0; /* hidden until JS places it (cold-visit fix 2026-09-13: a glowing ball sat at 0,0 of the empty stage for seconds before boot) — flowStart/flowBallTo set inline opacity 1 */
  transition: opacity .2s; pointer-events: none; z-index: 5;
}
#flow-ball.landing { box-shadow: 0 0 26px 8px rgba(240, 174, 48, .9); }
#flow-ball::after { content: ""; position: absolute; inset: -7px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .25); }

/* flow controls */
.flow-controls { display: flex; gap: 10px; justify-content: center; align-items: center; margin-top: 16px; flex-wrap: wrap; }
.flow-btn {
  background: var(--bg-card); color: var(--ink); border: 1px solid var(--line);
  border-radius: 10px; height: 40px; padding: 0 20px; font-weight: 800; font-size: .9rem; font-family: inherit;
  display: inline-flex; align-items: center;
}
.flow-btn:hover { border-color: var(--accent); }
.flow-btn.small { padding: 0 14px; font-size: .8rem; color: var(--ink-soft); }
#flow-beat-label { text-align: center; color: var(--ink-soft); font-size: .9rem; margin-top: 14px; font-weight: 700; }
/* in-game HUD: beat label + live mic badge as one centered group; judgment trail below */
#flow-hud { margin-top:14px; scroll-margin-top:12vh; } /* Play 跳顶目标：HUD 停在视口上部（≈12% 屏高处），词轨落在人眼自然视线区——贴顶盯全程脖子累 */
#flow-hud .hud-top { display:flex; justify-content:center; align-items:center; gap:8px; }
#flow-hud #flow-beat-label { margin-top:0; }
#flow-mic-live { display:flex; align-items:center; gap:6px; color:#55565e; }
#flow-mic-live svg { width:14px; height:14px; }
#flow-mic-live.on { color:#6bff9e; }
#flow-mic-live .eq { display:flex; align-items:flex-end; gap:2px; height:12px; }
#flow-mic-live .eq b { width:3px; height:100%; background:currentColor; border-radius:1px; transform:scaleY(.12); transform-origin:bottom; }
/* judgment trail: one slot per playable bar, verdict colors match the word-card outlines */
#flow-trail { display:flex; gap:4px; justify-content:center; margin-top:8px; }
#flow-trail i { flex:0 1 14px; min-width:6px; max-width:14px; height:6px; border-radius:3px; background:#17171c; border:1px solid var(--line); transition:background .18s, border-color .18s; }
#flow-trail i.cur { border-color:var(--accent); animation:trailPulse 1.1s ease-in-out infinite; }
#flow-trail i.t-done { background:rgba(240,174,48,.28); border-color:rgba(240,174,48,.45); }
#flow-trail i.t-perfect { background:#6bff9e; border-color:#6bff9e; }
#flow-trail i.t-great { background:#a3e635; border-color:#a3e635; }
#flow-trail i.t-good { background:var(--gold); border-color:var(--gold); }
#flow-trail i.t-off { background:#ff9f43; border-color:#ff9f43; }
#flow-trail i.t-miss { background:transparent; border-color:#3a3a44; opacity:.55; }
#flow-trail i[data-rest] { opacity:.3; } /* X rest slot: dimmed, never fills */
#flow-trail i[data-rest].cur { opacity:1; } /* the moving cursor still shows on rest bars */
@keyframes trailPulse { 50% { box-shadow:0 0 8px rgba(240,174,48,.55); } }
.flow-stats { display: flex; gap: 26px; justify-content: center; }
.flow-stats div { display: flex; flex-direction: column; align-items: center; }
.flow-stats b { font-size: 1.6rem; color: var(--gold); }
.flow-stats span { color: var(--ink-soft); font-size: .8rem; }

/* flow setup reuses the beat-cards / opt-chip styles */
#flow-setup .big-start { margin-top: 24px; }

/* the hidden attribute must override component display */
[hidden] { display: none !important; }
#flow-stage { position: relative; }

/* watermark: rides every screen recording (TK funnel: 2.2M plays showed the game with zero
   branding, comments literally asked "what is this"). Overlay at the stage's bottom edge —
   zero layout shift (buttons don't move), zero interaction, visible from first paint. */
#flow-watermark {
  position: absolute; left: 50%; bottom: -8px; transform: translateX(-50%);
  font-size: 12px; letter-spacing: .08em; color: var(--ink-soft);
  opacity: .5; pointer-events: none; user-select: none; white-space: nowrap; z-index: 5;
}

/* synthesized-beat fallback placeholder card */
.synth-fallback {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 22px; color: var(--ink); font-size: .9rem;
}
.synth-fallback span { color: var(--ink-soft); font-size: .72rem; }

/* flow persistent game area + beat-pick launch area */
.flow-launch { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-top: 12px; }
/* setup card: beat/topic pickers as labeled fields on one shared panel (2026-10-12 launch redesign) */
.setup-card {
  display: flex; align-items: flex-end; gap: 14px; width: 100%; max-width: 520px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px; padding: 12px 16px 14px;
}
.setup-field { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.setup-field label {
  font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-soft); padding-left: 2px;
}
#flow-beat-select, #flow-topic-select {
  background: var(--bg); color: var(--ink); border: 1px solid var(--line);
  border-radius: 10px; padding: 0 16px; font-size: .9rem; font-weight: 700; font-family: inherit;
  height: 42px; cursor: pointer; min-width: 0; max-width: 100%; width: 100%;
}
#flow-beat-select:focus, #flow-topic-select:focus { outline: none; border-color: var(--accent); }
/* my-words edit entry: a quiet ghost chip closing the setup card (EN-only element) */
.mw-edit { padding: 0 14px; height: 42px; font-size: .82rem; flex-shrink: 0; }
/* editor preview: accepted words as chips showing their rhyme family (link chip only when a /rhymes/ page exists) */
.mw-preview { margin: 10px 0 4px; display: flex; flex-wrap: wrap; gap: 8px; }
.mw-preview:empty { display: none; }
.mw-chip { background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px; padding: 6px 10px; font-size: .8rem; color: var(--ink); }
.mw-chip small { display: block; color: var(--ink-soft); font-size: .68rem; margin-top: 2px; }
a.mw-chip { text-decoration: none; }
a.mw-chip:hover { border-color: var(--accent); }
a.mw-chip small em { color: var(--accent); font-style: normal; }
/* editor suggestions: one-click "add this easier rhyme" chips (our common10k corpus doing the
 * difficulty-smoothing for the user's own list) */
.mw-suggest { margin: 4px 0 8px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.mw-suggest:empty { display: none; }
.mw-sug-label { color: var(--ink-soft); font-size: .75rem; text-transform: uppercase; letter-spacing: 1px; width: 100%; }
button.mw-sug { cursor: pointer; border-style: dashed; font-family: inherit; }
button.mw-sug:hover { border-color: var(--accent); color: var(--accent); }
/* save→see-it feedback: user's own words carry a ★ on the track; the topic select pulses once on save */
.mw-star { font-style: normal; font-size: .68em; vertical-align: super; margin-right: 3px; color: #ffd75e; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
@keyframes mwPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 215, 94, 0); } 50% { box-shadow: 0 0 0 5px rgba(255, 215, 94, .45); } }
#flow-topic-select.mw-pulse { animation: mwPulse .8s ease-in-out 2; border-color: #ffd75e; }
#flow-vid-chips { display: flex; gap: 8px; align-items: center; }
/* Play spans the full setup-card width: one aligned column, one obvious primary action */
.flow-launch .big-start { margin-top: 0; width: 100%; max-width: 520px; padding-left: 0; padding-right: 0; text-align: center; }

/* Daily Mix daily-combo card: merged with the leaderboard toggle into one capsule */
#daily-mix { display: flex; width: 100%; max-width: 520px; }
.daily-mix-btn {
  background: rgba(240, 174, 48, .08);
  border: 1px solid var(--line); border-radius: 12px 0 0 12px; color: var(--ink);
  padding: 10px 22px; font-size: .9rem; cursor: pointer; font-family: inherit;
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;
}
.daily-mix-btn:hover { border-color: var(--accent); }
.daily-mix-btn b { color: var(--accent); }
.daily-mix-btn.done { opacity: .65; }
#daily-mix .lb-toggle {
  margin-top: 0; opacity: 1; text-decoration: none; flex-shrink: 0; display: inline-flex; align-items: center;
  background: rgba(240, 174, 48, .08); border: 1px solid var(--line); border-left: none;
  border-radius: 0 12px 12px 0; padding: 10px 14px; color: var(--ink-soft); font-size: .78rem;
}
#daily-mix .lb-toggle:hover { border-color: var(--accent); color: var(--accent); opacity: 1; }

/* quiet row: add-beat / challenge / options — literally .flow-btn.small chips (same class as
   the New words / Lines row above), just grouped tighter under Play */
.quiet-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; }
.quiet-row .opts-toggle { opacity: 1; } /* the legacy .opts-toggle dim would single out Options in a row that should read uniform */

/* mic toggle as a status pill: the dot reads live state (gray off / green breathing on) */
#mic-toggle { border-radius: 999px; gap: 8px; }
#mic-toggle::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #55555f; flex-shrink: 0; }
#mic-toggle[aria-pressed="true"]::before { background: #6bff9e; animation: micDot 1.6s ease-in-out infinite; }
@keyframes micDot { 50% { opacity: .35; } }

/* ---------- Challenge (challenge.js) ---------- */
/* Challenge banner: gradient-border card, more prominent than the Daily card; text and buttons stack vertically on mobile */
#challenge-banner { width: 100%; max-width: 620px; }
#beat-banner { width: 100%; max-width: 620px; } /* beat-link landing card, reuses .chal-banner-card (flow.js renderBeatBanner) */
/* pre-paint skeleton: beat landings paint the card from frame 1 (JS only swaps text, geometry constant) → CLS 0 */
body.beat-landing #beat-banner { display: block; }
/* shared beat titles (raw YouTube titles, up to 60 chars) must never wrap — wrapping would shift the card between skeleton and filled states */
#beat-banner-name { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.chal-banner-card {
  position: relative;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: rgba(240, 174, 48, .1);
  border: 1px solid var(--accent); border-radius: var(--radius);
  padding: 16px 20px;
}
.chal-banner-text { flex: 1; min-width: 180px; font-size: .95rem; line-height: 1.5; }
.chal-banner-text b { color: var(--accent); }
.chal-banner-text span { color: var(--ink-soft); font-size: .85rem; }
.chal-score-col { text-align: center; }
.chal-score-big { font-size: 2.4rem; font-weight: 800; color: var(--gold); line-height: 1; }
.chal-score-big small { font-size: 1.1rem; color: var(--ink-soft); }
.chal-score-sub { font-size: .72rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }
#challenge-banner .big-start { flex-shrink: 0; }
#chal-exit, #beat-banner-x { position: absolute; top: 6px; right: 8px; padding: 2px 8px; }
@media (max-width: 520px) {
  .chal-banner-card { justify-content: center; text-align: center; }
  .chal-banner-text { flex-basis: 100%; }
}
.chal-broken { border-color: var(--line); }
.big-start:disabled { opacity: .45; cursor: default; }
/* Challenge in progress: hide the config area and the Daily card, keep only Play (challenge.js renames it to "Play the challenge") */
body.chal-active .flow-launch .setup-card,
body.chal-active .flow-launch .quiet-row { display: none; }
body.chal-active #daily-mix { display: none; }
body.chal-active #flow-reroll { display: none; } /* challenge mode locks the word-order seed, so reroll is pointless — hidden to avoid confusion */

/* Result area: self-reported score + comparison + rematch */
#challenge-result { margin: 4px auto 18px; max-width: 460px; }
.chal-ask { font-weight: 800; margin-bottom: 10px; }
.chal-ask-sub { color: var(--ink-soft); font-weight: 400; font-size: .85rem; }
.chal-score-row { display: flex; align-items: center; gap: 10px; justify-content: center; margin-bottom: 14px; }
.chal-score-row input[type=range] { flex: 1; max-width: 260px; accent-color: var(--accent); height: 32px; }
.chal-score-row b { color: var(--gold); font-size: 1.3rem; }
.chal-score-row span { color: var(--ink-soft); }
.chal-nudge { display: flex; align-items: center; gap: 10px; justify-content: center; flex-wrap: wrap; margin-bottom: 14px; }
.chal-nudge span { color: var(--ink-soft); font-size: .85rem; }
.chal-nudge .ghost-btn { font-size: .85rem; padding: 6px 14px; }
#challenge-result .big-start { margin-top: 0; padding: 12px 30px; font-size: 1rem; }
.chal-verdict { font-size: 1.15rem; font-weight: 800; margin-bottom: 14px; }
.chal-verdict b { color: var(--gold); }
.chal-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; align-items: center; }
.chal-actions .big-start { margin-top: 0; padding: 12px 24px; font-size: .95rem; }

/* Create-challenge modal (reuses the add-beat-box shell) */
.chal-summary {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 14px; font-size: .85rem; color: var(--ink-soft); margin-bottom: 4px;
}
#chal-link { font-size: .8rem; color: var(--ink-soft); }
#challenge-modal input[type=range] { width: 100%; accent-color: var(--accent); height: 32px; }
/* On mobile, modal buttons stack vertically with the primary button full-width (stops big-start from wrapping into a clump) */
@media (max-width: 600px) {
  #challenge-modal .ab-actions, #add-beat-modal .ab-actions, #fb-modal .ab-actions { flex-direction: column; }
  #challenge-modal .ab-actions button, #add-beat-modal .ab-actions button, #fb-modal .ab-actions button { width: 100%; }
  #challenge-modal .ab-actions .big-start, #add-beat-modal .ab-actions .big-start, #fb-modal .ab-actions .big-start { padding: 13px 20px; font-size: 1rem; }
}

/* Hints=None: word cards reduced to rhyme-family color blocks ("?" dimmed into the base color, pure freestyle) */
.flow-word-blank { color: rgba(16, 16, 20, .5); }

/* SEO collapsible block: content stays in the HTML (visible to crawlers), collapsed by default in the UI */
.seo-block details h2 { display: inline; font-size: 1rem; margin: 0; }
.seo-block summary { list-style: none; }
.seo-block summary::-webkit-details-marker { display: none; }
.seo-block summary::before { content: "▸ "; color: var(--accent); }
.seo-block details[open] summary::before { content: "▾ "; }

/* Custom-library modal + create-challenge modal + feedback modal + my-words editor (shared overlay styles) */
#add-beat-modal, #challenge-modal, #fb-modal, #mywords-modal {
  position: fixed; inset: 0; background: rgba(10, 8, 20, .78);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
#fb-modal[hidden], #mywords-modal[hidden] { display: none !important; }
.add-beat-box {
  background: var(--bg-card-2); border: 1px solid var(--line); border-radius: 20px;
  padding: 26px 28px; width: 100%; max-width: 460px; box-sizing: border-box;
  /* short viewports (small laptops, landscape phones): the box is taller than the screen and the
   * overlay doesn't scroll, so the submit button fell below the fold unreachable (2026-09-16 feedback) */
  max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overflow-y: auto;
}
.add-beat-box h3 { margin-bottom: 6px; }
.ab-hint { color: var(--ink-soft); font-size: .85rem; margin-bottom: 14px; }
.add-beat-box label { display: block; color: var(--ink-soft); font-size: .75rem; margin: 14px 0 6px; text-transform: uppercase; letter-spacing: 1px; }
.add-beat-box input[type=text], .add-beat-box input[type=number], .add-beat-box textarea {
  width: 100%; background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); padding: 10px 14px; font-size: .95rem; font-family: inherit; box-sizing: border-box;
}
.add-beat-box textarea { resize: vertical; min-height: 96px; margin-bottom: 10px; }
.add-beat-box input:focus, .add-beat-box textarea:focus { outline: none; border-color: var(--accent); }
/* feedback honeypot: humans never see it, autofill bots do */
#fb-hp { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; opacity: 0; }
/* lightweight feedback entry points: dotted-underline links, deliberately quieter than buttons */
.result-fb { display: inline-block; margin-top: 16px; font-size: .8rem; color: var(--ink-soft); text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.result-fb:hover { color: var(--ink); }
.fb-report { display: inline-block; margin-top: 8px; font-size: .78rem; color: var(--ink-soft); text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.fb-report:hover { color: var(--accent); }
/* feedback stars (modal + inline result-screen row) */
.fb-stars { display: inline-flex; gap: 2px; }
.fb-star { background: none; border: none; padding: 2px 4px; font-size: 1.5rem; line-height: 1; color: #3a3a42; cursor: pointer; transition: color .08s, transform .08s; }
.fb-star.on { color: var(--accent); }
.fb-star:hover { transform: scale(1.15); }
/* feedback category chips: single-select pills */
.fb-cats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.fb-cat { background: var(--bg-card); border: 1px solid var(--line); border-radius: 999px; color: var(--ink-soft); padding: 6px 12px; font-size: .8rem; font-family: inherit; cursor: pointer; }
.fb-cat:hover { border-color: var(--accent); color: var(--ink); }
.fb-cat.on { border-color: var(--accent); color: var(--accent); }
/* inline rate row on the result screen (quiet: no popup, one tap sends) */
.fb-rate { margin-top: 16px; font-size: .85rem; color: var(--ink-soft); display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; }
.fb-rate .fb-star { font-size: 1.2rem; }
.fb-rate-thx { color: var(--good); font-weight: 700; }
.fb-rate-more { color: var(--ink-soft); text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.fb-rate-more:hover { color: var(--ink); }
.add-beat-box #ab-analyze { margin-top: 10px; }
.ab-row { display: flex; gap: 12px; }
.ab-field { flex: 1; }
.ab-x2-wrap { display: flex; gap: 8px; }
.ab-x2-wrap input { flex: 1; }
.ab-x2-wrap .opt-chip { height: 38px; padding: 0 16px; flex-shrink: 0; }
.ab-status { min-height: 22px; margin-top: 10px; font-size: .85rem; color: var(--ink-soft); font-weight: 700; }
.ab-status.good { color: var(--good); }
/* Analyzing: spinner + rotating status text (analysis takes 30-60s; static text would make users think it froze and leave) */
.ab-spinner { display: inline-block; width: 13px; height: 13px; margin-right: 8px; vertical-align: -2px;
  border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%;
  animation: ab-spin .8s linear infinite; }
@keyframes ab-spin { to { transform: rotate(360deg); } }
.ab-status.ab-working { color: var(--accent); }
#ab-analyze:disabled { opacity: .55; cursor: wait; }

/* First-visit 3-step guide + mic-first CTA (permanently dismissed via ✕ or after any CTA starts a game; localStorage rg_seen_guide) */
/* First-paint state split (2026-09-13 CLS fix round 2): the static HTML ships in the FIRST-VISIT state
   (guide visible, mic pill folded) and the inline head script tags body.returning / body.challenge-landing /
   body.beat-landing BEFORE the game markup parses — so all populations paint their final layout with zero JS wait.
   flow.js initFirstGuide keeps the hidden attribute as the JS-side source of truth (sticky-play reads it). */
body.returning #first-guide, body.challenge-landing #first-guide, body.beat-landing #first-guide { display: none; }
body:not(.returning):not(.challenge-landing):not(.beat-landing) #mic-toggle { display: none; }
.first-guide { position: relative; background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  padding: 10px 30px 10px 14px; margin-bottom: 10px; font-size: .88rem; color: var(--ink-soft); text-align: left; }
.first-guide .fg-title { font-weight: 800; color: var(--ink); margin-bottom: 4px; }
.first-guide ol.fg-steps { margin: 0 0 6px; padding-left: 20px; }
.first-guide .fg-steps li { margin: 1px 0; }
.first-guide .fg-mic { border-top: 1px dashed var(--line); padding-top: 6px; }
.first-guide .fg-mic b { color: var(--accent); }
.first-guide .fg-cta { display: flex; gap: 10px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
/* mic CTA runs outlined gold, not solid: the one solid-gold seat on the page belongs to the real
   PLAY button (design-review 2026-10-09 — two solid-gold CTAs competed, and the guide's smaller one won clicks) */
/* 2026-10-09 rollback: the 10-09 outline restyle dropped guide-via mic grants 330→114 (-65%) — on
   first visit this button IS the mic ask, demoting it cost real mic adoption. Gold stays. */
.first-guide .fg-primary { background: var(--accent); color: #101014; font-weight: 800; font-size: .9rem;
  border-radius: 8px; padding: 10px 18px; display: inline-flex; align-items: center; }
.first-guide .fg-primary:hover { background: #ffc14d; }
.first-guide .fg-secondary { background: transparent; color: var(--ink-soft); font-size: .85rem;
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 14px; }
.first-guide .fg-secondary:hover { color: var(--ink); border-color: var(--accent); }
.first-guide-x { position: absolute; top: 8px; right: 10px; background: none; border: none;
  color: var(--ink-soft); font-size: .9rem; cursor: pointer; opacity: .6; padding: 2px 6px; }
.first-guide-x:hover { opacity: 1; }
.ab-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 24px; align-items: center; flex-wrap: wrap; }
.ab-actions .big-start { margin: 0; }

/* Add beat manual-fallback tool area (preview + tap-tempo + drum-hit placement) */
.ab-tools { margin-top: 16px; border-top: 1px dashed var(--line); padding-top: 12px; }
.ab-tools-title { color: var(--ink-soft); font-size: .8rem; margin: 0 0 10px; }
#ab-preview-wrap { margin-bottom: 10px; border-radius: 12px; overflow: hidden; }
#ab-preview-wrap iframe { width: 100%; aspect-ratio: 16 / 9; display: block; }
.ab-tools-row { display: flex; gap: 10px; }
.ab-tools-row .opt-chip { flex: 1; height: 40px; }

/* Small brand icon (logo graphic in header/footer) */
.brand-icon { width: 20px; height: 20px; border-radius: 5px; vertical-align: -3px; margin-right: 6px; }

/* Mobile above-the-fold compression: keep the Play button fully visible, no horizontal scrolling */
@media (max-width: 600px) {
  /* Header nav: link row is a scrollable strip — 5-6 links (Progress added 2026-09-11) at any label
     length must never push the page wider than the viewport (scrollbar hidden, swipe reveals the rest) */
  .site-header { padding: 12px 14px; }
  .brand { font-size: 1.05rem; flex-shrink: 0; }
  .site-nav { overflow-x: auto; scrollbar-width: none; }
  .site-nav::-webkit-scrollbar { display: none; }
  .site-nav a { margin-left: 12px; font-size: .85rem; }
  .hero-head { padding: 4px 0 0; }
  .hero-h1 { font-size: 1.35rem; margin-bottom: 4px; }
  .tagline { font-size: .9rem; line-height: 1.45; margin-bottom: 8px; }
  .flow-launch { margin-top: 8px; gap: 10px; }
  /* setup card wraps on phones: fields share a row, ✎ My words drops to its own line right-aligned */
  .setup-card { flex-wrap: wrap; gap: 10px 12px; padding: 12px 14px; }
  .setup-field { flex: 1 1 40%; }
  .mw-edit { margin-left: auto; }
  /* in-game: fold the hero away so the track starts cleanly under the site nav — a half-scrolled
     tagline peeking above the game read as a broken layout (2026-09-03 Android screenshot) */
  body.in-game .hero-head { display: none; }
  /* stretch the gray beat cells into strips: slim the row numbers + word tile so the 3 cells
     share more width (~52px→~70px each at 360px) — squares read as boxes, strips read as a beat timeline */
  .flow-row { gap: 6px; margin-bottom: 6px; }
  .flow-row-num { width: 14px; font-size: .65rem; }
  .flow-cells { gap: 4px; }
  .flow-word { min-width: 84px; padding-left: 8px; padding-right: 8px; }
  /* 2026-09-11 mobile bounce fix, pass 2: on a 406×879 phone Play still sat at y≈899 (below the
     fold) for returning visitors, and the first-visit guide's CTA was cut at the bottom edge —
     tighten the whole above-the-fold stack so Play lands inside the first screen. */
  #flow-hud { margin-top: 6px; }
  #flow-road { margin-top: 10px; padding: 4px 0; }
  .flow-cell { height: 34px; }
  .flow-controls { margin-top: 10px; }
  .flow-launch { gap: 8px; }
  .daily-mix-btn { padding: 8px 14px; font-size: .85rem; }
  .first-guide { padding: 8px 26px 8px 12px; margin-bottom: 8px; }
  /* the mic-value pitch line pushes the guide's own Play CTAs below the fold on phones — the
     primary button already says "Play with mic", so the line goes on small screens */
  .first-guide .fg-mic { display: none; }
  /* returning players know the pitch — fold the second tagline line so Play moves up ~1 line */
  body.returning .tagline-cta { display: none; }
  /* sticky Play bar: fixed-bottom fallback shown by flow.js initStickyPlay while the real Play is
     scrolled off-screen. display:none by default (below); only ≤600px unhides it. */
  #sticky-play:not([hidden]) { display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
    background: linear-gradient(rgba(10,10,10,0), var(--bg) 45%); }
  #sticky-play .big-start { margin: 0; width: 100%; padding: 13px 20px; font-size: 1.1rem; }
  body.sticky-play-on { padding-bottom: 86px; }
  /* touch targets ≥44px (2026-10-09 design-review P1): audit measured nav=19px, Options=36,
     New words=40, ✕ buttons=23×21, fb-star=28, lb-toggle=16 on phones — all sub-WCAG.
     Fattened only inside this mobile media query: desktop keeps its tight look (mouse precision
     doesn't need 44px), phones get real targets. Header loses 8px of padding to pay for the
     taller nav links so the above-the-fold stack doesn't drift down. */
  .site-header { padding: 8px 14px; }
  .site-nav a { padding: 10px 4px; }
  .ghost-btn, .ghost-btn.opts-toggle { padding: 12px 18px; } /* .opts-toggle's own rule comes later in the file — the double-class keeps the fat target winning */
  .opt-chip, #flow-options .opt-chip { padding: 13px 16px; }
  #flow-beat-select, #flow-topic-select { height: 44px; }
  #daily-mix .lb-toggle { padding: 14px 12px; }
  .mw-edit { height: 44px; }
  .flow-btn { height: 44px; }
  .daily-mix-btn { padding: 13px 14px; }
  .lb-toggle { padding: 14px 8px; }
  .fb-star { padding: 10px; }
  .first-guide-x { padding: 12px; }
  .ach-t-x { padding: 12px; }
  #chal-exit, #beat-banner-x { padding: 10px; }
  .first-guide .fg-primary, .first-guide .fg-secondary { min-height: 44px; }
  #mic-toggle { min-height: 48px; }
}
#sticky-play { display: none; }

/* Result-first settlement (2026-09-09): on the result screen everything that isn't the score leaves
 * the stage — header, hero, challenge card, the whole launch cluster, SEO blocks and footer.
 * The score is the first thing you see, not the slogan. again-btn lifts the clear via flowSetState. */
body.post-run .site-header,
body.post-run #ru-lang-banner,
body.post-run .hero-head,
body.post-run #challenge-banner,
body.post-run .flow-launch,
body.post-run main > .seo-block,
body.post-run .site-footer { display: none; }

/* mic on-beat judging (judge.js) */
.mic-hint { font-size:12px; color:var(--ink-soft); margin:6px 0 2px; } /* 负 margin 时代是跟旧 label 布局配套的；现在有轨迹条，保持正间距防重叠 */
/* hidden 时也占位：hint 出现/消失不再推挤词轨（display:none 由 [hidden] 来，覆盖成 block+invisible） */
#flow-mic-hint { height: 1.5em; line-height: 1.5em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; }
#flow-mic-hint[hidden] { display: block !important; visibility: hidden; } /* override the global [hidden]!important rule for this one element: it must keep its seat while invisible */
/* say-cue：沉默若干小节后当前词卡金色脉动（纯 box-shadow 动画，零布局位移） */
.flow-row .flow-word.say-cue { animation:sayCue .9s ease-in-out infinite; }
@keyframes sayCue { 50% { box-shadow:0 0 0 3px var(--accent) inset, 0 0 16px rgba(240,174,48,.5); } }
.mic-hint a { color: var(--accent); }
#mic-blocked-hint { color: var(--bad); } /* persistent rescue line under the Mic button while the browser has mic hard-blocked */
/* line-hint: example line for the current word (beginner scaffolding — read it or imitate it). Three states:
   off-screen (display:none, setup/result) → in-run but nothing to show (keeps its seat, invisible) → visible.
   The .on class is the "in a run" flag so the global [hidden]{display:none!important} never collapses the seat mid-run. */
#flow-line-hint { display:none; height:2.7em; line-height:1.35em; text-align:center; font-size:12.5px; color:var(--ink-soft); overflow:hidden; margin:0 0 2px; }
#flow-line-hint.on { display:block; }
#flow-line-hint.on[hidden] { display:block !important; visibility:hidden; }
#flow-line-hint b { color:var(--accent); font-weight:600; }
#flow-lines-toggle[aria-pressed="false"] { opacity:.55; }
#mic-toggle { padding:12px 26px; font-size:.95rem; justify-content:center; }
#mic-toggle[aria-pressed="false"] { border-color:var(--accent); color:var(--accent); }
#mic-toggle[aria-pressed="false"]:hover:not(:disabled) { background:rgba(240,174,48,.08); box-shadow:0 4px 18px rgba(240,174,48,.18); }
#mic-toggle[aria-pressed="true"] { border-color:#6bff9e; color:#6bff9e; }
#mic-toggle:disabled { opacity:.45; cursor:not-allowed; border-color:var(--line); color:var(--ink-soft); } /* 游戏中 disable 时盖住金边 */
#mic-toggle:disabled[aria-pressed="true"] { border-color:#6bff9e; color:#6bff9e; } /* 判定中绿框保留作指示灯，仅靠 opacity 表达不可点 */
.flow-row .flow-word.j-perfect { box-shadow:0 0 0 3px #6bff9e inset, 0 0 14px rgba(107,255,158,.4); }
.flow-row .flow-word.j-great { box-shadow:0 0 0 3px #a3e635 inset; }
.flow-row .flow-word.j-good { box-shadow:0 0 0 3px var(--gold) inset; }
.flow-row .flow-word.j-off { box-shadow:0 0 0 3px #ff9f43 inset; opacity:.75; }
.flow-row .flow-word.j-miss { opacity:.45; filter:grayscale(.6); }
/* hit juice: word card pops on perfect/great (transform-only, zero layout shift) */
.flow-row .flow-word.j-pop { animation:wordPop .22s ease-out; }
@keyframes wordPop { 40% { transform:scale(1.09); } 100% { transform:scale(1); } }
/* beat-4 cue: one-shot ring flash at the judge target downbeat (4k+3), drawn on an ::after overlay
   so it can never mask the card's own box-shadow (verdict tints) or transform (j-pop) — hit feedback
   stays fully visible. Adaptive: flow.js arms it only for heard-but-mistimed speakers. */
.flow-row .flow-word.beat-cue::after {
  content:''; position:absolute; inset:-4px; border-radius:9px; pointer-events:none;
  animation:beatCue .3s ease-out;
}
@keyframes beatCue {
  0% { box-shadow:0 0 0 3px var(--accent), 0 0 18px rgba(240,174,48,.8); }
  100% { box-shadow:0 0 0 0 rgba(240,174,48,0), 0 0 0 rgba(240,174,48,0); }
}
/* P1 timing ring: a 2.5px halo converges onto the active word card across the bar and lands exactly
   on the beat-4 judge target — "speak when the ring closes". Drawn on ::before (beat-cue owns ::after);
   transform/opacity only, zero layout. One run per bar: flowRenderRows rebuilds the rows at every bar
   change, and the per-bar duration comes from the inline --ringbar var (240/bpm s, set by flow.js). */
.flow-row .flow-word.ring::before {
  content:''; position:absolute; inset:-3px; border-radius:9px; pointer-events:none; opacity:0;
  border:2.5px solid rgba(255,255,255,.55);
  animation:flowRing var(--ringbar, 2.18s) linear 1;
}
@keyframes flowRing {
  0%   { transform:scale(1.25); opacity:0; border-color:rgba(255,255,255,.55); box-shadow:0 0 0 rgba(240,174,48,0); }
  10%  { opacity:.35; }
  25%  { opacity:.55; } /* beat-2 breathe */
  30%  { opacity:.4; }
  50%  { opacity:.6; }  /* beat-3 breathe */
  55%  { opacity:.45; }
  75%  { transform:scale(1.05); opacity:.7; border-color:rgba(240,200,90,.75); } /* beat 4 turns gold */
  96%  { transform:scale(1.0); opacity:1; border-color:var(--accent); box-shadow:0 0 18px rgba(240,174,48,.85); }
  100% { transform:scale(1.0); opacity:0; }
}
/* pause freezes the game clock (ball stops via flowTick) — freeze the ring with it or a mid-bar
   pause lets the animation finish early and desync from the beat on resume */
body.paused .flow-word.ring::before { animation-play-state:paused; }
/* hit shockwave: a judged hit fires an expanding ring off the card (the converge ring's counterpart:
   ring closes = prepare, wave bursts = hit). Tier-colored; miss/off never fire. Perfect gets a second
   fainter ripple 90ms late — the "aftershock". flow.js removes the spans ~650ms after the verdict. */
.flow-word .hitwave { position:absolute; inset:0; border-radius:6px; pointer-events:none; animation:hitwave .38s ease-out forwards; }
.flow-word .hitwave.t-perfect { border:2.5px solid #6bff9e; box-shadow:0 0 22px rgba(107,255,158,.65); }
.flow-word .hitwave.t-great { border:2px solid #a3e635; box-shadow:0 0 14px rgba(163,230,53,.5); }
.flow-word .hitwave.t-good { border:1.75px solid rgba(240,174,48,.9); }
.flow-word .hitwave.d2 { border-width:1.5px; box-shadow:none; opacity:0; animation:hitwave2 .5s ease-out .09s; }
@keyframes hitwave { 0% { transform:scale(1.0); opacity:.95; } 100% { transform:scale(1.45); opacity:0; } }
@keyframes hitwave2 { 0% { transform:scale(1.0); opacity:0; } 12% { opacity:.55; } 100% { transform:scale(1.62); opacity:0; } }
/* HUD streak counter */
.flow-streak { font-weight:700; font-size:.9rem; color:var(--accent); letter-spacing:.02em; }
.flow-streak.pop { animation:streakPop .25s ease-out; }
@keyframes streakPop { 40% { transform:scale(1.35); } 100% { transform:scale(1); } }

/* ---------- Endless mode (flow.js renderEndlessCard) ---------- */
/* endless lives as a 4th Duration chip (8/16/32/∞) — zero extra vertical space; locked = 🔒 teaser, the lock is the ad */
.endless-chip.locked { opacity:.55; }
/* in-run lives (❤❤❤), HUD chip next to the streak counter */
.flow-lives { font-size:.9rem; letter-spacing:.12em; }
/* ≥100 bars survived: result-screen century stamp (flex item of #result-words → full row) */
.endless-century { width:100%; font-weight:800; color:var(--gold); text-align:center; margin:4px 0 14px; font-size:1.05rem; }
/* endless personal best banner (result screen): gold with a soft glow — the run just beat every run before it */
.endless-pb { width:100%; font-weight:800; color:var(--gold); text-align:center; margin:4px 0 10px; font-size:1rem; letter-spacing:.04em; text-shadow:0 0 18px rgba(255,209,102,.35); }
#result-verified { background:var(--bg-elevated); border:1px solid var(--line); border-radius:14px; padding:14px; margin:12px 0; text-align:center; }
#result-verified .vj-score { font-size:30px; font-weight:800; color:#6bff9e; }
#result-verified .vj-sub { font-size:13px; color:var(--ink-soft); margin-top:4px; }
#result-verified .vj-recal { margin-top:10px; font-size:13px; }
#result-verified .vj-early { margin-top:8px; color:var(--ink); }
#result-verified .vj-early-btn { margin-left:10px; font-size:13px; padding:4px 14px; }
#result-screen .daily-next { font-size:14px; color:var(--gold); margin:12px auto 0; max-width:520px; text-align:center; }

/* ---------- Daily leaderboard (leaderboard.js) ---------- */
.lb-toggle { background:none; border:none; color:var(--ink-soft); font-size:.78rem; cursor:pointer; font-family:inherit; margin-top:6px; opacity:.75; text-decoration:underline; text-underline-offset:3px; }
.lb-toggle:hover { opacity:1; color:var(--accent); }
.lb-panel { width:100%; max-width:620px; background:var(--bg-elevated); border:1px solid var(--line); border-radius:12px; padding:12px 16px; margin-top:8px; }
.lb-box { background:var(--bg-elevated); border:1px solid var(--line); border-radius:14px; padding:14px; margin:12px auto 0; max-width:520px; text-align:center; }
.lb-submit { display:flex; align-items:center; justify-content:center; gap:8px; flex-wrap:wrap; }
.lb-label { font-size:13px; font-weight:700; color:var(--gold); }
#lb-name { background:#0d0d10; border:1px solid var(--line); border-radius:8px; color:var(--ink); font-family:inherit; font-size:13px; padding:7px 10px; width:140px; }
#lb-name:focus { outline:none; border-color:var(--accent); }
.lb-go { background:rgba(240,174,48,.12); border:1px solid var(--line); border-radius:8px; color:var(--ink); font-family:inherit; font-size:13px; padding:7px 14px; cursor:pointer; }
.lb-go:hover { border-color:var(--accent); }
.lb-go:disabled { opacity:.5; cursor:default; }
.lb-placed { font-size:14px; color:var(--ink); margin-top:10px; }
.lb-placed b { color:#6bff9e; }
.lb-rows { margin-top:10px; text-align:left; }
.lb-row { display:flex; align-items:baseline; gap:10px; font-size:13px; padding:4px 2px; border-bottom:1px solid rgba(46,46,52,.6); }
.lb-row:last-child { border-bottom:none; }
.lb-row.lb-me { color:var(--gold); }
.lb-rank { width:34px; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.lb-name { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lb-score { color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.lb-me-line { font-size:12px; color:var(--gold); margin-top:8px; }
.lb-empty, .lb-loading { font-size:13px; color:var(--ink-soft); }
.lb-hook { font-size:13px; color:var(--ink-soft); line-height:1.5; }
.lb-hook b { color:var(--accent); }
.lb-err { font-size:13px; color:#ff8a8a; margin-top:8px; }

/* setup area cleanup: Options collapsible panel */
.opts-toggle { font-size:.85rem; padding:9px 18px; opacity:.75; }
.opts-toggle:hover { opacity:1; }
#flow-options .launch-row + .launch-row { margin-top:14px; }

/* ---------- Achievements: unlock toasts + progress panel (achievements.js / progress.js, design §5/§6) ---------- */
/* toasts: fixed top-center stack, max 2 cards + one "+N more" chip; each auto-hides in 6s, ✕ closes */
#ach-toasts { position:fixed; top:10px; left:50%; transform:translateX(-50%); z-index:220;
  width:min(440px, calc(100vw - 24px)); display:flex; flex-direction:column; gap:8px; }
.ach-toast { background:#1e1a33; border:1px solid #3a3358; border-left:3px solid var(--gold); border-radius:14px;
  padding:12px 14px; box-shadow:0 10px 34px rgba(0,0,0,.55); animation:achIn .28s ease-out; }
@keyframes achIn { from { opacity:0; transform:translateY(-12px); } to { opacity:1; transform:none; } }
.ach-toast.out { transition:opacity .3s, transform .3s; opacity:0; transform:translateY(-10px); }
/* result screen: the score is the hero — badge toasts yield the top edge to it (design-review
   2026-10-09: a first-run "Badge Unlocked" card landed right on top of the result title).
   post-run moves the stack to the bottom, enter/exit animations flip direction to match. */
body.post-run #ach-toasts { top: auto; bottom: 10px; }
body.post-run .ach-toast { animation-name: achInUp; }
@keyframes achInUp { from { opacity:0; transform:translateY(12px); } to { opacity:1; transform:none; } }
body.post-run .ach-toast.out { transform: translateY(10px); }
.ach-t-top { display:flex; justify-content:space-between; align-items:center;
  font-size:11px; color:#a89fc9; text-transform:uppercase; letter-spacing:.08em; }
.ach-t-x { background:none; color:#a89fc9; font-size:15px; padding:0 2px; line-height:1; }
.ach-t-x:hover { color:#fff; }
.ach-t-name { font-weight:800; font-size:16px; color:var(--gold); margin-top:3px; }
.ach-t-cond { font-size:12.5px; color:#c9c2e8; margin-top:2px; }
.ach-t-actions { display:flex; gap:8px; margin-top:10px; }
.ach-t-actions button { background:rgba(240,174,48,.12); border:1px solid #3a3358; border-radius:8px;
  color:var(--ink); font-size:12.5px; padding:6px 14px; }
.ach-t-actions button:hover { border-color:var(--accent); }
.ach-t-actions .ach-t-share { background:var(--accent); color:#101014; font-weight:700; border-color:var(--accent); }
/* toast key line (e.g. Locked In also unlocks endless mode): green accent under the condition text */
.ach-t-key { color:#6bff9e; font-weight:700; }
.ach-more { align-self:center; font-size:12px; color:#a89fc9; background:#171233;
  border:1px solid #262447; border-radius:999px; padding:4px 12px; }
/* toast tiers (v1.1): t1 = one size up with a gold frame; t2 = celebration card (SVG hero + one-liner, 10s) */
.ach-toast.t1 { padding:16px 20px; border:1px solid rgba(255,209,102,.6); border-left:3px solid var(--gold); }
.ach-toast.t1 .ach-t-name { font-size:18px; }
.ach-toast.t2 { padding:18px 20px; border:1px solid rgba(255,209,102,.85);
  background:linear-gradient(160deg, rgba(255,209,102,.14), rgba(201,138,26,.05)), #1e1a33;
  box-shadow:0 12px 40px rgba(0,0,0,.6), 0 0 24px rgba(255,209,102,.15); }
.ach-t-hero { display:flex; justify-content:center; margin:6px 0 2px; color:var(--gold); }
.ach-t-hero svg { width:44px; height:44px; display:block; }
.ach-toast.t2 .ach-t-name { text-align:center; font-size:19px; }
.ach-t-line { text-align:center; font-size:13px; font-weight:600; color:#f4ecd8; margin-top:2px; }
.ach-toast.t2 .ach-t-cond { text-align:center; }
/* legendary fireworks canvas (achievements.js _fireworks): above page content/modals, below the toasts */
#ach-fw { position:fixed; inset:0; width:100%; height:100%; pointer-events:none; z-index:200; }

/* result-screen entry link: same quiet dotted-link register as .result-fb */
.prog-link { display:inline-block; margin-top:10px; font-size:.8rem; color:var(--ink-soft);
  text-decoration:underline dotted; text-underline-offset:3px; }
.prog-link:hover { color:var(--accent); }

/* progress panel overlay (same overlay register as #add-beat-modal/#challenge-modal/#fb-modal) */
#progress-modal { position:fixed; inset:0; background:rgba(10,8,20,.78);
  display:flex; align-items:center; justify-content:center; z-index:120; padding:16px; }
#progress-modal[hidden] { display:none !important; }
.prog-box { background:var(--bg-card-2); border:1px solid var(--line); border-radius:20px;
  width:100%; max-width:520px; max-height:calc(100vh - 40px); overflow-y:auto; padding:20px 18px; box-sizing:border-box; }
.prog-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:14px; }
.prog-head h3 { font-size:1.05rem; margin:0; }
#prog-close { background:none; color:var(--ink-soft); font-size:19px; padding:0 2px; line-height:1; }
#prog-close:hover { color:var(--ink); }
.prog-chips { display:grid; grid-template-columns:repeat(4, 1fr); gap:8px; }
.prog-chip { background:var(--bg-elevated); border:1px solid var(--line-2); border-radius:12px; padding:9px 4px; text-align:center; }
.prog-chip b { display:block; font-size:16px; font-weight:800; color:#fff; }
.prog-chip span { font-size:10px; color:var(--ink-soft); letter-spacing:.03em; }
.prog-form { background:var(--bg-elevated); border:1px solid var(--line-2); border-radius:12px; padding:12px 14px; }
.prog-form.off { color:var(--ink-soft); font-size:13px; text-align:center; }
.prog-form.pf-endless { margin-top:8px; }
.pf-line { font-size:13px; color:#c9c2e8; }
.acc-bar { height:10px; background:var(--line-2); border-radius:6px; overflow:hidden; margin:8px 0; }
.acc-bar i { display:block; height:100%; background:linear-gradient(90deg, #ff4d8d, #b06bff); border-radius:6px; }
.pf-sub { font-size:12px; color:var(--ink-soft); }
.prog-group-t { font-size:11px; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.08em; margin:18px 0 8px; }
.badge-card { display:flex; gap:11px; align-items:center; background:var(--bg-elevated); border:1px solid var(--line-2);
  border-radius:12px; padding:10px 12px; margin-bottom:8px; }
.badge-card.unlocked { border-color:rgba(255,209,102,.45); background:#191527; }
.badge-card .b-ic { width:34px; height:34px; border-radius:10px; background:#0f0d1a;
  display:flex; align-items:center; justify-content:center; font-size:16px; flex:0 0 auto; }
.badge-card.unlocked .b-ic { background:rgba(255,209,102,.12); }
.badge-card .b-tx { flex:1; min-width:0; display:flex; flex-direction:column; }
.badge-card .b-nm { font-size:13.5px; font-weight:700; }
.badge-card.unlocked .b-nm { color:var(--gold); }
.badge-card .b-cd { font-size:11.5px; color:var(--ink-soft); margin-top:2px; }
.badge-card .b-dt { font-size:10.5px; color:#6bff9e; margin-top:3px; }
.b-pbar { height:8px; background:var(--line-2); border-radius:6px; overflow:hidden; margin-top:6px; }
.b-pbar i { display:block; height:100%; background:linear-gradient(90deg, #ff4d8d, #b06bff); border-radius:6px; }
.b-pt { font-size:10.5px; color:var(--ink-soft); margin-top:3px; font-variant-numeric:tabular-nums; }
/* badge tiers (v1.1): t0 stays plain. t1 = gradient frame + faint glow, emoji ~1.15x — Locked In is the
   key card (it unlocks endless) and runs gold, the rest run cold blue/violet. t2 = legendary: hand-drawn
   SVG mark on a gold wash; locked t2 shows the mark's silhouette — a trailer, not a debt. */
.badge-card.t1 { border:1px solid transparent;
  background:linear-gradient(var(--bg-elevated), var(--bg-elevated)) padding-box, linear-gradient(135deg, rgba(80,140,255,.55), rgba(176,107,255,.35)) border-box;
  box-shadow:0 0 12px rgba(110,120,255,.10); }
.badge-card.t1.unlocked { background:linear-gradient(#191527, #191527) padding-box, linear-gradient(135deg, rgba(80,140,255,.7), rgba(176,107,255,.5)) border-box; }
.badge-card.t1.key { background:linear-gradient(var(--bg-elevated), var(--bg-elevated)) padding-box, linear-gradient(135deg, rgba(255,209,102,.65), rgba(201,138,26,.4)) border-box;
  box-shadow:0 0 12px rgba(255,209,102,.12); }
.badge-card.t1.key.unlocked { background:linear-gradient(#191527, #191527) padding-box, linear-gradient(135deg, rgba(255,209,102,.85), rgba(201,138,26,.55)) border-box; }
.badge-card.t1 .b-ic { font-size:18.4px; }
.badge-card.t2 { position:relative; overflow:hidden; border-color:rgba(255,209,102,.4);
  background:linear-gradient(160deg, rgba(255,209,102,.09), rgba(201,138,26,.04)), #171422; }
.badge-card.t2.unlocked { border-color:rgba(255,209,102,.75);
  background:linear-gradient(160deg, rgba(255,209,102,.16), rgba(201,138,26,.07)), #1b1626;
  box-shadow:0 0 16px rgba(255,209,102,.12); }
.badge-card.t2 .b-ic { background:rgba(255,209,102,.10); color:var(--gold); }
.badge-card.t2 .b-ic svg { width:22px; height:22px; display:block; }
.badge-card.t2 .b-ic.veiled { background:#0f0d1a; color:#8b8496; }
.badge-card.t2 .b-ic.veiled svg { opacity:.38; filter:grayscale(1); }
/* unlocked legendaries: one restrained diagonal sheen sweeping by every few seconds (motion-safe only) */
@media (prefers-reduced-motion: no-preference) {
  .badge-card.t2.unlocked::after { content:''; position:absolute; top:-40%; bottom:-40%; left:0; width:34%;
    background:linear-gradient(105deg, transparent, rgba(255,244,214,.13), transparent);
    transform:translateX(-140%) skewX(-18deg); animation:achSheen 4.6s ease-in-out infinite; pointer-events:none; }
  @keyframes achSheen { 0% { transform:translateX(-140%) skewX(-18deg); }
    38% { transform:translateX(430%) skewX(-18deg); } 100% { transform:translateX(430%) skewX(-18deg); } }
}
.prog-reset { margin-top:20px; text-align:center; }
#prog-reset-btn { background:none; border:none; color:var(--ink-soft); font-size:11.5px;
  opacity:.6; text-decoration:underline dotted; text-underline-offset:3px; padding:4px 8px; }
#prog-reset-btn:hover { opacity:1; }
#prog-reset-btn[data-arm="1"] { color:var(--bad); opacity:1; }
.prog-reset-note { font-size:11px; color:var(--ink-soft); margin-top:6px; }
/* near-miss PB line on the result screen (design §6): small, neutral, no adjectives */
#result-verified .ach-near { color:var(--gold); }

/* crawlable footer language links; the current language is marked non-pointer + bold */
.footer-lang a[aria-current] { font-weight: 700; pointer-events: none; }

/* language switcher dropdown in the top nav (details/summary, no JS needed to open) */
.lang-menu { position: relative; display: inline-block; margin-left: 20px; }
.lang-menu summary { list-style: none; cursor: pointer; color: var(--ink-soft); padding: 5px 12px; border: 1px solid var(--line); border-radius: 999px; font-size: .85rem; user-select: none; white-space: nowrap; }
.lang-menu summary::-webkit-details-marker { display: none; }
.lang-menu summary:hover { color: var(--ink); }
.lang-menu[open] summary { color: var(--accent); border-color: var(--accent); }
.lang-menu .lang-list { position: absolute; right: 0; top: calc(100% + 8px); z-index: 60; min-width: 138px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px; padding: 6px; box-shadow: 0 10px 34px rgba(0,0,0,.45); }
.lang-menu .lang-list a { display: block; margin: 0; padding: 8px 12px; border-radius: 9px; color: var(--ink); text-decoration: none; font-size: .9rem; }
.lang-menu .lang-list a:hover { background: var(--bg); color: var(--accent); }
.lang-menu .lang-list a[aria-current] { color: var(--accent); font-weight: 700; pointer-events: none; }
@media (max-width: 640px) { .lang-menu { margin-left: 12px; } .lang-menu summary { padding: 12px; font-size: .8rem; } } /* summary padding 12px: 🌐 tap target ~41px tall (2026-10-09 design-review) */
/* mobile: nav is a horizontal scroll strip (overflow-x:auto), which would clip the absolutely-positioned
   dropdown to 0 visible px — position:fixed escapes the overflow context (viewport-relative) */
@media (max-width: 600px) { .lang-menu .lang-list { position: fixed; top: 56px; right: 10px; } }

/* rhyme lookup form on narrow screens: input + button must fit the viewport (both /rhymes and /fr/rimes/) */
@media (max-width: 640px) {
  #lookup-form input { padding: 14px 16px !important; font-size: 1rem !important; }
  #lookup-form button { padding: 0 16px !important; font-size: .95rem !important; }
}

/* my-words tag editor (2026-09-29): chips + inline input share one box; chips reorder by pointer
   drag (touch-action:none so touch drags don't scroll the modal), tap still focuses the input */
#mw-tags { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px; padding: 8px; cursor: text; min-height: 54px; margin-bottom: 10px; }
#mw-tags:focus-within { border-color: var(--accent); }
#mw-tags input { flex: 1; min-width: 150px; background: transparent; border: none; outline: none; color: var(--ink); font-size: .95rem; font-family: inherit; padding: 6px 4px; }
.mw-tag { display: inline-flex; align-items: center; gap: 6px; background: rgba(255,255,255,.05); border: 1px solid #3a3a44; border-radius: 8px; padding: 5px 6px 5px 10px; font-size: .85rem; color: var(--ink); cursor: grab; user-select: none; -webkit-user-select: none; touch-action: none; }
.mw-tag.mw-drag { opacity: .35; cursor: grabbing; }
.mw-tag .mw-x { border: none; background: transparent; color: var(--ink-soft); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 2px; font-family: inherit; }
.mw-tag .mw-x:hover { color: #ff8a8a; }
/* delete-list two-tap arm state (no native confirm inside the game) */
.ghost-btn.warn { color: #ff8a8a; border-color: #ff8a8a; }
