/* ==========================================================================
   ONI STORM 2 — MAIN MENU
   Samurai Warriors 2-style menu, lit like the title screen: black smoke, a red
   drift on the hero side, a warm ember horizon that the silhouetted army and
   mountains stand against, the gold list on the left, the hero on the right.
   Loaded AFTER css/style.css; the title screen keeps every one of its rules.
   ========================================================================== */

/* ---------- 0. tokens ---------------------------------------------------- */
.menu{
  position:fixed; inset:0; z-index:40; overflow:hidden;
  opacity:0; visibility:hidden;
  font-family:var(--font-ui,"Segoe UI",system-ui,sans-serif);
  color:var(--ivory);
  transition:opacity .5s ease, visibility .5s;
  -webkit-tap-highlight-color:transparent;
}
body.menu-open .menu{opacity:1;visibility:visible}
body.menu-open .hero{opacity:0;visibility:hidden;transition:opacity .45s ease,visibility .45s}
body.menu-closing .menu{opacity:0;transition-duration:.35s}

/* ---------- 1. background ------------------------------------------------ */
/* The background IS the hero section's smoke: the same clip, the same seamless
   fog tiles, the same drifting radial blobs (section 5.1–5.2 of style.css).
   The only warm layer kept from the reference plate is the ground glow the
   army stands in — the mountains and the soldiers stay art layers on top.
   Everything else is smoke. */
