/**
 * LLM Monitor - Custom Styles
 * @comments-complete 2026-10-04
 *
 * Shared stylesheet of every authenticated view, loaded once by partials/head_assets.php
 * (cache-busting version: $headAssetsCssVersion there). Three parts: the :root blocks, where
 * every color, overlay and shadow value lives as a token (the Senuto design system slots for the
 * dark theme, :root.light with the light theme slots, then the app tokens that are expressions of
 * those slots, followed by one token section per view and a second :root.light block with the
 * light value of the few view tokens no slot can express), and the component rules below them
 * (cards, buttons, badges, alerts, forms, tables, modal), which read only var(--token) and
 * carry no color literal. Only the @media print block keeps plain colors, on purpose.
 */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');

/* ===== Theme slots (light theme stage 5b) =====
   Two themes, one set of component rules. The class on <html> (dark or light, set by
   partials/head_assets.php) picks the slot values: the first block below holds the dark theme
   and is also what a page without a class (sign-in) renders, :root.light overrides it.
   Slot names and values are those of the Senuto design system (senuto-lab-ds 0.12.0, 2026-10-04);
   values copied by hand from tokens/semantic.json; change the pattern first, then here.
   Everything else further down (aliases, tints, frame tokens) is an expression of these slots
   and follows the theme on its own: the class sits on the same element as :root, so the
   var() expressions are resolved against the active slot values. A token that has no slot and
   must differ per theme is an app token with a pair of values, marked "app token, no
   design-system slot": its dark value is in the block right below and its light value in :root.light.
   A view token that must differ per theme (JS parses it, or no slot expresses it) keeps its dark value in
   its view section and its light value in the second :root.light block, after the view sections. */
:root {
  color-scheme: dark;

  /* ===== Slots (design-system names), dark theme ===== */
  --background:                 #0a0a0a;
  --foreground:                 #fafafa;
  --card:                       #171717;
  --card-foreground:            #fafafa;
  --popover:                    #262626;
  --popover-foreground:         #fafafa;
  --muted:                      #262626;
  --muted-foreground:           #a3a3a3;
  --border:                     #ffffff1a;
  --input:                      #ffffff26;
  --ring:                       #737373;
  --primary:                    #5f4af3;
  --primary-foreground:         #fafafa;
  --link:                       #8d7ef6;
  --success:                    #4ade80;
  --success-foreground:         #171717;
  --warning:                    #fbbf24;
  --warning-foreground:         #171717;
  --destructive:                #f87171;
  --destructive-foreground:     #171717;
  --sidebar:                    #171717;
  --sidebar-foreground:         #fafafa;
  --sidebar-primary:            #5f4af3;
  --sidebar-primary-foreground: #fafafa;
  --sidebar-accent:             #262626;
  --sidebar-accent-foreground:  #fafafa;
  --sidebar-border:             #ffffff1a;
  --sidebar-ring:               #525252;
  --chart-1:                    #5f4af3;
  --chart-2:                    #2269f0;
  --chart-3:                    #c75f00;
  --chart-4:                    #df6b9b;
  --chart-5:                    #4e70e4;

  /* ===== App tokens with a pair of values, dark theme (app token, no design-system slot) ===== */
  --chart-6:        #2dd4bf;   /* series 6 (teal); the pattern has five chart slots, the app draws eight series */
  --chart-7:        #facc15;   /* series 7 (yellow) */
  --chart-8:        #22d3ee;   /* series 8 (cyan) */
  --info:           #60a5fa;   /* blue-400; the pattern has no info state */
  --success-text:   var(--success);       /* success as text or icon on a plain or tinted surface */
  --warning-text:   var(--warning);
  --destructive-text: var(--destructive);
  --info-text:      var(--info);
  --page-bg:        var(--background);    /* page background of every view's <body>; the card sits on --card in both themes */
  --overlay-modal:  rgba(0, 0, 0, 0.7);   /* scrim behind a modal */
  --shadow-badge:   0 2px 8px rgba(0, 0, 0, 0.45);
  --shadow-modal:   0 20px 25px -5px rgba(0, 0, 0, 0.5);
  --shadow-tooltip: 0 6px 18px rgba(0, 0, 0, 0.45);
  --client-frame:   #fb923c;   /* frame around the viewport while an agency works inside a client account: a hue outside the semantic palette; orange-400, 8.75 on --page-bg */
}

:root.light {
  color-scheme: light;

  /* ===== Slots (design-system names), light theme ===== */
  --background:                 #ffffff;
  --foreground:                 #0f172a;
  --card:                       #ffffff;
  --card-foreground:            #0a0a0a;
  --popover:                    #ffffff;
  --popover-foreground:         #0a0a0a;
  --muted:                      #f5f5f5;
  --muted-foreground:           #475569;
  --border:                     #e5e5e5;
  --input:                      #e5e5e5;
  --ring:                       #a3a3a3;
  --primary:                    #5f4af3;
  --primary-foreground:         #fafafa;
  --link:                       #5f4af3;
  --success:                    #16a34a;
  --success-foreground:         #171717;
  --warning:                    #d97706;
  --warning-foreground:         #171717;
  --destructive:                #dc2626;
  --destructive-foreground:     #ffffff;
  --sidebar:                    #fafafa;
  --sidebar-foreground:         #0a0a0a;
  --sidebar-primary:            #5f4af3;
  --sidebar-primary-foreground: #fafafa;
  --sidebar-accent:             #f5f5f5;
  --sidebar-accent-foreground:  #171717;
  --sidebar-border:             #e5e5e5;
  --sidebar-ring:               #a3a3a3;
  --chart-1:                    #5f4af3;
  --chart-2:                    #2269f0;
  --chart-3:                    #c75f00;
  --chart-4:                    #df6b9b;
  --chart-5:                    #18369c;

  /* ===== App tokens with a pair of values, light theme (app token, no design-system slot) ===== */
  --chart-6:        #0d9488;   /* teal-600 */
  --chart-7:        #a16207;   /* yellow-700; shade 600 reached only 2.94 on white, under the 3.0 floor of a chart mark */
  --chart-8:        #0891b2;   /* cyan-600 */
  --info:           #2563eb;   /* blue-600 */
  --success-text:   #166534;   /* green-800: the --success slot (green-600) reads 3.3 on white, and green-700 only 4.0 on its own 20% tint */
  --warning-text:   #92400e;   /* amber-800: amber-700 reads 4.2 on a 10% warning tint over the page surface */
  --destructive-text: #b91c1c; /* red-700 */
  --info-text:      #1d4ed8;   /* blue-700 */
  --page-bg:        var(--muted);         /* decision D4: a tinted page so the white card reads as a card */
  --overlay-modal:  rgba(15, 23, 42, 0.45);
  --shadow-badge:   0 2px 8px rgba(15, 23, 42, 0.12);
  --shadow-modal:   0 20px 25px -5px rgba(15, 23, 42, 0.15);
  --shadow-tooltip: 0 6px 18px rgba(15, 23, 42, 0.14);
  --client-frame:   #ea580c;   /* orange-600: orange-400 reads 2.08 on the light page, this one 3.26 on --page-bg, over the 3.0 floor of a graphic */
}

