/* ============================================================================
 * fretly-tokens.css - canonical design tokens for the entire app.
 * ============================================================================
 *
 * Single source of truth.  Every spacing, typography, radius, control-
 * height, control-padding value across Fretly references these tokens
 * via `var(--...)`.  See CLAUDE.md "TOP-PRIORITY DOCTRINE - Design
 * tokens + UI scale" for the doctrine.
 *
 * Architecture:
 *   - Root font-size = 14px * --ui-scale (anchored in site.css's
 *     `html` rule - 14 px matches Fretly's historical typographic
 *     baseline).  Tokens are in rem, so they scale automatically
 *     with --ui-scale.
 *   - --ui-density multiplies SPACING tokens only (padding/gap/margin
 *     density), leaving type sizes alone.
 *   - Both --ui-scale and --ui-density are set on <html> by
 *     fretly-ui-scale.js at boot from localStorage.
 *
 * Adding a new size?  Add the SEMANTIC token here, not in a
 * component-local file.  Component files reference `var(--...)`.
 *
 * Loaded BEFORE every other Fretly CSS file in app.php so every
 * downstream `var(--...)` resolves.
 */

:root {
  /* === User-controlled multipliers === */
  /* Set by fretly-ui-scale.js from localStorage at boot.
     Defaults applied here in case the JS hasn't loaded yet. */
  --ui-scale:   1;          /* 0.875 / 1.0 / 1.125 / 1.25 */
  --ui-density: 1;          /* 0.75 / 0.875 / 1.0 */

  /* === Root font size === */
  /* The single anchor every rem-based token scales from.  Owned by
     site.css `html { font-size: calc(14px * var(--ui-scale, 1)) }`
     - 14 px baseline matches Fretly's existing typographic convention.
     1rem = 14 px at scale 1.0; 17.5 px at scale 1.25; etc. */

  /* === Typography scale === */
  /* Modular scale, base 1rem = 14 px at --ui-scale: 1. */
  --font-xs:   0.7143rem;   /* 10 px equivalent */
  --font-sm:   0.8571rem;   /* 12 px */
  --font-base: 1rem;        /* 14 px - app body / control labels */
  --font-md:   1.0714rem;   /* 15 px - slightly heavier body */
  --font-lg:   1.2857rem;   /* 18 px - section headers */
  --font-xl:   1.5714rem;   /* 22 px - card titles */
  --font-2xl:  2rem;        /* 28 px - page titles */
  --font-3xl:  2.5714rem;   /* 36 px - hero */
  --font-display: 3.4286rem;/* 48 px - splash / login hero */

  /* Line heights - unitless so they scale with parent font-size. */
  --leading-tight:  1.2;
  --leading-snug:   1.35;
  --leading-normal: 1.5;
  --leading-loose:  1.7;

  /* Font weights - shared across the app. */
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold:   700;

  /* === Spacing scale === */
  /* Multiplied by --ui-density so users can compact/relax the UI
     independent of type size.  Values are in rem so they ALSO scale
     with --ui-scale via the root font-size.  Baseline 1rem = 14 px. */
  --space-0:   0;
  --space-2xs: calc(0.1429rem * var(--ui-density));   /*  2 px */
  --space-xs:  calc(0.2857rem * var(--ui-density));   /*  4 px */
  --space-sm:  calc(0.5714rem * var(--ui-density));   /*  8 px */
  --space-md:  calc(0.8571rem * var(--ui-density));   /* 12 px */
  --space-lg:  calc(1.1429rem * var(--ui-density));   /* 16 px */
  --space-xl:  calc(1.7143rem * var(--ui-density));   /* 24 px */
  --space-2xl: calc(2.2857rem * var(--ui-density));   /* 32 px */
  --space-3xl: calc(3.4286rem * var(--ui-density));   /* 48 px */
  --space-4xl: calc(4.5714rem * var(--ui-density));   /* 64 px */

  /* === Border radii === */
  /* Baseline 1rem = 14 px. */
  --radius-xs:   0.1429rem;  /* 2 px */
  --radius-sm:   0.2857rem;  /* 4 px */
  --radius-md:   0.5714rem;  /* 8 px */
  --radius-lg:   0.8571rem;  /* 12 px */
  --radius-xl:   1.1429rem;  /* 16 px */
  --radius-full: 9999px;     /* pill / circle */

  /* === List / tree indentation (Fretly List System) === */
  /* Consumed by fretly-list.css.  Tree rows set `--depth` (an
     integer custom property, written by JS) and CSS computes
     padding-left = base + depth * step.  Per-surface overrides
     re-declare --list-indent-base on the surface container.
     Baseline 1rem = 14 px. */
  --list-indent-base: 0.4286rem;  /* 6 px  — SCP sidebar default */
  --list-indent-step: 1rem;       /* 14 px per tree level */

  /* === Control dimensions === */
  /* Buttons, inputs, selects, dropdown triggers.
     Three sizes: sm/md/lg for chrome density variants.
     `md` is the default control size.  Baseline 1rem = 14 px. */
  --ctl-h-sm:    1.7143rem;  /* 24 px */
  --ctl-h-md:    2.1429rem;  /* 30 px */
  --ctl-h-lg:    2.5714rem;  /* 36 px */

  --ctl-pad-x-sm: var(--space-sm);
  --ctl-pad-x-md: var(--space-md);
  --ctl-pad-x-lg: var(--space-lg);
  --ctl-pad-y:    var(--space-xs);

  --ctl-font-sm: var(--font-xs);
  --ctl-font-md: var(--font-sm);
  --ctl-font-lg: var(--font-base);

  /* === Borders === */
  /* Fixed px - 1 px border at 100% scale stays 1 px regardless of
     --ui-scale.  Don't make this scale; sub-pixel rendering fails. */
  --border-w:        1px;
  --border-w-thick:  2px;

  /* === Shadows === */
  /* In rem so blur radius scales with UI.  Baseline 1rem = 14 px. */
  --shadow-sm: 0 0.0714rem 0.1429rem rgba(0,0,0,0.04);
  --shadow-md: 0 0.1429rem 0.4286rem rgba(0,0,0,0.06);
  --shadow-lg: 0 0.5714rem 1.1429rem rgba(0,0,0,0.08);

  /* === Z-index scale === */
  --z-base:     1;
  --z-sticky:   100;
  --z-dropdown: 200;
  --z-modal:    1000;
  --z-toast:    2000;
  /* Popovers/dropdowns must float above ANY host surface, including the
     legacy chord-diagram picker modal which hardcodes z-index:10000. */
  --z-popover:  10050;

  /* === Timing === */
  --t-fast:   120ms;
  --t-normal: 200ms;
  --t-slow:   320ms;

  /* === Layout === */
  /* Max content width on giant monitors.  Keeps the layout from
     sprawling edge-to-edge on 4K+ displays (per user 2026-05-11
     BenQ-monitor feedback).  In rem so it tracks --ui-scale.
     Baseline 1rem = 14 px so 114.2857rem ~= 1600 px at scale 1. */
  --max-content-w: 114.2857rem;

  /* === Layout breakpoints (documentation tokens) === */
  /* @media / @container queries CANNOT read var() — these tokens are
     the canonical documented values; every query implementing them
     uses the literal and cites the token name in a comment.  When
     changing a breakpoint, update the token here AND every cited
     literal (grep the token name).
     --bp-scp-drawer: viewport width at/below which SCP-shell side
       panes become overlay drawers instead of inline sticky panes.
       Consumers: scale-collection-page.css (@media drawer block),
       shared/scp-drawer.js (matchMedia mirror).
     --bp-scp-drawer-container: same decision measured against
       .scp-main's own inline-size (admin sidebar / docked dev-tools
       narrow the pane on wide viewports).  Consumers:
       scale-collection-page.css (@container twin), scp-drawer.js. */
  --bp-scp-drawer:           1300px;
  --bp-scp-drawer-container: 1200px;
}

/* NOTE: the `html { font-size: ... }` declaration that anchors every
   rem-based token is owned by site.css (which uses Fretly's
   historical 14 px baseline).  See site.css `html` rule for the
   `calc(14px * var(--ui-scale, 1))` source of truth. */

/* Reduced motion preference - disable transitions so density /
   scale changes don't animate jank during a settings flip. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --t-fast:   0ms;
    --t-normal: 0ms;
    --t-slow:   0ms;
  }
}
