/* ===================================================================
   AI Ronin: Quick Draw
   Palette: navy ground, cream type, coral accent.
   =================================================================== */

/* Yuji Syuku, subset to the 81 Japanese glyphs this game can actually put
   on screen — harvested mechanically from index.html and src/*.js, so the
   list cannot drift from the code (8.4MB -> 39KB). SIL Open Font License
   1.1 — see assets/fonts/OFL.txt. Self-hosted on purpose: the game has no
   external CDN dependency, at build time or at run time.

   The glyph count is in the filename because /assets/* ships as
   `immutable, max-age=31536000`: a returning player still holds the old
   15-glyph file for a year, so a new set of glyphs has to arrive under a
   new URL or it would never be fetched. */
@font-face{
  font-family:"Yuji Syuku Subset";
  src:url("assets/fonts/yuji-syuku-subset-81glyph.woff") format("woff");
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+2026,U+3002,U+3046,U+3048,U+304A,U+304C-304D,U+3053,
                U+3060-3061,U+3064,U+3066,U+306E-306F,U+3078,U+3081-3082,
                U+308B-308C,U+3092,U+4E00,U+4E09-4E0B,U+4E8C,U+4F8D,U+4FE1,
                U+521D,U+5229,U+5236,U+52DD,U+5317,U+53CC,U+57CE,U+5802,
                U+5915,U+5929,U+59CB,U+5CF6,U+5DCC,U+5E55,U+5EA6,U+5F71,
                U+5FCD,U+6226,U+6238,U+623B,U+624B,U+653F,U+6557,U+6575,
                U+65AC,U+6607,U+66AE,U+6700,U+6708,U+672C,U+69CB,U+6B21,
                U+6B66,U+6C5F,U+6C7A,U+6D41,U+708E,U+7121,U+76F8,U+77E5,
                U+7A7A,U+7B2C,U+7D42,U+7E3E,U+8005,U+8535,U+8987,U+898B,
                U+8A0E,U+90ED,U+9244,U+95D8,U+9ED2,U+FF01;
}

:root{
  --navy-900:#0b0e1f;
  --navy-800:#131736;
  --navy-700:#1b2148;
  --cream:#f8ecd6;
  --cream-dim:#cdbfa6;
  --coral:#ff6f5e;
  --coral-soft:#ff9a86;
  --gold:#ffcf7a;

  /* set by layout.js */
  --sprite-size:200px;
  --ground-y:600px;
  --sep:200px;
  --shake-x:0px;
  --shake-y:0px;
  /* written by dash.js / camera.js */
  --dash-ronin:0px;
  --dash-enemy:0px;
  --scale-ronin:1;
  --scale-enemy:1;
  --cam-x:0px;
  --bg-x:50%;
  --bg-y:50%;

  --safe-t:env(safe-area-inset-top,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-l:env(safe-area-inset-left,0px);
  --safe-r:env(safe-area-inset-right,0px);

  --font:"Avenir Next","Segoe UI Variable Display","Segoe UI",system-ui,
         -apple-system,"Helvetica Neue",Arial,sans-serif;

  /* Brush first, then whatever mincho the OS has, so a failed font load
     still reads as ink rather than falling back to a UI sans. */
  --font-ja:"Yuji Syuku Subset","Yu Mincho",YuMincho,"Hiragino Mincho ProN",
            "Noto Serif JP","Noto Serif CJK JP",serif;

  /* Muted ink colours — no primaries. */
  --ja-cream:#f2e4c9;
  --ja-ready:#ecd9a8;
  --ja-draw :#fdf6e6;
  --ja-win  :#d8b56a;
  --ja-lose :#a8503f;
  --ja-false:#9c5a52;
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

/* Id selectors below set display:flex, which would otherwise beat the
   UA's [hidden]{display:none} on specificity and show hidden panels. */
[hidden]{display:none !important}

html,body{
  height:100%;
  overflow:hidden;
  background:var(--navy-900);
}

body{
  font-family:var(--font);
  color:var(--cream);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

#app{
  position:fixed;
  inset:0;
  overflow:hidden;
  touch-action:manipulation;
  user-select:none;
  -webkit-user-select:none;
  -webkit-touch-callout:none;
  -webkit-tap-highlight-color:transparent;
  cursor:default;
}

/* --- Background ---------------------------------------------------- */
.bg-layer{position:absolute;inset:0;background:var(--navy-900)}
/* The camera pans the background through its own cover-crop rather than
   by transforming the layer — translating the layer would slide a hard
   edge into view. --bg-x comes from camera.js, --bg-y from layout.js. */
#bg{
  width:100%;height:100%;
  object-fit:cover;
  object-position:var(--bg-x,50%) var(--bg-y,50%);
  display:block;
}
/* Keeps type legible and hides the hard crop edges on tall screens. */
.bg-scrim{
  position:absolute;inset:0;
  pointer-events:none;
  background:
    linear-gradient(to bottom,
      rgba(11,14,31,.78) 0%,
      rgba(11,14,31,.30) 16%,
      rgba(11,14,31,0)   34%,
      rgba(11,14,31,0)   72%,
      rgba(11,14,31,.30) 86%,
      rgba(11,14,31,.72) 100%);
}

/* --- Stage / sprites ------------------------------------------------ */
#stage{
  position:absolute;inset:0;
  pointer-events:none;
  /* camera pan + impact shake; both are compositor-only */
  transform:translate3d(calc(var(--cam-x) + var(--shake-x)),var(--shake-y),0);
}

