/* ============================================================================
   Shared page styles - the single design layer behind EVERY HTML page this
   server renders (changelog, privacy policy, user portal, and whatever comes
   next).

   It is a port of the dashboard's design tokens
   (`apps/analytics-dashboard/src/index.css`) into plain CSS: same font, same
   palette, same radii, same elevation, same focus ring. The dashboard gets
   those values through Tailwind's `@theme`; this server has no build step for
   CSS, so the tokens are declared literally here and every page reads them
   through `var()`.

   RULES FOR NEW PAGES
   - Include `templates/partials/head.ejs` in the <head>. That is the whole
     hook-up: fonts, tokens, reset and primitives all arrive with it.
   - Never write a colour, font-family, shadow or radius literal in a page's
     own <style> block - reach for a token below. `pnpm pages:check`
     (blocking in CI) fails the build on a literal.
   - If a page needs a value that does not exist yet, ADD THE TOKEN HERE (and
     to the dashboard if it is a shared idea) rather than hardcoding it locally.

   THEMES
   The dashboard defaults to following the OS (`theme = 'system'`), and these
   pages have no settings UI to override it, so they follow
   `prefers-color-scheme` unconditionally. Dark is the canonical palette and is
   what `:root` declares; the light block below re-tints the same token names,
   which is why pages that stay token-driven get light mode for free.

   WHAT THIS FILE DELIBERATELY DOES NOT DO
   No global `* { margin: 0; padding: 0 }`. Two of the three pages are built on
   that reset and keep it locally; the portal is built on the UA's default
   block margins and would collapse under it. A shared sheet cannot have it
   both ways, so the opinionated half of the reset stays per page.
   ============================================================================ */

/* ============================================================================
   Fonts - self-hosted Geist, the dashboard's typeface.

   Same faces the dashboard pulls from `@fontsource-variable/geist`, but copied
   into `templates/assets/fonts/` rather than read out of node_modules: this
   server deploys standalone on Railway and its build only copies `templates/`
   (the same constraint that put the extension icons in `templates/icons/`).
   Re-copy from `node_modules/@fontsource-variable/geist{,-mono}/files/` if the
   package is upgraded.

   Only the upright latin faces ship (plus cyrillic for `ru`). The pages are
   translated into nine locales, and Geist covers none of ar/he/ja/hi - the
   `unicode-range` on each face means those scripts never request a file and
   fall through to the system stack, which is the correct outcome.
   ============================================================================ */

@font-face {
  font-family: 'Geist Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url(./fonts/geist-latin-wght-normal.woff2) format('woff2-variations');
  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: 'Geist Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url(./fonts/geist-latin-ext-wght-normal.woff2) format('woff2-variations');
  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: 'Geist Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url(./fonts/geist-cyrillic-wght-normal.woff2) format('woff2-variations');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Geist Mono Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url(./fonts/geist-mono-latin-wght-normal.woff2) format('woff2-variations');
  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;
}

/* ============================================================================
   Tokens (dark - canonical)
   ============================================================================ */

