/* ============================================================
   THE FACES — self-hosted, first-party, no third party in the critical path.
   ============================================================

   These used to be a `<link>` to fonts.googleapis.com in index.html. That cost
   TWO extra origins and TWO SERIAL round trips before a single glyph could
   start downloading: the woff2 URLs live INSIDE Google's stylesheet, so the
   font could not begin until that stylesheet had been fetched and parsed, over
   a connection that had to be opened, TLS-negotiated and DNS-resolved first. On
   the throttled profile the deploy is measured against (1.6 Mbps / 562 ms RTT)
   that was the floor under first contentful paint once the JS was deferred —
   the bundle work landed in 896d979 and left the fonts as the last blocker.

   The old justification for the CDN — "everybody already has Google Fonts
   cached" — died when browsers partitioned their HTTP caches by top-level site
   around 2020. A first-time visitor to this game shares nothing with anyone.

   Both families are SIL Open Font License 1.1, so hosting them ourselves is
   permitted; the licences ship beside the binaries in public/fonts/.

   WHAT IS HERE, and why it is 42 files:

     Alegreya       — ONE VARIABLE roman (400..800) + ONE VARIABLE italic
                      (400..700). A variable face covers every weight the design
                      system asks for in a single file, so the serif costs one
                      download, not four.
     Alegreya Sans  — 400 / 500 / 700 + a 400 italic, as STATIC faces. Google
                      does not publish a variable Alegreya Sans, so this is the
                      exact set the old `css2?family=` URL requested; nothing
                      about how type renders has changed.

   Six faces times seven unicode subsets = 42. This mirrors Google's own subset
   split rather than flattening it, and that is deliberate: `unicode-range` means
   a browser downloads a subset ONLY if the page actually contains a character
   in it. A Latin player fetches the latin file and nothing else, while a player
   whose NAME is Cyrillic — names and chat are user-entered and we do not get to
   assume an alphabet — still gets real Alegreya instead of a fallback face.
   Dropping the non-Latin subsets to save repository bytes would have saved zero
   RUNTIME bytes and cost exactly those players their type.

   font-display: swap, NOT block. `block` lays the page out with INVISIBLE text,
   which reads as a broken page, and it is not needed here: src/main.ts holds the
   app's own reveal behind a bounded wait on the chrome face, so during the hold
   the player sees the brand backdrop rather than a flash or a blank. `swap` is
   the correct partner for that gate — it guarantees that if the gate's timeout
   fires (a stalled or 404'd font), text still PAINTS in the fallback and then
   upgrades, so a font problem can never become a blank screen.

   The `src` URLs are RELATIVE (`../fonts/…`), not absolute `/fonts/…`. The app
   is served from the `/play/` subpath and an absolute path would resolve to
   `/fonts/…` on the deploy — the same trailing-slash trap the Caddyfile warns
   about for item icons, and it would 404 every face silently.
   ============================================================ */

/* Alegreya italic 400 700 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya italic 400 700 — cyrillic */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya italic 400 700 — greek-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya italic 400 700 — greek */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya italic 400 700 — vietnamese */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya italic 400 700 — latin-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-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;
}

/* Alegreya italic 400 700 — latin */
@font-face {
  font-family: 'Alegreya';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/alegreya-var-italic-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;
}

/* Alegreya normal 400 800 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya normal 400 800 — cyrillic */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya normal 400 800 — greek-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya normal 400 800 — greek */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya normal 400 800 — vietnamese */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya normal 400 800 — latin-ext */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-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;
}

/* Alegreya normal 400 800 — latin */
@font-face {
  font-family: 'Alegreya';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/alegreya-var-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;
}

/* Alegreya Sans italic 400 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya Sans italic 400 — cyrillic */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya Sans italic 400 — greek-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya Sans italic 400 — greek */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya Sans italic 400 — vietnamese */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya Sans italic 400 — latin-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-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;
}

/* Alegreya Sans italic 400 — latin */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-italic-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;
}