.sprite{
  position:absolute;
  left:50%;
  width:calc(var(--sprite-size) * var(--sprite-scale,1));
  height:calc(var(--sprite-size) * var(--sprite-scale,1));
  overflow:hidden;
  /* top is written by layout.js (ground line minus footFrac) */
}
.sprite img{
  position:absolute;
  top:0;left:0;
  width:calc(var(--sprite-size) * var(--sprite-scale,1) * 5);
  height:calc(var(--sprite-size) * var(--sprite-scale,1) * 5);
  max-width:none;
  image-rendering:auto;
  transform:translate3d(0,0,0);
  pointer-events:none;
}
#sp-ronin{transform:translateX(calc(-50% - var(--sep) / 2 + var(--dash-ronin)))}
#sp-enemy{transform:translateX(calc(-50% + var(--sep) / 2 + var(--dash-enemy)))}

.shadow{
  position:absolute;
  left:50%;
  width:calc(var(--sprite-size) * .40 * var(--shadow-scale,1));
  height:calc(var(--sprite-size) * .085 * var(--shadow-scale,1));
  top:calc(var(--ground-y) - var(--sprite-size) * .040);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
              rgba(6,8,20,.52) 0%, rgba(6,8,20,.30) 55%, rgba(6,8,20,0) 72%);
  pointer-events:none;
}
/* Shadows travel with their character, or they get left behind. */
#shadow-ronin{--shadow-scale:var(--scale-ronin);transform:translateX(calc(-50% - var(--sep) / 2 + var(--dash-ronin)))}
#shadow-enemy{--shadow-scale:var(--scale-enemy);transform:translateX(calc(-50% + var(--sep) / 2 + var(--dash-enemy)))}

/* --- Launch dust ----------------------------------------------------- */
/* Stays at the home position (no --dash-*): it marks where they pushed
   off from. Sized well under the character so it never covers a blade. */
.dust{
  position:absolute;
  left:50%;
  width:calc(var(--sprite-size) * .30);
  height:calc(var(--sprite-size) * .07);
  top:calc(var(--ground-y) - var(--sprite-size) * .035);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
              rgba(214,178,140,.40) 0%, rgba(214,178,140,.16) 55%,
              rgba(214,178,140,0) 75%);
  opacity:0;
  pointer-events:none;
}
#dust-ronin{transform:translateX(calc(-50% - var(--sep) / 2))}
#dust-enemy{transform:translateX(calc(-50% + var(--sep) / 2))}
#dust-ronin.go{animation:puff-r 260ms ease-out forwards}
#dust-enemy.go{animation:puff-e 260ms ease-out forwards}

@keyframes puff-r{
  0%  {opacity:0;   transform:translateX(calc(-50% - var(--sep) / 2)) scale(.4,.6)}
  30% {opacity:.85; transform:translateX(calc(-50% - var(--sep) / 2)) scale(1,1)}
  100%{opacity:0;   transform:translateX(calc(-50% - var(--sep) / 2)) scale(1.5,1.15)}
}
@keyframes puff-e{
  0%  {opacity:0;   transform:translateX(calc(-50% + var(--sep) / 2)) scale(.4,.6)}
  30% {opacity:.85; transform:translateX(calc(-50% + var(--sep) / 2)) scale(1,1)}
  100%{opacity:0;   transform:translateX(calc(-50% + var(--sep) / 2)) scale(1.5,1.15)}
}

/* A near-black ninja against a night sky needs a little separation. Kept
   deliberately faint and cool — moonlight, not a glow. Stage 2's enemy
   only; the Ronin and the stage 1 samurai never carry it. */
#sp-enemy.is-moonlit img{
  filter:drop-shadow(0 0 1px rgba(196,214,255,.55))
         drop-shadow(0 1px 2px rgba(0,0,0,.55));
}

/* --- Stage label ----------------------------------------------------- */
.stage-label{
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.16em;
  color:var(--cream-dim);
  text-shadow:0 1px 3px rgba(0,0,0,.85);
  white-space:nowrap;
}
.stage-label b{color:var(--cream);font-weight:700}
.stage-label span{font-family:var(--font-ja);margin-left:7px;color:var(--ja-cream);letter-spacing:.06em}

