/* Ninefall — the look.

   A dark stage the hero stands on, with everything else floating over it: an uppercase eyebrow, a
   serif name, rarity told by a pill, and a glass panel for whatever the screen lets you choose. The
   direction is the Mythic Model Lab tester: vignette and grain over a lit ground, gold on deep blue,
   micro-labels in wide uppercase, one characterful serif against a plain interface sans.

   Three rules hold it together:
     · one shape - a rounded rectangle at one of four radii; nothing is a circle or a pill
     · one control height - every button is --control tall, whatever it says
     · one spacing and tracking scale - the space between letters and parts comes from the tokens
       below and nowhere else, which is what makes it read as made rather than assembled.

   Nothing scrolls: every screen is sized to the display (see fit() in the sprite module). */

@font-face{
  font-family:"Playfair Display";
  src:url("/fonts/playfair-display.woff2") format("woff2-variations");
  font-weight:400 900;font-style:normal;font-display:swap;
}

:root{
  --bg:#070912;
  --ink:#f8f4ea;
  --muted:#9a9cab;
  --line:#ffffff1c;
  --line-soft:#ffffff0e;
  --panel:linear-gradient(180deg,#111625df,#090c15df);
  --panel-line:#ffffff18;
  --gold:#d9bd75;
  --gold-hi:#f0d58d;
  --grey:#9aa0ae;
  --green:#7cc08d;
  --blue:#91b4ff;
  --violet:#9277ff;
  --rarity:var(--grey);

  --serif:"Playfair Display",Georgia,"Times New Roman",serif;
  --sans:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* type: three roles, and the tracking each one wants */
  --t-display:clamp(32px,8.5vw,58px);
  --t-body:12.5px;
  --t-label:10px;
  --t-micro:9.5px;
  --track-display:-.015em;
  --track-label:.16em;
  --track-micro:.22em;
  --track-caption:.1em;
  --lead-display:.95;
  --lead-body:1.62;
  --lead-label:1.25;

  /* space: one scale, for every gap and every padding */
  --s1:6px; --s2:10px; --s3:14px; --s4:18px; --s5:24px;
  /* shape: rounded rectangles only */
  --r-panel:18px;
  --r-tile:14px;
  --r-control:12px;
  --r-pill:9px;
  --control:40px;

  --ease:cubic-bezier(.22,1,.36,1);
  --ease-inout:ease-in-out;
  --move:300ms;
  --travel:34px;
  color-scheme:dark;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;overflow:hidden;
  background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-size:var(--t-body);line-height:var(--lead-body);
  -webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;
  user-select:none;-webkit-user-select:none;
  touch-action:manipulation;overscroll-behavior:none;
  text-rendering:optimizeLegibility;
}
[hidden]{display:none!important}
button{font:inherit;color:inherit;cursor:pointer}
img{display:block;max-width:100%}

/* ---------- the stage: the world behind everything ---------- */
.stage{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--bg)}
.sky{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .5s var(--ease)}
.stage[data-ready="true"] .sky{opacity:1}
.vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at 50% 42%,transparent 38%,#03040a55 74%,#010207e6 112%)}
.grain{position:absolute;inset:0;pointer-events:none;opacity:.05;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E")}

/* ---------- the screen ---------- */
#view{
  position:relative;z-index:1;
  height:100dvh;width:100%;max-width:1180px;margin:0 auto;
  padding:max(var(--s4),env(safe-area-inset-top)) max(var(--s4),env(safe-area-inset-left)) calc(env(safe-area-inset-bottom) + 78px);
  display:flex;flex-direction:column;gap:var(--s3);
}
#view[data-slack] .grid,#view[data-slack] .frame,#view[data-slack] .body,#view[data-slack] .state{margin-block:auto}
/* One view gives way to the next: the incoming screen arrives a short way off its place and eases in.
   Transforms only, so the glass over the stage never flattens mid-move. */
[data-view]{visibility:hidden;animation:var(--move) var(--ease-inout) both paused}
[data-view][data-run="true"]{visibility:visible;animation-play-state:running}
[data-view="push"]{animation-name:view-push}
[data-view="pop"]{animation-name:view-pop}
[data-view="cover"]{animation-name:view-cover}
[data-view="dismiss"]{animation-name:view-dismiss}
@keyframes view-push{from{transform:translateX(var(--travel))}to{transform:none}}
@keyframes view-pop{from{transform:translateX(calc(-1 * var(--travel)))}to{transform:none}}
@keyframes view-cover{from{transform:translateY(var(--travel))}to{transform:none}}
@keyframes view-dismiss{from{transform:translateY(calc(-1 * var(--travel)))}to{transform:none}}
@media (prefers-reduced-motion:reduce){[data-view]{animation:none!important;visibility:visible}}

