/* ============================================================================
   Colours — the five themes
   ----------------------------------------------------------------------------
   THIS IS THE ONLY FILE IN THE APPLICATION ALLOWED TO CONTAIN A COLOUR.
   Every hex, rgb() and rgba() literal lives here; the component stylesheets,
   the Razor views and the chart renderer all reach for a var(--token) instead.
   StyleContractTests fails the build if a colour literal appears anywhere else,
   so the contract is machine-enforced rather than aspirational.

     :root                     light   — Open Color
     [data-theme="dark"]       dark    — a navy-tinted neutral ramp
     [data-theme="soft"]       soft    — Catppuccin Macchiato
     [data-theme="latte"]      latte   — Catppuccin Latte
     [data-theme="frappe"]     frappe  — Catppuccin Frappé

   The last three are one palette family, but they are three separate blocks and
   not a base block with overrides: each flavour's own steps fall differently
   against the 4.5:1 floor, so the role a given step plays changes between them.

   theme.js stamps data-theme on <html> in <head>, before first paint. Adding a
   sixth theme means adding one block here, one entry in theme.js's THEMES and
   one button in _Layout; no component rule changes, because no component rule
   names a colour.
   ============================================================================ */

:root {
    /* ------------------------------------------------------------------------
       LIGHT — Open Color (https://yeun.github.io/open-color/)
       The Open Color step is named on every line so a future change stays
       inside the ramp instead of inventing a new grey.
       ---------------------------------------------------------------------- */

    /* Surfaces */
    --bg: #f0f2f5;                    /* app canvas */
    --surface: #ffffff;               /* cards, tiles, inputs */
    --surface-alt: #f8f9fa;           /* gray-0  — table heads, panel heads */
    --surface-sunken: #f1f3f5;        /* gray-1  — tags, wells, tab tracks */
    --surface-hover: #f1f3f5;         /* gray-1  — row and button hover */
    --surface-raised: #ffffff;        /* popovers, toasts, dialogs */

    /* Text */
    --text: #1a1a2e;                  /* headings, primary copy */
    --text-body: #495057;             /* gray-7  — running body copy */
    --text-muted: #686e75;            /* gray-6 darkened — 4.59:1 on the darkest
                                         light background (--bg); gray-6 itself
                                         was 3.32:1 and failed on all four */
    --text-subtle: #adb5bd;           /* gray-5  — placeholders, rank numerals */
    --text-inverse: #ffffff;
    --text-link: #3b5bdb;             /* indigo-7 */

    /* Borders */
    --border: #dee2e6;                /* gray-3  — card and input outlines */
    --border-strong: #ced4da;         /* gray-4  — emphasised outlines */
    --border-subtle: #f1f3f5;         /* gray-1  — row separators */

    /* Brand.
       NOTE ON THE -on-soft FOREGROUNDS: several leave the Open Color ramp. Open
       Color's darkest step in a hue is often ~3.8:1 against that hue's step-1
       background, and badge text is small. Where the ramp and WCAG AA (4.5:1)
       disagree, the contrast requirement wins and the value is derived by
       darkening the ramp colour until it clears. Measured ratios are on each
       line; re-check them if a -soft background ever changes. */
    --brand: #3b5bdb;                 /* indigo-7 */
    --brand-hover: #364fc7;           /* indigo-8 */
    --brand-soft: #edf2ff;            /* indigo-0 */
    --brand-on-soft: #3b5bdb;         /* indigo-7   — 5.06:1 on brand-soft */
    --brand-ring: rgba(59, 91, 219, 0.1);

    /* Semantic — each role carries a solid pair (fill + hover) for buttons and
       a soft pair (background + foreground) for badges and notices. */
    --success: #288137;               /* green-9 darkened — white-on-fill is 4.90:1
                                         (green-9 itself gave 4.37:1 and failed
                                         .btn-success); also 4.90:1 as .text-green */
    --success-hover: #237032;
    --success-soft: #d3f9d8;          /* green-1 */
    --success-on-soft: #237032;       /* green-9 darkened — 5.33:1 (green-9 was 3.81) */

    --danger: #e03131;                /* red-8 */
    --danger-hover: #c92a2a;          /* red-9 */
    --danger-soft: #ffe3e3;           /* red-1 */
    --danger-on-soft: #c92a2a;        /* red-9      — 4.51:1 on danger-soft */

    --warning: #e67700;               /* orange-9 */
    --warning-hover: #d9480f;
    --warning-soft: #fff3bf;          /* yellow-1 */
    --warning-on-soft: #a85700;       /* orange-9 darkened — 4.67:1 (orange-9 was 2.69) */

    --info: #1971c2;                  /* blue-8 */
    --info-hover: #1864ab;            /* blue-9 */
    --info-soft: #d0ebff;             /* blue-1 */
    --info-on-soft: #1864ab;          /* blue-9    — 4.93:1 (blue-8 was 4.07) */

    --neutral-soft: #f1f3f5;          /* gray-1 */
    --neutral-on-soft: #686e75;       /* gray-6 darkened — 4.63:1 (gray-6 was 3.32) */

    /* A fifth severity between warning and danger: score D, risk High. */
    --severe: #d9480f;                /* orange-9 dark */
    --severe-soft: #ffe8cc;           /* orange-1 */
    --severe-on-soft: #bd3f0d;        /* orange-9 darkened — 4.55:1 */

    --accent-violet: #7048e8;         /* violet-7 — PR interaction node */

    /* Elevation */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
    --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.1);
    --shadow-xl: 0 12px 40px rgba(0, 0, 0, 0.18);
    --shadow-inset-focus: inset 0 0 0 1px var(--brand);
    --backdrop: rgba(17, 24, 39, 0.45);

    /* Sidebar — its own scale because it stays dark in every theme. */
    --sidebar-bg: #1a1a2e;
    --sidebar-brand-text: #ffffff;
    --sidebar-brand-sub: rgba(255, 255, 255, 0.4);
    --sidebar-border: rgba(255, 255, 255, 0.08);
    --sidebar-group: rgba(255, 255, 255, 0.35);
    --sidebar-item: rgba(255, 255, 255, 0.55);
    --sidebar-item-hover-bg: rgba(255, 255, 255, 0.08);
    --sidebar-item-hover-text: rgba(255, 255, 255, 0.9);
    --sidebar-item-active-bg: rgba(255, 255, 255, 0.12);
    --sidebar-item-active-text: #ffffff;
    --sidebar-scroll-thumb: rgba(255, 255, 255, 0.2);
    --sidebar-scroll-thumb-hover: rgba(255, 255, 255, 0.35);

    /* Status bar — shares the sidebar's dark ground. */
    --statusbar-bg: #1a1a2e;
    --statusbar-text: #ffffff;
    --statusbar-muted: rgba(255, 255, 255, 0.7);
    --statusbar-link: rgba(255, 255, 255, 0.5);
    --statusbar-chip-bg: rgba(255, 255, 255, 0.15);

    /* Code and log surfaces — dark in every theme, so they read as terminal
       output rather than as page content. */
    --code-bg: #0f172a;
    --code-text: #e2e8f0;
    --code-inline-bg: #f1f3f5;
    --code-inline-text: #1a1a2e;
    /* Highlighted code, drawn on --code-bg. That ground is dark in every theme,
       so these are Open Color's light steps and each clears 4.5:1 on it. dark and
       latte keep them; soft and frappe use their own flavour's accents. */
    --code-comment: #8b95a7;          /* slate, between gray-5 and gray-6 */
    --code-keyword: #b197fc;          /* violet-4 */
    --code-string: #8ce99a;           /* green-3 */
    --code-number: #ffc078;           /* orange-3 */
    --code-title: #74c0fc;            /* blue-3   functions and sections */
    --code-type: #66d9e8;             /* cyan-3   types and built-ins */
    --code-attr: #ffa8a8;             /* red-3    attributes, properties, variables */
    --code-meta: #ffe066;             /* yellow-4 preprocessor lines and annotations */
    --code-added: #8ce99a;            /* green-3 */
    --code-removed: #ffa8a8;          /* red-3 */
    --log-time: #64748b;
    --log-info: #93c5fd;
    --log-warning: #fcd34d;
    --log-warning-bg: rgba(252, 211, 77, 0.06);
    --log-error: #fca5a5;
    --log-error-bg: rgba(252, 165, 165, 0.08);
    --log-row-border: rgba(255, 255, 255, 0.04);
    --log-row-hover: rgba(255, 255, 255, 0.04);

    /* Diff */
    --diff-add-bg: #dcfce7;
    --diff-add-text: #166534;
    --diff-del-bg: #fef2f2;
    --diff-del-text: #991b1b;
    --diff-hunk-bg: #eff6ff;
    --diff-hunk-text: #1e40af;
    --diff-file-bg: #f8fafc;
    --diff-active-bg: #e0edff;

    /* Drag and drop */
    --dnd-target-bg: #f8faff;
    --dnd-over-bg: #eef2ff;
    --dnd-chip-active-bg: #e7f0ff;
    --dnd-chip-active-border: #c7d8ff;
    --dnd-chip-active-text: #1e3a8a;

    /* Charts — eight categorical series plus the three chrome colours the
       renderer needs. ckwm-charts.js reads these off the document element, so
       a theme switch repaints every chart with no JavaScript palette of its
       own. Ordered for maximum adjacent-pair contrast. */
    --chart-1: #3b5bdb;               /* indigo-7 */
    --chart-2: #2b8a3e;               /* green-9 */
    --chart-3: #e67700;               /* orange-9 */
    --chart-4: #7048e8;               /* violet-7 */
    --chart-5: #c2255c;               /* pink-9 */
    --chart-6: #0b7285;               /* cyan-9 */
    --chart-7: #862e9c;               /* grape-9 */
    --chart-8: #5c940d;               /* lime-9 */
    --chart-9: #1098ad;               /* cyan-7 */
    --chart-10: #66a80f;              /* lime-8 */
    --chart-11: #d6336c;              /* pink-8 */
    --chart-12: #5f3dc4;              /* violet-9 */
    --chart-axis: #686e75;            /* matches --text-muted */
    --chart-grid: #e9ecef;            /* gray-2 */
    --chart-value: #495057;           /* gray-7 */
    --chart-track: #f1f3f5;           /* gray-1 — unfilled bar background */
    --chart-baseline: #adb5bd;        /* gray-5 */
    --chart-label-on-fill: #ffffff;

    /* Sequential heatmap ramp — five steps, empty to busiest. A sequential scale
       must be ordered by lightness, not by hue, or the reader cannot rank cells. */
    --heat-0: #f1f3f5;                /* gray-1 — no activity */
    --heat-1: #d3f9d8;                /* green-1 */
    --heat-2: #8ce99a;                /* green-3 */
    --heat-3: #51cf66;                /* green-5 */
    --heat-4: #2b8a3e;                /* green-9 */

    /* Floating tooltip — dark in every theme, like the code surfaces. */
    --tooltip-bg: #1a1a2e;
    --tooltip-text: #ffffff;
    --tooltip-muted: #adb5bd;
}