/* --- STAGE CLEAR banner ---------------------------------------------- */
#banner{margin-top:10px;text-align:center;line-height:1.15}
#banner b{
  display:block;
  font-size:clamp(15px,4.6vw,26px);
  font-weight:800;letter-spacing:.18em;color:var(--gold);
  text-shadow:0 2px 10px rgba(0,0,0,.9);
}
#banner span{
  display:block;margin-top:3px;
  font-family:var(--font-ja);
  font-size:clamp(11px,3.2vw,17px);
  letter-spacing:.08em;color:var(--ja-win);
  text-shadow:0 2px 6px rgba(0,0,0,.75);
}

#btn-next small{
  display:block;margin-top:2px;
  font-family:var(--font-ja);
  font-size:.72em;letter-spacing:.05em;font-weight:400;opacity:.85;
}

/* --- Impact flash --------------------------------------------------- */
#flash{
  position:absolute;inset:0;
  background:#fff;
  opacity:0;
  pointer-events:none;
}

/* --- HUD ------------------------------------------------------------ */
.hud-top{
  position:absolute;top:0;left:0;right:0;
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:12px;
  padding:calc(var(--safe-t) + 14px) calc(var(--safe-r) + 16px)
          0 calc(var(--safe-l) + 16px);
  pointer-events:none;
}
.hud-top .btn{pointer-events:auto}

.brand{
  font-size:clamp(11px,3vw,15px);
  font-weight:700;
  letter-spacing:.16em;
  color:var(--cream);
  text-shadow:0 1px 3px rgba(0,0,0,.85);
  line-height:1.35;
}
.brand span{color:var(--coral-soft);display:block}

.hud-right{display:flex;flex-direction:column;align-items:flex-end;gap:8px}
.best{
  font-size:clamp(10px,2.6vw,12px);
  letter-spacing:.14em;
  color:var(--cream-dim);
  text-shadow:0 1px 3px rgba(0,0,0,.85);
  white-space:nowrap;
}
.best b{color:var(--gold);font-variant-numeric:tabular-nums;margin-left:6px}

/* --- Centre cue ----------------------------------------------------- */
#cue-wrap{
  position:absolute;
  left:50%;top:26%;
  transform:translate(-50%,-50%);
  width:min(92vw,560px);
  text-align:center;
  pointer-events:none;
}
#cue{
  font-size:clamp(30px,10.5vw,68px);
  font-weight:800;
  letter-spacing:.10em;
  line-height:1.06;
  text-shadow:0 3px 16px rgba(0,0,0,.9),0 1px 2px rgba(0,0,0,.9);
  min-height:1.06em;
}
#cue.is-draw{color:var(--coral)}
#cue.is-win{color:var(--gold)}
#cue.is-lose{color:var(--coral)}
#cue.is-tie{color:var(--cream)}
/* Japanese reading, directly under the English. About a third of its
   size, with a 12px floor so it stays legible on a small phone. The
   min-height reserves the line box, so swapping from the fallback mincho
   to the brush face changes glyph shapes but never moves anything. */
#cue-jp{
  font-family:var(--font-ja);
  font-weight:400;
  font-size:clamp(12px,3.5vw,24px);
  line-height:1.3;
  min-height:1.3em;
  margin-top:clamp(2px,0.6vw,6px);
  letter-spacing:.08em;
  color:var(--ja-cream);
  text-shadow:0 2px 6px rgba(0,0,0,.72),0 1px 1px rgba(0,0,0,.55);
}
#cue-jp.is-ja-ready{color:var(--ja-ready)}
#cue-jp.is-ja-draw {color:var(--ja-draw)}
#cue-jp.is-ja-win  {color:var(--ja-win)}
#cue-jp.is-ja-lose {color:var(--ja-lose)}
#cue-jp.is-ja-tie  {color:var(--ja-cream)}
#cue-jp.is-ja-false{color:var(--ja-false)}

/* Settles in just behind the English — 45ms, well inside the window that
   keeps the DRAW! cue feeling simultaneous. */
@keyframes cue-jp-in{
  from{opacity:0;transform:translateY(4px)}
  to  {opacity:1;transform:none}
}
#cue-jp.is-in{animation:cue-jp-in 260ms ease-out 45ms both}

#cue-sub{
  margin-top:10px;
  font-size:clamp(10px,2.9vw,13px);
  letter-spacing:.18em;
  color:var(--cream-dim);
  text-shadow:0 1px 4px rgba(0,0,0,.9);
  min-height:1.2em;
}