/* Alegreya Sans normal 400 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya Sans normal 400 — cyrillic */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya Sans normal 400 — greek-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya Sans normal 400 — greek */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya Sans normal 400 — vietnamese */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya Sans normal 400 — latin-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-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;
}

/* Alegreya Sans normal 400 — latin */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/alegreya-sans-400-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;
}

/* Alegreya Sans normal 500 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya Sans normal 500 — cyrillic */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya Sans normal 500 — greek-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya Sans normal 500 — greek */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya Sans normal 500 — vietnamese */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya Sans normal 500 — latin-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-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;
}

/* Alegreya Sans normal 500 — latin */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/alegreya-sans-500-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;
}

/* Alegreya Sans normal 700 — cyrillic-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* Alegreya Sans normal 700 — cyrillic */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Alegreya Sans normal 700 — greek-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-greek-ext.woff2') format('woff2');
  unicode-range: U+1F00-1FFF;
}

/* Alegreya Sans normal 700 — greek */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-greek.woff2') format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

/* Alegreya Sans normal 700 — vietnamese */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

/* Alegreya Sans normal 700 — latin-ext */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-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;
}

/* Alegreya Sans normal 700 — latin */
@font-face {
  font-family: 'Alegreya Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/alegreya-sans-700-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;
}
/* ============================================================
   VALICIA ONLINE — the house style
   Royal indigo · antique gold · parchment
   ============================================================

   Every colour below is SAMPLED FROM THE LOGO (references/Valicia Online
   Logo.png), not chosen to taste — the wordmark is the one piece of art the
   whole product is named after, so it is the authority on what the brand looks
   like and the UI matches it rather than the other way round.

   The three families, and what each is FOR:

     indigo (--space-*)   every surface. The logo's crest sits on a near-black
                          royal indigo; so does the game.
     gold   (--gold-*)    the frame, and anything the eye must land on. It is a
                          warm antique gold with a parchment highlight, NOT a
                          yellow — the wordmark's letters are aged vellum.
     violet (--violet-*)  the arcane accent, and the cool half of the frame
                          trim. It replaced a mint teal that came from an older
                          identity: the logo has no teal anywhere in it, and one
                          cool accent that is not in the artwork was enough to
                          make the whole UI read as belonging to a different
                          game. All 17 `var(--teal*)` uses were remapped onto
                          the violet ramp rather than being recoloured in place,
                          so nothing is left named after a colour it is not.
   ============================================================ */

