/* ---------------------------------------------------------------
   IMPAKT — the design system.

   Built on one idea: a system that argues with itself.

   Two voices. THE HOUSE is order — the ledger, the caps, the
   provably-fair maths, the console chrome. Near-black, mono
   numerals, tiny tracked-out labels, hard rules, nothing loud.
   THE CROWD is what happens when a room piles into somebody's
   bankroll. Saturated, oversized, skewed, overprinted.

   The rule: the house holds everything, and the crowd breaks it
   at exactly the moments money moves. Colour is not decoration
   here. If something is loud, it is loud because something
   happened.
   --------------------------------------------------------------- */

/*
 * The canvas, before anything else has loaded.
 *
 * The page background was set on `.season`, a class on the body, which cannot
 * apply until that stylesheet has arrived and parsed. Until then the browser
 * paints its own canvas, and its own canvas is white. That is the flash between
 * every navigation: not the page rendering slowly, the page rendering correctly
 * on top of a white sheet the browser had already put down.
 *
 * Setting it on `html` fixes the element itself; `color-scheme` fixes
 * everything the browser draws around it, the canvas during navigation,
 * scrollbars, and form controls, which would otherwise all default to light.
 */
html {
  background: #000;
  color-scheme: dark;
}

:root {
  /* ---- the house: order ----
     Near-black and off-white, taken from the identity. Almost everything on
     the platform is one of these two; colour is the exception, not the field. */
  --void:      #0a0a0a;
  --ground:    #101010;   /* the page */
  --card:      #171717;
  --raised:    #1f1f1f;
  --line:      rgba(250, 250, 250, .09);
  --line-hard: rgba(250, 250, 250, .2);
  --glass:     rgba(250, 250, 250, .045);

  --ink:       #fafafa;
  --paper:     #fcfbfb;   /* the light surface, for inverted chrome */
  --muted:     #8c8c8c;
  --faint:     #4f4f4f;

  /* ---- the crowd: three flats ----
     Not a spectrum and not a gradient set. Three saturated primaries used
     flat, which is what gives the identity its poster quality: they do not
     blend into each other or into the black, they interrupt it. */
  --red:    #d4291e;
  /*
   * Green, and it is called green.
   *
   * This was --yellow: #f4c63c, and live.css overrode it to #3fdc6f for the
   * watch page because "green is the affirmative colour in this design". Every
   * other stylesheet had already gone green on its own: the door, the overlay,
   * the store, the profile, the phone notice, season. Gold survived in this
   * file and in two decorative washes, so the definition was the last thing
   * still claiming it.
   *
   * That gap is not cosmetic. The Twitch panel generates its palette from this
   * file, so it shipped gold while every page it sits beside showed green, and
   * a token named for a colour it does not hold is how the next one goes wrong.
   */
  --green:  #3fdc6f;
  --blue:   #0000be;

  --red-dim:    rgba(212, 41, 30, .16);
  --green-dim:  rgba(63, 220, 111, .16);
  --blue-dim:   rgba(0, 0, 190, .3);
  --green-edge: rgba(63, 220, 111, .5);

  /* Roles, so a page never reaches for a colour by its name. */
  --signal:    var(--green);    /* coins, wins, the mark */
  --signal-hi: #6ef39a;
  --surge:     var(--red);      /* heat, loss, live */
  --volt:      var(--blue);     /* crowdplay, the house side */
  --toxic:     #3fbf6a;         /* settled, paid, confirmed */
  --ember:     var(--red);
  --deep:      var(--blue);
  --live:      var(--red);

  --signal-dim: var(--green-dim);
  --signal-edge: var(--green-edge);
  --volt-dim:   var(--blue-dim);

  --surge-dim:  var(--red-dim);
  --toxic-dim:  rgba(63, 191, 106, .14);

  --accent: var(--blue);
  --accent-hi: #2020d8;
  --ok: var(--toxic);
  /*
   * The --gold aliases are gone. They were older names kept so nothing resolved
   * to nothing, and once the brand went green they were four tokens called gold
   * holding green, which is the same trap one level down.
   */

  /* ---- type ----
     A grotesque, from what is already on the machine. Not a webfont: a face
     that fails to load takes the identity with it, and a licensed one has to
     be bought before it can ship. Numbers still set in mono, so a figure that
     ticks does not reflow. */
  --face: 'Plus Jakarta Sans', 'Helvetica Neue', Helvetica, -apple-system,
          BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  --display: var(--face);

  --micro-size: 8.5px;
  --micro-track: .18em;

  /* ---- corners ----
     One scale, five steps. There were twenty one different radii across the
     stylesheets, which is why nothing lined up: a video framed at 22px next to
     a card at 14px next to a button at 9px reads as three different products.

     The step is chosen by what the thing is, not by how big it happens to be. */
  --r-xs:   4px;    /* tags, chips, the smallest marks */
  --r-sm:   8px;    /* buttons, inputs, controls */
  --r-md:  12px;    /* cards, panels, tiles */
  --r-lg:  18px;    /* frames: video, hero, the console, anything you look into */
  --r-pill: 999px;

  /* Older names, kept so nothing resolves to nothing. */
  --radius: var(--r-md);
  --radius-sm: var(--r-sm);
}