/* --- Result panel --------------------------------------------------- */
#panel{
  position:absolute;
  left:50%;top:41%;
  transform:translateX(-50%);
  width:min(92vw,460px);
  text-align:center;
  pointer-events:none;
}
#times{
  display:flex;justify-content:center;gap:clamp(18px,7vw,46px);
  padding:12px 18px;
  border-radius:14px;
  background:rgba(11,14,31,.62);
  border:1px solid rgba(248,236,214,.14);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
}
.time{display:flex;flex-direction:column;gap:3px}
.time span{
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.16em;color:var(--cream-dim);
}
.time b{
  font-size:clamp(17px,5.2vw,24px);
  font-weight:700;font-variant-numeric:tabular-nums;color:var(--cream);
}
#note{
  margin-top:10px;
  font-size:clamp(10px,2.9vw,13px);
  letter-spacing:.13em;
  color:var(--gold);
  text-shadow:0 1px 4px rgba(0,0,0,.9);
}

/* --- Bottom HUD ----------------------------------------------------- */
.hud-bottom{
  position:absolute;left:0;right:0;bottom:0;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:0 calc(var(--safe-r) + 16px)
          calc(var(--safe-b) + 18px) calc(var(--safe-l) + 16px);
  pointer-events:none;
}
.hud-bottom .btn{pointer-events:auto}

#hint{
  font-size:clamp(9px,2.6vw,12px);
  letter-spacing:.18em;
  color:var(--cream-dim);
  text-shadow:0 1px 4px rgba(0,0,0,.9);
  text-align:center;
  min-height:1.2em;
}
#stats{
  font-size:clamp(9px,2.3vw,11px);
  letter-spacing:.12em;
  color:rgba(205,191,166,.7);
  text-shadow:0 1px 4px rgba(0,0,0,.9);
  font-variant-numeric:tabular-nums;
  min-height:1.2em;
}

/* --- Buttons -------------------------------------------------------- */
.btn{
  font-family:inherit;
  font-size:clamp(12px,3.4vw,15px);
  font-weight:700;
  letter-spacing:.16em;
  color:var(--navy-900);
  background:var(--coral);
  border:none;
  border-radius:999px;
  padding:14px 34px;
  cursor:pointer;
  touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;
  box-shadow:0 6px 20px rgba(0,0,0,.45);
  transition:transform .12s ease,background-color .12s ease,opacity .12s ease;
}
.btn:hover:not(:disabled){background:var(--coral-soft)}
.btn:active:not(:disabled){transform:translateY(1px)}
.btn:disabled{opacity:.45;cursor:default}
.btn:focus-visible{outline:3px solid var(--gold);outline-offset:3px}

.btn-ghost{
  background:rgba(11,14,31,.6);
  color:var(--cream-dim);
  border:1px solid rgba(248,236,214,.22);
  padding:8px 14px;
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.14em;
  box-shadow:none;
}
.btn-ghost:hover:not(:disabled){background:rgba(27,33,72,.8);color:var(--cream)}

/* --- Error ---------------------------------------------------------- */
#error{
  position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:16px;padding:24px;
  background:rgba(11,14,31,.94);
  text-align:center;
}
.err-title{font-size:clamp(15px,4.4vw,20px);font-weight:800;letter-spacing:.14em;color:var(--coral)}
.err-body{font-size:clamp(11px,3vw,13px);color:var(--cream-dim);max-width:44ch;line-height:1.6}

/* --- Debug ---------------------------------------------------------- */
#debug{
  position:absolute;left:8px;bottom:8px;
  font:11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:#8ef;background:rgba(0,0,0,.72);
  padding:6px 9px;border-radius:6px;white-space:pre;
  pointer-events:none;z-index:10;
}

/* --- Landscape: tuck HUD to the sides, keep the duel band clear ------ */
@media (orientation:landscape) and (max-height:520px){
  #cue-wrap{top:15%}
  #cue{font-size:clamp(22px,6.6vh,42px)}
  /* A third of the English would be ~8px here; hold the legibility floor. */
  #cue-jp{font-size:11px;margin-top:2px}
  #cue-sub{margin-top:6px}
  .hud-bottom{gap:6px;padding-bottom:calc(var(--safe-b) + 10px)}
  .btn{padding:9px 24px}

  /* The duel band fills the middle of a short landscape screen, so the
     times move out to the empty margins either side of the fighters
     instead of sitting on top of them. */
  /* No transform here: a transformed ancestor would turn the note's
     position:fixed into position:absolute against this box. */
  #panel{
    top:50%;left:0;right:0;width:auto;
    transform:none;
  }
  #times{
    background:none;border:none;padding:0;
    backdrop-filter:none;-webkit-backdrop-filter:none;
    justify-content:space-between;
    padding-left:calc(var(--safe-l) + 14px);
    padding-right:calc(var(--safe-r) + 14px);
  }
  .time{
    background:rgba(11,14,31,.68);
    border:1px solid rgba(248,236,214,.14);
    border-radius:12px;
    padding:8px 14px;
    backdrop-filter:blur(3px);
    -webkit-backdrop-filter:blur(3px);
  }
  .time b{font-size:clamp(15px,3.4vh,20px)}
  #note{
    /* +52px, not +40px: the Japanese line grew the cue block. */
    position:fixed;left:50%;top:calc(15% + 52px);
    transform:translateX(-50%);
    margin-top:0;white-space:nowrap;
  }
}

