/* ==========================================================================
   EVENITY DESIGN SYSTEM — "SIGNAL"
   ==========================================================================

   CHARACTER
   Broadcast control room at 2AM. Precise, electric, confident. A tool for
   performers: it should look like it belongs on a stage, not in a corporate
   dashboard.

   WHY VOLT
   Lime #D8FF47 is the signature because nobody in this market uses it —
   TikTok is red, Twitch is purple, IndoFinity is blue/green. More importantly
   it is semantically right: lime is the colour of a VU meter and a camera
   tally light. "On air." It also has excellent contrast over arbitrary video
   and does not fight skin tones, which matters for every overlay.

   A CALMER RAMP WAS TRIED ONCE AND REJECTED. Lifting the base off black AND
   desaturating the accents together read as PALE rather than calm — the
   intensity is the product, and "soft" is not a thing to guess at for somebody
   else's eyes. See docs/research/interaksi-field-list.md, DEBUG 12.

   WHAT CHANGED ON 20 SEP 2026, AND WHY IT IS NOT THE SAME THING: the founder
   himself asked for a softer base after comparing with other tools, so the
   request is no longer a guess (that was the actual objection in DEBUG 12).
   This time ONLY the surfaces moved — the accents are untouched. The numbers,
   the cost, and the reason `dusk` is now decoration-only are recorded at the
   base tokens below, and the comparison lives in docs/mockups/comfort-tone.html.
   If a future change wants to soften the ACCENTS, that is still uncharted —
   see DEBUG 12 first.

   THE OVERLAY IS DELIBERATELY NOT THIS PALETTE. overlay.css carries its own
   literals and does not load this file, on purpose: on stream, contrast against
   unknown video beats comfort, and a gift alert SHOULD shout.

   RULES FOR ADDING TO THIS FILE
   1. Never hardcode a colour in a component. Add a token here first.
   2. Every token must earn its place: if a value is used once, inline it.
   3. Overlay surfaces must stay transparent — see overlay.css.
   ========================================================================== */