/* ---------- the head: what this is, whose it is, how rare ---------- */
.head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);flex:0 0 auto}
.brand{min-width:0}
.tools{flex:0 0 auto;display:flex;gap:var(--s1)}
.eyebrow{margin:0;font-size:var(--t-micro);letter-spacing:var(--track-micro);text-transform:uppercase;color:#b9b2a2;line-height:var(--lead-label)}
.title{
  margin:var(--s1) 0 0;font-family:var(--serif);font-weight:500;
  font-size:var(--t-display);line-height:var(--lead-display);letter-spacing:var(--track-display);
  text-wrap:balance;overflow-wrap:anywhere;
}
.pills{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s2)}
.pill{
  min-height:26px;padding:0 var(--s2);display:inline-flex;align-items:center;
  border:1px solid var(--line);border-radius:var(--r-pill);
  background:#090c14aa;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  font-size:var(--t-micro);letter-spacing:var(--track-label);text-transform:uppercase;color:#d6d2c9;white-space:nowrap;line-height:1;
}
.pill[data-rarity]{border-color:color-mix(in srgb,var(--rarity) 42%,transparent);color:var(--rarity);box-shadow:inset 0 0 18px color-mix(in srgb,var(--rarity) 9%,transparent)}
.pill[data-rarity="0"]{--rarity:var(--grey)}
.pill[data-rarity="1"]{--rarity:var(--green)}
.pill[data-rarity="2"]{--rarity:var(--blue)}
.pill[data-rarity="3"]{--rarity:var(--violet)}
.pill[data-rarity="4"]{--rarity:var(--gold)}

