/* theme.css - Katalog design tokens.
   The single source of truth for type, colour, spacing, depth and motion.

   Load order on a page: theme.css → kat-ui.css → (page-local <style>).
   fonts.css is a deprecated alias shim kept only for pages not yet migrated -
   it now forwards to the same families defined here, so no page can end up on
   the retired Zodiak/General Sans stack.

   TYPE - three families, each with one job:
     --font-display  Sora        headings, numbers, UI emphasis
     --font-body     Manrope     body copy, controls, everything else
     --font-editorial Newsreader italic - reserved for hero lines and narrative
                                 numbers ONLY. Sparse use is what makes it read
                                 as art direction rather than decoration.
   --font-mono is IBM Plex Mono, used for eyebrows//labels/metadata. It is
   defined HERE rather than inherited from fonts.css: kat-ui.css's .kat-eyebrow,
   shell.js's group labels and ~95 call sites across the app resolve it, so
   leaving it to a file we're retiring would silently fall back to the UA
   default everywhere. */
@import url('https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700&family=Manrope:wght@400;500;600;700;800&family=Newsreader:ital,opsz,wght@1,6..72,400;1,6..72,500&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {
  /* ---- type families ---- */
  --font-display: 'Sora', 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-body: 'Manrope', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-label: 'Manrope', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', 'SF Mono', Menlo, Consolas, monospace;
  --font-editorial: 'Newsreader', Georgia, 'Times New Roman', serif;

  /* ---- surfaces ---- */
  --canvas: #F4F3EF;
  --surface: #FFFFFF;
  --surface-alt: #F3F1EC;
  --surface-alt-2: #F0EEE9;
  --surface-alt-3: #FAF9F6;

  /* Dark surfaces - formalised from the one-off gradient that home.html's
     valuation card hardcoded. Used for the single dominant "hero" moment on a
     screen, never for a whole page of cards. */
  --surface-dark: #1F1B17;
  --surface-dark-2: #302A24;
  --surface-dark-3: #443B32;
  --ink-inverse: #F7F5F1;
  --ink-inverse-2: rgba(247, 245, 241, .72);
  --ink-inverse-3: rgba(247, 245, 241, .52);
  --border-inverse: rgba(247, 245, 241, .14);

  /* ---- borders ---- */
  --border-sidebar: #E7E4DC;
  --border-card: #E6E3DB;
  --border-input: #DFDBD2;
  --border-divider: #EDEBE5;
  --border-strong: #D2CDC2;

  /* ---- ink ---- */
  --ink: #17130F;
  --ink-2: #453E37;
  --ink-3: #6B6660;
  --ink-4: #857F75;
  --ink-5: #97918A;
  --ink-6: #A49E93;
  --ink-7: #B2ABA0;

  /* ---- accent ---- */
  --accent: #E85D2F;
  --accent-hover: #C24A18;
  --accent-deep: #A63C0F;
  --accent-tint: rgba(232, 93, 47, .10);
  --accent-tint-2: rgba(232, 93, 47, .18);

  /* Gold is a SECOND semantic accent, not a stray colour: it marks realised
     value and exportable artefacts (valuation figures, download/report
     actions). kalculator.html already used it this way consistently across the
     headline range, katalog total and per-track value - promoted here so the
     meaning is enforced rather than re-invented per page. Distinct from
     --warning, which means "attention needed". */
  --value: #8A6A1E;
  --value-2: #B08B2C;
  --value-tint: rgba(138, 106, 30, .12);

  /* ---- semantic ---- */
  --positive: #1F8A5B;
  --positive-tint: rgba(31, 138, 91, .11);
  --warning: #B07E25;
  --warning-2: #D2A03A;
  --warning-tint: rgba(192, 138, 46, .13);
  --danger: #C4483A;
  --danger-tint: rgba(196, 72, 58, .11);

  /* ---- rights-type palette (one system, reused across every chart) ---- */
  --rights-publishing: #E85D2F;
  --rights-master: #2C2824;
  --rights-neighbouring: #2F8F86;
  --rights-sync: #D2A03A;

  /* ---- radii ----
     Deliberately tighter than the previous 14px/9px. Large radii on every
     container is the single strongest "generated template" tell; a near-square
     edge reads as editorial and lets borders do the structural work. */
  --radius-card: 10px;
  --radius-control: 7px;
  --radius-logo: 7px;
  --radius-bar: 3px;
  --radius-pill: 999px;

  /* ---- type scale ----
     Ratio-based with real steps. The old scale had display-lg 28 / display 26
     / title-lg 22 - differences too small to register as hierarchy, which is
     why screens read as flat. */
  --fs-hero: 56px;
  --fs-display-xl: 44px;
  --fs-display-lg: 34px;
  --fs-display: 28px;
  --fs-title-lg: 22px;
  --fs-title: 19px;
  --fs-body-lg: 17px;
  --fs-body: 15.5px;
  --fs-ui: 14px;
  --fs-ui-sm: 13.5px;
  --fs-label: 13px;
  --fs-sub: 12.5px;
  --fs-caption: 12px;
  --fs-micro: 11px;
  --fs-eyebrow: 10.5px;
  --fs-tiny: 10px;

  /* ---- spacing - 4px base, 8px rhythm ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* legacy aliases - many pages already reference these */
  --pad: 22px;
  --pad-compact: 16px;

  /* ---- depth ----
     Three levels only, all low-contrast. Depth comes from a hairline border
     plus a barely-there shadow, not from a soft glow under everything. */
  --shadow-sm: 0 1px 2px rgba(23, 19, 15, .04);
  --shadow-md: 0 4px 16px -4px rgba(23, 19, 15, .10), 0 1px 3px rgba(23, 19, 15, .05);
  --shadow-lg: 0 18px 48px -12px rgba(23, 19, 15, .18), 0 2px 6px rgba(23, 19, 15, .05);
  --shadow-accent: 0 6px 18px -4px rgba(232, 93, 47, .34);

  /* ---- motion ---- */
  --duration-fast: 130ms;
  --duration-base: 240ms;
  --duration-slow: 420ms;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-in-out: cubic-bezier(.4, 0, .2, 1);
  --ease-spring: cubic-bezier(.34, 1.32, .64, 1);

  /* ---- focus ----
     One ring, used everywhere. Consistent focus is both an accessibility
     requirement and one of the details that separates considered products from
     prototypes. */
  --focus-ring: 0 0 0 3px rgba(232, 93, 47, .32);

  /* Translucent version of --canvas, for the blurred sticky topbar. Must be a
     literal rgba (a blur needs alpha), so it gets its own token per theme. */
  --topbar-bg: rgba(244, 243, 239, .86);
}

