/* notation-4-daw design tokens — the single source of truth for every value.
 *
 * TWO LAYERS, mirroring the Figma library:
 *
 *   1. PRIMITIVES  — raw values. A small closed set of hues plus their alpha
 *      tints. Nothing outside this block invents a colour.
 *   2. SEMANTIC    — everything the app actually uses. Each one is a var()
 *      reference to a primitive, never a literal.
 *
 * The split is what stops the system drifting: a semantic token cannot wander
 * away from its hue, because it has no value of its own. Retuning a hue is one
 * edit in PRIMITIVES.
 *
 * Alpha tints are written as literal rgba() rather than CSS relative color
 * syntax (`rgb(from var(--purple) r g b / .2)`), which needs Safari 16.4+ and
 * would silently fail on the older WKWebView shipped with macOS 10.15–12 — our
 * CMake deployment target. `npm test` fails the build if a tint's RGB does not
 * match its base primitive, so the derivation is enforced without the syntax.
 *
 * Mirrored as typed TS in `src/ui/tokens.ts`. Change a value HERE; the TS side
 * holds var() references and needs no edit. The one exception is the `raw`
 * export in tokens.ts (literal hex for the notation canvas, which cannot
 * resolve var()) — those MUST be updated in lockstep.
 *
 * The app is dark-only by design: it lives inside a DAW, where a light UI would
 * be jarring. There is deliberately no light theme and no prefers-color-scheme
 * block. If one is ever added, it belongs here and nowhere else.
 */