/* ============================================================================
   DARK THEME — a navy-tinted neutral ramp, hue-matched to the brand ink.
   Solid semantic fills lighten (a 700-level green on a near-black surface is
   unreadable) and the soft pairs become low-chroma tints of the same hue.
   ========================================================================== */
[data-theme="dark"] {
    --bg: #12121c;
    --surface: #1b1b2a;
    --surface-alt: #232336;
    --surface-sunken: #16161f;
    --surface-hover: #262639;
    --surface-raised: #232336;

    --text: #e6e8f0;
    --text-body: #c3c7d6;
    --text-muted: #8b90a8;
    --text-subtle: #6b7091;
    --text-inverse: #12121c;
    --text-link: #91a7ff;

    --border: #2e2e42;
    --border-strong: #3d3d55;
    --border-subtle: #242434;

    --brand: #5c7cfa;
    --brand-hover: #748ffc;
    --brand-soft: #262c4d;
    --brand-on-soft: #a3b3ff;
    --brand-ring: rgba(116, 143, 252, 0.22);

    --success: #37b24d;
    --success-hover: #40c057;
    --success-soft: #1d3527;
    --success-on-soft: #8ce99a;

    --danger: #f03e3e;
    --danger-hover: #ff6b6b;
    --danger-soft: #3d2029;
    --danger-on-soft: #ffa8a8;

    --warning: #f59f00;
    --warning-hover: #ffa94d;
    --warning-soft: #3d2c14;
    --warning-on-soft: #ffd8a8;

    --info: #1c7ed6;
    --info-hover: #4dabf7;
    --info-soft: #16304a;
    --info-on-soft: #a5d8ff;

    --neutral-soft: #262639;
    --neutral-on-soft: #8b90a8;

    --severe: #f76707;
    --severe-soft: #402512;
    --severe-on-soft: #ffc078;

    --accent-violet: #9775fa;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.5);
    --shadow-xl: 0 12px 40px rgba(0, 0, 0, 0.65);
    --backdrop: rgba(6, 6, 12, 0.65);

    --sidebar-bg: #16161f;
    --sidebar-border: rgba(255, 255, 255, 0.06);

    --statusbar-bg: #16161f;

    --code-bg: #0d0d16;
    --code-text: #c3c7d6;
    --code-inline-bg: #262639;
    --code-inline-text: #e6e8f0;
    --log-time: #6b7091;

    --diff-add-bg: #14301f;
    --diff-add-text: #8ce99a;
    --diff-del-bg: #38181f;
    --diff-del-text: #ffa8a8;
    --diff-hunk-bg: #1b2a45;
    --diff-hunk-text: #a5d8ff;
    --diff-file-bg: #1f1f2f;
    --diff-active-bg: #262c4d;

    --dnd-target-bg: #191926;
    --dnd-over-bg: #262c4d;
    --dnd-chip-active-bg: #262c4d;
    --dnd-chip-active-border: #3d4675;
    --dnd-chip-active-text: #a3b3ff;

    --chart-1: #748ffc;
    --chart-2: #51cf66;
    --chart-3: #ffa94d;
    --chart-4: #b197fc;
    --chart-5: #f783ac;
    --chart-6: #3bc9db;
    --chart-7: #da77f2;
    --chart-8: #a9e34b;
    --chart-9: #22b8cf;
    --chart-10: #94d82d;
    --chart-11: #f06595;
    --chart-12: #845ef7;
    --chart-axis: #8b90a8;
    --chart-grid: #2e2e42;
    --chart-value: #c3c7d6;
    --chart-track: #232336;
    --chart-baseline: #6b7091;
    --chart-label-on-fill: #12121c;

    --heat-0: #232336;
    --heat-1: #1d3527;
    --heat-2: #2b6a3c;
    --heat-3: #40c057;
    --heat-4: #8ce99a;

    --tooltip-bg: #262639;
    --tooltip-text: #e6e8f0;
    --tooltip-muted: #8b90a8;
}