:root {
  /* Every token below is an expression of the slots above (or a fixed identity color, marked),
     declared once and valid in both themes. Components keep reading the older app token names,
     which are aliases of the slots. */

  /* ===== Backgrounds (aliases of the slots) ===== */
  --bg-primary:   var(--background);
  --bg-secondary: var(--card);
  --bg-tertiary:  var(--muted);
  --bg-code:      var(--muted);
  --card-bg:      var(--card);    /* read by views through var(--card-bg, fallback) */
  --panel-deep:   var(--muted);   /* read by views through var(--panel-deep, fallback): the inset surface */

  /* ===== Text (two levels, as in the pattern) ===== */
  --text-primary:   var(--foreground);
  --text-secondary: var(--muted-foreground);
  --text-muted:     var(--muted-foreground);

  /* ===== Accent - Senuto Purple ===== */
  --accent-primary: var(--primary);   /* fills, focus, rings, borders; never headings or numbers (use --text-primary) */
  --accent-light:   var(--link);      /* accent used as readable text; headings and numbers use --text-primary instead */
  /* End stop of the What's new gradient (sidebar pill, "New" badge of whats_new.php): a fixed identity color, the same in both themes.
     pink-700: the label (--sidebar-primary-foreground) reads 5.35 to 6.36 along the gradient; pink-600 reached only 4.40 at the pink end. */
  --accent-pink:    #be185d;

  /* Opacity variants of the accent (app tokens, no design-system slot): reuse instead of literal rgba() in inline styles */
  --accent-primary-05:  color-mix(in srgb, var(--primary) 5%, transparent);
  --accent-primary-08:  color-mix(in srgb, var(--primary) 8%, transparent);
  --accent-primary-10:  color-mix(in srgb, var(--primary) 10%, transparent);
  --accent-primary-12:  color-mix(in srgb, var(--primary) 12%, transparent);   /* shared with brand_mentions.php */
  --accent-primary-15:  color-mix(in srgb, var(--primary) 15%, transparent);
  --accent-primary-20:  color-mix(in srgb, var(--primary) 20%, transparent);
  --accent-primary-30:  color-mix(in srgb, var(--primary) 30%, transparent);
  --accent-primary-40:  color-mix(in srgb, var(--primary) 40%, transparent);

  /* ===== Semantic colors: fills and borders (aliases of the slots). As TEXT use --success-text and its siblings. ===== */
  --color-success: var(--success);
  --color-warning: var(--warning);
  --color-error:   var(--destructive);
  --color-info:    var(--info);
  --positive:      var(--success-text);       /* read by views through var(--positive, fallback): text and fill, so the text-safe shade */
  --danger:        var(--destructive-text);   /* same, for the error color */

  /* ===== Borders ===== */
  --border-subtle: var(--border);
  --border-strong: var(--input);
  --border-accent: color-mix(in srgb, var(--primary) 40%, transparent);   /* hovered card border */
  --field-border:  color-mix(in srgb, var(--muted-foreground) 65%, transparent);   /* app token, no design-system slot: the pattern's --input border reads 1.2 (light) to 1.6 (dark) on a field, under the 3.0 floor of a field border; this one reads 3.08 and 3.39 */

  /* ===== Chart series colors, read through window.LMPalette (assets/js/palette.js) =====
     --series-1..8 are the eight series of the app: --chart-1..5 of the pattern, then three app
     tokens. The client's own brand is always --chart-1. Named by role, not by hue.
     The report widgets keep their own --rpt-series-* in _rpt_styles.php. */
  --series-1:   var(--chart-1);
  --series-2:   var(--chart-2);
  --series-3:   var(--chart-3);
  --series-4:   var(--chart-4);
  --series-5:   var(--chart-5);
  --series-6:   var(--chart-6);
  --series-7:   var(--chart-7);
  --series-8:   var(--chart-8);
  --series-own: var(--chart-1);

  /* Sentiment of a brand mention (Brand Prompt ranked list). Used as text color and as fill by the views,
     so the values are the text-safe shades, which also clear 3.0 as a fill on both page surfaces. */
  --sentiment-positive: var(--success-text);
  --sentiment-neutral:  var(--muted-foreground);
  --sentiment-negative: var(--destructive-text);

  /* Citation source type (GAPs source mix): five series colors, "other" is the muted text color */
  --source-type-ranking:  var(--chart-1);
  --source-type-recenzja: var(--chart-2);
  --source-type-poradnik: var(--chart-3);
  --source-type-blog:     var(--chart-4);
  --source-type-forum:    var(--chart-5);
  --source-type-inne:     var(--muted-foreground);

  /* ===== Frame tokens (light theme stages 2 and 5b) ===== */

  /* Opacity variants of the semantic colors (app tokens, no design-system slot) */
  --color-success-10: color-mix(in srgb, var(--success) 10%, transparent);
  --color-success-20: color-mix(in srgb, var(--success) 20%, transparent);
  --color-error-10:   color-mix(in srgb, var(--destructive) 10%, transparent);
  --color-error-20:   color-mix(in srgb, var(--destructive) 20%, transparent);
  --color-info-05:    color-mix(in srgb, var(--info) 5%, transparent);
  --color-info-10:    color-mix(in srgb, var(--info) 10%, transparent);
  --color-info-20:    color-mix(in srgb, var(--info) 20%, transparent);
  --color-info-28:    color-mix(in srgb, var(--info) 28%, transparent);
  --color-warning-05: color-mix(in srgb, var(--warning) 5%, transparent);
  --color-warning-12: color-mix(in srgb, var(--warning) 12%, transparent);
  --color-warning-18: color-mix(in srgb, var(--warning) 18%, transparent);
  --color-warning-28: color-mix(in srgb, var(--warning) 28%, transparent);
  --color-warning-35: color-mix(in srgb, var(--warning) 35%, transparent);
  --text-secondary-18: color-mix(in srgb, var(--muted-foreground) 18%, transparent);   /* --text-secondary at 18% */
  --alert-warning-bg:  color-mix(in srgb, var(--warning) 10%, transparent);            /* tint of .alert-warning */

  /* Dotted underline of .lm-help tooltip triggers, shared by 8+ views */
  --lm-help-underline: color-mix(in srgb, var(--muted-foreground) 55%, transparent);

  /* Segment badges on cards: the warning slot for Branded, the brand blue for Generic */
  --seg-badge-branded-bg: var(--warning);
  --seg-badge-branded-fg: var(--warning-foreground);
  --seg-badge-generic-bg: var(--chart-2);
  --seg-badge-generic-fg: var(--primary-foreground);

  /* Side menu: sidebar* names are design-system slots, defined above; the two marked app tokens have none */
  --sidebar-foreground-dim: color-mix(in srgb, var(--sidebar-foreground) 60%, var(--sidebar));   /* app token, no design-system slot: text of the small sub-items */
  --sidebar-dot:            color-mix(in srgb, var(--sidebar-foreground) 45%, var(--sidebar));   /* app token, no design-system slot: bullet before a sub-item */

  /* Top bar and its account menu (app tokens, no design-system slot): the bar sits on the page surface */
  --topbar-bg:                    var(--background);   /* bar and account dropdown surface */
  --topbar-border:                var(--border);
  --topbar-foreground:            var(--muted-foreground);   /* icons, links and secondary text */
  --topbar-foreground-dim:        var(--muted-foreground);   /* a third text level fails 4.5 in the light theme, so it equals --topbar-foreground */
  --topbar-foreground-strong:     var(--foreground);   /* account e-mail */
  --topbar-hover-bg:              var(--muted);   /* hovered or open icon button */
  --topbar-avatar-bg:             var(--muted);
  --topbar-item-hover-bg:         color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered row of the account dropdown */
  --topbar-item-hover-foreground: var(--foreground);

  /* Global tooltip box (a popover, as in the pattern); the frame of an agency inside a client account is --client-frame, an app token with a pair of values, above */
  --tooltip-bg:         var(--popover);
  --tooltip-border:     var(--border);
  --tooltip-foreground: var(--popover-foreground);

  /* ===== Keywords view (keywords.php), light theme stage 3 =====
     Light theme stage 5b: every value below is an expression of the theme slots, so each token follows the theme on its own. */
  /* Shared candidates: roles that other views repeat */
  --kw-help-underline:        var(--lm-help-underline);   /* dotted underline of .lm-help tooltip triggers: the frame token of the same role; shared candidate */
  --kw-pending-warning-border: color-mix(in srgb, var(--warning) 30%, transparent);   /* border of the "data collection has not started" banner, pairs with --alert-warning-bg; shared candidate */

  /* Visibility and position score colors of the keyword tables: they color text, so the text-safe shades */
  --kw-score-good:  var(--success-text);       /* visibility >= 20%, position <= 3 */
  --kw-score-mid:   var(--warning-text);       /* visibility >= 5%, position <= 6 */
  --kw-score-low:   var(--destructive-text);   /* visibility below 5% */
  --kw-score-poor:  var(--destructive-text);   /* position above 6 */
  --kw-text-dim:    var(--muted-foreground);   /* no value, "prompts" sub-line, collected-on-page dot */

  /* Table hover tints */
  --kw-th-hover-bg:  color-mix(in srgb, var(--muted) 95%, var(--foreground));   /* hovered sortable header cell: the hover state of the header surface (--muted), one 5% step toward the text color */
  --kw-row-hover-bg: color-mix(in srgb, var(--foreground) 5%, transparent);     /* hovered keyword row */

  /* Toolbar, pagination bar and ledger surfaces */
  --kw-pagebar-bg:   color-mix(in srgb, var(--foreground) 3%, transparent);     /* top pagination bar of the flat table */
  --kw-subhead-bg:   color-mix(in srgb, var(--foreground) 1.5%, transparent);   /* sub-group header of the ledger */
  --kw-subwrap-bg:   color-mix(in srgb, var(--background) 25%, transparent);    /* wrapper of the sub-groups of an open group: a step toward the --background slot, darker than the card in the dark theme and invisible on the white card of the light theme */
  --kw-legend-none:  color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* "not visible" dot of the ledger legend; a graphic that carries meaning, so it keeps 3.0 on the page in both themes */

  /* Active filter chip */
  --kw-chip-fg:            var(--foreground);   /* value text of the chip; its label (<em>) and the remove button stay --accent-light */
  --kw-chip-x-hover-bg:    color-mix(in srgb, var(--link) 25%, transparent);   /* hovered remove button of a chip */
  --kw-chip-x-hover-fg:    var(--foreground);

  /* Ledger group header details */
  --kw-cc-bg:            color-mix(in srgb, var(--foreground) 6%, transparent);   /* country code pill */
  --kw-cc-border:        color-mix(in srgb, var(--foreground) 8%, transparent);
  --kw-health-track-bg:  var(--page-bg);   /* track of the strong/weak health bar: the page color seen through the card, darker than the card in the dark theme (owner decision 2026-10-04, dark tracks as in GAPs) */
  --kw-zerochip-bg:      color-mix(in srgb, var(--destructive) 12%, transparent); /* "N at 0%" chip */
  --kw-zerochip-border:  color-mix(in srgb, var(--destructive) 35%, transparent);
  --kw-zerochip-fg:      var(--destructive-text);
  --kw-pchip-bg:         color-mix(in srgb, var(--foreground) 5%, transparent);   /* "+N more" chip of the collapsed group preview */

  /* ===== Prompt detail view (prompt.php), light theme stage 3 =====
     Every value is an expression of the theme slots, so it follows the active theme. */
  --prm-avg-position:          var(--text-primary);   /* number in the "Avg position" tile: a KPI number, so the text color (decision D5 B) */
  --prm-caption:               var(--muted-foreground);   /* faint caption under a tile value and the empty-value dash */
  --prm-banner-warning-border: color-mix(in srgb, var(--warning) 30%, transparent);   /* border of the "Data collection has not started yet" banner (its background is --alert-warning-bg) */

  /* ===== Response preview partial (partials/response_preview.php), light theme stage 3 =====
     Every value is an expression of the theme slots, so it follows the active theme. */
  /* Error banner (load failure) */
  --rp-error-bg:        color-mix(in srgb, var(--destructive) 10%, transparent);
  --rp-error-border:    color-mix(in srgb, var(--destructive) 30%, transparent);
  --rp-error-text:      var(--destructive-text);

  /* "Data collection has not started yet" banner: background is --alert-warning-bg, only the border is new */
  --rp-pending-border:  color-mix(in srgb, var(--warning) 30%, transparent);   /* pairs with --alert-warning-bg */

  /* "Cited" badge on a citation */
  --rp-cited-bg:        color-mix(in srgb, var(--info) 20%, var(--card));   /* opaque, so the badge reads the same on a plain row, a monitored row and the card */
  --rp-cited-fg:        var(--info-text);

  /* Text and links inside the citation, source, link, shopping, map and recommendation lists */
  --rp-text-strong:     var(--foreground);   /* titles, prices and the active nested tab; shared candidate (strong text on a card) */
  --rp-tab-idle:        var(--muted-foreground);   /* idle nested tab */
  --rp-link:            var(--info-text);   /* link of an item that is not a monitored brand: blue, so it stays apart from the green monitored rows (R8 before R9; needs the owner's word if --link is preferred) */
  --rp-star:            var(--warning-text);   /* shopping rating stars */

  /* Item rows */
  --rp-item-bg:         var(--muted);   /* inset row on the card */
  --rp-item-border:     var(--border);   /* left bar of a row that is not a monitored brand */

  /* Rows that belong to a monitored brand (green accent) */
  --rp-mon-text:        var(--success-text);
  --rp-mon-link:        var(--success-text);   /* URL line of a monitored citation */
  --rp-mon-bg:          color-mix(in srgb, var(--success) 20%, transparent);
  --rp-mon-border:      var(--success-text);   /* left bar: the text-safe shade, because the --success slot reads 2.6 against this tint in the light theme */

  /* Recommendation row that is not a monitored brand (its border is --accent-primary) */
  --rp-rec-bg:          color-mix(in srgb, var(--primary) 8%, transparent);   /* 8%, not 20%: the old surface was a dark violet at 20%, which is about 8% of the accent; at 20% the accent left bar reads 2.7 against the tint in the dark theme */

  /* Answer text: code, tables, images */
  --rp-code-bg:         color-mix(in srgb, var(--foreground) 8%, transparent);   /* code and pre in .answer-html-content (a .prose parent overrides it); a tint, because the answer box has no background of its own and sits on the card */
  --rp-prose-code-bg:   color-mix(in srgb, var(--foreground) 8%, transparent);   /* code and pre in .prose */
  --rp-th-bg:           color-mix(in srgb, var(--foreground) 6%, transparent);   /* table header cell in .prose */
  --rp-table-border:    var(--border);
  --rp-img-shadow:      var(--shadow-badge);

  /* ===== Sentiment Analysis view (sentiment_analysis.php), light theme stage 3 =====
     Every value is an expression of the theme slots (tints of --success, --destructive and --muted-foreground, a shadow token, the modal scrim), so it follows the active theme and no value here needs a pair. */
  /* Sentiment overview: verdict pill backgrounds (positive / negative / neutral) */
  --sent-verdict-pos-bg:  color-mix(in srgb, var(--success) 12%, transparent);
  --sent-verdict-neg-bg:  color-mix(in srgb, var(--destructive) 12%, transparent);   /* 12%, not 13%: the negative text reads 4.49 on a 13% tint in the dark theme */
  --sent-verdict-neu-bg:  color-mix(in srgb, var(--muted-foreground) 16%, transparent);

  /* Sentiment overview: hero gauge track gradient mid stops and centre tick */
  --sent-gauge-neg-mid:   color-mix(in srgb, var(--destructive) 25%, transparent);
  --sent-gauge-neu-mid:   color-mix(in srgb, var(--muted-foreground) 40%, transparent);
  --sent-gauge-pos-mid:   color-mix(in srgb, var(--success) 25%, transparent);
  --sent-gauge-center:    var(--muted-foreground);   /* centre tick of the hero gauge */
  --sent-gauge-marker-shadow: var(--shadow-badge);   /* drop shadow of the hero gauge marker */

  /* Sentiment overview: role comparison rows, breakdown bar and legend */
  --sent-role-center:     var(--muted-foreground);   /* centre tick of the role-row gauges */
  --sent-seg-neutral:     var(--muted-foreground);   /* neutral segment of the pos/neu/neg breakdown bar; the same color as its legend swatch and the neutral gauge color */
  --sent-legend-neutral-swatch: var(--muted-foreground);   /* swatch dot of the Neutral legend card */
  --sent-role-competitor-swatch: var(--muted-foreground);  /* swatch of the "Defined competitors" role row */
  --sent-role-other-swatch: color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* swatch of the "Other brands" role row: one step weaker than the competitor swatch */
  --sent-you-pill-bg:     color-mix(in srgb, var(--primary) 16%, transparent);   /* "You" pill fill */
  --sent-you-pill-border: color-mix(in srgb, var(--primary) 35%, transparent);   /* "You" pill outline */

  /* Negative-sentiment alert banner, keyword table row hover and response chip */
  --sent-alert-border:    color-mix(in srgb, var(--destructive) 38%, transparent);
  --sent-alert-bg-hover:  color-mix(in srgb, var(--destructive) 16%, transparent);
  --sent-kwrow-hover-bg:  color-mix(in srgb, var(--destructive) 6%, transparent);   /* hovered row of the negative-keywords table */
  --sent-neg-chip-bg:     color-mix(in srgb, var(--destructive) 12%, transparent);   /* sentiment chip in the keyword detail modal */
  --sent-neg-chip-border: color-mix(in srgb, var(--destructive) 25%, transparent);

  /* Keyword detail modal: backdrop (shared candidate, other views use their own scrims) */
  --sent-modal-overlay:   var(--overlay-modal);

  /* Funnel: stage badge tints (TOFU reuses --accent-primary-15) and arrow / empty-state strokes */
  --sent-stage-mofu-bg:   color-mix(in srgb, var(--warning) 15%, transparent);
  --sent-stage-bofu-bg:   color-mix(in srgb, var(--success) 15%, transparent);
  --sent-funnel-arrow-stem: var(--muted-foreground);   /* stem of the arrows between funnel panels */
  --sent-funnel-empty-icon: var(--muted-foreground);   /* info icon of the "no funnel data" takeaway */

  /* ===== AI Brand Review view (brand_intelligence.php), light theme stage 3 =====
     Every value is an expression of the theme slots, so it follows the active theme; the three sentiment stops are the one pair of values (JS parses them). */
  /* Shared candidate: dotted underline of every .lm-help tooltip trigger (same value and role as --lm-help-underline) */
  --bi-help-underline:      var(--lm-help-underline);

  /* Shared candidate: accent wash on hover of pills, tabs and buttons (same value and role as --accent-primary-12) */
  --bi-accent-hover-bg:     var(--accent-primary-12);

  /* Dimension rings and funnel: sentiment scale stops, read by JS (tokenRgb) as hex, so they are a pair of literals, never color-mix */
  --bi-sent-base:           #a3a3a3;   /* pair (R11): neutral stop (sentiment 0), the --muted-foreground slot; also the middle of the legend gradient */
  --bi-sent-pos:            #4ade80;   /* pair (R11): positive end of the ring colour interpolation, the --success slot; also the legend gradient end */
  --bi-sent-neg:            #f87171;   /* pair (R11): negative end of the ring colour interpolation, the --destructive slot; also the legend gradient start */
  --bi-ring-track:          var(--page-bg);   /* track behind a visibility ring, drawn on the --panel-deep cell: the page color, darker than the cell in the dark theme and the same value as the cell in the light one (owner decision 2026-10-04, dark tracks as in GAPs) */
  --bi-fill-muted:          color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* "no data in this segment" ring and the muted last bar of a recommendation card */
  --bi-cell-hover-border:   color-mix(in srgb, var(--primary) 40%, transparent);   /* hovered dimension ring cell border: the accent border, because --border would not change on hover */
  --bi-funnel-cluster-bg:   color-mix(in srgb, var(--foreground) 4.5%, transparent);   /* funnel row stat cluster surface */
  --bi-funnel-track-bg:     var(--page-bg);    /* funnel row bar track: the page color (owner decision 2026-10-04, dark tracks as in GAPs) */
  --bi-tip-shadow:          var(--shadow-tooltip);   /* hover tip of a dimension cell */

  /* Recommendation cards ("What this means" panel) */
  --bi-explain-bg:          var(--muted);   /* inset panel on the card */
  --bi-explain-border:      var(--border);

  /* AI brief (section A) */
  --bi-accent-deep:         color-mix(in srgb, var(--primary) 75%, var(--background));   /* bottom stop of the lead card accent bar: a deeper violet in the dark theme, a fade toward the page in the light theme */
  --bi-dot-glow:            color-mix(in srgb, var(--link) 18%, transparent);   /* halo around the lead dot */
  --bi-text-lead:           var(--muted-foreground);   /* lead paragraph and insight text */
  --bi-text-sum:            var(--muted-foreground);   /* per-platform summary paragraph */
  --bi-num-bg:              color-mix(in srgb, var(--primary) 18%, transparent);   /* numbered recommendation badge */
  --bi-chip-bg:             color-mix(in srgb, var(--warning) 10%, transparent);   /* "where competitors win" chip */
  --bi-chip-border:         color-mix(in srgb, var(--warning) 22%, transparent);
  --bi-tile-on-bg:          linear-gradient(135deg, color-mix(in srgb, var(--primary) 20%, transparent), color-mix(in srgb, var(--bi-accent-deep) 6%, transparent));   /* highlighted branded tile */
  --bi-tile-on-border:      color-mix(in srgb, var(--link) 32%, transparent);
  --bi-tag-bg:              color-mix(in srgb, var(--link) 18%, transparent);   /* tile tag */
  --bi-tag-generic-bg:      color-mix(in srgb, var(--muted-foreground) 16%, transparent);   /* tile tag, generic variant */

  /* Topics (section E): soft tints of the positive and negative status colours */
  --bi-positive-soft:       color-mix(in srgb, var(--success) 15%, transparent);   /* Strong badge, positive delta */
  --bi-negative-soft:       color-mix(in srgb, var(--destructive) 15%, transparent);  /* Weak badge, negative delta */
  --bi-positive-faint:      color-mix(in srgb, var(--success) 5%, transparent);   /* Strong row surface */
  --bi-negative-faint:      color-mix(in srgb, var(--destructive) 5%, transparent);   /* Weak row surface */
  --bi-bar-muted:           color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* non-leading bar of a topic row */

  /* Radar legend: "Calculated" tag */
  --bi-calc-bg:             color-mix(in srgb, var(--link) 14%, transparent);
  --bi-calc-border:         color-mix(in srgb, var(--link) 25%, transparent);

  /* Trends (section T): delta chips */
  --bi-chip-good-border:    color-mix(in srgb, var(--success) 35%, transparent);
  --bi-chip-good-bg:        color-mix(in srgb, var(--success) 8%, transparent);
  --bi-chip-bad-border:     color-mix(in srgb, var(--destructive) 35%, transparent);
  --bi-chip-bad-bg:         color-mix(in srgb, var(--destructive) 8%, transparent);

  /* ===== Competitive Landscape view (competitive_landscape.php), light theme stage 3 =====
     Every value is an expression of the theme slots, except the six heat map stops: _readRgbToken() parses them in JS, so they are a pair of hex values (dark here, light in :root.light). */
  /* Breakdown heat map. The six --cl-heat-N stops are parsed by _readRgbToken() in the view (hex or rgb() only) and interpolated in JS; do not use alpha or color-mix here. Each ramp is the mix of two slot values in six even steps, built so that --foreground clears 4.5 on every stop and on every interpolated color between them. The legend swatches read these same tokens. */
  --cl-heat-1:            #262626;   /* ramp stop 1: lowest visibility; pair (R11), dark = --muted */
  --cl-heat-2:            #312d4f;   /* ramp stop 2; pair (R11), dark = --muted mixed 20% toward --primary */
  --cl-heat-3:            #3d3478;   /* ramp stop 3; pair (R11), dark = 40% */
  --cl-heat-4:            #483ca1;   /* ramp stop 4; pair (R11), dark = 60% */
  --cl-heat-5:            #5443ca;   /* ramp stop 5; pair (R11), dark = 80% */
  --cl-heat-6:            #5f4af3;   /* ramp stop 6: highest visibility; pair (R11), dark = --primary */
  --cl-heat-text-dark:    var(--foreground);   /* cell text above the 46% threshold; the same color as below it, because every stop of both ramps is readable with --foreground */
  --cl-heat-text-light:   var(--foreground);   /* cell text at or below the 46% threshold */
  --cl-heat-cell-border:  var(--border);   /* separator under each heat map cell */
  --cl-no-presence-dot:   var(--muted-foreground);   /* row-header dot of a dimension value no brand appears in (drawn at 50% opacity) */

  /* Marks of your brand in the heat map: legend swatch outline and the edge lines of its cells */
  --cl-you-outline:       var(--primary);   /* legend swatch outline marking "your brand" */
  --cl-you-edge:          color-mix(in srgb, var(--primary) 50%, transparent);   /* left and right edge lines of your brand's heat map cells */

  /* Brand ranking cards and tabs */
  --cl-help-underline:    var(--lm-help-underline);   /* dotted underline of .lm-help terms (the shared frame token) */
  --cl-hero-grad-start:   color-mix(in srgb, var(--primary) 14%, transparent);     /* your brand's ranking card: gradient start */
  --cl-hero-grad-mid:     color-mix(in srgb, var(--primary) 3%, transparent);      /* your brand's ranking card: gradient middle (at 60%) */
  --cl-hero-border:       color-mix(in srgb, var(--link) 45%, transparent);        /* your brand's ranking card border */
  --cl-chip-role-bg:      color-mix(in srgb, var(--muted-foreground) 12%, transparent);   /* "competitor" role chip background */
  --cl-chip-other-bg:     color-mix(in srgb, var(--muted-foreground) 8%, transparent);    /* "Discovered" role chip background */
  --cl-chip-small-bg:     color-mix(in srgb, var(--warning) 10%, transparent);    /* "Small sample" chip background */
  --cl-chip-small-border: color-mix(in srgb, var(--warning) 40%, transparent);    /* "Small sample" chip dashed border */
  --cl-pill-lead-border:  color-mix(in srgb, var(--link) 50%, transparent);       /* border of the metric tile that leads its metric */
  --cl-comp-mark:         color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* single-metric race: competitor stem, dot and legend swatch; one step weaker than the discovered brands' --text-muted */
  --cl-client-halo:       color-mix(in srgb, var(--primary) 22%, transparent);    /* single-metric race: glow around your brand's dot */
  --cl-badge-bg:          color-mix(in srgb, var(--primary) 12%, transparent);    /* country badge next to a section title */
  --cl-ctab-bg:           var(--muted);   /* country tab, resting */
  --cl-ctab-hover-bg:     color-mix(in srgb, var(--foreground) 5%, var(--muted));   /* country tab, hovered */

  /* Other brands in answers, Metric trends */
  --cl-kbd-border:        color-mix(in srgb, var(--primary) 22%, transparent);    /* border of the "Unmonitored" pill */
  --cl-obx-row-hover:     color-mix(in srgb, var(--primary) 4%, transparent);     /* hovered row of the other-brands list */
  --cl-tier-moderate:     var(--primary);   /* "Moderate" tier marker in the other-brands list; needs owner review: a pair (a lighter violet in :root.light), because --link equals --primary in the light theme and the strong and moderate markers would be identical */
  --cl-tier-emerging:     color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* "Emerging" tier marker in the other-brands list: neutral, the weakest tier */
  --cl-delta-up-border:   color-mix(in srgb, var(--success) 22%, transparent);    /* border of a positive trend chip (background is --color-success-10) */
  --cl-delta-down-border: color-mix(in srgb, var(--destructive) 22%, transparent);   /* border of a negative trend chip (background is --color-error-10) */
  --cl-delta-neutral-bg:  color-mix(in srgb, var(--muted-foreground) 6%, transparent);   /* "new" and flat trend chips background */
  --cl-scale-on-fg:       var(--primary-foreground);   /* text of the active Weekly/Monthly/Yearly button (on --accent-primary) */
  --cl-tbl-hero-grad-start: color-mix(in srgb, var(--primary) 16%, transparent);   /* your brand's row in the trends table: gradient start */
  --cl-tbl-hero-grad-mid:   color-mix(in srgb, var(--primary) 4%, transparent);    /* your brand's row in the trends table: gradient middle (at 46%) */

  /* ===== GAPs view (gaps.php), light theme stage 3 =====
     Stage 5b-2: every value is an expression of the theme slots (it follows the active theme),
     except the three shadow colors, which are a pair of values (marked needs owner review),
     and the monogram saturation and lightness, which are the same in both themes (fixed identity color). */
  /* Surfaces (cards, tiles, inputs, chips) */
  --gaps-surface-inset:              var(--muted);   /* inset surface: tiles, rows, inputs, chips, detail panels (R6; lighter than the card in the dark theme, darker in the light one) */
  --gaps-chip-muted-bg:              var(--muted);   /* background of a muted chip or disabled button (R6) */
  --gaps-hover-bg:                   color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered row of the header table of contents (R6 hover overlay) */
  --gaps-table-row-hover-bg:         color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered row of the domain tables (R6 hover overlay) */
  --gaps-tab-bg:                     var(--muted);   /* resting tab background (R6) */
  --gaps-tab-hover-bg:               color-mix(in srgb, var(--muted) 90%, var(--foreground));   /* hovered tab: the muted surface with a little foreground, same recipe as .btn-secondary:hover (R6 hover state) */
  --gaps-group-head-bg:              var(--muted);   /* header strip of a shortlist group (R6) */
  --gaps-mdot-bg:                    var(--muted);   /* resting background of the small marker next to a win tile (R6) */
  --gaps-tile-weak-top:              color-mix(in srgb, var(--warning) 8%, var(--gaps-surface-inset));       /* top stop of the weak-signal KPI tile gradient: the inset surface with a warning tint (R1, opaque) */
  --gaps-tile-headline-top:          color-mix(in srgb, var(--destructive) 8%, var(--gaps-surface-inset));   /* top stop of the headline KPI tile gradient: the inset surface with an error tint (R1, opaque) */

  /* Bars and tracks */
  --gaps-track-bg:                   var(--page-bg);   /* empty track behind a progress or share bar, empty coverage dot: the page color seen through the card, darker than the card in both themes, so the accent fill keeps 3.0 on it (--muted, R6, gave 2.71 in the dark theme) */
  --gaps-ladder-track-bg:            var(--page-bg);   /* track of a Gap Ladder rung: same reasoning as --gaps-track-bg */
  --gaps-ladder-fill-bg:             color-mix(in srgb, var(--muted-foreground) 65%, transparent);   /* fill of a competitor rung in the Gap Ladder: neutral gray (the 65% recipe of --field-border) that stays above the 3.0 graphic floor on its track (R4) */
  --gaps-skeleton-base:              var(--muted);   /* base color of the loading shimmer (R6) */
  --gaps-skeleton-shine:             color-mix(in srgb, var(--muted) 90%, var(--foreground));   /* highlight of the loading shimmer (R6 hover recipe) */

  /* Accent variants */
  --gaps-accent-deep:                var(--primary);   /* start of the own-brand ladder fill and hovered brief tile border; the former deeper purple differs only slightly from the accent, so it takes the same value (R6 principle) */
  --gaps-url-toggle-hover-fg:        var(--foreground);   /* text of the hovered "View articles" pill (R5) */
  --gaps-dock-badge-inverse-bg:      var(--primary-foreground);   /* background of the count badge inside the filled dock pill: the color that sits on the accent fill (R5) */

  /* Text on solid priority colors */
  --gaps-on-success:                 var(--success-foreground);   /* text on a solid success background (priority pill) (R5) */
  --gaps-on-error:                   var(--destructive-foreground);   /* text on a solid error background (priority pill) (R5) */
  --gaps-on-warning:                 var(--warning-foreground);   /* text on a solid warning background (priority pill) (R5) */

  /* Trend sparkline */
  --gaps-trend-neutral:              var(--muted-foreground);   /* neutral stroke and dots of the headline trend sparkline (R4) */
  --gaps-trend-empty-dot:            color-mix(in srgb, var(--muted-foreground) 70%, transparent);   /* placeholder dots while the trend has no points; decorative (R4, weaker level) */

  /* Warning tints; the 12% and 35% steps are --color-warning-12 and --color-warning-35 */
  --gaps-warning-08:                 color-mix(in srgb, var(--warning) 8%, transparent);
  --gaps-warning-10:                 color-mix(in srgb, var(--warning) 10%, transparent);
  --gaps-warning-13:                 color-mix(in srgb, var(--warning) 13%, transparent);
  --gaps-warning-25:                 color-mix(in srgb, var(--warning) 25%, transparent);
  --gaps-warning-30:                 color-mix(in srgb, var(--warning) 30%, transparent);
  --gaps-warning-33:                 color-mix(in srgb, var(--warning) 33%, transparent);
  --gaps-warning-40:                 color-mix(in srgb, var(--warning) 40%, transparent);

  /* Error tints; the 20% step is --color-error-20 */
  --gaps-error-05:                   color-mix(in srgb, var(--destructive) 5%, transparent);
  --gaps-error-08:                   color-mix(in srgb, var(--destructive) 8%, transparent);
  --gaps-error-12:                   color-mix(in srgb, var(--destructive) 12%, transparent);
  --gaps-error-32:                   color-mix(in srgb, var(--destructive) 32%, transparent);
  --gaps-error-35:                   color-mix(in srgb, var(--destructive) 35%, transparent);
  --gaps-error-55:                   color-mix(in srgb, var(--destructive) 55%, transparent);

  /* Success tints; the 10% step is --color-success-10 */
  --gaps-success-05:                 color-mix(in srgb, var(--success) 5%, transparent);
  --gaps-success-08:                 color-mix(in srgb, var(--success) 8%, transparent);
  --gaps-success-12:                 color-mix(in srgb, var(--success) 12%, transparent);
  --gaps-success-13:                 color-mix(in srgb, var(--success) 13%, transparent);
  --gaps-success-14:                 color-mix(in srgb, var(--success) 14%, transparent);
  --gaps-success-30:                 color-mix(in srgb, var(--success) 30%, transparent);
  --gaps-success-33:                 color-mix(in srgb, var(--success) 33%, transparent);
  --gaps-success-35:                 color-mix(in srgb, var(--success) 35%, transparent);

  /* Accent tints; the 8% and 10% steps are --accent-primary-08 and --accent-primary-10 */
  --gaps-accent-04:                  color-mix(in srgb, var(--primary) 4%, transparent);
  --gaps-accent-22:                  color-mix(in srgb, var(--primary) 22%, transparent);
  --gaps-accent-28:                  color-mix(in srgb, var(--primary) 28%, transparent);
  --gaps-accent-45:                  color-mix(in srgb, var(--primary) 45%, transparent);
  --gaps-accent-50:                  color-mix(in srgb, var(--primary) 50%, transparent);

  /* Deep accent tints, badge of the Diagnose bucket (the deep purple maps to the accent, R1) */
  --gaps-accent-deep-20:             color-mix(in srgb, var(--primary) 20%, transparent);
  --gaps-accent-deep-40:             color-mix(in srgb, var(--primary) 40%, transparent);

  /* Light accent tints (the --link color) */
  --gaps-accent-light-12:            color-mix(in srgb, var(--link) 12%, transparent);
  --gaps-accent-light-35:            color-mix(in srgb, var(--link) 35%, transparent);
  --gaps-accent-light-40:            color-mix(in srgb, var(--link) 40%, transparent);

  /* Violet tints, "View articles" pill border and stability pill (the light violet maps to --link, R1) */
  --gaps-violet-14:                  color-mix(in srgb, var(--link) 14%, transparent);
  --gaps-violet-45:                  color-mix(in srgb, var(--link) 45%, transparent);

  /* Info tints; the 10% step is --color-info-10 */
  --gaps-info-32:                    color-mix(in srgb, var(--info) 32%, transparent);

  /* Neutral gray tints: neutral badges, chips and tiles (gray maps to --muted-foreground, R1 and R4) */
  --gaps-neutral-06:                 color-mix(in srgb, var(--muted-foreground) 6%, transparent);
  --gaps-neutral-08:                 color-mix(in srgb, var(--muted-foreground) 8%, transparent);
  --gaps-neutral-10:                 color-mix(in srgb, var(--muted-foreground) 10%, transparent);
  --gaps-neutral-12:                 color-mix(in srgb, var(--muted-foreground) 12%, transparent);
  --gaps-neutral-16:                 color-mix(in srgb, var(--muted-foreground) 16%, transparent);
  --gaps-neutral-20:                 color-mix(in srgb, var(--muted-foreground) 20%, transparent);
  --gaps-neutral-22:                 color-mix(in srgb, var(--muted-foreground) 22%, transparent);
  --gaps-neutral-25:                 color-mix(in srgb, var(--muted-foreground) 25%, transparent);

  /* Foreground overlays, shared candidate (a white overlay in the dark theme, a dark one in the light theme, R2) */
  --gaps-white-015:                  color-mix(in srgb, var(--foreground) 1.5%, transparent);
  --gaps-white-02:                   color-mix(in srgb, var(--foreground) 2%, transparent);
  --gaps-white-04:                   color-mix(in srgb, var(--foreground) 4%, transparent);
  --gaps-white-06:                   color-mix(in srgb, var(--foreground) 6%, transparent);
  --gaps-white-08:                   color-mix(in srgb, var(--foreground) 8%, transparent);

  /* Scrims and shadow colors, shared candidate (compare --overlay-modal and --shadow-*) */
  --gaps-shadow-35:                  rgba(0, 0, 0, 0.35);   /* drop shadow of the shortlist dock pill; dark value of a pair, needs owner review (R13: the shadow geometry stays in the rule, so the color cannot be a --shadow-* token) */
  --gaps-backdrop-45:                var(--overlay-modal);   /* backdrop behind the shortlist slide-over (R3) */
  --gaps-shadow-50:                  rgba(0, 0, 0, 0.5);   /* shadow of the slide-over panel and of the filter dialog; dark value of a pair, needs owner review (R13) */
  --gaps-overlay-55:                 var(--overlay-modal);   /* overlay behind the filter-switch dialog (R3) */
  --gaps-shadow-55:                  rgba(0, 0, 0, 0.55);   /* shadow of the Articles modal; dark value of a pair, needs owner review (R13) */

  /* Monogram tiles: hue is computed in JS from the domain, saturation and lightness live here;
     a fixed identity color, the same in both themes (R12): the tile carries its own background and text */
  --gaps-monogram-bg-s:            55%;
  --gaps-monogram-bg-l:            22%;
  --gaps-monogram-fg-s:            70%;
  --gaps-monogram-fg-l:            78%;

  /* ===== Sign-in page (login.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots, so the page follows the theme class on <html>
     if one is ever set. Today login.php sets none and renders the dark theme only. The page no longer carries
     an older palette of its own: its former rendered values are replaced by the slots. */

  /* Page surfaces and base text */
  --login-body-bg:            var(--page-bg);            /* body background (the wrapper below covers it on screen) */
  --login-body-text:          var(--foreground);         /* base text color of the page */
  --login-page-bg:            var(--page-bg);            /* wrapper behind the form */
  --login-title:              var(--foreground);         /* "LLM Monitor" heading: a heading uses the text color, not the accent */
  --login-text-secondary:     var(--muted-foreground);   /* "AI Chats Scraping" line */
  --login-text-muted:         var(--muted-foreground);   /* subtitle, field labels, checkbox label, show-password toggle */

  /* Email and password fields */
  --login-input-bg:           var(--muted);              /* field fill */
  --login-input-border:       var(--field-border);       /* field border */
  --login-input-focus-border: var(--link);               /* field border while focused: the accent as a line, in its readable shade */
  --login-input-text:         var(--foreground);         /* typed text */
  --login-input-placeholder:  var(--muted-foreground);   /* placeholder text: it carries a hint, so it keeps the muted text level */
  --login-eye-icon:           var(--muted-foreground);   /* show/hide password eye icon */

  /* "Keep me logged in" checkbox */
  --login-check-on:           var(--primary);            /* fill and border of the checked box */
  --login-check-off-border:   var(--field-border);       /* border of the unchecked box */
  --login-check-mark:         var(--primary-foreground); /* tick inside the checked box */

  /* Sign In button */
  --login-btn-bg:             var(--primary);
  --login-btn-text:           var(--primary-foreground);

  /* Error and success alerts above the form */
  --login-error:              var(--destructive-text);   /* text and border of the error alert */
  --login-error-bg:           var(--color-error-10);
  --login-success:            var(--success-text);       /* text and border of the success alert */
  --login-success-bg:         var(--color-success-10);

  /* Page scrollbar (shown when the viewport is shorter than the form wrapper) */
  --login-scrollbar-track:       var(--page-bg);
  --login-scrollbar-thumb:       color-mix(in srgb, var(--muted-foreground) 65%, transparent);   /* same recipe as the thumb of the app scrollbar */
  --login-scrollbar-thumb-hover: var(--primary);

  /* ===== Documentation view (documentation.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots, so it follows the dark and the light theme on its own. */
  --doc-chip-fg-active:       var(--foreground);                                      /* text of a hovered or current "On this page" chip (the current chip sits on --accent-primary-15, so it is not --primary-foreground) */
  --doc-caveat-bg:            color-mix(in srgb, var(--warning) 8%, transparent);     /* amber note under a metric card */
  --doc-caveat-border:        color-mix(in srgb, var(--warning) 22%, transparent);
  --doc-callout-bg:           color-mix(in srgb, var(--warning) 7%, transparent);     /* amber callout box */
  --doc-callout-border:       color-mix(in srgb, var(--warning) 30%, transparent);    /* shared candidate: same value as --gaps-warning-30 (its left edge is --color-warning) */
  --doc-table-row-hover-bg:   color-mix(in srgb, var(--foreground) 2%, transparent);  /* hovered row of a documentation table (the same 2% weight as the former white wash) */
  --doc-step-num-bg:          color-mix(in srgb, var(--primary) 14%, transparent);    /* number badge of a step (its border is --border-accent); accent tint between --accent-primary-12 and -15 */

  /* ===== Prompts view (prompts.php, partials/prompts_list.php), light theme stage 4 =====
     Every value is an expression of the theme slots, so it follows the active theme; no token of this section has a pair of values. */

  /* Bulk actions bar, shown while prompts or keyword groups are selected */
  --prl-bulkbar-bg:            color-mix(in srgb, var(--link) 10%, transparent);
  --prl-bulkbar-border:        color-mix(in srgb, var(--link) 30%, transparent);

  /* Solid danger button (Delete selected, Delete permanently): the destructive slot, hovered the way .btn-danger is; its text is --destructive-foreground */
  --prl-danger-solid-bg:       var(--destructive);
  --prl-danger-solid-hover-bg: color-mix(in srgb, var(--destructive) 92%, var(--foreground));

  /* Ghost danger button (row Delete, Delete keyword): its text is --destructive-text; the hover text is that color pulled toward the foreground, as a:hover does */
  --prl-danger-ghost-hover-bg: color-mix(in srgb, var(--destructive) 15%, transparent);
  --prl-danger-ghost-hover-fg: color-mix(in srgb, var(--destructive-text) 80%, var(--foreground));
  --prl-danger-ghost-border:   color-mix(in srgb, var(--destructive) 30%, transparent);

  /* Checkbox colour of the delete confirmations (the destructive slot); the other checkboxes use --accent-primary */
  --prl-danger-check:          var(--destructive);

  /* Red-tinted panels of the delete and move modals (text on them is --destructive-text or --text-secondary) */
  --prl-alert-bg:              color-mix(in srgb, var(--destructive) 10%, transparent);   /* "deletes ALL prompts" banner and the move country error; shared candidate: same value as --color-error-10 */
  --prl-alert-border:          color-mix(in srgb, var(--destructive) 40%, transparent);
  --prl-impact-bg:             color-mix(in srgb, var(--destructive) 8%, transparent);   /* "This will permanently delete" block */
  --prl-impact-border:         color-mix(in srgb, var(--destructive) 25%, transparent);
  --prl-confirm-bg:            color-mix(in srgb, var(--destructive) 6%, transparent);   /* label panels of the Full reset option and of Delete duplicates */
  --prl-confirm-border:        color-mix(in srgb, var(--destructive) 30%, transparent);
  --prl-modal-overlay:         var(--overlay-modal);   /* backdrop of the four modals: the shared modal scrim */

  /* Per-page buttons of the flat table and hovered table row */
  --prl-perpage-idle-fg:       var(--muted-foreground);   /* an inactive per-page button */
  --prl-perpage-idle-hover-fg: var(--foreground);
  --prl-row-hover-bg:          color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered row */

  /* Keyword ledger group header: country code pill, "N active" chip, scope band */
  --prl-cc-bg:                 color-mix(in srgb, var(--foreground) 6%, transparent);   /* country code pill; shared candidate: same role as --kw-cc-bg */
  --prl-cc-border:             color-mix(in srgb, var(--foreground) 8%, transparent);   /* shared candidate: same role as --kw-cc-border */
  --prl-active-chip-bg:        color-mix(in srgb, var(--success) 12%, transparent);
  --prl-active-chip-border:    color-mix(in srgb, var(--success) 35%, transparent);
  --prl-active-chip-fg:        var(--success-text);
  --prl-scopeband-fg:          var(--destructive-text);
  --prl-scopeband-bg:          color-mix(in srgb, var(--destructive) 8%, transparent);
  --prl-scopeband-border:      color-mix(in srgb, var(--destructive) 25%, transparent);

  /* Branded | Generic type switch and the bulk Set type buttons (not the card badges of .seg-badge-*) */
  --prl-type-branded-fg:       var(--link);   /* the nearest slot to the indigo this switch drew before (rule R1, light violet) */
  --prl-type-branded-bg:       color-mix(in srgb, var(--link) 11%, transparent);   /* the same tint strength as the Generic segment: 11% is the highest at which the Generic text still reads 4.5 on it in the light theme */
  --prl-type-generic-fg:       color-mix(in srgb, var(--chart-4) 70%, var(--foreground));   /* series 4 (pink) pulled toward the text color: lighter in the dark theme, darker in the light one, text-safe on the tint below */
  --prl-type-generic-bg:       color-mix(in srgb, var(--prl-type-generic-fg) 11%, transparent);

  /* Prompts table partial (partials/prompts_list.php), shared by keyword.php and search.php */
  --prl-pagebar-bg:            color-mix(in srgb, var(--foreground) 3%, transparent);   /* top pagination bar; shared candidate: same role as --kw-pagebar-bg */
  --prl-badge-generic-bg:      color-mix(in srgb, var(--muted-foreground) 15%, transparent);   /* "Generic" badge of a prompt row */
  --prl-badge-generic-border:  color-mix(in srgb, var(--muted-foreground) 30%, transparent);
  --prl-badge-feature-fg:      var(--text-primary);   /* Shopping, Maps and Recommendations badges (their fill is --accent-primary-20, border --accent-primary-40); link text on that tint reads 4.2 in the light theme, so the strong text color */
  --prl-subtext:               var(--muted-foreground);   /* "(N platforms)" line under the average position */
  --prl-empty-dash:            var(--muted-foreground);   /* the "-" shown when a row has no average position or check date */

  /* ===== Brand Mentions views (brand_mentions.php, brand_mentions_keyword.php, brand_prompt.php), light theme stage 4 =====
     Light theme stage 5b: every value below is an expression of the theme slots, except the answer highlighter, which is a fixed identity color. */

  /* Hover tip of the "Mentions" header help and the top-brands tooltip: a popover, with the tooltip shadow of the frame. */
  --bm-tooltip-bg:           var(--popover);
  --bm-tooltip-shadow:       var(--shadow-tooltip);

  /* Pagination bar above the tables and hover tint of a table row */
  --bm-pagebar-bg:           color-mix(in srgb, var(--foreground) 3%, transparent);   /* shared candidate: same value as --kw-pagebar-bg */
  --bm-row-hover-bg:         color-mix(in srgb, var(--foreground) 5%, transparent);   /* shared candidate: same value as --kw-row-hover-bg */

  /* "Data collection in progress" banner (brand_mentions.php); its text is --warning-text. */
  --bm-collecting-bg:        color-mix(in srgb, var(--warning) 8%, transparent);
  --bm-collecting-border:    color-mix(in srgb, var(--warning) 30%, transparent);

  /* Grouped Ledger of brand_mentions.php: its own copy of the keywords.php rules, same values as the --kw-* tokens (shared candidates) */
  --bm-chip-fg:              var(--foreground);                                          /* shared candidate: same value as --kw-chip-fg */
  --bm-chip-x-hover-bg:      color-mix(in srgb, var(--link) 25%, transparent);          /* shared candidate: same value as --kw-chip-x-hover-bg */
  --bm-chip-x-hover-fg:      var(--foreground);                                          /* shared candidate: same value as --kw-chip-x-hover-fg */
  --bm-subhead-bg:           color-mix(in srgb, var(--foreground) 1.5%, transparent);  /* shared candidate: same value as --kw-subhead-bg */
  --bm-cc-bg:                color-mix(in srgb, var(--foreground) 6%, transparent);     /* shared candidate: same value as --kw-cc-bg */
  --bm-cc-border:            color-mix(in srgb, var(--foreground) 8%, transparent);     /* shared candidate: same value as --kw-cc-border */
  --bm-health-track-bg:      var(--page-bg);     /* shared candidate: same value as --kw-health-track-bg */
  --bm-zerochip-bg:          color-mix(in srgb, var(--destructive) 12%, transparent);   /* shared candidate: same value as --kw-zerochip-bg */
  --bm-zerochip-border:      color-mix(in srgb, var(--destructive) 35%, transparent);   /* shared candidate: same value as --kw-zerochip-border */
  --bm-zerochip-fg:          var(--destructive-text);                                    /* shared candidate: same value as --kw-zerochip-fg */
  --bm-pchip-bg:             color-mix(in srgb, var(--foreground) 5%, transparent);     /* shared candidate: same value as --kw-pchip-bg */
  --bm-subwrap-bg:           color-mix(in srgb, var(--background) 25%, transparent);    /* shared candidate: same value as --kw-subwrap-bg */

  /* "Generic" tag on a prompt row (brand_mentions_keyword.php): a chip, so the --muted surface with the frame border */
  --bm-generic-chip-bg:      var(--muted);
  --bm-generic-chip-border:  var(--border);

  /* AI visibility brief of brand_mentions_keyword.php (same markup family as the AI Brand Review brief, but its own values) */
  --bm-brief-bar-end:        var(--primary);   /* bottom stop of the lead card accent bar: a fill, the accent slot */
  --bm-brief-text:           var(--foreground);   /* overview paragraph */
  --bm-brief-chip-fg:        var(--foreground);   /* text of a "where competitors win" chip */
  --bm-brief-idx-bg:         color-mix(in srgb, var(--link) 12%, transparent);   /* number badge of a recommended action */
  --bm-brief-idx-border:     color-mix(in srgb, var(--link) 28%, transparent);
  --bm-brief-detail:         var(--muted-foreground);   /* detail line under a recommended action */
  --bm-brief-foot-strong:    var(--foreground);   /* answer count in the brief footer */

  /* Prompt detail page (brand_prompt.php) */
  --bm-error-bg:             var(--color-error-10);   /* shared candidate with --rp-error-bg of response_preview.php (same role) */
  --bm-error-border:         color-mix(in srgb, var(--destructive) 30%, transparent);   /* shared candidate with --rp-error-border of response_preview.php (same role) */
  --bm-error-text:           var(--destructive-text);   /* shared candidate with --rp-error-text of response_preview.php (same role) */
  --bm-pending-border:       color-mix(in srgb, var(--warning) 30%, transparent);   /* "Data collection has not started yet" banner border, pairs with --alert-warning-bg; shared candidate with --prm-banner-warning-border of prompt.php (same role) */
  --bm-caption:              var(--muted-foreground);   /* collection date under a Response Summary tile; shared candidate with --prm-caption of prompt.php (same role) */
  --bm-brand-hl-bg:          #fde047;   /* fixed identity color, same in both themes (R12): yellow-300 highlighter behind a counted brand mention in the answer text */
  --bm-brand-hl-fg:          #111827;   /* fixed identity color, same in both themes (R12): dark text on that highlight, 13.5 on yellow */

  /* ===== Add prompts and Competitors views (projects_add.php, competitors.php), light theme stage 4 =====
     Two token groups: --cmp-* for competitors.php, --pad-* for projects_add.php. Each value is what the views rendered before they moved to tokens (the dark theme value). */

  /* ===== competitors.php (--cmp-*) ===== */

  /* Category colours: the four stat numbers and the category badge in the table share them. Direct, Marketplace and Reference
     use the text-safe shades of the red, blue and accent slots, Indirect is the orange series colour (chart 3) shaded for text; each badge tint is its colour at 10%, except Reference at 6%
     (the link colour on a 10% accent tint reads 4.40 on a hovered row). The neutral badge is the muted surface. */
  --cmp-cat-direct-fg:       var(--destructive-text);
  --cmp-cat-direct-bg:       color-mix(in srgb, var(--destructive) 10%, transparent);
  --cmp-cat-indirect-fg:     color-mix(in srgb, var(--chart-3) 70%, var(--foreground));   /* the orange series colour (chart 3) pushed towards the foreground so it reads as text: lighter in the dark theme, darker in the light one */
  --cmp-cat-indirect-bg:     color-mix(in srgb, var(--cmp-cat-indirect-fg) 10%, transparent);
  --cmp-cat-marketplace-fg:  var(--info-text);
  --cmp-cat-marketplace-bg:  color-mix(in srgb, var(--info) 10%, transparent);
  --cmp-cat-reference-fg:    var(--link);
  --cmp-cat-reference-bg:    color-mix(in srgb, var(--primary) 6%, transparent);
  --cmp-cat-other-fg:        var(--muted-foreground);   /* badge of a category the map does not know */
  --cmp-cat-other-bg:        var(--muted);

  /* Table */
  --cmp-row-hover-bg:        color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered competitor row */
  --cmp-notmapped-bg:        color-mix(in srgb, var(--warning) 10%, transparent);   /* "Not mapped" warning badge, text is --warning-text */
  --cmp-optional-fg:         var(--muted-foreground);   /* "(optional)" hint after a field label; same colour as the label, the parentheses carry the difference */

  /* Edit and Delete row buttons: the border is the full info / destructive slot, so it stays visible on the card in both themes */
  --cmp-edit-fg:             var(--info-text);
  --cmp-edit-border:         var(--info);
  --cmp-edit-hover-bg:       color-mix(in srgb, var(--info) 15%, transparent);
  --cmp-edit-hover-fg:       color-mix(in srgb, var(--info-text) 80%, var(--foreground));   /* the text shade pushed towards the foreground: lighter in the dark theme, darker in the light one */
  --cmp-delete-border:       var(--destructive);   /* text is --destructive-text */
  --cmp-delete-hover-bg:     color-mix(in srgb, var(--destructive) 15%, transparent);
  --cmp-delete-hover-fg:     color-mix(in srgb, var(--destructive-text) 80%, var(--foreground));

  /* Per-page selector (inactive size button) */
  --cmp-perpage-fg:          var(--muted-foreground);
  --cmp-perpage-hover-fg:    var(--foreground);

  /* Mapping matrix */
  --cmp-unmapped-bg:         color-mix(in srgb, var(--warning) 8%, transparent);   /* banner "brands not mapped yet", text is --warning-text */
  --cmp-unmapped-border:     color-mix(in srgb, var(--warning) 30%, transparent);
  --cmp-none-bg:             color-mix(in srgb, var(--destructive) 10%, transparent);   /* "none" buttons, text is --destructive-text */

  /* Modals and toast */
  --cmp-modal-overlay:       var(--overlay-modal);   /* backdrop of the add/edit and delete modals: the scrim of the theme */
  --cmp-form-error-bg:       color-mix(in srgb, var(--destructive) 8%, transparent);   /* error line in the add/edit modal, text is --destructive-text */
  --cmp-form-error-border:   color-mix(in srgb, var(--destructive) 25%, transparent);
  --cmp-confirm-delete-bg:       var(--destructive);   /* confirm button of the delete modal, text is --destructive-foreground */
  --cmp-confirm-delete-hover-bg: color-mix(in srgb, var(--destructive) 92%, var(--foreground));   /* same hover recipe as .btn-danger */
  --cmp-toast-shadow:        var(--shadow-modal);

  /* ===== projects_add.php (--pad-*) ===== */

  /* Header pill and account picker */
  --pad-agency-warn-bg:      color-mix(in srgb, var(--warning) 10%, transparent);   /* "No client account selected" pill, text is --warning-text */
  --pad-agency-warn-border:  color-mix(in srgb, var(--warning) 30%, transparent);
  --pad-pick-hover-bg:       color-mix(in srgb, var(--foreground) 5%, transparent);   /* hovered row of the account search list */

  /* Manual / CSV / AI Wizard tab switch: the active tab is an accent fill, an idle tab is a card-coloured pill (the muted slot would vanish
     against the light page, which is --muted too) */
  --pad-tab-on-bg:           var(--primary);
  --pad-tab-on-fg:           var(--primary-foreground);
  --pad-tab-off-bg:          var(--card);
  --pad-tab-off-fg:          var(--muted-foreground);
  --pad-tab-off-hover-fg:    var(--foreground);

  /* CSV import result tiles (text colours are --success-text, --warning-text, --text-primary, --destructive-text) */
  --pad-tile-ok-bg:          color-mix(in srgb, var(--success) 10%, transparent);
  --pad-tile-ok-border:      color-mix(in srgb, var(--success) 25%, transparent);
  --pad-tile-dup-db-bg:      color-mix(in srgb, var(--warning) 10%, transparent);
  --pad-tile-dup-db-border:  color-mix(in srgb, var(--warning) 25%, transparent);
  --pad-tile-dup-csv-bg:     color-mix(in srgb, var(--primary) 10%, transparent);   /* "Duplicates in CSV" tile: the accent family, as its number was */
  --pad-tile-dup-csv-border: color-mix(in srgb, var(--primary) 25%, transparent);
  --pad-tile-err-bg:         color-mix(in srgb, var(--destructive) 10%, transparent);
  --pad-tile-err-border:     color-mix(in srgb, var(--destructive) 25%, transparent);
  --pad-tile-neutral-bg:     color-mix(in srgb, var(--foreground) 4%, transparent);   /* "Total rows" tile and the "Errors" tile when there are none */
  --pad-errlist-divider:     var(--border);   /* line between import errors: the ordinary divider line */

  /* AI Wizard list and tooltip */
  --pad-tick-fg:             var(--success-text);   /* tick next to a checked generated prompt */
  --pad-branded:             var(--link);   /* Branded column, button and radio: the accent colour as text (the link colour) */
  --pad-generic:             color-mix(in srgb, var(--chart-4) 70%, var(--foreground));   /* Generic column, button and radio: the pink series colour pushed towards the foreground so small text clears 4.5 on both themes */
  --pad-block-border:        color-mix(in srgb, var(--destructive) 32%, transparent);   /* "Before you can save" box, heading is --destructive-text */
  --pad-block-bg:            color-mix(in srgb, var(--destructive) 8%, transparent);
  --pad-tip-shadow:          var(--shadow-tooltip);   /* the (i) tooltip bubble */
  --pad-toast-shadow:        var(--shadow-modal);

  /* ===== Other views, light theme stage 4 =====
     Smaller views, one token group per file below. Each value is what the view rendered before it moved to tokens (the dark theme value). */

  /* ===== Getting started (frontend/getting_started.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots, so it follows the dark and the light theme on its own.
     The page aliases these as --gsx-* on .gsx-page. The four platform dots (.gsx-pf-chatgpt, -gemini,
     -perplexity, -copilot) keep their literals: platform colors are outside this stage. */
  --gs-accent-light:        var(--link);                                                    /* readable accent of links, icons and the focus ring; headings and numbers use --text-primary instead */
  --gs-success:             var(--success-text);                                            /* "done" green of badges, the legend dot and the progress note: text and fill, so the text-safe shade */
  --gs-success-soft:        color-mix(in srgb, var(--success) 14%, transparent);            /* fill of the "done" badge and the completed progress note */
  --gs-success-border:      color-mix(in srgb, var(--success) 35%, transparent);            /* outline of the "done" badge and the completed progress note */
  --gs-text-dim:            var(--muted-foreground);                                        /* faint text and icons: the muted text level, the pattern has no third one */
  --gs-on-warning:          var(--warning-foreground);                                      /* text on the solid warning background ("To do" badge, "Start here" flag) */
  --gs-keywords-border:     color-mix(in srgb, var(--link) 45%, transparent);               /* border of the Keywords node card */
  --gs-keywords-shadow:     0 0 0 1px color-mix(in srgb, var(--link) 6%, transparent), 0 18px 40px -22px color-mix(in srgb, var(--link) 30%, transparent);   /* ring and glow of the Keywords node card */
  --gs-keywords-stub-soft:  color-mix(in srgb, var(--link) 14%, transparent);               /* fill of the "Keywords" result-card source pill */
  --gs-start-flag-shadow:   0 4px 14px -4px color-mix(in srgb, var(--warning) 60%, transparent);   /* glow under the "Start here" flag */
  --gs-prompt-row-divider:  color-mix(in srgb, var(--foreground) 3%, transparent);          /* hairline between prompt rows of the keyword tree */
  --gs-pf-fg:               #ffffff;                                                        /* letter on a platform dot of the keyword tree: fixed identity color, same in both themes (needs owner review: the platform colors are outside this stage and white reaches 2.1 to 5.5 on them) */
  --gs-pf-border:           color-mix(in srgb, var(--foreground) 12%, transparent);         /* outline of a platform dot of the keyword tree */
  --gs-engine-band-wash:    color-mix(in srgb, var(--link) 8%, transparent);                /* top wash of the engine band background */
  --gs-engine-band-border:  color-mix(in srgb, var(--link) 28%, transparent);               /* border of the engine band */
  --gs-engine-glow:         color-mix(in srgb, var(--link) 16%, transparent);               /* pulsing glow behind the engine band */

  /* ===== Keyword detail view (frontend/keyword.php), light theme stage 4 =====
     Every value is an expression of the theme slots, so it follows the active theme; the text colors are the text-safe shades. */
  --kwd-progress-done:      var(--success-text);   /* "Checkpoint progress" when every expected response is collected */
  --kwd-progress-partial:   var(--warning-text);   /* "Checkpoint progress" while collection is partial */
  --kwd-progress-none:      var(--muted-foreground);   /* "Checkpoint progress" when nothing is collected yet */
  --kwd-score-good:         var(--success-text);   /* Overall visibility at 20% and above */
  --kwd-score-mid:          var(--warning-text);   /* Overall visibility from 5% */
  --kwd-score-low:          var(--destructive-text);   /* Overall visibility below 5% */
  --kwd-text-dim:           var(--muted-foreground);   /* "N/M prompts reached" sub-line */
  --kwd-pending-warning-border: color-mix(in srgb, var(--warning) 30%, transparent);   /* border of the "Data collection has not started yet" banner, pairs with --alert-warning-bg */

  /* ===== Brands list view (frontend/brands_list.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --bl-error-bg:            color-mix(in srgb, var(--destructive) 8%, transparent);    /* list-load error banner fill */
  --bl-error-border:        color-mix(in srgb, var(--destructive) 30%, transparent);   /* list-load error banner border */
  --bl-warning-bg:          color-mix(in srgb, var(--warning) 8%, transparent);        /* warning banner, "No prompts yet" badge and name-conflict notice fill */
  --bl-warning-border:      color-mix(in srgb, var(--warning) 30%, transparent);       /* border of the same three warning surfaces */
  --bl-form-error-bg:       color-mix(in srgb, var(--destructive) 8%, transparent);    /* "Add brand" form error fill */
  --bl-form-error-border:   color-mix(in srgb, var(--destructive) 25%, transparent);   /* "Add brand" form error border */
  --bl-tip-bg:              var(--popover);                                            /* BMV and SoV tooltip surface (a layer over the content) */
  --bl-tip-shadow:          var(--shadow-tooltip);                                     /* shadow of the BMV and SoV tooltips */
  --bl-modal-backdrop:      var(--overlay-modal);                                      /* scrim behind the Add brand and View profile dialogs */

  /* ===== Bug tracker (frontend/bugs.php and partials/bug_report_button.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots, so it follows the dark and the light theme on its own. */
  --bug-badge-new-bg:          color-mix(in srgb, var(--info) 9%, transparent);              /* status badge "new" fill (info tint) */
  --bug-badge-in-progress-bg:  color-mix(in srgb, var(--warning) 9%, transparent);           /* status badge "in progress" fill (warning tint) */
  --bug-badge-verify-bg:       color-mix(in srgb, var(--muted-foreground) 9%, transparent);  /* status badge "verify" fill (text-secondary tint) */
  --bug-badge-done-bg:         color-mix(in srgb, var(--success) 9%, transparent);           /* status badge "done" fill (success tint) */
  --bug-badge-rejected-bg:     color-mix(in srgb, var(--destructive) 9%, transparent);       /* status badge "rejected" fill (error tint) */
  --bug-kind-bug-bg:           color-mix(in srgb, var(--destructive) 12%, transparent);      /* "bug" kind pill fill */
  --bug-updated-badge-bg:      color-mix(in srgb, var(--info) 12%, transparent);             /* "updated" badge fill */
  --bug-row-hover-bg:          color-mix(in srgb, var(--foreground) 5%, transparent);        /* hovered row of the report list */
  --bug-tab-count-on-bg:       var(--primary-foreground);                                    /* count badge on the active tab: a light pill with accent text; a white wash on the accent fill read only 4.0 in the dark theme */
  --bug-backdrop:              var(--overlay-modal);                                         /* scrim behind the report dialog and the detail window */
  --bug-fab-shadow:            var(--shadow-badge);                                          /* shadow of the floating "Report" button (a small floating control) */
  --bug-dialog-shadow:         var(--shadow-modal);                                          /* shadow of the report dialog */

  /* ===== Accounts view (frontend/accounts.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --acc-badge-active-bg:       color-mix(in srgb, var(--success) 9%, transparent);       /* "Active" account badge fill */
  --acc-badge-suspended-bg:    color-mix(in srgb, var(--warning) 9%, transparent);       /* "Suspended" account badge fill */
  --acc-badge-deactivated-bg:  color-mix(in srgb, var(--destructive) 9%, transparent);   /* "Deactivated" account badge fill */
  --acc-share-flag-bg:         color-mix(in srgb, var(--warning) 9%, transparent);       /* "Account inactive" tag of a report share link */
  --acc-bar-error-bg:          color-mix(in srgb, var(--destructive) 35%, transparent);  /* track of a collection bar in the dead-pipeline state */
  --acc-menu-shadow:           var(--shadow-tooltip);                                    /* shadow of the account actions dropdown (a popover) */
  --acc-switch-thumb-on:       var(--primary-foreground);                                /* thumb of the Enabled switch while it is on: the text color of an accent fill */

  /* ===== Prompts limits view (frontend/prompts_limits.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --plm-chip-warn-bg:          color-mix(in srgb, var(--warning) 10%, transparent);      /* warning chip fill; shared candidate: same value as --gaps-warning-10 */
  --plm-own-row-bg:            color-mix(in srgb, var(--foreground) 4%, transparent);    /* the account's own row of the pool table; shared candidate (a wash of the text color) */
  --plm-row-hover-bg:          color-mix(in srgb, var(--foreground) 4%, transparent);    /* hovered row of the pool table */
  --plm-nocap-tag-bg:          color-mix(in srgb, var(--foreground) 4%, transparent);    /* "No cap" tag fill */
  --plm-dock-shadow:           var(--shadow-modal);                                      /* shadow of the pending-changes dock and its message (a floating panel) */

  /* ===== Settings view (frontend/settings.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --set-text-faint:            var(--muted-foreground);                                  /* "(global)" label and the empty templates note: the muted text level, the pattern has no third one */
  --set-error-bg:              color-mix(in srgb, var(--destructive) 8%, transparent);   /* narrative language error banner fill */
  --set-error-border:          color-mix(in srgb, var(--destructive) 30%, transparent);  /* narrative language error banner border */

  /* ===== Contact messages view (frontend/contact_messages.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --cm-pending-bg:             color-mix(in srgb, var(--warning) 20%, transparent);      /* "Pending" forwarded-status badge fill (the same step --color-success-20 and --color-error-20 have) */

  /* ===== Data export view (frontend/data_export.php), light theme stage 4 =====
     Stage 5b-2: every value is an expression of the theme slots and the frame tokens, so it follows the dark and the light theme on its own. */
  --dx-clear-bg:               color-mix(in srgb, var(--destructive) 10%, transparent);  /* "Clear" button fill */
  --dx-row-hover-bg:           color-mix(in srgb, var(--foreground) 5%, transparent);    /* hovered row of the checkpoint picker; shared candidate: same value as --topbar-item-hover-bg */
}

