/* Jevcraft — obsidian & end stone.
   Pale end-stone pages, taken from the goal: the
   End. The brand is black and white: the accent is the ink itself (links, buttons, the treasury's fees line, the next
   Jev), and hovering fades it to the page's grey. The other colours only carry meaning: green = live / progress,
   red = danger / deaths / reflex, amber = fallback / warnings, violet = the End and victory. */

/* ------------------------------------------------------------------ fonts
   Self-hosted so no visitor request goes to a third party. The latin subsets Google Fonts serves (IBM Plex Sans v23
   as a variable font, IBM Plex Mono v20), only the weights the site uses. SIL Open Font License 1.1:
   fonts/<family>/OFL.txt. */

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('fonts/ibm-plex-sans/ibm-plex-sans-latin-variable.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ibm-plex-mono/ibm-plex-mono-latin-400.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/ibm-plex-mono/ibm-plex-mono-latin-500.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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/ibm-plex-mono/ibm-plex-mono-latin-600.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;
}

:root {
  color-scheme: light;

  /* content: end stone */
  --bg: #f3f0e6;
  --surface: #fbf9f3;
  --surface-2: #efebdf;
  --surface-3: #e6e1d2;
  --line: #e0dbcb;
  --line-2: #cfc8b4;

  /* text (all ≥ 4.5:1 on --bg, --surface and --surface-2) */
  --text: #1c1724;
  --text-2: #4d4658;
  --text-3: #6a6374;
  --ink: #1c1724;
  --on-ink: #ffffff;

  /* brand accent: the ink (no colour); --accent-hover is what it fades to on hover, --accent-light the accent on the
     obsidian screens */
  --accent: #1c1724;
  --accent-2: #1c1724;
  --accent-hover: #6a6374;
  --accent-soft: #ebe7dc;
  --accent-line: #dcd6c6;
  --accent-light: #ffffff;

  /* meaning (text-safe shades) */
  --ok: #166534;
  --info: #1d4ed8;
  --warn: #92400e;
  --bad: #b91c1c;
  --end: #6d28d9;
  --overworld: #4d7c0f;
  --nether: #c2410c;

  /* fills */
  --green: #16a34a;
  --green-soft: #e6f4e3;
  --red: #dc2626;
  --amber: #f59e0b;
  --amber-soft: #fbf1d6;
  --violet: #7c3aed;
  --violet-soft: #efe9fb;
  --bar: #a8a090;

  /* type */
  --font-sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

  --radius: 12px;
  --radius-sm: 8px;
  /* Wide screens get wide content: tiles grow instead of empty margins; the gutter scales with the window. */
  --gutter: clamp(20px, 2.6vw, 48px);
  --maxw: 1760px;
  --topbar-h: 60px;
  --shadow: 0 1px 2px rgba(28, 23, 36, 0.05);
  --screen: #17131d;
}

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

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font: 400 15px/1.55 var(--font-sans);
  color: var(--text);
  background: var(--bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { display: block; max-width: 100%; }
a { color: var(--accent-2); text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--line-2); }
a:hover { color: var(--accent-hover); }
p { margin: 0; }
h1, h2, h3 { margin: 0; font-weight: 600; }
code, .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
button { font: inherit; color: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--accent-line); color: var(--text); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* On the obsidian the light accent (the dark one is under 3:1 there). */
.viewer :focus-visible, .skip-link:focus-visible { outline-color: var(--accent-light); }
/* The skip link's target takes focus without a ring around the whole page. */
#main:focus { outline: none; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 16px; top: -48px; z-index: 100;
  background: var(--accent); color: #fff; padding: 8px 12px; font-weight: 600; text-decoration: none; border-radius: var(--radius-sm);
}
.skip-link:focus { top: 8px; color: #fff; }

.muted { color: var(--text-3); }
.gold { color: var(--text); }
.red { color: var(--bad); }

/* ------------------------------------------------------------------ icons (CSS masks, no external files) */

.ico {
  display: inline-block;
  width: 1em;
  height: 1em;
  flex: none;
  background-color: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
  mask: var(--i) center / contain no-repeat;
  vertical-align: -0.125em;
}
.ico-heart { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 2h4v1H2zM10 2h4v1h-4zM1 3h6v1H1zM9 3h6v1H9zM1 4h14v4H1zM2 8h12v1H2zM3 9h10v1H3zM4 10h8v1H4zM5 11h6v1H5zM6 12h4v1H6zM7 13h2v1H7z'/%3E%3C/svg%3E"); }
.ico-food { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1h5v1H8zM7 2h7v1H7zM6 3h9v5H6zM7 8h7v1H7zM8 9h4v1H8zM5 9h3v2H5zM4 11h2v2H4zM1 11h3v2H1zM2 13h3v2H2z'/%3E%3C/svg%3E"); }
.ico-close { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 2h3v3H2zM5 5h2v2H5zM7 7h2v2H7zM9 9h2v2H9zM11 11h3v3h-3zM11 2h3v3h-3zM9 5h2v2H9zM5 9h2v2H5zM2 11h3v3H2z'/%3E%3C/svg%3E"); }
.ico-fullscreen { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 1h6v2H3v4H1zM9 1h6v6h-2V3H9zM1 9h2v4h4v2H1zM13 9h2v6H9v-2h4z'/%3E%3C/svg%3E"); }
.ico-fullscreen-exit { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5 1h2v6H1V5h4zM9 1h2v4h4v2H9zM1 9h6v6H5v-4H1zM9 9h6v2h-4v4H9z'/%3E%3C/svg%3E"); }
.ico-copy { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M5 1h10v10h-3V9h1V3H7v1H5zM1 5h10v10H1zM3 7v6h6V7z'/%3E%3C/svg%3E"); }
.ico-external { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 3h6v2H4v7h7V8h2v6H2zM9 1h6v6h-2V5h-1v1h-1v1h-1v1H9v1H8v1H7V9h1V8h1V7h1V6h1V5h1V3H9z'/%3E%3C/svg%3E"); }
.ico-info { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4 1h8v1h2v2h1v8h-1v2h-2v1H4v-1H2v-2H1V4h1V2h2zM7 4v2h2V4zM7 7v5h2V7z'/%3E%3C/svg%3E"); }
.ico-arrow { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 7h10v2H1zM8 3h2v2H8zM10 5h2v2h-2zM12 7h2v2h-2zM10 9h2v2h-2zM8 11h2v2H8z'/%3E%3C/svg%3E"); }
.ico-back { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5 7h10v2H5zM6 3h2v2H6zM4 5h2v2H4zM2 7h2v2H2zM4 9h2v2H4zM6 11h2v2H6z'/%3E%3C/svg%3E"); }
.ico-flag { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 1h2v14H2zM4 2h9v1H4zM4 3h10v5H4zM4 8h9v1H4z'/%3E%3C/svg%3E"); }
.ico-warn { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7 1h2v2h1v3h1v3h1v3h1v3H3v-3h1V9h1V6h1V3h1zM7 6v4h2V6zM7 11v2h2v-2z'/%3E%3C/svg%3E"); }
.ico-scale { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 10h3v5H1zM6 6h3v9H6zM11 2h3v13h-3z'/%3E%3C/svg%3E"); }

/* ------------------------------------------------------------------ tones */

.tone-ok { --tone: var(--ok); }
.tone-info { --tone: var(--info); }
.tone-warn { --tone: var(--warn); }
.tone-bad { --tone: var(--bad); }
.tone-muted { --tone: var(--text-3); }
.tone-end { --tone: var(--end); }
.tone-overworld { --tone: var(--overworld); }
.tone-nether { --tone: var(--nether); }

/* ------------------------------------------------------------------ buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 15px;
  font: 500 13.5px/1.1 var(--font-sans);
  color: var(--text);
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.btn:hover { background: var(--surface-2); color: var(--text); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary, .btn-gold { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover, .btn-gold:hover { background: var(--text-2); border-color: var(--text-2); color: #fff; }
.btn .ico-arrow { font-size: 11px; transition: transform 0.15s; }
.btn:hover .ico-arrow { transform: translateX(2px); }
.btn-ghost { background: transparent; box-shadow: none; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-small { padding: 6px 11px; font-size: 12.5px; }

/* ------------------------------------------------------------------ badges / pills */

.pill, .dim, .flag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  font: 500 12px/1.3 var(--font-sans);
  white-space: nowrap;
  color: color-mix(in srgb, var(--tone, var(--text-2)) 80%, var(--text)); /* ≥ 5.4:1 on every surface */
  border: 1px solid color-mix(in srgb, var(--tone, var(--text-3)) 24%, transparent);
  background: color-mix(in srgb, var(--tone, var(--text-3)) 7%, var(--surface));
  border-radius: 999px;
}
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.online { display: inline-flex; align-items: center; gap: 6px; font: 500 12px/1 var(--font-sans); color: var(--text-3); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font: 500 12.5px/1.3 var(--font-sans);
  color: var(--text-3);
}
.eyebrow .ico { font-size: 12px; }

/* ------------------------------------------------------------------ top bar
   The bar every page shares, on the page's own end stone: the wordmark on the left, the page links (Live, Treasury,
   Docs: each its own page) in the middle, on the right Token and X. */

.topbar {
  position: sticky; top: 0; z-index: 50;
  background: rgba(243, 240, 230, 0.9);
  -webkit-backdrop-filter: saturate(1.3) blur(12px);
  backdrop-filter: saturate(1.3) blur(12px);
  border-bottom: 1px solid var(--line);
}
/* Three columns, the outer two equal, so the links sit in the middle of the bar. */
.topbar-inner { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 12px; min-height: var(--topbar-h); padding: 0 var(--gutter); }
.brand { justify-self: start; display: inline-flex; align-items: center; gap: 9px; color: var(--text); text-decoration: none; }
/* The logo: a block in half-pixel hairline, its faces in nearly even dots, where Jevs have mined. */
.brand-mark { display: block; width: 20px; height: 23px; }
/* hovering fades the whole wordmark, the block with it */
.brand:hover { color: var(--accent-hover); }
.brand:hover .brand-mark { opacity: 0.5; }
.brand-name { font: 600 18px/1 var(--font-sans); letter-spacing: -0.025em; white-space: nowrap; }
.topnav { display: flex; align-self: stretch; gap: 2px; min-width: 0; }
.topnav a { position: relative; display: inline-flex; align-items: center; padding: 0 14px; font: 500 14.5px/1 var(--font-sans); color: var(--text-2); text-decoration: none; white-space: nowrap; }
.topnav a:hover { color: var(--text); }
.topnav a:focus-visible { outline-offset: -6px; }
.topnav a.is-active { color: var(--text); }
/* the current page: a line right under its text (the text is centred in the link, so 50% plus a bit more than half a
   cap height clears the descenders) */
.topnav a.is-active::after { content: ''; position: absolute; left: 14px; right: 14px; top: calc(50% + 0.72em); height: 2px; background: var(--ink); }
.topbar-right { justify-self: end; display: flex; align-items: center; gap: 2px; min-width: 0; }

.content { flex: 1 0 auto; width: 100%; max-width: var(--maxw); margin-inline: auto; padding: 28px var(--gutter) 72px; container-type: inline-size; }

/* ------------------------------------------------------------------ API banner */

.api-banner { background: #fef2f2; border-bottom: 1px solid #fecaca; color: #7f1d1d; }
.api-banner-inner { display: flex; align-items: center; gap: 12px; max-width: var(--maxw); margin-inline: auto; padding: 10px var(--gutter); font-size: 14px; }
.api-banner-icon { flex: none; width: 14px; height: 14px; background: var(--red); -webkit-mask: var(--i) center / contain no-repeat; mask: var(--i) center / contain no-repeat; --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M7 1h2v2h1v3h1v3h1v3h1v3H3v-3h1V9h1V6h1V3h1zM7 6v4h2V6zM7 11v2h2v-2z'/%3E%3C/svg%3E"); }
.api-banner strong { color: #7f1d1d; font-weight: 600; }
/* Stale data: dim the graphics only; text keeps its contrast (the banner already says the data is old). */
body.is-stale :is(.bar-track, .jt-screen) { opacity: 0.55; transition: opacity 0.3s; }

/* ------------------------------------------------------------------ type: eyebrows, titles, section rules */

/* Small caps eyebrow over a title. */
.caps { font: 600 11.5px/1.3 var(--font-sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-2); }
/* Section header: small caps with a rule running to the right edge. */
.caps-head { display: flex; align-items: center; gap: 14px; margin: 36px 0 14px; font: 600 11.5px/1.3 var(--font-sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-3); }
.caps-head::after { content: ''; flex: 1; min-width: 24px; height: 1px; background: var(--line-2); }
.caps-head > span { min-width: 0; }
.view-head + .caps-head { margin-top: 0; }

.view-head { display: grid; gap: 10px; margin-bottom: 32px; }
.view-title { font: 600 clamp(30px, 3.2vw, 46px)/1.05 var(--font-sans); letter-spacing: -0.04em; text-wrap: balance; }

/* ------------------------------------------------------------------ live: only the streams, one tile per playing Jev, then
   the unlock tile */

.wall { display: grid; gap: 16px; }
/* No page width cap: the streams run across the whole window. */
.page-live .content { max-width: none; }
.jt { position: relative; min-width: 0; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; background: var(--screen); box-shadow: 0 1px 2px rgba(28, 25, 23, 0.06), 0 12px 28px -18px rgba(28, 25, 23, 0.35); }
.jt-screen { position: absolute; inset: 0; }
.jt .viewer { position: absolute; inset: 0; aspect-ratio: auto; border: 0; border-radius: 0; }
.jt .viewer-sub { display: none; }
.jt .viewer-ph-inner { gap: 4px; padding: 8px 12px; }
/* The placeholder's "Watch live" button sits above the tile's link, like the fullscreen and stop buttons; the rest of
   the tile still opens the bot's page. */
.jt .viewer-ph-inner { z-index: 4; pointer-events: none; }
.jt .viewer-watch { pointer-events: auto; }
/* The whole tile opens the bot's page; the viewer's own buttons (fullscreen, stop) stay above it. */
.jt-link { position: absolute; inset: 0; z-index: 3; border-radius: var(--radius); }
.jt-link:hover { background: rgba(255, 255, 255, 0.05); }
.jt-link:focus-visible { outline: 3px solid #93c5fd; outline-offset: -3px; }
.jt .viewer-ctls { z-index: 5; }
/* Name row on the picture: white on a scrim (the viewer's buttons are in the bottom right corner). */
.jt-top { position: absolute; top: 0; left: 0; right: 0; z-index: 4; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 10px 12px 22px 12px; pointer-events: none; color: #fff; background: linear-gradient(rgba(0, 0, 0, 0.6), transparent); }
.jt-title { min-width: 0; font: 600 14.5px/1.2 var(--font-sans); letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); }
.jt-live { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; font: 500 11.5px/1.4 var(--font-sans); border-radius: 999px; white-space: nowrap; color: #fff; }
.jt-live { display: none; background: var(--red); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; font-size: 10.5px; }
.jt-live-dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; animation: pulse 2s ease-in-out infinite; }
.jt.is-live .jt-live { display: inline-flex; }
.jt-skeleton { background: var(--surface); box-shadow: none; border: 1px solid var(--line); }
.jt-skeleton .sk-viewer { height: 100%; border-radius: 0; }

/* The next Jev: what the treasury still needs before the policy starts it, big, and under it a thin bar from the
   policy's stop line (−1 on the left: below it the newest Jev is deleted) to its next start (+1 on the right: another
   starts). Same 16:9 cell as a stream (it grows if its text needs more room). */
.jt-unlock { overflow: visible; display: flex; flex-direction: column; justify-content: center; gap: 14px; padding: 20px 24px; color: var(--text); text-decoration: none; background: var(--surface); border: 1px dashed var(--line-2); box-shadow: none; }
.jt-unlock:hover { color: var(--text); border-color: var(--text-3); background: var(--surface-2); }
/* Its words grow with the tile. */
.jt-unlock { container-type: inline-size; }
.wall .unlock-line { font-size: clamp(13px, 2.5cqi, 19px); }
.wall .unlock-link { font-size: clamp(13px, 2.3cqi, 17px); }
/* One line above the bar: the amount still missing (or the state's word) and what it is for. */
.unlock-line { margin: 0; font-size: 13px; line-height: 1.45; color: var(--text-3); }
.unlock-amount { font-family: var(--font-mono); color: var(--text-2); }
/* The amount's digits roll to each new value, like a counter. */
.roll { display: inline-flex; vertical-align: bottom; }
.roll-d { display: inline-block; height: 1.45em; line-height: 1.45em; overflow: hidden; }
.roll-s { display: flex; flex-direction: column; transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); }
.roll-s > span { height: 1.45em; }
.unlock-dot { display: inline-block; width: 6px; height: 6px; margin: 0 8px 0.14em 0; vertical-align: middle; border-radius: 50%; background: var(--ink); animation: pulse 2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .roll-s { transition: none; } .unlock-dot { animation: none; } }
.unlock-meter { display: flex; align-items: center; gap: 10px; }
.unlock-end { flex: none; font: 600 12px/1 var(--font-mono); }
.unlock-minus { color: var(--bad); }
.unlock-plus { color: var(--ok); }
.unlock-end.is-off { color: var(--text-3); opacity: 0.55; }
.unlock-bar { position: relative; display: block; flex: 1; min-width: 0; height: 3px; background: var(--surface-3); border-radius: 2px; }
.unlock-fill { position: absolute; inset: 0 auto 0 0; background: var(--ink); border-radius: 2px; transition: width 0.6s ease; }
/* All of the tile is the link to the Treasury; this says so, so it is text, not a link inside a link. */
.unlock-link { align-self: flex-start; font-size: 13px; line-height: 1.2; color: var(--text-2); text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.jt-unlock:hover .unlock-link { color: var(--text); text-decoration-color: currentColor; }

.inst-viewer { position: relative; }
.viewer-source { position: absolute; top: 10px; left: 10px; z-index: 3; padding: 3px 9px; font: 500 12px/1.4 var(--font-sans); color: #fff; background: rgba(0, 0, 0, 0.5); border: 1px solid rgba(255, 255, 255, 0.28); border-radius: 999px; cursor: help; }

/* The game's HUD and scoreboard (mcgui.js), drawn at whole device pixels over the browser view (the video has its own). It
   sits inside the viewer, so it goes fullscreen with the picture. */
.mc-gui { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; pointer-events: none; image-rendering: pixelated; }

.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; min-width: 0; box-shadow: var(--shadow); }
.panel-title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; font: 600 16px/1.3 var(--font-sans); letter-spacing: -0.01em; margin-bottom: 16px; }

/* ------------------------------------------------------------------ victory */

.victory {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 56px 24px 52px;
  margin-bottom: 28px;
  background: linear-gradient(180deg, var(--violet-soft), var(--surface));
  border: 1px solid #ddd6fe;
  border-radius: var(--radius);
}
.victory-inner { position: relative; z-index: 1; display: grid; justify-items: center; gap: 12px; }
.victory-eyebrow { font: 600 12.5px/1 var(--font-sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--end); }
.victory-title { font: 600 56px/1.05 var(--font-sans); letter-spacing: -0.045em; color: var(--text); }
.victory-text { font-size: 17px; color: var(--text-2); }
.victory .btn { margin-top: 10px; }
.victory-confetti { position: absolute; inset: 0; pointer-events: none; }
/* three falls, then gone (it must not move forever) */
.confetto { position: absolute; top: -12px; width: 7px; height: 7px; border-radius: 1px; background: var(--amber); opacity: 0; animation: confetti-fall linear 3 forwards; }
.confetto.c-end { background: var(--violet); }
.confetto.c-ok { background: var(--green); }
.confetto.c-white { background: var(--line-2); width: 5px; height: 5px; }
.victory-inline { padding: 28px; margin-bottom: 20px; }
.victory-inline .victory-title { font-size: 30px; letter-spacing: -0.03em; }

/* ------------------------------------------------------------------ decision (the instance page) */

.card-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; flex-basis: 100%; }

/* objective */

/* current action */
.current { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); min-width: 0; }
.current .eyebrow { color: var(--ok); font-weight: 600; }

/* decision: the move that ran in the text colour, every other option in one grey (no fading by probability), Confidence
   and Options in the text colour. */
.decision { min-width: 0; }
.decision.is-fresh .bar.is-chosen .bar-label { animation: pick-flash 0.8s ease-out; }
.bars { list-style: none; margin: 0; padding: 0; display: grid; align-content: start; gap: 7px; }
.bar { display: grid; grid-template-columns: minmax(0, 1fr) 34% 46px; align-items: center; gap: 10px; font-size: 13px; }
.bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-3); }
.bar-track { position: relative; height: 4px; background: var(--surface-3); border-radius: 999px; overflow: hidden; }
.bar-fill { position: absolute; inset: 0 auto 0 0; background: var(--bar); border-radius: 999px; transition: width 0.45s ease; }
.bar-pct { text-align: right; color: var(--text-3); font-size: 11.5px; }
.bar.is-chosen .bar-label { color: var(--text); font-weight: 500; }
.bar.is-chosen .bar-fill { background: var(--text); }
.bar.is-chosen .bar-pct { color: var(--text); }
.decision-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); }
.decision-meta dt { font: 400 11.5px/1.3 var(--font-sans); color: var(--text); }
.decision-meta dd { margin: 3px 0 0; font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.decision-empty { display: none; color: var(--text-3); font-size: 13px; padding: 8px 0 2px; }
.decision.is-empty .decision-body { display: none; }
.decision.is-empty .decision-empty { display: block; }
/* A decision without a source (.is-auto): a note in place of the bars, confidence and latency. A fallback, a reflex or
   an only option has none: it is its one move at 100% (decisionBars). */
.decision-auto { display: none; padding: 10px 12px; border-left: 2px solid var(--tone, var(--text-3)); background: color-mix(in srgb, var(--tone, var(--text-3)) 7%, transparent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.decision.has-note .decision-auto { display: block; }
.decision.is-auto .decision-body { display: none; }
.decision.has-note:not(.is-auto) .decision-auto { margin-bottom: 12px; }
.decision-auto-title { font: 600 15px/1.4 var(--font-sans); color: var(--tone, var(--text-2)); overflow-wrap: anywhere; }
.decision-auto.tone-muted .decision-auto-title { color: var(--text-2); }
.decision-auto-note { margin-top: 4px; font-size: 13.5px; line-height: 1.5; color: var(--text-2); }

/* key/value strips */
.kv { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0; padding-top: 14px; border-top: 1px solid var(--line); }
.kv dt { font: 400 11.5px/1.3 var(--font-sans); color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kv dd { margin: 3px 0 0; font-size: 14px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ------------------------------------------------------------------ viewer */

.viewer { --screen: #1c1917; position: relative; aspect-ratio: 16 / 9; background: var(--screen); overflow: hidden; }
.viewer-lg { border-radius: var(--radius); }
.viewer-ph {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  padding: 16px;
  text-align: center;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.07) 1px, transparent 1.5px) 0 0 / 18px 18px, var(--screen);
}
.viewer-ph-inner { position: relative; z-index: 1; display: grid; justify-items: center; gap: 6px; max-width: 34ch; padding: 14px 18px; }
.viewer-ph-icon { width: 8px; height: 8px; margin-bottom: 4px; border-radius: 50%; background: #57534e; }
.viewer.is-available .viewer-ph-icon { background: #4ade80; box-shadow: 0 0 0 5px rgba(74, 222, 128, 0.16); animation: pulse 2s ease-in-out infinite; }
.viewer-title { font: 600 15px/1.3 var(--font-sans); color: #d6d3d1; }
.viewer.is-available .viewer-title { color: #fff; }
.viewer-sub { font-size: 13px; color: #a8a29e; }
.viewer-watch { margin-top: 10px; }
.viewer .btn-primary { background: #fff; border-color: #fff; color: var(--ink); }
.viewer .btn-primary:hover { background: #e7e5e4; border-color: #e7e5e4; color: var(--ink); }
.viewer-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; }
/* The game camera, letterboxed rather than cropped: its HUD and scoreboard sit at the edges of the picture. */
.viewer-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #000; }
.viewer.is-live .viewer-ph { display: none; }
/* The video is connecting: keep the placeholder ("Connecting…") over it until it plays. */
.viewer.is-loading .viewer-ph { display: grid; }
/* The viewer's buttons (fullscreen, and stop while it plays) sit in the picture's bottom right corner. */
.viewer-ctls { position: absolute; bottom: 10px; right: 10px; z-index: 2; display: none; gap: 6px; }
.viewer.is-live .viewer-ctls { display: flex; }
.viewer-ctl { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; color: var(--text); background: rgba(255, 255, 255, 0.9); border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; }
.viewer-ctl:hover { background: var(--surface); }
.viewer:fullscreen { aspect-ratio: auto; border: 0; border-radius: 0; }
.viewer:-webkit-full-screen { aspect-ratio: auto; border: 0; border-radius: 0; }

/* ------------------------------------------------------------------ empty / skeleton */

.empty { display: grid; justify-items: center; gap: 10px; padding: 56px 24px; text-align: center; border: 1px dashed var(--line-2); border-radius: var(--radius); background: var(--surface); }
.empty-icon { width: 10px; height: 10px; border-radius: 50%; background: var(--amber); box-shadow: 0 0 0 6px #fef3c7; margin-bottom: 8px; }
.empty-title { font: 600 20px/1.3 var(--font-sans); letter-spacing: -0.02em; }
.empty-text { color: var(--text-2); max-width: 56ch; }
.empty .btn { margin-top: 8px; }
.empty-page { margin-top: 24px; }

.sk { border-radius: 6px; background: linear-gradient(90deg, var(--surface-2) 0%, var(--surface-3) 50%, var(--surface-2) 100%); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; }
.sk-title { height: 24px; width: 42%; }
.sk-viewer { aspect-ratio: 16 / 9; width: 100%; }
.sk-viewer-lg { margin-top: 20px; border-radius: var(--radius); }
.sk-line { height: 14px; width: 88%; }
.inst-loading { display: grid; gap: 10px; }

/* ------------------------------------------------------------------ treasury */

/* The pot (treasury.js): the head, then the drawing, which scrolls sideways on a phone. */
/* As wide as the page: the drawing grows with the window (treasury.js). */
.pot { margin-inline: auto; }
.pot-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px; }
.pot-title { margin: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 10px; font-size: 22px; font-weight: 500; letter-spacing: -0.02em; }
.pot-badge { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font: 600 11.5px/1.4 var(--font-sans); letter-spacing: 0.04em; text-transform: uppercase; }
.pot-badge.bad { background: #fde7e7; color: var(--bad); }
.pot-badge.warn { background: var(--amber-soft); color: var(--warn); }
.pot-balance { margin: 24px 0 0; font-size: 44px; font-weight: 500; letter-spacing: -0.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.pot-note { margin: 6px 0 0; font: 12px var(--font-mono); color: var(--text-3); }
.pot-note.is-prose { font: 14px/1.5 var(--font-sans); color: var(--text-2); max-width: 70ch; }
.pot-wallet { margin: 4px 0 0; font: 12px var(--font-mono); color: var(--text-3); }
.pot-addr { padding: 0; border: 0; background: none; font: inherit; color: var(--text-2); cursor: pointer; text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
.pot-addr:hover { color: var(--text); text-decoration-color: currentColor; }
.pot-verify { margin-left: 12px; color: inherit; }
/* The drawing at its own size (never enlarged), at most 1100 px wide, in the middle of the page. */
.pot-flow { max-width: 1100px; margin: 24px auto 0; overflow-x: auto; }
.pot-flow svg { display: block; width: 100%; height: auto; font-family: var(--font-sans); }
/* The four numbers under the drawing (treasuryStats() in site.js): from the page's left edge to its right, the same
   gap between each two, never closer than 24 px; on a phone two by two. */
.pot-stats { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line); }
.pot-stats dl { display: flex; justify-content: space-between; gap: 24px; margin: 0; }
.pot-stat { min-width: 0; max-width: calc((100% - 72px) / 4); }
.pot-stat dt { font: 400 12px/1.3 var(--font-sans); color: var(--text-3); }
.pot-stat dd { margin: 6px 0 0; font: 400 20px/1.2 var(--font-mono); letter-spacing: -0.01em; color: var(--text); font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
  .pot-stats dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 24px; }
  .pot-stat { max-width: none; }
}
.pot-name { font: 500 16px var(--font-sans); fill: var(--text); }
.pot-name.gone { fill: var(--text-3); }
.pot-name.next { fill: var(--accent-2); }
.pot-mono { font: 12px var(--font-mono); fill: var(--text-3); font-variant-numeric: tabular-nums; }
.pot-small { font: 11px var(--font-mono); fill: var(--text-3); font-variant-numeric: tabular-nums; }
.pot-mono.next { fill: var(--accent-2); }
.pot-mono.why { fill: var(--bad); font-weight: 600; }
.pot-line { fill: none; stroke: #e2dccb; stroke-width: 10; stroke-linecap: round; }
.pot-line.is-new { stroke-dasharray: 1; animation: pot-open 1.3s ease-out both; }
@keyframes pot-open { from { stroke-dashoffset: 1; } }
.pot-line.next { stroke: #c9c2ae; stroke-width: 2; stroke-dasharray: 3 7; }
.pot-line.is-dry { stroke-dasharray: 1; animation: pot-dry 1.4s ease-in forwards; }
@keyframes pot-dry { to { stroke-dashoffset: -1; } }
.is-stopping { animation: pot-blink 0.9s ease-in-out infinite alternate; }
@keyframes pot-blink { to { opacity: 0.25; } }
/* the fees line: its inlet in the accent, the line the colour of the lines to the Jevs */
.pot-in { stroke: #e2dccb; stroke-width: 8; }
.pot-inlet { fill: var(--accent); }
.pot-bar { fill: var(--ink); }
.pot-bar.gone { fill: none; stroke: var(--text-3); stroke-width: 1.5; stroke-dasharray: 3 3; }
.pot-bar.next { fill: none; stroke: #b9b2a0; stroke-width: 1.5; stroke-dasharray: 3 3; }
.pot-bar.is-new { animation: pot-grow 0.7s ease-out both; transform-box: fill-box; transform-origin: center; }
@keyframes pot-grow { from { transform: scale(0.2); opacity: 0; } }
.pot-block { fill: var(--bg); stroke: var(--ink); stroke-width: 1.5; }
.pot-block.gone { stroke: var(--text-3); }
.pot-block.next { stroke: #b9b2a0; stroke-dasharray: 3 3; }
.pot-fill { fill: var(--ink); transition: y 0.25s linear, height 0.25s linear; }
.pot-dot { fill: var(--accent); }
.pot-flow [data-href] { cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
  .pot-line.is-new { animation: none; stroke-dasharray: none; }
  .pot-line.is-dry { animation: none; opacity: 0.15; }
  .is-stopping, .pot-bar.is-new { animation: none; }
  .pot-fill { transition: none; }
}
@media (max-width: 639px) { .pot-balance { font-size: 38px; } }

/* ------------------------------------------------------------------ docs */

.docs { display: grid; grid-template-columns: 180px minmax(0, 720px); gap: 56px; justify-content: center; padding-top: 12px; }
.docs-nav { position: sticky; top: calc(var(--topbar-h) + 24px); align-self: start; display: grid; gap: 10px; font-size: 14px; }
.docs-nav a { color: var(--text-2); text-decoration: none; }
.docs-nav a:hover { color: var(--text); }
.docs-title { font: 500 34px/1.1 var(--font-sans); letter-spacing: -0.03em; }
.docs-body section { margin-top: 36px; padding-top: 32px; border-top: 1px solid var(--line); }
.docs-body h2 { margin: 0 0 12px; font: 500 22px/1.2 var(--font-sans); letter-spacing: -0.02em; }
.docs-body section > p, .docs-body li, .docs-rows dd p { font-size: 15.5px; line-height: 1.65; color: var(--text-2); }
.docs-body section > p + p { margin-top: 12px; }
.docs-rows { display: grid; gap: 0; margin: 14px 0 0; }
.docs-rows > div { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 4px 20px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.docs-rows dt { font-size: 15px; font-weight: 500; color: var(--text); }
.docs-rows dd { margin: 0; min-width: 0; }
.docs-model { margin: 2px 0 6px; font-size: 12.5px; color: var(--text-3); overflow-wrap: anywhere; }
.legal { display: grid; gap: 6px; font-size: 13px; line-height: 1.5; color: var(--text-3); }
.legal a { color: inherit; }
@media (max-width: 900px) {
  .docs { display: block; padding-top: 0; }
  .docs-nav { display: none; }
}
@media (max-width: 560px) {
  .docs-rows > div { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------------ instance page */

.back-link { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 22px; color: var(--text-2); text-decoration: none; font-size: 14px; font-weight: 500; }
.back-link:hover { color: var(--text); }
.back-link .ico { color: var(--text-3); font-size: 13px; }
.inst-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-bottom: 10px; }
.inst-who { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.inst-who::before { content: '/'; color: var(--text-3); }
.inst-head .back-link { margin: 0; }
.inst-title-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.inst-name { font: 600 16px/1.2 var(--font-sans); letter-spacing: -0.01em; overflow-wrap: anywhere; }
.inst-head .card-badges { margin-left: 0; }
/* One small line with the way back and the name, then the stream, as big as fits the window under them, and beside it
   the Actions list with no box: its first row level with the stream's top, Confidence and Options with its bottom.
   Under the stream on narrow screens, at most 8 rows. */
.page-instance .content { max-width: none; padding-top: 16px; }
.inst-stage { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 28px; margin: 0 auto 20px;
  max-width: calc(max(480px, calc((100vh - var(--topbar-h) - 68px) * 16 / 9)) + 368px); }
.inst-top { min-width: 0; }
.inst-moves { position: relative; min-width: 0; min-height: 240px; }
.inst-moves-body { position: absolute; inset: 0; display: flex; flex-direction: column; padding-top: 2px; }
.inst-moves-body > div, .inst-moves .decision, .inst-moves .decision-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.inst-moves .bars { flex: 1; min-height: 0; overflow: hidden; }
.inst-moves .panel-title { font: 500 13px/1.3 var(--font-sans); color: var(--text-3); letter-spacing: 0; margin-bottom: 12px; }
@media (max-width: 900px) {
  .inst-stage { grid-template-columns: minmax(0, 1fr); gap: 16px; max-width: max(480px, calc((100vh - var(--topbar-h) - 68px) * 16 / 9)); }
  .inst-moves { min-height: 0; }
  .inst-moves-body { position: static; }
  .inst-moves .bars > li:nth-child(n + 9) { display: none; }
}
/* The fullscreen button is always on the bot page's stream (the stop button only while it plays). Fullscreen shows the
   stream alone (.viewer:fullscreen). */
.inst-stage .viewer-ctls { display: flex; }
.inst-stage .viewer:not(.is-live) .viewer-close { display: none; }
/* Stats & costs, quiet: no fill or shadow, everything in the text colour. */
.inst-stats { background: transparent; box-shadow: none; }
.inst-stats .panel-title { font: 500 13px/1.3 var(--font-sans); letter-spacing: 0; margin-bottom: 12px; }
.tags { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.tag { padding: 3px 8px; font-size: 12px; color: var(--text-2); background: var(--surface-2); border-radius: 6px; overflow-wrap: anywhere; }
.tile { position: relative; display: grid; grid-template-rows: auto 1fr; gap: 10px; min-height: 72px; padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; min-width: 0; }
.check { display: grid; grid-template-columns: 16px 22px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 7px 10px; font-size: 14px; color: var(--text-3); border-radius: var(--radius-sm); }

.log { list-style: none; margin: 0; padding: 0 12px 0 0; max-height: 440px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
/* Who chose an action when it was not a plain Jev pick (event data.source). */

/* The stats as plain label / value pairs, no lines between them. */
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0; margin: 0; }
.stat-cell { padding: 10px 14px 10px 0; min-width: 0; }
.stat-cell dt { font: 400 12px/1.3 var(--font-sans); color: var(--text); }
.stat-cell dd { margin: 5px 0 0; font-size: 15px; font-weight: 400; letter-spacing: -0.01em; color: var(--text); overflow-wrap: anywhere; }
.stat-cell dd.stat-cell-sub { display: block; margin: 2px 0 0; font: 400 11.5px/1.4 var(--font-sans); letter-spacing: 0; color: var(--text); overflow-wrap: anywhere; }

.labels { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.labels li { position: relative; padding-left: 18px; font-size: 14px; line-height: 1.55; color: var(--text-2); }
.labels strong { color: var(--text); font-weight: 600; margin-right: 4px; }

/* The watcher's calls: a raspberry pink, apart from the other four for the three common colour-vision deficiencies too. */
/* The API note's dot: Jev, the planner and the watcher. */
/* Model calls OpenRouter billed without a price in their answer (calls that timed out): API, but none of the three kinds. */
.view-head + .costs > .caps-head:first-child { margin-top: 0; }

/* ------------------------------------------------------------------ other Jevs' record (cross-Jev learning) */

/* Decision view: what of the record was in Jev's input, and an option's other-Jevs rate under its bar. */

/* Instance page: the "Learned from other Jevs" panel and the plan history's record lines. */
.learned { margin-bottom: 20px; }
/* A plan the watcher asked for: who asked, then its words. */

/* How it works: the learning loop's totals line. */

.topbar-link { display: inline-flex; align-items: center; height: 40px; padding: 0 10px; font: 500 14px/1 var(--font-sans); color: var(--text-2); text-decoration: none; border-radius: var(--radius-sm); }
/* Token and X hover like the page links beside them: the colour only, no box. */
.topbar-link:hover { color: var(--text); }
.social { display: grid; place-items: center; width: 40px; height: 40px; color: var(--text-2); border-radius: var(--radius-sm); }
.social:hover { color: var(--text); }
/* the logos are inline SVG in the pages, so they draw even with an older cached stylesheet */
.social-icon { width: 20px; height: 20px; }

/* The legal lines at the end of How it works. */

/* ------------------------------------------------------------------ animation */

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes pick-flash { from { color: var(--ok); } to { color: inherit; } }
@keyframes confetti-fall {
  0% { transform: translate(0, -20px) rotate(0deg); opacity: 0; }
  10% { opacity: 1; }
  100% { transform: translate(var(--drift, 0), 420px) rotate(540deg); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .confetto { display: none; }
  .sk { background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line-2); }
}

/* ------------------------------------------------------------------ responsive
   The page's grids follow the width of the content column (container queries on .content); the top bar follows the
   window. */

/* fragment jumps and focused elements land below the sticky top bar */
html { scroll-padding-top: calc(var(--topbar-h) + 8px); }

/* Two tiles per row, three on wide screens: a second row starts on the left, under the first; fewer than three tiles
   (one short row) stand in the middle. A tile is never so big that two rows would not fit in
   the window (the top bar and paddings are about 150 px), which only very wide, short monitors reach. */
@container (min-width: 601px) {
  .wall { display: flex; flex-wrap: wrap; }
  .wall:not(:has(> .jt:nth-child(3))) { justify-content: center; }
  .wall > .jt { flex: 0 0 calc((100% - 16px) / 2); max-width: max(480px, calc((100vh - 150px) * 8 / 9)); }
}
@container (min-width: 1180px) {
  .wall > .jt { flex-basis: calc((100% - 32px) / 3); }
}

@container (max-width: 940px) {
  /* What runs in two columns: Jev and the planner, the watcher across, then the build and the raw data. */
}


/* Two streams per row: the unlock tile stays 16:9 beside them, a little tighter. */
@container (min-width: 601px) and (max-width: 1000px) {
  .jt-unlock { gap: 10px; padding: 16px 20px; }
}

@container (max-width: 600px) {
  .wall { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  /* The table of Jevs playing fits a phone: tighter cells, and its headings may wrap. */
  .rule-head { font-size: 20px; }
  .panel { padding: 18px; }
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .victory { padding: 40px 16px 36px; }
  .victory-title { font-size: 34px; }
  .victory-inline { padding: 24px 16px; }
}

@media (max-width: 640px) {
  :root { --gutter: 16px; }
  body { font-size: 14.5px; }
  .content { padding-top: 16px; padding-bottom: 48px; }
  .view-head { margin-bottom: 24px; }
}

@media (max-width: 640px) {
  /* Small tablets: the links take the room between the wordmark and Token and X, centred in it. */
  .topbar-inner { grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; }
  .topnav { justify-self: center; }
  .brand-name { font-size: 16px; }
  .topnav a { padding: 0 8px; font-size: 13.5px; }
  .topnav a.is-active::after { left: 8px; right: 8px; }
}

/* Phones: the wordmark and the links (plus Token and X) do not fit in one row, so the links get a row of their own
   under the wordmark, spread across the width (their text lines up with the gutters). If a very narrow window still
   cannot hold them, the row scrolls sideways; the page never does. */
@media (max-width: 560px) {
  :root { --topbar-h: 84px; }
  .topbar-inner { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 44px 40px; grid-template-areas: 'brand right' 'nav nav'; column-gap: 8px; row-gap: 0; }
  .brand { grid-area: brand; }
  .topbar-right { grid-area: right; }
  .topnav { grid-area: nav; justify-self: stretch; justify-content: space-between; gap: 0; margin-inline: -8px; overflow-x: auto; scrollbar-width: none; }
  .topnav::-webkit-scrollbar { display: none; }
  .topnav a { padding: 0 8px; font-size: 14px; }
}

/* The narrowest phones (320 px and below). */
@media (max-width: 360px) {
  .topnav { margin-inline: -6px; }
  .topnav a { padding: 0 6px; font-size: 13px; }
  .topnav a.is-active::after { left: 6px; right: 6px; }
}
@media (max-width: 300px) {
  .topnav { margin-inline: -4px; }
  .topnav a { padding: 0 4px; font-size: 12px; }
  .topnav a.is-active::after { left: 4px; right: 4px; }
}