/* --- Reduced motion -------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .btn{transition:none}
  .dust{display:none}
  /* Same name, defined later: the movement drops out, the fade stays. */
  @keyframes cue-jp-in{
    from{opacity:0}
    to  {opacity:1}
  }
}

/* ===================================================================
   Home menu, records, and the all-clear ending.
   Everything below is additive: no rule above this line is changed.
   =================================================================== */

/* --- Button variants -------------------------------------------------- */
/* Same shape as #btn-next's caption, applied to every menu button. */
.btn small{
  display:block;margin-top:2px;
  font-family:var(--font-ja);
  font-size:.72em;letter-spacing:.05em;font-weight:400;opacity:.85;
}
/* The secondary action. Distinguished by outline and size as well as
   colour, so it does not rely on hue alone to read as "not the main one". */
.btn-outline{
  background:transparent;
  color:var(--cream);
  border:1.5px solid rgba(248,236,214,.4);
  box-shadow:none;
  padding:10px 26px;
  font-size:clamp(11px,3vw,13px);
}
.btn-outline:hover:not(:disabled){
  background:rgba(27,33,72,.72);
  border-color:rgba(248,236,214,.7);
}

/* --- Menus ------------------------------------------------------------ */
#home-menu,#final-menu{
  display:flex;flex-direction:column;align-items:center;gap:10px;
}
#home-menu .btn,#final-menu .btn{pointer-events:auto}

/* --- Musashi's line --------------------------------------------------- */
#speech{
  position:absolute;
  left:50%;top:30%;
  transform:translate(-50%,-50%);
  width:min(88vw,32rem);
  text-align:center;
  pointer-events:none;
  opacity:0;
}
#speech.is-in{
  animation:speech-in 460ms ease-out both;
}
#speech.is-out{
  opacity:0;
  transition:opacity 420ms ease-in;
}
@keyframes speech-in{
  from{opacity:0;transform:translate(-50%,calc(-50% + 6px))}
  to  {opacity:1;transform:translate(-50%,-50%)}
}
#speech-name{
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.22em;
  color:var(--cream-dim);
  text-shadow:0 1px 4px rgba(0,0,0,.85);
  margin-bottom:7px;
}
#speech-name span{
  font-family:var(--font-ja);
  margin-left:8px;letter-spacing:.1em;color:var(--ja-cream);
}
/* The Japanese is the line; the English sits under it, quietly. */
#speech-ja{
  font-family:var(--font-ja);
  font-size:clamp(15px,4.6vw,24px);
  line-height:1.65;
  letter-spacing:.06em;
  color:var(--cream);
  text-shadow:0 2px 8px rgba(0,0,0,.85),0 1px 2px rgba(0,0,0,.7);
}
#speech-en{
  margin-top:9px;
  font-size:clamp(10px,2.7vw,13px);
  font-style:italic;
  letter-spacing:.04em;
  color:var(--cream-dim);
  text-shadow:0 1px 5px rgba(0,0,0,.85);
}

/* --- The all-clear title ---------------------------------------------- */
#finale{
  position:absolute;
  /* Sits where the result cue would be — on this screen the cue is
     deliberately empty, so the title has the band to itself. */
  left:50%;top:28%;
  transform:translate(-50%,-50%);
  width:min(94vw,40rem);
  text-align:center;
  pointer-events:none;
}
#finale-en{
  font-size:clamp(11px,3.2vw,16px);
  font-weight:700;letter-spacing:.28em;
  color:var(--cream-dim);
  text-shadow:0 2px 8px rgba(0,0,0,.9);
  margin-bottom:clamp(6px,1.6vw,12px);
}
/* Ink, not neon: warm off-white gold over a dense sumi shadow. */
#finale-ja{
  font-family:var(--font-ja);
  font-size:clamp(40px,15vw,104px);
  font-weight:700;
  line-height:1.12;
  letter-spacing:.06em;
  color:#e8cf94;
  text-shadow:
    0 3px 0 rgba(20,15,7,.55),
    0 6px 26px rgba(0,0,0,.92),
    0 1px 3px rgba(0,0,0,.9);
}
#finale.is-in #finale-en{animation:finale-sub-in 460ms ease-out 160ms both}
#finale.is-in #finale-ja{animation:finale-in 380ms cubic-bezier(.22,1.2,.36,1) both}
/* One firm settle from slightly oversized. No bounce, spin or flash. */
@keyframes finale-in{
  from{opacity:0;transform:scale(1.14)}
  to  {opacity:1;transform:scale(1)}
}
@keyframes finale-sub-in{
  from{opacity:0}
  to  {opacity:1}
}

