/* Tenshin Arts — shared styles for auth + admin pages.
   Same tokens as site.css: the SLATE palette (cool neutral + indigo), Fraunces +
   Figtree. Keep these two blocks identical — site.css is the source of truth and
   carries the rationale and the measured contrast. */
:root{
  --paper:#F6F7F9; --paper-2:#ECEFF3; --paper-3:#F1F4F8;
  --ink:#171A21; --ink-soft:#5D6472;
  --accent:#5567E0; --support:#2A93A0; --warn:#B4741A;   /* bright pair: display only */
  /* AA-contrast siblings (match site.css): text-on-colour + small text on paper */
  --accent-deep:#3A49B8; --support-deep:#166B75; --ember:#B23B1F;
  /* the ON-DARK sibling — site.css had it, this file did not, so every
     `var(--accent-lift)` here silently resolved to nothing and the colour fell
     back to inherit. Same class of bug as --ink-900. The footer needs it. */
  --accent-lift:#93A0F5;
  --line:rgba(23,26,33,.14);
  --ink-900:#12141A;
  --display:"Fraunces",Georgia,serif;
  --body:"Figtree",system-ui,sans-serif;
}
*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:1.0625rem;line-height:1.6;-webkit-font-smoothing:antialiased;
  /* THE UNIT SILHOUETTE — rounded top, near-square base, so a surface reads as a
     thing STANDING on the floor rather than a pill floating on it. Lifted off
     `.cab` in site.css, same value.
     ⚠ Deliberately NOT in :root — that block above must stay byte-identical to
     site.css's, which is why site.css puts it here too. Keep them in step. */
  --r-unit:14px 14px 4px 4px}

/* ── THE UNIT, on the auth/app pages (2026-07-26) ────────────────────────────
   The site-wide vocabulary pass reached `/` and `/games` only, because those load
   site.css and everything served through base.html loads this file. So the two
   marketing pages spoke a machine language and the moment you signed in you were
   back on 20px pillows. Same four devices, no new ones invented:

     the unit silhouette  14px 14px 4px 4px   from `.cab`
     the light bar        3px inset, .55      from `.cab-top::after`
     the coin slot        22x3 solid          from `.cab-coin .slot`
     the pedestal         dark kick plate     from `.cab-base`

   ★ THE RULE THAT KEEPS IT STRUCTURAL: a UNIT is a surface you can act on or read
   a standing from. PROSE NEVER GETS A LIGHT BAR. That is why `.card` `.panel`
   `.facts` `.tk` and `.zone-danger` are units and `.note`, `.note-game`, `.tenet`
   and `.legal .tldr` are not — the last one is the tell, since it is a boxed
   summary that looks exactly like a unit and is something you only read.

   ⚠ Two treatments, not one: the light bar is LIT (translucent, .55), the coin
   slot is MILLED METAL (solid). Copying .55 onto the slot makes it disappear.
   Decorative only — every `::before` is empty and no text contrast moves. */
.card,.panel,.facts,.tk,.zone-danger{border-radius:var(--r-unit);position:relative;overflow:hidden}
.card::before,.panel::before,.facts::before,.tk::before,.zone-danger::before{
  content:"";position:absolute;left:1.1rem;right:1.1rem;top:0;height:3px;
  border-radius:0 0 2px 2px;background:var(--acc,var(--accent));opacity:.55;
  pointer-events:none}
/* a destructive zone wears its OWN colour, the way a game's cabinet wears its
   own accent — an ember box with an indigo lamp on it is two claims at once */