/* ---------- controls: one height, one shape ---------- */
.icon,.util,.btn,.seg button,.dock button{
  min-height:var(--control);
  border-radius:var(--r-control);
  font-size:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;line-height:1.2;
  transition:color .2s ease,border-color .2s ease,background-color .2s ease,transform .16s var(--ease);
}
.icon,.util{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s1);
  border:1px solid var(--line);background:#ffffff06;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);color:#c9cbd4;
}
.icon{width:var(--control);flex:0 0 auto}
.util{padding:0 var(--s3)}
.icon:active,.util:active,.btn:active,.seg button:active,.dock button:active{transform:scale(.96)}
.icon:hover,.util:hover{color:var(--ink)}
.icon svg,.util svg,.btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.icon:focus-visible,.util:focus-visible,.seg button:focus-visible,.dock button:focus-visible,.btn:focus-visible,.tile:focus-visible,.frame:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.btn{
  padding:0 var(--s4);display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  border:1px solid color-mix(in srgb,var(--gold) 34%,transparent);
  background:linear-gradient(180deg,#d9bd7518,#d9bd7506);color:#f6e6bf;
}
.btn[data-tone="quiet"]{border-color:var(--line);background:#ffffff06;color:#c9cbd4}

/* ---------- the glass panel, and the segmented rows it holds ---------- */
.panel{
  flex:0 0 auto;padding:var(--s2);
  border:1px solid var(--panel-line);border-radius:var(--r-panel);
  background:var(--panel);backdrop-filter:blur(22px) saturate(130%);-webkit-backdrop-filter:blur(22px) saturate(130%);
  box-shadow:0 18px 70px #0007;
  display:grid;gap:var(--s1);
}
.seg{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:var(--s1)}
.seg[data-cols="3"]{grid-auto-flow:row;grid-template-columns:repeat(3,1fr)}
.seg[data-cols="4"]{grid-auto-flow:row;grid-template-columns:repeat(4,1fr)}
.seg button{
  padding:0 var(--s1);
  border:1px solid var(--line);background:#ffffff05;color:#a8abb5;
  font-size:var(--t-micro);
}
.seg button[aria-pressed="true"],.seg button[aria-current]{
  color:#fff4d9;border-color:color-mix(in srgb,var(--gold) 38%,transparent);
  background:linear-gradient(180deg,#d9bd7520,#d9bd750a);box-shadow:inset 0 0 18px #d9bd7512;
}
.seg button:disabled,.btn:disabled{opacity:.34;transform:none;cursor:default}
.pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--s1)}

/* ---------- where a hero stands ----------
   The shot is the hero's frame: the sprite is scaled so its frame lands here. Anything that reaches
   past it - a wide weapon, one that hangs below the feet - keeps its full size and hangs outside,
   over whatever is around it, rather than being cropped or shrunk to fit. */
.frame,.tile{overflow:visible}
/* the sprite is art, not a target: a weapon hanging over a button never swallows the tap */
.shot{position:relative;width:100%;height:var(--shot-h,0px);pointer-events:none}
.shot canvas{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:calc(100% * var(--spill,1));max-width:none;height:auto;
  image-rendering:pixelated;
}
.frame{position:relative;flex:0 0 auto;margin:0}
.frame .shot canvas{filter:drop-shadow(0 22px 34px #0006)}

/* ---------- grids of heroes ---------- */
.grid{flex:0 0 auto;display:grid;gap:var(--s3)}
.grid[data-cols="2"]{grid-template-columns:repeat(2,1fr)}
.grid[data-cols="3"]{grid-template-columns:repeat(3,1fr)}
.tile{
  position:relative;margin:0;padding:var(--s2) var(--s1) var(--s1);display:grid;gap:var(--s1);
  border:1px solid var(--line-soft);border-radius:var(--r-tile);
  background:linear-gradient(180deg,#ffffff09,#ffffff03);
  transition:border-color .2s ease,transform .16s var(--ease);
}
.tile:active{transform:scale(.98)}
.tile[data-rarity]{border-color:color-mix(in srgb,var(--rarity) 24%,transparent)}
.tile[data-rarity="0"]{--rarity:var(--grey)}
.tile[data-rarity="1"]{--rarity:var(--green)}
.tile[data-rarity="2"]{--rarity:var(--blue)}
.tile[data-rarity="3"]{--rarity:var(--violet)}
.tile[data-rarity="4"]{--rarity:var(--gold);box-shadow:inset 0 -30px 40px -30px var(--gold)}
.tile figcaption{font-size:var(--t-micro);letter-spacing:var(--track-caption);text-transform:uppercase;color:#c3c5cd;text-align:center;line-height:var(--lead-label);overflow-wrap:anywhere}

/* ---------- numbers ---------- */
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3)}
.stat{display:grid;gap:var(--s1);min-width:0}
.stat span{font-size:var(--t-micro);letter-spacing:var(--track-micro);text-transform:uppercase;color:var(--muted);line-height:1}
.stat strong{font-size:21px;font-weight:600;line-height:1;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.stat small{font-size:var(--t-micro);letter-spacing:var(--track-caption);color:var(--muted);font-variant-numeric:tabular-nums;line-height:1.2}
.bar{height:3px;border-radius:2px;background:#ffffff14;overflow:hidden}
.bar i{display:block;height:100%;background:linear-gradient(90deg,color-mix(in srgb,var(--gold) 60%,transparent),var(--gold));transform-origin:left center;transform:scaleX(var(--fill,0));transition:transform .9s var(--ease)}
.facts{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s2)}
.fact{display:grid;gap:4px;min-width:0}
.fact span{font-size:var(--t-micro);letter-spacing:var(--track-micro);text-transform:uppercase;color:var(--muted);line-height:1}
.fact b{font-weight:500;font-size:var(--t-body);line-height:var(--lead-label);overflow-wrap:anywhere}

/* ---------- states, hints, toast ---------- */
.state{
  padding:var(--s5);display:grid;gap:var(--s2);justify-items:start;
  border:1px solid var(--line);border-radius:var(--r-panel);background:var(--panel);
  backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);
}
.state p{margin:0}
.state h2{margin:0;font-family:var(--serif);font-weight:500;font-size:22px;line-height:1.15;letter-spacing:-.01em}
.state small{color:var(--muted);font-size:var(--t-body);line-height:var(--lead-body);max-width:46ch}
.state .btn{margin-top:var(--s1)}
.hint{flex:0 0 auto;margin:0;text-align:center;font-size:var(--t-micro);letter-spacing:var(--track-micro);text-transform:uppercase;color:#7f8390}
.toast{
  position:fixed;z-index:40;left:50%;transform:translateX(-50%);
  bottom:calc(env(safe-area-inset-bottom) + 86px);
  max-width:min(92vw,420px);padding:var(--s2) var(--s3);
  display:flex;align-items:center;gap:var(--s3);
  border:1px solid var(--panel-line);border-radius:var(--r-control);background:var(--panel);
  backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);box-shadow:0 14px 50px #0008;
  font-size:var(--t-body);color:#dcdde3;
}

/* ---------- the dock ---------- */
.dock{
  position:fixed;z-index:20;left:50%;transform:translateX(-50%);
  bottom:calc(env(safe-area-inset-bottom) + 12px);
  padding:var(--s1);display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:var(--s1);
  width:min(420px,calc(100vw - 28px));
  border:1px solid var(--panel-line);border-radius:var(--r-panel);background:var(--panel);
  backdrop-filter:blur(22px) saturate(130%);-webkit-backdrop-filter:blur(22px) saturate(130%);
  box-shadow:0 16px 50px #0008;
}
.dock button{
  border:0;background:transparent;color:#9497a3;
  display:flex;align-items:center;justify-content:center;gap:var(--s1);
  font-size:var(--t-micro);
}
.dock button svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.dock button[aria-current="page"]{color:#fff4d9;background:linear-gradient(180deg,#d9bd751f,#d9bd7508)}

@media (min-width:760px){
  #view{gap:var(--s4);padding-inline:34px}
  .grid{gap:var(--s4)}
  .panel{padding:var(--s3);gap:var(--s2)}
}