:root.light {
  /* ===== View tokens with a pair of values, light theme (light theme stage 5b-2) ===== */
  /* Only the sections that hold a token the slots cannot express appear here (AI Brand Review, Competitive
     Landscape, GAPs); the dark value of each token is in its section above. Every other view token is an
     expression of the slots and follows the theme without an entry in this block. */

  /* ===== AI Brand Review view: light values of the pair tokens ===== */
  --bi-sent-base:           #475569;   /* pair (R11): neutral stop, the light --muted-foreground slot */
  --bi-sent-pos:            #15803d;   /* pair (R11): green-700, one step darker than the --success slot, which reads only 3.02 on the muted cell and the ring track (the same color in the light theme), a 0.02 margin over the 3.0 floor */
  --bi-sent-neg:            #dc2626;   /* pair (R11): the light --destructive slot */

  /* ===== Competitive Landscape view (competitive_landscape.php), light theme stage 3: light values of the pair tokens ===== */
  --cl-heat-1:            #f5f5f5;   /* ramp stop 1: lowest visibility; pair (R11), light = --muted */
  --cl-heat-2:            #e0ddf5;   /* ramp stop 2; pair (R11), light = --muted mixed 20% toward the dark-theme --link (#8d7ef6) */
  --cl-heat-3:            #cbc5f5;   /* ramp stop 3; pair (R11), light = 40% */
  --cl-heat-4:            #b7aef6;   /* ramp stop 4; pair (R11), light = 60% */
  --cl-heat-5:            #a296f6;   /* ramp stop 5; pair (R11), light = 80% */
  --cl-heat-6:            #8d7ef6;   /* ramp stop 6: highest visibility; pair (R11), light = the dark-theme --link, the darkest stop that still clears 4.5 under --foreground */
  --cl-tier-moderate:     #8d7ef6;   /* "Moderate" tier marker; needs owner review: the dark-theme --link, the lightest violet that still reads 3.26 against the white card */

  /* ===== GAPs view: light values of the pair tokens ===== */
  --gaps-shadow-35:                  rgba(15, 23, 42, 0.12);   /* light value of the pair, needs owner review: same slate as --shadow-badge, similar strength */
  --gaps-shadow-50:                  rgba(15, 23, 42, 0.15);   /* light value of the pair, needs owner review: same strength as --shadow-modal */
  --gaps-shadow-55:                  rgba(15, 23, 42, 0.15);   /* light value of the pair, needs owner review: same strength as --shadow-modal */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Page background of every view's <body>. Tailwind's bg-gray-900 painted it before and beat the
   body rule above (class over element selector), so --page-bg carries that same value and the
   rendered result is unchanged. */
.lm-page {
  background-color: var(--page-bg);
}

/* Custom Scrollbar */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--bg-primary);
}