/* ============================================================================
   SOFT THEME — Catppuccin Macchiato.
   Macchiato's accents are pastel by design, so they carry as text and as chart
   series but are too low-contrast to sit under white button labels. Solid
   fills therefore take the pastel accent with DARK text (--text-inverse maps
   to crust), which is the palette's own convention.
   ========================================================================== */
[data-theme="soft"] {
    --bg: #1e2030;                    /* mantle */
    --surface: #24273a;               /* base */
    --surface-alt: #303446;           /* between base and surface0 */
    --surface-sunken: #1e2030;        /* mantle */
    --surface-hover: #363a4f;         /* surface0 */
    --surface-raised: #303446;

    --text: #cad3f5;                  /* text */
    --text-body: #b8c0e0;             /* subtext1 */
    --text-muted: #a5adcb;            /* subtext0 */
    --text-subtle: #8087a2;           /* overlay1 */
    --text-inverse: #181926;          /* crust — label colour on pastel fills */
    --text-link: #8aadf4;             /* blue */

    --border: #494d64;                /* surface1 */
    --border-strong: #5b6078;         /* surface2 */
    --border-subtle: #363a4f;         /* surface0 */

    --brand: #8aadf4;                 /* blue */
    --brand-hover: #b7bdf8;           /* lavender */
    --brand-soft: #363a4f;            /* surface0 */
    --brand-on-soft: #8aadf4;
    --brand-ring: rgba(138, 173, 244, 0.25);

    --success: #a6da95;               /* green */
    --success-hover: #b8e3aa;
    --success-soft: #363a4f;
    --success-on-soft: #a6da95;

    --danger: #ed8796;                /* red */
    --danger-hover: #ee99a0;          /* maroon */
    --danger-soft: #363a4f;
    --danger-on-soft: #ed8796;

    --warning: #eed49f;               /* yellow */
    --warning-hover: #f5a97f;         /* peach */
    --warning-soft: #363a4f;
    --warning-on-soft: #eed49f;

    --info: #8bd5ca;                  /* teal */
    --info-hover: #91d7e3;            /* sky */
    --info-soft: #363a4f;
    --info-on-soft: #8bd5ca;

    --neutral-soft: #363a4f;
    --neutral-on-soft: #a5adcb;

    --severe: #f5a97f;                /* peach */
    --severe-soft: #363a4f;
    --severe-on-soft: #f5a97f;

    --accent-violet: #c6a0f6;         /* mauve */

    --shadow-sm: 0 1px 2px rgba(24, 25, 38, 0.5);
    --shadow-md: 0 4px 12px rgba(24, 25, 38, 0.45);
    --shadow-lg: 0 4px 16px rgba(24, 25, 38, 0.55);
    --shadow-xl: 0 12px 40px rgba(24, 25, 38, 0.7);
    --backdrop: rgba(24, 25, 38, 0.6);

    --sidebar-bg: #181926;            /* crust */
    --sidebar-brand-text: #cad3f5;
    --sidebar-brand-sub: #8087a2;
    --sidebar-border: rgba(202, 211, 245, 0.08);
    --sidebar-group: #8087a2;         /* overlay1 — overlay0 was 3.73:1 on crust */
    --sidebar-item: #a5adcb;          /* subtext0 */
    --sidebar-item-hover-bg: rgba(202, 211, 245, 0.07);
    --sidebar-item-hover-text: #cad3f5;
    --sidebar-item-active-bg: rgba(138, 173, 244, 0.14);
    --sidebar-item-active-text: #8aadf4;
    --sidebar-scroll-thumb: rgba(202, 211, 245, 0.18);
    --sidebar-scroll-thumb-hover: rgba(202, 211, 245, 0.3);

    --statusbar-bg: #181926;
    --statusbar-text: #cad3f5;
    --statusbar-muted: #a5adcb;
    --statusbar-link: #8087a2;
    --statusbar-chip-bg: rgba(202, 211, 245, 0.12);

    --code-bg: #181926;               /* crust */
    --code-text: #cad3f5;
    --code-inline-bg: #363a4f;
    --code-inline-text: #cad3f5;
    --code-comment: #939ab7;          /* overlay2 */
    --code-keyword: #c6a0f6;          /* mauve */
    --code-string: #a6da95;           /* green */
    --code-number: #f5a97f;           /* peach */
    --code-title: #8aadf4;            /* blue */
    --code-type: #eed49f;             /* yellow */
    --code-attr: #8bd5ca;             /* teal */
    --code-meta: #f5bde6;             /* pink */
    --code-added: #a6da95;            /* green */
    --code-removed: #ed8796;          /* red */
    --log-time: #6e738d;
    --log-info: #8aadf4;
    --log-warning: #eed49f;
    --log-warning-bg: rgba(238, 212, 159, 0.08);
    --log-error: #ed8796;
    --log-error-bg: rgba(237, 135, 150, 0.1);
    --log-row-border: rgba(202, 211, 245, 0.05);
    --log-row-hover: rgba(202, 211, 245, 0.05);

    --diff-add-bg: rgba(166, 218, 149, 0.14);
    --diff-add-text: #a6da95;
    --diff-del-bg: rgba(237, 135, 150, 0.14);
    --diff-del-text: #ed8796;
    --diff-hunk-bg: rgba(138, 173, 244, 0.14);
    --diff-hunk-text: #8aadf4;
    --diff-file-bg: #1e2030;
    --diff-active-bg: rgba(138, 173, 244, 0.16);

    --dnd-target-bg: #1e2030;
    --dnd-over-bg: rgba(138, 173, 244, 0.12);
    --dnd-chip-active-bg: rgba(138, 173, 244, 0.16);
    --dnd-chip-active-border: #5b6078;
    --dnd-chip-active-text: #8aadf4;

    --chart-1: #8aadf4;               /* blue */
    --chart-2: #a6da95;               /* green */
    --chart-3: #f5a97f;               /* peach */
    --chart-4: #c6a0f6;               /* mauve */
    --chart-5: #f5bde6;               /* pink */
    --chart-6: #8bd5ca;               /* teal */
    --chart-7: #b7bdf8;               /* lavender */
    --chart-8: #eed49f;               /* yellow */
    --chart-9: #7dc4e4;               /* sapphire */
    --chart-10: #f0c6c6;              /* flamingo */
    --chart-11: #ee99a0;              /* maroon */
    --chart-12: #91d7e3;              /* sky */
    --chart-axis: #a5adcb;
    --chart-grid: #494d64;
    --chart-value: #b8c0e0;
    --chart-track: #363a4f;
    --chart-baseline: #6e738d;
    --chart-label-on-fill: #181926;

    --heat-0: #363a4f;                /* surface0 */
    --heat-1: #4a5c4d;
    --heat-2: #6a8f6b;
    --heat-3: #86bd82;
    --heat-4: #a6da95;                /* green */

    --tooltip-bg: #363a4f;            /* surface0 */
    --tooltip-text: #cad3f5;
    --tooltip-muted: #a5adcb;
}

