/* Everden arcade skin - the one palette the whole product speaks.
 *
 * Brief (mikey, 2026-08-20): retro-arcade Telegram mini-app to match
 * tokehunt.xyz. Dark space-blue, sky-cyan and lime accents, chunky pixel
 * typography, Wii / Pokedex-style gamified cards. "I don't want players to
 * feel they are in a completely different game."
 *
 * That last sentence is the whole spec. Everden had seventeen palettes - the
 * shell plus sixteen arenas, each themed to its den - and crossing from the
 * app into an arena looked like crossing into another product. So this file is
 * loaded FIRST everywhere, and everything after it either uses these tokens or
 * is a deliberate exception.
 *
 * Two layers, and the second is the reason a 2000-line restyle was a migration
 * rather than a rewrite:
 *
 *   1. --ar-* : the canonical tokens. New work names these.
 *   2. the alias block: the semantic names the existing stylesheets already
 *      used - --bg, --panel, --ink, --accent, --muted, --line - repointed at
 *      the arcade palette. Sixteen arenas and a 386KB shell inherited the new
 *      look from that block without a line of their own being touched.
 *
 * Per-den identity survives as ONE token. An arena sets --ar-den to its own
 * hue and keeps its silhouette; it does not get to bring its own background,
 * its own button shape or its own typeface.
 */

/* --- typeface ---------------------------------------------------------------
 *
 * Self-hosted, not Google's CDN. This runs inside a Telegram webview for an
 * audience that includes networks where fonts.gstatic.com does not resolve,
 * and a pixel UI that falls back to system sans is not the same product. Six
 * subsets, 70KB total, which is a fifth of what the Lottie player already
 * costs us. Cyrillic is included for Press Start 2P because player names go in
 * headings; VT323 has no Cyrillic subset upstream, so Cyrillic body text lands
 * on the monospace fallback by design.
 */