:root {
  color-scheme: dark light;

  --font-sans:
    'Geist Variable', 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    sans-serif;
  --font-mono:
    'Geist Mono Variable', 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* --- The dashboard's `--color-dark-*` scale, refresh palette. Higher number
     = darker surface. The page sits a step below the cards, which lift onto an
     elevated surface with a soft shadow. --- */
  --color-dark-50: #fafafa; /* strongest foreground text */
  --color-dark-100: #ededed; /* body text */
  --color-dark-200: #dbdbdb;
  --color-dark-300: #c8c8c8;
  --color-dark-400: #ababab; /* muted text */
  --color-dark-500: #808791; /* very muted text */
  --color-dark-600: #363b45; /* heavier borders */
  --color-dark-700: #20232a; /* inset / input / hover surface */
  --color-dark-800: #15171c; /* card surface - lifted above the page */
  --color-dark-900: #0a0b0e; /* page background - deep slate, not pure black */
  --color-dark-950: #060708;

  --color-accent-blue: #5b93ff;
  --color-accent-green: #22c55e;
  --color-accent-red: #ef4444;
  --color-accent-yellow: #eab308;
  --color-accent-purple: #a855f7;

  --border-subtle: oklch(1 0 0 / 12%);

  /* Elevation scale: resting cards -> popovers/dropdowns -> modals. */
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.7);
  --elev-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 14px 34px -14px rgba(0, 0, 0, 0.78);
  --elev-3: 0 4px 12px rgba(0, 0, 0, 0.5), 0 26px 64px -18px rgba(0, 0, 0, 0.85);

  /* Geometry. `--radius-card` is the dashboard's refresh card radius; controls
     (buttons, inputs, selects) sit at its `rounded-lg`. */
  --radius-card: 1rem;
  --radius-control: 0.5rem;
  --radius-pill: 999px;

  /* --- Semantic aliases. Pages read these, not the raw scale, so a page's CSS
     says what a colour is FOR. --- */
  --bg: var(--color-dark-900);
  --bg-elev: var(--color-dark-800);
  --bg-elev-2: var(--color-dark-700);
  --text: var(--color-dark-100);
  --text-strong: var(--color-dark-50);
  --text-dim: var(--color-dark-400);
  --text-muted: var(--color-dark-500);

  --accent: var(--color-accent-blue);
  --accent-2: var(--color-accent-purple);
  --accent-2-soft: color-mix(in srgb, var(--color-accent-purple) 13%, transparent);
  --accent-2-line: color-mix(in srgb, var(--color-accent-purple) 34%, transparent);
  --accent-soft: color-mix(in srgb, var(--color-accent-blue) 14%, transparent);
  --accent-line: color-mix(in srgb, var(--color-accent-blue) 45%, transparent);
  /* The dashboard's canonical keyboard ring: accent at 50%. */
  --accent-ring: color-mix(in srgb, var(--color-accent-blue) 50%, transparent);
  --accent-contrast: #ffffff; /* text on a filled accent button */

  --border: var(--border-subtle);
  --border-strong: var(--color-dark-600);

  --radius: var(--radius-card);
  --shadow: var(--elev-1);
  --shadow-lg: var(--elev-2);

  --success: var(--color-accent-green);
  --warning: var(--color-accent-yellow);
  --danger: var(--color-accent-red);
  --info: var(--color-accent-blue);
  --success-soft: color-mix(in srgb, var(--success) 13%, transparent);
  --warning-soft: color-mix(in srgb, var(--warning) 13%, transparent);
  --danger-soft: color-mix(in srgb, var(--danger) 13%, transparent);
  --info-soft: color-mix(in srgb, var(--info) 13%, transparent);
  --success-line: color-mix(in srgb, var(--success) 34%, transparent);
  --warning-line: color-mix(in srgb, var(--warning) 34%, transparent);
  --danger-line: color-mix(in srgb, var(--danger) 34%, transparent);
  --info-line: color-mix(in srgb, var(--info) 34%, transparent);

  /* A recess in a card (code block, meter track). Darker than the card in
     dark, lighter-gray in light - so it is theme-flipped, not a fixed black. */
  --inset: color-mix(in srgb, var(--color-dark-950) 55%, transparent);
  /* Translucent fill for a sticky bar that content scrolls under. */
  --scrim: color-mix(in srgb, var(--bg) 85%, transparent);
  /* The page-top brand wash. Reads as accent light spilling from the header. */
  --wash-1: color-mix(in srgb, var(--color-accent-blue) 16%, transparent);
  --wash-2: color-mix(in srgb, var(--color-accent-purple) 11%, transparent);
}

/* ============================================================================
   Tokens (light) - mirrors the dashboard's refresh-light palette: white cards
   floating on a soft gray page. Only the token VALUES change; no page rule is
   repeated here.
   ============================================================================ */

@media (prefers-color-scheme: light) {
  :root {
    --color-dark-50: #050505;
    --color-dark-100: #131313;
    --color-dark-200: #232323;
    --color-dark-300: #383838;
    --color-dark-400: #545454;
    --color-dark-500: #6b7280;
    --color-dark-600: #c3c8d1;
    --color-dark-700: #eceef2;
    --color-dark-800: #ffffff;
    --color-dark-900: #f3f4f7;
    --color-dark-950: #eef0f4;

    --color-accent-blue: #3b82f6;
    /* Green/yellow/red/purple are held at their dashboard values on dark, but
       these pages set body copy in them (a changelog entry's type, a policy
       callout) where the dashboard mostly uses them for dots and borders. On
       white, the 500-step yellow lands near 1.9:1. Each drops to the 600/700
       step of the SAME hue for text legibility; nothing else moves. */
    --color-accent-green: #16a34a;
    --color-accent-yellow: #a16207;
    --color-accent-red: #dc2626;
    --color-accent-purple: #9333ea;

    --border-subtle: oklch(0 0 0 / 8%);

    --elev-1: 0 1px 2px rgba(15, 23, 42, 0.05), 0 8px 24px -12px rgba(15, 23, 42, 0.18);
    --elev-2: 0 2px 6px rgba(15, 23, 42, 0.08), 0 14px 34px -14px rgba(15, 23, 42, 0.22);
    --elev-3: 0 4px 12px rgba(15, 23, 42, 0.1), 0 26px 64px -18px rgba(15, 23, 42, 0.28);

    --inset: color-mix(in srgb, var(--color-dark-700) 70%, transparent);
  }
}

/* ============================================================================
   Base - the half of the reset every page can share, plus the app-wide
   defaults (typography, focus ring, scrollbar) the dashboard applies in its
   own base layer.
   ============================================================================ */

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: inherit;
}

code,
kbd,
pre,
samp {
  font-family: var(--font-mono);
}