/* ============================================================================
   LATTE THEME — Catppuccin Latte, the family's light flavour.
   Latte's ramp is compressed: subtext0 measures 4.37:1 on base and its accents
   sit between 2.3:1 and 4.9:1 against white, so almost nothing clears AA at the
   size this application sets text. Every value below that leaves the palette is
   the same colour darkened in HSL, hue and saturation untouched, until it
   clears; the measured ratio is on the line. Solid fills therefore carry WHITE
   labels, the light-theme convention, not the pastel-with-dark-text convention
   the Macchiato block uses.

   Code, log and tooltip surfaces are deliberately NOT overridden here: they are
   dark in every theme, and Latte has no dark step to build them from.
   ========================================================================== */
[data-theme="latte"] {
    /* Surfaces. Every text-bearing surface is base or mantle; crust is reserved
       for the sidebar, because subtext-grade text does not clear AA on it. */
    --bg: #e6e9ef;                    /* mantle — app canvas, the darkest ground */
    --surface: #eff1f5;               /* base */
    --surface-alt: #eaedf2;           /* between base and mantle */
    --surface-sunken: #e6e9ef;        /* mantle */
    --surface-hover: #e6e9ef;         /* mantle */
    --surface-raised: #eff1f5;        /* base */

    --text: #4c4f69;                  /* text     — 6.57:1 on --bg */
    --text-body: #5c5f77;             /* subtext1 — 5.14:1 on --bg */
    --text-muted: #63667a;            /* subtext0 darkened 8% — 4.65:1 on --bg;
                                         subtext0 itself was 4.06 and failed */
    --text-subtle: #8c8fa1;           /* overlay1 — placeholders, rank numerals */
    --text-inverse: #ffffff;          /* label colour on solid fills */
    --text-link: #0a4fd9;             /* blue darkened 18% — 5.93:1 on --surface */

    --border: #ccd0da;                /* surface0 */
    --border-strong: #bcc0cc;         /* surface1 */
    --border-subtle: #dce0e8;         /* crust */

    /* Roles. A solid doubles as a text colour (.text-green, alert icons), so it
       is measured against --surface; a -on-soft is measured against its own
       -soft, which is that accent at 15% over base. */
    --brand: #0a4fd9;                 /* blue darkened 18% — 5.93:1 on --surface */
    --brand-hover: #0843b8;
    --brand-soft: #d0dcf5;
    --brand-on-soft: #0a4fd9;         /* 4.86:1 on brand-soft */
    --brand-ring: rgba(10, 79, 217, 0.14);

    --success: #2c6d1d;               /* green darkened 32% — 5.61:1 on --surface */
    --success-hover: #255d19;
    --success-soft: #d5e5d7;
    --success-on-soft: #2c6d1d;       /* 4.84:1 on success-soft */

    --danger: #d20f39;                /* red — 4.80:1 on --surface, kept as-is */
    --danger-hover: #b20d30;
    --danger-soft: #ebcfd9;
    --danger-on-soft: #b20d30;        /* red darkened 15% — 4.83:1 (red was 3.74) */

    --warning: #885712;               /* yellow darkened 39% — 5.43:1 on --surface;
                                         yellow itself was 2.31 and unusable as text */
    --warning-hover: #744a0f;
    --warning-soft: #ede2d5;
    --warning-on-soft: #885712;       /* 4.81:1 on warning-soft */

    --info: #11696e;                  /* teal darkened 28% — 5.68:1 on --surface */
    --info-hover: #0e595e;
    --info-soft: #cfe3e7;
    --info-on-soft: #11696e;          /* 4.83:1 on info-soft */

    --neutral-soft: #e6e9ef;          /* mantle */
    --neutral-on-soft: #63667a;       /* 4.65:1 on neutral-soft */

    --severe: #a63d01;                /* peach darkened 37% — 5.65:1 on --surface */
    --severe-soft: #f1dcd2;
    --severe-on-soft: #a63d01;        /* 4.84:1 on severe-soft */

    --accent-violet: #8839ef;         /* mauve — 4.79:1 on --surface, kept as-is */

    --shadow-sm: 0 1px 2px rgba(76, 79, 105, 0.12);
    --shadow-md: 0 4px 12px rgba(76, 79, 105, 0.08);
    --shadow-lg: 0 4px 16px rgba(76, 79, 105, 0.12);
    --shadow-xl: 0 12px 40px rgba(76, 79, 105, 0.2);
    --backdrop: rgba(76, 79, 105, 0.45);

    /* Sidebar. Latte's is light — crust, the palette's own chrome step — so all
       twelve tokens are restated; the inherited dark scale would be white ink. */
    --sidebar-bg: #dce0e8;            /* crust */
    --sidebar-brand-text: #4c4f69;    /* 6.04:1 on crust */
    --sidebar-brand-sub: #6c6f85;     /* subtext0 — a sub-label, not body text */
    --sidebar-border: rgba(76, 79, 105, 0.12);
    --sidebar-group: #6c6f85;         /* subtext0 — section headers, same class */
    --sidebar-item: #5c5f77;          /* subtext1 — 4.73:1 on crust */
    --sidebar-item-hover-bg: rgba(76, 79, 105, 0.07);
    --sidebar-item-hover-text: #4c4f69;
    --sidebar-item-active-bg: rgba(10, 79, 217, 0.12);
    --sidebar-item-active-text: #0a4fd9;   /* 5.07:1 on crust (blue was 3.71) */
    --sidebar-scroll-thumb: rgba(76, 79, 105, 0.2);
    --sidebar-scroll-thumb-hover: rgba(76, 79, 105, 0.32);

    --statusbar-bg: #dce0e8;
    --statusbar-text: #4c4f69;
    --statusbar-muted: #5c5f77;
    --statusbar-link: #6c6f85;
    --statusbar-chip-bg: rgba(76, 79, 105, 0.1);

    --code-inline-bg: #e6e9ef;
    --code-inline-text: #4c4f69;

    --diff-add-bg: #d5e5d7;
    --diff-add-text: #2c6d1d;
    --diff-del-bg: #ebcfd9;
    --diff-del-text: #b20d30;
    --diff-hunk-bg: #d0dcf5;
    --diff-hunk-text: #0a4fd9;
    --diff-file-bg: #eaedf2;
    --diff-active-bg: #d0dcf5;

    --dnd-target-bg: #eaedf2;
    --dnd-over-bg: #d0dcf5;
    --dnd-chip-active-bg: #d0dcf5;
    --dnd-chip-active-border: #bcc0cc;
    --dnd-chip-active-text: #0a4fd9;

    /* Charts take the accents unaltered: these are fills, not text, and hue
       separation matters more here than the 4.5:1 floor. */
    --chart-1: #1e66f5;               /* blue */
    --chart-2: #40a02b;               /* green */
    --chart-3: #fe640b;               /* peach */
    --chart-4: #8839ef;               /* mauve */
    --chart-5: #ea76cb;               /* pink */
    --chart-6: #179299;               /* teal */
    --chart-7: #7287fd;               /* lavender */
    --chart-8: #df8e1d;               /* yellow */
    --chart-9: #209fb5;               /* sapphire */
    --chart-10: #dd7878;              /* flamingo */
    --chart-11: #e64553;              /* maroon */
    --chart-12: #04a5e5;              /* sky */
    --chart-axis: #63667a;
    --chart-grid: #dce0e8;
    --chart-value: #5c5f77;
    --chart-track: #e6e9ef;
    --chart-baseline: #9ca0b0;        /* overlay0 */
    --chart-label-on-fill: #ffffff;

    --heat-0: #e6e9ef;                /* mantle — no activity */
    --heat-1: #bcd7be;
    --heat-2: #93c48d;
    --heat-3: #6ab25c;
    --heat-4: #40a02b;                /* green */
}

