/* ARIA design tokens — visual refinement 2026-08-07 (master brief: private-beta
   visual refinement). One sheet shared by every screen: Login, Projects, Script
   Editor, Workbench. Theme = light (default) / dark via <html data-theme="dark">,
   persisted under the shared localStorage key "aria_theme".

   MASTER MARK: the circular AUF WASSEN face emblem shipped at
   static/aria_mark_disc.png is the permanent identity. It is never redrawn,
   recolored or replaced — only placed small and calm in the brand area. Every
   red in this sheet is sampled FROM that emblem (its crescent reads ~#820708);
   there are no orange accents anywhere in the system.

   TYPEFACE NOTE: the brief calls for a DIN-inspired human-industrial system.
   No DIN license ships with this repo and nothing unlicensed may be embedded,
   so the type stack stays on self-hosted Hanken Grotesk (OFL) — an open,
   engineered, warm humanist grotesque with DIN-adjacent proportions, and the
   only face that renders identically for every tester on every OS.
   RECOMMENDED WHEN BUDGET ALLOWS: license DIN Next LT Pro, Theinhardt, or
   ABC Diatype and swap --font-ui; nothing else in the system needs to change.
   Weight discipline is enforced here: headings/nav/key labels use 700 (Bold)
   only — never 800/900, never thin or condensed display cuts. */

/* Self-hosted brand fonts (OFL) — the product runs local-first and must not
   depend on Google Fonts being reachable. Latin subsets. */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/hanken-grotesk-latin-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/courier-prime-latin-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Courier Prime';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/courier-prime-latin-700.woff2') format('woff2');
}

:root {
  /* ---- brand (fixed in both themes) ---- */
  --ink-brand: #171614;
  --paper-brand: #EFEDE8;
  --oxblood: #7B0A0A;
  --oxblood-border: #4A0707;
  /* The disciplined red, sampled from the emblem's crescent. Used ONLY for
     meaningful states, active navigation and key rules. 7.7:1 on the light
     base — it carries information, so it must stay readable. */
  --red: #8C0A0B;
  --red-hover: #6E0708;
  /* `--gold` / `--gold-dark` are legacy token NAMES kept so no screen loses a
     rule while the orange they used to carry is gone for good: --gold now
     resolves to the disciplined red (states, active nav, key rules) and
     --gold-dark to a warm graphite for quiet labels. Renaming the tokens
     would touch ~80 call sites for zero visual gain. */
  --gold: #8C0A0B;
  --gold-dark: #5C574F;
  --green: #2E7D32;
  --error-text: #E2726B;
  --near-black: #151412;
  --auth-card: #1A1918;
  --input-border-dark: #3A3833;
  --dark-muted: #A29C93;

  /* ---- light theme: the base material ----
     Warm smoke-gray / pewter with a satin-vinyl quiet. Not paper, not dark
     mode, not a gradient: a calm tactile ground that lets red mean something. */
  --bg: #E7E5E0;
  --card: #EFEEEA;
  --card2: #EAE8E3;
  --edit: #F2F0EB;
  --sel: #DCD9D2;
  --ink: #1A1917;
  --title: #1A1917;
  --muted: #5C574F;
  --faint: #7C776F;
  --line: #D0CCC4;
  --line2: #DEDAD3;
  /* Texture is discovered, never seen first. */
  --grain-opacity: .014;
  --grain-blend: multiply;
  --halftone-ink: rgba(26, 25, 23, .30);

  /* ---- type ---- */
  --font-ui: 'Hanken Grotesk', system-ui, sans-serif;
  --font-mono: ui-monospace, Menlo, monospace;
  --font-screenplay: 'Courier Prime', 'Courier New', monospace;
}

[data-theme="dark"] {
  --bg: #191817;
  --card: #232220;
  --card2: #1F1E1C;
  --edit: #2A2825;
  --sel: #2C2A27;
  --ink: #E9E6E0;
  --title: #D8D5CE;
  --muted: #9E998F;
  --faint: #6E6A62;
  --line: #35332F;
  --line2: #272522;
  --grain-opacity: .022;
  --grain-blend: screen;
  --halftone-ink: rgba(233, 230, 224, .22);
  /* The emblem red is too dark to read on a dark ground, so the dark theme
     uses a lifted TINT of the same red (4.1:1) — same hue family, still no
     orange anywhere. */
  --red: #D2504E;
  --red-hover: #E0645F;
  --gold: #D2504E;
  --gold-dark: #A29C93;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}
::selection { background: var(--red); color: var(--paper-brand); }

/* ---- motion language (no bouncy easing) ---- */
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: scale(.98) translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes markBreath { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes sweep { 0% { transform: translateX(-260%); } 100% { transform: translateX(640%); } }
@keyframes barGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.fade-up { animation: fadeUp .45s cubic-bezier(.2,.7,.3,1) both; }

/* ---- surface texture (fixed, per-theme blend/opacity) ----
   Dialled far down from the previous film-grain wash: at this opacity it reads
   as the tooth of the material, not as an effect laid over the product. */
.grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 60;
  opacity: var(--grain-opacity); mix-blend-mode: var(--grain-blend);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="2"/></filter><rect width="100%25" height="100%25" filter="url(%23n)"/></svg>');
}

/* ---- Ben-Day halftone, for TINY portions of a divider only ----
   A print-shop dot screen that fades out within ~110px. Applied to a handful
   of rules so the eye finds it on the second pass, never the first. */
.halftone-rule {
  position: relative;
}
.halftone-rule::after {
  content: ""; position: absolute; left: 0; bottom: -1px; width: 108px; height: 3px;
  pointer-events: none; opacity: .5;
  background-image: radial-gradient(var(--halftone-ink) 34%, transparent 36%);
  background-size: 3px 3px;
  -webkit-mask-image: linear-gradient(90deg, #000, transparent);
  mask-image: linear-gradient(90deg, #000, transparent);
}

/* ---- iridescent focus edge (restrained micro-detail) ----
   Interaction lines only: a 1px sheen that shifts hue across its length so a
   focused edge feels like light catching acetate. Never a glow, never a halo.
   Honors reduced-motion by simply being static (it already is). */
.irid-edge {
  position: relative;
}
.irid-edge::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  opacity: 0; transition: opacity .18s ease; pointer-events: none;
  background: linear-gradient(90deg,
    rgba(140,10,11,.85) 0%, rgba(120,60,90,.55) 28%,
    rgba(70,95,120,.45) 52%, rgba(120,110,70,.5) 76%, rgba(140,10,11,.8) 100%);
}
.irid-edge:focus-within::after { opacity: 1; }

/* ---- brand area ----
   The emblem stays small and calm; AUF WASSEN is the master identity and ARIA
   is the (temporary) beta product label sitting under it, never competing. */
.brand-header {
  flex: none; background: var(--oxblood); border-bottom: 2px solid var(--oxblood-border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 26px; height: 64px; position: relative;
}
.brand-header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1px;
  background: rgba(140,10,11,.4);
}
.brand-header .brand-lockup { display: flex; align-items: center; gap: 11px; }
.brand-header .brand-lockup img { height: 34px; width: 34px; object-fit: contain; flex: none; }
.brand-header .brand-lockup .wordmark {
  font: 700 15px/1 var(--font-ui); letter-spacing: .16em; color: var(--paper-brand); white-space: nowrap;
}

/* ---- shared monospace kicker/label ---- */
.mono-label {
  font: 700 9px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase;
}