:root {
  /* ---- Palette ---- */

  /* Background — the logo's royal indigo. Sampled: its darkest field is #0c0c18 and the crest's
     shadowed stonework sits around #271e53 / #202750, which is what the raised surfaces use. */
  --space-0:        #070613;     /* deepest, behind everything */
  --space-1:        #0f0d24;     /* main page bg */
  --space-2:        #171338;     /* card matting */
  --space-3:        #221c50;     /* raised */
  --space-4:        #322a72;     /* hover / accent backdrop */

  /* Frosted glass surfaces */
  --glass:          rgba(255, 255, 255, 0.03);
  --glass-hi:       rgba(255, 255, 255, 0.07);
  /* 0.78, not the 0.55 it was. "Deep" glass backs the status block, the action bar and the minimap
     — all of which sit directly on the WORLD. At 55% the meadow's green came through strongly
     enough to turn the indigo panel olive, so the one piece of chrome that must be readable at a
     glance took its colour from whatever the player happened to be standing on. */
  --glass-deep:     rgba(9, 7, 26, 0.78);
  --glass-stroke:   rgba(255, 255, 255, 0.10);
  /* CHROME — the fill for anything that sits directly on the WORLD (status block, chat, minimap)
     rather than over a dimmed backdrop.
     Deliberately near-opaque. Frosted glass is a lovely idea over a neutral page and a bad one over
     a saturated meadow: measured, the status block came out #3d5209, an olive that is mostly the
     grass underneath it plus the panel's own gold inner glow. Chrome whose colour is decided by
     whatever the player is standing on is not chrome, and on a green map it stopped being the
     brand's indigo altogether. */
  --chrome:         rgba(13, 10, 34, 0.93);
  --glass-stroke-hi:rgba(255, 255, 255, 0.20);

  /* Text */
  /* PARCHMENT, not white. The wordmark's letters are aged vellum (#dfbb95 in shadow, near-cream at
     the highlight), and a pure cool white next to that gold reads as a different product. */
  --ink:            #f4ecdc;     /* primary */
  --ink-soft:       #cbc2de;
  --ink-mute:       #918aad;
  --ink-quill:      #c0b7d6;     /* italic flavor */

  /* Accents */
  /* Antique gold. Warmer and a touch redder than the old #e6c46d, matching the logo's trim
     (sampled #dfbb95 light / #956b48 mid / #5e3a23 deep). */
  --gold:           #c9a46e;     /* antique bronze-gold, NOT a yellow */
  --gold-hi:        #efdcbb;     /* champagne highlight — the wordmark's lit edge */
  --gold-deep:      #7d5a2e;
  --gold-glow:      rgba(201, 164, 110, 0.40);

  /* ---- Ornate frame trim (gold + crystal-teal filigree) ---- */
  /* the signature carved-frame gradient: warm gold corners bleeding into cool crystal-teal */
  --frame-gold:     #c9a46e;
  --frame-violet:   #9a86e8;
  --frame-trim:     linear-gradient(135deg,
                      var(--gold-hi) 0%, var(--gold) 18%, var(--gold-deep) 34%,
                      var(--violet-deep) 50%, var(--violet) 66%, var(--gold-deep) 82%,
                      var(--gold) 100%);
  --frame-trim-soft: linear-gradient(135deg,
                      rgba(201,164,110,.85) 0%, rgba(125,90,46,.6) 40%,
                      rgba(82,70,150,.6) 60%, rgba(201,189,255,.85) 100%);
  --frame-inner-glow: 0 0 0 1px rgba(201,164,110,.18) inset,
                      0 0 22px -6px rgba(201,164,110,.30) inset,
                      0 0 34px -10px rgba(154,134,232,.30) inset;
  /* 8 layers = small L-bracket flourishes at each corner. Painted with default
     background-attachment (fixed to the element's box), so they stay put even
     when a panel's content scrolls. Compose in front of the panel fill:
       background: var(--frame-corners), <fill> padding-box, var(--frame-trim) border-box; */
  --frame-corners:
    linear-gradient(var(--frame-gold),var(--frame-gold)) 9px 7px/15px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 7px 9px/2px 15px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 9px) 7px/15px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 7px) 9px/2px 15px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 9px calc(100% - 7px)/15px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 7px calc(100% - 9px)/2px 15px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 9px) calc(100% - 7px)/15px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 7px) calc(100% - 9px)/2px 15px no-repeat;
  /* compact corner brackets for small chrome (status / minimap): 10px arms, tighter inset */
  --frame-corners-sm:
    linear-gradient(var(--frame-gold),var(--frame-gold)) 5px 4px/10px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 4px 5px/2px 10px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 5px) 4px/10px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 4px) 5px/2px 10px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 5px calc(100% - 4px)/10px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) 4px calc(100% - 5px)/2px 10px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 5px) calc(100% - 4px)/10px 2px no-repeat,
    linear-gradient(var(--frame-gold),var(--frame-gold)) calc(100% - 4px) calc(100% - 5px)/2px 10px no-repeat;

  /* THE cool accent, and the cool half of the frame trim. Sampled from the logo's laurel leaves and
     the crest's violet banners (#524696 mid, #8ea0d2 light, #271e53 dark). */
  --violet:         #9a86e8;     /* arcane */
  --violet-hi:      #c9bdff;
  --violet-deep:    #524696;
  --violet-glow:    rgba(154, 134, 232, 0.45);

  /* Signal colors */
  --hp:             #ff8095;     /* HP */
  --hp-deep:        #a83a4f;
  --hp-soft:        rgba(255, 128, 149, 0.18);

  --sp:             #74b8ff;     /* SP / mana */
  --sp-deep:        #2962b8;
  --sp-soft:        rgba(116, 184, 255, 0.18);

  --amber:          #ffc564;     /* AP / energy */
  --amber-deep:     #b88322;
  --amber-soft:     rgba(255, 197, 100, 0.18);

  --xp:             #c5a8ff;     /* XP */
  --xp-deep:        #7253c4;
  --xp-soft:        rgba(197, 168, 255, 0.18);

  --rose:           #ff8095;     /* alias for HP-tone usage */
  --rose-deep:      #a83a4f;
  --rose-soft:      rgba(255, 128, 149, 0.18);

  --sage:           #92e0ad;     /* positive */
  --sage-deep:      #2c8a52;
  --sage-soft:      rgba(146, 224, 173, 0.18);

  --ember:          #ff7a52;     /* danger / critical */
  --ember-deep:     #a82d10;
  --ember-soft:     rgba(255, 122, 82, 0.18);

  /* ---- Type ---- */
  /* ONE SUPERFAMILY, TWO VOICES: Alegreya and Alegreya Sans.
     PROSE — names, titles, dialogue, item descriptions — is Alegreya, a humanist serif designed for
     long-form reading with a calligraphic, slightly restless texture. It has warmth and a hand
     behind it, which is what the world's own writing needs.
     CHROME — every label, tag, counter, stat readout and HP number — is Alegreya Sans: the same
     skeleton without the serifs, so the HUD is unmistakably the same type system as the prose while
     staying crisp at the 10-12px the interface actually runs at.
     THIS IS THE THIRD TYPE SYSTEM HERE AND THE REASONS THE FIRST TWO WENT ARE WORTH KEEPING:
       - Cinzel + Spectral was replaced for looking TEMPLATED. Cinzel is the default fantasy
         webfont, what every generated "medieval" layout reaches for. Outfit/Inter went the same way.
       - IM Fell English + Pixelify Sans replaced it and was replaced in turn for being HARD TO
         READ, which is the failure that matters most. IM Fell is a 17th-century digitisation:
         irregular stems, low x-height, ink-spread — beautiful in a specimen, punishing in a 13px
         item description. And a pixel face has no hinting, so every label under ~11px greyed into
         mush; raising the floor to 11px treated the symptom and left the cause.
     The lesson both times: distinctiveness is worth nothing if the player cannot read the number.
     Alegreya is not a defaults-list pick — it is a text face with real character — but it is a TEXT
     face first, and legibility is the constraint it was designed against.
     Sizes: nothing in the interface is set below 11px. That floor started as a pixel-font
     workaround and is kept because it was right on its own terms. */
  --font-display:   "Alegreya", "Iowan Old Style", Georgia, serif;
  --font-banner:    "Alegreya Sans", "Segoe UI", system-ui, sans-serif;   /* uppercase + tracking */
  --font-body:      "Alegreya", "Iowan Old Style", Georgia, serif;
  --font-quill:     "Alegreya", Georgia, serif;                   /* italic flavor */
  /* Numerals that must line up in a column. Alegreya Sans ships tabular figures; the `.t-mono` and
     readout rules opt into them with font-variant-numeric, so a stat column aligns without dropping
     out of the type system into a developer-tooling monospace. */
  --font-mono:      "Alegreya Sans", "Segoe UI", system-ui, sans-serif;

  /* ---- Spacing ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;

  /* ---- Radii (modern: gentle, consistent) ---- */
  --r-1: 4px;
  --r-2: 8px;
  --r-3: 14px;
  --r-4: 20px;
  --r-pill: 999px;
}

