/**
 * WS Suite design tokens - deep indigo, glass, violet.
 *
 * A modern launcher aesthetic: a deep indigo ground lit by soft magenta and violet
 * fields, panels that read as frosted glass, generous radii, and one vivid violet
 * reserved for the action that matters.
 *
 * Three things here are consequences of building on glass rather than matters of
 * taste, and each one is load-bearing:
 *
 * 1. THE GLASS IS DARK, NOT WHITE. The obvious way to build a frosted panel is white
 *    at low alpha, and it is wrong here: over a vivid ground it lifts the surface to a
 *    mid-purple that nothing readable can sit on. This is the same choice macOS makes
 *    for dark vibrancy - the material darkens what is behind it while still letting the
 *    hue through. It is what makes a saturated background and legible text coexist.
 *
 * 2. THERE ARE TWO TEXT COLOURS, NOT THREE. A third, dimmer step does not exist: any
 *    colour that clears 4.5:1 on this ground converges on --text-muted no matter how it
 *    is tuned, so a separate --text-faint would have been the same grey under a second
 *    name. The third level of hierarchy is carried by size, weight and letter-spacing
 *    instead - the small uppercase treatment shared by `.panel__title` and
 *    `.card__facts dt` - which costs no contrast at all.
 *
 * 3. THE ACCENT IS SPLIT IN TWO. --accent is a fill that white text sits on, so it must
 *    be dark enough for white to clear 4.5:1. --accent-text is a foreground on the dark
 *    ground, so it must be light enough to clear it there. Those pull in opposite
 *    directions and one token cannot satisfy both. Using the fill as a link colour is
 *    the mistake this split exists to prevent.
 *
 * Every value below that carries text was solved numerically against the composited
 * worst case, not picked by eye. `npm run check:contrast` recomputes the whole thing
 * from these tokens and fails the build if a change breaks it.
 */