::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted-foreground) 65%, transparent);
  border-radius: 5px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--accent-primary);
}

/* Utility Classes */
.no-scrollbar::-webkit-scrollbar {
  display: none;
}

.no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* Card Styles */
.card {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  padding: 1.5rem;
  position: relative;
}

.card:hover {
  border-color: var(--border-accent);
  transition: border-color 0.2s ease;
}

.seg-badge {
  position: absolute;
  top: -10px;
  right: 16px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 11px;
  border-radius: 6px;
  box-shadow: var(--shadow-badge);
  z-index: 5;
  pointer-events: none;
}

.seg-badge-branded {
  background: var(--seg-badge-branded-bg);
  color: var(--seg-badge-branded-fg);
}

.seg-badge-generic {
  background: var(--seg-badge-generic-bg);
  color: var(--seg-badge-generic-fg);
}

/* Button Styles */
.btn {
  padding: 0.5rem 1rem;
  border-radius: 6px;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent-primary);
  color: var(--primary-foreground);
}

.btn-primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--primary) 92%, var(--foreground));
  color: var(--primary-foreground);   /* an <a class="btn"> would otherwise take the a:hover link color */
}

.btn-secondary {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.btn-secondary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--muted) 90%, var(--foreground));
  color: var(--text-primary);
}