:root {
  /* ========================================================================
   * 1. PRIMITIVES — raw values. The only place a literal colour may appear.
   * ===================================================================== */

  --white: #FFFFFF;
  --black: #000000;
  --grey: #797979;
  --grey-dark: #131313;
  --purple: #C483FF;
  --green: #00FF62;
  --yellow: #FFD400;
  --red: #EC3F3F;

  /* Greys between --grey-dark and --grey, for surfaces and borders. Named by
     lightness so the ramp is legible as a ramp. */
  --grey-05: #1E1E1E;
  --grey-15: #2B2B2B;
  --grey-20: #333333;
  --grey-25: #444444;
  --grey-40: #555555;
  --grey-70: #AAAAAA;
  --grey-85: #DDDDDD;

  /* Alpha tints. Each MUST keep the RGB of the primitive it derives from —
     enforced by src/ui/tokens.test.ts. */
  --purple-50: rgba(196, 131, 255, 0.5);
  --purple-10: rgba(196, 131, 255, 0.1);
  --purple-20: rgba(196, 131, 255, 0.2);
  --purple-30: rgba(196, 131, 255, 0.3);
  --white-08: rgba(255, 255, 255, 0.08);
  --white-20: rgba(255, 255, 255, 0.2);
  --white-25: rgba(255, 255, 255, 0.25);
  --white-50: rgba(255, 255, 255, 0.5);
  --black-50: rgba(0, 0, 0, 0.5);
  --black-75: rgba(0, 0, 0, 0.75);
  --green-15: rgba(0, 255, 98, 0.15);
  --red-15: rgba(236, 63, 63, 0.15);
  --yellow-08: rgba(255, 212, 0, 0.08);
  --yellow-16: rgba(255, 212, 0, 0.16);
  --yellow-60: rgba(255, 212, 0, 0.6);

  /* Notation-only hues. The staff needs more distinguishable colours than the
     chrome does — these have no counterpart in the Figma UI library. */
  --cyan: #03DAC6;
  --magenta: #E040FB;
  --blue: #64B5F6;
  --salmon: #EF9A9A;

  /* ========================================================================
   * 2. SEMANTIC — what the app uses. Always a var(), never a literal.
   * ===================================================================== */

  /* --- Brand ----------------------------------------------------------- */
  --accent: var(--purple);
  /* Filled state of pills and toggles. */
  --accent-fill: var(--purple-20);

  /* --- Surfaces (darkest to lightest) ---------------------------------- */
  /* The floor everything sits on; the canvas draws straight onto it. */
  --bg-floor: var(--black);
  /* Raised chrome: toolbars, track headers, popovers, dialogs. */
  --bg-elevation: var(--grey-05);
  /* Recessed well reading as inset against bg-elevation: diff panels, code
     blocks, log output, inputs, empty track rows. */
  --bg-well: var(--grey-dark);
  /* Raised neutral chip on a dark row: form controls, scope-navigator bars. */
  --bg-chip: var(--grey-15);
  /* Scrim behind modal dialogs. */
  --bg-scrim: var(--black-75);

  /* --- Borders ---------------------------------------------------------- */
  --border: var(--grey-20);
  /* Border on interactive controls — reads above --border. */
  --border-strong: var(--grey-25);

  /* --- Text ------------------------------------------------------------- */
  /* Primary reading text. */
  --text: var(--grey-85);
  /* Secondary/label text — the toolbar's resting colour. */
  --text-muted: var(--grey);
  /* Disabled text. */
  --text-dim: var(--grey-40);
  /* Hover/active text, and text on a filled surface. The only pure white. */
  --text-strong: var(--white);
  /* Group captions. White at low opacity so it reads on any surface rather
     than being tuned to one. */
  --text-group-label: var(--white-20);

  /* --- Icon ------------------------------------------------------------- */
  /* Resting colour for icon graphics and chevrons. Goes --text-strong on hover. */
  --icon: var(--grey);

  /* --- Status ----------------------------------------------------------- */
  /* Three indicators, matching the Figma library. Each has a soft fill for
     inline callouts and filled secondary buttons. */
  --indicator-green: var(--green);
  --indicator-yellow: var(--yellow);
  --indicator-red: var(--red);
  --indicator-green-fill: var(--green-15);
  --indicator-red-fill: var(--red-15);
  /* Unsaved changes. Deliberately the caution hue, not the error one. */
  --dirty: var(--yellow);
  /* Muted track (red) and soloed track (yellow) — a matched pair. */
  --muted: var(--red);
  --solo: var(--yellow);

  /* --- Notation canvas --------------------------------------------------
   * Score semantics, not UI chrome, so restyling the UI cannot restyle the
   * staff. Kept in sync with `raw` in tokens.ts. */
  --score-note: var(--purple);
  /* Fill of a framed scope-navigator bar (playhead / selection). Dimmer than
     --accent so the 1px outline around it still reads. */
  --scope-bar-framed: var(--purple-50);
  /* Tail of a sustained note, and a note held but not re-struck. Defined from the
     Figma library; the canvas currently draws tails with --select-fill instead, so
     these are declared but not yet wired up. Point CanvasGrid at them when the
     tail/silent distinction is implemented. */
  --note-tail: var(--purple-20);
  --note-silent: var(--purple-10);
  --score-note-grace: var(--grey-70);
  /* Staff furniture: barlines, stems, beams, ledger/tie curves, tied notes. */
  --score-staff: var(--grey);
  --score-playhead: var(--yellow);
  /* Selection-preview marker. Same yellow as the selection box that spawned it, held
     translucent so it reads as belonging to the selection rather than as a second
     transport playhead (which is green — --score-let-ring, below). */
  --score-preview-playhead: var(--yellow-60);
  --score-let-ring: var(--green);
  --score-palm-mute: var(--yellow);
  /* Harmonic family — one hue per type so they stay distinguishable at a
     glance on a dense staff. */
  --score-harmonic: var(--cyan);
  --score-harm-pinch: var(--yellow);
  --score-harm-tap: var(--blue);
  --score-harm-semi: var(--salmon);
  --score-feedback: var(--magenta);

  /* --- Overlays ---------------------------------------------------------
   * Translucent washes. Canvas ones are mirrored in `raw` (tokens.ts), since
   * ctx.fillStyle cannot resolve var(). */
  /* Note selection. */
  --select-wash: var(--purple-10);
  --select-fill: var(--purple-20);
  --select-fill-strong: var(--purple-30);
  /* Loop region and its bracket. */
  --loop-wash: var(--yellow-08);
  --loop-wash-mid: var(--yellow-16);
  --loop-edge: var(--yellow-60);
  /* Let-ring / sustain span. */
  --sustain-wash: var(--green-15);
  /* Close sign of pass 1 in the written-out view (where the folded view closes): the sign's
     white at half strength, so it reads as "the repeat is defined up to here" without
     competing with a real close. Linked copies (passes 2..N) have no wash: their notes draw
     faded instead (CanvasGrid LINKED_COPY_NOTE_ALPHA). */
  --repeat-sign-pass: var(--white-50);
  /* Neutral overlays: hover fills, skipped-bar hatching. */
  --overlay-faint: var(--white-08);
  --overlay-skip: var(--white-08);
  /* Softer scrim for non-modal dimming. */
  --scrim-soft: var(--black-50);

  /* --- Log / diff output ------------------------------------------------
   * Direction semantics in the debug log and cloud diff panels. */
  --log-incoming: var(--blue);
  --log-outgoing: var(--yellow);
  /* Cloud-conflict compare on the canvas. Fixed to the SERVER's point of view so
   * a note keeps its colour when flipping Mine|Theirs: green = their addition,
   * red = only in mine (their removal), yellow = changed. Reuses the indicator
   * hues rather than minting new ones. */
  --diff-added: var(--green);
  --diff-removed: var(--red);
  --diff-changed: var(--yellow);

  /* ===== Typography ====================================================== */
  /* The UI font — self-hosted Inter 400 (see main.tsx), so the plugin renders
     the same offline and in every DAW; system sans if the webfont fails. */
  --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  /* The one serif, always bold where used: track names, section/bar titles and
     the staff's small technical annotations. A system font, so no webfont.
     Mirrored as the literal `fontSerif` in tokens.ts for the canvas. */
  --font-serif: Georgia, 'Times New Roman', serif;
  /* Fixed-width: log output, keyboard-shortcut keys, the transport readout. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Notation glyphs (SMuFL), registered with @font-face in index.css. Mirrored
     as the literal `fontMusic` in tokens.ts for the canvas. */
  --font-music: 'Bravura';
  --font-size-small: 10px;
  --font-size-body: 14px;
  --font-size-heading: 16px;
  --font-size-display: 18px;

  /* ===== Space (2px grid) ================================================ */
  --space-xxs: 2px;
  --space-xs: 4px;
  --space-sm: 6px;
  --space-md: 8px;
  --space-lg: 12px;
  --space-xl: 16px;
  --space-xxl: 24px;

  /* ===== Radius ========================================================== */
  /* Small marks and swatches (conflict legend, tempo-lane inline input) — tighter than the button default. */
  --radius-sm: 3px;
  --radius-md: 4px;
  --radius-lg: 6px;
  --radius-xl: 8px;
  --radius-full: 9999px;

  /* ===== Elevation ======================================================= */
  --shadow-popover: 0 4px 12px rgba(0, 0, 0, 0.5);
  --shadow-dialog: 0 8px 32px rgba(0, 0, 0, 0.6);

  /* ===== Motion ==========================================================
   * Colour and opacity only — never animate layout, the playhead must stay
   * frame-accurate. */
  --motion-fast: 120ms ease;
}