:root {
  /* ---------------------------------------------------------------------------
   * Ground
   *
   * The window is deep indigo with three soft colour fields over it. They are what
   * stops a dark interface reading as flat grey. Their opacities are deliberately
   * restrained: every point they brighten the ground to is a point all light text has
   * to survive, so the wash and the type are the same decision.
   * ------------------------------------------------------------------------- */
  --bg-deep: #0a0518;
  --bg: #0d0620;
  --bg-lift: #110828;

  --wash-violet: rgba(124, 63, 232, 0.15);
  --wash-magenta: rgba(214, 51, 168, 0.12);
  --wash-blue: rgba(63, 106, 232, 0.07);

  /* The lightest point the wash above can reach, and so the worst case for any light
   * text. Not hand-picked: it is the three washes composited over --bg-lift, and the
   * contrast script recomputes that and rejects this token if it flatters the palette. */
  --bg-ceiling: #371a5b;

  /* ---------------------------------------------------------------------------
   * Glass
   *
   * A dark tint plus a bright hairline. The hairline is what actually sells the
   * effect - without an edge catching light a translucent panel reads as a smudge
   * rather than as a pane.
   *
   * --glass-border is decorative and sits below 3:1 on purpose: the panel's own fill
   * already separates it from the ground, so the edge is not carrying the meaning
   * alone. --glass-border-strong is for controls whose boundary IS the only thing
   * marking them - inputs, mainly - and it is held above 3:1 for that reason.
   * ------------------------------------------------------------------------- */
  --glass: rgba(12, 6, 30, 0.4);
  --glass-raised: rgba(255, 255, 255, 0.055);
  --glass-hover: rgba(255, 255, 255, 0.09);
  --glass-sunken: rgba(0, 0, 0, 0.28);

  /* The dimming layer behind a dialog. Darker and less saturated than the ground so
   * the dialog reads as lit and the page behind it as switched off. */
  --scrim: rgba(6, 3, 16, 0.68);

  --glass-border: rgba(255, 255, 255, 0.1);
  --glass-border-strong: rgba(255, 255, 255, 0.42);

  --blur: saturate(160%) blur(20px);
  --blur-heavy: saturate(170%) blur(34px);

  /* ---------------------------------------------------------------------------
   * Text
   * ------------------------------------------------------------------------- */
  --text: #f2f0fa;
  --text-muted: #a092c2;

  /* ---------------------------------------------------------------------------
   * Accent
   * ------------------------------------------------------------------------- */
  --accent: #7847e3;
  --accent-hover: #855aeb;
  --accent-pressed: #6a3ad4;
  /* The dark end of the pressed gradient. */
  --accent-deep: #4f24a8;
  --accent-ink: #ffffff;
  --accent-text: #a884fc;
  --accent-glow: rgba(120, 71, 227, 0.5);

  /* Emphasis that is not an action - a count, a badge, a highlight. Keeping this
   * apart from the accent is what stops a colourful interface becoming one where
   * nothing looks clickable and everything looks important. */
  --magenta: #f260d2;
  --magenta-glow: rgba(238, 99, 208, 0.4);

  /* Gradient stops are tokens because the gradient is what actually gets painted. A
   * flat --accent that passes tells you nothing about the light end of the fill the
   * button is really wearing, and the light end is where white ink fails first. Both
   * stops of both gradients are checked against the ink that sits on them. */
  --gradient-accent-from: #7f52e8;
  --gradient-accent-to: #5f2fc9;
  --gradient-accent: linear-gradient(135deg, var(--gradient-accent-from) 0%, var(--gradient-accent-to) 100%);

  /* Hover and pressed are gradients too, not flat colours. Swapping a gradient for a
   * flat colour swaps a background-image for a background-color: the image is dropped
   * at once while the colour animates up from transparent, and for that moment the
   * button is see-through. Keeping every state a gradient removes the swap entirely.
   * Both reuse stops that are already audited for white ink. */
  --gradient-accent-hover: linear-gradient(135deg, var(--accent-hover) 0%, var(--accent-pressed) 100%);
  --gradient-accent-pressed: linear-gradient(135deg, var(--accent-pressed) 0%, var(--accent-deep) 100%);

  --gradient-magenta-from: #f38add;
  --gradient-magenta-to: #9b74ff;
  --gradient-magenta: linear-gradient(135deg, var(--gradient-magenta-from) 0%, var(--gradient-magenta-to) 100%);

  /* ---------------------------------------------------------------------------
   * Status
   * ------------------------------------------------------------------------- */
  --danger: #f9798c;
  --danger-surface: rgba(255, 84, 122, 0.14);
  --danger-border: rgba(255, 84, 122, 0.34);

  --success: #15bb7b;
  --success-surface: rgba(60, 214, 152, 0.13);
  --success-border: rgba(60, 214, 152, 0.32);

  --warning: #df9903;
  --warning-surface: rgba(255, 184, 60, 0.13);
  --warning-border: rgba(255, 184, 60, 0.32);

  --info: #a695f9;
  --info-surface: rgba(124, 92, 255, 0.18);
  --info-border: rgba(124, 92, 255, 0.36);

  /* ---------------------------------------------------------------------------
   * Type
   *
   * `ui-rounded` resolves to SF Pro Rounded on Apple platforms and falls back
   * gracefully elsewhere. It gets close to the soft geometric feel of the reference
   * without shipping a font file - which matters for a desktop app that has to start
   * instantly and work offline.
   * ------------------------------------------------------------------------- */
  /*
   * Keep in step with TYPE.ui in packages/shared/src/brand.ts - a test fails if these
   * drift. Windows-first ordering is deliberate: the fallbacks only matter if a host
   * refuses the bundled face, and Segoe UI is the one that will be there.
   */
  --font: "Manrope", "Segoe UI Variable Text", "Segoe UI", "Helvetica Neue", Arial;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Keep in step with TYPE.display in packages/shared/src/brand.ts. */
  --font-display: "Halfre", "Manrope", "Segoe UI Variable Display", "Segoe UI", "Helvetica Neue", Arial;

  --text-2xs: 10px;
  --text-xs: 11px;
  --text-sm: 12px;
  --text-base: 13px;
  --text-md: 15px;
  --text-lg: 19px;
  --text-xl: 24px;
  --text-2xl: 30px;

  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.6;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  --tracking-label: 0.09em;

  /* ---------------------------------------------------------------------------
   * Space
   * ------------------------------------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;

  /* ---------------------------------------------------------------------------
   * Shape and depth
   *
   * Larger radii than a utility interface would use. On glass a tight corner looks
   * cut rather than moulded, and that softness is most of what reads as "modern".
   * ------------------------------------------------------------------------- */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 18px;
  --radius-xl: 24px;
  --radius-full: 999px;

  --shadow-card: 0 8px 28px rgba(0, 0, 0, 0.32);
  --shadow-raised: 0 14px 40px rgba(0, 0, 0, 0.42);
  --shadow-overlay: 0 28px 72px rgba(0, 0, 0, 0.6);
  --shadow-accent: 0 8px 24px var(--accent-glow);

  /* The highlight along a pane's top edge, where light would catch it. An inset so it
   * needs no extra element. */
  --edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.13);

  /* ---------------------------------------------------------------------------
   * Motion
   * ------------------------------------------------------------------------- */
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 110ms;
  --duration: 200ms;

  --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent-text);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms;
    --duration: 0ms;
  }
}