/* ==========================================================================
   THE UI FACES — SELF-HOSTED, AND WHY
   ==========================================================================

   THE STACK USED TO LIE. `--ev-font-ui` has always started with "Inter", and `--ev-font-mono` with
   "JetBrains Mono" — but no `@font-face` existed anywhere in the repository, so both names resolved to
   nothing and every dashboard actually rendered in Segoe UI and Consolas. That is the difference that
   is hard to point at and easy to feel: weight steps that do not exist, flat letter-spacing, and
   numbers whose widths shift while they count.

   WHAT IS DELIBERATELY NOT CHANGED: the OVERLAYS. A widget or an alert draws on the streamer's machine
   over unknown video with no network, and its faces come from the OS on purpose (see overlay.css and
   ALERT_FONTS). This block only serves the dashboard, which this machine serves anyway.

   TWO FILES, TWO FACES, 88KB. Both are the latin subset of the VARIABLE face, so every weight we ask
   for (650, 750, 850 — the tokens use in-between weights on purpose) is a real step instead of the
   browser snapping to the nearest static cut. Both are SIL OFL 1.1: the licence texts travel beside
   them in this folder, which is what the licence asks for.

   PROVENANCE (kept here because nothing can re-download them on the streamer's machine):
     Inter             @fontsource-variable/inter        rsms/inter            LICENSE-Inter.txt
     JetBrains Mono    @fontsource-variable/jetbrains-mono  JetBrains/JetBrainsMono  LICENSE-JetBrainsMono.txt
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-latin-var.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("fonts/jetbrains-mono-latin-var.woff2") format("woff2");
}

:root {
  /* ---------------------------------------------------------------- base --
      A near-black with a blue-violet undertone. Pure #000 looks cheap and
      crushes shadows on OLED; a slight tint reads as "engineered".

      LIFTED ON 20 SEP 2026, AT THE FOUNDER'S REQUEST. The measured problem was
      not the hue but the LUMINANCE and the STEPS between surfaces:
        page #07070c (0.22%) -> card #0d0d15 (0.43%)   step 0.21
      Every dashboard he compared against sits between 0.48% and 1.16%, with a
      step of 0.55-0.64 — 2-5x lighter, and 2.5x more separation. At 0.21 the
      border of a card is nearly invisible, which reads as "berkabut", and
      near-white text on a 0.22% page halates ("huruf mengambang").

      The new ramp is SOFT-A from docs/mockups/comfort-tone.html: it lands
      exactly on the ladder of the reference the founder sent (#0f0f10 / #1a1a1a),
      and keeps the slate undertone.

      WHAT DID NOT CHANGE: the accents. Volt is still #d8ff47 at full saturation.
      Lifting the base already drops its contrast 16.87 -> 15.20, and that is
      what removes the glare. This is NOT the calmer ramp rejected in DEBUG 12 —
      there the ACCENTS were desaturated too (see the note above). What this
      costs, measured: `mist` 7.05 -> 6.35 (still AA), and `dusk` 4.18 -> 3.77,
      so dusk is now DECORATION ONLY and small text uses mist. Both rules were
      already in this file; they are now enforced by the numbers. */

   /* WHAT CHANGED ON 21 SEP 2026, AT THE FOUNDER'S REQUEST: the palette of a layout
   mock-up he approved, applied to the whole dashboard. Two things moved, and this
   is the second time the surfaces have moved without the accents being softened
   (DEBUG 12 is still the record of why "calmer" is not a guess to make for
   somebody else's eyes).

   1. THE NEUTRAL RAMP TURNED GREEN. The old ramp was blue-tinted — #101216 carries
      more blue than red, and #1f232a is visibly cool. The new one is olive: the page
      is #0b0c0b, a card #111310, a raised row #15170f. That is the change that makes
      volt sit ON the surface instead of next to it.
   2. VOLT IS #cff000, NOT #d8ff47. The old volt carried 71 of blue, which reads as
      PALE lime; the new one carries none, so it is pure lime-yellow. Everything
      derived from it (bright / dim / deep / a12 / a24 / a40) was recomputed from the
      new hex, and so was the glow.

   MEASURED on the new surfaces, because "it looks nice" is not a number: body text
   16.31:1, secondary text 10.81:1, mist on a card 6.96:1, dusk 4.29:1 (so dusk stays
   DECORATION ONLY — ids, badges, an "off" marker — exactly as the note below already
   required), volt on the page 15.04:1, the primary button's near-black on volt
   15.04:1, plasma 6.69:1, ion 10.83:1, amber 10.21:1. The button ink is #0b0c0b —
   the page colour itself, not a second black nobody can point at.

   THE OVERLAYS DID NOT MOVE, on purpose: overlay.css and widget.css carry their own
   literals (see the top of this file), because an alert draws over unknown video
   where contrast beats comfort. This block is the DASHBOARD's palette. */
  --ev-void: #0b0c0b;      /* the page */
  --ev-well: #0d0f0c;      /* a field, recessed INTO a card */
  --ev-obsidian: #111310;  /* a card / a panel */
  --ev-slate: #15170f;     /* raised: a row inside a card, a hovered nav row */
  --ev-graphite: #1d2016;  /* a button, a switch track */
  --ev-ash: #272b20;
  --ev-iron: #3a3f30;

  /* --------------------------------------------------------------- text --
     SECONDARY TEXT WAS BRIGHTENED, at the founder's request: "hurufnya terlalu kecil
     dan susah di baca". Measured on --ev-obsidian, the old --ev-dusk was ~3.0:1 —
     under AA, and it was the colour of the smallest text in the app. `mist` is now
     ~7.1:1 and `dusk` ~4.2:1, so the two muted levels are both readable and still a
     visible step apart. This is NOT the rejected "calmer ramp" of DEBUG 12 (that was
     about softening the surfaces and desaturating the accents); the background is
     untouched and volt/plasma are unchanged. */
  --ev-white: #e9ebe5;
  --ev-fog: #c2c7b8;
  --ev-mist: #9aa094;
  --ev-dusk: #767b6e;

  /* ----------------------------------------------------------- signature --
     VOLT is the brand. Use it sparingly: primary actions, the live state and
     focus rings. If everything is volt, nothing is.

     `--ev-volt-bright` is the hover, kept as a token rather than a literal in
     the button rule (rule 1 above) — same value the component used to carry. */
  --ev-volt: #cff000;
  --ev-volt-bright: #ddff40;
  --ev-volt-dim: #9cb400;
  --ev-volt-deep: #5f7000;
  --ev-volt-a12: rgb(207 240 0 / 12%);
  --ev-volt-a24: rgb(207 240 0 / 24%);
  --ev-volt-a40: rgb(207 240 0 / 40%);

  /* --------------------------------------------------------------- alert --
     PLASMA carries gifts and urgency. Deliberately the furthest hue from VOLT
     so an alert reads instantly, even in peripheral vision. */
  --ev-plasma: #ff6a6a;
  --ev-plasma-bright: #ff8f8f;
  --ev-plasma-dim: #cc5252;
  --ev-plasma-a14: rgb(255 106 106 / 14%);
  --ev-plasma-a32: rgb(255 106 106 / 32%);

  /* ---------------------------------------------------------------- info -- */
  --ev-ion: #5ad9c6;
  --ev-ion-a14: rgb(90 217 198 / 14%);
  --ev-ion-a32: rgb(90 217 198 / 32%);

  /* ------------------------------------------------------------- statuses -- */
  --ev-amber: #ffb020;
  --ev-amber-a16: rgb(255 176 32 / 16%);
  /* EMBER WENT HOTTER when plasma became a soft red (#ff6a6a): the tier ramp below
     promises that a bigger gift looks hotter, and an orange-red sitting next to a
     soft red breaks that promise. #ff4d1f is the same family, further in. */
  --ev-ember: #ff4d1f;
  --ev-ember-a16: rgb(255 77 31 / 16%);

  /* Gift value tiers drive alert colour. Monotonic, so a bigger gift always
     looks hotter — that is the entire point of a stream alert. */
  --ev-tier-0: var(--ev-ion);
  --ev-tier-1: var(--ev-volt);
  --ev-tier-2: var(--ev-amber);
  --ev-tier-3: var(--ev-plasma);
  --ev-tier-4: var(--ev-ember);

  /* -------------------------------------------------------------- surface --
      THE BORDERS WENT UP WITH THE SURFACES: a white hairline at 7% is a lot
      weaker over #171a20 than it was over #0d0d15, and the whole point of the
      lift is that a card edge is readable without shouting. */
  --ev-border: rgb(255 255 255 / 8%);
  --ev-border-strong: rgb(255 255 255 / 16%);
  --ev-glow-volt: 0 0 0 1px var(--ev-volt-a24), 0 0 24px -4px var(--ev-volt-a40);
  --ev-glow-plasma: 0 0 0 1px var(--ev-plasma-a32), 0 0 32px -6px var(--ev-plasma-a32);

  /* Behind a modal. Kept as a token rather than a literal in the backdrop rule
     (rule 1 above) — same value the component used to carry. */
  --ev-scrim: rgb(4 5 3 / 72%);

  /* -------------------------------------------------------------- spacing --
     4px base. Only these steps; arbitrary values create drift. */
  --ev-s1: 4px;
  --ev-s2: 8px;
  --ev-s3: 12px;
  --ev-s4: 16px;
  --ev-s5: 20px;
  --ev-s6: 24px;
  --ev-s8: 32px;
  --ev-s10: 40px;
  --ev-s12: 48px;
  --ev-s16: 64px;

  /* --------------------------------------------------------------- radius -- */
  --ev-r-xs: 4px;
  --ev-r-sm: 6px;
  --ev-r-md: 10px;
  --ev-r-lg: 14px;
  --ev-r-xl: 20px;
  --ev-r-full: 999px;

  /* ---------------------------------------------------- table geometry --
     ONE ROW HEIGHT FOR EVERY LIST IN THE PRODUCT.

     Rows used to be sized by whatever they held: `padding: 8px 0` around the cell's
     own content, so a row with a switch measured 49px and the next one 50px, and a
     table of nothing but numbers looked uneven for a reason a reader could feel but
     not name. A list is read DOWN a column, so the heights have to agree — and a
     height that is a token is the only version of that which survives the next row
     somebody adds.

     50px is the smallest value that holds the tallest thing a row puts in it — the
     34px icon button in the Sound Alerts preview cell — with 8px of air above and
     below. The header band is deliberately shorter: it is 12px uppercase and no
     control lives in it.

     Read by `.ev-table__head` / `.ev-table__row` (packages/design/components.css).
     A page that changes a table's COLUMNS does not touch either of these. */
  /* Auction console: explicit floors keep names and coins readable before scrolling. */
  --ev-auction-cols: 28px minmax(180px, 1.4fr) minmax(80px, 1fr) 110px;
  --ev-auction-board-min: 458px;
  --ev-auction-side: 400px;
  --ev-auction-item-min: 240px;
  --ev-auction-preview-h: 430px;
  --ev-auction-battle-preview-h: 820px;
  --ev-line: 1px;
  --ev-row-h: 50px;
  --ev-row-head-h: 40px;

  /* ------------------------------------------------------------ typography --
     Inter for UI. A monospace is reserved for NUMBERS and IDENTIFIERS, which
     is what gives the interface its control-room feel: readouts must not
     reflow as digits change.

     BOTH FACES ARE NOW ACTUALLY LOADED. The stack named them from the first day
     while nothing served them, so the dashboard rendered in Segoe UI and
     Consolas; the @font-face block at the top of this file is what makes these
     two names mean something. Both are the VARIABLE latin subset, so the
     in-between weights below (650, 750) are real.
     The OVERLAYS stay on OS fonts on purpose — see that block.

     THE SCALE WENT UP ONE NOTCH (11/12/13/14 → 12/14/15/16), at the founder's
     request that the text was too small to read. The worst case was the pair that
     mattered most: hints and toggle descriptions were the SMALLEST text in the app
     (12px) AND the dimmest (dusk) — and those are the sentences that explain a form.
     Everything moves together, so the hierarchy is unchanged; only the size is. */
  --ev-font-ui: "Inter", "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ev-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;

  --ev-text-xs: 12px;
  --ev-text-sm: 14px;
  --ev-text-md: 15px;
  --ev-text-base: 16px;
  --ev-text-lg: 18px;
  --ev-text-xl: 22px;
  --ev-text-2xl: 28px;
  --ev-text-3xl: 36px;
  --ev-text-4xl: 48px;

  --ev-num: var(--ev-font-mono);
  --ev-tracking-tight: -0.02em;
  --ev-tracking-caps: 0.09em;

  /* ---------------------------------------------------------------- motion --
     Snappy and confident. Anything above 300ms feels sluggish in a stream
     tool, and an alert has roughly one second to land. */
  --ev-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ev-t-fast: 120ms;
  --ev-t-base: 200ms;
  --ev-t-slow: 320ms;

  /* ---------------------------------------------------------------- depth -- */
  --ev-shadow-sm: 0 1px 2px rgb(0 0 0 / 40%);
  --ev-shadow-md: 0 8px 24px -8px rgb(0 0 0 / 60%);
  --ev-shadow-lg: 0 24px 60px -20px rgb(0 0 0 / 75%);

  /* --------------------------------------------------------------- layers -- */
  --ev-z-sticky: 100;
  --ev-z-drawer: 200;
  --ev-z-modal: 300;
  --ev-z-toast: 400;
}