.btn-success {
  background: var(--color-success);
  color: var(--success-foreground);
}

.btn-success:hover:not(:disabled) {
  background: color-mix(in srgb, var(--success) 92%, var(--foreground));
  color: var(--success-foreground);
}

.btn-danger {
  background: var(--color-error);
  color: var(--destructive-foreground);
}

.btn-danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--destructive) 92%, var(--foreground));
  color: var(--destructive-foreground);
}

/* Badge Styles */
.badge {
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 500;
  display: inline-block;
}

.badge-admin {
  background: var(--accent-primary-10);
  color: var(--link);
}

.badge-user {
  background: var(--color-info-20);
  color: var(--info-text);
}

.badge-active {
  background: var(--color-success-20);
  color: var(--success-text);
}

.badge-inactive {
  background: var(--color-error-20);
  color: var(--destructive-text);
}

/* Alert Styles */
.alert {
  padding: 1rem;
  border-radius: 8px;
  margin-bottom: 1rem;
  font-size: 0.875rem;
  border: 1px solid;
}

.alert-success {
  background-color: var(--color-success-10);
  border-color: var(--color-success);
  color: var(--success-text);
}

.alert-error {
  background-color: var(--color-error-10);
  border-color: var(--color-error);
  color: var(--destructive-text);
}