/* --- Final-clear numbers (kept to three) ------------------------------ */
#final-info{
  display:flex;justify-content:center;gap:clamp(14px,5.5vw,34px);
  padding:11px 16px;
  border-radius:14px;
  background:rgba(11,14,31,.62);
  border:1px solid rgba(248,236,214,.14);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
}
.fi{display:flex;flex-direction:column;gap:3px}
.fi span{
  font-size:clamp(8px,2.2vw,10px);
  letter-spacing:.15em;color:var(--cream-dim);
}
.fi b{
  font-size:clamp(15px,4.6vw,21px);
  font-weight:700;font-variant-numeric:tabular-nums;color:var(--gold);
}

/* --- Ranking ---------------------------------------------------------- */
#ranking{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  background:rgba(6,8,18,.9);
  backdrop-filter:blur(5px);
  -webkit-backdrop-filter:blur(5px);
  z-index:6;
}
/* The one scrollable surface in the game. The duel screen keeps
   html,body{overflow:hidden} untouched. */
#rank-scroll{
  width:min(92vw,430px);
  max-height:100%;
  overflow-y:auto;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(12px,3vw,18px);
  padding:calc(var(--safe-t) + 22px) calc(var(--safe-r) + 20px)
          calc(var(--safe-b) + 22px) calc(var(--safe-l) + 20px);
  text-align:center;
}
#rank-title{
  font-size:clamp(17px,5vw,25px);
  font-weight:800;letter-spacing:.2em;color:var(--cream);
}
#rank-title span{
  font-family:var(--font-ja);
  margin-left:10px;font-size:.62em;letter-spacing:.1em;
  font-weight:400;color:var(--ja-cream);
}
#rank-best{
  width:100%;border-collapse:collapse;
  font-variant-numeric:tabular-nums;
}
#rank-best th,#rank-best td{
  padding:9px 4px;
  border-bottom:1px solid rgba(248,236,214,.12);
}
#rank-best th{
  text-align:left;font-weight:700;
  font-size:clamp(10px,2.8vw,12px);
  letter-spacing:.14em;color:var(--cream-dim);
}
#rank-best th small{
  font-family:var(--font-ja);
  margin-left:8px;font-size:.92em;font-weight:400;
  letter-spacing:.06em;color:var(--ja-cream);
}
#rank-best td{
  text-align:right;
  font-size:clamp(13px,3.8vw,16px);
  font-weight:700;color:var(--gold);
}
#rank-totals{
  width:100%;
  display:grid;grid-template-columns:1fr auto;
  gap:7px 12px;align-items:baseline;
  font-variant-numeric:tabular-nums;
}
#rank-totals dt{
  text-align:left;
  font-size:clamp(9px,2.6vw,11px);
  letter-spacing:.14em;color:var(--cream-dim);
}
#rank-totals dd{
  text-align:right;
  font-size:clamp(12px,3.4vw,15px);
  font-weight:700;color:var(--cream);
}
/* No record yet — dimmed, and never styled by colour alone. */
#rank-best td.is-empty,#rank-totals dd.is-empty{
  color:rgba(205,191,166,.5);font-weight:400;
}
#rank-scroll .btn{margin-top:4px;flex:0 0 auto}

/* --- Landscape: the ending has to fit a very short band --------------- */
@media (orientation:landscape) and (max-height:520px){
  #home-menu,#final-menu{flex-direction:row;gap:10px}
  #speech{top:25%;width:min(80vw,34rem)}
  #speech-ja{font-size:clamp(13px,3.9vh,20px);line-height:1.5}
  #speech-en{font-size:clamp(9px,2.2vh,12px);margin-top:5px}
  #speech-name{margin-bottom:4px}
  #finale{top:26%}
  #finale-ja{font-size:clamp(26px,11vh,52px)}
  #finale-en{font-size:clamp(9px,2.4vh,13px);letter-spacing:.24em;margin-bottom:4px}
  /* #panel goes full-width here so the times can sit in the margins;
     the ending's one pill must not stretch with it. */
  #final-info{padding:7px 12px;gap:clamp(12px,4vw,26px);
              width:fit-content;max-width:100%;margin-inline:auto}
  .fi b{font-size:clamp(13px,3.2vh,17px)}
  .btn-outline{padding:8px 20px}
  #rank-scroll{width:min(96vw,560px);gap:10px}
  #rank-best th,#rank-best td{padding:6px 4px}
}

