/* flashback — the shared system. Loaded by every page before its own stylesheet.

   The whole site is one idea: flashback is a machine that winds chain history
   back and plays it, so the site is that machine's own paperwork. Three
   surfaces, and a rule about which one a thing is allowed to live on.

     PAPER   concrete grey. Structure, type, rules, labels, argument.
             Nothing measured is ever drawn straight onto it.
     PLATE   the ink-blue ground. Every piece of data the chain gave us —
             the tape band, a cook tile, the console once it is armed, the
             replay stage itself — is a plate laid on the paper.
     SIGNAL  acid and red. Only ever on a plate, never on paper.

   The plate palette is the old stage palette, values shifted off pure black
   onto a deep ultramarine, so the replay page and the result card keep working
   off the same token names they always used. */

/* PP Frama — the display face. One weight, drawn geometric, set enormous and
   tight. Every headline on the site is this and nothing else is. */
@font-face{
  font-family:'Frama';font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/PPFrama-Regular.woff) format('woff');
}
/* GT America Mono — everything that is a fact. Labels, addresses, prices,
   counters, buttons. If it is measured or copied it is set in this. */
@font-face{
  font-family:'GT America Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/GTAmericaMono-Regular.woff2) format('woff2'),
      url(/fonts/GTAmericaMono-Regular.woff) format('woff');
}