.alert-warning {
  background-color: var(--alert-warning-bg);
  border-color: var(--color-warning);
  color: var(--warning-text);
}

.alert-info {
  background-color: var(--color-info-10);
  border-color: var(--color-info);
  color: var(--info-text);
}

/* Form Styles */
.form-group {
  margin-bottom: 1rem;
}

.form-label {
  display: block;
  margin-bottom: 0.5rem;
  color: var(--text-secondary);
  font-size: 0.875rem;
  font-weight: 500;
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  padding: 0.75rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--field-border);
  border-radius: 6px;
  color: var(--text-primary);
  font-size: 0.875rem;
  font-family: inherit;
  transition: border-color 0.2s ease;
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  outline: none;
  border-color: var(--link);   /* --link, not --primary: the same color in the light theme, but in the dark theme --primary reads 2.7 against a field and --link clears 3.0 */
  box-shadow: 0 0 0 3px var(--accent-primary-10);
}

.form-input::placeholder,
.form-textarea::placeholder {
  color: var(--muted-foreground);
  opacity: 1;   /* browsers dim placeholders by default; the muted text color already is the placeholder level */
}

/* Table Styles */
table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 1rem;
  text-align: left;
  border-bottom: 1px solid var(--border-subtle);
}

th {
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

tbody tr {
  transition: background-color 0.2s ease;
}

tbody tr:hover {
  background: var(--bg-tertiary);
}

/* Modal Styles */
.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--overlay-modal);
  backdrop-filter: blur(4px);
  z-index: 99999;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.modal.active {
  display: flex;
}