/* ---------------- the two voices ---------------- */

/*
 * ORDER. A label printed by the machine: tiny, tracked wide,
 * uppercase, never emphasised. These carry no meaning on their own,
 * they name the number next to them.
 */
.micro {
  font-size: var(--micro-size);
  letter-spacing: var(--micro-track);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}

.micro.dim { color: var(--faint); }

/* Numbers are mono and tabular everywhere. A figure that reflows as
   it ticks is a figure nobody trusts. */
.figure {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

/*
 * THE BREAK. Heavy, tight, sheared forward. Reserved for the
 * moments the crowd takes over: a wordmark, a pot filling, a
 * payout. Using it anywhere else spends it.
 */
.shout {
  font-family: var(--display);
  font-weight: 900;
  letter-spacing: -.045em;
  text-transform: uppercase;
  line-height: 1;
  transform: skewX(-9deg);
  transform-origin: left center;
}

/* A rule the house draws. Thin, hard, full width, no rounding. */
.rule {
  height: 1px;
  background: var(--line);
  border: 0;
  margin: 0;
}

/*
 * Overprint: two colours on the same words, offset, the way a
 * misregistered press does it. This is the system breaking on
 * purpose, so it is one class and it is used sparingly.
 */
.overprint {
  position: relative;
  color: var(--ink);
}

.overprint::before {
  content: attr(data-echo);
  position: absolute;
  left: -2px;
  top: 1px;
  color: var(--surge);
  mix-blend-mode: screen;
  opacity: .85;
  pointer-events: none;
}

/* Stacked plates: a panel that sits on a visible second layer,
   so a composition reads as built rather than drawn. */
.plate {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.plate::after {
  content: '';
  position: absolute;
  inset: 6px -6px -6px 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  z-index: -1;
  pointer-events: none;
}

/* ---------------- the age confirmation ----------------
   Asked once, in front of a first purchase, and on every page that can start
   one. It lives in tokens.css because the store and the watch page both raise
   it and neither owns it. Declining is a real button, not a corner cross. */

.age-wrap {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, .78);
  backdrop-filter: blur(6px);
}

.age-box {
  width: min(420px, 100%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 26px 24px;
  border: 1px solid var(--line, #26262a);
  border-radius: 16px;
  background: var(--panel, #101013);
  color: var(--ink, #e7e7e7);
  font-family: 'Archivo', system-ui, sans-serif;
  text-align: left;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
}

.age-title { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
.age-line { margin: 0; font-size: 14px; line-height: 1.55; color: var(--mute, #9a9aa3); }

.age-row { display: flex; gap: 10px; margin-top: 6px; }
.age-row button {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 14px;
  border-radius: 999px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1.3;
  cursor: pointer;
}
.age-no {
  border: 1px solid var(--line, #26262a);
  background: transparent;
  color: var(--mute, #9a9aa3);
}
.age-no:hover { color: var(--ink, #e7e7e7); border-color: var(--mute, #9a9aa3); }
.age-yes {
  border: 0;
  background: var(--green, #3fdc6f);
  color: #04120a;
}
.age-yes:hover:not(:disabled) { filter: brightness(1.08); }
.age-yes:disabled { opacity: .6; cursor: default; }