.menu-bg{position:absolute;inset:0;z-index:0;
  background:radial-gradient(120% 85% at 50% 6%,#1a141c 0%,#0b0a0d 48%,#050506 100%)}

/* the reference's hazy battlefield light — bottom band only, behind the smoke */
.m-sky{position:absolute;inset:0;
  background:
    radial-gradient(84% 38% at 64% 106%,rgba(255,228,172,.70) 0%,rgba(255,198,124,.34) 38%,rgba(176,110,44,.12) 66%,transparent 86%),
    linear-gradient(180deg,rgba(140,88,32,0) 36%,rgba(140,88,32,.34) 70%,rgba(96,56,16,.62) 100%)}

/* THE smoke, warm-lit: the hero clip, screen-blended out of its black and
   masked to sit in the sky so the ground haze stays readable underneath */
.m-smoke{position:absolute;inset:-3%;overflow:hidden;opacity:.9;mix-blend-mode:screen;
  pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 52%,rgba(0,0,0,.72) 76%,rgba(0,0,0,.34) 100%);
  mask-image:linear-gradient(180deg,#000 0%,#000 52%,rgba(0,0,0,.72) 76%,rgba(0,0,0,.34) 100%)}
.m-smoke video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:sepia(.72) saturate(1.65) brightness(.86) contrast(1.06);
  animation:m-breathe 52s ease-in-out infinite alternate}
@keyframes m-breathe{from{transform:scale(1.04)}to{transform:scale(1.12) translate3d(-1%,-1%,0)}}
html.no-smoke .m-smoke{display:none}

/* the smoke *patterns*: the hero section's seamless fog tiles, inverted and
   multiplied so the same noise darkens the gold like drifting ash-clouds */
.m-fog{position:absolute;inset:-12%;pointer-events:none;background-repeat:repeat;
  mix-blend-mode:multiply;opacity:.30;
  filter:invert(1) sepia(.8) saturate(1.15) contrast(1.06)}
.mf1{background-image:url(../assets/art/fog-tile-512.png);background-size:940px;animation:fog-a 110s linear infinite}
.mf2{background-image:url(../assets/art/fog-tile-384.png);background-size:600px;opacity:.22;animation:fog-b 150s linear infinite}
.mf3{background-image:url(../assets/art/fog-tile-512.png);background-size:1500px;opacity:.16;animation:fog-c 210s linear infinite}
@keyframes fog-a{from{background-position:0 0}to{background-position:940px -260px}}
@keyframes fog-b{from{background-position:0 0}to{background-position:-600px 180px}}
@keyframes fog-c{from{background-position:0 0}to{background-position:-1500px 90px}}
@media (prefers-reduced-motion:reduce){.mf1,.mf2,.mf3{animation:none!important}}

/* red drift: a thin crimson veil on the hero side, so she has her own light */
.m-red{position:absolute;inset:0;mix-blend-mode:multiply;pointer-events:none;opacity:.34;
  -webkit-mask-image:linear-gradient(90deg,transparent 26%,rgba(0,0,0,.35) 52%,#000 76%);
  mask-image:linear-gradient(90deg,transparent 26%,rgba(0,0,0,.35) 52%,#000 76%)}
.m-red video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:sepia(.6) saturate(1.5) brightness(1.1);
  animation:m-red-drift 46s ease-in-out infinite alternate}
@keyframes m-red-drift{from{transform:scale(1.06)}to{transform:scale(1.13) translate3d(-1.6%,1%,0)}}
html.no-smoke .m-red{display:none}

/* a soft warm bloom over the horizon — the light the army stands in, plus the
   hero section's two drifting fog blobs (style.css .f1/.f3) and its beam,
   re-cast warm so they read as smoke over the glow instead of flat gradients */
.m-glow{position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(58% 100% at 50% 0%,rgba(255,212,160,.12),rgba(255,180,120,.05) 42%,transparent 74%),
    radial-gradient(70% 30% at 70% 92%,rgba(255,238,198,.5) 0%,rgba(255,214,150,.22) 44%,rgba(255,200,130,0) 76%),
    radial-gradient(46% 26% at 88% 60%,rgba(255,186,120,.2),transparent 78%)}
.m-glow::before,.m-glow::after{content:"";position:absolute;
  background:radial-gradient(closest-side,var(--fc),transparent 72%);
  animation:drift var(--ft) ease-in-out infinite alternate}
.m-glow::before{--fc:rgba(255,236,196,.16);--ft:74s;
  width:70vmax;height:52vmax;left:-18%;top:-12%}
.m-glow::after{--fc:rgba(196,214,255,.13);--ft:96s;
  width:80vmax;height:54vmax;left:8%;top:52%}

/* NO MOUNTAINS. The range is gone from the scene: it used to sit over the
   right half of the frame and cut the warrior at the hips. What is left is
   the open horizon — smoke above, a warm firelit ground below. */

/* the firelight the army stands in: a low warm glow on the horizon, placed
   exactly where the warband now stands so the silhouettes read against
   light instead of black-on-black. The falloff is long and soft — a short
   one leaves a visible elliptical edge on the smoke, which reads as a dirty
   ring rather than as light. */
.m-armyglow{position:absolute;left:28%;bottom:0;width:52%;height:46%;
  background:radial-gradient(ellipse 52% 52% at 50% 68%,
    rgba(255,226,176,.60) 0%,
    rgba(255,190,116,.34) 22%,
    rgba(255,146,64,.16) 46%,
    rgba(255,124,52,.06) 68%,
    transparent 100%);
  mix-blend-mode:screen;
  pointer-events:none;
  opacity:.9}
/* the ground the army stands on: a soft elliptical contact shadow, so the
   figures have a base instead of dissolving into the frame edge. Its darkest
   point sits ON the feet line, not above it. */
.m-army::after{content:"";position:absolute;left:41%;bottom:5vh;width:30vw;height:16vh;
  pointer-events:none;
  background:radial-gradient(ellipse 52% 40% at 50% 62%,
    rgba(8,5,3,.68) 0%,rgba(10,6,4,.40) 42%,transparent 76%)}

/* The warband plate is a 1100x846 group shot, and its upper half is opaque
   GREY MIST painted by the artist. Brightened 2x (the plate is near-black, so
   it needs the gain to read as backlit metal) that mist becomes a bright grey
   box over the smoke — which is exactly what a straight "show the whole
   plate" placement gives you.

   So the plate is shown as its BOTTOM band only: the commander, the big
   standard and the front ranks — the part with the figures in it — with the
   painted mist cropped away. object-fit:cover does the crop; the wide box
   (aspect 2.17) is the bottom 506 rows of the plate. The edges are feathered
   by the mask, so there is never a hard rectangle. */
.m-army{position:absolute;inset:0;pointer-events:none}
.m-band{position:absolute;left:41%;bottom:11vh;width:30vw;aspect-ratio:2.17;
  overflow:hidden;pointer-events:none;
  -webkit-mask-image:linear-gradient(90deg,transparent 0%,#000 5%,#000 86%,rgba(0,0,0,.4) 95%,transparent 100%),
    linear-gradient(180deg,transparent 0%,rgba(0,0,0,.5) 9%,#000 22%,#000 74%,rgba(0,0,0,.55) 92%,transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg,transparent 0%,#000 5%,#000 86%,rgba(0,0,0,.4) 95%,transparent 100%),
    linear-gradient(180deg,transparent 0%,rgba(0,0,0,.5) 9%,#000 22%,#000 74%,rgba(0,0,0,.55) 92%,transparent 100%);
  mask-composite:intersect}
.m-band img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 100%;
  filter:sepia(.72) saturate(1.55) brightness(2.05) contrast(1.24)
         drop-shadow(0 14px 18px rgba(16,8,3,.55))}
.m-army::before{content:"";position:absolute;left:41%;bottom:11vh;width:30vw;height:16vw;
  pointer-events:none;mix-blend-mode:screen;opacity:.6;
  background:
    radial-gradient(ellipse 26% 24% at 56% 52%,rgba(255,236,196,.6) 0%,rgba(255,206,138,.26) 44%,transparent 76%),
    linear-gradient(180deg,rgba(255,226,176,.30) 0%,rgba(255,196,124,.10) 22%,transparent 48%)}
/* the mounted samurai — the big one, closest to the viewer. He stands just
   in front of the ranks, on the same ground line, fully in frame. */
.m-rider{position:absolute;left:47%;bottom:11vh;height:28vh;width:auto;
  filter:sepia(.52) brightness(2.45) contrast(1.26) saturate(1.2)
         drop-shadow(0 16px 20px rgba(14,7,3,.6));
  opacity:.97;
  -webkit-mask-image:linear-gradient(180deg,#000 60%,rgba(0,0,0,.42) 92%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 60%,rgba(0,0,0,.42) 92%,transparent 100%)}

/* the middle distance: a luminous dust band BEHIND the ranks, so the army
   reads as silhouettes standing in light rather than a sepia illustration
   pasted on a brown field. */
.m-mist{position:absolute;left:0;right:0;bottom:0;height:38%;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(214,202,184,0) 0%,rgba(210,198,180,.10) 40%,rgba(204,190,170,.24) 72%,rgba(198,184,164,.32) 100%)}

/* the foreground: the ground the viewer is standing on. A dark base with a
   thin warm spill, so the bottom of the frame is a near plane instead of an
   empty wash. Kept light — a heavy band turns the lower third to mud. */
.m-fg{position:absolute;left:0;right:0;bottom:0;height:26%;pointer-events:none;
  background:
    radial-gradient(56% 44% at 32% 112%,rgba(255,166,72,.12) 0%,transparent 64%),
    linear-gradient(180deg,rgba(4,3,3,0) 0%,rgba(5,4,4,.20) 52%,rgba(3,3,3,.46) 100%)}

/* god rays off the horizon glow — the air itself, catching the low sun */
.m-rays{position:absolute;inset:-6% -14% 0 -14%;pointer-events:none;mix-blend-mode:screen;
  opacity:.5;
  background:
    conic-gradient(from 186deg at 72% 104%,
      transparent 0deg, rgba(255,214,150,.16) 4deg, transparent 9deg,
      transparent 13deg, rgba(255,206,138,.11) 17deg, transparent 23deg,
      transparent 28deg, rgba(255,220,160,.09) 31deg, transparent 36deg);
  -webkit-mask-image:radial-gradient(70% 58% at 72% 100%,#000 10%,transparent 76%);
  mask-image:radial-gradient(70% 58% at 72% 100%,#000 10%,transparent 76%);
  animation:m-rays 34s ease-in-out infinite alternate}
@keyframes m-rays{from{transform:translateX(-1.4%) rotate(-.5deg)}to{transform:translateX(1.4%) rotate(.5deg)}}

/* a flight of birds crossing the far sky — the only thing that moves up there */
.m-birds{position:absolute;left:52%;top:16%;width:min(16vw,230px);pointer-events:none;opacity:.5;
  animation:m-birds 48s linear infinite}
.m-birds svg{width:100%;height:auto;display:block;overflow:visible}
.m-birds path{fill:none;stroke:rgba(24,18,14,.62);stroke-width:1.6;stroke-linecap:round}
@keyframes m-birds{
  0%{transform:translate(0,0)}
  48%{transform:translate(-46vw,-7vh)}
  52%{transform:translate(-48vw,-7.4vh)}
  100%{transform:translate(-96vw,2vh)}}

/* embers: warm sparks, kept faint so they read on the bright plate */
.m-embers{position:absolute;inset:0;pointer-events:none}
.m-embers i{position:absolute;bottom:-6vh;left:calc(var(--x)*1vw);
  width:calc(var(--sz)*1.25px);height:calc(var(--sz)*1.25px);border-radius:50%;
  background:radial-gradient(circle,#b4531a 0%,#8a3a10 60%,transparent 74%);
  opacity:0;animation:rise var(--dur) linear var(--delay) infinite}
@keyframes rise{0%{opacity:0;transform:translate3d(0,0,0)}
  7%{opacity:calc(var(--op)*.55)}55%{opacity:calc(var(--op)*.35)}
  100%{opacity:0;transform:translate3d(var(--dx),-108vh,0)}}

/* a deep shadow on the list side, so cream type keeps its contrast in the
   smoke. The mode column gets its own darker pocket — red on warm brown is
   a low-contrast pair and STORY MODE only survives because of its glow. */
.m-scrim{position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(66% 68% at 15% 42%,rgba(3,3,5,.72) 0%,rgba(3,3,5,.44) 46%,rgba(3,3,5,0) 78%),
    radial-gradient(52% 46% at 30% 62%,rgba(3,3,5,.52) 0%,rgba(3,3,5,.24) 52%,transparent 84%),
    linear-gradient(90deg,rgba(3,3,5,.62) 0%,rgba(4,4,6,.18) 34%,rgba(3,3,5,0) 54%)}

/* one huge brush kanji, far back in the haze */
.m-watermark{position:absolute;right:20vw;top:12vh;z-index:1;pointer-events:none;
  font-family:var(--font-jp,"Zen Mincho",serif);font-weight:900;line-height:.8;
  font-size:70vh;color:#5a3410;opacity:.09;letter-spacing:0}

/* bright ground haze — figures dissolve into it instead of sitting on a line */
.m-haze{position:absolute;left:0;right:0;bottom:0;height:30%;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,240,208,0) 0%,rgba(255,236,196,.5) 46%,rgba(255,238,200,.9) 100%)}

.m-vig{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(128% 96% at 52% 34%,transparent 42%,rgba(3,3,5,.42) 82%,rgba(3,3,5,.72) 100%),
    linear-gradient(180deg,rgba(3,3,5,.45),transparent 18% 74%,rgba(3,3,5,.55)),
    radial-gradient(120% 46% at 46% 100%,rgba(120,70,22,.34),transparent 70%)}
.m-grain{position:absolute;inset:0;pointer-events:none;opacity:.22;mix-blend-mode:multiply;
  background:url(../assets/grain.png) repeat;background-size:64px}
html.no-grain .m-grain{display:none}

/* thin mottled gold rules, top and bottom — the scroll frame */
.m-frame{position:absolute;left:0;right:0;height:9px;z-index:3;pointer-events:none;
  background:linear-gradient(90deg,#7c521f,#d9ab5c 12%,#f3e0ac 28%,#a97a2f 44%,#e8cf95 62%,#8a5f22 80%,#d9ab5c 94%,#7c521f);
  box-shadow:0 0 0 1px rgba(58,36,10,.45)}
.m-frame.t{top:0}.m-frame.b{bottom:0;transform:scaleY(-1)}

/* ---------- 2. the hero -------------------------------------------------- */
/* She stands in the open now — the mountains are gone. She is framed from
   the head down to the knees and the shins dissolve into the ground haze,
   so the figure reads as a portrait crop rather than a cut-off person.
   She is a SEPARATE transparent PNG (750x1500), so she can be placed on her
   own plane: nearer the viewer than the ranks, clear of the frame edge. */
.m-hero{position:absolute;right:26vw;top:12vh;height:112vh;z-index:10;pointer-events:none;
  transform-origin:50% 100%;animation:hero-breathe 7.5s ease-in-out infinite}
@keyframes hero-breathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-6px) scale(1.005)}}
/* mon crest — the actual image, blended behind hero */
.m-crest{position:absolute;right:4vw;top:50%;width:44vw;height:44vw;
  transform:translateY(-50%);z-index:5;pointer-events:none;opacity:.38;
  mix-blend-mode:screen;filter:saturate(1.1) contrast(1.05) brightness(1.08)}
/* SEPARATION: a pocket of darkness behind her, so the smoke does not eat her
   silhouette. The old build put a bright halo there, which lightened the
   background AROUND her and dissolved her edges instead of holding them.
   The falloff is very long and wide — a tight one leaves a visible elliptical
   edge on the smoke, which reads as a dirty ring. */
.m-hero::before{content:"";position:absolute;inset:-26% -46% -14% -58%;z-index:-1;
  background:radial-gradient(52% 46% at 58% 44%,
    rgba(5,4,3,.62) 0%,rgba(7,5,4,.30) 46%,transparent 92%)}
/* the warm light she stands in — a low horizon sun from the left, kept weak
   so it warms her edge without washing the sky */
.m-hero::after{content:"";position:absolute;inset:-16% -40% -6% -50%;z-index:-1;
  background:radial-gradient(52% 46% at 46% 54%,
    rgba(255,214,152,.22) 0%,rgba(255,186,110,.09) 52%,transparent 88%)}
/* Solid down to the knees (70% of the plate), then a FAST dissolve into the
   haze: the knees are the last solid thing you see, so she reads as cropped
   at the knee rather than sliced off by the frame edge. */
.m-hero img{height:100%;width:auto;display:block;
  filter:drop-shadow(-14px 4px 22px rgba(255,158,74,.26))
         drop-shadow(-20px 26px 38px rgba(48,24,6,.42))
         drop-shadow(0 0 30px rgba(190,40,50,.12))
         brightness(0.96);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 69%,rgba(0,0,0,.55) 72%,rgba(0,0,0,.18) 75%,transparent 78%);
  mask-image:linear-gradient(180deg,#000 0%,#000 69%,rgba(0,0,0,.55) 72%,rgba(0,0,0,.18) 75%,transparent 78%)}

/* ---------- 3. logo lockup (top-left) ----------------------------------- */
.m-top{position:absolute;top:4.6vh;left:4.2vw;z-index:4;pointer-events:none}
.m-kicker{display:block;font-family:var(--font-ui,sans-serif);font-size:13px;font-weight:700;
  letter-spacing:.3em;color:#d8b478;margin-bottom:6px;
  text-shadow:0 1px 3px rgba(0,0,0,.85)}
.m-mark{font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(44px,6.6vw,104px);line-height:.9;color:#f6ead0;
  text-shadow:0 2px 0 rgba(0,0,0,.7),0 4px 18px rgba(0,0,0,.7),0 0 42px rgba(255,176,60,.16)}
.m-mark i{font-style:normal;color:#e0342c;margin-left:.12em;
  text-shadow:0 0 18px rgba(224,52,44,.55),0 2px 6px rgba(0,0,0,.8)}
.m-jp{font-family:var(--font-jp,"Zen Mincho",serif);font-weight:900;color:#e8564a;
  font-size:clamp(16px,2vw,27px);letter-spacing:.34em;margin-top:6px;opacity:.95;
  text-shadow:0 1px 4px rgba(0,0,0,.85)}

/* ---------- 4. the list -------------------------------------------------- */
/* The list is a RING of entries on a shared left edge: every entry is pinned
   to the same left margin (the title lockup's) and js/menu.js stacks it by its
   signed distance from the selection, wrapping past either end. The selected
   entry always rides the middle of the free band. */
.m-list{position:absolute;left:6.5vw;top:0;bottom:0;width:max-content;max-width:min(58vw,920px);
  z-index:5}
body.panel-open .m-list{opacity:0;pointer-events:none;transform:scale(.95);
  transition:opacity .28s ease,transform .28s ease}

.m-item{appearance:none;background:none;border:0;padding:0;margin:0;cursor:pointer;
  font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  position:absolute;left:0;top:0;transform-origin:left center;
  text-align:left;
  transition:transform .26s cubic-bezier(.2,.85,.25,1),opacity .24s,color .24s,letter-spacing .24s,filter .2s;
  will-change:transform,opacity;white-space:nowrap;text-wrap:nowrap}

/* The metal lives on an inner span, NOT on the button. That is what lets the
   flare plate sit BEHIND the letterforms: the old build painted the flare
   over the word (measured 2.5/10 legible) and the flare was deleted. On the
   span the flare is a separate layer under the glyphs, so the word stays
   crisp and the glow reads as light behind it. */
.m-item .tx{display:inline-block;color:transparent;
  background:linear-gradient(180deg,#fff8e2 0%,#ffe09a 20%,#f5ab35 46%,#d97a18 70%,#a84a10 100%);
  background-size:100% 200%;background-position:50% 0%;
  -webkit-background-clip:text;background-clip:text;
  filter:drop-shadow(0 0 1.6px rgba(0,0,0,1)) drop-shadow(0 2px 10px rgba(0,0,0,.9))
         drop-shadow(0 0 22px rgba(0,0,0,.6));
  transition:filter .2s}

.m-item.big{font-size:clamp(30px,4.7vw,68px);letter-spacing:.02em}
  /* the system entries keep a quieter, deeper gold so they stay secondary */
.m-item.sub{font-size:clamp(16px,2.1vw,28px);letter-spacing:.1em}
.m-item.sub .tx{background-image:linear-gradient(180deg,#ffeec6 0%,#e8c483 42%,#b08640 100%)}

/* selected — the OPPOSITE of the list: crimson, lit from within, with a
   light sweeping across the letters, a breathing bloom around them, a flare
   burning BEHIND the word and a brushed rule drawing in under it. */
.m-item.sel{letter-spacing:.07em;
  filter:drop-shadow(0 0 18px rgba(255,58,34,.5)) drop-shadow(0 0 44px rgba(255,58,34,.28))}
.m-item.sel .tx{background-image:linear-gradient(112deg,
    #ffd8cf 0%, #ff9d86 6%, #ff5a42 14%, #e0261b 26%, #a80f0a 38%,
    #ff7a5c 54%, #ffe0d4 66%, #d8251a 80%, #8c0d0b 92%, #c11a12 100%);
  background-size:320% 100%;background-position:0% 50%;
  animation:sel-sweep 4.4s cubic-bezier(.45,0,.2,1) infinite;
  filter:drop-shadow(0 0 1.6px rgba(0,0,0,.98)) drop-shadow(0 2px 9px rgba(0,0,0,.85))
         drop-shadow(0 0 12px rgba(255,58,34,.4))}
/* the light runs across the word and back — a slow shine, never a strobe */
@keyframes sel-sweep{
  0%{background-position:0% 50%}
  46%{background-position:100% 50%}
  54%{background-position:100% 50%}
  100%{background-position:0% 50%}}
/* the bloom breathes so the picked entry is the brightest thing on screen */
@keyframes sel-pulse{
  0%,100%{filter:drop-shadow(0 0 18px rgba(255,58,34,.42)) drop-shadow(0 0 34px rgba(255,58,34,.2))}
  50%{filter:drop-shadow(0 0 30px rgba(255,72,44,.72)) drop-shadow(0 0 70px rgba(255,58,34,.44))}}

/* THE FLARE — light burning behind the selected word. It sits under the
   glyphs (z-index:-1 inside the button's own stacking context), so it
   surrounds the letterforms instead of washing them out. */
.m-item.sel::before{content:"";position:absolute;left:-50px;right:-40px;top:50%;height:150%;
  transform:translateY(-50%);z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse at 50% 50%,
    rgba(255,178,72,.22) 0%,rgba(255,140,40,.07) 52%,transparent 74%);
  opacity:.95;border-radius:50%;
  animation:sel-disc 3.2s ease-in-out infinite}
@keyframes sel-disc{0%,100%{transform:translateY(-50%) scale(1);opacity:.85}
  50%{transform:translateY(-50%) scale(1.07);opacity:1}}
/* a brushed gold rule that draws itself in under the selected word */
.m-item.sel::after{content:"";position:absolute;left:0;right:-6%;bottom:-4%;height:13%;
  z-index:-1;pointer-events:none;
  background:linear-gradient(90deg,rgba(255,198,104,.85) 0%,rgba(255,240,198,.95) 46%,
    rgba(255,198,104,.7) 78%,transparent 100%);
  transform:scaleX(0);transform-origin:0 50%;
  animation:sel-rule .55s cubic-bezier(.2,.85,.25,1) forwards}
@keyframes sel-rule{to{transform:scaleX(1)}}

/* hover: an unselected entry warms up when the pointer is on it */
.m-item:not(.sel):hover .tx{filter:drop-shadow(0 0 1.6px rgba(0,0,0,1))
    drop-shadow(0 2px 10px rgba(0,0,0,.9)) drop-shadow(0 0 26px rgba(255,190,90,.42))
    brightness(1.18)}

/* entrance: the entries fade up in ring order when the menu opens, and they
   slide in from the left as they arrive. The SLIDE is on the CSS `translate`
   property, not `transform` — menu.js owns `transform` for the carousel, and
   an animation on `transform` would fight it. Only opacity is animated on
   the button itself, and the keyframe lands on the entry's own --o, so a
   dimmed entry does not flash bright on its way in. */
body.menu-open .m-item{animation:item-in .5s cubic-bezier(.2,.85,.25,1) backwards}
body.menu-open .m-item[data-i="0"]{animation-delay:.05s}
body.menu-open .m-item[data-i="1"]{animation-delay:.09s}
body.menu-open .m-item[data-i="2"]{animation-delay:.13s}
body.menu-open .m-item[data-i="3"]{animation-delay:.17s}
body.menu-open .m-item[data-i="4"]{animation-delay:.21s}
body.menu-open .m-item[data-i="5"]{animation-delay:.25s}
body.menu-open .m-item[data-i="6"]{animation-delay:.29s}
@keyframes item-in{from{opacity:0;translate:-26px 0}to{opacity:var(--o,1);translate:0 0}}
/* the selected entry carries the bloom AND the entrance together — the old
   rule `body.menu-open .m-item` outranked `.m-item.sel` and killed the
   sweep, the bloom and the flare on the very entry that needs them. */
body.menu-open .m-item.sel{animation:item-in .5s cubic-bezier(.2,.85,.25,1) backwards,
  sel-pulse 2.8s ease-in-out infinite}
body.menu-open .m-item.sel[data-i="0"]{animation-delay:.05s,0s}
body.menu-open .m-item.sel[data-i="1"]{animation-delay:.09s,0s}
body.menu-open .m-item.sel[data-i="2"]{animation-delay:.13s,0s}
body.menu-open .m-item.sel[data-i="3"]{animation-delay:.17s,0s}
body.menu-open .m-item.sel[data-i="4"]{animation-delay:.21s,0s}
body.menu-open .m-item.sel[data-i="5"]{animation-delay:.25s,0s}
body.menu-open .m-item.sel[data-i="6"]{animation-delay:.29s,0s}

/* keyboard focus follows the selection; the gradient alone marks it, so no
   outline ring — that ring was the "box" around the selected entry */
.m-item:focus,.m-item:focus-visible{outline:none}
.p-card:focus{outline:none}

/* ---------- 5. description strip + key legend ---------------------------- */
/* The strip reads the highlighted entry the way the real game does — VAULT's
   "View the spoils of your many victories!" and so on — with the fixed tagline
   kept underneath it, smaller and dimmer. */
.m-tag{position:absolute;left:0;right:0;bottom:9px;z-index:5;margin:0;padding:11px 4.2vw 13px;
  background:linear-gradient(180deg,rgba(0,0,0,0),rgba(0,0,0,.55) 42%,rgba(0,0,0,.82));
  color:#e9d9b4;font-style:italic;letter-spacing:.03em;
  text-shadow:0 1px 3px rgba(0,0,0,.55)}
/* the strip's text stops short of the credit in the corner */
.m-desc{margin:0;font-size:clamp(15px,1.75vw,22px);color:#f3e4c2;line-height:1.25;
  max-width:min(74%,900px);
  transition:opacity .16s ease,transform .16s ease}
.m-desc.swap{opacity:0;transform:translateY(5px)}
.m-tagline{margin:4px 0 0;font-size:clamp(11px,1.05vw,14px);opacity:.45}
.m-tag b{font-style:italic;color:#ffc96a}
/* credit: the crest and the maker's name, bottom right where the key legend
   used to sit */
.m-credit{position:absolute;right:4.2vw;bottom:20px;z-index:6;display:flex;align-items:center;
  gap:10px;pointer-events:none}
.m-mon{width:clamp(28px,2.6vw,40px);height:auto;opacity:.82;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.65));
  animation:mon-turn 44s linear infinite}
@keyframes mon-turn{to{transform:rotate(360deg)}}
.m-by{font-size:12px;letter-spacing:.3em;color:#e6cfa0;text-transform:uppercase;
  text-shadow:0 1px 4px rgba(0,0,0,.75)}
body.panel-open .m-tag,body.panel-open .m-credit{opacity:0;transition:opacity .25s}

/* ---------- 6. panels ---------------------------------------------------- */
.m-panel{position:absolute;inset:0;z-index:6;display:none;place-items:center;padding:6vh 4vw}
body.panel-open .m-panel{display:grid}
.m-panel::before{content:"";position:absolute;inset:0;background:rgba(4,4,6,.8);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:panel-dim .28s ease both}
@keyframes panel-dim{from{opacity:0}to{opacity:1}}

.p-card{position:relative;width:min(1080px,100%);max-height:82vh;overflow:auto;
  background:linear-gradient(165deg,rgba(16,10,4,.97),rgba(28,17,6,.95));
  border:1px solid rgba(214,170,92,.42);
  box-shadow:0 30px 90px rgba(0,0,0,.6),inset 0 0 0 1px rgba(255,232,180,.06);
  padding:clamp(18px,2.6vw,34px) clamp(18px,3vw,40px) clamp(14px,2vw,24px);
  animation:card-in .3s cubic-bezier(.2,.85,.25,1) both;scrollbar-width:thin;
  scrollbar-color:rgba(214,170,92,.5) transparent}
@keyframes card-in{from{opacity:0;transform:translateY(16px) scale(.985)}to{opacity:1;transform:none}}
.p-card::-webkit-scrollbar{width:8px}
.p-card::-webkit-scrollbar-thumb{background:rgba(214,170,92,.45)}

.p-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  border-bottom:1px solid rgba(214,170,92,.3);padding-bottom:12px;margin-bottom:16px}
.p-title{margin:0;font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(24px,3.2vw,42px);color:#f7dfae;transform:skewX(-9deg);
  text-shadow:0 2px 0 rgba(0,0,0,.5),0 0 22px rgba(224,168,66,.35);line-height:1}
.p-sub{margin:6px 0 0;font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:#b78f4d}
.p-jp{font-family:var(--font-jp,"Zen Mincho",serif);font-weight:900;color:#d8433f;
  font-size:clamp(15px,1.8vw,22px);letter-spacing:.3em;opacity:.8}

.p-body{color:#e9d9b4;font-size:clamp(13px,1.1vw,15px);line-height:1.6}
.p-body h4{margin:0 0 6px;font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:#b78f4d}
.p-body p{margin:0 0 12px;color:#cdb98f}
.p-foot{display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:space-between;
  margin-top:18px;padding-top:12px;border-top:1px solid rgba(214,170,92,.24);
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:#8f7647}
.p-key{display:inline-block;padding:2px 8px;margin-right:6px;border:1px solid rgba(214,170,92,.5);
  border-radius:3px;color:#e6cf9d;letter-spacing:.14em}
.p-note{color:#8f7647;font-style:italic;text-transform:none;letter-spacing:.04em;font-size:12px}

/* rows (chapters, heroes, stages) */
.p-rows{display:grid;gap:6px}
.p-row{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;
  padding:9px 12px;border:1px solid rgba(214,170,92,.16);background:rgba(255,236,190,.03);
  color:#d9c69c;cursor:pointer;transition:background .15s,border-color .15s,transform .15s}
.p-row:hover{background:rgba(255,220,150,.09);border-color:rgba(214,170,92,.45)}
.p-row.sel{background:linear-gradient(90deg,rgba(255,196,92,.22),rgba(255,196,92,.05));
  border-color:rgba(255,206,120,.75);color:#ffeec4;transform:translateX(3px)}
.p-row .idx{font-family:var(--font-title,"OniStormMenu",Georgia,serif);font-size:19px;
  color:#d8a44f;min-width:2ch;text-align:center}
.p-row .nm{font-size:14px;letter-spacing:.14em;text-transform:uppercase}
.p-row .nm em{display:block;font-style:normal;font-size:11px;letter-spacing:.05em;
  text-transform:none;color:#93804f;margin-top:2px}
.p-row .rt{font-size:11px;letter-spacing:.16em;color:#a48c56;text-transform:uppercase;white-space:nowrap}

/* two-column split: list on the left, detail on the right */
.p-split{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:22px}
.p-detail{border-left:1px solid rgba(214,170,92,.24);padding-left:22px}
.p-detail .big{font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(20px,2.4vw,30px);color:#ffe0a2;transform:skewX(-9deg);line-height:1.05;margin:0 0 8px}
.p-detail .meta{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px}
.p-detail .tag{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:#d8a44f;
  border:1px solid rgba(214,170,92,.35);padding:3px 8px}
.p-stats{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:12px;color:#b39c6c}
.p-stats b{color:#e2c894;font-weight:600}

/* hero emblems */
.p-emblem{width:46px;height:46px;flex:none}
.p-emblem svg{width:100%;height:100%;display:block}

/* options */
.p-opt{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:11px 12px;
  border:1px solid rgba(214,170,92,.18);background:rgba(255,236,190,.03);cursor:pointer;color:#dcc99f;
  transition:border-color .15s,background .15s;width:100%;text-align:left;font:inherit}
.p-opt:hover{border-color:rgba(214,170,92,.5);background:rgba(255,220,150,.08)}
.p-opt .lab{font-size:12px;letter-spacing:.2em;text-transform:uppercase}
.p-opt .lab em{display:block;font-style:normal;letter-spacing:.02em;text-transform:none;
  font-size:11px;color:#8f7647;margin-top:3px}
.p-sw{width:52px;height:24px;flex:none;border:1px solid rgba(214,170,92,.5);position:relative;
  background:rgba(0,0,0,.35);transition:background .18s}
.p-sw::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;background:#8a714a;
  transition:transform .18s,background .18s}
.p-opt[aria-pressed="true"] .p-sw{background:rgba(255,180,60,.3)}
.p-opt[aria-pressed="true"] .p-sw::after{transform:translateX(28px);background:#ffce72}

/* sugoroku board */
.p-board{display:grid;grid-template-columns:repeat(10,1fr);gap:4px;margin-top:4px}
.p-space{aspect-ratio:1;display:grid;place-items:center;font-size:10px;letter-spacing:.06em;
  border:1px solid rgba(214,170,92,.28);background:rgba(255,236,190,.04);color:#a48c56;
  font-family:var(--font-title,"OniStormMenu",Georgia,serif)}
.p-space.star{background:rgba(255,196,92,.22);color:#ffe3a6;border-color:rgba(255,206,120,.7)}
.p-space.boss{background:rgba(190,40,40,.3);color:#ffcdc0;border-color:rgba(220,90,70,.7)}
.p-space.s{grid-column:span 2;aspect-ratio:auto;padding:6px 0;text-align:center}

/* vault gallery */
.p-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}
.p-cell{border:1px solid rgba(214,170,92,.22);background:rgba(255,236,190,.03);padding:14px;
  display:grid;gap:10px;justify-items:center;text-align:center}
.p-cell img{max-width:100%;height:auto;display:block}
.p-cell .cap{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:#a48c56}

/* the film grain sits over the whole screen, figure included, so nothing
   looks pasted on top of the plate. It is also the dither that stops the
   big smooth gradients (sky, ground haze) from banding on an 8-bit display. */
.menu::after{content:"";position:absolute;inset:0;z-index:8;pointer-events:none;
  background:url(../assets/grain.png) repeat;opacity:.16;mix-blend-mode:overlay}
html.no-grain .menu::after{display:none}

/* OPTIONS toggles (js/menu.js persists them). The cursor rule lives in
   css/style.css section 14, so `no-cursor` wins by specificity + !important. */
html.no-cursor,html.no-cursor *{cursor:auto!important}
html.no-motion .menu,html.no-motion .menu *{animation:none!important;transition:none!important}

/* soldiers removed — clean smoke only */
.m-army,.m-armyglow,.m-mist,.m-haze,.m-watermark{display:none}

/* ---------- 7. transitions ----------------------------------------------- */
/* one bright blade-flash when the title gives way to the menu */
.m-wipe{position:fixed;inset:0;z-index:60;pointer-events:none;opacity:0;
  background:linear-gradient(100deg,rgba(255,255,255,0) 38%,rgba(255,250,232,.98) 50%,rgba(255,255,255,0) 62%)}
body.menu-open .m-wipe{animation:m-wipe .82s cubic-bezier(.4,0,.2,1) both}
@keyframes m-wipe{0%{opacity:0;transform:translateX(-42%) skewX(-14deg)}
  22%{opacity:1}60%{opacity:.7}100%{opacity:0;transform:translateX(46%) skewX(-14deg)}}

/* ---------- 8. reduced motion + no-video --------------------------------- */
@media (prefers-reduced-motion:reduce){
  .m-smoke video,.m-red video,.m-hero,.m-item.sel::before,.m-item.sel::after,
  .m-item .tx,.m-embers,.mf1,.mf2,.mf3{animation:none!important}
  .m-embers{display:none}
  body.menu-open .m-item{animation:none!important}
  .m-wipe{display:none}
}

/* ---------- 9. responsive ------------------------------------------------ */
@media (max-width:860px){
  /* phone: lockup + figure up top, the list lives on a dark plate at the
     bottom, banner hidden so nothing sits behind the glyphs */
  .m-top{top:3.6vh;left:6vw}
  .m-mark{font-size:clamp(30px,11vw,46px)}
  .m-kicker{font-size:10px;letter-spacing:.26em}
  .m-hero{height:74vh;right:-8vw;top:6vh;bottom:auto}
  .m-hero::before{inset:-10% -16% -4% -20%}
  .m-band{left:-8%;bottom:10vh;width:88vw;aspect-ratio:2.17}
  .m-rider{left:58%;bottom:13vh;height:22vh}
  .m-armyglow{left:16%;bottom:6vh;width:56%;height:26%}
  .m-rays{opacity:.34}
  .m-birds{left:44%;top:12%;width:min(30vw,180px)}
  /* phone: the list keeps its shared left edge and its own dark plate, and
     the crest shrinks */
  .m-list{left:8vw;width:max-content;max-width:92vw;top:0;bottom:0}
  /* the hero is a sibling of .menu-bg, so it paints ABOVE that block's scrim —
     on a phone the list needs its own backdrop or the type sits on her armour.
     The anchor box has no height, so the plate is sized from the viewport. */
  .m-list::before{content:"";position:absolute;left:-4vw;right:-10vw;top:-14vh;bottom:-14vh;
    z-index:-1;pointer-events:none;
    background:radial-gradient(58% 52% at 50% 50%,rgba(3,3,5,.86),rgba(3,3,5,.55) 62%,transparent 88%)}
  .m-item.big{font-size:clamp(26px,8.4vw,40px)}
  .m-item.sub{font-size:clamp(15px,4.8vw,21px)}
  /* on a phone the type sits over the warrior's armour, so it goes flat
     cream with a hard shadow instead of the gold metal gradient */
  .m-item .tx{background-image:none;color:#f7e8c4;
    filter:drop-shadow(0 0 1.4px rgba(0,0,0,1)) drop-shadow(0 2px 9px rgba(0,0,0,.8))}
  .m-item.sub .tx{color:#e2cea4;
    filter:drop-shadow(0 0 1.4px rgba(0,0,0,1)) drop-shadow(0 1px 7px rgba(0,0,0,.75))}
  .m-item.sel .tx{color:#ffd9cf;background-image:linear-gradient(112deg,
    #ffd8cf 0%, #ff9d86 6%, #ff5a42 14%, #e0261b 26%, #a80f0a 38%,
    #ff7a5c 54%, #ffe0d4 66%, #d8251a 80%, #8c0d0b 92%, #c11a12 100%);
    background-size:320% 100%;background-position:0% 50%}
  .m-army{inset:0;opacity:.9}
  .m-army::after{left:14%;bottom:4vh;width:56%;height:14vh}
  .m-army::before{left:-8%;bottom:13vh;width:70vw;height:26vw}
  .m-watermark{font-size:38vh;right:-4vw;top:18vh;opacity:.05}
  /* the list now sits over the middle of the plate, so the scrim has to dark
     that band too — cream type over the warrior needs something to sit on */
  .m-scrim{background:linear-gradient(180deg,rgba(3,3,5,.34) 24%,rgba(3,3,5,.70) 46%,rgba(3,3,5,.88) 100%),
    radial-gradient(84% 30% at 42% 46%,rgba(3,3,5,.55),transparent 74%)}
  .m-glow{background:radial-gradient(120% 26% at 50% 76%,rgba(255,238,198,.4) 0%,rgba(255,206,150,.14) 52%,transparent 82%)}
  .m-credit{right:6vw;bottom:calc(16px + env(safe-area-inset-bottom,0px))}
  .m-mon{width:24px}
  .m-by{font-size:10px;letter-spacing:.22em}
  .m-tag{padding:9px 6vw calc(14px + env(safe-area-inset-bottom,0px))}
  .m-desc{font-size:clamp(14px,4.1vw,18px);max-width:100%}
  .m-tagline{font-size:11px;margin-top:3px;max-width:78%}
  .p-split{grid-template-columns:1fr;gap:14px}
  .p-detail{border-left:0;border-top:1px solid rgba(214,170,92,.24);padding:14px 0 0}
  .m-panel{padding:4vh 3vw;align-items:start}
  .p-card{max-height:88vh}
  .p-board{grid-template-columns:repeat(5,1fr)}
}
@media (max-height:520px) and (orientation:landscape){
  .m-hero{height:96vh;top:2vh;bottom:auto}
}

/* ==========================================================================
   CHARACTER SELECTION — Samurai Warriors 2 style roster screen
   ========================================================================== */

/* ---------- tokens ---------------------------------------------------- */
.character{
  position:fixed; inset:0; z-index:50; overflow:hidden;
  opacity:0; visibility:hidden;
  font-family:var(--font-ui,"Segoe UI",system-ui,sans-serif);
  color:var(--ivory);
  transition:opacity .5s ease, visibility .5s;
  -webkit-tap-highlight-color:transparent;
}
body.character-open .character{opacity:1;visibility:visible}
body.character-open .menu{opacity:0;visibility:hidden;transition:opacity .4s ease}
body.character-closing .character{opacity:0;transition-duration:.35s}

/* ---------- background ------------------------------------------------ */
.c-bg{position:absolute;inset:0;z-index:0;
  background:radial-gradient(120% 85% at 50% 6%,#1a141c 0%,#0b0a0d 48%,#050506 100%)}

/* smoke layer — screen blend like menu */
.c-smoke{position:absolute;inset:-3%;overflow:hidden;opacity:.85;mix-blend-mode:screen;
  pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 52%,rgba(0,0,0,.72) 76%,rgba(0,0,0,.34) 100%);
  mask-image:linear-gradient(180deg,#000 0%,#000 52%,rgba(0,0,0,.72) 76%,rgba(0,0,0,.34) 100%)}
.c-smoke video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:sepia(.65) saturate(1.5) brightness(.82) contrast(1.06);
  animation:c-breathe 52s ease-in-out infinite alternate}
@keyframes c-breathe{from{transform:scale(1.04)}to{transform:scale(1.12) translate3d(-1%,-1%,0)}}
html.no-smoke .c-smoke{display:none}

/* red drift on right side */
.c-red{position:absolute;inset:0;mix-blend-mode:multiply;pointer-events:none;opacity:.28;
  -webkit-mask-image:linear-gradient(90deg,transparent 40%,rgba(0,0,0,.35) 60%,#000 80%);
  mask-image:linear-gradient(90deg,transparent 40%,rgba(0,0,0,.35) 60%,#000 80%)}
.c-red video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:sepia(.55) saturate(1.4) brightness(1.1);
  animation:c-red-drift 46s ease-in-out infinite alternate}
@keyframes c-red-drift{from{transform:scale(1.06)}to{transform:scale(1.13) translate3d(-1.6%,1%,0)}}
html.no-smoke .c-red{display:none}

/* fog tiles */
.c-fog{position:absolute;inset:-12%;pointer-events:none;background-repeat:repeat;
  mix-blend-mode:multiply;opacity:.25;
  filter:invert(1) sepia(.7) saturate(1.1) contrast(1.05)}
.cf1{background-image:url(../assets/art/fog-tile-512.png);background-size:940px;animation:fog-a 110s linear infinite}
.cf2{background-image:url(../assets/art/fog-tile-384.png);background-size:600px;opacity:.2;animation:fog-b 150s linear infinite}
.cf3{background-image:url(../assets/art/fog-tile-512.png);background-size:1500px;opacity:.14;animation:fog-c 210s linear infinite}
@media (prefers-reduced-motion:reduce){.cf1,.cf2,.cf3{animation:none!important}}

/* thin gold rules */
.c-frame{position:absolute;left:0;right:0;height:9px;z-index:3;pointer-events:none;
  background:linear-gradient(90deg,#7c521f,#d9ab5c 12%,#f3e0ac 28%,#a97a2f 44%,#e8cf95 62%,#8a5f22 80%,#d9ab5c 94%,#7c521f);
  box-shadow:0 0 0 1px rgba(58,36,10,.45)}
.c-frame.t{top:0}.c-frame.b{bottom:0;transform:scaleY(-1)}

/* ---------- top lockup -------------------------------------------------- */
.c-top{position:absolute;top:4.6vh;left:4.2vw;z-index:4;pointer-events:none}
.c-kicker{display:block;font-family:var(--font-ui,sans-serif);font-size:13px;font-weight:700;
  letter-spacing:.3em;color:#d8b478;margin-bottom:6px;text-shadow:0 1px 3px rgba(0,0,0,.85)}
.c-mark{font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(44px,6.6vw,104px);line-height:.9;color:#f6ead0;
  text-shadow:0 2px 0 rgba(0,0,0,.7),0 4px 18px rgba(0,0,0,.7),0 0 42px rgba(255,176,60,.16)}
.c-mark i{font-style:normal;color:#e0342c;margin-left:.12em;
  text-shadow:0 0 18px rgba(224,52,44,.55),0 2px 6px rgba(0,0,0,.8)}
.c-jp{font-family:var(--font-jp,"Zen Mincho",serif);font-weight:900;color:#e8564a;
  font-size:clamp(16px,2vw,27px);letter-spacing:.34em;margin-top:6px;opacity:.95;
  text-shadow:0 1px 4px rgba(0,0,0,.85)}

/* ---------- carousel ---------------------------------------------------- */
.c-carousel{
  position:absolute;left:3.5vw;top:50%;transform:translateY(-50%);
  z-index:10;display:flex;align-items:center;gap:16px;pointer-events:none
}
.c-nav{
  appearance:none;background:rgba(8,6,4,.85);border:1px solid rgba(214,170,92,.35);
  width:48px;height:48px;border-radius:50%;display:grid;place-items:center;
  color:#e2c894;cursor:pointer;transition:background .18s,border-color .18s,transform .18s,box-shadow .18s;
  pointer-events:auto;flex:none
}
.c-nav:hover{background:rgba(255,236,190,.12);border-color:rgba(255,206,120,.7);transform:scale(1.08);
  box-shadow:0 0 24px rgba(255,176,60,.25)}
.c-nav:focus{outline:none;box-shadow:0 0 0 2px #ffce72,0 0 24px rgba(255,176,60,.35)}
.c-nav svg{width:22px;height:22px}
.c-nav-prev{transform:rotate(180deg)}
html[dir="rtl"] .c-nav-prev{transform:none}
html[dir="rtl"] .c-nav-next{transform:rotate(180deg)}

.c-portraits{
  position:relative;width:96px;height:520px;flex:none;
  display:flex;flex-direction:column;justify-content:center;align-items:center;gap:14px
}

/* circular path positions for 4 portraits */
.c-portrait{
  position:relative;width:80px;height:80px;border-radius:50%;
  overflow:hidden;cursor:pointer;pointer-events:auto;
  transition:transform .35s cubic-bezier(.2,.85,.25,1),opacity .3s,filter .3s,box-shadow .3s,z-index .3s;
  will-change:transform,opacity,filter,box-shadow
}
.c-portrait img{width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.15) contrast(1.05) brightness(.92)}
.c-portrait::before{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:2px solid transparent;pointer-events:none;z-index:1;
  transition:border-color .3s,box-shadow .3s,opacity .3s
}
.c-portrait::after{
  content:"";position:absolute;inset:0;border-radius:50%;
  background:radial-gradient(ellipse at 50% 50%,rgba(255,236,190,.08),transparent 70%);
  pointer-events:none;z-index:2;opacity:0;transition:opacity .3s
}

/* depth states via data-depth: 0=selected(center), 1=adjacent, 2=far, 3=farther */
.c-portrait[data-depth="0"]{
  transform:scale(1.35) translateZ(0);opacity:1;z-index:10;
  filter:grayscale(0) contrast(1.15) brightness(1.1) drop-shadow(0 0 24px rgba(224,52,44,.55))
}
.c-portrait[data-depth="0"]::before{
  border-color:#ffce72;box-shadow:0 0 28px rgba(255,206,114,.6),inset 0 0 28px rgba(255,206,114,.25);opacity:1
}
.c-portrait[data-depth="0"]::after{opacity:1}

.c-portrait[data-depth="1"],
.c-portrait[data-depth="-1"]{
  transform:scale(1.0) translateY(0) translateZ(0);opacity:.85;z-index:5;
  filter:grayscale(.25) contrast(1.0) brightness(.85)
}
.c-portrait[data-depth="1"]::before,
.c-portrait[data-depth="-1"]::before{
  border-color:rgba(214,170,92,.45);box-shadow:0 0 16px rgba(214,170,92,.25);opacity:1
}

.c-portrait[data-depth="2"],
.c-portrait[data-depth="-2"]{
  transform:scale(.78) translateY(0) translateZ(0);opacity:.55;z-index:2;
  filter:grayscale(.6) contrast(.9) brightness(.7)
}
.c-portrait[data-depth="2"]::before,
.c-portrait[data-depth="-2"]::before{opacity:0}

.c-portrait[data-depth="3"],
.c-portrait[data-depth="-3"]{
  transform:scale(.6) translateY(0) translateZ(0);opacity:.25;z-index:1;
  filter:grayscale(.85) contrast(.8) brightness(.55)
}
.c-portrait[data-depth="3"]::before,
.c-portrait[data-depth="-3"]::before{opacity:0}

.c-portrait:focus{outline:none}
.c-portrait:focus-visible::before{border-color:#ffce72;box-shadow:0 0 0 2px #ffce72,0 0 24px rgba(255,176,60,.35)}

/* ---------- main character stage --------------------------------------- */
.c-stage{
  position:absolute;left:calc(3.5vw + 96px + 32px);top:50%;transform:translateY(-50%);
  width:calc(100% - (3.5vw + 96px + 32px) - 380px - 4.2vw);max-width:720px;
  z-index:8;display:flex;flex-direction:column;align-items:center;justify-content:center;
  pointer-events:none
}
.c-platform{
  position:absolute;bottom:0;left:50%;transform:translateX(-50%);
  width:min(85%,580px);aspect-ratio:1;
  background:
    radial-gradient(ellipse 80% 35% at 50% 55%,
      rgba(255,206,114,.35) 0%,
      rgba(255,176,60,.18) 35%,
      rgba(255,140,40,.06) 60%,
      transparent 80%),
    conic-gradient(from 180deg at 50% 50%,
      transparent 0deg, rgba(255,206,114,.18) 12deg, transparent 24deg,
      transparent 36deg, rgba(255,198,124,.14) 48deg, transparent 60deg);
  filter:blur(2px);opacity:.9;animation:c-platform 8s ease-in-out infinite alternate
}
@keyframes c-platform{
  0%{transform:translateX(-50%) scale(1) rotate(0deg);opacity:.85}
  50%{transform:translateX(-50%) scale(1.02) rotate(.6deg);opacity:.95}
  100%{transform:translateX(-50%) scale(1) rotate(0deg);opacity:.85}
}
@media (prefers-reduced-motion:reduce){.c-platform{animation:none!important}}

.c-glow{
  position:absolute;inset:0;pointer-events:none;z-index:-1;
  background:radial-gradient(ellipse 60% 80% at 50% 55%,
    rgba(255,90,66,.18) 0%,
    rgba(255,140,40,.12) 30%,
    rgba(255,176,60,.06) 55%,
    transparent 80%);
  opacity:0;transition:opacity .5s ease
}
.c-glow.active{opacity:1}

.c-figure{
  position:relative;z-index:5;max-width:100%;max-height:78vh;width:auto;height:auto;
  object-fit:contain;
  filter:
    drop-shadow(-8px 4px 18px rgba(255,58,34,.35))
    drop-shadow(-14px 20px 32px rgba(48,24,6,.55))
    drop-shadow(0 0 40px rgba(224,52,44,.18))
    brightness(.98);
  opacity:0;transform:translateY(24px) scale(.96);
  transition:opacity .45s cubic-bezier(.2,.85,.25,1),transform .45s cubic-bezier(.2,.85,.25,1),filter .3s
}
.c-figure.ready{opacity:1;transform:none}
.c-figure.switching{opacity:0;transform:translateY(-16px) scale(.98)}

/* nameplate under character */
.c-nameplate{
  position:absolute;bottom:-68px;left:50%;transform:translateX(-50%);
  text-align:center;pointer-events:none;white-space:nowrap
}
.c-name-en{
  display:block;font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(28px,4.2vw,56px);line-height:1;
  color:#f6ead0;
  text-shadow:0 2px 0 rgba(0,0,0,.7),0 4px 18px rgba(0,0,0,.7),0 0 32px rgba(255,176,60,.22);
  transform:skewX(-9deg);letter-spacing:.02em
}
.c-name-jp{
  display:block;font-family:var(--font-jp,"Zen Mincho",serif);font-weight:900;
  font-size:clamp(16px,2.2vw,26px);color:#e8564a;letter-spacing:.3em;margin-top:4px;opacity:.9
}

/* ---------- info panel -------------------------------------------------- */
.c-info{
  position:absolute;right:4.2vw;top:50%;transform:translateY(-50%);
  width:360px;max-width:calc(100% - 4.2vw - 4.2vw - 3.5vw - 96px - 32px);
  z-index:10;display:flex;flex-direction:column;gap:20px;pointer-events:auto
}
.c-title-block{text-align:right}
.c-char-title{
  margin:0;font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(28px,4.8vw,52px);line-height:1.05;color:#f7dfae;
  transform:skewX(-9deg);text-shadow:0 2px 0 rgba(0,0,0,.5),0 0 22px rgba(224,168,66,.35)
}
.c-char-sub{
  margin:6px 0 0;font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:#b78f4d
}
.c-desc{color:#cdb98f;font-size:clamp(13px,1.1vw,15px);line-height:1.65;text-align:right;
  border-right:2px solid rgba(214,170,92,.35);padding-right:14px}

.c-stats{display:flex;flex-direction:column;gap:16px}
.c-stat{display:flex;flex-direction:column;gap:6px;text-align:right}
.c-stat-label{
  font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:#8f7647
}
.c-stat-bar{
  position:relative;height:10px;background:rgba(8,6,4,.85);
  border:1px solid rgba(214,170,92,.28);border-radius:5px;overflow:hidden
}
.c-stat-fill{
  position:absolute;top:0;bottom:0;right:0;width:0%;
  background:linear-gradient(90deg,#e0342c,#ff7a5c 40%,#ffce72 70%,#fff8e2);
  border-radius:4px;transition:width .5s cubic-bezier(.2,.85,.25,1);
  box-shadow:0 0 12px rgba(255,120,40,.5),inset 0 0 12px rgba(255,255,255,.15)
}
.c-stat-value{
  font-family:var(--font-title,"OniStormMenu",Georgia,serif);
  font-size:clamp(18px,2.4vw,28px);color:#ffce72;text-align:right;
  text-shadow:0 1px 3px rgba(0,0,0,.6),0 0 12px rgba(255,206,114,.35)
}

/* stat bar colors per stat */
.c-stat:nth-child(1) .c-stat-fill{background:linear-gradient(90deg,#e0342c,#ff7a5c 40%,#ffce72 70%,#fff8e2)}
.c-stat:nth-child(2) .c-stat-fill{background:linear-gradient(90deg,#2a7ae0,#5ca8ff 40%,#a8d0ff 70%,#dcf0ff)}
.c-stat:nth-child(3) .c-stat-fill{background:linear-gradient(90deg,#8e3ce0,#c07aff 40%,#e8c8ff 70%,#f3e8ff)}

.c-actions{display:flex;gap:14px;margin-top:8px}
.c-btn{
  appearance:none;border:1px solid rgba(214,170,92,.45);
  background:linear-gradient(165deg,rgba(16,10,4,.97),rgba(28,17,6,.95));
  color:#e6cf9d;padding:12px 20px;font-family:var(--font-ui,sans-serif);
  font-size:12px;letter-spacing:.18em;text-transform:uppercase;cursor:pointer;
  display:flex;align-items:center;gap:8px;transition:border-color .18s,background .18s,box-shadow .18s,transform .12s
}
.c-btn:hover{border-color:rgba(255,206,120,.85);background:rgba(255,236,190,.12);box-shadow:0 0 20px rgba(255,176,60,.18);transform:translateY(-1px)}
.c-btn:focus{outline:none;box-shadow:0 0 0 2px #ffce72,0 0 20px rgba(255,176,60,.3)}
.c-key{
  display:inline-block;padding:1px 8px;border:1px solid rgba(214,170,92,.55);
  border-radius:3px;background:rgba(0,0,0,.35);color:#ffce72;
  font-family:var(--font-title,"OniStormMenu",Georgia,serif);font-size:11px;letter-spacing:.1em
}

/* ---------- credit ------------------------------------------------------ */
.c-credit{
  position:absolute;right:4.2vw;bottom:20px;z-index:6;display:flex;align-items:center;
  gap:10px;pointer-events:none
}
.c-mon{width:clamp(28px,2.6vw,40px);height:auto;opacity:.82;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.65));
  animation:mon-turn 44s linear infinite}
@keyframes mon-turn{to{transform:rotate(360deg)}}
.c-by{font-size:12px;letter-spacing:.3em;color:#e6cfa0;text-transform:uppercase;
  text-shadow:0 1px 4px rgba(0,0,0,.75)}
body.panel-open .c-credit{opacity:0;transition:opacity .25s}

/* ---------- grain overlay ----------------------------------------------- */
.character::after{content:"";position:absolute;inset:0;z-index:20;pointer-events:none;
  background:url(../assets/grain.png) repeat;opacity:.16;mix-blend-mode:overlay}
html.no-grain .character::after{display:none}

/* ---------- responsive -------------------------------------------------- */
@media (max-width:1280px){
  .c-carousel{left:2.5vw;gap:12px}
  .c-portraits{width:80px;height:440px;gap:10px}
  .c-portrait{width:68px;height:68px}
  .c-portrait[data-depth="0"]{transform:scale(1.28)}
  .c-stage{left:calc(2.5vw + 80px + 24px);width:calc(100% - (2.5vw + 80px + 24px) - 320px - 4.2vw);max-width:580px}
  .c-info{right:3vw;width:300px}
}
@media (max-width:860px){
  .character{overflow:auto}
  .c-carousel{
    position:relative;left:auto;top:auto;transform:none;
    flex-direction:column;align-items:center;width:100%;
    padding:20vh 4vw 8vh;margin:0 auto;max-width:400px;gap:16px
  }
  .c-nav{width:40px;height:40px;order:2}
  .c-nav-prev{order:1;transform:rotate(180deg)}
  .c-nav-next{order:3}
  .c-portraits{
    order:2;width:100%;height:auto;flex-direction:row;flex-wrap:wrap;
    justify-content:center;gap:12px;padding:0 2vw
  }
  .c-portrait{width:72px;height:72px}
  .c-portrait[data-depth="0"]{transform:scale(1.2)}
  .c-stage{
    position:relative;left:auto;top:auto;transform:none;width:100%;max-width:none;
    order:3;padding:0 4vw 4vh
  }
  .c-figure{max-height:45vh}
  .c-nameplate{bottom:-56px}
  .c-info{position:relative;right:auto;top:auto;transform:none;width:100%;max-width:none;order:4;padding:0 4vw 8vh;align-items:center;text-align:center}
  .c-desc{border-right:none;border-bottom:2px solid rgba(214,170,92,.35);padding:0 0 14px;text-align:center;max-width:380px}
  .c-stats{flex-direction:row;justify-content:center;flex-wrap:wrap;max-width:380px}
  .c-stat{flex:1;min-width:100px}
  .c-stat-label,.c-stat-value,.c-char-sub{text-align:center}
  .c-char-title{text-align:center}
  .c-actions{justify-content:center;width:100%}
  .c-credit{position:relative;right:auto;bottom:auto;margin-top:16px;justify-content:center}
  .c-top{left:50%;transform:translateX(-50%);top:3.6vh;text-align:center}
}