/* --- Small phones ----------------------------------------------------- */
@media (max-width:360px){
  #finale-ja{font-size:13vw}
  #speech-ja{font-size:14px}
  #final-info{gap:12px;padding:9px 11px}
  .btn{padding:12px 26px}
  .btn-outline{padding:9px 20px}
}

/* --- Reduced motion: the fades stay, the movement goes ---------------- */
@media (prefers-reduced-motion:reduce){
  /* Same names, defined later, so only the transform drops out. */
  @keyframes speech-in{
    from{opacity:0;transform:translate(-50%,-50%)}
    to  {opacity:1;transform:translate(-50%,-50%)}
  }
  @keyframes finale-in{
    from{opacity:0;transform:none}
    to  {opacity:1;transform:none}
  }
}

/* ===================================================================
   Continues, GAME OVER, the world boards and the rank-in form.
   Additive: no rule above this line is changed.
   =================================================================== */

/* --- Continues -------------------------------------------------------
   The top-left column, under the wordmark. It is the one band of the
   screen nothing else uses: the stage name and BEST TIME are in the
   right column, the cue sits at 26%, the result panel at 50%, and the
   buttons are all in the bottom HUD. Ink and gold only — the dots are
   the same brush palette as everything else, not an icon set. */
.hud-left{
  display:flex;flex-direction:column;align-items:flex-start;gap:6px;
  min-width:0;
}
.continues{
  display:flex;align-items:baseline;gap:8px;
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.16em;
  color:var(--cream-dim);
  text-shadow:0 1px 3px rgba(0,0,0,.85);
  white-space:nowrap;
}
.cont-label{opacity:.85}
.cont-dots{
  font-size:clamp(10px,2.8vw,13px);
  letter-spacing:.02em;
  color:var(--gold);
  line-height:1;
}
/* The hollow dots are drawn by the same glyph run, so only the whole
   line needs a colour; the spent ones read as spent because ○ is an
   outline. On the last continue the row warms toward the coral the
   result screen already uses for a loss. */
.cont-dots.is-left-1{color:var(--coral-soft)}

/* --- GAME OVER -------------------------------------------------------
   No new screen: the result panel is already correct, the centre cue
   already says the word, and this is simply the only button left. */
#btn-title{margin-top:2px}

/* --- Ranking: the switch --------------------------------------------
   Three equal columns rather than a scrolling row, so nothing is ever
   off-screen on a phone and the panel never scrolls sideways. The second
   word drops to its own line, which is what keeps "FASTEST BLADE" inside
   a third of a 320px screen. */
#rank-tabs{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:6px;width:100%;flex:0 0 auto;
}
.rank-tab{
  font:inherit;
  font-size:clamp(8px,2.2vw,10px);
  font-weight:700;
  letter-spacing:.10em;
  line-height:1.35;
  text-align:center;
  padding:8px 4px;
  color:var(--cream-dim);
  background:rgba(11,14,31,.55);
  border:1px solid rgba(248,236,214,.16);
  border-radius:10px;
  cursor:pointer;
  transition:background 140ms ease,color 140ms ease,border-color 140ms ease;
}
.rank-tab span{display:block;opacity:.75}
.rank-tab:hover{color:var(--cream)}
.rank-tab.is-on{
  color:var(--navy-900);
  background:var(--gold);
  border-color:var(--gold);
}
.rank-tab.is-on span{opacity:.8}
.rank-tab:focus-visible{outline:3px solid var(--gold);outline-offset:3px}

.rank-panel{display:flex;flex-direction:column;gap:8px;width:100%}
.rank-head{
  display:flex;flex-direction:column;gap:2px;text-align:center;
  margin-top:2px;
}
.rank-head b{
  font-size:clamp(11px,3vw,14px);
  letter-spacing:.20em;color:var(--gold);
}
.rank-head span{
  font-size:clamp(8px,2.2vw,10px);
  letter-spacing:.22em;color:var(--cream-dim);
}
.rank-head span[lang="ja"]{font-family:var(--font-ja);letter-spacing:.10em}

/* --- Ranking: a board row -------------------------------------------- */
.board{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}
.board li{
  display:grid;
  grid-template-columns:1.8em 1.4em 1fr auto;
  align-items:center;
  gap:8px;
  padding:6px 8px;
  border-radius:8px;
  background:rgba(11,14,31,.42);
  font-size:clamp(10px,2.7vw,12px);
}
.board li:nth-child(1){background:rgba(226,178,90,.14)}
.bd-rank{
  color:var(--gold);font-weight:700;text-align:right;
  font-variant-numeric:tabular-nums;letter-spacing:.04em;
}
.bd-flag{font-size:1.15em;line-height:1;text-align:center}
.bd-name{
  color:var(--cream);letter-spacing:.06em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;
}
.bd-ms{
  color:var(--cream);font-variant-numeric:tabular-nums;
  letter-spacing:.06em;white-space:nowrap;
}
/* The stage a strike happened on wraps under the row on narrow screens
   rather than squeezing the name. */