/* ==========================================================================
   DARK THEME
   Applied two ways:
     1. Automatically from the OS setting - pure CSS, so there is no flash of
        the light theme on load.
     2. Explicitly via <html data-theme="dark"> (the in-app toggle, persisted by
        kat-theme.js). data-theme="light" pins light even if the OS is dark.

   Almost every page aliases its local variables onto these tokens
   (--bg-panel: var(--surface), --text-primary: var(--ink), …), so redefining
   them here recolours those pages with no per-page work.

   Not a grey inversion: the hues stay warm (brown-black rather than blue-black)
   so the palette still reads as the same brand in the dark.
   ========================================================================== */
:root[data-theme='dark'] {
  --canvas: #141110;
  --surface: #1C1917;
  --surface-alt: #23201D;
  --surface-alt-2: #2A2622;
  --surface-alt-3: #191614;

  --border-sidebar: #2C2824;
  --border-card: #2E2A26;
  --border-input: #38332E;
  --border-divider: #262320;
  --border-strong: #494239;

  --ink: #F5F2ED;
  --ink-2: #DAD4CB;
  --ink-3: #B5AEA4;
  --ink-4: #9A938A;
  --ink-5: #8A837A;
  --ink-6: #756E66;
  --ink-7: #625C55;

  /* Brighter orange: #E85D2F is muddy against a near-black ground. */
  --accent: #FF7043;
  /* On dark, "hover" must LIGHTEN. The component CSS uses --accent-hover at
     rest and --accent-deep on hover, so the two are deliberately inverted here
     rather than rewriting every button rule. */
  --accent-hover: #FF7043;
  --accent-deep: #FF8C66;
  --accent-tint: rgba(255, 112, 67, .16);
  --accent-tint-2: rgba(255, 112, 67, .26);

  --value: #D4A93F;
  --value-2: #E5C169;
  --value-tint: rgba(212, 169, 63, .16);

  --positive: #4CB782;
  --positive-tint: rgba(76, 183, 130, .16);
  --warning: #D9A544;
  --warning-2: #E8BC63;
  --warning-tint: rgba(217, 165, 68, .16);
  --danger: #E8705F;
  --danger-tint: rgba(232, 112, 95, .16);

  --rights-publishing: #FF7043;
  --rights-master: #C9C1B6;
  --rights-neighbouring: #46B3A8;
  --rights-sync: #E8BC63;

  /* Inverse pair flips too, so .kat-card--dark's children stay legible. */
  --surface-dark: #241F1B;
  --surface-dark-2: #2E2823;
  --surface-dark-3: #3B342D;
  --ink-inverse: #F5F2ED;
  --ink-inverse-2: rgba(245, 242, 237, .72);
  --ink-inverse-3: rgba(245, 242, 237, .52);
  --border-inverse: rgba(245, 242, 237, .12);

  /* Shadows read as almost nothing on dark; depth comes from borders instead,
     so these are deepened rather than removed. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow-md: 0 4px 16px -4px rgba(0, 0, 0, .55), 0 1px 3px rgba(0, 0, 0, .40);
  --shadow-lg: 0 18px 48px -12px rgba(0, 0, 0, .70), 0 2px 6px rgba(0, 0, 0, .45);
  --shadow-accent: 0 6px 18px -4px rgba(255, 112, 67, .40);
  --focus-ring: 0 0 0 3px rgba(255, 112, 67, .40);
  --topbar-bg: rgba(20, 17, 16, .86);
}

/* The same block, driven by the OS. Excluded when the user has explicitly
   pinned light. Kept as a duplicate rather than a shared selector list because
   `:root[data-theme='dark'], @media …` cannot be expressed as one rule. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --canvas: #141110;
    --surface: #1C1917;
    --surface-alt: #23201D;
    --surface-alt-2: #2A2622;
    --surface-alt-3: #191614;

    --border-sidebar: #2C2824;
    --border-card: #2E2A26;
    --border-input: #38332E;
    --border-divider: #262320;
    --border-strong: #494239;

    --ink: #F5F2ED;
    --ink-2: #DAD4CB;
    --ink-3: #B5AEA4;
    --ink-4: #9A938A;
    --ink-5: #8A837A;
    --ink-6: #756E66;
    --ink-7: #625C55;

    --accent: #FF7043;
    --accent-hover: #FF7043;
    --accent-deep: #FF8C66;
    --accent-tint: rgba(255, 112, 67, .16);
    --accent-tint-2: rgba(255, 112, 67, .26);

    --value: #D4A93F;
    --value-2: #E5C169;
    --value-tint: rgba(212, 169, 63, .16);

    --positive: #4CB782;
    --positive-tint: rgba(76, 183, 130, .16);
    --warning: #D9A544;
    --warning-2: #E8BC63;
    --warning-tint: rgba(217, 165, 68, .16);
    --danger: #E8705F;
    --danger-tint: rgba(232, 112, 95, .16);

    --rights-publishing: #FF7043;
    --rights-master: #C9C1B6;
    --rights-neighbouring: #46B3A8;
    --rights-sync: #E8BC63;

    --surface-dark: #241F1B;
    --surface-dark-2: #2E2823;
    --surface-dark-3: #3B342D;
    --ink-inverse: #F5F2ED;
    --ink-inverse-2: rgba(245, 242, 237, .72);
    --ink-inverse-3: rgba(245, 242, 237, .52);
    --border-inverse: rgba(245, 242, 237, .12);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
    --shadow-md: 0 4px 16px -4px rgba(0, 0, 0, .55), 0 1px 3px rgba(0, 0, 0, .40);
    --shadow-lg: 0 18px 48px -12px rgba(0, 0, 0, .70), 0 2px 6px rgba(0, 0, 0, .45);
    --shadow-accent: 0 6px 18px -4px rgba(255, 112, 67, .40);
    --focus-ring: 0 0 0 3px rgba(255, 112, 67, .40);
    --topbar-bg: rgba(20, 17, 16, .86);
  }
}

/* Tell the browser to darken its own furniture (scrollbars, form controls). */
:root[data-theme='dark'] { color-scheme: dark; }
:root[data-theme='light'] { color-scheme: light; }

@keyframes katFade {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@keyframes katShimmer {
  from { background-position: -200% 0; }
  to { background-position: 200% 0; }
}

body.kat-shell-body {
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.55;
  /* Financial tables only align if digits share a width. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Headings inherit the display face by default so pages stop having to
   re-declare it per rule. */
body.kat-shell-body h1,
body.kat-shell-body h2,
body.kat-shell-body h3,
body.kat-shell-body h4 {
  font-family: var(--font-display);
  color: var(--ink);
  letter-spacing: -.02em;
  line-height: 1.15;
}

::selection { background: var(--accent-tint-2); color: var(--ink); }