:root{
  /* ---- PLATE (also the stage) ----
     These names are load-bearing: scorecard.js ships its own stylesheet and
     chart.js mirrors these hexes into canvas, so the names stay exactly what
     they were and only the values moved.

     2026-09-14: the plate is light. It was black (and before that
     ultramarine-black) — a monitor. The owner wanted no black anywhere, so the
     plate is now a hair off the paper's white, ink is dark, and the signal is
     the logo's blue for up and the paper red for down. Every name is what it
     was; chart.js, scorecard.js and clip.js mirror these values and moved with
     them. A plate is still a plate: the pixel grid marks it, and the paper it
     sits on is pure white. */
  --bg:#F7F7F9;
  --bg-2:#EDEDF2;
  --bg-3:#E2E2E9;
  --line:#D6D6DE;
  --line-2:#BFBFCB;

  --ink:#0B0B0C;
  --dim:#4F4F5B;
  --faint:#8A8A96;

  /* The flood: the one saturated colour in the system, and the colour the
     whole page turns when a replay opens. It is the logo's ring. */
  --flood:#0D04B8;
  --flood-2:#09037F;

  /* ---- PAPER ----
     White, since 2026-09-14 (it was warm concrete). */
  --pg:#FFFFFF;
  --pg-2:#F4F4F7;
  --pg-3:#E9E9EF;
  --pi:#0B0B0C;
  --pi-2:#45454F;
  --pi-3:#7A7A86;
  --rule:rgba(11,11,12,.22);
  --rule-2:rgba(11,11,12,.1);
  /* A loss, on paper: the red taken down until it holds against white. */
  --pg-down:#C41E10;

  /* ---- SIGNAL ----
     Up is the brand colour, as it always was — it is just blue now. Red is
     the only other hue in the system and it means exactly one thing. */
  --up:#0D04B8;
  --up-soft:#DCD9FF;
  --down:#C41E10;
  --down-soft:#F6D4CF;
  --accent:#0D04B8;
  --accent-ink:#FFFFFF;
  --basis:#7A7A96;          /* cost basis: deliberately neutral, never a hue */
  --accent-rgb:13,4,184;
  --up-rgb:13,4,184;
  --down-rgb:196,30,16;
  --ink-rgb:11,11,12;
  --flood-rgb:13,4,184;
  --pi-rgb:11,11,12;

  /* Bloom, on plates only, and only while something is playing. Held far
     down: on a light plate a glow is a smudge, so this is the memory of one. */
  --glow-up:0 0 14px rgba(var(--up-rgb),.16),0 0 40px rgba(var(--up-rgb),.07);
  --glow-down:0 0 14px rgba(var(--down-rgb),.16),0 0 40px rgba(var(--down-rgb),.07);
  --glow-ink:0 0 12px rgba(var(--ink-rgb),.1);

  --font-display:'Frama','Helvetica Neue',Helvetica,Arial,sans-serif;
  --font-mono:'GT America Mono',ui-monospace,"SF Mono",Menlo,Consolas,monospace;

  /* ---- the sheet ----
     Paper is ruled, not gridded: one hairline every 88px across the column,
     the way a register is ruled. It is a texture and it is held far below
     anything the page actually draws. */
  --sheet-rule:rgba(11,11,12,.055);
  --sheet:repeating-linear-gradient(90deg,transparent 0 87px,var(--sheet-rule) 87px 88px);
  /* The plate keeps the old pixel grid — that is the monitor, and it should
     still look like a monitor. */
  --grid-a:.07;
  --grid-px:26px;
  --grid-bg:
    linear-gradient(rgba(var(--ink-rgb),var(--grid-a)) 1px,transparent 1px),
    linear-gradient(90deg,rgba(var(--ink-rgb),var(--grid-a)) 1px,transparent 1px);
  --scan-bg:repeating-linear-gradient(180deg,transparent 0 2px,rgba(11,11,12,.03) 2px 3px);

  /* Registration marks. Four corner crosses on any box, the way a plate is
     marked for the press. Carried by a pseudo-element with
     background:var(--reg-bg);background-repeat:no-repeat. */
  --reg-len:9px;
  --reg-th:1px;
  --reg-c:currentColor;
  --reg-bg:
    linear-gradient(var(--reg-c),var(--reg-c)) left top/var(--reg-len) var(--reg-th),
    linear-gradient(var(--reg-c),var(--reg-c)) left top/var(--reg-th) var(--reg-len),
    linear-gradient(var(--reg-c),var(--reg-c)) right top/var(--reg-len) var(--reg-th),
    linear-gradient(var(--reg-c),var(--reg-c)) right top/var(--reg-th) var(--reg-len),
    linear-gradient(var(--reg-c),var(--reg-c)) left bottom/var(--reg-len) var(--reg-th),
    linear-gradient(var(--reg-c),var(--reg-c)) left bottom/var(--reg-th) var(--reg-len),
    linear-gradient(var(--reg-c),var(--reg-c)) right bottom/var(--reg-len) var(--reg-th),
    linear-gradient(var(--reg-c),var(--reg-c)) right bottom/var(--reg-th) var(--reg-len);

  /* Viewfinder brackets. Four L-corners on one box, eight strips, so any
     positioned pseudo-element can carry them with background:var(--vf-bg).
     Thinner than they were: this system draws with hairlines, and a 3px
     bracket next to a 1px rule reads as a different drawing. */
  --vf-len:20px;
  --vf-th:1px;
  --vf-c:var(--accent);
  --vf-bg:
    linear-gradient(var(--vf-c),var(--vf-c)) left top/var(--vf-len) var(--vf-th),
    linear-gradient(var(--vf-c),var(--vf-c)) left top/var(--vf-th) var(--vf-len),
    linear-gradient(var(--vf-c),var(--vf-c)) right top/var(--vf-len) var(--vf-th),
    linear-gradient(var(--vf-c),var(--vf-c)) right top/var(--vf-th) var(--vf-len),
    linear-gradient(var(--vf-c),var(--vf-c)) left bottom/var(--vf-len) var(--vf-th),
    linear-gradient(var(--vf-c),var(--vf-c)) left bottom/var(--vf-th) var(--vf-len),
    linear-gradient(var(--vf-c),var(--vf-c)) right bottom/var(--vf-len) var(--vf-th),
    linear-gradient(var(--vf-c),var(--vf-c)) right bottom/var(--vf-th) var(--vf-len);

  /* Nothing in this system is rounded. A plate has corners. */
  --r:0px;
  --r-sm:0px;
  --ease:cubic-bezier(.2,.7,.3,1);
  --snap:cubic-bezier(.16,1,.3,1);
  --slam:cubic-bezier(.34,1.56,.64,1);
  --gut:clamp(16px,3.2vw,44px);
}

