/* =============================================================================
   Raven — base tokens
   =============================================================================
   Scale, shape and depth. Colour lives in palette.css; this file must contain
   NO colour values at all.

   Per frontend-standard §0.2 check 1, a raw hex / rgb() / hsl() anywhere outside
   tokens/ is a violation. Use sites reference var(--token) only, always.
   ========================================================================== */

:root {

  /* ---------------------------------------------------------------------------
     RADIUS — decided by an element's ROLE, never by taste (§1)
     ---------------------------------------------------------------------------
     The test: is this element the primary substance of the page, or a widget
     floating on top of it?

     Raven leans harder on --r-none than most apps, and that is deliberate: the
     look is a precision instrument, machined and square. Rounded corners are the
     exception, not the reflex.

     A coloured edge accent is ALWAYS paired with --r-none (§2.2). A single-edge
     accent on a rounded container is a locked violation.
     ------------------------------------------------------------------------ */
  --r-none: 0;      /* THE PAGE'S SUBSTANCE — asset rows, credential rows, lists,
                       tables, panels, and FORMS. Anything carrying a severity
                       spine is here by definition. */
  --r-sm:   4px;    /* tiny chips */
  --r:      6px;    /* CONTROLS — buttons, inputs, selects, pills, badges */
  --r-lg:   12px;   /* TRUE FLOATERS — the reveal dialog, popovers, menus,
                       toasts, the QR panel */
  --r-xl:   18px;   /* hero panels */

  /* Nested radii are CONCENTRIC, not equal (§1.1): outer = inner + gap.
     Write the relationship with calc() on tokens, never the computed number —
     `calc(var(--r-lg) - var(--sp-2))` says WHY; `4px` is just a result that
     silently breaks if the scale is ever retuned. */

  /* ---------------------------------------------------------------------------
     SPACING
     ---------------------------------------------------------------------------
     Generous internal padding is where perceived solidity comes from — thin
     things feel cheap mostly because they are cramped. Padding does more for
     mass than any effect.
     ------------------------------------------------------------------------ */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;

  /* Page padding: generous outer whitespace is part of the look (§3). */
  --page-pad:        var(--sp-7);   /* desktop */
  --page-pad-mobile: var(--sp-3);

  /* ---------------------------------------------------------------------------
     TYPOGRAPHY
     ---------------------------------------------------------------------------
     One neutral grotesque with real weight range, plus a REAL MONOSPACE for all
     machine data. The monospace is functional, not stylistic: it makes a
     transposed digit in an IP or fingerprint visible, and it distinguishes 0/O
     and 1/l in a system where that distinction can cost an hour.

     SELF-HOSTED, always. No font CDN — the CSP forbids third-party origins, and
     the old system pulling a font from unpkg into a page rendering SSH config is
     exactly the pattern this replaces. (§0.2 check 10)
     ------------------------------------------------------------------------ */
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Fira Mono', monospace;

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-bold:    700;   /* headings are sized and weighted to ANCHOR a page,
                          not merely label it — much of the perceived mass
                          comes from type */

  --fs-xs:  12px;
  --fs-sm:  13px;
  --fs-md:  15px;
  --fs-lg:  16px;
  --fs-xl:  18px;
  --fs-2xl: 26px;   /* page H1 */
  --fs-3xl: 32px;
  --fs-4xl: 40px;   /* hero */

  --lh:       1.45;
  --lh-tight: 1.2;

  /* Letter-spacing tightens as size grows. */
  --ls-h1:   -0.02em;
  --ls-hero: -0.025em;

  /* ---------------------------------------------------------------------------
     ROWS — the single most important measurement in the product
     ---------------------------------------------------------------------------
     44–52px: taller than a typical data table, because each row is a solid slab
     with real internal padding rather than a line of text. Still dense enough to
     scan twenty at a glance.

     Note this floor is the same 44px as the coarse-pointer touch-target minimum
     (§7.1 rule 3), which is a happy coincidence worth preserving.
     ------------------------------------------------------------------------ */
  --row-h:     48px;
  --row-h-min: 44px;
  --row-pad-x: var(--sp-4);
  --row-pad-y: var(--sp-3);

  /* The severity spine (§2.2, §5A.3). A thin vertical accent bar down a row's
     LEFT edge — encountered first when reading left to right, and stacking into
     a scannable vertical rhythm so you see the SHAPE of the risk on a host
     before reading a word. Always on a --r-none container. */
  --spine-w:       3px;
  --spine-w-strong: 4px;   /* root / break_glass earn a heavier spine */

  /* Minimum interactive size under a coarse pointer (§7.1 rule 3). */
  --touch-min: 44px;

  /* ---------------------------------------------------------------------------
     ELEVATION AND DEPTH
     ---------------------------------------------------------------------------
     Weight comes from DEPTH AND PROPORTION, not decoration. Two mechanisms:

       1. genuine tonal separation  (--bg < --surface < --surface-2, palette.css)
       2. a fine light-catch along a surface's top edge, as a machined bevel
          would have

     THE LINE TO AVOID: substantial must not tip into skeuomorphic. Depth and
     tonal separation, yes; gloss, inner glows and rounded gradient buttons, no.
     If it starts looking like a 2011 iOS app, the bevel on the buttons is almost
     always the culprit — cut that first.

     Note §2.4: rows and containers separate with 1px hairlines or crisp gaps,
     NOT drop shadows. Shadows appear only on TRUE OVERLAYS.
     ------------------------------------------------------------------------ */
  --elev-0: none;
  --elev-1: 0 1px 2px rgb(0 0 0 / 0.24);                                  /* resting panel */
  --elev-2: 0 2px 4px rgb(0 0 0 / 0.28), 0 1px 2px rgb(0 0 0 / 0.20);     /* raised */
  --elev-3: 0 8px 24px rgb(0 0 0 / 0.40), 0 2px 6px rgb(0 0 0 / 0.28);    /* popover / menu */
  --elev-4: 0 16px 48px rgb(0 0 0 / 0.52), 0 4px 12px rgb(0 0 0 / 0.32);  /* modal / reveal */

  /* The light-catch: a 1px lighter top edge that reads as a machined bevel.
     Applied as an inset shadow so it composes with a real border. */
  --edge-light: inset 0 1px 0 0 var(--edge);

  /* The opposite of elevation: a RECESSED well, for the field a revealed secret
     sits in. It reads as milled into the panel rather than laid on top, which is
     what makes the reveal feel like an instrument rather than a text box. */
  --inset-well: inset 0 1px 3px rgb(0 0 0 / 0.5);

  /* Small fixed glyph sizes. These are shape, not layout — a freshness dot is a
     dot at every width — so they live here rather than as bare px at a use site. */
  --dot:  8px;
  --icon: 14px;

  /* ---------------------------------------------------------------------------
     MOTION — damped and mechanical, never bouncy (§5A.6)
     ---------------------------------------------------------------------------
     SPEED IS THE FEATURE. No animation over 200ms, and no spinner for anything
     that finishes under 300ms.
     ------------------------------------------------------------------------ */
  --dur-fast: 90ms;
  --dur:      140ms;
  --dur-slow: 200ms;   /* the ceiling. Nothing animates longer than this. */

  /* No overshoot, no spring. A precision instrument's controls move with
     damping; they do not bounce. */
  --ease:     cubic-bezier(0.2, 0, 0.2, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);

  --spinner-delay: 300ms;

  /* ---------------------------------------------------------------------------
     Z-INDEX
     ------------------------------------------------------------------------ */
  --z-nav:      100;
  --z-drawer:   200;
  --z-backdrop: 300;
  --z-dialog:   400;   /* the reveal panel lives here */
  --z-toast:    500;

  /* ---------------------------------------------------------------------------
     LAYOUT
     ------------------------------------------------------------------------ */
  --rail-w:           240px;
  --rail-w-collapsed: 56px;
  --nav-h:            56px;
  --content-max:      1440px;
}

/* Respect the user's motion preference. Motion here is functional — a reveal's
   transition marks a consequential action — so it degrades to instant rather
   than being replaced with something else. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0ms;
    --dur:      0ms;
    --dur-slow: 0ms;
  }
}