@font-face {
  font-family: 'Press Start 2P'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/press-start-2p-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Press Start 2P'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/press-start-2p-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Press Start 2P'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/press-start-2p-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Press Start 2P'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/press-start-2p-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'VT323'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/vt323-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'VT323'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/vt323-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- tokens ---------------------------------------------------------------- */

:root {
  /* surfaces */
  --ar-bg:            #020617;
  --ar-panel:         #0c1e3e;
  --ar-panel-2:       #172554;
  --ar-input:         #172554;

  /* ink */
  --ar-ink:           #f8fafc;
  --ar-muted:         #94a3b8;
  --ar-link:          #38bdf8;

  /* accents */
  --ar-cyan:          #38bdf8;
  --ar-lime:          #a3e635;
  --ar-red:           #ef4444;
  --ar-yellow:        #facc15;
  --ar-mythic:        #a44dff;

  /* borders */
  --ar-line:          #1e3a8a;
  --ar-line-soft:     #1e3a8a66;
  --ar-live:          #ff2a2a;

  /* Per-den identity, and the ONLY colour an arena may claim as its own. It
   * tints the eyebrow, the sigil and the panel aura; it never becomes a
   * background or a button. Defaults to cyan so an arena that sets nothing
   * still looks like the rest of the product. */
  --ar-den:           var(--ar-cyan);

  /* type */
  --ar-display: 'Press Start 2P', Silkscreen, ui-monospace, SFMono-Regular, Menlo, monospace;
  --ar-body:    'VT323', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* geometry */
  --ar-radius:        .75rem;
  --ar-radius-sm:     .5rem;
  --ar-press:         4px;      /* how far a button dips */

  /* depth */
  --ar-glow-cyan:     0 0 24px #38bdf83d;
  --ar-glow-lime:     0 0 24px #a3e6353d;
  --ar-shadow:        0 12px 32px #00000066;

  /* safe areas, named once so sixteen arenas stop each inventing them */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
}

/* --- the alias layer --------------------------------------------------------
 *
 * The pre-arcade stylesheets are full of var(--accent), var(--panel),
 * var(--ink). Repointing those names here restyles all of them at once, and
 * keeps doing it for any rule that is added later without reading this file.
 *
 * --green and --gold are the two that stopped meaning what they say. Everden's
 * palette was forest and brass; the arcade has no gold and its "good thing
 * happened" colour is lime. Both are kept as names because dozens of rules say
 * them, and both now resolve to the arcade equivalent rather than to the
 * colour they are called. Renaming the call sites is a separate, mechanical
 * pass; changing what they resolve to is what makes the product one product.
 */
:root {
  --bg:         var(--ar-bg);
  --panel:      var(--ar-panel);
  --panel2:     var(--ar-panel-2);
  --panel-edge: var(--ar-line);
  --ink:        var(--ar-ink);
  --text:       var(--ar-ink);
  --muted:      var(--ar-muted);
  --sub:        var(--ar-muted);
  --line:       var(--ar-line-soft);
  --accent:     var(--ar-cyan);
  --cyan:       var(--ar-cyan);
  --cyan-dim:   #0ea5e9;
  --blue:       var(--ar-cyan);
  --green:      var(--ar-lime);
  --lime:       var(--ar-lime);
  --acid:       var(--ar-lime);
  --gold:       var(--ar-yellow);
  --brass:      var(--ar-yellow);
  --yellow:     var(--ar-yellow);
  --reward:     var(--ar-lime);
  --danger:     var(--ar-red);
  --red:        var(--ar-red);
  --orange:     var(--ar-yellow);
  --paper:      var(--ar-panel);
  --tile:       var(--ar-panel-2);
  --tone:       var(--ar-den);
  --button:     var(--ar-cyan);
  --display:    var(--ar-display);
  --shadow:     var(--ar-shadow);
}

/* --- base ------------------------------------------------------------------ */

.arcade,
.arcade body {
  background: var(--ar-bg);
  color: var(--ar-ink);
  font-family: var(--ar-body);
  font-size: 1.0625rem;
  line-height: 1.35;
  /* Pixel faces are drawn on the pixel grid. Antialiasing them puts grey on
   * every edge, which is exactly the crispness the brief asks for back. */
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
  /* Style only: a synthesised BOLD on a pixel face is a smeared pixel face,
   * but flavour lines in the shell are set italic and VT323 ships no italic. */
  font-synthesis: style;
}

/* Press Start 2P is a WIDE face - every glyph is one square em. At phone
 * widths an unclamped heading wraps mid-word or overflows, so the cap is part
 * of the type rule rather than something each page remembers. */
.arcade h1, .arcade h2, .arcade h3,
.ar-display {
  font-family: var(--ar-display);
  font-weight: 400;
  line-height: 1.15;
  word-spacing: -.05em;
  letter-spacing: 0;
}
.arcade h1 { font-size: clamp(1.25rem, 4vw, 2rem); }
.arcade h2 { font-size: clamp(1rem, 3.4vw, 1.5rem); }
.arcade h3 { font-size: clamp(.8125rem, 2.8vw, 1.125rem); }

.arcade a { color: var(--ar-link); }

/* The label above a title. Small caps-ish, den-tinted, the one place an arena
 * gets to say whose arena it is. */
.ar-eyebrow {
  display: block;
  font-family: var(--ar-display);
  font-size: .5rem;
  letter-spacing: .18em;
  color: var(--ar-den);
  text-transform: uppercase;
}

.ar-muted { color: var(--ar-muted); }

/* --- cards ----------------------------------------------------------------- */

.ar-card {
  position: relative;
  background: var(--ar-panel);
  border: 1px solid var(--ar-line);
  border-radius: var(--ar-radius);
  padding: 1rem;
}
/* The screen-glow highlight along the top edge - what makes a flat navy
 * rectangle read as a lit panel rather than a div. */
.ar-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(180deg, #ffffff14, transparent 38%);
}
.ar-card > * { position: relative; }

.ar-card--den   { border-color: color-mix(in srgb, var(--ar-den) 55%, var(--ar-line)); }
.ar-card--live  { border-color: var(--ar-live); box-shadow: 0 0 18px #ff2a2a33; }
.ar-card--mythic{ border-color: var(--ar-mythic); box-shadow: 0 0 22px #a44dff40; }

/* --- buttons ----------------------------------------------------------------
 *
 * Chunky and pressable: the shadow IS the button's side wall, so pressing dips
 * the face by exactly the wall height and the wall flattens to nothing. Any
 * other press animation on an arcade button reads as a web page.
 */
.ar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  min-height: 3rem;
  padding: .75rem 1.25rem;
  border: 0;
  border-radius: var(--ar-radius-sm);
  background: var(--ar-panel-2);
  color: var(--ar-ink);
  font-family: var(--ar-display);
  font-size: .625rem;
  letter-spacing: .08em;
  line-height: 1.4;
  text-align: center;
  cursor: pointer;
  box-shadow: 0 var(--ar-press) 0 #0b1120, 0 8px 16px #00000059;
  transition: transform .06s linear, box-shadow .06s linear;
  -webkit-tap-highlight-color: transparent;
}
.ar-btn:active,
.ar-btn[aria-pressed='true'] {
  transform: translateY(var(--ar-press));
  box-shadow: 0 0 0 #0b1120, 0 2px 6px #00000059;
}
.ar-btn:disabled { opacity: .38; filter: grayscale(1); cursor: default; }
.ar-btn:disabled:active { transform: none; }

.ar-btn--primary { background: var(--ar-cyan); color: #04121f; box-shadow: 0 var(--ar-press) 0 #0369a1, 0 8px 18px #38bdf833; }
.ar-btn--primary:active { box-shadow: 0 0 0 #0369a1, 0 2px 6px #38bdf833; }
.ar-btn--success { background: var(--ar-lime); color: #16240a; box-shadow: 0 var(--ar-press) 0 #4d7c0f, 0 8px 18px #a3e63533; }
.ar-btn--success:active { box-shadow: 0 0 0 #4d7c0f, 0 2px 6px #a3e63533; }
.ar-btn--danger  { background: var(--ar-red);  color: #2a0707; box-shadow: 0 var(--ar-press) 0 #991b1b, 0 8px 18px #ef444433; }
.ar-btn--danger:active  { box-shadow: 0 0 0 #991b1b, 0 2px 6px #ef444433; }
.ar-btn--ghost {
  background: transparent; color: var(--ar-muted);
  border: 1px solid var(--ar-line); box-shadow: none;
}
.ar-btn--ghost:active { transform: translateY(2px); box-shadow: none; }
.ar-btn--block { display: flex; width: 100%; }

/* The slow diagonal shine across a main call to action. Deliberately only on
 * .ar-btn--cta: on every button at once it stops reading as emphasis. */
.ar-btn--cta { position: relative; overflow: hidden; }
.ar-btn--cta::after {
  content: '';
  position: absolute;
  top: -60%; bottom: -60%; left: -30%;
  width: 28%;
  background: linear-gradient(100deg, transparent, #ffffff5c, transparent);
  transform: skewX(-18deg);
  animation: ar-shine 3.6s ease-in-out infinite;
}
@keyframes ar-shine {
  0%, 62% { left: -30%; }
  100%    { left: 118%; }
}

/* --- LED status dots -------------------------------------------------------- */

.ar-led {
  display: inline-block;
  width: .5rem; height: .5rem;
  border-radius: 50%;
  background: var(--ar-muted);
  box-shadow: 0 0 6px currentColor;
  vertical-align: middle;
}
.ar-led--ready { background: var(--ar-lime);   box-shadow: 0 0 8px #a3e635; animation: ar-blink 2.4s steps(1) infinite; }
.ar-led--warn  { background: var(--ar-yellow); box-shadow: 0 0 8px #facc15; animation: ar-blink 1.4s steps(1) infinite; }
.ar-led--alert { background: var(--ar-red);    box-shadow: 0 0 8px #ef4444; animation: ar-blink .8s  steps(1) infinite; }
@keyframes ar-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .25; } }

/* --- inputs ----------------------------------------------------------------- */

.ar-input, .arcade input, .arcade textarea, .arcade select {
  background: var(--ar-input);
  border: 1px solid var(--ar-line);
  border-radius: var(--ar-radius-sm);
  color: var(--ar-ink);
  font-family: var(--ar-body);
  font-size: 1rem;
  padding: .625rem .75rem;
}
.ar-input:focus-visible, .arcade input:focus-visible, .arcade textarea:focus-visible {
  outline: 2px solid var(--ar-cyan);
  outline-offset: 1px;
}

/* --- chips and meters -------------------------------------------------------- */

.ar-chip {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .25rem .625rem;
  border: 1px solid var(--ar-line);
  border-radius: 999px;
  background: var(--ar-panel-2);
  color: var(--ar-muted);
  font-family: var(--ar-display);
  font-size: .5rem;
  letter-spacing: .1em;
}

.ar-meter {
  height: .5rem;
  border-radius: 999px;
  background: #0b1120;
  border: 1px solid var(--ar-line);
  overflow: hidden;
}
.ar-meter > * {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--ar-cyan), var(--ar-lime));
  transition: width .3s linear;
}

/* --- effects ------------------------------------------------------------------
 *
 * The CRT overlay. Fixed rather than scrolling, pointer-events off, and drawn
 * at 1px steps so it stays a texture instead of turning into moire on a
 * high-DPI phone. Opacity is low on purpose: it should be felt, not read.
 */
.ar-scanlines::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, #00000038 0 1px, transparent 1px 3px);
  opacity: .45;
  mix-blend-mode: multiply;
}

.ar-glow-cyan { box-shadow: var(--ar-glow-cyan); }
.ar-glow-lime { box-shadow: var(--ar-glow-lime); }

/* Animated electric sheen, for a rare or mythic item only. */
.ar-mythic {
  background: linear-gradient(100deg, var(--ar-mythic), var(--ar-cyan), var(--ar-mythic));
  background-size: 220% 100%;
  animation: ar-sheen 4s linear infinite;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
@keyframes ar-sheen { to { background-position: -220% 0; } }

/* Everything above is decoration, and a player who has asked their phone to
 * stop moving things has asked for this too. */
@media (prefers-reduced-motion: reduce) {
  .ar-btn--cta::after,
  .ar-led--ready, .ar-led--warn, .ar-led--alert,
  .ar-mythic { animation: none; }
  .ar-btn { transition: none; }
}