/* ==========================================================================
   SIGNATURE ELEMENTS
   The motifs that make a screen instantly recognisable as Evenity. They are
   used consistently across app, overlay and style guide.
   ========================================================================== */

/* 1. THE GRID
   A faint volt grid behind empty states. It is what stops a blank screen from
   looking broken, and it is the cheapest brand signal we have. */
.ev-grid {
  background-image:
    linear-gradient(var(--ev-volt-a12) 1px, transparent 1px),
    linear-gradient(90deg, var(--ev-volt-a12) 1px, transparent 1px);
  background-size: 28px 28px;
  background-position: center;
}

/* 2. THE CORNER
   IT WAS THE NOTCH: a machined corner cut instead of a rounded one, on the theory that it made a card
   read as a hardware panel rather than as a generic app card. The founder retired it on 21 SEP 2026 —
   he asked for the rounded corner — so the class is GONE rather than left here unused: a motif nothing
   uses is a motif that ships a lie in a design system. The panel cards that carried it keep the
   stronger edge that made them the branded surface; only the cut is gone. See `.ev-card--panel` in
   components.css. */

/* 3. THE TALLY
   A glowing indicator that mirrors a broadcast camera tally light: volt when
   live, amber while connecting, red on error, grey when idle. This is the
   single most repeated element in the product. */