/* ============================================================
   Base
   ============================================================ */
* { box-sizing: border-box; }

/* Cosmic backdrop — layered: deep base + 2 nebulae + starfield */
.rpg-cosmos {
  position: relative;
  min-height: 100vh;
  background:
    /* violet nebula bloom top-left */
    radial-gradient(900px 600px at 12% -10%, rgba(106, 78, 198, 0.40) 0%, transparent 60%),
    /* teal nebula bottom-right */
    radial-gradient(1100px 700px at 95% 110%, rgba(47, 138, 130, 0.32) 0%, transparent 60%),
    /* core */
    radial-gradient(1400px 900px at 50% 30%, #161c45 0%, #0a0d28 70%),
    linear-gradient(180deg, #0a0d28 0%, #07091a 100%);
  background-attachment: fixed;
}
/* starfield overlay — three densities */
.rpg-cosmos::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    /* big stars */
    radial-gradient(1.2px 1.2px at 12% 18%, rgba(255,255,255,0.85) 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 78% 32%, rgba(255,236,200,0.85) 50%, transparent 100%),
    radial-gradient(1.2px 1.2px at 45% 75%, rgba(220,210,255,0.85) 50%, transparent 100%),
    radial-gradient(1.4px 1.4px at 88% 88%, rgba(255,255,255,0.85) 50%, transparent 100%),
    radial-gradient(1.2px 1.2px at 6% 62%, rgba(190,220,255,0.85) 50%, transparent 100%),
    radial-gradient(1.6px 1.6px at 62% 8%, rgba(255,255,255,0.95) 50%, transparent 100%),
    radial-gradient(1.3px 1.3px at 25% 92%, rgba(255,236,200,0.8) 50%, transparent 100%),
    /* small dust */
    radial-gradient(0.6px 0.6px at 35% 25%, rgba(255,255,255,0.6) 50%, transparent 100%),
    radial-gradient(0.6px 0.6px at 70% 60%, rgba(255,255,255,0.6) 50%, transparent 100%),
    radial-gradient(0.6px 0.6px at 18% 80%, rgba(255,255,255,0.6) 50%, transparent 100%),
    radial-gradient(0.6px 0.6px at 92% 22%, rgba(255,255,255,0.6) 50%, transparent 100%),
    radial-gradient(0.6px 0.6px at 50% 50%, rgba(255,255,255,0.5) 50%, transparent 100%),
    radial-gradient(0.5px 0.5px at 8% 35%, rgba(255,255,255,0.5) 50%, transparent 100%),
    radial-gradient(0.5px 0.5px at 82% 72%, rgba(255,255,255,0.5) 50%, transparent 100%);
  background-size: 100% 100%;
  opacity: 0.9;
}
/* faint grid — like a celestial sphere graticule */
.rpg-cosmos::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.025) 50%, transparent 100%);
  background-size: 200px 100%;
  background-repeat: repeat-x;
  opacity: 0.6;
}

