/* The visual system: warm, layered, quiet. A collector's app, not a terminal.
 *
 * Four ideas carry it, and they survive the move to the browser unchanged
 * because they were never about the toolkit:
 *
 * - **Depth replaces outlines.** Surfaces are ordered by lightness - window,
 *   page, panel, raised, hover - and a thing is "in front" because it is
 *   lighter, not because it is ringed. Hairlines survive only where two
 *   surfaces of the same tone genuinely meet.
 * - **The neutrals are warm.** #0d0d0d is a cold, clinical black. Everything
 *   here sits on a warm axis (hue ~30 degrees, chroma low enough to still read
 *   as grey), which is closer to the subject matter and considerably easier to
 *   sit in front of for an hour.
 * - **One type scale, seven steps.** Sizes that differ by 0.5px do not create
 *   hierarchy, they create noise.
 * - **Motion exists, and is never in the way.** Three durations, two curves.
 *
 * **The data colours are deliberately untouched.** The diverging blue/red pair,
 * the reserved status four, and the sequential interest ramp were validated
 * against a dark background and are load-bearing for how every number in the
 * product reads. Changing which hexes carry meaning is a research decision, not
 * a styling one, and this file does not get to make it.
 */

:root {
  /* Surfaces, ordered back to front. Lightness *is* the elevation signal, so
     these are meaningfully spaced rather than nearly identical. */
  --bg-app: #0c0a09;
  --bg-page: #1a1715;
  --bg-panel: #241f1b;
  --bg-elevated: #2d2724;
  --bg-hover: #38312c;
  --bg-sunken: #141110;
  --bg-floating: #332c28;

  --bg-select: #1c3a5e;
  --bg-select-soft: rgba(57, 135, 229, 0.14);

  /* Ink. Warm whites: pure #ffffff on a dark surface glares, and a hint of
     warmth in the lightest ink is the difference between "screen" and "paper". */
  --fg: #f6f2ec;
  --fg-dim: #c6bfb5;
  --fg-muted: #8e867b;
  --fg-faint: #6a635b;

  /* Lines. Both are last resorts - prefer a change of surface. */
  --grid: #282320;
  --border: #37312c;
  --hairline: rgba(246, 242, 236, 0.07);

  /* Signed values: a diverging pair with FG_DIM as the neutral midpoint. */
  --pos: #3987e5;
  --neg: #e66767;
  --pos-strong: #6da7ec;
  --neg-strong: #f08f8f;

  --accent: #3987e5;
  --accent-soft: #1c5cab;
  --accent-wash: rgba(57, 135, 229, 0.16);

  /* Reserved status palette. Never reused for a data series, and never shown
     without its label. */
  --good: #0ca30c;
  --warn: #fab219;
  --serious: #ec835a;
  --crit: #d03b3b;

  /* The forecast's own colour. Purple because the two rankings this platform
     maintains must never be confused for one another, and neither may borrow
     the status palette. */
  --forecast: #9370db;

  /* Reserved for exactly one thing: a card priced in the reader's own money
     rather than the market's - "What can you buy today?", its tile, its
     header figure, its row evidence. Proposed by the 2026-08-06 design
     review as a brand-only accent ("something that belongs next to a graded
     slab") and unused until this feature gave it a job. Never mixed with
     --accent, never shown without the number it prices. */
  --invest: #c9985a;
  --invest-soft: #96622a;
  --invest-wash: rgba(201, 152, 90, 0.13);
  --invest-wash-strong: rgba(201, 152, 90, 0.22);

  --mono: Consolas, "Cascadia Mono", "Courier New", monospace;
  --sans: "Segoe UI", system-ui, -apple-system, sans-serif;

  /* Type scale: seven steps, each a clear jump from the last. */
  --fs-display: 32px;
  /* Two further steps, and the only ones outside the seven, added for the front
     page. That screen is a document a stranger reads rather than an instrument
     an owner operates: its opening statement is a poster headline and its body
     is prose, and set at --fs-display and --fs-body the whole thing read like a
     settings dialog. Fluid rather than fixed, because it is the one surface
     here that should use whatever width the window has. Nothing else may use
     these - a dense table with a fluid type size is a table that reflows while
     you read it. */
  --fs-hero: clamp(29px, 4.1vw, 50px);
  --fs-lead: clamp(19px, 2.05vw, 27px);
  --fs-prose: 14.5px;
  --fs-title: 22px;
  --fs-heading: 15px;
  --fs-body: 13px;
  --fs-small: 12px;
  --fs-micro: 11px;
  --fs-caption: 10.5px;

  /* Radius scale. Generous and consistent - a 6px corner beside a 10px corner
     is the visual equivalent of a typo. */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;

  /* Spacing scale. Everything in the app should be one of these. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;

  /* Motion. The entire vocabulary. `--ease` is for anything the pointer asked
     for; it decelerates into place, so the result feels like it arrived rather
     than stopped. `--ease-soft` is for things that appear on their own. */
  --dur-fast: 130ms;
  --dur-base: 200ms;
  --dur-slow: 320ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-soft: cubic-bezier(0.65, 0, 0.35, 1);

  --row-height: 56px;
  --compact-row: 28px;
}

/* Tones. One name per meaning, so a badge, a table cell and a sentence can
   never disagree about what "warning" looks like. */
.tone-good { color: var(--good); }
.tone-warning { color: var(--warn); }
.tone-serious { color: var(--serious); }
.tone-critical { color: var(--crit); }
.tone-neutral { color: var(--fg-dim); }
.tone-muted { color: var(--fg-muted); }
.tone-accent { color: var(--accent); }
.tone-positive { color: var(--pos); }
.tone-negative { color: var(--neg); }

/* The foil sweep, desaturated. A saturated spectrum sitting beside the
   diverging blue/red pair would read as data; this reads as a material. It is
   rationed to the rarity pips and the tile hover, because everywhere else would
   turn a signature into wallpaper. */
:root {
  --foil: linear-gradient(135deg, #7fd4e8, #9db8f0, #c9a5e8, #efa8c4,
                          #f0c79a, #a8dcb8);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