/* ============================================================================
   FRAPPE THEME — Catppuccin Frappé, one step lighter than Macchiato.
   That single step is what forces this block to differ from the Macchiato one
   rather than copy it: Frappé's surface0 is light enough that blue (4.10:1) and
   red (3.57:1) fail on it, so the badge ground drops to crust, where the whole
   accent set clears with room. Solid fills keep the family convention of a
   pastel fill under dark text, with --text-inverse mapped to crust.
   ========================================================================== */
[data-theme="frappe"] {
    --bg: #292c3c;                    /* mantle */
    --surface: #303446;               /* base */
    --surface-alt: #383c50;           /* between base and surface0 */
    --surface-sunken: #292c3c;        /* mantle */
    --surface-hover: #383c50;         /* surface0 was 4.26:1 under subtext0 */
    --surface-raised: #383c50;

    --text: #c6d0f5;                  /* text */
    --text-body: #b5bfe2;             /* subtext1 */
    --text-muted: #a5adce;            /* subtext0 — 4.91:1 on --surface-hover */
    --text-subtle: #838ba7;           /* overlay1 */
    --text-inverse: #232634;          /* crust — label colour on pastel fills */
    --text-link: #8caaee;             /* blue */

    --border: #51576d;                /* surface1 */
    --border-strong: #626880;         /* surface2 */
    --border-subtle: #414559;         /* surface0 */

    /* Every -soft ground is crust. One neutral ground for all six roles is the
       Macchiato block's convention; only the step chosen differs. */
    --brand: #8caaee;                 /* blue */
    --brand-hover: #babbf1;           /* lavender */
    --brand-soft: #232634;            /* crust */
    --brand-on-soft: #8caaee;         /* 6.51:1 on crust */
    --brand-ring: rgba(140, 170, 238, 0.25);

    --success: #a6d189;               /* green */
    --success-hover: #b6d99e;
    --success-soft: #232634;
    --success-on-soft: #a6d189;       /* 8.66:1 */

    --danger: #e78284;                /* red */
    --danger-hover: #ea999c;          /* maroon */
    --danger-soft: #232634;
    --danger-on-soft: #e78284;        /* 5.67:1 */

    --warning: #e5c890;               /* yellow */
    --warning-hover: #ef9f76;         /* peach */
    --warning-soft: #232634;
    --warning-on-soft: #e5c890;       /* 9.29:1 */

    --info: #81c8be;                  /* teal */
    --info-hover: #99d1db;            /* sky */
    --info-soft: #232634;
    --info-on-soft: #81c8be;          /* 7.82:1 */

    --neutral-soft: #232634;
    --neutral-on-soft: #a5adce;       /* 6.77:1 */

    --severe: #ef9f76;                /* peach */
    --severe-soft: #232634;
    --severe-on-soft: #ef9f76;        /* 7.07:1 */

    --accent-violet: #ca9ee6;         /* mauve */

    --shadow-sm: 0 1px 2px rgba(35, 38, 52, 0.5);
    --shadow-md: 0 4px 12px rgba(35, 38, 52, 0.45);
    --shadow-lg: 0 4px 16px rgba(35, 38, 52, 0.55);
    --shadow-xl: 0 12px 40px rgba(35, 38, 52, 0.7);
    --backdrop: rgba(35, 38, 52, 0.6);

    --sidebar-bg: #232634;            /* crust */
    --sidebar-brand-text: #c6d0f5;
    --sidebar-brand-sub: #838ba7;
    --sidebar-border: rgba(198, 208, 245, 0.08);
    --sidebar-group: #949cbb;         /* overlay2 — overlay1 was 4.45:1 on crust */
    --sidebar-item: #a5adce;          /* subtext0 — 6.77:1 on crust */
    --sidebar-item-hover-bg: rgba(198, 208, 245, 0.07);
    --sidebar-item-hover-text: #c6d0f5;
    --sidebar-item-active-bg: rgba(140, 170, 238, 0.14);
    --sidebar-item-active-text: #8caaee;
    --sidebar-scroll-thumb: rgba(198, 208, 245, 0.18);
    --sidebar-scroll-thumb-hover: rgba(198, 208, 245, 0.3);

    --statusbar-bg: #232634;
    --statusbar-text: #c6d0f5;
    --statusbar-muted: #a5adce;
    --statusbar-link: #838ba7;
    --statusbar-chip-bg: rgba(198, 208, 245, 0.12);

    --code-bg: #232634;               /* crust */
    --code-text: #c6d0f5;
    --code-inline-bg: #414559;
    --code-inline-text: #c6d0f5;
    --code-comment: #949cbb;          /* overlay2 */
    --code-keyword: #ca9ee6;          /* mauve */
    --code-string: #a6d189;           /* green */
    --code-number: #ef9f76;           /* peach */
    --code-title: #8caaee;            /* blue */
    --code-type: #e5c890;             /* yellow */
    --code-attr: #81c8be;             /* teal */
    --code-meta: #f4b8e4;             /* pink */
    --code-added: #a6d189;            /* green */
    --code-removed: #e78284;          /* red */
    --log-time: #737994;              /* overlay0 */
    --log-info: #8caaee;
    --log-warning: #e5c890;
    --log-warning-bg: rgba(229, 200, 144, 0.08);
    --log-error: #e78284;
    --log-error-bg: rgba(231, 130, 132, 0.1);
    --log-row-border: rgba(198, 208, 245, 0.05);
    --log-row-hover: rgba(198, 208, 245, 0.05);

    --diff-add-bg: rgba(166, 209, 137, 0.14);
    --diff-add-text: #a6d189;
    --diff-del-bg: rgba(231, 130, 132, 0.14);
    --diff-del-text: #e78284;
    --diff-hunk-bg: rgba(140, 170, 238, 0.14);
    --diff-hunk-text: #8caaee;
    --diff-file-bg: #292c3c;
    --diff-active-bg: rgba(140, 170, 238, 0.16);

    --dnd-target-bg: #292c3c;
    --dnd-over-bg: rgba(140, 170, 238, 0.12);
    --dnd-chip-active-bg: rgba(140, 170, 238, 0.16);
    --dnd-chip-active-border: #626880;
    --dnd-chip-active-text: #8caaee;

    --chart-1: #8caaee;               /* blue */
    --chart-2: #a6d189;               /* green */
    --chart-3: #ef9f76;               /* peach */
    --chart-4: #ca9ee6;               /* mauve */
    --chart-5: #f4b8e4;               /* pink */
    --chart-6: #81c8be;               /* teal */
    --chart-7: #babbf1;               /* lavender */
    --chart-8: #e5c890;               /* yellow */
    --chart-9: #85c1dc;               /* sapphire */
    --chart-10: #eebebe;              /* flamingo */
    --chart-11: #ea999c;              /* maroon */
    --chart-12: #99d1db;              /* sky */
    --chart-axis: #a5adce;
    --chart-grid: #51576d;
    --chart-value: #b5bfe2;
    --chart-track: #414559;
    --chart-baseline: #737994;
    --chart-label-on-fill: #232634;

    --heat-0: #414559;                /* surface0 */
    --heat-1: #5a6865;
    --heat-2: #748b71;
    --heat-3: #8dae7d;
    --heat-4: #a6d189;                /* green */

    --tooltip-bg: #414559;            /* surface0 */
    --tooltip-text: #c6d0f5;
    --tooltip-muted: #b5bfe2;         /* subtext0 was 4.26:1 on surface0 */
}
