/* ============================================================
 * JARGAN SEMANTIC TOKEN LAYER — Single Source of Truth
 * BU-373: Collapse competing token/theme files into ONE look-agnostic layer
 * ------------------------------------------------------------
 * RULES:
 *   - Token NAMES are semantic, never look-named
 *     --color-canvas (NOT --paper / --ed-canvas / --newsprint)
 *     --radius-md    (NOT --rounded / --sharp)
 *     --font-display (NOT --serif / --playfair)
 *   - :root is the CONTROL theme = the usable production Blazor admin look
 *     (sans / rounded / soft-shadow / Traffic Orange). The editorial Newsprint
 *     look is now the swappable variant, applied via class jgn-variant-b.
 *   - A throwaway variant is ONE added CSS layer of token value
 *     overrides — zero markup edits required
 *   - This file replaces:
 *       jargan-tokens.css  (ed-* editorial tokens, look-named)
 *       tokens.css         (color-brand and neutral tokens, mixed)
 *       styles-editorial.css :root block (duplicate overrides)
 *       themes-canonical.css :root block (--body-bg etc)
 *       themes.css :root block (glass-morphism vars)
 * ============================================================ */

/* ---- Google Fonts ---- */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,600&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  /* ---- Palette (semantic roles, not colour names) ---- */
  --color-canvas:           #f8f8f8;   /* page background */
  --color-surface:          #ffffff;   /* raised card/panel surface */
  --color-ink:              #1a1a1a;   /* primary text */
  --color-ink-dim:          #4a4a4a;   /* secondary text (neutral gray) */
  --color-ink-muted:        #6b6b6b;   /* tertiary / meta text (5.3:1 on #F9F9F7) */
  /* blue-gray text ramp (the app's dominant secondary/tertiary text hue — distinct
     from the neutral ink-dim/muted; exact dominant defaults so the un-skinned app is
     identical, theme blocks flip them light on dark vibes). PM-010 text sweep. */
  --color-ink-secondary:    #6b7280;   /* blue-gray secondary (Tailwind gray-500) */
  --color-ink-tertiary:     #9ca3af;   /* blue-gray tertiary / placeholder (gray-400) */
  /* text that lives on ALWAYS-DARK chrome (app header, dark modals, inverted strips)
     — must STAY light on every theme. Do NOT route this to ink-* (those flip dark on
     light vibes). */
  --color-invert-ink-dim:   #c7ccd3;   /* light-gray label on dark chrome */
  /* ink as an rgb triple, for text the app sets via rgba(0,0,0,α) (muted-by-opacity
     body/meta text). Default 0,0,0 = byte-identical; themes flip it light so the
     opacity-muted text stays legible on dark vibes. Use: rgba(var(--color-ink-rgb), α). */
  --color-ink-rgb:          0, 0, 0;
  --signal-tone:          #ffffff;
  --signal-amt:           0%;
  --color-status-success-text: color-mix(in srgb, var(--color-status-success), var(--signal-tone) var(--signal-amt));
  --color-status-warning-text: color-mix(in srgb, var(--color-status-warning), var(--signal-tone) var(--signal-amt));
  --color-status-error-text:   color-mix(in srgb, var(--color-status-error), var(--signal-tone) var(--signal-amt));
  --color-status-info-text:    color-mix(in srgb, var(--color-status-info), var(--signal-tone) var(--signal-amt));
  --color-indigo-text:         color-mix(in srgb, var(--color-indigo), var(--signal-tone) var(--signal-amt));
  --color-vis-highlight-text:  color-mix(in srgb, var(--color-vis-highlight), var(--signal-tone) var(--signal-amt));

  /* BU-532 (reskin-tokenize /plan/generator): the Plan Generator's material
     signal family — stage-category tabs, gantt bars, revision-kind markers.
     Distinct from the orange stage ramp; defaults are the page's exact values. */
  --color-sig-green:        #4caf50;
  --color-sig-green-rgb:    76, 175, 80;
  --color-sig-blue:         #2196f3;
  --color-sig-blue-rgb:     33, 150, 243;
  --color-sig-amber:        #ff9800;
  --color-sig-amber-rgb:    255, 152, 0;
  --color-sig-purple:       #9c27b0;
  --color-sig-purple-rgb:   156, 39, 176;
  --color-sig-slate:        #607d8b;
  --color-sig-blue-deep:    #1976d2;   /* selected gantt bar / calendar drop target */
  --color-sig-blue-deep-rgb: 25, 118, 210;
  --color-status-error-strong: #b91c1c; /* danger button hover/pressed fill */
  --color-fill-neutral-strong: #495057; /* dark neutral chip fill with on-accent text */
  --color-surface-rgb:      255, 255, 255;  /* surface as rgb for rgba(var(),a) glass that auto-themes */
  /* ---- Soft-tint system (PM-010 tint sweep) ----
     Pale colored badge/surface backgrounds: bg+border use rgba(var(--*-rgb), a) so they
     composite over the THEMED surface (pale on light, dark on dark) — auto-theming, no
     per-theme values. Text uses theme-aware tint-*-text tokens: dark on the pale default
     badge, flipped light on dark vibes (so default identity holds AND text stays legible). */
  --color-status-success-rgb: 25, 135, 84;
  --color-status-warning-rgb: 217, 119, 6;
  --color-status-error-rgb:   220, 38, 38;
  --color-status-info-rgb:    2, 132, 199;
  --color-indigo-rgb:         99, 102, 241;
  --color-tint-warning-text:  #854F0B;
  --color-tint-info-text:     #0C447C;
  --color-tint-success-text:  #27500A;
  --color-tint-error-text:    #b91c1c;
  --color-tint-indigo-text:   #3C3489;
  --color-line:             #e2e2e2;   /* hairline divider / border (light) */
  --color-line-strong:      #d1d5db;   /* heavier divider (gray-300) */
  --color-line-subtle:      #f3f4f6;   /* faint divider / row separator (gray-100) */
  --color-line-invert:      #2a2f37;   /* divider on always-dark chrome */
  --color-hover-surface:    #f3f3f3;   /* hover / focus surface fill */
  /* near-white elevation tints the app hardcodes on panels/rows (PM-010 Phase 3
     structural tokenize). Exact defaults so the un-skinned app is identical;
     variants remap them so these surfaces recolor instead of staying white. */
  --color-surface-raised:   #fafafa;   /* subtle raised panel (warm) */
  --color-surface-sunken:   #f5f5f5;   /* sunken / hover row (warm) */
  --color-surface-cool:     #f9fafb;   /* cool faint panel */
  --color-surface-cool-2:   #f3f4f6;   /* cool muted row */
  --color-accent:           #DD5100;   /* brand signal — Traffic Orange */
  --color-accent-rgb:       221, 81, 0; /* accent as rgb triple for rgba(var(--color-accent-rgb), a) tints (PM-010 tokenize) */
  --color-accent-aa:        #BD4500;   /* AA-safe shade on light canvas (4.62:1) */
  --color-accent-on-dark:   #FF6B1A;   /* accent on inverted/dark backgrounds */
  --color-accent-tint:      rgba(221, 81, 0, 0.06);
  --color-accent-hover:     rgba(221, 81, 0, 0.10);
  --color-accent-strong:    #8A3300;   /* accent pressed/hover-dark */
  --color-on-accent:        #FFFFFF;   /* text/icon on an accent fill */
  --color-invert-bg:        #111111;   /* inverted strip background */
  --color-invert-ink:       #FFFFFF;   /* text on inverted strip */

  /* ---- Funnel-stage ramp (canonical — consumed by markup AND charts) ---- */
  --color-stage-1:          #FFB380;   /* Awareness */
  --color-stage-2:          #FF8138;   /* Consideration */
  --color-stage-3:          #DD5100;   /* Decision */
  --color-stage-4:          #8A3300;   /* Retention */
  /* BU-382: named stage aliases. The 4 funnel stages were hardcoded with three
     different (and inconsistent) hue sets across compose-workbench.css,
     PlanGenerator.razor.css, and design-system.css. These named tokens alias the
     canonical --color-stage-1..4 ramp (which the per-vibe block below maps onto
     --v-stage-* so it repaints per vibe). Every stage circle / pill / chip /
     swatch / quad-letter routes through these for ONE consistent, vibe-aware set. */
  --color-stage-awareness:     var(--color-stage-1);
  --color-stage-consideration: var(--color-stage-2);
  --color-stage-decision:      var(--color-stage-3);
  --color-stage-retention:     var(--color-stage-4);

  /* ---- Status ---- */
  --color-indigo:           #6366f1;   /* chart/secondary indigo (funnel-level, position-bar, tier badge) — PM-010 tokenize */
  --color-status-success:   #198754;
  --color-status-warning:   #D97706;
  --color-status-error:     #DC2626;
  --color-status-info:      #0284C7;

  /* ---- Platform identity (signal-only; do not use for body text) ---- */
  --color-platform-instagram: #E1306C;
  --color-platform-facebook:  #1877F2;
  --color-platform-linkedin:  #0A66C2;
  --color-platform-youtube:   #FF0000;
  --color-platform-twitter:   #1DA1F2;
  --color-platform-tiktok:    #000000;
  --color-platform-spotify:   #1DB954;
  --color-platform-email:     #6B7280;
  --color-platform-sms:       #25D366;
  --color-platform-blog:      #14B8A6;

  /* ---- Position-type signal (IL concept colours) ---- */
  --color-pt-coin:          #0DCAF0;
  --color-pt-barbell:       #F59E0B;
  --color-pt-flywheel:      #198754;
  --color-pt-hub-spoke:     #6F42C1;
  --color-pt-pyramid:       #DD5100;

  /* ---- Visualization ---- */
  --color-vis-line:         #1F2937;
  --color-vis-node-fill:    #FFFFFF;
  --color-vis-node-border:  #374151;
  --color-vis-node-text:    #1F2937;
  --color-vis-title:        #111827;
  --color-vis-subtitle:     #6B7280;
  --color-vis-highlight:    #3B82F6;
  --color-vis-highlight-rgb: 59, 130, 246;  /* BU-386: rgb triple for rgba(var(),a) pricing-panel tints */

  /* ---- Visualization: studio-warm two-family system (BU-530, proven in BU-524 lab) ----
     Orange family marks the focal role of each position type (Hub, Fulcrum,
     Side A, Driver, Apex); plum family carries the structure. Ink on tints
     holds WCAG AA (worst measured lab pair 5.3:1).
     TOKENIZATION-GATE CONTRACT: every value is a computed chain over the
     themed canonicals (--color-surface / --color-ink / --color-accent) plus
     the --signal-amt lighten, so ALL vibes repaint the viz with zero per-vibe
     blocks. Plum is the viz's structural signal: hue is identity (literal),
     legibility is themed (signal-lighten + surface mixes). Default resolves
     within a perceptual hair of the lab values. */
  --viz-ink:                var(--color-ink, #1A1A1A);
  --viz-ink-muted:          color-mix(in srgb, #6E6961, var(--signal-tone) var(--signal-amt));
  --viz-line:               var(--color-ink, #1A1A1A);
  --viz-focal:              var(--color-accent, #DD5100);
  --viz-focal-deep:         color-mix(in srgb, color-mix(in srgb, var(--color-accent) 75%, #200800), var(--signal-tone) var(--signal-amt));
  --viz-focal-tint:         color-mix(in srgb, var(--color-accent) 15%, var(--color-surface));
  --viz-structure-text:     color-mix(in srgb, #4B4B5F, var(--signal-tone) var(--signal-amt));
  --viz-structure-border:   color-mix(in srgb, #8A8AA4, var(--signal-tone) var(--signal-amt));
  --viz-structure-tint:     color-mix(in srgb, #8A8AA4 18%, var(--color-surface));
  --viz-structure-tint-deep:color-mix(in srgb, #8A8AA4 28%, var(--color-surface));
  --viz-neutral-fill:       color-mix(in srgb, var(--color-ink) 5%, var(--color-surface));

  /* ---- Borders ---- */
  --border-grid:            1px solid #e2e2e2;
  --border-section:         2px solid var(--color-accent);
  --border-subtle:          1px solid var(--color-line);

  /* ---- Radius ---- */
  --radius-none:            0;
  --radius-sm:              4px;     /* editorial: sharp corners */
  --radius-md:              8px;
  --radius-lg:              12px;
  --radius-xl:              16px;
  --radius-pill:            9999px; /* kept for avatars / stage dots only */

  /* ---- Shadows ---- */
  --shadow-none:            none;
  --shadow-sm:              0 1px 2px rgba(0,0,0,0.06);   /* editorial: flat, no soft shadows */
  --shadow-md:              0 2px 8px rgba(0,0,0,0.08);
  --shadow-lg:              0 8px 24px rgba(0,0,0,0.12);
  --shadow-xl:              0 16px 48px rgba(0,0,0,0.16);
  --shadow-hover:           0 4px 12px rgba(0,0,0,0.12);
  --shadow-hover-transform: translateY(-2px);

  /* ---- Type families ---- */
  --font-display:           'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-prose:             'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-ui:                'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:              'JetBrains Mono', 'SF Mono', 'Monaco', 'Fira Code', monospace;

  /* ---- Type scale ---- */
  --text-hero:              clamp(3rem, 7vw, 6rem);
  --text-display:           clamp(2rem, 4vw, 3.5rem);
  --text-h1:                clamp(1.5rem, 3vw, 2.25rem);
  --text-h2:                1.5rem;
  --text-h3:                1.125rem;
  --text-body:              0.9375rem;   /* 15px */
  --text-ui:                0.875rem;    /* 14px */
  --text-caption:           0.75rem;     /* 12px */
  --text-label:             0.6875rem;   /* 11px */
  --text-mono:              0.8125rem;   /* 13px */

  /* ---- Leading ---- */
  --leading-tight:          0.9;
  --leading-display:        1.1;
  --leading-body:           1.65;
  --leading-ui:             1.4;

  /* ---- Weight ---- */
  --weight-display:         700;
  --weight-strong:          700;
  --weight-medium:          500;
  --weight-body:            400;

  /* ---- Tracking ---- */
  --tracking-display:       -0.025em;
  --tracking-hero:          -0.035em;
  --tracking-eyebrow:       0.16em;

  /* ---- Spacing (4-unit grid) ---- */
  --space-1:    4px;
  --space-2:    8px;
  --space-3:    12px;
  --space-4:    16px;
  --space-5:    20px;
  --space-6:    24px;
  --space-8:    32px;
  --space-10:   40px;
  --space-12:   48px;
  --space-16:   64px;

  /* ---- Layout (themeable — a swap can rearrange) ---- */
  --content-max:            880px;
  --shell-max:              1200px;
  --measure-max:            540px;
  --split-cols:             1fr 1fr;  /* variant can flip to 1fr */
  --split-gap:              var(--space-8);
  --grid-min:               220px;
  --space-section:          var(--space-12);
  --space-block:            var(--space-6);

  /* ---- Motion ---- */
  --motion-fast:            150ms ease-out;
  --motion-mid:             250ms ease-out;
  --motion-slow:            350ms ease-out;

  /* ---- Legacy aliases (for components that still reference old names) ----
     These keep the build green while the migration progresses. Remove each
     alias once its consumer has been updated to the canonical name above. */
  --color-brand-primary:               var(--color-accent);
  --color-brand-primary-light-10:      #E56B1A;
  --color-brand-primary-dark-10:       var(--color-accent-aa);
  --color-brand-primary-dark-20:       var(--color-accent-strong);
  --color-neutral-white:               var(--color-canvas);
  --color-neutral-gray-50:             #F5F5F5;
  --color-neutral-gray-100:            #EEEEEA;
  --color-neutral-gray-200:            var(--color-line);
  --color-neutral-gray-300:            #D4D4CE;
  --color-neutral-gray-400:            #A3A3A3;
  --color-neutral-gray-500:            var(--color-ink-muted);
  --color-neutral-gray-600:            #525252;
  --color-neutral-gray-700:            var(--color-ink-dim);
  --color-neutral-gray-800:            #262626;
  --color-neutral-gray-900:            var(--color-ink);
  --color-neutral-black:               var(--color-ink);
  --ed-canvas:                         var(--color-canvas);
  --ed-ink:                            var(--color-ink);
  --ed-ink-dim:                        var(--color-ink-dim);
  --ed-ink-muted:                      var(--color-ink-muted);
  --ed-ink-meta:                       var(--color-ink-muted);
  --ed-divider:                        var(--color-line);
  --ed-hover-surface:                  var(--color-hover-surface);
  --ed-accent:                         var(--color-accent);
  --ed-accent-aa:                      var(--color-accent-aa);
  --ed-accent-dark:                    var(--color-accent-on-dark);
  --ed-accent-tint:                    var(--color-accent-tint);
  --ed-accent-hover:                   var(--color-accent-hover);
  --ed-border-grid:                    var(--border-grid);
  --ed-border-section:                 var(--border-section);
  --ed-border-subtle:                  var(--border-subtle);
  --ed-border-radius:                  var(--radius-md);
  --ed-shadow-none:                    var(--shadow-none);
  --ed-shadow-hover:                   var(--shadow-hover);
  --ed-shadow-hover-t:                 var(--shadow-hover-transform);
  --ed-font-display:                   var(--font-display);
  --ed-font-prose:                     var(--font-prose);
  --ed-font-ui:                        var(--font-ui);
  --ed-font-mono:                      var(--font-mono);
  --ed-text-hero:                      var(--text-hero);
  --ed-text-display:                   var(--text-display);
  --ed-text-h1:                        var(--text-h1);
  --ed-text-h2:                        var(--text-h2);
  --ed-text-h3:                        var(--text-h3);
  --ed-text-body:                      var(--text-body);
  --ed-text-ui:                        var(--text-ui);
  --ed-text-caption:                   var(--text-caption);
  --ed-text-label:                     var(--text-label);
  --ed-text-mono:                      var(--text-mono);
  --ed-leading-tight:                  var(--leading-tight);
  --ed-leading-display:                var(--leading-display);
  --ed-leading-body:                   var(--leading-body);
  --ed-leading-ui:                     var(--leading-ui);
  --ed-sp-1:  var(--space-1);
  --ed-sp-2:  var(--space-2);
  --ed-sp-3:  var(--space-3);
  --ed-sp-4:  var(--space-4);
  --ed-sp-5:  var(--space-5);
  --ed-sp-6:  var(--space-6);
  --ed-sp-8:  var(--space-8);
  --ed-sp-10: var(--space-10);
  --ed-sp-12: var(--space-12);
  --ed-sp-16: var(--space-16);
  --ed-transition:      var(--motion-mid);
  --ed-transition-fast: var(--motion-fast);
  /* theme-canonical legacy aliases */
  --body-bg:               var(--color-canvas);
  --body-color:            var(--color-ink);
  --surface-bg:            var(--color-hover-surface);
  --voice-badge-color:     var(--color-accent);
  --error-color:           var(--color-status-error);
  /* themes.css legacy aliases */
  --radius-2xl:            16px;
  --radius-none: 0;
  --glass-panel-bg:        var(--color-surface);
  --glass-panel-border:    var(--color-line);
  --glass-panel-shadow:    var(--shadow-md);
  --glass-card-bg:         var(--color-surface);
  --glass-card-bg-hover:   var(--color-hover-surface);
  --glass-card-border:     var(--color-line);
  --glass-card-border-hover: var(--color-ink-muted);
  --glass-card-shadow:     var(--shadow-sm);
  --glass-card-shadow-hover: var(--shadow-hover);
  --input-bg:              var(--color-surface);
  --input-bg-focus:        var(--color-surface);
  --input-border:          var(--color-line);
  --input-border-focus:    var(--color-ink-muted);
  --btn-bg:                var(--color-ink);
  --btn-border:            var(--color-ink);
  --btn-color:             var(--color-invert-ink);
  --btn-bg-hover:          var(--color-ink-dim);
  --success-bg:            rgba(25, 135, 84, 0.08);
  --success-border:        rgba(25, 135, 84, 0.35);
  --success-color:         #155936;
  --error-bg:              rgba(220, 38, 38, 0.08);
  --error-border:          rgba(220, 38, 38, 0.35);
  --error-color-state:     #7F1D1D;
  /* transitions aliases */
  --transition-fast:       var(--motion-fast);
  --transition-normal:     var(--motion-mid);
  --transition-slow:       var(--motion-slow);
  /* font aliases */
  --font-sans:             var(--font-ui);
  /* spacing aliases */
  --space-0:  0;
  /* text size aliases */
  --text-xs:   var(--text-label);
  --text-sm:   var(--text-caption);
  --text-base: var(--text-body);
  --text-lg:   var(--text-h3);
  --text-xl:   1.25rem;
  --text-2xl:  var(--text-h2);
  --text-3xl:  1.875rem;
  --text-4xl:  2.25rem;
  --font-normal:    var(--weight-body);
  --font-medium:    var(--weight-medium);
  --font-semibold:  600;
  --font-bold:      var(--weight-strong);
  --leading-normal: var(--leading-ui);
  --leading-relaxed: 1.75;
}

/* ============================================================
 * THROWAWAY VARIANT LAYER (A/B swap demo — BU-373 acceptance)
 * Apply: add class="jgn-variant-b" to <html> or <body>
 * Restyles the migrated surface with ZERO markup edits; swaps the surface to
 * the editorial Newsprint look (serif / warm canvas / sharp corners / hard
 * offset shadow).
 * ============================================================ */
.jgn-variant-b {
  --color-canvas:       #E8E0CF;
  --color-surface:      #F6F1E5;
  --color-ink:          #111111;
  --color-ink-dim:      #404040;
  --color-ink-muted:    #737373;
  --color-line:         #E5E5E0;
  --color-hover-surface: #F5F5F5;
  --color-invert-bg:    #111111;
  --color-invert-ink:   #FFFFFF;
  --radius-none:        0;
  --radius-sm:          0;
  --radius-md:          0;
  --radius-lg:          0;
  --radius-xl:          0;
  --shadow-sm:          none;
  --shadow-md:          none;
  --shadow-lg:          none;
  --shadow-hover:       4px 4px 0 0 #111111;
  --shadow-hover-transform: translate(-2px, -2px);
  --font-display:       'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-prose:         'Lora', Georgia, 'Times New Roman', serif;
  --weight-display:     800;
  --border-grid:        1px solid #111111;
  --border-section:     4px solid #111111;
  --ed-border-radius:   0;
  --radius-2xl:         0;
  --glass-panel-shadow: none;
  --glass-card-shadow:  none;
}

/* PM-010: Bootstrap bridge — most admin screens are Bootstrap-painted (--bs-* vars),
   which bypass the canonical tokens. Override Bootstrap's surface variables in the
   variant ONLY (control keeps Bootstrap defaults, so control is byte-identical).
   This makes Bootstrap-based screens repaint on the jgn-variant-b token swap. */
.jgn-variant-b {
  --bs-body-bg:            #E8E0CF;   /* paper canvas (= variant --color-canvas) */
  --bs-body-color:         #111111;   /* ink */
  --bs-secondary-bg:       #F6F1E5;   /* paper surface */
  --bs-secondary-color:    #404040;
  --bs-tertiary-bg:        #EFE8D8;
  --bs-tertiary-color:     #737373;
  --bs-emphasis-color:     #111111;
  --bs-border-color:       #C9BFA8;   /* editorial rule */
  --bs-card-bg:            #F6F1E5;
  --bs-card-color:         #111111;
  --bs-card-border-color:  #C9BFA8;
  --bs-card-cap-bg:        #EFE8D8;
  --bs-heading-color:      #111111;
}

/* PM-010: Bootstrap component surfaces — Bootstrap sets these per-component, so a
   root --bs-* override loses to the component's local default. Scope under the
   variant (control unaffected) so the swap repaints them app-wide. */
.jgn-variant-b .card,
.jgn-variant-b .modal-content,
.jgn-variant-b .dropdown-menu,
.jgn-variant-b .list-group-item,
.jgn-variant-b .offcanvas,
.jgn-variant-b .accordion-button,
.jgn-variant-b .accordion-item {
  background-color: var(--color-surface);
  color: var(--color-ink);
  border-color: var(--color-line);
}
.jgn-variant-b .card { border-radius: var(--radius-md); }
.jgn-variant-b .table { --bs-table-bg: transparent; --bs-table-color: var(--color-ink); }

/* PM-010: Bootstrap component-variable families — extend the variant bridge across
   the rest of Bootstrap so tables, forms, nav, badges, buttons repaint on swap.
   Variant-scoped only (control = Bootstrap defaults, untouched). Accent buttons
   keep Traffic Orange (brand signal, not theme-invariant chrome). */
.jgn-variant-b {
  /* tables */
  --bs-table-bg:            transparent;
  --bs-table-color:         var(--color-ink);
  --bs-table-border-color:  var(--color-line);
  --bs-table-striped-bg:    rgba(17,17,17,0.03);
  --bs-table-hover-bg:      rgba(17,17,17,0.05);
  /* forms */
  --bs-form-control-bg:     var(--color-surface);
  /* nav / tabs */
  --bs-nav-tabs-border-color: var(--color-line);
  --bs-nav-tabs-link-active-bg: var(--color-surface);
  --bs-nav-tabs-link-active-color: var(--color-ink);
  /* generic borders + headings */
  --bs-border-color-translucent: var(--color-line);
}
/* form inputs + secondary/light/outline buttons -> paper surface (primary stays accent) */
.jgn-variant-b .form-control,
.jgn-variant-b .form-select,
.jgn-variant-b .input-group-text {
  background-color: var(--color-surface);
  color: var(--color-ink);
  border-color: var(--color-line);
}
.jgn-variant-b .btn-light,
.jgn-variant-b .btn-outline-secondary,
.jgn-variant-b .btn-secondary {
  --bs-btn-bg: var(--color-surface);
  --bs-btn-color: var(--color-ink);
  --bs-btn-border-color: var(--color-line);
  --bs-btn-hover-bg: var(--color-hover-surface);
}
.jgn-variant-b .badge.bg-light,
.jgn-variant-b .badge.text-bg-light { background-color: var(--color-surface) !important; color: var(--color-ink) !important; }

/* PM-010: Bootstrap .table uses a nested colour cascade (striped/active/hover states
   override --bs-table-color). Set the state variables too so table text reskins. */
.jgn-variant-b .table {
  --bs-table-color: var(--color-ink);
  --bs-table-striped-color: var(--color-ink);
  --bs-table-active-color: var(--color-ink);
  --bs-table-hover-color: var(--color-ink);
  --bs-emphasis-color: var(--color-ink);
}

/* PM-010: panel/host shells + remaining surface containers -> variant surface */
.jgn-variant-b .panel-host-panel,
.jgn-variant-b .panel-host-panel-header,
.jgn-variant-b .panel-host-panel-body,
.jgn-variant-b [class*="panel-host"],
.jgn-variant-b .neo-panel,
.jgn-variant-b .neo-panel-flat {
  background-color: var(--color-surface);
  border-color: var(--color-line);
}

/* PM-010: scoped-CSS components ([b-hash] selectors tie + win on load order) need
   higher specificity to reskin. html.jgn-variant-b (0,2,1) beats scoped (0,2,0). */
html.jgn-variant-b .panel-host-panel,
html.jgn-variant-b .panel-host-panel-header,
html.jgn-variant-b .panel-host-panel-body,
html.jgn-variant-b [class*="panel-host"],
html.jgn-variant-b .neo-panel,
html.jgn-variant-b .neo-panel-flat,
html.jgn-variant-b .neo-card {
  background-color: var(--color-surface);
  border-color: var(--color-line);
  color: var(--color-ink);
}
html.jgn-variant-b .panel-host-panel { background-color: var(--color-surface) !important; }

/* ============================================================
 * CANONICAL LAYER → data-theme awareness (PM-010 convergence).
 * The app's themes set --bg-color/--surface-bg/--bg-* but never the canonical
 * --color-* tokens, so components routed to var(--color-surface) stayed light
 * under every theme. Map the canonical tokens per data-theme here so a theme
 * = values in ONE block and every --color-*-consuming component recolors.
 * Mirrors each theme's existing surface/ink intent.
 * ============================================================ */
[data-theme="dark"] {
  /* BU-532: the legacy dark block predates the link routing the generic vibe
     mapping has — a, .btn-link stayed #0071c1 (3.36:1 on charcoal). Same fix. */
  --color-brand-secondary: #6ab8ff;
  --bs-link-color:         #6ab8ff;
  --bs-link-hover-color:   #8ec9ff;
  --color-canvas:         #1a1a2e;
  --color-surface:        #16213e;
  --color-surface-raised: #1e2a48;
  --color-surface-sunken: #0f3460;
  --color-surface-cool:   #16213e;
  --color-surface-cool-2: #1a2540;
  --color-hover-surface:  #2a3f5f;
  --color-ink:            #eaeaea;
  --signal-amt:           44%;
  --color-accent-strong:  #ff8a4d;
  --color-accent-aa:      #ff8a4d;
  --color-ink-rgb:        234, 234, 234;
  --color-surface-rgb:    22, 33, 62;
  --color-tint-warning-text:  #f0b860;
  --color-tint-info-text:     #93c5fd;
  --color-tint-success-text:  #86efac;
  --color-tint-error-text:    #fca5a5;
  --color-tint-indigo-text:   #c7d2fe;
  --color-ink-dim:        #a8b0c0;
  --color-ink-muted:      #8a93a8;
  --color-ink-secondary:  #a8b0c0;
  --color-ink-tertiary:   #8a93a8;
  --color-line:           rgba(255,255,255,0.12);
  --color-line-strong:    rgba(255,255,255,0.20);
  --color-line-subtle:    rgba(255,255,255,0.08);
  /* themes.css component-surface layer (close the shared coverage gap: dark was
     missing the bs-/component-var layer that dusk had, so bg-light/alert/kpi/
     pack/voice-badge surfaces leaked white under dark). */
  --surface-bg:           #16213e;
  --body-bg:              #1a1a2e;
  --kpi-strip-bg:         #0f3460;
  --pack-card-bg:         #16213e;
  --card-footer-bg:       #0f3460;
  --voice-badge-bg:       #1e2a48;
  --glass-panel-bg:       rgba(22,33,62,0.85);
  --glass-card-bg:        rgba(30,42,72,0.7);
  --input-bg:             #0f3460;
  --input-bg-focus:       #1e2a48;
  --bs-secondary-bg:      #1e2a48;
  --bs-light:             #16213e;
  --bs-light-rgb:         22,33,62;
  --bs-body-color:        #eaeaea;
  --bs-body-bg:           #1a1a2e;
  --bs-emphasis-color:    #ffffff;
  --bs-heading-color:     #eaeaea;
  --bs-secondary-color:   #a8b0c0;
}
[data-theme="pastel-mondrian"] {
  --color-canvas:         #f7ead4;
  --color-surface:        #fdf6e6;   /* distinct warm cream (ΔE>24 from default #fff so themed surfaces read as repainted, not leaked) */
  --color-surface-raised: #fbf0dc;
  --color-surface-sunken: #f1e4cf;
  --color-surface-cool:   #fbf3e6;
  --color-surface-cool-2: #f1e4cf;
  --color-hover-surface:  #f1e4cf;
  --color-ink:            #304c61;
  --color-ink-rgb:        48, 76, 97;
  --color-surface-rgb:    253, 246, 230;
  --color-ink-dim:        #5a6b78;
  --color-ink-muted:      #5A6C83;   /* BU-552: darkened from #708299 (3.31:1) to 4.52:1 on canvas / 4.99:1 on surface — AA; stays lighter than ink-dim so muted<dim<ink hierarchy holds */
  --color-ink-secondary:  #5a6b78;
  --color-ink-tertiary:   #708299;
  --color-line:           #d4c5a8;
  --color-line-strong:    #c2b08a;
  --color-line-subtle:    #e2d4ba;
  /* themes.css component-surface layer (close the shared coverage gap for pastel). */
  --surface-bg:           #fdf6e6;
  --body-bg:              #f7ead4;
  --kpi-strip-bg:         #f1e4cf;
  --pack-card-bg:         #fdf6e6;
  --card-footer-bg:       #f1e4cf;
  --voice-badge-bg:       #efe2c8;
  --glass-panel-bg:       rgba(253,246,230,0.85);
  --glass-card-bg:        rgba(251,240,220,0.7);
  --input-bg:             #fdf6e6;
  --input-bg-focus:       #fbf0dc;
  --bs-secondary-bg:      #f1e4cf;
  --bs-light:             #fdf6e6;
  --bs-light-rgb:         253,246,230;
  --bs-body-color:        #304c61;
  --bs-body-bg:           #f7ead4;
  --bs-emphasis-color:    #1f3344;
  --bs-heading-color:     #304c61;
  --bs-secondary-color:   #5a6b78;
}

/* FRESH-VIBE PROOF (PM-010): "Dusk" — a never-used deep-indigo vibe, authored
   values-only to test rapid-reskin against the calibrated gate. Canonical + the
   themes.css component-surface layer, one block, NO new application rules, NO
   component edits. What still leaks = families not yet in the shared contract. */
[data-theme="dusk"] {
  --color-canvas:         #16121f;
  --color-surface:        #221b33;
  --color-surface-raised: #2b2240;
  --color-surface-sunken: #1b1528;
  --color-surface-cool:   #221b33;
  --color-surface-cool-2: #251d38;
  --color-hover-surface:  #312747;
  --color-ink:            #ece8f5;
  --signal-amt:           44%;
  --color-accent-strong:  #ff8a4d;
  --color-accent-aa:      #ff8a4d;
  --color-ink-rgb:        236, 232, 245;
  --color-surface-rgb:    34, 27, 51;
  --color-tint-warning-text:  #f0b860;
  --color-tint-info-text:     #93c5fd;
  --color-tint-success-text:  #86efac;
  --color-tint-error-text:    #fca5a5;
  --color-tint-indigo-text:   #c7d2fe;
  --color-ink-dim:        #b6acce;
  --color-ink-muted:      #a59cc0;
  --color-ink-secondary:  #b6acce;
  --color-ink-tertiary:   #a59cc0;
  --color-line:           rgba(255,255,255,0.12);
  --color-line-strong:    rgba(255,255,255,0.20);
  --color-line-subtle:    rgba(255,255,255,0.08);
  /* themes.css component-surface layer (same block) */
  --surface-bg:           #221b33;
  --body-bg:              #16121f;
  --kpi-strip-bg:         #1b1528;
  --pack-card-bg:         #221b33;
  --card-footer-bg:       #1b1528;
  --voice-badge-bg:       #2b2240;
  --glass-panel-bg:       rgba(34,27,51,0.85);
  --glass-card-bg:        rgba(43,34,64,0.7);
  --input-bg:             #1b1528;
  --input-bg-focus:       #2b2240;
  --bs-secondary-bg:      #2b2240;
  --bs-light:             #221b33;
  --bs-light-rgb:         34,27,51;
  --bs-body-color:        #ece8f5;
  --bs-body-bg:           #16121f;
  --bs-emphasis-color:    #ffffff;
  --bs-heading-color:     #ece8f5;
  --bs-secondary-color:   #b6acce;
}

/* COLD-VIBE ACCEPTANCE (PM-010): "Deep Sea" — abyssal teal-black, bioluminescent
   cyan accents, kelp-green highlights. Authored values-only, same shape as Dusk:
   canonical + themes.css component layer + --bs-* + tint-text + ink-rgb + surface-rgb,
   ONE block, NO new application rules, NO component edits. Brand accent stays Traffic
   Orange (signal preserved; keeps the gate's accent exclusion valid). */
[data-theme="deep-sea"] {
  --color-canvas:         #04161a;
  --color-surface:        #0a2329;
  --color-surface-raised: #0e2e36;
  --color-surface-sunken: #061b20;
  --color-surface-cool:   #0a2329;
  --color-surface-cool-2: #0c2a31;
  --color-hover-surface:  #123a44;
  --color-ink:            #e0f5f0;
  --signal-amt:           44%;
  --color-accent-strong:  #ff8a4d;
  --color-accent-aa:      #ff8a4d;
  --color-ink-dim:        #9ec9c4;
  --color-ink-muted:      #6f9b97;
  --color-ink-secondary:  #9ec9c4;
  --color-ink-tertiary:   #6f9b97;
  --color-ink-rgb:        224, 245, 240;
  --color-surface-rgb:    10, 35, 41;
  --color-line:           rgba(120, 230, 220, 0.14);
  --color-line-strong:    rgba(120, 230, 220, 0.22);
  --color-line-subtle:    rgba(120, 230, 220, 0.08);
  --color-tint-warning-text: #f0d890;
  --color-tint-info-text:    #7fe3ff;
  --color-tint-success-text: #9be8a0;
  --color-tint-error-text:   #ff9a9a;
  --color-tint-indigo-text:  #b8c0ff;
  /* themes.css component-surface layer */
  --surface-bg:           #0a2329;
  --body-bg:              #04161a;
  --kpi-strip-bg:         #061b20;
  --pack-card-bg:         #0a2329;
  --card-footer-bg:       #061b20;
  --voice-badge-bg:       #0e2e36;
  --glass-panel-bg:       rgba(10,35,41,0.85);
  --glass-card-bg:        rgba(14,46,54,0.7);
  --input-bg:             #061b20;
  --input-bg-focus:       #0e2e36;
  --bs-secondary-bg:      #0e2e36;
  --bs-light:             #0a2329;
  --bs-light-rgb:         10,35,41;
  --bs-body-color:        #e0f5f0;
  --bs-body-bg:           #04161a;
  --bs-emphasis-color:    #ffffff;
  --bs-heading-color:     #e0f5f0;
  --bs-secondary-color:   #9ec9c4;
}

/* carbon-lime — MAPS the Blazor --color-* scheme onto the canonical --v-* vars
   from jargan-vibe-palette.css (shared, single source of truth with the SPA).
   No raw hex: the vibe + the brand colour live in the palette, one place. */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) {
  --color-canvas:         var(--v-canvas);
  --color-surface:        var(--v-surface);
  --color-surface-raised: var(--v-surface-raised);
  --color-surface-sunken: var(--v-surface-sunken);
  --color-surface-cool:   var(--v-surface);
  --color-surface-cool-2: var(--v-surface-raised);
  --color-hover-surface:  var(--v-hover);
  --color-ink:            var(--v-ink);
  --signal-amt:           44%;
  /* BRAND signal = JARGAN orange. Reads the --admin surface variant first so the
     admin can strategically diverge from the SPA, else the shared --v-accent-brand. */
  --color-accent:         var(--v-accent-brand--admin, var(--v-accent-brand));
  --color-on-accent:      var(--v-on-accent);
  --color-accent-hover:   var(--v-accent-brand-soft);
  --color-accent-tint:    var(--v-accent-brand-tint);
  --color-accent-strong:  var(--v-accent-2);
  --color-accent-aa:      var(--v-accent-2);
  --color-ink-dim:        var(--v-ink-dim);
  --color-ink-muted:      var(--v-ink-muted);
  --color-ink-secondary:  var(--v-ink-dim);
  --color-ink-tertiary:   var(--v-ink-muted);
  --color-ink-rgb:        var(--v-ink-rgb);
  --color-surface-rgb:    var(--v-surface-rgb);
  --color-line:           var(--v-line);
  --color-line-strong:    var(--v-line-strong);
  --color-line-subtle:    var(--v-line-subtle);
  /* PM-010 reskin coverage: stage identity recolors per vibe (matches SP-509 on the
     SPA). Without these the pale default stage tints (#FFB380 etc.) stay constant and
     stage-tinted borders (compose media-card multilink / engagement tabs) never repaint
     under the dark vibe. Map onto the canonical per-vibe stage palette. */
  --color-stage-1:        var(--v-stage-awareness);
  --color-stage-2:        var(--v-stage-consideration);
  --color-stage-3:        var(--v-stage-decision);
  --color-stage-4:        var(--v-stage-retention);
  --color-tint-warning-text: var(--v-warning);
  --color-tint-info-text:    var(--v-info);
  --color-tint-success-text: var(--v-success);
  --color-tint-error-text:   var(--v-error);
  --color-tint-indigo-text:  #b8c0ff;
  --surface-bg:           var(--v-surface);
  --body-bg:              var(--v-canvas);
  --kpi-strip-bg:         var(--v-canvas);
  --pack-card-bg:         var(--v-surface);
  --card-footer-bg:       var(--v-canvas);
  --voice-badge-bg:       var(--v-surface-raised);
  --glass-panel-bg:       color-mix(in srgb, var(--v-surface) 85%, transparent);
  --glass-card-bg:        color-mix(in srgb, var(--v-surface-raised) 70%, transparent);
  --input-bg:             var(--v-canvas);
  --input-bg-focus:       var(--v-surface-raised);
  --bs-secondary-bg:      var(--v-surface-raised);
  --bs-light:             var(--v-surface);
  --bs-light-rgb:         var(--v-surface-rgb);
  --bs-body-color:        var(--v-ink);
  --bs-body-bg:           var(--v-canvas);
  --bs-emphasis-color:    #ffffff;
  --bs-heading-color:     var(--v-ink);
  --bs-secondary-color:   var(--v-ink-dim);
  /* Bootstrap .card kept its white --bs-card-bg (bridged for .jgn-variant-b but not
     the vibe), leaving template-builder / edit-form cards white with light labels on
     top. Bridge the card family onto the token origin. */
  --bs-card-bg:           var(--v-surface);
  --bs-card-color:        var(--v-ink);
  --bs-card-border-color: var(--v-line);
  --bs-card-cap-bg:       var(--v-surface-sunken);
  /* PM-010 reskin coverage: legacy color-text- / color-border aliases are used by
     older pages (btn-cancel, pager-count, etc.) with a hardcoded light fallback and
     were never defined per-theme, so they stayed light-gray under the vibe. Define
     them on the canonical origin so every legacy consumer reskins. */
  --color-text-primary:   var(--v-ink);
  --color-text-secondary: var(--v-ink-dim);
  --color-text-tertiary:  var(--v-ink-muted);
  --color-text:           var(--v-ink);
  --color-border:         var(--v-line);
  /* Status colours were never redefined for the vibe, so they fell back to the dark
     default saturated set (#DC2626 etc.) which sits at ~3.5:1 on charcoal and never
     repaints. Route to the canonical light status palette (AA on dark). Fixes status
     text/badges app-wide incl. the simulator --over/--ok tokens that alias these. */
  --color-status-success: var(--v-success);
  --color-status-warning: var(--v-warning);
  --color-status-error:   var(--v-error);
  --color-status-info:    var(--v-info);
  /* Links: the global `a, .btn-link` rule uses var(--color-brand-secondary, #0071c1)
     and Bootstrap's --bs-link-color; both land at ~3.5:1 blue on charcoal. Route to
     the vibe's light info cyan so every link clears AA. */
  --color-brand-secondary: var(--v-info);
  --bs-link-color:        var(--v-info);
  --bs-link-hover-color:  var(--v-info);
  /* --border-grid is a composite border shorthand hardcoded to a light hairline
     (1px solid #e2e2e2) and never redefined per-theme, so jgn-card / jgn-stat-grid
     top-rules didn't repaint. Route to the token line. */
  --border-grid:          1px solid var(--v-line);
  /* PM-010 reskin coverage: the data-theme vibe blocks were missing the Bootstrap
     border/table bridge that .jgn-variant-b carries, so generic Bootstrap borders
     (--bs-border-color default #dee2e6) and table cells leaked light defaults under
     the dark vibe (the /analytics matrix sub-header, utility-bordered cells). Mirror
     the variant bridge onto the data-theme so the swap repaints them. */
  --bs-border-color:             var(--v-line);
  --bs-border-color-translucent: var(--v-line);
  --bs-table-bg:                 transparent;
  --bs-table-color:              var(--v-ink);
  --bs-table-border-color:       var(--v-line);
  --bs-table-striped-color:      var(--v-ink);
  --bs-table-hover-color:        var(--v-ink);
  --bs-table-active-color:       var(--v-ink);
  /* BU-390: invert strip (.badge.bg-dark and other inverted chrome) was pinned to the
     root default #111/#fff and never repainted per vibe, so on the LIGHT sepia vibe the
     dark badge stayed dark-locked (gate darkChrome). Map the invert pair onto the vibe
     ink/canvas so the strip flips with the skin: a vibe-ink strip on a light vibe
     (changed from #111 -> repaints), a light strip on a dark vibe. */
  --color-invert-bg:             var(--v-ink);
  --color-invert-ink:            var(--v-canvas);
}

/* BU-390: sepia-ledger is the only LIGHT vibe in the shared block above, so the
   on-dark signal-tone (#fff) + pale on-dark text tokens lighten text toward white on
   cream (invisible). Re-point them to AA-on-cream values for this vibe only. The two
   dark vibes (carbon-lime, harbor-night) keep the shared on-dark values.
   SPECIFICITY IDIOM (BU-390): the generic-vibe mapping block above is
   [data-theme]:not(x6) = (0,7,0) and ALSO matches sepia-ledger, so a plain
   :root[data-theme="sepia-ledger"] (0,2,0) override LOSES to it. To win, a
   per-vibe token override MUST mirror the same :not() chain so it is (0,8,0)+.
   Reuse this prefix for any future per-vibe override that overrides a generic-block token. */
:root[data-theme="sepia-ledger"]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) {
  /* signal mix darkens toward sepia ink on the light vibe (was #ffffff lighten) so every
     *-text color-mix (status-*-text, indigo-text, vis-highlight-text, compose stage text,
     and the .btn-outline-* color-mix in jgn-components.css) resolves AA-dark on cream. */
  --signal-tone: #241c10;
  --color-tint-indigo-text: #3c3489;
  /* BU-388: colored tokens that are AA as a FILL/badge-bg on cream but FAIL AA as TEXT.
     Add AA-dark sepia TEXT variants WITHOUT touching the bright fill values (--v-accent-2
     #b5532a and --v-warning #b06410 stay correct as badge backgrounds / borders).
       - --color-accent-aa / --color-accent-strong: the accent-2 sienna used AS TEXT
         (.jgn-badge--accent, compose/analytics/media accent labels). #b5532a is 4.60 on
         cream but 4.11 on the raised surface (sub-AA); darker sienna #8a3d1c -> 7.05 cream
         / 6.30 surface, still recognizably sienna. Drives the bulk of /compose contrast=109.
       - --color-tint-warning-text: line 740 of the generic block sets this to raw
         var(--v-warning) #b06410 (3.40 on tinted badge). Darker amber #854F0B -> 4.88 on
         the badge tint / 6.24 on cream, still amber. (Matches the dark-default value.) */
  --color-accent-aa:         #8a3d1c;
  --color-accent-strong:     #8a3d1c;
  --color-tint-warning-text: #854F0B;
}

/* PM-010 reskin coverage: Bootstrap .table-secondary (the /analytics coverage-matrix
   sub-header row) hardcodes its OWN light --bs-table-bg via the table-variant mixin,
   so it ignores the row-level remap above. Override it to a token surface so it
   repaints with the vibe instead of staying near-white. */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .table-secondary {
  --bs-table-bg:           var(--v-surface-sunken);
  --bs-table-color:        var(--v-ink);
  --bs-table-border-color: var(--v-line);
}

/* PM-010 reskin coverage: Bootstrap form controls keep a white --bs-body-bg default,
   so /preferences/profile inputs stayed white under the dark vibe. Route them to token
   surfaces (the .jgn-variant-b bridge does the same for the class variant). */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .form-control,
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .form-select,
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .input-group-text {
  background-color: var(--v-surface);
  color: var(--v-ink);
  border-color: var(--v-line);
}

/* PM-010 reskin coverage: outline/secondary/light buttons keep Bootstrap's fixed
   gray --bs-btn-border-color (#6c757d) which never repaints. Bridge them onto the
   token origin so their chrome reskins with the vibe (also covers the legacy edit
   forms). Solid/brand buttons keep Traffic Orange (signal, theme-invariant). */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-outline-secondary,
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-light,
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-secondary {
  --bs-btn-border-color: var(--v-line);
  --bs-btn-color: var(--v-ink);
  --bs-btn-hover-bg: var(--v-hover);
  --bs-btn-hover-border-color: var(--v-line-strong);
  --bs-btn-hover-color: var(--v-ink);
}
/* Solid secondary/light buttons also carry a fixed Bootstrap fill (#6c757d / #f8f9fa)
   that never repaints. Route the fill to a token surface. */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-secondary,
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-light {
  --bs-btn-bg: var(--v-surface-raised);
  --bs-btn-active-bg: var(--v-hover);
}
/* Bootstrap accordion ships white --bs-accordion-bg / light borders. Bridge it. */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .accordion {
  --bs-accordion-bg: var(--v-surface);
  --bs-accordion-color: var(--v-ink);
  --bs-accordion-border-color: var(--v-line);
  --bs-accordion-btn-bg: var(--v-surface);
  --bs-accordion-btn-color: var(--v-ink);
  --bs-accordion-active-bg: var(--v-surface-raised);
  --bs-accordion-active-color: var(--v-ink);
  --bs-accordion-btn-focus-border-color: var(--v-line);
}
/* Some outline-secondary buttons (e.g. template filter pills) carry a direct
   border-color: #6b7280 that beats the --bs-btn-border-color var. Force the resting
   border to the OPAQUE border token (not the near-transparent --v-line): the swap
   leaves the inherited light value in place when applied to a freshly-loaded
   (data-theme=null) tree, and a transparent target can't out-distance #e2e2e2 in
   the gate's RGB-channel check. #3a424a repaints unambiguously. */
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-outline-secondary:not(:hover):not(.active),
[data-theme]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) .btn-secondary:not(:hover):not(.active) {
  border-color: var(--v-border) !important;
}

/* BU-532: gallery-plaster is a LIGHT vibe under the generic mapping (which assumes
   dark and sets a 44% white signal-lighten). Same idiom as sepia-ledger: keep the
   amount, flip the tone to the vibe's ink so signal text DARKENS on plaster. */
:root[data-theme="gallery-plaster"]:not([data-theme="default"]):not([data-theme="dark"]):not([data-theme="deep-sea"]):not([data-theme="dusk"]):not([data-theme="instrument-paper"]):not([data-theme="pastel-mondrian"]) {
  --signal-tone: #23201c;
}