.bd-stage{
  grid-column:3 / -1;
  font-size:.82em;letter-spacing:.16em;
  color:rgba(205,191,166,.7);
}
.board-msg{
  display:flex;flex-direction:column;gap:4px;
  text-align:center;padding:18px 6px;
}
.board-msg b{
  font-size:clamp(10px,2.8vw,12px);
  letter-spacing:.20em;color:var(--cream-dim);font-weight:700;
}
.board-msg span{
  font-family:var(--font-ja);
  font-size:clamp(11px,3.2vw,14px);
  letter-spacing:.10em;color:var(--ja-cream);
}
.rank-actions{
  display:flex;gap:8px;justify-content:center;flex-wrap:wrap;
  margin-top:4px;flex:0 0 auto;
}

/* --- The quiet offline line ------------------------------------------ */
#net-note{
  font-size:clamp(8px,2.1vw,10px);
  letter-spacing:.20em;
  color:rgba(205,191,166,.55);
  text-shadow:0 1px 4px rgba(0,0,0,.9);
}

/* --- Rank-in form ----------------------------------------------------- */
#entry{
  position:absolute;inset:0;z-index:7;
  display:flex;align-items:center;justify-content:center;
  padding:calc(var(--safe-t) + 12px) calc(var(--safe-r) + 14px)
          calc(var(--safe-b) + 12px) calc(var(--safe-l) + 14px);
  background:rgba(8,10,22,.90);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  overflow-y:auto;
}
#entry-form{
  display:flex;flex-direction:column;gap:7px;
  width:min(94vw,420px);
  max-height:100%;
  padding:16px 18px;
  border:1px solid rgba(226,178,90,.35);
  border-radius:14px;
  background:rgba(11,14,31,.75);
}
#entry-title{
  font-size:clamp(13px,3.6vw,17px);
  letter-spacing:.22em;color:var(--gold);text-align:center;margin:0;
}
#entry-title span{
  display:block;font-family:var(--font-ja);
  font-size:.72em;letter-spacing:.12em;color:var(--ja-cream);margin-top:3px;
}
#entry-sub{
  text-align:center;
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.14em;color:var(--cream-dim);
  font-variant-numeric:tabular-nums;
  margin-bottom:2px;
}
.entry-label{
  font-size:clamp(9px,2.3vw,10px);
  letter-spacing:.20em;color:var(--cream-dim);margin-top:4px;
}
.entry-label span{font-family:var(--font-ja);letter-spacing:.08em;margin-left:6px}
#entry-name,#entry-country{
  font:inherit;
  font-size:16px;            /* iOS zooms a focused field under 16px */
  padding:10px 12px;
  color:var(--cream);
  background:rgba(8,10,22,.85);
  border:1px solid rgba(248,236,214,.22);
  border-radius:10px;
  width:100%;
}
#entry-name:focus-visible,#entry-country:focus-visible{
  outline:3px solid var(--gold);outline-offset:2px;
}
.entry-hint{
  font-size:clamp(8px,2vw,9px);
  letter-spacing:.16em;color:rgba(205,191,166,.6);
}
#entry-msg{
  min-height:1.3em;text-align:center;
  font-size:clamp(9px,2.4vw,11px);
  letter-spacing:.14em;color:var(--gold);
}
.entry-actions{
  display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:4px;
}

/* --- Landscape: the short band --------------------------------------- */
@media (orientation:landscape) and (max-height:520px){
  .hud-left{gap:4px}
  .continues{font-size:9px;gap:6px}
  .cont-dots{font-size:10px}
  .rank-tab{padding:6px 3px;font-size:8px;letter-spacing:.06em}
  .board li{padding:4px 7px;gap:6px}
  .rank-head b{font-size:11px}
  /* A soft keyboard leaves almost nothing here, so the form scrolls
     inside itself rather than pushing its buttons off-screen. */
  #entry-form{gap:5px;padding:12px 14px}
  #entry-title{font-size:12px}
  .entry-label{margin-top:2px}
  #entry-name,#entry-country{padding:7px 10px}
}

/* --- Small phones ----------------------------------------------------- */
@media (max-width:360px){
  .continues{gap:6px;letter-spacing:.10em}
  .cont-dots{letter-spacing:0}
  .rank-tab{letter-spacing:.04em;padding:7px 2px}
  .board li{grid-template-columns:1.6em 1.3em 1fr auto;gap:6px;padding:5px 6px}
  #entry-form{padding:14px}
}

/* --- Reduced motion --------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .rank-tab{transition:none}
}