.modal-content {
  background: var(--bg-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  padding: 2rem;
  max-width: 500px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-modal);
}

/* Sidebar Styles */
.sidebar {
  transition: transform 0.3s ease;
}

/* Header Styles */
header {
  backdrop-filter: blur(10px);
}

/* Typography */
h1,
h2,
h3,
h4,
h5,
h6 {
  color: var(--text-primary);
  font-weight: 600;
  line-height: 1.2;
}

h1 {
  font-size: 2rem;
}

h2 {
  font-size: 1.5rem;
}

h3 {
  font-size: 1.25rem;
}

a {
  color: var(--link);
  text-decoration: none;
  transition: color 0.2s ease;
}

a:hover {
  color: color-mix(in srgb, var(--link) 80%, var(--foreground));
}

/* Animations */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in {
  animation: fadeIn 0.3s ease;
}

/* Alpine.js Transitions */
[x-cloak] {
  display: none !important;
}

/* Loading Spinner */
.spinner {
  border: 3px solid var(--bg-tertiary);
  border-top-color: var(--accent-primary);
  border-radius: 50%;
  width: 24px;
  height: 24px;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Text Utilities */
.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Responsive */
@media (max-width: 768px) {
  .modal-content {
    padding: 1.5rem;
  }
  
  th,
  td {
    padding: 0.75rem;
    font-size: 0.875rem;
  }
}

/* Print Styles */
@media print {
  body {
    background: white;
    color: black;
  }
  
  .no-print {
    display: none !important;
  }
}