/* ============================================================
   Document chrome
   ============================================================ */

.doc {
  position: relative;
  z-index: 1;
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5) var(--sp-8);
}

.doc-header {
  text-align: center;
  margin-bottom: var(--sp-7);
  position: relative;
}
.doc-eyebrow {
  font-family: var(--font-banner);
  font-size: 12px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--violet);
  margin: 0 0 var(--sp-4);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
}
.doc-eyebrow svg { width: 14px; height: 14px; color: var(--gold); }

.doc-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 96px;
  line-height: 0.95;
  margin: 0;
  color: var(--ink);
  letter-spacing: -0.01em;
  text-shadow: 0 0 60px rgba(184, 155, 255, 0.25);
}
.doc-title .accent {
  font-style: italic;
  color: var(--gold);
  background: linear-gradient(180deg, var(--gold-hi) 0%, var(--gold) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.doc-subtitle {
  font-family: var(--font-body);
  font-size: 19px;
  font-weight: 300;
  color: var(--ink-soft);
  margin: var(--sp-5) auto 0;
  max-width: 680px;
  text-wrap: balance;
  letter-spacing: 0.01em;
}

/* Section heading */
.section-mark {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
}
.section-mark svg { width: 16px; height: 16px; color: var(--gold); }
.section-eyebrow {
  font-family: var(--font-banner);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--violet);
  margin: 0;
}
.section-title {
  font-family: var(--font-display);
  font-size: 56px;
  font-weight: 400;
  margin: 0 0 var(--sp-3);
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.005em;
}
.section-desc {
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 300;
  color: var(--ink-soft);
  margin: 0 0 var(--sp-6);
  max-width: 760px;
  text-wrap: pretty;
  line-height: 1.6;
}

/* ============================================================
   Constellation dividers — the recurring motif
   ============================================================ */
.constellation {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  margin: var(--sp-8) auto;
  color: var(--gold);
  opacity: 0.7;
}
.constellation::before,
.constellation::after {
  content: "";
  flex: 1;
  height: 1px;
  max-width: 280px;
  background: linear-gradient(90deg, transparent, var(--gold-glow) 40%, var(--gold-glow) 60%, transparent);
}
.constellation svg { width: 56px; height: 24px; }

/* Hairline horizontal rule, used inside panels */
.line-rule {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--glass-stroke-hi) 30%, var(--glass-stroke-hi) 70%, transparent);
  margin: var(--sp-4) 0;
  position: relative;
}
.line-rule.has-dot::after {
  content: "✦";
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-size: 10px;
  color: var(--gold);
  background: var(--space-1);
  padding: 0 8px;
  line-height: 1;
}