/* The dashboard's keyboard-focus floor: every interactive element gets a
   visible indicator, in the accent, offset from the control. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-control);
}

::selection {
  background: var(--accent-soft);
}

/* Custom scrollbar - matches the dashboard's 8px themed bar. */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: var(--bg-elev);
}

::-webkit-scrollbar-thumb {
  background: var(--color-dark-600);
  border-radius: var(--radius-pill);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--color-dark-500);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================================
   Primitives (`.aug-*`)

   The dashboard's component recipes, transcribed for a page with no React and
   no Tailwind. A NEW page should build out of these and add only what is
   genuinely its own; the three pages that predate this file keep their own
   class names and read the tokens above instead (see docs/server-page-styling.md).
   ============================================================================ */

/* Page column. `--aug-shell-max` is per page - a form reads best narrow, a
   board of cards should use the window. */
.aug-shell {
  width: 100%;
  max-width: var(--aug-shell-max, 960px);
  margin: 0 auto;
  padding-inline: 1.5rem;
}

/* bg-dark-800 border border-dark-600 rounded-xl p-6, plus the refresh
   elevation the dashboard gives every resting card. */
.aug-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}

/* The interactive-card affordance: only cards that are themselves a link or a
   button lift, so static panels stay still. */
a.aug-card,
button.aug-card {
  display: block;
  text-decoration: none;
  transition:
    border-color 200ms ease,
    box-shadow 200ms ease,
    transform 200ms ease;
}

a.aug-card:hover,
button.aug-card:hover {
  border-color: var(--accent-line);
  box-shadow: var(--shadow-lg);
}

@media (prefers-reduced-motion: no-preference) {
  a.aug-card:hover,
  button.aug-card:hover {
    transform: translateY(-2px);
  }
}

/* buttonClass() from the dashboard: inline-flex, gap-2, rounded-lg, px-4 py-2,
   text-sm, font-medium, and the canonical focus ring. */
.aug-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.25rem;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color 150ms ease,
    color 150ms ease,
    border-color 150ms ease;
}

/* `sm` - the in-card / toolbar size. */
.aug-btn--sm {
  padding: 0.375rem 0.75rem;
}

.aug-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--accent-ring);
}

.aug-btn:disabled,
.aug-btn[aria-disabled='true'] {
  opacity: 0.5;
  cursor: not-allowed;
}

.aug-btn--primary {
  background: var(--accent);
  color: var(--accent-contrast);
}

.aug-btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 80%, transparent);
}

.aug-btn--secondary {
  background: var(--bg-elev-2);
  color: var(--color-dark-200);
  border-color: var(--border);
}

.aug-btn--secondary:hover:not(:disabled) {
  background: var(--color-dark-600);
  color: var(--color-dark-100);
}

.aug-btn--danger {
  background: var(--danger);
  color: var(--accent-contrast);
}

.aug-btn--danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger) 80%, transparent);
}

.aug-btn--quiet {
  background: transparent;
  color: var(--color-dark-300);
}

.aug-btn--quiet:hover:not(:disabled) {
  background: color-mix(in srgb, var(--bg-elev-2) 50%, transparent);
  color: var(--color-dark-100);
}

/* Form controls, from the dashboard's shared filter-control recipe. */
.aug-input,
.aug-select {
  min-width: 0;
  padding: 0.375rem 0.75rem;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  color: var(--color-dark-200);
  font-family: inherit;
  font-size: 0.875rem;
}

.aug-input:focus-visible,
.aug-select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-ring);
}

/* Status pill. Pair with a `--<status>` modifier or set `--pill` locally. */
.aug-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--pill-line, var(--border));
  border-radius: var(--radius-pill);
  background: var(--pill-soft, var(--bg-elev-2));
  color: var(--pill, var(--text-dim));
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
}

.aug-badge--success {
  --pill: var(--success);
  --pill-soft: var(--success-soft);
  --pill-line: var(--success-line);
}

.aug-badge--warning {
  --pill: var(--warning);
  --pill-soft: var(--warning-soft);
  --pill-line: var(--warning-line);
}

.aug-badge--danger {
  --pill: var(--danger);
  --pill-soft: var(--danger-soft);
  --pill-line: var(--danger-line);
}

.aug-badge--info {
  --pill: var(--info);
  --pill-soft: var(--info-soft);
  --pill-line: var(--info-line);
}

/* Data table - the dashboard's `TABLE_TH_CLASS` / `TABLE_ROW_CLASS`. */
.aug-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.aug-table th {
  padding: 0.75rem 1rem;
  color: var(--text-dim);
  font-weight: 500;
  text-align: start;
}

.aug-table td {
  padding: 0.75rem 1rem;
}

.aug-table tbody tr {
  border-bottom: 1px solid var(--border);
  transition: background-color 150ms ease;
}

.aug-table tbody tr:hover {
  background: color-mix(in srgb, var(--bg-elev-2) 40%, transparent);
}

/* Inline code / identifiers (a UID, a version). */
.aug-mono {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.aug-muted {
  color: var(--text-muted);
}