.ev-tally {
  width: 8px;
  height: 8px;
  border-radius: var(--ev-r-full);
  background: var(--ev-dusk);
  flex: 0 0 auto;
  transition: background var(--ev-t-base) var(--ev-ease), box-shadow var(--ev-t-base) var(--ev-ease);
}

.ev-tally--live {
  background: var(--ev-volt);
  box-shadow: 0 0 0 3px var(--ev-volt-a24), 0 0 14px 1px var(--ev-volt-a40);
  animation: ev-tally-pulse 2.4s var(--ev-ease) infinite;
}

.ev-tally--connecting {
  background: var(--ev-amber);
  box-shadow: 0 0 0 3px var(--ev-amber-a16);
  animation: ev-tally-pulse 1.1s var(--ev-ease) infinite;
}

.ev-tally--error { background: var(--ev-plasma); box-shadow: 0 0 0 3px var(--ev-plasma-a14); }
.ev-tally--ended { background: var(--ev-dusk); }

@keyframes ev-tally-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* ==========================================================================
   READOUT
   Numbers that change constantly. Monospace + tabular figures so the width
   never shifts while watching a live counter tick.
   ========================================================================== */

.ev-readout {
  font-family: var(--ev-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: var(--ev-tracking-tight);
}

.ev-readout--xl { font-size: var(--ev-text-3xl); font-weight: 700; line-height: 1; }
.ev-readout--lg { font-size: var(--ev-text-xl); font-weight: 700; line-height: 1; }
.ev-readout--md { font-size: var(--ev-text-lg); font-weight: 600; }

/* A label above a readout, in the style of a console meter. */
.ev-gauge-label {
  font-size: var(--ev-text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--ev-tracking-caps);
  color: var(--ev-dusk);
}

@media (prefers-reduced-motion: reduce) {
  .ev-tally--live,
  .ev-tally--connecting { animation: none; }
}