/* ============================================================
   .panel — frosted glass surface with luminous hairline border
   ============================================================ */
.panel {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.045) 0%, rgba(255,255,255,0.015) 100%),
    var(--space-2);
  border: 1px solid var(--glass-stroke);
  border-radius: var(--r-3);
  padding: var(--sp-5);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(255, 255, 255, 0.02) inset,
    0 20px 50px -20px rgba(0, 0, 0, 0.5),
    0 4px 10px -4px rgba(0, 0, 0, 0.3);
}
/* subtle inner glow on the top edge */
.panel::before {
  content: "";
  position: absolute;
  top: 0; left: 8%; right: 8%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25) 50%, transparent);
  pointer-events: none;
}
.panel--flat {
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow:
    0 0 0 1px var(--glass-stroke) inset,
    0 4px 12px -4px rgba(0, 0, 0, 0.4);
  padding: var(--sp-4);
}
.panel--quiet {
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--glass-stroke);
  padding: var(--sp-4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: none;
}

/* Corner sigil ornaments — luminous rune-like marks */
.panel > .corners { position: absolute; inset: 0; pointer-events: none; }
.panel > .corners svg {
  position: absolute; width: 18px; height: 18px;
  color: var(--gold);
  opacity: 0.7;
  filter: drop-shadow(0 0 4px var(--gold-glow));
}
.panel > .corners svg:nth-child(1) { top: 10px;    left: 10px; }
.panel > .corners svg:nth-child(2) { top: 10px;    right: 10px;  transform: scaleX(-1); }
.panel > .corners svg:nth-child(3) { bottom: 10px; left: 10px;   transform: scaleY(-1); }
.panel > .corners svg:nth-child(4) { bottom: 10px; right: 10px;  transform: scale(-1,-1); }

/* ============================================================
   Buttons — luminous with subtle glow
   ============================================================ */
.btn {
  font-family: var(--font-banner);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--glass-hi);
  border: 1px solid var(--glass-stroke-hi);
  border-radius: var(--r-pill);
  padding: 11px 22px;
  cursor: pointer;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
  box-shadow: 0 1px 0 rgba(255,255,255,0.06) inset, 0 2px 8px -2px rgba(0,0,0,0.4);
}
.btn:hover {
  transform: translateY(-1px);
  background: rgba(255,255,255,0.10);
  box-shadow: 0 1px 0 rgba(255,255,255,0.10) inset, 0 6px 14px -4px rgba(0,0,0,0.5);
}
.btn:active { transform: translateY(0); }