.zone-danger{--acc:#B23B1F}
a{color:var(--accent-deep)}
::selection{background:var(--accent);color:#fff}
:focus-visible{outline:3px solid var(--support);outline-offset:2px}

/* header */
.site-head{background:var(--paper);border-bottom:1px solid var(--line)}
.site-head .bar{max-width:1140px;margin:0 auto;padding:0 clamp(1.25rem,5vw,3rem);
  height:72px;display:flex;align-items:center;justify-content:space-between}
.brand{text-decoration:none;font-family:var(--display);font-weight:600;font-size:1.35rem;color:var(--ink)}
.brand .glyph{display:none}   /* logo retired — wordmark only */
.brand .txt,.brand .rom{font-family:var(--display);font-weight:600;font-size:1.35rem;color:var(--ink)}
/* ⚠ TAP TARGETS — WCAG 2.5.8 wants 24x24 (2026-07-26). An inline <a> with no padding has a hit
   box the size of its GLYPHS, and `padding:0` on .logout made that literal: a ~18px sign-out
   button. The type size is UNCHANGED here; only the hit box grows. The 0.3rem of horizontal
   padding is taken back out of the flex `gap` (1.6 -> 1.3rem) so the spacing between items is
   identical to the pixel, and the bar is a fixed 72px centred row so the vertical growth is
   absorbed by the bar's own padding. Do NOT put `padding:0` back on a chrome control -- there is
   an assertion in `python app.py check` that will go red. */
.site-head nav{display:flex;gap:1.3rem;align-items:center}
.site-head nav a,.logout{display:inline-flex;align-items:center;min-height:24px;padding:.3rem .15rem}
.site-head nav a{font-family:var(--body);font-weight:500;font-size:.95rem;text-decoration:none;color:var(--ink-soft)}
.site-head nav a:hover{color:var(--ink)}
.logout{border:0;background:none;font-family:var(--body);font-weight:500;font-size:.95rem;color:var(--ink-soft);cursor:pointer}
.logout:hover{color:var(--accent-deep)}
@media (max-width:640px){.site-head nav a.hide-sm{display:none}}

/* centered auth card */
.auth-wrap{min-height:calc(100vh - 72px);display:grid;place-items:center;padding:2.5rem 1.25rem}
.card{width:100%;max-width:430px;background:var(--paper-2);padding:clamp(1.75rem,4vw,2.75rem)}
.card h1{font-family:var(--display);font-weight:600;color:var(--ink);font-size:2rem;margin:0 0 .35rem;letter-spacing:-.01em}
.card .sub{color:var(--ink-soft);margin:0 0 1.7rem;font-size:.98rem}
label{display:block;font-family:var(--body);font-weight:600;font-size:.78rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);margin:1rem 0 .45rem}
input{width:100%;font-family:var(--body);font-size:1rem;padding:.75rem .9rem;background:var(--paper);
  border:1.5px solid var(--line);border-radius:12px;color:var(--ink)}
input:focus{outline:3px solid var(--support);outline-offset:1px;border-color:transparent}
.btn{width:100%;margin-top:1.7rem;font-family:var(--body);font-weight:600;font-size:1rem;
  background:var(--accent-deep);color:#fff;border:0;border-radius:12px;padding:.9rem 1rem;cursor:pointer;transition:background .2s}
.btn:hover{background:#2E3A94}
.alt{margin:1.4rem 0 0;font-size:.95rem;color:var(--ink-soft)}
/* the error box is ember because it is an ERROR, not because it was the old
   brand hue — it must not follow the accent when the palette changes */
.err{background:rgba(178,59,31,.10);border:1px solid rgba(178,59,31,.38);color:#96301A;
  border-radius:12px;padding:.7rem .9rem;font-size:.92rem;margin:0 0 .4rem}
.note{margin:1.6rem 0 0;padding-top:1.4rem;border-top:1px solid var(--line);font-size:.85rem;line-height:1.55;color:var(--ink-soft)}
.note p{margin:0 0 .55rem}
.note p:last-child{margin-bottom:0}
.note strong{color:var(--ink);font-weight:700}
.note-game{border:0;padding:1rem 1.1rem;margin:1.1rem 0 0;background:var(--paper-3);border-left:3px solid var(--accent);border-radius:0 12px 12px 0}
.note-game p{color:var(--ink)}
.note-game em{font-style:italic}
.code-box{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:1.45rem;letter-spacing:.1em;
  text-align:center;background:var(--paper);border:2px dashed var(--accent);border-radius:12px;
  padding:1.1rem .6rem;margin:1.3rem 0;color:var(--ink);user-select:all;word-break:break-all}

/* recovery-code screen: copy / download / confirm */
.code-actions{display:flex;gap:.6rem;margin:-.5rem 0 1rem}
.btn-sm{font-family:var(--body);font-weight:600;font-size:.85rem;padding:.5rem 1.1rem;border-radius:12px;
  background:var(--paper);border:1.5px solid var(--line);color:var(--ink);cursor:pointer}
.btn-sm:hover{border-color:var(--ink)}
.checkline{display:flex;align-items:center;gap:.55rem;font-size:.95rem;color:var(--ink);
  text-transform:none;letter-spacing:0;margin:1rem 0 1.3rem;cursor:pointer}
.checkline input{width:auto;margin:0}
.btn.is-disabled{opacity:.45;pointer-events:none;cursor:not-allowed}

/* signup: recovery-method choice */
.recovery-choice{border:1px solid var(--line);border-radius:12px;padding:.9rem 1.1rem;margin-top:1.2rem}
.recovery-choice legend{font-family:var(--body);font-weight:600;font-size:.72rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-soft);padding:0 .4rem}
.recovery-choice label{display:flex;align-items:flex-start;gap:.55rem;font-size:.95rem;color:var(--ink);
  text-transform:none;letter-spacing:0;margin:.5rem 0}
.recovery-choice input[type=radio]{width:auto;margin:.25rem 0 0}
.recovery-choice .rec{color:var(--ink-soft)}
.recovery-choice .rphr{display:block;margin:.6rem 0 .35rem}
.hint{font-size:.85rem;color:var(--ink-soft);margin:.4rem 0 0;line-height:1.5}
.agree{font-size:.82rem;color:var(--ink-soft);text-align:center;margin:.9rem 0 0;line-height:1.5}

/* danger zone (delete account) */
.danger{margin-top:1.8rem;padding-top:1.5rem;border-top:1px solid var(--line)}
.danger h2{font-family:var(--display);font-weight:600;font-size:1.2rem;color:#b23b1f;margin:0 0 .4rem}
.danger p{font-size:.92rem;color:var(--ink-soft);margin:0 0 .6rem}
.btn-danger{background:#b23b1f}
.btn-danger:hover{background:#9c3016}

/* contact form */
textarea{width:100%;font-family:var(--body);font-size:1rem;padding:.75rem .9rem;background:var(--paper);
  border:1.5px solid var(--line);border-radius:12px;color:var(--ink);resize:vertical;min-height:120px}
textarea:focus{outline:3px solid var(--support);outline-offset:1px;border-color:transparent}
label .opt{text-transform:none;font-weight:400;letter-spacing:0;color:var(--ink-soft)}

/* admin: support tickets */
.tk-list{display:grid;gap:1rem;max-width:720px}
.tk{background:var(--paper-2);border:1px solid var(--line);padding:1.2rem 1.4rem}
.tk-head{display:flex;justify-content:space-between;gap:1rem;margin-bottom:.6rem;font-size:.85rem}
.tk-who{font-family:var(--display);font-weight:600;color:var(--ink)}
.tk-when{color:var(--ink-soft)}
.tk-msg{margin:0 0 .6rem;color:var(--ink);white-space:pre-wrap;line-height:1.6}
.tk-contact{margin:0 0 .9rem;font-size:.92rem;color:var(--ember)}
.btn-resolve{font-family:var(--body);font-weight:600;font-size:.9rem;padding:.55rem 1.2rem;border-radius:12px;
  background:#b23b1f;color:#fff;border:0;cursor:pointer}
.btn-resolve:hover{background:#9c3016}

/* legal / long-form pages */
.legal-wrap{max-width:760px;margin:0 auto;padding:clamp(2.5rem,6vw,4.5rem) clamp(1.25rem,5vw,3rem)}
.legal h1{font-family:var(--display);font-weight:600;color:var(--ink);font-size:clamp(2rem,4.5vw,2.8rem);margin:0 0 .3rem;letter-spacing:-.01em}
.legal .updated{color:var(--ink-soft);font-size:.9rem;margin:0 0 1.8rem}
.legal h2{font-family:var(--display);font-weight:600;color:var(--ink);font-size:1.4rem;margin:2.2rem 0 .6rem}
.legal p,.legal li{color:var(--ink);font-size:1.02rem;line-height:1.7}
.legal ul{padding-left:1.3rem;margin:.5rem 0}
.legal li{margin:.35rem 0}
.legal a{color:var(--accent-deep)}
.legal .tldr{background:var(--paper-2);border-radius:14px;padding:1.2rem 1.5rem;margin:1.3rem 0 2rem}
.legal .tldr ul{margin:.4rem 0 0}

/* ── footer ──────────────────────────────────────────────────────────────────
   The app pages used to carry `.mini-foot`, a pale two-item strip; the marketing
   pages carried a different footer entirely. There is one footer now — this block
   mirrors site.css's, and only the `.shell` width differs (app pages are 1140,
   marketing runs to --stage). Keep the two in step when either changes.
   Measured on --ink (#171A21): --paper 16.24 · --accent-lift 7.12 · muted 7.66.
   NOTE this defines `.shell` for app.css; it exists nowhere else in these pages. */
.shell{width:100%;max-width:1140px;margin:0 auto;
  padding-left:clamp(1.25rem,5vw,3rem);padding-right:clamp(1.25rem,5vw,3rem)}
footer{background:var(--ink);color:var(--paper);padding:clamp(2.6rem,5vw,3.8rem) 0 1.9rem;
  --foot-muted:color-mix(in srgb,var(--paper) 66%,var(--ink));
  --foot-rule:color-mix(in srgb,var(--paper) 18%,var(--ink))}
/* THE PEDESTAL — `.cab-base`'s kick plate, so an app page ends the way the hall's
   machines do. Identical to site.css's rule; keep the two in step. */
footer::after{content:"";display:block;height:52px;margin:1.9rem 0 -1.9rem;
  background:var(--ink-900);border-top:1px solid var(--foot-rule);
  box-shadow:0 14px 0 -11px rgba(255,255,255,.06) inset}
.foot{display:grid;grid-template-columns:minmax(15rem,1fr) minmax(0,2.1fr) minmax(9rem,.7fr);
  gap:clamp(1.8rem,3.5vw,3.5rem);align-items:start}
.foot .brand{color:var(--paper);font-size:1.45rem}
.foot-tag{font-family:var(--display);font-style:italic;font-size:1.05rem;color:var(--accent-lift);margin:.4rem 0 0}
.foot-where{margin:1rem 0 0;font-size:.9rem;color:var(--foot-muted)}
.foot h2{font-family:var(--body);font-weight:700;font-size:.72rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--paper);margin:0 0 1rem}
.foot ul{list-style:none;margin:0;padding:0}
/* 2.5.8 again: these are nav links in a list, not links in a sentence, so the inline exception
   does not cover them. The row is 24px tall now and the 3px it gained is taken back out of the
   margin (.5 -> .3rem), so the column's pitch is within half a pixel of what it was. */
.foot li{margin:0 0 .3rem;font-size:.92rem;line-height:1.45;min-height:24px;display:flex;align-items:center}
.foot li a{display:flex;align-items:center;min-height:24px}
.foot-games{columns:3;column-gap:clamp(1rem,2.2vw,2.4rem)}
.foot-games li{break-inside:avoid}
.foot a:not(.brand){color:var(--accent-lift);text-decoration:none}
.foot a:not(.brand):hover{text-decoration:underline}
.foot .soon{color:var(--foot-muted)}
.foot .soon i{font-style:normal;font-size:.64rem;letter-spacing:.1em;text-transform:uppercase;
  white-space:nowrap;margin-left:.4rem}
.foot-base{margin-top:clamp(2rem,4vw,3rem);padding-top:1.4rem;border-top:1px solid var(--foot-rule)}
.foot-base p{margin:0;font-size:.85rem;color:var(--foot-muted)}
.foot-base a{color:var(--accent-lift);text-decoration:none}
.foot-base a:hover{text-decoration:underline}
.foot .tm{display:block;margin-top:.7rem;font-size:.78rem}
footer :focus-visible{outline:3px solid var(--accent-lift);outline-offset:3px;border-radius:2px}
@media (max-width:1080px){
  .foot{grid-template-columns:1fr minmax(9rem,.55fr)}
  .foot-brandcol{grid-column:1/-1}
  .foot-games{columns:2}
}
@media (max-width:560px){
  .foot{grid-template-columns:1fr;gap:1.9rem}
  .foot-games{columns:1}
}

/* launcher */
.play-wrap{max-width:1140px;margin:0 auto;padding:clamp(2.5rem,6vw,4.5rem) clamp(1.25rem,5vw,3rem)}
.play-head{font-family:var(--display);color:var(--ink);font-weight:600;font-size:clamp(2rem,4.2vw,3rem);margin:0 0 .5rem;letter-spacing:-.01em}
.play-sub{color:var(--ink-soft);margin:0 0 2.6rem;max-width:56ch}

/* ── the standing pages: contact · account ──────────────────────────────────
   These were both wearing `.auth-wrap` + `.card` — the centred 430px box built
   for a login form. It is the right shape for "type two fields and leave" and
   the wrong one for a page you read: Contact had three explanatory notes stacked
   under a form in a column narrower than its own prose, and Account had four
   unrelated jobs (who you are · recovery · admin · delete forever) in one card
   with the destructive one at the bottom of the same scroll.

   A page, then: a header that says what this is, and zones that are visibly
   separate things. Same tokens, no new dependencies. */
.page{max-width:1000px;margin:0 auto;padding:clamp(2rem,5vw,3.5rem) clamp(1.25rem,5vw,3rem) 4rem}
.page-head{max-width:56ch;margin:0 0 clamp(1.8rem,4vw,2.6rem)}
/* THE COIN SLOT on the section label — `.cab-coin .slot`, same 22x3. `currentColor` so a
   recoloured eyebrow takes the slot with it without a second rule.
   ⚠ This became a flex box to hold the slot, so `text-align:center` no longer centres it —
   anything centring an eyebrow needs `justify-content:center` explicitly. */
.page-head .eyebrow{display:flex;align-items:center;gap:.7rem;font-family:var(--body);
  font-weight:600;font-size:.72rem;
  letter-spacing:.16em;text-transform:uppercase;color:var(--support-deep);margin:0 0 .7rem}
.page-head .eyebrow::before{content:"";width:22px;height:3px;border-radius:2px;
  background:currentColor;flex:none}
.page-head h1{font-family:var(--display);font-weight:600;font-size:clamp(2.1rem,5vw,3rem);
  line-height:1.05;letter-spacing:-.015em;margin:0}
.page-head .lede{color:var(--ink-soft);font-size:1.06rem;margin:.9rem 0 0;line-height:1.6}

.cols{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(1.5rem,4vw,3rem);align-items:start}
@media (max-width:820px){.cols{grid-template-columns:1fr}}

.panel{background:var(--paper-2);border:1px solid var(--line);
  padding:clamp(1.3rem,3vw,1.9rem)}
.panel + .panel{margin-top:1rem}
.panel h2{font-family:var(--display);font-weight:600;font-size:1.3rem;letter-spacing:-.01em;
  margin:0 0 .5rem}
.panel p{margin:0 0 .8rem;font-size:.98rem;line-height:1.6}
.panel p:last-child{margin-bottom:0}
.panel .btn{margin-top:1.2rem}
/* the form panel sits on paper so the fields (which are paper) still read as fields */
.panel.form-panel{background:var(--paper)}
.panel.form-panel input,.panel.form-panel textarea{background:var(--paper-2)}

/* a claim the site actually keeps, set like a claim rather than a footnote */
.tenet{border-left:3px solid var(--accent);padding:.1rem 0 .1rem 1.1rem;margin:0 0 1.4rem}
.tenet strong{display:block;font-family:var(--display);font-weight:600;font-size:1.15rem;
  letter-spacing:-.01em;margin:0 0 .3rem;color:var(--ink)}
.tenet span{color:var(--ink-soft);font-size:.96rem;line-height:1.6;display:block}

/* account: identity read-outs are not form fields — they were disabled inputs,
   which look editable, tab like controls, and are read out as such */
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));
  gap:1px;background:var(--line);border:1px solid var(--line);overflow:hidden}
.facts div{background:var(--paper-2);padding:1rem 1.2rem}
.facts dt{font-family:var(--body);font-weight:600;font-size:.7rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-soft);margin:0 0 .3rem}
.facts dd{margin:0;font-family:var(--display);font-weight:600;font-size:1.3rem;
  letter-spacing:-.01em;color:var(--ink);word-break:break-word}

/* the destructive zone is the one thing that must not look like its neighbours */
.zone-danger{margin-top:2.5rem;border:1px solid rgba(178,59,31,.35);
  background:rgba(178,59,31,.045);padding:clamp(1.3rem,3vw,1.9rem)}
.zone-danger h2{font-family:var(--display);font-weight:600;font-size:1.3rem;color:#96301A;
  margin:0 0 .4rem}
.zone-danger p{font-size:.96rem;color:var(--ink-soft);margin:0 0 1rem;max-width:60ch}
.zone-danger .btn{background:#B23B1F;margin-top:1.2rem}
.zone-danger .btn:hover{background:#96301A}