*{box-sizing:border-box}
/* The UA rule for [hidden] loses to any author selector, and this system
   styles almost everything by class — a .veil-card{display:flex} was enough to
   put a hidden node back on screen. One !important here is cheaper than
   remembering to write .thing[hidden] beside every display we set. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--font-mono);font-size:13px;line-height:1.45;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
/* The landing page is paper. Everything on it that carries data says so for
   itself by taking the plate tokens back. */
body.paper{background:var(--pg);color:var(--pi)}

button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
a{color:inherit;text-decoration:none}
h1,h2,h3,p{margin:0}

/* ---- type ---- */
/* Display. Set once, sized by the block that uses it. Frama has a wide
   sidebearing at large sizes, so display type is always tracked in. */
.dsp{font-family:var(--font-display);font-weight:400;letter-spacing:-.035em;line-height:.9}
/* The label voice: small, spaced, upper, and the only thing allowed to be
   quiet. Every caption on the site is one of these. */
.lbl{
  font-family:var(--font-mono);font-size:10px;line-height:1.2;
  letter-spacing:.18em;text-transform:uppercase;
}
/* The display face, applied to markup that asks for it by name. It kept the
   class it had when the face was a pixel font — every page and both canvas
   renderers reach for `.px`, and renaming it would buy nothing. */
.px{font-family:var(--font-display);font-weight:400;letter-spacing:-.02em}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---- primitives ----
   A field is a ruled line, not a box: the paper already has boxes on it and a
   second border inside one is noise. */
.field{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--rule);
  color:inherit;padding:10px 0 9px;font:inherit;font-size:15px;letter-spacing:-.01em;
  outline:none;border-radius:0;
  transition:border-color .18s var(--ease);
}
.field::placeholder{color:var(--pi-3)}
.field:focus{border-color:var(--flood)}
.field.bad{border-color:var(--down)}

/* A button is a solid block of ink with mono set into it. Hover flips it. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:15px 22px;border:1px solid var(--pi);background:var(--pi);color:var(--pg);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease);
}
.btn:hover{background:transparent;color:var(--pi)}
.btn-primary{background:var(--flood);border-color:var(--flood);color:#fff}
.btn-primary:hover{background:var(--pi);border-color:var(--pi);color:var(--pg)}
.btn:disabled{cursor:default;background:transparent;color:var(--pi-3);border-color:var(--rule)}
.btn:disabled:hover{background:transparent;color:var(--pi-3);border-color:var(--rule)}

.pos{color:var(--up)}
.neg{color:var(--down)}
/* On paper the signal colours are unreadable, so a gain there is ink-blue and
   a loss is the same red darkened until it holds against concrete. */
.paper .pos{color:var(--flood)}
.paper .neg{color:var(--pg-down)}

/* The monitor's ground, wherever a plate needs it. */
.surface{background-color:var(--bg);background-image:var(--grid-bg);background-size:var(--grid-px) var(--grid-px)}

/* one scrollbar treatment everywhere */
*::-webkit-scrollbar{width:8px;height:8px}
*::-webkit-scrollbar-thumb{background:var(--rule);border-radius:0}
*::-webkit-scrollbar-thumb:hover{background:var(--pi-3)}
*::-webkit-scrollbar-track{background:transparent}
body:not(.paper)::-webkit-scrollbar-thumb{background:var(--line-2)}

/* ---- motion gate ----
   Every entrance on the site is a GSAP tween off an element that starts at
   opacity 0 in CSS, so a blocked or failed script cannot leave the page blank:
   motion.js clears .gate the moment it has run, and this rule stops applying. */
html.gated .gate{opacity:0}
html.gated .gate-y{opacity:0;transform:translateY(18px)}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
  html.gated .gate,html.gated .gate-y{opacity:1;transform:none}
}