/* Primary — a CARVED slab with a gilded rim.
 *
 * It was a luminous yellow gradient with a white shine along the top, which is the single most
 * generic button in interface design and has no counterpart in the logo: that gold reads as metal
 * because it is DARK WITH A LIT EDGE, not because it is bright. So the fill is the same obsidian
 * the panels are cut from, the rim is gilded, and the only light is the hairline where a bevel
 * would catch the sun. Matches .v-btn in src/ui/brandStyles.ts, which the pre-game screens use. */
.btn--primary {
  color: var(--gold-hi);
  background: linear-gradient(180deg, #2b2360 0%, #1b1642 55%, #120e30 100%);
  border: 1px solid var(--gold-deep);
  text-shadow: 0 1px 2px rgba(0,0,0,0.8);
  box-shadow:
    0 1px 0 rgba(239,220,187,0.22) inset,
    0 -1px 0 rgba(0,0,0,0.5) inset,
    0 8px 22px -10px rgba(0,0,0,0.7);
}
.btn--primary:hover {
  color: #fff4de;
  border-color: var(--gold);
  background: linear-gradient(180deg, #3a2f7d 0%, #241d54 55%, #16113a 100%);
  box-shadow:
    0 1px 0 rgba(239,220,187,0.34) inset,
    0 -1px 0 rgba(0,0,0,0.5) inset,
    0 0 22px -6px var(--gold-glow),
    0 10px 24px -10px rgba(0,0,0,0.85);
}

/* Violet — secondary action. The same slab, rimmed in violet instead of gold: whether the edge is
   METAL is what separates the primary from everything else, and it survives the two sitting side
   by side far better than size or hue would. */
.btn--violet,
.btn--teal {          /* legacy alias: the class shipped before the accent was rebranded */
  color: var(--violet-hi);
  background: linear-gradient(180deg, rgba(60,50,130,.34), rgba(20,16,48,.5));
  border: 1px solid rgba(154,134,232,.30);
  box-shadow: none;
}

/* Danger */
.btn--danger {
  color: #fff;
  background: linear-gradient(180deg, #ff8d72 0%, var(--ember-deep) 100%);
  border: 1px solid #ffb39e;
  box-shadow: 0 0 22px rgba(255, 122, 82, 0.35), 0 6px 14px -4px rgba(0,0,0,0.5);
}

/* Ghost — glass outline */
.btn--ghost {
  background: transparent;
  border: 1px solid var(--glass-stroke-hi);
  color: var(--ink-soft);
  box-shadow: none;
}
.btn--ghost:hover {
  background: var(--glass);
  color: var(--ink);
}

.btn[disabled] {
  cursor: not-allowed;
  opacity: 0.4;
  filter: grayscale(0.6) brightness(0.85);
  transform: none !important;
  box-shadow: 0 0 0 1px var(--glass-stroke) inset !important;
}

.btn--small  { padding: 7px 14px; font-size: 11px; }
.btn--xsmall { padding: 5px 10px; font-size: 11px; }   /* 11px = the interface floor, see the type note */

/* ============================================================
   Type utilities
   ============================================================ */
.t-display    { font-family: var(--font-display); }
.t-banner     { font-family: var(--font-banner); font-weight: 500; letter-spacing: .16em; text-transform: uppercase; }
.t-quill      { font-family: var(--font-quill); font-style: italic; color: var(--ink-quill); }
.t-meta       { font-family: var(--font-banner); font-weight: 500; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--violet); }
/* Numbers are CHROME, not prose: the prose serif draws '1' as a bare stem and has no tabular
   figures, so a column of values in it neither aligns nor disambiguates. */
.t-num        { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.t-mono       { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.t-soft       { color: var(--ink-soft); }
.t-mute       { color: var(--ink-mute); }
.t-gold       { color: var(--gold); }
.t-teal       { color: var(--violet); }
.t-violet     { color: var(--violet); }

/* Code chip */
.code-chip {
  font-family: var(--font-mono);
  font-size: 12px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--glass-stroke);
  padding: 1px 7px;
  border-radius: 4px;
  color: var(--violet-hi);
}
