/* ===== /css/tokens.css?v=6 ===== */
/* Nexora v4 design tokens — Confident Editorial with Vibrant Soul.
   Linear-meets-Stripe direction: electric indigo brand, sophisticated
   accent palette, restored subtle shadows, hover micro-motion ready. */

:root {
  /* ── Typography ──────────────────────────────────────────────── */
  --font-display: 'Fraunces', 'Georgia', 'Times New Roman', serif;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* ── Spacing — 4-pt scale ────────────────────────────────────── */
  --space-1:  4px;   --space-2:  8px;   --space-3:  12px;  --space-4:  16px;
  --space-5:  24px;  --space-6:  32px;  --space-7:  48px;  --space-8:  64px;
  --space-9:  96px;  --space-10: 128px;

  /* ── Radii ───────────────────────────────────────────────────── */
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-full: 9999px;

  /* ── Shadow — RESTORED (subtle but present for depth) ────────── */
  --shadow-none:     none;
  --shadow-subtle:   0 1px 2px rgba(15,15,30,.04);
  --shadow-card:     0 1px 2px rgba(15,15,30,.04), 0 2px 4px rgba(15,15,30,.04);
  --shadow-elevated: 0 4px 12px -2px rgba(15,15,30,.08), 0 2px 6px rgba(15,15,30,.05);
  --shadow-modal:    0 24px 48px -12px rgba(15,15,30,.20), 0 8px 16px rgba(15,15,30,.06);
  --shadow-focus:    0 0 0 3px rgba(80,70,229,0.30);
  --shadow-glow:     0 0 0 4px rgba(80,70,229,0.16), 0 4px 12px -2px rgba(80,70,229,0.30);
  --shadow-glow-soft: 0 4px 24px -8px rgba(80,70,229,0.30);

  /* ── Focus ring — unified. All interactive elements read from these
     tokens (button, form, card, link). The halo is composed of an inner
     surface-colored spacer + an outer brand halo, so the ring visually
     "floats" above the border regardless of surface color. Overridable
     per component via `--ring-color` if a tone-specific ring is needed. */
  --ring-width:  3px;
  --ring-offset: 2px;
  --ring-color:  var(--brand-glow);

  /* ── Motion — material standard ──────────────────────────────── */
  --ease:        cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --d-instant:   100ms;
  --d-fast:      150ms;
  --d:           240ms;
  --d-slow:      320ms;

  /* ── Brand — ELECTRIC INDIGO (vibrant, alive, sophisticated) ─── */
  --brand:         #5046E5;
  --brand-hover:   #4338CA;
  --brand-active:  #3730A3;
  --brand-fade:    rgba(80,70,229,0.10);
  --brand-strong:  rgba(80,70,229,0.22);
  --brand-glow:    rgba(80,70,229,0.30);
  --brand-soft:    #EEF0FE;
  --brand-gradient: linear-gradient(135deg, #5046E5 0%, #7C3AED 100%);

  /* ── Secondary accent — WARM CORAL (sparingly, for delight) ──── */
  --accent-coral:      #F97316;
  --accent-coral-fade: rgba(249,115,22,0.10);
  --accent-coral-soft: #FFF3EA;

  /* ── Canvas — cleaner warm white ─────────────────────────────── */
  --bg:           #FBFBFA;
  --surface:      #FFFFFF;
  --surface-soft: #F4F4F2;
  --surface-2:    #FFFFFF;
  --bg-hover:     #F0F0EE;

  /* ── Text — confident deep neutral ───────────────────────────── */
  --text:    #18181B;
  --text-2:  #52525B;
  --muted:   #A1A1AA;

  /* ── Border — clean gray ─────────────────────────────────────── */
  --border:        #E4E4E7;
  --border-strong: #D4D4D8;
  --border-soft:   #F4F4F5;

  /* ── Semantic — VIBRANT (not muted, but considered) ──────────── */
  --success:    #16A34A;
  --success-bg: rgba(22,163,74,0.10);
  --warning:    #EA580C;
  --warning-bg: rgba(234,88,12,0.10);
  --danger:     #DC2626;
  --danger-bg:  rgba(220,38,38,0.10);
  --info:       #2563EB;
  --info-bg:    rgba(37,99,235,0.10);

  /* ── Legacy aliases (preserved for backward compat) ──────────── */
  --accent:        var(--brand);
  --accent-hover:  var(--brand-hover);
  --accent2:       var(--info);
  --accent2-light: var(--info-bg);
  --green:         var(--success);
  --green-light:   var(--success-bg);
  --red:           var(--danger);
  --red-light:    var(--danger-bg);
  --yellow:        var(--warning);
  --yellow-light:  var(--warning-bg);
  --orange:        var(--accent-coral);
  --purple:        #7C3AED;
  --teal:          #0D9488;
  --card:          var(--surface);
  --intent-success: var(--success);
  --intent-danger:  var(--danger);
  --intent-warning: var(--warning);
  --intent-info:    var(--info);
  --intent-neutral: var(--muted);

  /* ── A6 (Wave/Agent 4): Colorblind-safe badge ICONS ─────────────────
     Status badges that rely on green + orange + yellow simultaneously
     fail deuteranopia (red-green colour vision deficiency). These
     custom properties document the suggested Feather / Lucide icon
     name to PAIR WITH each colour so the meaning is conveyed by both
     hue AND shape. Consumers (badge components) should read these
     values via getComputedStyle or apply them via content/attr().
     Purely additive — no existing colour token is touched. */
  --badge-icon-green:  "check-circle";   /* success / on-track / done */
  --badge-icon-orange: "zap";            /* initiative / attention */
  --badge-icon-yellow: "alert-triangle"; /* warning / problem-solving */
  --badge-icon-red:    "x-octagon";      /* failure / blocker / overdue */

  color-scheme: light;
}

/* ══════════════════════════════════════════════════════════════════
   DARK MODE — SINGLE SOURCE OF TRUTH
   ------------------------------------------------------------------
   Merged with the former [data-theme="dark"] block from
   css/nexora-theme.css (Consolidation Sprint / Day 4). Where the two
   files disagreed the more considered nexora-theme values won:
   canvas & surfaces get a subtle purple/indigo tint, borders and
   hovers use rgba-white for cheaper compositing.
   ════════════════════════════════════════════════════════════════ */
[data-theme="dark"],
html.dark,
.dark-theme {
  --brand:         #818CF8;
  --brand-hover:   #A5B4FC;
  --brand-active:  #C7D2FE;
  --brand-fade:    rgba(129,140,248,0.14);
  --brand-strong:  rgba(129,140,248,0.26);
  --brand-glow:    rgba(129,140,248,0.36);
  --brand-soft:    rgba(129,140,248,0.08);

  --accent-coral:      #FB923C;
  --accent-coral-fade: rgba(251,146,60,0.14);

  /* Canvas — kept nexora-theme's purple-tinted deep values. */
  --bg:           #0A0A0F;
  --surface:      #111118;
  --surface-soft: #16161F;
  --surface-2:    #16161F;
  --card:         #16161F;
  --bg-hover:     rgba(255,255,255,0.04);
  --bg-input:     #1C1C28;
  --bg-overlay:   rgba(0,0,0,.7);

  /* Sidebar-scoped surfaces (dark also carries a brand-tinted border). */
  --sidebar-bg:     #0E0E14;
  --sidebar-border: rgba(99,102,241,.25);

  /* Neutrals — nexora-theme's softer set for readability on tinted bg. */
  --text:         #F0F0F5;
  --text-2:       #C0C0D0;
  --muted:        #8888A0;
  --muted-light:  #55556A;

  /* Borders — rgba-white so they inherit the surface tint. */
  --border:        rgba(255,255,255,0.06);
  --border-strong: rgba(255,255,255,0.14);
  --border-soft:   rgba(255,255,255,0.03);
  --border-light:  rgba(255,255,255,0.03);

  /* Legacy semantic aliases used by v2 and app.css component rules. */
  --accent:        var(--brand);
  --accent-light:  rgba(129,140,248,0.10);
  --accent-hover:  var(--brand-hover);
  --accent2:       #22D3EE;
  --accent2-light: rgba(34,211,238,0.10);
  --green:         #4ADE80;  --green-light:  rgba(74,222,128,0.10);
  --yellow:        #FDE68A;  --yellow-light: rgba(253,230,138,0.08);
  --red:           #FCA5A5;  --red-light:    rgba(252,165,165,0.08);
  --purple:        #C4B5FD;  --purple-light: rgba(196,181,253,0.08);
  --orange:        #FDBA74;  --orange-light: rgba(253,186,116,0.08);
  --teal:          #5EEAD4;  --teal-light:   rgba(94,234,212,0.08);
  --pink:          #F9A8D4;  --pink-light:   rgba(249,168,212,0.08);

  --shadow-xs:       0 1px 3px rgba(0,0,0,.40);
  --shadow-sm:       0 2px 8px rgba(0,0,0,.40);
  --shadow-md:       0 4px 16px rgba(0,0,0,.45);
  --shadow-lg:       0 10px 40px rgba(0,0,0,.50);
  --shadow-xl:       0 20px 60px rgba(0,0,0,.60);
  --shadow-card:     0 1px 2px rgba(0,0,0,.40), 0 2px 4px rgba(0,0,0,.30);
  --shadow-elevated: 0 4px 12px -2px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.30);
  --shadow-modal:    0 24px 48px -12px rgba(0,0,0,.70), 0 8px 16px rgba(0,0,0,.40);
  --shadow-focus:    0 0 0 3px rgba(129,140,248,0.40);
  --shadow-glow:     0 0 0 4px rgba(129,140,248,0.20), 0 4px 12px -2px rgba(129,140,248,0.40);

  color-scheme: dark;
}

/* ===== /css/v2/system_tokens.css?v=1 ===== */
/* DEPRECATED: see ./tokens_unified.css for canonical design tokens.
   All z-index, motion, duration, easing, and transition tokens previously
   defined here have moved to tokens_unified.css (single source of truth).
   This file is kept only so existing <link rel="stylesheet"> tags do not 404.
   Safe to delete once index.html no longer references it. */
/* @import stripped by build-assets */

/* ===== /css/app.css?v=57 ===== */
/* ═══════════════════════════════════════════════
   PM COMMAND CENTER — Design System v8
   ═══════════════════════════════════════════════ */

/* ── SVG Icon Utilities ─────────────────────── */
.icon{display:inline-block;vertical-align:middle;flex-shrink:0;}
.icon-10{width:10px;height:10px;}
.icon-11{width:11px;height:11px;}
.icon-12{width:12px;height:12px;}
.icon-13{width:13px;height:13px;}
.icon-14{width:14px;height:14px;}
.icon-15{width:15px;height:15px;}
.icon-16{width:16px;height:16px;}
.icon-17{width:17px;height:17px;}
.icon-20{width:20px;height:20px;}
.icon-21{width:21px;height:21px;}
.icon-22{width:22px;height:22px;}
.icon-28{width:28px;height:28px;}
.icon-30{width:30px;height:30px;}
:root{
  /* Core palette — warm off-white base, calm zinc tones, Notion/Asana-inspired */
  --bg:#fafaf9;              /* warm off-white (stone-50) */
  --surface:#ffffff;
  --card:#ffffff;
  --border:#e7e5e4;          /* stone-200 — softer than slate */
  --border-light:#f5f5f4;    /* stone-100 */
  --bg-input:#fafaf9;
  --bg-hover:#f5f5f4;
  --bg-overlay:rgba(28,25,23,.35);   /* warm overlay, less harsh */
  --sidebar-bg:#fafaf9;       /* light-on-light sidebar */
  --sidebar-border:#e7e5e4;

  /* Brand — softer indigo-violet */
  --accent:#6366f1;           /* indigo-500 — slightly softer than 4f46e5 */
  --accent-hover:#4f46e5;
  --accent-light:#eef2ff;     /* indigo-50 */
  --accent2:#0ea5e9;
  --accent2-light:#e0f2fe;

  /* Semantic — same hue but tuned for pastel-bg pattern */
  --green:#059669;   --green-light:#ecfdf5;
  --yellow:#d97706;  --yellow-light:#fffbeb;
  --red:#dc2626;     --red-light:#fef2f2;
  --purple:#7c3aed;  --purple-light:#f5f3ff;
  --orange:#ea580c;  --orange-light:#fff7ed;
  --teal:#0d9488;    --teal-light:#f0fdfa;
  --pink:#db2777;    --pink-light:#fdf2f8;

  /* Text — warm zinc instead of cool slate */
  --text:#18181b;             /* zinc-900 */
  --text-2:#3f3f46;           /* zinc-700 */
  --muted:#71717a;            /* zinc-500 */
  --muted-light:#a1a1aa;      /* zinc-400 */

  /* Elevation — softer, less contrasty */
  --shadow-xs:0 1px 2px rgba(28,25,23,.04);
  --shadow-sm:0 1px 3px rgba(28,25,23,.06),0 1px 2px rgba(28,25,23,.03);
  --shadow-md:0 4px 12px rgba(28,25,23,.06),0 2px 4px rgba(28,25,23,.03);
  --shadow-lg:0 10px 28px rgba(28,25,23,.08),0 4px 8px rgba(28,25,23,.04);
  --shadow-xl:0 20px 56px rgba(28,25,23,.12),0 8px 16px rgba(28,25,23,.05);

  /* Typography */
  --font:'Inter',system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono','Fira Code',monospace;

  /* Radius — slightly larger, more modern */
  --r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:20px;
}

/* ── Dark Theme — warm zinc/stone instead of cool slate ── */
[data-theme="dark"]{
  --bg:#18181b;              /* zinc-900 */
  --surface:#27272a;         /* zinc-800 */
  --card:#27272a;
  --border:#3f3f46;          /* zinc-700 */
  --border-light:#27272a;
  --bg-input:#18181b;
  --bg-hover:rgba(255,255,255,.05);
  --bg-overlay:rgba(0,0,0,.55);
  --sidebar-bg:#18181b;
  --sidebar-border:rgba(255,255,255,.08);

  /* Softer accent for dark */
  --accent:#a5b4fc;
  --accent-hover:#c7d2fe;
  --accent-light:rgba(165,180,252,.14);
  --accent2:#67e8f9;
  --accent2-light:rgba(103,232,249,.12);

  /* Semantic — pastel saturation on warm bg */
  --green:#6ee7b7;  --green-light:rgba(110,231,183,.14);
  --yellow:#fcd34d; --yellow-light:rgba(252,211,77,.12);
  --red:#fca5a5;    --red-light:rgba(252,165,165,.12);
  --purple:#c4b5fd; --purple-light:rgba(196,181,253,.12);
  --orange:#fdba74; --orange-light:rgba(253,186,116,.12);
  --teal:#5eead4;   --teal-light:rgba(94,234,212,.12);
  --pink:#f9a8d4;   --pink-light:rgba(249,168,212,.12);

  /* Warm text — zinc instead of slate */
  --text:#fafaf9;            /* stone-50 */
  --text-2:#e7e5e4;          /* stone-200 */
  --muted:#a1a1aa;           /* zinc-400 */
  --muted-light:#71717a;     /* zinc-500 */

  --shadow-xs:0 1px 3px rgba(0,0,0,.3);
  --shadow-sm:0 2px 6px rgba(0,0,0,.3);
  --shadow-md:0 4px 16px rgba(0,0,0,.35);
  --shadow-lg:0 10px 40px rgba(0,0,0,.45);
  --shadow-xl:0 24px 64px rgba(0,0,0,.55);
}

/* ── Reset & Base ── */
*{margin:0;padding:0;box-sizing:border-box;}
html{-webkit-font-smoothing:antialiased;}
body{background:var(--bg);color:var(--text);font-family:var(--font);min-height:100vh;font-size:14px;line-height:1.5;}

/* ── Loading ── */
.loading{position:fixed;inset:0;background:var(--surface);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:16px;z-index:999;}
.spinner{width:36px;height:36px;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite;}
@keyframes spin{to{transform:rotate(360deg)}}
.loading-text{font-size:13px;color:var(--muted);font-family:var(--mono);letter-spacing:.03em;}
.nav-hidden{display:none!important;}
.spinner-sm{width:16px;height:16px;border-width:2px;}

/* ══════════════════════════════════════════════
   LOGIN PAGE — Track-C calm/friendly aesthetic
═══════════════════════════════════════════════ */
#loginScreen{display:none;min-height:100vh;background:var(--bg);align-items:center;justify-content:center;position:relative;overflow:hidden;}
/* Two soft radial glows behind the card — gentle brand presence without heavy chrome */
#loginScreen::before{content:'';position:absolute;top:-180px;left:-120px;width:520px;height:520px;border-radius:50%;background:radial-gradient(circle,rgba(99,102,241,.16),transparent 65%);filter:blur(40px);pointer-events:none;}
#loginScreen::after{content:'';position:absolute;bottom:-160px;right:-120px;width:480px;height:480px;border-radius:50%;background:radial-gradient(circle,rgba(139,92,246,.14),transparent 65%);filter:blur(40px);pointer-events:none;}
.login-wrap{width:420px;max-width:92vw;animation:fadeUp .5s cubic-bezier(.16,1,.3,1) both;z-index:1;}
@keyframes fadeUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}
.login-brand{text-align:center;margin-bottom:32px;}
.login-logo{width:56px;height:56px;display:flex;align-items:center;justify-content:center;margin:0 auto 14px;filter:drop-shadow(0 8px 24px rgba(99,102,241,.22));}
.login-logo svg{width:56px;height:56px;}
.login-title{font-size:28px;font-weight:700;color:var(--text);letter-spacing:-.6px;}
.login-sub{font-size:13px;color:var(--muted);margin-top:6px;font-weight:500;}
.login-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-xl);padding:32px;box-shadow:var(--shadow-md);}
.login-card-title{font-size:13px;color:var(--muted);font-weight:600;letter-spacing:.1px;margin-bottom:22px;}
.login-error{background:var(--red-light);border:1px solid rgba(220,38,38,.2);border-radius:var(--r-sm);padding:10px 14px;font-size:12.5px;color:var(--red);margin-bottom:16px;display:none;align-items:center;gap:8px;}
.login-error.show{display:flex;}
.login-card .btn-primary{margin-top:6px;}
[data-theme="dark"] #loginScreen{background:var(--bg);}
[data-theme="dark"] #loginScreen::before{background:radial-gradient(circle,rgba(99,102,241,.22),transparent 65%);}
[data-theme="dark"] #loginScreen::after{background:radial-gradient(circle,rgba(139,92,246,.20),transparent 65%);}

/* ══════════════════════════════════════════════
   FORMS
═══════════════════════════════════════════════ */
.form-group{margin-bottom:18px;}
.form-label{font-size:12px;font-weight:600;color:var(--text-2);letter-spacing:.1px;margin-bottom:7px;display:block;}
.form-input,.form-select,.form-textarea{width:100%;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);font-size:13.5px;padding:10px 14px;outline:none;transition:all .15s;}
.form-input:focus,.form-select:focus,.form-textarea:focus{border-color:var(--accent);background:var(--card);box-shadow:0 0 0 3px var(--accent-light);}
.form-input::placeholder,.form-textarea::placeholder{color:var(--muted-light);}
.form-select option{background:var(--card);}
.form-textarea{min-height:80px;resize:vertical;}

/* ══ MULTI-SELECT ASSIGNEE ═══════════════════════════════════ */
.assignee-multi-wrap{position:relative;}
.assignee-tags{min-height:38px;background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);padding:5px 8px;display:flex;flex-wrap:wrap;gap:5px;align-items:center;cursor:pointer;transition:all .2s;}
.assignee-tags:focus-within,.assignee-tags.open{border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px rgba(79,70,229,.1);}
.assignee-tag{display:inline-flex;align-items:center;gap:4px;background:var(--purple-light);color:var(--purple);border:1px solid #c4b5fd;border-radius:20px;padding:2px 8px;font-size:11px;font-weight:600;}
.assignee-tag .tag-remove{cursor:pointer;color:var(--purple);line-height:1;font-size:13px;background:none;border:none;padding:0;}
.assignee-tag .tag-remove:hover{color:var(--purple);}
.assignee-placeholder{font-size:13px;color:var(--muted-light);}
.assignee-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--surface);border:1.5px solid var(--accent);border-radius:var(--r-sm);box-shadow:0 8px 24px rgba(0,0,0,.12);z-index:9999;max-height:260px;overflow:hidden;display:none;flex-direction:column;}
.assignee-dropdown.open{display:flex;}
.assignee-dropdown-search{padding:8px 8px 6px;border-bottom:1px solid var(--border-light);background:var(--surface);position:sticky;top:0;z-index:1;}
.assignee-search-input{width:100%;border:1px solid var(--border);border-radius:var(--r-sm);padding:7px 10px;font-size:13px;font-family:inherit;color:var(--text);background:var(--surface);outline:none;box-sizing:border-box;}
.assignee-search-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(79,70,229,.12);}
.assignee-dropdown-list{overflow-y:auto;max-height:210px;-webkit-overflow-scrolling:touch;}
.assignee-dropdown-empty{padding:14px 12px;font-size:12px;color:var(--muted);text-align:center;}
.assignee-dropdown-item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:12.5px;cursor:pointer;transition:background .12s;}
.assignee-dropdown-item:hover{background:var(--purple-light);}
.assignee-dropdown-item.selected{background:var(--purple-light);color:var(--purple);font-weight:600;}
.assignee-dropdown-item .item-check{width:14px;height:14px;border:1.5px solid var(--border);border-radius:3px;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.assignee-dropdown-item.selected .item-check{background:var(--accent);border-color:var(--accent);color:var(--surface);}

/* ══ DATE INPUT STYLING ══════════════════════════════════════ */
.date-wrap{position:relative;display:block;}
.date-wrap .form-input[type="date"]{padding-left:36px;cursor:pointer;color:var(--text);}
.date-wrap .form-input[type="date"]::-webkit-calendar-picker-indicator{
  opacity:0;position:absolute;left:0;top:0;width:100%;height:100%;cursor:pointer;}
.date-wrap .date-icon{
  position:absolute;left:11px;top:50%;transform:translateY(-50%);
  color:var(--muted);pointer-events:none;display:flex;align-items:center;}
.form-input[type="date"]:not(.date-wrap .form-input){
  appearance:none;-webkit-appearance:none;cursor:pointer;}

.form-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.form-hint{font-size:10.5px;color:var(--muted);margin-top:4px;}
.input-wrap{position:relative;}
.input-wrap .form-input{padding-left:40px;}
.input-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:14px;pointer-events:none;}

/* ══════════════════════════════════════════════
   BUTTONS
═══════════════════════════════════════════════ */
.btn{padding:9px 16px;border-radius:var(--r-sm);border:1px solid transparent;font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;transition:all .15s cubic-bezier(.4,0,.2,1);display:inline-flex;align-items:center;justify-content:center;gap:6px;letter-spacing:.01em;line-height:1;}
.btn:active{transform:scale(.97);}
.btn-primary{background:var(--accent);color:var(--surface);box-shadow:0 1px 2px rgba(99,102,241,.18);}
.btn-primary:hover{background:var(--accent-hover);box-shadow:0 2px 8px rgba(99,102,241,.25);}
.btn-ghost{background:transparent;color:var(--text-2);border-color:var(--border);}
.btn-ghost:hover{color:var(--text);border-color:var(--muted-light);background:var(--bg-hover);}
.btn-secondary{background:var(--bg-hover);color:var(--text);border-color:var(--border);}
.btn-secondary:hover{background:var(--border-light);}
.btn-danger{background:transparent;color:var(--red);border-color:var(--red-light);}
.btn-danger:hover{background:var(--red-light);}
.btn-warning{background:transparent;color:var(--yellow);border-color:var(--yellow-light);}
.btn-warning:hover{background:var(--yellow-light);}
.btn-teal{background:transparent;color:var(--teal);border-color:var(--teal-light);}
.btn-teal:hover{background:var(--teal-light);}
.btn-purple{background:transparent;color:var(--purple);border-color:var(--purple-light);}
.btn-purple:hover{background:var(--purple-light);}
.btn-sm{padding:6px 11px;font-size:11.5px;border-radius:7px;}
.btn-full{width:100%;padding:12px;}

/* ══════════════════════════════════════════════
   LAYOUT
═══════════════════════════════════════════════ */
.app{display:flex;height:100vh;overflow:hidden;}

/* ── Sidebar — light-on-light, calm ── */
.sidebar{width:236px;background:var(--sidebar-bg);display:flex;flex-direction:column;padding:0;flex-shrink:0;position:relative;border-right:1px solid var(--sidebar-border);transition:width .3s cubic-bezier(.4,0,.2,1);}
.logo{padding:22px 20px 18px;border-bottom:1px solid var(--border-light);}
.logo-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;margin-bottom:10px;filter:drop-shadow(0 2px 8px rgba(80,70,229,.22));}
.logo-text{font-size:15px;font-weight:700;color:var(--text);letter-spacing:-.3px;}
.logo-sub{font-size:10px;color:var(--muted);font-family:var(--mono);margin-top:2px;}
.nav{padding:14px 10px;flex:1;overflow-y:auto;}
.nav-group{margin-bottom:2px;}
.nav-group-toggle{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;cursor:pointer;border-radius:8px;transition:background .15s;user-select:none;}
.nav-group-toggle:hover{background:var(--bg-hover);}
.nav-group-toggle span{font-size:10px;font-weight:700;color:var(--muted-light);text-transform:uppercase;letter-spacing:1px;}
.nav-chevron{color:var(--muted-light);transition:transform .25s cubic-bezier(.4,0,.2,1);flex-shrink:0;}
.nav-group.open .nav-chevron{transform:rotate(180deg);}
.nav-group-items{overflow:hidden;max-height:0;transition:max-height .28s cubic-bezier(.4,0,.2,1);}
.nav-group.open .nav-group-items{max-height:600px;}
.nav-item{display:flex;align-items:center;gap:10px;padding:8px 12px;cursor:pointer;color:var(--text-2);font-size:13px;font-weight:500;transition:all .15s;border-radius:8px;margin-bottom:2px;position:relative;}
.nav-item:hover{color:var(--text);background:var(--bg-hover);}
.nav-item.active{color:var(--accent);background:var(--accent-light);font-weight:600;}
.nav-item.active::before{content:none;}
.nav-icon{font-size:15px;width:20px;text-align:center;flex-shrink:0;color:var(--muted);}
.nav-item:hover .nav-icon{color:var(--text);}
.nav-item.active .nav-icon{color:var(--accent);}
.nav-badge{margin-left:auto;background:var(--red);color:var(--surface);font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px;}
.sidebar-user{padding:14px 16px;border-top:1px solid var(--border-light);display:flex;gap:10px;align-items:center;background:transparent;}
.s-avatar{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,var(--accent),var(--purple));display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:var(--surface);flex-shrink:0;box-shadow:0 2px 6px rgba(99,102,241,.25);}
.s-info{flex:1;min-width:0;}
.s-name{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text);}
.s-role{font-size:10.5px;color:var(--muted);margin-top:1px;}
.logout-btn{background:none;border:none;cursor:pointer;color:var(--muted);font-size:15px;padding:6px;border-radius:8px;transition:all .15s;flex-shrink:0;}
.logout-btn:hover{color:var(--red);background:var(--red-light);}

/* ── Topbar icon buttons (shared) ── */
.topbar-icon-btn,.sidebar-toggle,.lang-toggle,.theme-toggle{border-radius:8px;border:none;background:transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:all .15s;color:var(--muted);padding:6px 9px;flex-shrink:0;}
.topbar-icon-btn:hover,.sidebar-toggle:hover,.lang-toggle:hover,.theme-toggle:hover{color:var(--accent);background:var(--accent-light);}
.topbar-icon-btn svg,.sidebar-toggle svg,.lang-toggle svg,.theme-toggle svg{width:15px;height:15px;}

/* ── Sidebar collapsed ── */
.sidebar.collapsed{width:60px;}
.sidebar.collapsed .logo{padding:16px 0;display:flex;flex-direction:column;align-items:center;}
.sidebar.collapsed .logo-icon{margin-bottom:0;}
.sidebar.collapsed .logo-text,.sidebar.collapsed .logo-sub{display:none;}
.sidebar.collapsed .nav{padding:8px 6px;}
.sidebar.collapsed .nav-group-toggle{justify-content:center;padding:8px 0;}
.sidebar.collapsed .nav-group-toggle span,.sidebar.collapsed .nav-chevron{display:none;}
.sidebar.collapsed .nav-label,.sidebar.collapsed .nav-badge{display:none;}
.sidebar.collapsed .nav-item{justify-content:center;padding:9px 0;gap:0;}
.sidebar.collapsed .nav-icon{margin:0;width:auto;}
.sidebar.collapsed .sidebar-user{justify-content:center;padding:12px 6px;}
.sidebar.collapsed .s-info,.sidebar.collapsed .logout-btn{display:none;}
.sidebar.collapsed .s-avatar{width:32px;height:32px;font-size:12px;}
.sidebar.collapsed .nav-item[data-tooltip]:hover::after{content:attr(data-tooltip);position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);background:var(--text);color:var(--card);padding:6px 11px;border-radius:8px;font-size:12px;font-weight:500;white-space:nowrap;z-index:1000;pointer-events:none;box-shadow:var(--shadow-md);}

/* ── Language toggle ── */
.lang-icon-id{display:none;}
[data-lang="id"] .lang-icon-en{display:none;}
[data-lang="id"] .lang-icon-id{display:block;}

/* ── Main area ── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg);}
.topbar{background:var(--card);border-bottom:1px solid var(--border-light);padding:0 28px;height:60px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;}
.topbar-left{display:flex;align-items:center;gap:14px;}
.page-title{font-size:17px;font-weight:700;color:var(--text);letter-spacing:-.4px;}
.sub-tabs-bar{background:var(--card);border-bottom:1px solid var(--border-light);padding:10px 28px;flex-shrink:0;}
.sub-tabs{display:flex;flex-direction:column;gap:6px;}
.sub-tabs-row{display:flex;gap:2px;align-items:center;overflow-x:auto;scrollbar-width:thin;}
.sub-tabs-row-inner{padding-top:2px;}
.sub-tab-cluster{font-weight:700;letter-spacing:.2px;}
.sub-tabs::-webkit-scrollbar{height:4px;}
.sub-tabs::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:2px;}
.sub-tab{border:none;background:transparent;padding:7px 14px;font-size:13px;font-weight:500;font-family:var(--font);color:var(--muted);cursor:pointer;border-radius:8px;transition:all .15s;white-space:nowrap;}
.sub-tab:hover{color:var(--text);background:var(--bg-hover);}
.sub-tab.sub-tab-active{background:var(--accent-light);color:var(--accent);font-weight:600;}
[data-theme="dark"] .sub-tabs-bar{background:var(--card);border-color:var(--border-light);}
[data-theme="dark"] .sub-tab{color:var(--muted);}
[data-theme="dark"] .sub-tab:hover{color:var(--text);background:var(--bg-hover);}
[data-theme="dark"] .sub-tab.sub-tab-active{background:var(--accent-light);color:var(--accent);}
.page-sub{font-size:12px;color:var(--muted);border-left:1px solid var(--border);padding-left:12px;display:none;}
.topbar-right{display:flex;gap:6px;align-items:center;}
.topbar-date{font-size:11.5px;color:var(--muted);background:var(--bg);padding:5px 11px;border-radius:20px;border:1px solid var(--border);margin-right:6px;}
.content{flex:1;overflow-y:auto;padding:28px 32px;}
.content::-webkit-scrollbar{width:6px;}
.content::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px;}
.content::-webkit-scrollbar-track{background:transparent;}

.page{display:none;}
/* AI page fills full content height */
.content.ai-active{overflow:hidden;padding:0;display:flex;flex-direction:column;}
.content.ai-active #page-ai{display:flex;flex-direction:column;flex:1;min-height:0;padding:20px;}
.content.ai-active #page-ai .ai-panel{flex:1;min-height:0;}
.page.active{display:block;animation:pageIn .2s ease both;}
@keyframes pageIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ── Section header ── */
.section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;}
.section-heading{font-size:14px;font-weight:700;color:var(--text);}
.section-sub{font-size:12px;color:var(--muted);margin-top:2px;}
.section-title{font-size:10.5px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.8px;margin-bottom:10px;display:flex;align-items:center;gap:8px;}
.section-title::after{content:'';flex:1;height:1px;background:var(--border);}

/* ══════════════════════════════════════════════
   TOOLBAR / FILTERS
═══════════════════════════════════════════════ */
.toolbar{display:flex;gap:10px;align-items:center;margin-bottom:18px;flex-wrap:wrap;}
.search-box{position:relative;flex:1;min-width:200px;}
.search-input{width:100%;background:var(--card);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);font-size:13px;padding:9px 12px 9px 36px;outline:none;transition:all .15s;}
.search-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light);}
.search-input::placeholder{color:var(--muted-light);}
.search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:13px;pointer-events:none;}
.filter-select{background:var(--card);border:1px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);font-size:12.5px;padding:9px 12px;outline:none;cursor:pointer;transition:border-color .15s;}
.filter-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light);}
.filter-select option{background:var(--card);}
.result-count{font-size:11.5px;color:var(--muted);white-space:nowrap;background:var(--bg);padding:5px 11px;border-radius:20px;border:1px solid var(--border);}

/* ══════════════════════════════════════════════
   KPI CARDS — calm, minimal, generous whitespace
═══════════════════════════════════════════════ */
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:24px;}
.kpi-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);padding:22px 24px;position:relative;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);}
.kpi-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--border);}
.kpi-card-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:16px;margin-bottom:16px;flex-shrink:0;}
.kpi-card.blue .kpi-card-icon{background:var(--accent-light);color:var(--accent);}
.kpi-card.green .kpi-card-icon{background:var(--green-light);color:var(--green);}
.kpi-card.yellow .kpi-card-icon{background:var(--yellow-light);color:var(--yellow);}
.kpi-card.red .kpi-card-icon{background:var(--red-light);color:var(--red);}
.kpi-card.purple .kpi-card-icon{background:var(--purple-light);color:var(--purple);}
.kpi-label{font-size:11.5px;color:var(--muted);font-weight:600;letter-spacing:.2px;margin-bottom:6px;}
.kpi-val{font-size:30px;font-weight:700;color:var(--text);line-height:1.1;margin-bottom:6px;letter-spacing:-.5px;}
.kpi-sub{font-size:12px;color:var(--muted);}
.kpi-trend{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;padding:3px 8px;border-radius:20px;margin-top:6px;}
.kpi-trend.up{background:var(--green-light);color:var(--green);}
.kpi-trend.down{background:var(--red-light);color:var(--red);}
.kpi-trend.neutral{background:var(--bg);color:var(--muted);}
/* removed bottom gradient bar — calm look prefers no extra chrome */
.kpi-bar{display:none;}

/* ══════════════════════════════════════════════
   DASHBOARD LAYOUT
═══════════════════════════════════════════════ */
.dash-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:20px;}
.dash-grid-70-30{display:grid;grid-template-columns:7fr 3fr;gap:18px;margin-bottom:20px;}
.dash-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-bottom:20px;}
.chart-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;transition:box-shadow .2s;}
.chart-card:hover{box-shadow:var(--shadow-sm);}
.chart-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;}
.chart-title{font-size:14px;font-weight:700;color:var(--text);letter-spacing:-.1px;}
.chart-subtitle{font-size:12px;color:var(--muted);font-weight:400;margin-top:3px;}
.chart-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;}
.deadline-item{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--border-light);}
.deadline-item:last-child{border-bottom:none;}
.deadline-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.deadline-name{font-size:12.5px;font-weight:500;flex:1;}
.deadline-pm{font-size:10.5px;color:var(--muted);}
.deadline-days{font-size:11px;font-weight:700;padding:3px 8px;border-radius:20px;white-space:nowrap;}

/* ── Summary strip ── */
.summary-strip{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:24px;}
.strip-item{background:var(--card);padding:16px 20px;text-align:center;}
.strip-val{font-size:22px;font-weight:700;color:var(--text);letter-spacing:-.3px;}
.strip-label{font-size:11px;color:var(--muted);font-weight:600;margin-top:4px;}

/* ══════════════════════════════════════════════
   TABLES — calm, hover-only stripe, no chrome
═══════════════════════════════════════════════ */
.table-wrap{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:22px;}
table{width:100%;border-collapse:collapse;font-size:13px;}
thead th{background:var(--bg);padding:12px 16px;text-align:left;font-size:11px;font-weight:600;color:var(--muted);letter-spacing:.3px;border-bottom:1px solid var(--border);white-space:nowrap;}
td{padding:12px 16px;border-bottom:1px solid var(--border-light);vertical-align:middle;}
tr:last-child td{border-bottom:none;}
tbody tr{transition:background .12s;}
tbody tr:hover td{background:var(--bg-hover);}
.empty-row td{text-align:center;color:var(--muted);padding:40px;font-size:13px;}
.table-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:40px;color:var(--muted);font-size:13px;}
.td-primary{font-size:13px;font-weight:500;color:var(--text);line-height:1.4;}
.td-sub{font-size:11.5px;color:var(--muted);margin-top:2px;line-height:1.3;}
.td-meta{font-size:12px;color:var(--text-2);}
.row-muted td{opacity:.55;}
.text-red{color:var(--red);font-weight:600;}

/* ══════════════════════════════════════════════
   BADGES & CHIPS — pastel-bg + saturated-text
═══════════════════════════════════════════════ */
.badge{padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600;letter-spacing:.1px;display:inline-block;white-space:nowrap;}
.badge-green{background:var(--green-light);color:var(--green);}
.badge-blue{background:var(--accent-light);color:var(--accent);}
.badge-yellow{background:var(--yellow-light);color:var(--yellow);}
.badge-red{background:var(--red-light);color:var(--red);}
.badge-purple{background:var(--purple-light);color:var(--purple);}
.badge-gray{background:var(--bg-hover);color:var(--muted);}
.badge-teal{background:var(--teal-light);color:var(--teal);}
.badge-orange{background:var(--orange-light);color:var(--orange);}

.person-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:20px;font-size:11.5px;font-weight:500;white-space:nowrap;}
.person-chip.pm{background:var(--purple-light);color:var(--purple);}
.person-chip.pmo{background:var(--teal-light);color:var(--teal);}
.chip-label{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;opacity:.65;}

.skill-chip{display:inline-flex;align-items:center;padding:3px 9px;border-radius:20px;font-size:10.5px;font-weight:600;background:var(--accent2-light);color:var(--accent2);border:1px solid var(--accent2);margin:2px;}
.skill-chips{display:flex;flex-wrap:wrap;gap:3px;margin-top:6px;}

.action-cell{display:flex;gap:4px;flex-wrap:nowrap;}
.result-count-inline{font-size:11px;color:var(--muted);font-family:var(--mono);}

/* ══════════════════════════════════════════════
   PROGRESS
═══════════════════════════════════════════════ */
.progress-row{display:flex;align-items:center;gap:8px;}
.progress-bar{background:var(--border);border-radius:4px;height:6px;overflow:hidden;flex:1;min-width:70px;}
.progress-fill{height:100%;border-radius:4px;transition:width .5s ease;}
.progress-pct{font-size:11px;font-family:var(--mono);color:var(--muted);width:32px;text-align:right;font-weight:600;}

/* ══════════════════════════════════════════════
   ACCESS BANNER
═══════════════════════════════════════════════ */
.access-banner{border-radius:var(--r-md);padding:11px 16px;font-size:12.5px;margin-bottom:18px;display:flex;align-items:center;gap:8px;}
.access-banner.full{background:var(--green-light);border:1px solid var(--green);color:var(--green);}
.access-banner.limited{background:var(--yellow-light);border:1px solid var(--yellow);color:var(--yellow);}

/* ══════════════════════════════════════════════
   KANBAN
═══════════════════════════════════════════════ */
.kanban-controls{display:flex;gap:8px;margin-bottom:16px;align-items:center;flex-wrap:wrap;}
.kanban{display:flex;flex-direction:column;gap:0;margin-bottom:22px;}
.kanban-project-block{margin-bottom:26px;}
.kanban-project-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg) var(--r-lg) 0 0;border-bottom:1px solid var(--border-light);padding:18px 22px;display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;}
.kanban-project-card-main{flex:1;min-width:0;}
.kanban-project-card-title{font-size:14px;font-weight:800;color:var(--text);display:flex;align-items:center;gap:8px;flex-wrap:wrap;line-height:1.3;}
.kanban-project-card-meta{display:flex;flex-wrap:wrap;gap:16px;margin-top:8px;font-size:11.5px;color:var(--muted);}
.kanban-project-card-meta span{display:flex;align-items:center;gap:4px;}
.kanban-project-progress{flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:5px;min-width:120px;padding-top:2px;}
.kanban-progress-bar{width:120px;height:6px;background:var(--border);border-radius:3px;overflow:hidden;}
.kanban-progress-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,var(--info),var(--teal));}
.kanban-cols{display:grid;grid-template-columns:repeat(4,minmax(200px,1fr));gap:14px;background:var(--card);border:1px solid var(--border);border-top:none;border-radius:0 0 var(--r-lg) var(--r-lg);padding:16px;}
.kanban-col{background:var(--bg);border:1px solid var(--border-light);border-radius:var(--r-md);padding:14px;min-height:200px;}
.kanban-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid var(--border-light);}
.kanban-title{font-size:12.5px;font-weight:700;}
.kanban-count{background:var(--card);color:var(--muted);font-size:12px;padding:2px 9px;border-radius:10px;border:1px solid var(--border);font-weight:600;}
.task-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);padding:14px;margin-bottom:10px;transition:all .15s cubic-bezier(.4,0,.2,1);}
.task-card:hover{border-color:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow-sm);}
/* Overdue task card — static red border-left as a11y fallback when motion is reduced */
.task-card.task-card-overdue{border-color:#fca5a5;border-left:3px solid var(--danger,#dc2626);background:linear-gradient(135deg,var(--red-light),var(--surface));box-shadow:0 0 0 1px rgba(239,68,68,.1),var(--shadow-xs);}
.task-card.task-card-overdue:hover{border-color:var(--danger);box-shadow:0 0 0 2px rgba(239,68,68,.15),var(--shadow-md);}
.overdue-badge{display:inline-flex;align-items:center;gap:3px;font-size:12px;font-weight:700;color:var(--danger);background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.25);padding:1px 7px;border-radius:10px;white-space:nowrap;}
@media (prefers-reduced-motion: no-preference){.overdue-badge{animation:overduePulse 2s ease-in-out infinite;}}
@keyframes overduePulse{0%,100%{opacity:1}50%{opacity:.7}}
.task-dates.overdue-date{color:var(--danger);}
.task-dates.overdue-date svg{color:var(--danger);}
.overdue-days{font-weight:600;color:var(--danger);}
[data-theme="dark"] .task-card.task-card-overdue{background:linear-gradient(135deg,rgba(239,68,68,.08),var(--card));border-color:rgba(252,165,165,.3);}
[data-theme="dark"] .task-card.task-card-overdue:hover{border-color:rgba(252,165,165,.5);}
[data-theme="dark"] .overdue-badge{color:#fca5a5;background:rgba(239,68,68,.15);border-color:rgba(252,165,165,.3);}
[data-theme="dark"] .task-dates.overdue-date{color:#fca5a5;}
[data-theme="dark"] .task-dates.overdue-date svg{color:#fca5a5;}
[data-theme="dark"] .overdue-days{color:#fca5a5;}
.task-title{font-size:12.5px;font-weight:600;margin-bottom:8px;line-height:1.4;color:var(--text);}
.task-meta{display:flex;gap:5px;flex-wrap:wrap;align-items:center;}
.task-proj{font-size:10.5px;color:var(--accent2);font-weight:500;}
.task-dates{font-size:12px;line-height:1.35;color:var(--muted);margin-top:6px;display:flex;align-items:center;gap:4px;}
.task-actions{display:flex;gap:5px;margin-top:10px;flex-wrap:wrap;}
.task-assignee{display:flex;align-items:center;gap:6px;margin-top:6px;padding-top:6px;border-top:1px solid var(--border-light);}
.task-avatar{width:22px;height:22px;border-radius:6px;background:linear-gradient(135deg,var(--accent),var(--purple));display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:var(--surface);flex-shrink:0;}
.task-assignee-name{font-size:11px;font-weight:500;color:var(--text-2);}

/* ══════════════════════════════════════════════
   TEAM
═══════════════════════════════════════════════ */
.team-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-bottom:24px;}
.team-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;cursor:pointer;transition:all .15s cubic-bezier(.4,0,.2,1);}
.team-card:hover{border-color:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow-md);}
.team-card-header{display:flex;gap:14px;align-items:flex-start;margin-bottom:14px;}
.team-avatar{width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,var(--accent),var(--purple));display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:700;color:var(--surface);flex-shrink:0;box-shadow:0 3px 10px rgba(79,70,229,.25);}
.team-name{font-size:14px;font-weight:700;color:var(--text);}
.team-role{font-size:11.5px;color:var(--muted);margin-top:2px;}
.team-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border-light);}
.team-stat{text-align:center;padding:8px 4px;background:var(--bg);border-radius:8px;}
.team-stat-val{font-size:20px;font-weight:700;font-family:var(--mono);}
.team-stat-label{font-size:12px;line-height:1.3;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;font-weight:600;margin-top:2px;}
.team-cap-bar{margin-top:12px;}
.team-cap-label{font-size:11px;color:var(--muted);margin-bottom:5px;display:flex;justify-content:space-between;font-weight:500;}
.team-score-row{display:flex;align-items:center;gap:7px;margin-top:10px;}
.team-score-stars{display:flex;gap:2px;}
.team-score-val{font-size:12px;font-weight:700;font-family:var(--mono);}
.team-score-label{font-size:10.5px;color:var(--muted);}

/* ══════════════════════════════════════════════
   STARS & SCORES
═══════════════════════════════════════════════ */
.stars{display:inline-flex;gap:2px;}
.star{font-size:13px;}
.star.on{color:var(--yellow);}
.star.off{color:var(--border);}
.score-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:700;}
.score-pill.s5{background:var(--green-light);color:var(--success);}
.score-pill.s4{background:var(--accent-light);color:var(--info);}
.score-pill.s3{background:var(--yellow-light);color:var(--yellow);}
.score-pill.s2{background:var(--orange-light);color:var(--warning);}
.score-pill.s1{background:var(--red-light);color:var(--danger);}

/* ══════════════════════════════════════════════
   EVAL CARDS
═══════════════════════════════════════════════ */
.eval-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:14px;margin-bottom:10px;box-shadow:var(--shadow-xs);}
.eval-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:7px;}
.eval-category{font-size:12.5px;font-weight:700;color:var(--text);}
.eval-meta{font-size:10.5px;color:var(--muted);margin-top:4px;font-family:var(--mono);}
.eval-notes{font-size:12px;color:var(--muted);margin-top:6px;line-height:1.5;font-style:italic;border-top:1px solid var(--border-light);padding-top:6px;}
.eval-actions{display:flex;gap:4px;margin-top:8px;justify-content:flex-end;}
.appraisal-summary{background:linear-gradient(135deg,var(--bg),var(--bg-hover));border:1px solid var(--border);border-radius:var(--r-md);padding:16px;margin-bottom:16px;}
.appraisal-title{font-size:12.5px;font-weight:700;margin-bottom:12px;display:flex;justify-content:space-between;align-items:center;}
.appraisal-avg{font-size:24px;font-weight:700;font-family:var(--mono);color:var(--accent);}
.cat-bar-row{display:flex;align-items:center;gap:10px;margin-bottom:8px;}
.cat-bar-label{font-size:11px;color:var(--muted);width:130px;flex-shrink:0;}
.cat-bar-track{flex:1;background:var(--border);border-radius:4px;height:7px;overflow:hidden;}
.cat-bar-fill{height:100%;border-radius:4px;}
.cat-bar-val{font-size:11px;font-family:var(--mono);font-weight:700;width:28px;text-align:right;color:var(--text);}

/* ══════════════════════════════════════════════
   SCORE PICKER
═══════════════════════════════════════════════ */
.score-picker{display:flex;gap:8px;margin-top:8px;}
.score-btn{width:40px;height:40px;border-radius:10px;border:1.5px solid var(--border);background:var(--bg);color:var(--muted);font-size:14px;font-weight:700;cursor:pointer;transition:all .18s;display:flex;align-items:center;justify-content:center;}
.score-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
.score-btn.selected{border-color:var(--yellow);background:var(--yellow-light);color:var(--yellow);}
.score-labels{display:flex;gap:8px;margin-top:5px;}
.score-label-item{width:40px;font-size:9.5px;color:var(--muted);text-align:center;}

/* ══════════════════════════════════════════════
   TOAST
═══════════════════════════════════════════════ */
.toast{position:fixed;bottom:24px;right:24px;background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:12px 18px;font-size:13px;display:flex;align-items:center;gap:9px;z-index:300;transform:translateY(80px);opacity:0;transition:all .3s cubic-bezier(.16,1,.3,1);box-shadow:var(--shadow-lg);min-width:220px;}
.toast.show{transform:translateY(0);opacity:1;}
.toast.success{border-color:#86efac;color:var(--success);background:var(--green-light);}
.toast.error{border-color:#fca5a5;color:var(--danger);background:var(--red-light);}

/* ══════════════════════════════════════════════
   MODAL
═══════════════════════════════════════════════ */
.modal-overlay{position:fixed;inset:0;background:var(--bg-overlay);backdrop-filter:blur(8px);display:none;align-items:center;justify-content:center;z-index:100;animation:overlayIn .18s ease both;}
.modal-overlay.open{display:flex;}
@keyframes overlayIn{from{opacity:0;}to{opacity:1;}}
.modal{background:var(--card);border:1px solid var(--border);border-radius:var(--r-xl);padding:32px;width:520px;max-width:min(92vw,520px);max-height:90vh;overflow-y:auto;box-shadow:var(--shadow-xl);animation:modalIn .22s cubic-bezier(.16,1,.3,1);}
.modal-wide{width:680px;max-width:min(92vw,680px);}
body.modal-open{overflow:hidden;}
/* Type tab buttons in task modal */
.type-tab{padding:6px 14px;border-radius:20px;border:1.5px solid var(--border);background:var(--surface);font-size:12px;font-weight:600;color:var(--muted);cursor:pointer;transition:all .15s;font-family:var(--font);}
.type-tab:hover{border-color:var(--accent);color:var(--accent);}
.type-tab.active{background:var(--accent);border-color:var(--accent);color:var(--surface);box-shadow:0 2px 8px rgba(79,70,229,.3);}
#typeTab-Epic.active{background:var(--purple);border-color:var(--purple);}
#typeTab-Subtask.active{background:var(--green);border-color:var(--green);}
@keyframes modalIn{from{opacity:0;transform:scale(.96) translateY(8px)}to{opacity:1;transform:none}}
.modal-wide{width:680px;}
.modal-title{font-size:18px;font-weight:700;margin-bottom:24px;display:flex;align-items:center;gap:10px;color:var(--text);letter-spacing:-.3px;}
.modal-actions{display:flex;gap:10px;margin-top:24px;justify-content:flex-end;padding-top:20px;border-top:1px solid var(--border-light);}
.modal-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;}
.modal-header .modal-title{margin-bottom:0;}
.modal-body{margin-bottom:0;}
.modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:20px;padding-top:16px;border-top:1px solid var(--border-light);}
.modal-close{background:none;border:none;cursor:pointer;color:var(--muted);display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--r-sm);transition:all .12s;flex-shrink:0;padding:0;}
.modal-close:hover{background:var(--bg-hover);color:var(--text);}
.modal-close-injected{position:absolute;top:12px;right:12px;z-index:2;background:rgba(0,0,0,.04);}
.modal-close-injected:hover{background:rgba(0,0,0,.08);}
[data-theme="dark"] .modal-close-injected{background:rgba(255,255,255,.06);}
[data-theme="dark"] .modal-close-injected:hover{background:rgba(255,255,255,.10);color:var(--text);}
/* Required field indicator + inline error */
.form-label.req::after,label.req::after{content:' *';color:var(--red);font-weight:700;}
.form-input.has-error,.form-select.has-error,.form-textarea.has-error{border-color:var(--red) !important;background:rgba(239,68,68,.04);}
.form-error{display:block;color:var(--red);font-size:11px;margin-top:4px;font-weight:500;}
/* Button loading state */
.btn.is-loading{position:relative;color:transparent !important;pointer-events:none;opacity:.85;}
.btn.is-loading::after{content:'';position:absolute;left:50%;top:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border:2px solid currentColor;border-radius:50%;border-right-color:transparent;animation:btnSpin .6s linear infinite;color:var(--surface);}
.btn-ghost.is-loading::after,.btn-secondary.is-loading::after{color:var(--text);}
@keyframes btnSpin{to{transform:rotate(360deg);}}
/* Focus ring (accessibility) */
.form-input:focus,.form-select:focus,.form-textarea:focus,.search-input:focus,.filter-select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(99,102,241,.18);}
.btn:focus-visible,.sub-tab:focus-visible,.nav-item:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
/* Global top loading bar (shows during any fetch via api()) */
#globalLoadingBar{position:fixed;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--accent),transparent);background-size:200% 100%;z-index:9999;opacity:0;pointer-events:none;transition:opacity .15s;}
#globalLoadingBar.active{opacity:1;animation:loadingBarSweep 1.2s linear infinite;}
@keyframes loadingBarSweep{0%{background-position:200% 0;}100%{background-position:-200% 0;}}
/* Page skeleton (centered spinner) for async page first-load */
.page-skeleton{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;color:var(--muted);gap:12px;}
.page-skeleton .spinner{width:28px;height:28px;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite;}
.page-skeleton-text{font-size:12.5px;color:var(--muted);}
@keyframes spin{to{transform:rotate(360deg);}}

/* ══════════════════════════════════════════════
   AI WIDGET — floating quick-chat
═══════════════════════════════════════════════ */
#aiWidgetFab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;border:none;cursor:pointer;background:linear-gradient(135deg,var(--accent),var(--purple));color:var(--surface);display:flex;align-items:center;justify-content:center;z-index:90;box-shadow:0 8px 24px rgba(99,102,241,.32);transition:all .2s cubic-bezier(.4,0,.2,1);}
#aiWidgetFab:hover{transform:translateY(-2px) scale(1.04);box-shadow:0 12px 28px rgba(99,102,241,.42);}
#aiWidgetFab:active{transform:scale(.96);}
#aiWidgetFab svg{width:24px;height:24px;}
#aiWidgetFab.hidden{display:none;}
.ai-widget{position:fixed;bottom:96px;right:24px;width:380px;max-width:calc(100vw - 32px);height:560px;max-height:calc(100vh - 130px);background:var(--card);border:1px solid var(--border);border-radius:var(--r-xl);box-shadow:var(--shadow-xl);display:flex;flex-direction:column;z-index:91;overflow:hidden;transform:translateY(12px) scale(.96);opacity:0;pointer-events:none;transition:all .22s cubic-bezier(.16,1,.3,1);}
.ai-widget.open{transform:translateY(0) scale(1);opacity:1;pointer-events:auto;}
.aiw-header{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:14px 16px;border-bottom:1px solid var(--border-light);background:linear-gradient(135deg,rgba(99,102,241,.06),rgba(139,92,246,.04));}
.aiw-title{display:flex;align-items:center;gap:10px;min-width:0;}
.aiw-title-icon{width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,var(--accent),var(--purple));color:var(--surface);display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.aiw-title-icon svg{width:16px;height:16px;}
.aiw-title-main{font-size:13.5px;font-weight:700;color:var(--text);letter-spacing:-.1px;}
.aiw-title-sub{font-size:11px;color:var(--muted);margin-top:1px;}
.aiw-actions{display:flex;gap:4px;flex-shrink:0;}
.aiw-action-btn{width:30px;height:30px;border:none;background:transparent;color:var(--muted);cursor:pointer;border-radius:8px;display:flex;align-items:center;justify-content:center;transition:all .12s;}
.aiw-action-btn:hover{color:var(--text);background:var(--bg-hover);}
.aiw-action-btn svg{width:14px;height:14px;}
.aiw-log{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px;}
.aiw-log::-webkit-scrollbar{width:5px;}
.aiw-log::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px;}
.aiw-intro{padding:6px 4px;}
.aiw-intro-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:4px;}
.aiw-intro-sub{font-size:11.5px;color:var(--muted);margin-bottom:12px;}
.aiw-suggests{display:flex;flex-direction:column;gap:6px;}
.aiw-suggest{text-align:left;border:1px solid var(--border);background:var(--card);padding:9px 12px;border-radius:10px;font-family:var(--font);font-size:12.5px;color:var(--text);cursor:pointer;transition:all .12s;}
.aiw-suggest:hover{border-color:var(--accent);background:var(--accent-light);color:var(--accent);}
.aiw-msg{padding:10px 13px;border-radius:12px;max-width:88%;font-size:13px;line-height:1.55;white-space:pre-wrap;word-wrap:break-word;}
.aiw-user{background:var(--accent-light);color:var(--accent);align-self:flex-end;border-bottom-right-radius:4px;font-weight:500;}
.aiw-ai{background:var(--bg);color:var(--text);align-self:flex-start;border-bottom-left-radius:4px;border:1px solid var(--border-light);}
.aiw-ai-error{background:var(--red-light);color:var(--red);align-self:flex-start;border-bottom-left-radius:4px;border:1px solid rgba(220,38,38,.18);}
.aiw-ai-loading{background:var(--bg);color:var(--muted);align-self:flex-start;border-bottom-left-radius:4px;border:1px solid var(--border-light);font-style:italic;}
.aiw-ai-loading::after{content:'';display:inline-block;width:8px;height:8px;margin-left:6px;border:1.5px solid var(--muted);border-top-color:transparent;border-radius:50%;animation:spin .8s linear infinite;vertical-align:middle;}
.aiw-input-row{display:flex;gap:8px;padding:12px 14px;border-top:1px solid var(--border-light);background:var(--card);}
#aiWidgetInput{flex:1;background:var(--bg-input);border:1px solid var(--border);border-radius:10px;padding:9px 12px;font-family:var(--font);font-size:13px;color:var(--text);outline:none;transition:all .12s;}
#aiWidgetInput:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light);}
#aiWidgetSendBtn{width:36px;height:36px;flex-shrink:0;border:none;background:linear-gradient(135deg,var(--accent),var(--purple));color:var(--surface);border-radius:10px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .12s;}
#aiWidgetSendBtn:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(99,102,241,.3);}
#aiWidgetSendBtn:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}
#aiWidgetSendBtn svg{width:14px;height:14px;}
[data-theme="dark"] .aiw-header{background:linear-gradient(135deg,rgba(99,102,241,.10),rgba(139,92,246,.06));}
@media (max-width:520px){
  .ai-widget{right:8px;left:8px;width:auto;bottom:80px;height:calc(100vh - 110px);max-height:none;}
  #aiWidgetFab{bottom:16px;right:16px;width:52px;height:52px;}
}
.confirm-box{background:var(--surface);border-radius:var(--r-xl);padding:32px;width:380px;text-align:center;box-shadow:var(--shadow-xl);}
.confirm-icon{font-size:40px;margin-bottom:12px;}
.confirm-title{font-size:16px;font-weight:700;margin-bottom:8px;}
.confirm-msg{font-size:13px;color:var(--muted);margin-bottom:20px;line-height:1.6;}
.confirm-actions{display:flex;gap:8px;justify-content:center;}

/* ══════════════════════════════════════════════
   DRAWER
═══════════════════════════════════════════════ */
.drawer-overlay{position:fixed;inset:0;background:rgba(15,23,42,.35);backdrop-filter:blur(3px);display:none;z-index:90;}
.drawer-overlay.open{display:block;}
.drawer{position:fixed;top:0;right:0;width:540px;height:100vh;background:var(--surface);border-left:1px solid var(--border);display:flex;flex-direction:column;z-index:91;transform:translateX(100%);transition:transform .3s cubic-bezier(.16,1,.3,1);box-shadow:-8px 0 32px rgba(15,23,42,.08);}
.drawer.open{transform:translateX(0);}
.drawer-header{padding:22px 24px 18px;border-bottom:1px solid var(--border);display:flex;align-items:flex-start;gap:14px;}
.drawer-close{background:none;border:none;color:var(--muted);cursor:pointer;font-size:18px;padding:4px 6px;margin-left:auto;transition:all .2s;flex-shrink:0;border-radius:8px;}
.drawer-close:hover{color:var(--text);background:var(--bg);}
.drawer-body{flex:1;overflow-y:auto;padding:22px 24px;}
.drawer-body::-webkit-scrollbar{width:4px;}
.drawer-body::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:2px;}
.drawer-section{margin-bottom:24px;}
.drawer-section-label{font-size:10px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.8px;margin-bottom:10px;padding-bottom:7px;border-bottom:1px solid var(--border-light);display:flex;align-items:center;gap:6px;}
.detail-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid var(--border-light);}
.detail-row:last-child{border-bottom:none;}
.detail-label{font-size:12.5px;color:var(--muted);}
.detail-value{font-size:12.5px;font-weight:600;text-align:right;color:var(--text);}
.drawer-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:20px;overflow-x:auto;}
.drawer-tab{padding:10px 18px;font-size:12.5px;font-weight:600;cursor:pointer;color:var(--muted);border-bottom:2.5px solid transparent;transition:all .18s;white-space:nowrap;}
.drawer-tab.active{color:var(--accent);border-bottom-color:var(--accent);}
.drawer-tab:hover{color:var(--text);}
.tab-content{display:none;}
.tab-content.active{display:block;animation:pageIn .15s ease both;}
.pm-pmo-cards{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;}
.pm-card{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-md);padding:16px;}
.pm-card-type{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px;}
.pm-card.is-pm .pm-card-type{color:var(--purple);}
.pm-card.is-pmo .pm-card-type{color:var(--teal);}
.pm-avatar-sm{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:var(--surface);margin-bottom:9px;}
.pm-card.is-pm .pm-avatar-sm{background:linear-gradient(135deg,var(--purple),var(--accent));}
.pm-card.is-pmo .pm-avatar-sm{background:linear-gradient(135deg,var(--teal),var(--accent2));}
.pm-name{font-size:13px;font-weight:700;}
.pm-role{font-size:11px;color:var(--muted);}
.mini-task-item{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:11px 13px;margin-bottom:8px;display:flex;align-items:center;justify-content:space-between;gap:8px;transition:all .15s;}
.mini-task-item:hover{border-color:rgba(79,70,229,.25);background:var(--purple-light);}
.mini-task-title{font-size:12.5px;font-weight:500;flex:1;}
.mini-task-meta{display:flex;gap:5px;align-items:center;flex-shrink:0;}
.mini-risk-item{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:10px 13px;margin-bottom:8px;}
.mini-risk-title{font-size:12.5px;font-weight:500;margin-bottom:5px;}
.mini-risk-meta{display:flex;gap:5px;flex-wrap:wrap;}

/* ── Team member drawer ── */
.member-proj-card{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-md);padding:14px;margin-bottom:10px;transition:all .15s;}
.member-proj-card:hover{border-color:rgba(79,70,229,.25);}
.member-proj-title{font-size:12.5px;font-weight:700;margin-bottom:7px;}
.member-proj-meta{display:flex;gap:6px;flex-wrap:wrap;align-items:center;}
.member-task-row{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;margin-bottom:8px;transition:all .15s;}
.member-task-row:hover{border-color:rgba(79,70,229,.25);background:var(--purple-light);}
.member-task-title{font-size:12px;font-weight:500;flex:1;}
.member-task-meta{display:flex;gap:5px;align-items:center;flex-shrink:0;}

/* ══════════════════════════════════════════════
   TASK HISTORY / TIMELINE
═══════════════════════════════════════════════ */
.history-form{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-md);padding:18px;margin-bottom:20px;}
.history-form-title{font-size:12.5px;font-weight:700;margin-bottom:14px;color:var(--accent2);}
.timeline{position:relative;padding-left:2px;}
.timeline::before{content:'';position:absolute;left:14px;top:0;bottom:0;width:2px;background:linear-gradient(180deg,var(--accent),transparent);}
.timeline-item{position:relative;padding-left:38px;margin-bottom:20px;}
.timeline-dot{position:absolute;left:7px;top:4px;width:16px;height:16px;border-radius:50%;background:var(--accent);border:3px solid var(--surface);z-index:1;box-shadow:0 0 0 2px var(--accent);}
.timeline-dot.has-obstacle{background:var(--yellow);box-shadow:0 0 0 2px var(--yellow);}
.timeline-date{font-size:10.5px;color:var(--muted);font-family:var(--mono);margin-bottom:6px;font-weight:500;}
.timeline-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:14px;box-shadow:var(--shadow-xs);}
.timeline-update{font-size:12.5px;line-height:1.6;margin-bottom:8px;color:var(--text);}
.timeline-by{font-size:10.5px;color:var(--accent2);font-family:var(--mono);font-weight:600;}
.obstacle-box,.solution-box{margin-top:10px;padding:9px 12px;border-radius:8px;font-size:12px;line-height:1.5;}
.obstacle-box{background:var(--red-light);border:1px solid #fca5a5;color:var(--danger);}
.solution-box{background:var(--green-light);border:1px solid #86efac;color:var(--success);}
.obstacle-label,.solution-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px;opacity:.75;}
.timeline-actions{display:flex;justify-content:flex-end;margin-top:8px;}
/* ── Activity Log ────────────────────────────────────────── */
.activity-log-wrap{display:flex;flex-direction:column;gap:0;}
.activity-item{display:flex;gap:10px;padding:9px 0;border-bottom:1px solid var(--bg);}
.activity-item:last-child{border-bottom:none;}
.activity-icon{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px;}
.activity-icon.created{background:var(--accent-light);color:var(--info);}
.activity-icon.updated{background:var(--yellow-light);color:var(--yellow);}
.activity-icon.status{background:var(--green-light);color:var(--success);}
.activity-icon.comment{background:var(--purple-light);color:var(--purple);}
.activity-icon.deleted{background:var(--red-light);color:var(--danger);}
.activity-body{flex:1;min-width:0;}
.activity-desc{font-size:12px;line-height:1.5;color:var(--text);}
.activity-desc strong{color:var(--accent2);font-weight:600;}
.activity-meta{font-size:10.5px;color:var(--muted);margin-top:2px;font-family:var(--mono);}
/* ── Project File Upload ─────────────────────────────────── */
.proj-file-zone{border:1.5px dashed #c7d2fe;border-radius:9px;padding:12px 14px;display:flex;align-items:center;gap:9px;cursor:pointer;transition:all .2s;background:var(--surface);margin-top:4px;}
.proj-file-zone:hover,.proj-file-zone.drag-over{border-color:var(--accent);background:var(--purple-light);}
.proj-file-zone.has-file{border-style:solid;border-color:var(--green);background:var(--green-light);}
.proj-file-list{margin-top:8px;display:flex;flex-direction:column;gap:5px;}
.proj-file-chip{display:flex;align-items:center;gap:7px;background:var(--bg);border:1px solid var(--border);border-radius:7px;padding:5px 10px;font-size:11.5px;font-weight:500;color:var(--text);}
.proj-file-chip a{color:var(--accent);text-decoration:none;font-size:11px;margin-left:auto;}
.proj-file-chip a:hover{text-decoration:underline;}
.proj-file-remove{margin-left:4px;color:var(--muted);cursor:pointer;font-size:12px;background:none;border:none;padding:0 2px;}
.no-history{text-align:center;color:var(--muted);font-size:13px;padding:32px;}

/* ══════════════════════════════════════════════
   AI PANEL
═══════════════════════════════════════════════ */
.ai-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;display:flex;flex-direction:column;flex:1;min-height:0;box-shadow:var(--shadow-sm);}
.ai-header{background:linear-gradient(90deg,var(--bg),var(--bg-hover));padding:14px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;flex-shrink:0;}
.chat-messages{flex:1;overflow-y:auto;padding:18px 20px;display:flex;flex-direction:column;gap:14px;background:var(--bg);min-height:0;}
.chat-messages::-webkit-scrollbar{width:5px;}
.chat-messages::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:3px;}
.msg{display:flex;gap:10px;max-width:88%;}
.msg.user{align-self:flex-end;flex-direction:row-reverse;}
.msg-bubble{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:13px 17px;font-size:13.5px;line-height:1.7;box-shadow:var(--shadow-xs);}
.msg.user .msg-bubble{background:linear-gradient(135deg,var(--accent-light),var(--accent-light));border-color:#bfdbfe;color:var(--info);}
.msg-bubble.error-bubble{border-color:#fca5a5;background:var(--red-light);}
.error-detail{font-size:11px;color:var(--red);margin-top:7px;font-family:var(--mono);background:var(--surface);border-radius:6px;padding:7px 9px;line-height:1.5;}
.msg-avatar{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;margin-top:3px;background:linear-gradient(135deg,var(--accent-light),var(--accent-light));border:1px solid #c7d2fe;}
.msg.user .msg-avatar{background:linear-gradient(135deg,var(--accent-light),#bfdbfe);border-color:#93c5fd;}
.chat-input-row{padding:14px 18px;border-top:1px solid var(--border);display:flex;gap:9px;background:var(--surface);flex-shrink:0;}
.chat-input{flex:1;background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);font-size:13px;padding:10px 14px;outline:none;resize:none;transition:all .2s;max-height:120px;}
.chat-input:focus{border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px rgba(79,70,229,.1);}
.chat-input::placeholder{color:var(--muted-light);}
.quick-prompts{padding:9px 16px;display:flex;flex-wrap:wrap;gap:6px;background:var(--bg);border-bottom:1px solid var(--border);flex-shrink:0;}
.qp{background:var(--surface);border:1.5px solid var(--border);color:var(--muted);font-size:10.5px;font-weight:500;padding:4px 10px;border-radius:20px;cursor:pointer;transition:all .18s;}
.qp:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
.ai-dot{width:7px;height:7px;background:var(--green);border-radius:50%;animation:pulse 2s infinite;}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.api-key-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:24px;margin-bottom:20px;border-top:3px solid var(--accent);box-shadow:var(--shadow-sm);}
.api-key-status{font-size:12.5px;margin:8px 0;min-height:18px;}
.api-key-status.ok{color:var(--green);}
.api-key-status.err{color:var(--red);}
.api-key-input-row{display:flex;gap:9px;margin-bottom:8px;}
/* ── AI Upload Zone ─────────────────────────────────────── */
.upload-zone-wrap{padding:8px 16px 8px;background:var(--bg);border-bottom:1px solid var(--border);flex-shrink:0;}
.upload-zone{border:1.5px dashed #c7d2fe;border-radius:10px;padding:10px 14px;display:flex;align-items:center;gap:10px;cursor:pointer;transition:all .2s;background:var(--surface);min-height:46px;}
.upload-zone:hover,.upload-zone.drag-over{border-color:var(--accent);background:var(--purple-light);}
.upload-zone.has-file{border-style:solid;border-color:var(--green);background:var(--green-light);}
.upload-zone-icon{width:30px;height:30px;border-radius:8px;background:var(--purple-light);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .2s;}
.upload-zone.has-file .upload-zone-icon{background:var(--green-light);}
.upload-zone-text{flex:1;min-width:0;}
.upload-zone-label{font-size:11.5px;font-weight:600;color:var(--text);}
.upload-zone-sub{font-size:10px;color:var(--muted);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.file-ext-badge{font-size:9px;font-weight:700;padding:2px 7px;border-radius:5px;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0;}
.file-ext-badge.pdf{background:var(--red-light);color:var(--danger);}
.file-ext-badge.image{background:var(--yellow-light);color:var(--yellow);}
.file-ext-badge.text{background:var(--accent-light);color:var(--info);}
.upload-clear{width:22px;height:22px;border-radius:50%;border:1.5px solid var(--border);background:var(--surface);color:var(--text-muted);font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .15s;line-height:1;}
.upload-clear:hover{border-color:var(--danger);color:var(--danger);background:var(--red-light);}
/* ── Role-specific AI quick actions ────────────────────── */
.role-prompts{padding:7px 14px 8px;border-bottom:1px solid var(--border);flex-shrink:0;background:var(--surface);}
.role-prompts-label{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;display:flex;align-items:center;gap:4px;margin-bottom:6px;}
.role-prompts-btns{display:flex;flex-wrap:wrap;gap:5px;}
.rqp{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;padding:5px 12px;border-radius:20px;cursor:pointer;border:1.5px solid transparent;transition:all .18s;white-space:nowrap;}
.rqp.rqp-product{background:var(--purple-light);border-color:#d8b4fe;color:var(--purple);}
.rqp.rqp-product:hover{background:var(--purple);color:var(--surface);border-color:var(--purple);}
.rqp.rqp-pm{background:var(--accent-light);border-color:#93c5fd;color:var(--info);}
.rqp.rqp-pm:hover{background:var(--info);color:var(--surface);border-color:var(--info);}
.rqp.rqp-pmo{background:var(--green-light);border-color:#86efac;color:var(--success);}
.rqp.rqp-pmo:hover{background:var(--success);color:var(--surface);border-color:var(--success);}
/* ── Doc analysis quick prompts ────────────────────────── */
.doc-prompts{padding:7px 14px;background:linear-gradient(90deg,var(--purple-light),var(--accent-light));border-bottom:1px solid var(--accent-light);flex-shrink:0;display:none;flex-wrap:wrap;gap:5px;align-items:center;}
.doc-prompts.show{display:flex;}
.doc-prompts-label{font-size:9.5px;font-weight:700;color:var(--accent);text-transform:uppercase;letter-spacing:.5px;margin-right:2px;white-space:nowrap;}
.dqp{background:var(--surface);border:1.5px solid #c7d2fe;color:var(--accent-hover);font-size:10px;font-weight:600;padding:3px 9px;border-radius:20px;cursor:pointer;transition:all .18s;white-space:nowrap;}
.dqp:hover{background:var(--accent-hover);color:var(--surface);border-color:var(--accent-hover);}
/* ── Chat file preview chip (in message) ───────────────── */
.file-chip{display:inline-flex;align-items:center;gap:6px;background:var(--bg-hover);border:1px solid var(--border);border-radius:8px;padding:5px 10px;font-size:11px;font-weight:500;color:var(--muted);margin-bottom:7px;}
.file-chip-icon{width:20px;height:20px;border-radius:5px;display:flex;align-items:center;justify-content:center;background:var(--accent-light);flex-shrink:0;}
/* ── Download actions bar ───────────────────────────────── */
.msg-actions{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px;padding-top:8px;border-top:1px solid rgba(0,0,0,.06);}
.dl-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 11px;border-radius:7px;font-size:10.5px;font-weight:600;border:1.5px solid var(--border);background:var(--surface);color:var(--text-muted);cursor:pointer;transition:all .15s;}
.dl-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--purple-light);}
.dl-btn.primary-dl{border-color:var(--accent);color:var(--accent);background:var(--purple-light);}
.dl-btn.primary-dl:hover{background:var(--accent);color:var(--surface);}
/* ── AI Tabs ─────────────────────────────────────────────── */
.ai-tab-btns{display:flex;gap:3px;align-items:center;}
.ai-tab-btn{padding:4px 10px;border-radius:7px;border:1.5px solid transparent;background:transparent;color:var(--muted);font-size:10.5px;font-weight:600;cursor:pointer;transition:all .15s;font-family:var(--font);white-space:nowrap;}
.ai-tab-btn:hover{background:var(--accent-light);color:var(--accent);}
.ai-tab-btn.active{background:var(--accent-light);border-color:var(--accent);color:var(--accent);}
/* ── AI Sub-header (History / Prompts tabs) ─────────────── */
.ai-sub-header{display:flex;align-items:center;justify-content:space-between;padding:10px 18px;border-bottom:1px solid var(--border);background:var(--bg);flex-shrink:0;font-size:12.5px;font-weight:600;color:var(--text);}
/* ── History list items ─────────────────────────────────── */
.ai-history-item{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;cursor:pointer;transition:all .15s;display:flex;align-items:flex-start;gap:10px;}
.ai-history-item:hover{border-color:var(--accent);box-shadow:var(--shadow-xs);}
.ai-history-item-body{flex:1;min-width:0;}
.ai-history-item-title{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px;}
.ai-history-item-meta{font-size:10.5px;color:var(--muted);display:flex;gap:8px;flex-wrap:wrap;}
.ai-history-item-del{width:26px;height:26px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-size:13px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .15s;}
.ai-history-item-del:hover{border-color:var(--red);color:var(--red);background:var(--red-light);}
/* ── Custom Prompt items ────────────────────────────────── */
.ai-prompt-item{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;display:flex;align-items:flex-start;gap:10px;}
.ai-prompt-item-body{flex:1;min-width:0;}
.ai-prompt-item-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:4px;}
.ai-prompt-item-content{font-size:11.5px;color:var(--muted);line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.ai-prompt-item-actions{display:flex;gap:5px;flex-shrink:0;}
.ai-prompt-use{padding:4px 12px;border-radius:7px;border:1.5px solid var(--accent);background:var(--accent-light);color:var(--accent);font-size:10.5px;font-weight:600;cursor:pointer;transition:all .15s;}
.ai-prompt-use:hover{background:var(--accent);color:var(--surface);}
.ai-prompt-edit{width:26px;height:26px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s;}
.ai-prompt-edit:hover{border-color:var(--accent);color:var(--accent);}
.ai-prompt-del{width:26px;height:26px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-size:13px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s;}
.ai-prompt-del:hover{border-color:var(--red);color:var(--red);background:var(--red-light);}

/* ══════════════════════════════════════════════
   PROFILE
═══════════════════════════════════════════════ */
.profile-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:28px;max-width:520px;margin-bottom:20px;box-shadow:var(--shadow-sm);}
.profile-header{display:flex;gap:18px;align-items:center;margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid var(--border);}
.profile-big-avatar{width:64px;height:64px;border-radius:18px;background:linear-gradient(135deg,var(--accent),var(--purple));display:flex;align-items:center;justify-content:center;font-size:26px;font-weight:700;color:var(--surface);flex-shrink:0;box-shadow:0 4px 16px rgba(79,70,229,.3);}
.pw-section{border-top:1px solid var(--border-light);padding-top:20px;margin-top:6px;}
.pw-section-label{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.7px;font-weight:700;margin-bottom:14px;}

/* ══════════════════════════════════════════════
   GANTT
═══════════════════════════════════════════════ */
.gantt-project-block{margin-bottom:28px;}
.gantt-project-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg) var(--r-lg) 0 0;border-bottom:2px solid var(--accent2);padding:16px 20px;display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;}
.gantt-project-card-main{flex:1;min-width:0;}
.gantt-project-card-title{font-size:15px;font-weight:800;color:var(--text);display:flex;align-items:center;gap:8px;flex-wrap:wrap;line-height:1.3;}
.gantt-project-card-meta{display:flex;flex-wrap:wrap;gap:16px;margin-top:8px;font-size:11.5px;color:var(--muted);}
.gantt-project-card-meta span{display:flex;align-items:center;gap:4px;}
.gantt-project-progress{flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:5px;min-width:130px;}
.gantt-progress-bar{width:130px;height:6px;background:var(--border);border-radius:3px;overflow:hidden;}
.gantt-progress-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,var(--accent2),var(--teal));}
.gantt-project-block{margin-bottom:28px;}
.gantt-project-card{background:linear-gradient(135deg,var(--accent-light) 0%,var(--accent-light) 100%);border:1.5px solid var(--border);border-radius:var(--r-lg) var(--r-lg) 0 0;border-bottom:2px solid var(--accent2);padding:16px 22px;display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;}
.gantt-project-card-main{flex:1;min-width:0;}
.gantt-project-card-title{font-size:15px;font-weight:800;color:var(--text);display:flex;align-items:center;gap:8px;flex-wrap:wrap;line-height:1.3;}
.gantt-project-card-meta{display:flex;flex-wrap:wrap;gap:18px;margin-top:9px;font-size:11.5px;color:var(--muted);}
.gantt-project-card-meta span{display:flex;align-items:center;gap:4px;}
.gantt-project-progress{flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:5px;min-width:130px;padding-top:2px;}
.gantt-progress-bar{width:130px;height:6px;background:var(--border);border-radius:3px;overflow:hidden;}
.gantt-progress-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,var(--info),var(--teal));}
.gantt-wrap{background:var(--surface);border:1.5px solid var(--border);border-top:none;border-radius:0 0 var(--r-lg) var(--r-lg);overflow:hidden;box-shadow:var(--shadow-sm);}
.gantt-header-row{background:var(--bg);}
.gantt-header{padding:18px 22px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;}
.gantt-proj-title{font-size:14px;font-weight:700;}
.gantt-legend{display:flex;gap:14px;align-items:center;flex-wrap:wrap;}
.gantt-legend-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--muted);}
.gantt-legend-dot{width:10px;height:10px;border-radius:3px;}
.gantt-area{overflow-x:auto;padding:0 0 4px;}
.gantt-area::-webkit-scrollbar{height:5px;}
.gantt-area::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:3px;}
.gantt-table{min-width:100%;border-collapse:collapse;}
.gantt-row-label{padding:9px 16px;font-size:11.5px;font-weight:500;white-space:nowrap;min-width:160px;border-right:1px solid var(--border);vertical-align:middle;}
.gantt-row-label-sub{font-size:10px;color:var(--muted);margin-top:2px;}
.gantt-header-row th{background:var(--bg);padding:7px 0;font-size:9px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;text-align:center;white-space:nowrap;border-bottom:1px solid var(--border);}
.gantt-cell{padding:5px 2px;vertical-align:middle;position:relative;}
.gantt-bar{height:24px;border-radius:6px;position:relative;min-width:4px;display:flex;align-items:center;padding:0 7px;font-size:10px;font-weight:600;color:var(--surface);white-space:nowrap;overflow:hidden;cursor:default;transition:opacity .15s;}
.gantt-bar:hover{opacity:.85;}
.gantt-bar.todo{background:var(--text-muted);}
.gantt-bar.inprog{background:linear-gradient(90deg,var(--info),var(--accent));}
.gantt-bar.done{background:linear-gradient(90deg,var(--green),var(--teal));}
.gantt-bar.overdue{background:linear-gradient(90deg,var(--danger),var(--warning));}
.gantt-bar.projbar{background:linear-gradient(90deg,var(--purple),var(--pink));}
.gantt-bar.epicbar{background:linear-gradient(90deg,var(--accent),var(--purple));height:20px;border-radius:4px;font-size:9.5px;}
.gantt-bar.subtaskbar{height:16px;border-radius:3px;font-size:9px;opacity:.9;}
.gantt-no-date{font-size:11px;color:var(--muted);padding:14px 18px;}
/* Task type badges */
.type-badge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:700;padding:1px 7px;border-radius:20px;letter-spacing:.3px;flex-shrink:0;}
.type-badge.epic{background:var(--purple-light);color:var(--purple);border:1px solid #c4b5fd;}
.type-badge.task{background:var(--accent-light);color:var(--info);border:1px solid #93c5fd;}
.type-badge.subtask{background:var(--green-light);color:var(--success);border:1px solid #86efac;}
/* Gantt row styles by type */
.gantt-row-epic{background:rgba(99,102,241,.05);}
.gantt-row-subtask{background:rgba(16,185,129,.025);}
.gantt-label-epic{padding-left:24px;font-weight:700;font-size:11.5px;color:var(--purple);}
.gantt-label-task-under-epic{padding-left:40px;}
.gantt-label-subtask{padding-left:56px;font-size:10.5px;color:var(--muted);}
.gantt-collapse-btn{cursor:pointer;font-size:10px;margin-right:4px;transition:transform .15s;display:inline-block;}

/* ══════════════════════════════════════════════
   AVAILABILITY
═══════════════════════════════════════════════ */
.avail-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:20px;}
.avail-kpi{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:18px;position:relative;overflow:hidden;box-shadow:var(--shadow-sm);}
.avail-kpi::after{content:'';position:absolute;bottom:0;left:0;right:0;height:3px;}
.avail-kpi.idle::after{background:linear-gradient(90deg,var(--green),var(--teal));}
.avail-kpi.busy::after{background:linear-gradient(90deg,var(--red),var(--pink));}
.avail-kpi.part::after{background:linear-gradient(90deg,var(--yellow),var(--orange));}
.avail-kpi.all::after{background:linear-gradient(90deg,var(--accent),var(--accent2));}
.avail-kpi-icon{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:16px;margin-bottom:12px;}
.avail-kpi.idle .avail-kpi-icon{background:var(--green-light);}
.avail-kpi.busy .avail-kpi-icon{background:var(--red-light);}
.avail-kpi.part .avail-kpi-icon{background:var(--yellow-light);}
.avail-kpi.all .avail-kpi-icon{background:var(--accent-light);}
.avail-kpi-label{font-size:10.5px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.7px;}
.avail-kpi-val{font-size:30px;font-weight:700;font-family:var(--mono);margin:4px 0 2px;color:var(--text);}
.avail-kpi-sub{font-size:11px;color:var(--muted);}
.avail-timeline-wrap{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:20px;box-shadow:var(--shadow-sm);}
.avail-member-row{display:grid;grid-template-columns:190px 1fr;border-bottom:1px solid var(--border-light);}
.avail-member-row:last-child{border-bottom:none;}
.avail-member-row:hover{background:var(--bg);}
.avail-label-cell{padding:12px 16px;border-right:1px solid var(--border);display:flex;flex-direction:column;justify-content:center;gap:4px;}
.avail-member-name{font-size:12.5px;font-weight:700;}
.avail-member-role{font-size:10.5px;color:var(--muted);}
.avail-bar-cell{padding:10px 12px;}
.avail-bar-track{height:28px;background:var(--green-light);border-radius:7px;position:relative;overflow:hidden;border:1px solid #bbf7d0;}
.avail-bar-segment{position:absolute;top:0;height:100%;display:flex;align-items:center;padding:0 7px;font-size:10px;font-weight:600;color:var(--surface);white-space:nowrap;overflow:hidden;transition:opacity .15s;}
.avail-bar-segment:hover{opacity:.8;z-index:2;}
.avail-bar-segment.seg-busy{background:linear-gradient(90deg,var(--info),var(--accent));}
.avail-bar-segment.seg-full{background:linear-gradient(90deg,var(--danger),var(--warning));}
.avail-bar-segment.seg-idle{background:rgba(16,185,129,.25);color:var(--success);}
.avail-idle-pill{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:20px;font-size:10.5px;font-weight:700;margin-top:4px;}
.avail-idle-pill.idle{background:var(--green-light);color:var(--success);}
.avail-idle-pill.busy{background:var(--red-light);color:var(--danger);}
.avail-idle-pill.part{background:var(--yellow-light);color:var(--yellow);}
.avail-date-header{display:grid;grid-template-columns:190px 1fr;border-bottom:1px solid var(--border);background:var(--bg);}
.avail-date-ticks{padding:7px 12px;position:relative;height:30px;}
.avail-date-tick{position:absolute;font-size:9px;color:var(--muted);transform:translateX(-50%);white-space:nowrap;font-weight:600;}
.suggest-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:18px;margin-bottom:10px;display:flex;align-items:center;gap:14px;box-shadow:var(--shadow-xs);transition:all .18s;}
.suggest-card:hover{border-color:rgba(79,70,229,.3);transform:translateY(-1px);box-shadow:var(--shadow-md);}
.suggest-card.urgent{border-color:var(--orange-light);background:var(--orange-light);}
.suggest-avatar{width:44px;height:44px;border-radius:12px;background:linear-gradient(135deg,var(--accent),var(--purple));display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:var(--surface);flex-shrink:0;box-shadow:0 3px 8px rgba(79,70,229,.25);}
.suggest-info{flex:1;}
.suggest-name{font-size:13.5px;font-weight:700;}
.suggest-detail{font-size:11.5px;color:var(--muted);margin-top:4px;line-height:1.6;}
.avail-filter-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:16px;}
.avail-legend{display:flex;gap:12px;align-items:center;margin-left:auto;flex-wrap:wrap;}
.avail-legend-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--muted);}
.avail-legend-dot{width:10px;height:10px;border-radius:3px;}
.skill-filter-btn{padding:5px 12px;border-radius:20px;border:1.5px solid var(--border);background:var(--surface);color:var(--muted);font-size:11px;font-weight:600;cursor:pointer;transition:all .18s;font-family:var(--font);}
.skill-filter-btn:hover,.skill-filter-btn.active{border-color:var(--accent2);background:var(--accent2-light);color:var(--accent2);}

/* ══════════════════════════════════════════════
   EMPTY STATE
═══════════════════════════════════════════════ */
.empty-state{text-align:center;padding:48px 24px;color:var(--muted);}
.empty-state-icon{font-size:40px;margin-bottom:12px;filter:grayscale(30%);}
.empty-state-title{font-size:15px;font-weight:700;color:var(--text-2);margin-bottom:7px;}
.empty-state-sub{font-size:13px;line-height:1.7;max-width:300px;margin:0 auto;}

/* ══════════════════════════════════════════════
   ROLES
═══════════════════════════════════════════════ */
.role-pill{display:inline-flex;align-items:center;padding:3px 10px;border-radius:20px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;}
.role-pill.admin{background:var(--pink-light);color:var(--pink);}
.role-pill.manager{background:var(--purple-light);color:var(--purple);}
.role-pill.pm{background:var(--accent-light);color:var(--info);}
.role-pill.pmo{background:var(--teal-light);color:var(--teal);}
.role-pill.developer{background:rgba(8,145,178,.1);color:var(--accent2);border:1px solid rgba(8,145,178,.3);}
.role-pill.viewer{background:var(--bg);color:var(--muted);border:1px solid var(--border);}

/* ══════════════════════════════════════════════
   PAGINATION
═══════════════════════════════════════════════ */
.pagination{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-top:1px solid var(--border);background:var(--bg);flex-wrap:wrap;gap:8px;}
.pagination-info{font-size:11.5px;color:var(--muted);font-family:var(--mono);}
.pagination-controls{display:flex;align-items:center;gap:4px;}
.pg-btn{width:32px;height:32px;border-radius:7px;border:1.5px solid var(--border);background:var(--surface);color:var(--muted);font-size:12px;font-weight:600;cursor:pointer;transition:all .15s;display:flex;align-items:center;justify-content:center;}
.pg-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
.pg-btn:disabled{opacity:.35;cursor:not-allowed;}
.pg-btn.active{background:var(--accent);border-color:var(--accent);color:var(--surface);}
.pg-size{background:var(--surface);border:1.5px solid var(--border);border-radius:7px;color:var(--text);font-family:var(--font);font-size:12px;padding:5px 8px;outline:none;cursor:pointer;}
.pg-size:focus{border-color:var(--accent);}










/* ══ KANBAN MOUSE DRAG ═══════════════════════════════════════ */
.task-card{cursor:grab;user-select:none;}
.task-card:active{cursor:grabbing;}
.kd-clone{position:fixed;pointer-events:none;z-index:9999;opacity:.85;transform:rotate(2deg) scale(1.03);box-shadow:0 12px 32px rgba(79,70,229,.25);transition:none;border-radius:10px;background:var(--surface);}
.kd-drop-zone{border:2px dashed var(--accent)!important;background:rgba(79,70,229,.05)!important;transition:background .15s;}
.kd-drop-zone-done{border:2px dashed var(--green)!important;background:rgba(16,185,129,.05)!important;}
.kd-drop-zone-inprog{border:2px dashed var(--accent)!important;background:rgba(59,130,246,.05)!important;}
.kd-source{opacity:.3;}

/* ══ IMPORT TASKS PAGE ═══════════════════════════════════════ */
/* Import container & cards */
.import-container{max-width:960px;margin:0 auto;}
.import-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);padding:20px 24px;}
.import-card-header{display:flex;align-items:flex-start;gap:10px;margin-bottom:16px;color:var(--accent);}
.import-card-title{font-size:15px;font-weight:700;color:var(--text);}
.import-card-desc{font-size:12px;color:var(--muted);margin-top:2px;}
/* Step bar */
.import-steps-bar{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:28px;padding:0 40px;}
.import-step-dot{display:flex;flex-direction:column;align-items:center;gap:4px;position:relative;z-index:1;}
.import-step-dot span{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;background:var(--bg);border:2px solid var(--border);color:var(--muted);transition:all .3s;}
.import-step-dot small{font-size:10px;font-weight:600;color:var(--muted);white-space:nowrap;}
.import-step-dot.active span{background:var(--accent);border-color:var(--accent);color:var(--surface);}
.import-step-dot.active small{color:var(--accent);}
.import-step-dot.done span{background:var(--green);border-color:var(--green);color:var(--surface);}
.import-step-dot.done small{color:var(--green);}
.import-step-line{flex:1;height:2px;background:var(--border);margin:0 -4px;margin-bottom:18px;transition:background .3s;}
.import-step-line.done{background:var(--green);}
/* Drop zone */
.import-drop-zone{border:2px dashed var(--border);border-radius:var(--r-lg);padding:36px 20px;text-align:center;cursor:pointer;transition:all .2s;background:var(--bg);}
.import-drop-zone:hover,.import-drop-zone.drag-over{border-color:var(--accent);background:var(--accent-light);}
.import-drop-icon{width:56px;height:56px;border-radius:50%;background:var(--accent-light);color:var(--accent);display:flex;align-items:center;justify-content:center;margin:0 auto 12px;}
/* Column badges */
.import-col-badge{background:var(--bg);border:1px solid var(--border-light);border-radius:6px;padding:6px 10px;font-size:11.5px;color:var(--text);font-weight:500;display:flex;align-items:center;gap:4px;flex-wrap:wrap;}
.import-col-req{color:var(--red);font-weight:700;margin-right:2px;}
.import-col-hint{color:var(--muted);font-size:10px;}
/* Editable table */
.import-table-wrap{max-height:calc(100vh - 360px);overflow:auto;border:1px solid var(--border);border-radius:var(--r-md);}
.import-table{width:100%;border-collapse:collapse;font-size:12px;}
.import-table thead{position:sticky;top:0;z-index:2;}
.import-table th{background:var(--bg-input,#f8fafc);padding:8px 10px;text-align:left;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);border-bottom:2px solid var(--border);white-space:nowrap;}
.import-table td{padding:4px 4px;border-bottom:1px solid var(--border-light);vertical-align:middle;}
.import-table tr:hover td{background:var(--accent-light);}
.import-table tr.row-error td{background:rgba(220,38,38,.04);}
.import-table .import-cell-input{width:100%;border:1px solid transparent;background:transparent;padding:4px 6px;font-size:12px;font-family:var(--font);color:var(--text);border-radius:4px;transition:all .15s;outline:none;box-sizing:border-box;}
.import-table .import-cell-input:hover{border-color:var(--border);}
.import-table .import-cell-input:focus{border-color:var(--accent);background:var(--card);box-shadow:0 0 0 2px rgba(79,70,229,.1);}
.import-table .import-cell-select{width:100%;border:1px solid transparent;background:transparent;padding:4px 6px;font-size:12px;font-family:var(--font);color:var(--text);border-radius:4px;cursor:pointer;outline:none;appearance:auto;}
.import-table .import-cell-select:hover{border-color:var(--border);}
.import-table .import-cell-select:focus{border-color:var(--accent);background:var(--card);}
.import-table .import-row-num{font-family:var(--mono);font-size:10px;color:var(--muted);text-align:center;width:32px;padding:4px 6px;}
.import-table .import-row-actions{width:32px;text-align:center;padding:4px;}
.import-row-del{border:none;background:transparent;color:var(--muted);cursor:pointer;padding:4px;border-radius:4px;transition:all .15s;display:flex;align-items:center;justify-content:center;}
.import-row-del:hover{background:var(--red-light);color:var(--red);}
#importPreviewTable thead th{position:sticky;top:0;background:var(--text);color:var(--bg-hover);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:9px 12px;text-align:left;white-space:nowrap;}
#importPreviewTable tbody tr{border-bottom:1px solid var(--border-light);}
#importPreviewTable tbody tr:hover{background:var(--bg);}
#importPreviewTable tbody td{padding:8px 12px;color:var(--text);font-size:12.5px;vertical-align:middle;}
#importPreviewTable tbody tr.row-error{background:var(--red-light);}
#importPreviewTable tbody tr.row-error td{color:var(--danger);}
.import-progress-bar{height:4px;background:var(--border);border-radius:2px;margin-top:6px;overflow:hidden;}
.import-progress-fill{height:100%;background:var(--accent);border-radius:2px;transition:width .3s;}

/* ══ PROJECT TREE PAGE ═══════════════════════════════════════════ */
.tree-project-block{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);margin-bottom:16px;overflow:hidden;box-shadow:var(--shadow-sm);}
.tree-project-header{display:flex;align-items:center;gap:12px;padding:14px 18px;cursor:pointer;background:linear-gradient(135deg,var(--text) 0%,var(--text-2) 100%);user-select:none;transition:filter .15s;}
.tree-project-header:hover{filter:brightness(1.1);}
.tree-project-title{font-size:14px;font-weight:700;color:var(--bg-hover);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.tree-project-meta{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;}
.tree-project-toggle{color:var(--text-muted);transition:transform .2s;flex-shrink:0;}
.tree-project-toggle.open{transform:rotate(90deg);}
.tree-project-body{padding:0;}
.tree-project-body.collapsed{display:none;}
.tree-project-stats{display:flex;gap:20px;padding:10px 18px;background:var(--bg);border-bottom:1px solid var(--border-light);flex-wrap:wrap;}
.tree-stat{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);}
.tree-stat strong{color:var(--text);font-weight:700;}
.tree-progress-bar{height:5px;background:var(--border);border-radius:3px;overflow:hidden;width:80px;}
.tree-progress-fill{height:100%;border-radius:3px;transition:width .3s;}

/* Epic row */
.tree-epic{display:flex;align-items:flex-start;gap:0;padding:10px 18px;border-bottom:1px solid var(--border-light);cursor:pointer;background:var(--purple-light);transition:background .12s;isolation:isolate;}
.tree-epic:hover{background:var(--purple-light);}
.tree-epic-toggle{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:var(--purple);flex-shrink:0;margin-right:4px;transition:transform .18s;}
.tree-epic-toggle.open{transform:rotate(90deg);}
.tree-epic-icon{width:22px;height:22px;background:var(--purple);border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:8px;position:relative;z-index:1;}
.tree-epic-body{flex:1;min-width:0;}
.tree-epic-title{font-size:13px;font-weight:700;color:var(--purple);}
.tree-epic-meta{display:flex;align-items:center;gap:8px;margin-top:4px;flex-wrap:wrap;}
.tree-epic-children{display:none;background:var(--purple-light);overflow:hidden;}
.tree-epic-children.open{display:block;}

/* Task row */
.tree-task{display:flex;align-items:flex-start;gap:0;padding:9px 18px 9px 54px;border-bottom:1px solid var(--bg-hover);background:var(--surface);transition:background .12s;isolation:isolate;}
.tree-task:hover{background:var(--bg);}
.tree-task-standalone{padding-left:18px;background:var(--surface);}
.tree-task-icon{width:18px;height:18px;background:var(--info);border-radius:5px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:8px;margin-top:0;position:relative;z-index:1;}
.tree-task-toggle{min-width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:var(--info);flex-shrink:0;transition:transform .18s;}
.tree-task-toggle.open{transform:rotate(90deg);}
.tree-task-body{flex:1;min-width:0;}
.tree-task-title{font-size:12.5px;font-weight:600;color:var(--text);}
.tree-task-meta{display:flex;align-items:center;gap:6px;margin-top:3px;flex-wrap:wrap;}
.tree-task-children{display:none;}
.tree-task-children.open{display:block;}

/* Subtask row */
.tree-subtask{display:flex;align-items:flex-start;gap:0;padding:7px 18px 7px 90px;border-bottom:1px solid var(--bg);background:var(--bg);transition:background .12s;isolation:isolate;}
.tree-subtask:hover{background:var(--bg-hover);}
.tree-subtask-from-epic{padding-left:90px;}
.tree-subtask-icon{width:16px;height:16px;background:var(--green);border-radius:4px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:8px;margin-top:1px;position:relative;z-index:1;}
.tree-subtask-body{flex:1;min-width:0;}
.tree-subtask-title{font-size:12px;font-weight:500;color:var(--text);}
.tree-subtask-meta{display:flex;align-items:center;gap:5px;margin-top:2px;flex-wrap:wrap;}

/* No connector lines */

/* Empty state */
.tree-empty{padding:32px;text-align:center;color:var(--muted);font-size:13px;}

/* ══ GANTT/TREE TABS ══════════════════════════════════════════ */
.tab-btn{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:none;background:transparent;border-radius:7px;font-family:var(--font);font-size:12.5px;font-weight:600;color:var(--muted);cursor:pointer;transition:all .15s;}
.tab-btn:hover{color:var(--text);background:rgba(0,0,0,.04);}
.tab-btn.tab-active{background:var(--surface);color:var(--accent);box-shadow:0 1px 4px rgba(0,0,0,.1);}

.tree-epic,.tree-task,.tree-subtask{display:flex;}
.tree-actions{display:none;align-items:center;gap:4px;flex-shrink:0;margin-left:8px;}
.tree-epic:hover .tree-actions,
.tree-task:hover .tree-actions,
.tree-subtask:hover .tree-actions{display:flex;}
.tree-actions .tree-action-btn{padding:3px 6px;line-height:1;}

/* ══ KNOWLEDGE BASE ══════════════════════════════════════════ */
#page-kb{margin:-24px -26px;width:calc(100% + 52px);}
.kb-layout{display:grid;grid-template-columns:220px 1fr;gap:0;width:100%;height:calc(100vh - 80px);overflow:hidden;}

/* Sidebar */
.kb-sidebar{background:var(--surface);border-right:1px solid var(--border);overflow-y:auto;padding:0;}
.kb-sidebar-section{padding:14px 16px;border-bottom:1px solid var(--border-light);}
.kb-sidebar-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--muted-light);margin-bottom:10px;}
.kb-search{width:100%;padding:8px 12px;border:1.5px solid var(--border);border-radius:var(--r-sm);font-size:12.5px;font-family:var(--font);background:var(--bg);transition:all .2s;}
.kb-search:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px rgba(79,70,229,.1);}
.kb-filter-group{display:flex;flex-direction:column;gap:1px;}
.kb-filter{padding:7px 10px;font-size:12.5px;border-radius:var(--r-sm);cursor:pointer;color:var(--text-2);transition:all .15s;font-weight:500;display:flex;align-items:center;gap:8px;}
.kb-filter:hover{background:var(--accent-light);color:var(--accent);}
.kb-filter.active{background:var(--accent);color:var(--surface);font-weight:600;}
.kb-empty-small{font-size:11.5px;color:var(--muted-light);padding:8px 4px;}
.kb-pinned-item{padding:6px 10px;font-size:12px;border-radius:var(--r-sm);cursor:pointer;color:var(--text-2);display:flex;align-items:center;gap:6px;transition:all .15s;}
.kb-pinned-item:hover{background:var(--accent-light);color:var(--accent);}

/* Main area */
.kb-main{overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;}
.kb-tab-bar{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;gap:10px;}
.kb-tabs{display:flex;gap:4px;background:var(--bg);padding:3px;border-radius:var(--r-md);flex-shrink:0;}
.kb-tab{border:none;background:transparent;padding:7px 14px;font-size:12.5px;font-weight:600;font-family:var(--font);color:var(--muted);cursor:pointer;border-radius:var(--r-sm);transition:all .15s;white-space:nowrap;}
.kb-tab:hover{color:var(--text);}
.kb-tab.active{background:var(--surface);color:var(--accent);box-shadow:var(--shadow-xs);}
.kb-actions{display:flex;gap:8px;flex-shrink:0;}

/* Notes toolbar */
.kb-notes-toolbar{display:flex;align-items:center;justify-content:space-between;padding:10px 0;margin-bottom:4px;gap:10px;flex-wrap:wrap;}
.kb-toolbar-left{display:flex;align-items:center;gap:8px;}
.kb-toolbar-right{display:flex;align-items:center;gap:6px;}
.kb-results-count{font-size:12px;color:var(--muted);font-weight:500;}
.kb-toolbar-label{font-size:11px;color:var(--muted-light);font-weight:600;text-transform:uppercase;letter-spacing:.5px;}
.kb-toolbar-select{font-size:12px;padding:4px 8px;border:1.5px solid var(--border);border-radius:var(--r-sm);background:var(--card);color:var(--text);font-family:var(--font);cursor:pointer;transition:border-color .15s;}
.kb-toolbar-select:focus{outline:none;border-color:var(--accent);}

/* Pagination */
.kb-pagination{display:flex;justify-content:center;padding:20px 0 4px;}
.kb-pag-inner{display:flex;align-items:center;gap:4px;}
.kb-pag-btn{min-width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:1.5px solid var(--border);border-radius:var(--r-sm);background:var(--card);color:var(--text-2);font-size:12.5px;font-weight:600;cursor:pointer;transition:all .15s;font-family:var(--font);}
.kb-pag-btn:hover:not(:disabled):not(.active){border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
.kb-pag-btn.active{background:var(--accent);color:var(--surface);border-color:var(--accent);}
.kb-pag-btn:disabled{opacity:.35;cursor:not-allowed;}
.kb-pag-ellipsis{padding:0 4px;color:var(--muted);font-size:13px;}

/* Note cards */
.kb-notes-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px;}
.kb-note-card{background:var(--card);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:18px;cursor:pointer;transition:all .18s;position:relative;}
.kb-note-card:hover{border-color:var(--accent);box-shadow:var(--shadow-md);transform:translateY(-2px);}
.kb-note-card .kb-card-cat{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;margin-bottom:8px;display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;}
.kb-card-cat-meeting{background:var(--purple-light);color:var(--purple);}
.kb-card-cat-decision{background:var(--yellow-light);color:var(--yellow);}
.kb-card-cat-technical{background:var(--accent2-light);color:var(--accent2);}
.kb-card-cat-general{background:var(--bg);color:var(--muted);}
.kb-note-card .kb-card-title{font-size:14px;font-weight:700;color:var(--text);margin-bottom:8px;line-height:1.35;}
.kb-note-card .kb-card-preview{font-size:12.5px;color:var(--text-2);line-height:1.55;max-height:56px;overflow:hidden;-webkit-line-clamp:3;display:-webkit-box;-webkit-box-orient:vertical;}
.kb-note-card .kb-card-footer{display:flex;align-items:center;justify-content:space-between;margin-top:14px;padding-top:10px;border-top:1px solid var(--border-light);font-size:11px;color:var(--muted);}
.kb-note-card .kb-card-tags{display:flex;gap:4px;flex-wrap:wrap;}
.kb-card-tag{background:var(--accent-light);color:var(--accent);padding:2px 8px;border-radius:12px;font-size:10px;font-weight:600;}
.kb-card-author{margin-left:6px;font-style:italic;color:var(--accent);font-weight:500;}
.kb-note-card .kb-pin-badge{position:absolute;top:10px;right:10px;color:var(--accent);}

/* Editor */
.kb-editor-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--border-light);}
.kb-editor-actions{display:flex;gap:8px;}
.kb-editor-form{display:flex;flex-direction:column;gap:14px;flex:1;overflow-y:auto;}
.kb-title-input{width:100%;padding:10px 0;border:none;font-size:22px;font-weight:700;font-family:var(--font);color:var(--text);background:transparent;outline:none;}
.kb-title-input::placeholder{color:var(--muted-light);}
.kb-meta-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;}
.kb-meta-select{max-width:200px;font-size:12.5px;padding:7px 10px;}
.kb-custom-select{position:relative;display:inline-block;}
.kb-custom-select-btn{display:flex;align-items:center;gap:6px;cursor:pointer;text-align:left;appearance:none;-webkit-appearance:none;background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);white-space:nowrap;}
.kb-custom-select-btn:focus{border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px rgba(79,70,229,.1);}
.kb-csel-icon{width:14px;height:14px;flex-shrink:0;color:var(--accent);}
.kb-csel-chevron{width:10px;height:10px;flex-shrink:0;margin-left:auto;color:var(--muted);transition:transform .2s;}
.kb-custom-select.open .kb-csel-chevron{transform:rotate(180deg);}
.kb-custom-select-dropdown{display:none;position:absolute;top:calc(100% + 4px);left:0;min-width:100%;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--shadow);z-index:100;overflow:hidden;}
.kb-custom-select.open .kb-custom-select-dropdown{display:block;}
.kb-csel-option{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;font-size:12.5px;color:var(--text);transition:background .15s;}
.kb-csel-option:hover{background:var(--bg-hover);}
.kb-csel-option.active{background:rgba(79,70,229,.06);color:var(--accent);font-weight:600;}
.kb-csel-option .kb-csel-icon{color:var(--accent);}
.kb-meta-input{flex:1;min-width:140px;font-size:12.5px;padding:7px 10px;}
.kb-content-textarea{flex:1;width:100%;min-height:75vh;padding:14px;border:1.5px solid var(--border);border-radius:var(--r-md);font-family:var(--mono);font-size:13px;line-height:1.7;resize:vertical;background:var(--bg);transition:all .2s;box-sizing:border-box;}
.kb-content-textarea:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px rgba(79,70,229,.1);}
.kb-backlinks{margin-top:10px;padding:14px;background:var(--bg);border-radius:var(--r-md);border:1px solid var(--border-light);}
.kb-backlinks-label{font-size:11px;font-weight:700;color:var(--muted);margin-bottom:8px;display:flex;align-items:center;}
.kb-backlink-item{padding:5px 10px;font-size:12px;color:var(--accent);cursor:pointer;border-radius:var(--r-sm);transition:background .12s;font-weight:500;}
.kb-backlink-item:hover{background:var(--accent-light);}

/* AI menu dropdown */
.kb-ai-menu{position:absolute;top:calc(100% + 4px);right:0;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:100;min-width:180px;padding:4px;overflow:hidden;}
.kb-ai-menu-item{display:flex;align-items:center;gap:8px;padding:9px 12px;font-size:12.5px;font-weight:500;color:var(--text-2);cursor:pointer;border-radius:var(--r-sm);transition:all .12s;}
.kb-ai-menu-item:hover{background:var(--accent-light);color:var(--accent);}
.kb-ai-menu-item svg{flex-shrink:0;color:var(--muted);}
.kb-ai-menu-item:hover svg{color:var(--accent);}

/* Graph view — layout consolidated 2026-07-02.
   Rules used to sit on a single flex row with space-between + wrap, which
   collapsed into a 3–4-row stacked mess whenever `.kb-main` fell below the
   ~720 px threshold needed to fit info + all controls. Now the toolbar is a
   vertical stack (info line on top, controls row below), and the controls
   themselves stay in a single horizontal row with `overflow-x: auto`. */
.kb-graph-toolbar{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:6px;
  margin-bottom:8px;
}
.kb-graph-info{font-size:12px;color:var(--muted);font-weight:600;letter-spacing:.02em;}
.kb-graph-controls{
  display:flex;
  gap:4px;
  align-items:center;
  flex-wrap:nowrap;
  overflow-x:auto;
  overflow-y:hidden;
  padding-bottom:2px;              /* space so overflow scrollbar (when it appears) doesn't clip focus rings */
  scrollbar-width:thin;
}
/* Compact WebKit scrollbar for the controls row on macOS/Windows */
.kb-graph-controls::-webkit-scrollbar{height:4px}
.kb-graph-controls::-webkit-scrollbar-thumb{background:var(--border-strong,var(--border));border-radius:2px}
/* On viewports wider than the KB sidebar + comfortable controls width we
   can go back to a single info+controls row aligned right; keeps the older,
   denser look on desktop while never producing the stacked-mess state. */
@media (min-width: 1100px){
  .kb-graph-toolbar{
    flex-direction:row;
    align-items:center;
    justify-content:space-between;
  }
  .kb-graph-controls{overflow:visible;padding-bottom:0}
}
/* Legend — pill-style chips */
.kb-graph-legend{display:flex;gap:5px;padding:0 0 7px;flex-wrap:wrap;align-items:center;}
.kb-graph-legend-chip{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border-radius:20px;font-size:7px;font-weight:700;letter-spacing:.04em;border:1px solid transparent;line-height:1.7;}
/* Node category dots */
.kb-graph-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;box-shadow:0 0 4px currentColor;}
/* Edge type lines */
.kb-graph-edge-line{width:18px;height:0;flex-shrink:0;}
/* Canvas */
.kb-graph-canvas{width:100%;height:calc(100vh - 225px);border:1px solid var(--border);border-radius:12px;cursor:grab;position:relative;box-shadow:0 2px 12px rgba(0,0,0,.06);transition:box-shadow .2s;}
.kb-graph-canvas:hover{box-shadow:0 4px 20px rgba(99,102,241,.1);}
.kb-graph-canvas:active{cursor:grabbing;}
/* Tooltip — glassmorphism */
.kb-graph-tooltip{
  position:absolute;max-width:290px;padding:12px 16px;
  background:rgba(255,255,255,0.94);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid rgba(99,102,241,0.18);
  border-radius:12px;box-shadow:0 8px 28px rgba(0,0,0,.13),0 0 0 1px rgba(255,255,255,.6) inset;
  font-size:12px;z-index:100;pointer-events:none;line-height:1.5;
}
.kb-graph-tooltip .tt-title{font-weight:700;font-size:13px;margin-bottom:5px;color:var(--text);}
.kb-graph-tooltip .tt-cat{display:inline-block;padding:2px 9px;border-radius:20px;font-size:10px;font-weight:700;margin-bottom:5px;letter-spacing:.03em;}
.kb-graph-tooltip .tt-tags{font-size:10px;color:var(--muted);margin-bottom:4px;font-family:var(--mono,monospace);}
.kb-graph-tooltip .tt-preview{font-size:12px;color:var(--text-2);line-height:1.55;margin-bottom:2px;}
.kb-graph-tooltip .tt-meta{font-size:10px;color:var(--text-muted);margin-top:6px;display:flex;gap:10px;border-top:1px solid rgba(0,0,0,.06);padding-top:6px;}
.kb-graph-tooltip .tt-meta span{display:inline-flex;align-items:center;gap:3px;}
/* Fullscreen */
#kbGraphView.kb-graph-fullscreen{position:fixed;inset:0;z-index:99999;background:var(--bg);padding:18px;display:flex;flex-direction:column;}
#kbGraphView.kb-graph-fullscreen .kb-graph-toolbar{flex-shrink:0;}
#kbGraphView.kb-graph-fullscreen .kb-graph-canvas{flex:1;height:auto;border-radius:14px;}
/* Dark mode overrides */
[data-theme="dark"] .kb-graph-tooltip{background:rgba(17,24,39,0.92);border-color:rgba(99,102,241,0.25);box-shadow:0 8px 28px rgba(0,0,0,.4);}
[data-theme="dark"] .kb-graph-tooltip .tt-title{color:var(--bg-hover);}
[data-theme="dark"] .kb-graph-tooltip .tt-preview{color:var(--text-muted);}
[data-theme="dark"] .kb-graph-tooltip .tt-meta{border-color:rgba(255,255,255,.07);}
[data-theme="dark"] .kb-graph-legend-chip{background:rgba(255,255,255,.04)!important;border-color:rgba(255,255,255,.08)!important;color:var(--text-muted)!important;}

/* Template modal */
.kb-tpl-modal-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 0;margin-bottom:2px;}
.kb-tpl-modal-title{display:flex;align-items:center;gap:8px;font-size:16px;font-weight:700;color:var(--text);}
.kb-tpl-modal-title svg{color:var(--accent);}
.kb-tpl-modal-desc{padding:0 24px;font-size:12.5px;color:var(--muted);margin-bottom:4px;}

/* Templates */
.kb-template-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:12px;padding:16px 20px 20px;}
.kb-template-card{background:var(--card);border:1.5px solid var(--border);border-radius:var(--r-lg);padding:20px 14px;text-align:center;cursor:pointer;transition:all .2s;display:flex;flex-direction:column;align-items:center;gap:4px;}
.kb-template-card:hover{border-color:var(--accent);box-shadow:var(--shadow-md);transform:translateY(-2px);}
.tpl-icon-wrap{width:44px;height:44px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;margin-bottom:6px;transition:transform .2s;}
.tpl-icon-wrap svg{width:22px;height:22px;}
.kb-template-card:hover .tpl-icon-wrap{transform:scale(1.1);}
.kb-template-card .tpl-name{font-size:13px;font-weight:700;color:var(--text);line-height:1.3;}
.kb-template-card .tpl-cat{font-size:10.5px;color:var(--muted);font-weight:500;text-transform:uppercase;letter-spacing:.4px;}

/* Empty state */
.kb-notes-empty{text-align:center;padding:60px 24px;color:var(--muted);}
.kb-notes-empty svg{width:52px;height:52px;margin-bottom:14px;opacity:.25;}
.kb-notes-empty h3{font-size:16px;color:var(--text-2);margin-bottom:8px;font-weight:600;}
.kb-notes-empty p{font-size:13px;line-height:1.5;}

/* Project filter pills */
.kb-project-pill{display:inline-flex;padding:5px 12px;font-size:11.5px;border-radius:20px;cursor:pointer;color:var(--text-2);background:var(--bg);border:1.5px solid var(--border);margin:2px;transition:all .15s;font-weight:500;}
.kb-project-pill:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
.kb-project-pill.active{background:var(--accent);color:var(--surface);border-color:var(--accent);}

/* ── KB Meeting Transcription ── */
.btn-accent2{background:var(--accent2);color:var(--surface);border:none;box-shadow:0 2px 8px rgba(14,165,233,.25);}
.btn-accent2:hover{background:var(--accent2);box-shadow:0 4px 14px rgba(14,165,233,.35);}
.kb-meeting-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--border-light);}
.kb-meeting-status{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--text-2);font-family:var(--mono);}
.kb-rec-dot{width:10px;height:10px;border-radius:50%;background:var(--text-muted);display:inline-block;transition:background .2s;}
.kb-rec-dot.recording{background:var(--danger);animation:kbPulse 1.2s ease-in-out infinite;}
@keyframes kbPulse{0%,100%{opacity:1;transform:scale(1);}50%{opacity:.5;transform:scale(1.3);}}
.kb-meeting-setup{display:flex;flex-direction:column;gap:14px;}
.kb-meeting-title-row{margin-bottom:4px;}
.kb-meeting-lang-row{display:flex;align-items:center;gap:10px;}
.kb-transcript-area{margin-top:18px;flex:1;display:flex;flex-direction:column;min-height:0;}
.kb-transcript-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--muted-light);margin-bottom:10px;}
.kb-transcript-lines{flex:1;max-height:350px;overflow-y:auto;padding:14px;background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-md);font-size:13px;line-height:1.7;color:var(--text-2);}
.kb-transcript-lines .ts-line{padding:4px 0;border-bottom:1px solid var(--border-light);}
.kb-transcript-lines .ts-time{font-size:10px;color:var(--muted-light);font-family:var(--mono);margin-right:10px;}
.kb-transcript-current{padding:10px 14px;margin-top:8px;background:var(--accent-light);border-radius:var(--r-sm);font-size:13px;color:var(--accent);min-height:28px;font-style:italic;}
.kb-meeting-actions{display:flex;gap:10px;margin-top:18px;padding-top:16px;border-top:1px solid var(--border-light);}
.kb-summary-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--muted-light);margin-bottom:10px;margin-top:18px;}
.kb-summary-content{padding:16px;background:var(--bg);border:1.5px solid var(--border);border-radius:var(--r-md);font-size:13px;line-height:1.7;color:var(--text);}
.kb-summary-content h2,.kb-summary-content h3{margin:12px 0 6px;font-size:14px;font-weight:700;}
.kb-summary-content ul{padding-left:20px;margin:6px 0;}
.kb-summary-content li{margin:4px 0;}

@media(max-width:900px){
  .kb-layout{grid-template-columns:1fr;height:auto;}
  .kb-sidebar{border-right:none;border-bottom:1px solid var(--border);max-height:240px;}
  .kb-notes-grid{grid-template-columns:1fr;}
  .kb-tab-bar{flex-direction:column;align-items:stretch;}
  .kb-tabs{justify-content:center;}
  .kb-actions{justify-content:center;}
}
@media(max-width:768px){
  .kanban-cols{grid-template-columns:repeat(2,minmax(180px,1fr));}
  .sub-tabs-bar{padding:6px 12px;}
  .content{padding:16px 12px;}
  .topbar{padding:0 12px;}
  .topbar-date{display:none;}
  .modal{padding:20px;}
  .dash-grid-70-30,.dash-grid-2col{grid-template-columns:1fr !important;}
  .kpi-grid{grid-template-columns:repeat(2,1fr) !important;}
}
@media(max-width:520px){
  .kanban-cols{grid-template-columns:1fr;}
  .kpi-grid{grid-template-columns:1fr !important;}
  .modal{padding:16px;border-radius:var(--r-md);}
  .sub-tab{padding:5px 10px;font-size:12px;}
}

/* ══════════════════════════════════════════════
   THEME TOGGLE BUTTON
═══════════════════════════════════════════════ */
.theme-icon-dark{display:none;}
[data-theme="dark"] .theme-icon-light{display:none;}
[data-theme="dark"] .theme-icon-dark{display:block;}

/* ══════════════════════════════════════════════
   DARK THEME — COMPREHENSIVE OVERRIDES
═══════════════════════════════════════════════ */

/* ── Base & Loading ── */
[data-theme="dark"] .loading{background:var(--bg);color:var(--text);}
[data-theme="dark"] .loading-text{color:var(--muted);}
[data-theme="dark"] .content::-webkit-scrollbar-thumb{background:var(--border);}
[data-theme="dark"] .content::-webkit-scrollbar-track{background:transparent;}

/* ── Sidebar (already dark — slightly adjust for deeper bg) ── */
[data-theme="dark"] .sidebar{background:var(--sidebar-bg);}
[data-theme="dark"] .sidebar::after{background:linear-gradient(180deg,transparent,var(--sidebar-border),transparent);}
[data-theme="dark"] .sidebar-user{border-top-color:rgba(255,255,255,.05);}

/* ── Topbar ── */
[data-theme="dark"] .topbar{background:var(--surface);border-bottom-color:var(--border);box-shadow:0 1px 4px rgba(0,0,0,.25);}
[data-theme="dark"] .topbar-date{background:var(--bg-input);border-color:var(--border);color:var(--muted);}

/* ── Forms ── */
[data-theme="dark"] .form-input,
[data-theme="dark"] .form-select,
[data-theme="dark"] .form-textarea{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .form-input:focus,
[data-theme="dark"] .form-select:focus,
[data-theme="dark"] .form-textarea:focus{background:var(--surface);border-color:var(--accent);box-shadow:0 0 0 3px rgba(165,180,252,.12);}
[data-theme="dark"] .form-select option{background:var(--surface);color:var(--text);}
[data-theme="dark"] .form-input::placeholder,
[data-theme="dark"] .form-textarea::placeholder{color:var(--muted-light);}

/* ── Assignee multi-select ── */
[data-theme="dark"] .assignee-tags{background:var(--bg-input);border-color:var(--border);}
[data-theme="dark"] .assignee-tags:focus-within,
[data-theme="dark"] .assignee-tags.open{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .assignee-dropdown{background:var(--surface);border-color:var(--border);}
[data-theme="dark"] .assignee-dropdown-search{background:var(--surface);border-bottom-color:var(--border);}
[data-theme="dark"] .assignee-search-input{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .assignee-search-input:focus{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .assignee-option:hover{background:var(--bg-hover);}

/* ── Search & Filters ── */
[data-theme="dark"] .search-input{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .search-input:focus{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .filter-select{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .filter-select option{background:var(--surface);color:var(--text);}

/* ── Cards ── */
[data-theme="dark"] .kpi-card,
[data-theme="dark"] .chart-card,
[data-theme="dark"] .team-card,
[data-theme="dark"] .eval-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .task-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .task-card:hover{border-color:var(--accent);background:rgba(165,180,252,.06);}

/* ── Badges — inverted for dark (dark bg + bright text) ── */
[data-theme="dark"] .badge-green{background:rgba(110,231,183,.14);color:#6ee7b7;}
[data-theme="dark"] .badge-blue{background:rgba(147,197,253,.14);color:#93c5fd;}
[data-theme="dark"] .badge-yellow{background:rgba(253,230,138,.12);color:#fde68a;}
[data-theme="dark"] .badge-red{background:rgba(252,165,165,.14);color:#fca5a5;}
[data-theme="dark"] .badge-purple{background:rgba(196,181,253,.12);color:#c4b5fd;}
[data-theme="dark"] .badge-gray{background:rgba(156,163,175,.12);color:var(--border);}
[data-theme="dark"] .badge-teal{background:rgba(94,234,212,.12);color:#5eead4;}
[data-theme="dark"] .badge-orange{background:rgba(253,186,116,.12);color:#fdba74;}

/* ── Tables ── */
[data-theme="dark"] .table-wrap{background:var(--card);border-color:var(--border);}
[data-theme="dark"] thead th{background:rgba(255,255,255,.03);color:var(--muted);border-color:var(--border);}
[data-theme="dark"] tbody td{border-color:var(--border);color:var(--text);}
[data-theme="dark"] tbody tr:hover td{background:var(--bg-hover);}

/* ── Kanban ── */
[data-theme="dark"] .kanban-project-card{background:linear-gradient(135deg,rgba(165,180,252,.06),rgba(165,180,252,.02));border-color:var(--border);}
[data-theme="dark"] .kanban-cols{background:var(--surface);border-color:var(--border);}
[data-theme="dark"] .kanban-col{background:rgba(255,255,255,.03);border-color:var(--border);}
[data-theme="dark"] .kanban-count{background:var(--bg-input);color:var(--muted);}
[data-theme="dark"] .kanban-progress-bar{background:var(--border);}

/* ── Strips ── */
[data-theme="dark"] .strip-item{background:var(--card);border-color:var(--border);}

/* ── Buttons ── */
[data-theme="dark"] .btn{color:var(--text);}
[data-theme="dark"] .btn-primary{background:var(--accent);color:var(--text);box-shadow:0 2px 10px rgba(165,180,252,.2);}
[data-theme="dark"] .btn-primary:hover{background:#c7d2fe;box-shadow:0 4px 16px rgba(165,180,252,.3);}
[data-theme="dark"] .btn-ghost{color:var(--text-2);}
[data-theme="dark"] .btn-ghost:hover{background:var(--bg-hover);color:var(--text);}
[data-theme="dark"] .btn-outline{background:transparent;border-color:var(--border);color:var(--text-2);}
[data-theme="dark"] .btn-outline:hover{background:var(--bg-hover);border-color:var(--muted);color:var(--text);}
[data-theme="dark"] .btn-danger{color:var(--red);border-color:rgba(252,165,165,.3);}
[data-theme="dark"] .btn-danger:hover{background:var(--red-light);}
[data-theme="dark"] .btn-accent2{background:var(--accent2);color:var(--text);}

/* ── Modals ── */
[data-theme="dark"] .modal-overlay{background:var(--bg-overlay);}
[data-theme="dark"] .modal{background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-xl);}
[data-theme="dark"] .modal-header{color:var(--text);}
[data-theme="dark"] .modal-footer{border-top-color:var(--border);background:rgba(255,255,255,.02);}
[data-theme="dark"] .modal-body{color:var(--text);}

/* ── Toast ── */
[data-theme="dark"] .toast{background:var(--surface);border:1px solid var(--border);color:var(--text);box-shadow:var(--shadow-lg);}

/* ── Gantt ── */
[data-theme="dark"] .gantt-wrap{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .gantt-grid{background:var(--card);}
[data-theme="dark"] .gantt-header{border-bottom-color:var(--border);}
[data-theme="dark"] .gantt-header-row,
[data-theme="dark"] .gantt-header-row th{background:rgba(255,255,255,.03);border-color:var(--border);color:var(--muted);}
[data-theme="dark"] .gantt-row-label{border-right-color:var(--border);color:var(--text);}
[data-theme="dark"] .gantt-row-epic{background:rgba(99,102,241,.08);}
[data-theme="dark"] .gantt-row-subtask{background:rgba(94,234,212,.04);}

/* ── Risk ── */
[data-theme="dark"] .risk-cell{border-color:var(--border);}

/* ── Availability ── */
[data-theme="dark"] .avail-card{background:var(--card);border-color:var(--border);}

/* ── AI Chat Panel ── */
[data-theme="dark"] .ai-panel{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .ai-header{background:linear-gradient(90deg,rgba(255,255,255,.03),rgba(255,255,255,.01));border-bottom-color:var(--border);}
[data-theme="dark"] .chat-messages{background:var(--bg);}
[data-theme="dark"] .chat-messages::-webkit-scrollbar-thumb{background:var(--border);}
[data-theme="dark"] .msg-bubble{background:var(--surface);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .msg.user .msg-bubble{background:linear-gradient(135deg,rgba(165,180,252,.15),rgba(165,180,252,.08));border-color:rgba(165,180,252,.2);color:var(--text);}
[data-theme="dark"] .msg-bubble.error-bubble{border-color:rgba(252,165,165,.3);background:var(--red-light);}
[data-theme="dark"] .error-detail{color:var(--red);background:var(--bg-input);}
[data-theme="dark"] .msg-avatar{background:linear-gradient(135deg,rgba(165,180,252,.12),rgba(165,180,252,.06));border-color:rgba(165,180,252,.2);}
[data-theme="dark"] .msg.user .msg-avatar{background:linear-gradient(135deg,rgba(103,232,249,.12),rgba(103,232,249,.06));border-color:rgba(103,232,249,.2);}
[data-theme="dark"] .chat-input-row{background:var(--surface);border-top-color:var(--border);}
[data-theme="dark"] .chat-input{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .chat-input:focus{background:var(--surface);border-color:var(--accent);box-shadow:0 0 0 3px rgba(165,180,252,.1);}
[data-theme="dark"] .quick-prompts{background:rgba(255,255,255,.02);border-bottom-color:var(--border);}
[data-theme="dark"] .qp{background:var(--bg-input);border-color:var(--border);color:var(--muted);}
[data-theme="dark"] .qp:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-light);}
[data-theme="dark"] .api-key-card{background:var(--card);border-color:var(--border);border-top-color:var(--accent);}

/* AI upload zone */
[data-theme="dark"] .upload-zone-wrap{background:rgba(255,255,255,.02);border-bottom-color:var(--border);}
[data-theme="dark"] .upload-zone{border-color:rgba(165,180,252,.25);background:var(--bg-input);}
[data-theme="dark"] .upload-zone:hover,
[data-theme="dark"] .upload-zone.drag-over{border-color:var(--accent);background:var(--accent-light);}
[data-theme="dark"] .upload-zone.has-file{border-color:var(--green);background:var(--green-light);}
[data-theme="dark"] .upload-zone-icon{background:var(--accent-light);}
[data-theme="dark"] .upload-zone.has-file .upload-zone-icon{background:var(--green-light);}
[data-theme="dark"] .upload-clear{border-color:var(--border);background:var(--surface);color:var(--muted);}
[data-theme="dark"] .upload-clear:hover{border-color:var(--red);color:var(--red);background:var(--red-light);}
[data-theme="dark"] .role-prompts{background:var(--card);border-bottom-color:var(--border);}
[data-theme="dark"] .rqp.rqp-product{background:rgba(124,58,237,.12);border-color:rgba(124,58,237,.35);color:#c4b5fd;}
[data-theme="dark"] .rqp.rqp-product:hover{background:var(--purple);color:var(--surface);border-color:var(--purple);}
[data-theme="dark"] .rqp.rqp-pm{background:rgba(29,78,216,.12);border-color:rgba(29,78,216,.35);color:#93c5fd;}
[data-theme="dark"] .rqp.rqp-pm:hover{background:var(--info);color:var(--surface);border-color:var(--info);}
[data-theme="dark"] .rqp.rqp-pmo{background:rgba(21,128,61,.12);border-color:rgba(21,128,61,.35);color:#86efac;}
[data-theme="dark"] .rqp.rqp-pmo:hover{background:var(--success);color:var(--surface);border-color:var(--success);}
[data-theme="dark"] .doc-prompts{background:linear-gradient(90deg,rgba(165,180,252,.06),rgba(103,232,249,.04));border-bottom-color:var(--border);}
[data-theme="dark"] .doc-prompts-label{color:var(--accent);}
[data-theme="dark"] .dqp{background:var(--bg-input);border-color:rgba(165,180,252,.25);color:var(--accent);}
[data-theme="dark"] .dqp:hover{background:var(--accent);color:var(--text);border-color:var(--accent);}
[data-theme="dark"] .file-ext-badge.pdf{background:var(--red-light);color:var(--red);}
[data-theme="dark"] .file-ext-badge.image{background:var(--yellow-light);color:var(--yellow);}
[data-theme="dark"] .file-ext-badge.text{background:rgba(147,197,253,.14);color:#93c5fd;}

/* ── Knowledge Base ── */
[data-theme="dark"] .kb-sidebar{background:var(--surface);border-right-color:var(--border);}
[data-theme="dark"] .kb-search-input{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .kb-search-input:focus{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .kb-note-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .kb-note-card:hover{border-color:var(--accent);background:rgba(165,180,252,.04);}
[data-theme="dark"] .kb-main{background:var(--bg);}
[data-theme="dark"] .kb-graph-canvas{border-color:rgba(99,102,241,0.2);box-shadow:0 2px 12px rgba(0,0,0,.3);}
[data-theme="dark"] .kb-content-textarea{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .kb-content-textarea:focus{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .kb-title-input{color:var(--text);}
[data-theme="dark"] .kb-backlinks{background:rgba(255,255,255,.03);border-color:var(--border);}
[data-theme="dark"] .kb-summary-content{background:var(--bg-input);border-color:var(--border);color:var(--text);}

/* KB template modal */
[data-theme="dark"] .kb-tpl-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .kb-tpl-card:hover{border-color:var(--accent);background:rgba(165,180,252,.06);}
[data-theme="dark"] .kb-tpl-modal-header{border-bottom-color:var(--border);}

/* KB custom selects */
[data-theme="dark"] .kb-custom-select-btn{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .kb-custom-select-btn:focus{background:var(--surface);border-color:var(--accent);}
[data-theme="dark"] .kb-custom-select-dropdown{background:var(--surface);border-color:var(--border);box-shadow:var(--shadow-lg);}
[data-theme="dark"] .kb-csel-option:hover{background:var(--bg-hover);}
[data-theme="dark"] .kb-csel-option.active{background:var(--accent-light);color:var(--accent);}

/* KB category filters */
[data-theme="dark"] .kb-cat-filter{color:var(--muted);}
[data-theme="dark"] .kb-cat-filter:hover{background:var(--bg-hover);color:var(--text);}
[data-theme="dark"] .kb-cat-filter.active{background:var(--accent-light);color:var(--accent);}

/* KB AI dropdown */
[data-theme="dark"] .kb-ai-menu{background:var(--surface);border-color:var(--border);box-shadow:var(--shadow-lg);}
[data-theme="dark"] .kb-ai-menu div:hover{background:var(--bg-hover);}

/* KB meeting */
[data-theme="dark"] .kb-transcript-area{background:var(--bg-input);border-color:var(--border);}
[data-theme="dark"] .kb-meeting-setup{background:var(--surface);}

/* ── Pagination ── */
[data-theme="dark"] .pagination button{background:var(--surface);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .pagination button:hover{background:var(--bg-hover);}

/* ── Login — keep login screen mostly as-is (already dark gradient) ── */
[data-theme="dark"] .login-card{background:rgba(31,41,55,.97);box-shadow:var(--shadow-xl);}
[data-theme="dark"] .login-card-title{color:var(--muted);}
[data-theme="dark"] .login-error{background:var(--red-light);border-color:rgba(252,165,165,.3);}
[data-theme="dark"] .demo-acc{background:rgba(255,255,255,.04);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .demo-acc:hover{background:var(--accent-light);border-color:var(--accent);}
[data-theme="dark"] .demo-name{color:var(--text);}
[data-theme="dark"] .demo-cred{color:var(--muted);}

/* ── Import ── */
[data-theme="dark"] .import-drop-zone{background:var(--bg-input);border-color:var(--border);}
[data-theme="dark"] .import-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .import-table th{background:var(--bg-input);}
[data-theme="dark"] .import-table .import-cell-input:focus,[data-theme="dark"] .import-table .import-cell-select:focus{background:var(--bg-input);}
[data-theme="dark"] .import-drop-icon{background:rgba(165,180,252,.12);color:var(--accent);}

/* ── Access banner ── */
[data-theme="dark"] .access-banner.limited{background:var(--yellow-light);border-color:rgba(253,230,138,.3);color:var(--yellow);}

/* ── Scrollbar (global) ── */
[data-theme="dark"] ::-webkit-scrollbar-track{background:transparent;}
[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.1);border-radius:4px;}
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.18);}
/* ══ PRODUCT MANAGEMENT — NAV ══════════════════════════════════════ */
.nav-product { display: flex; }

/* ══ OKR ════════════════════════════════════════════════════════════ */
.okr-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-sm);
}
.okr-card-header { display: flex; align-items: flex-start; gap: 12px; }
.okr-title { font-weight: 700; font-size: 15px; color: var(--text); margin-bottom: 2px; }
.okr-desc { font-size: 12px; color: var(--muted); margin-top: 4px; }
.okr-status-badge {
  display: inline-block;
  font-size: 10px; font-weight: 700;
  padding: 2px 8px; border-radius: 10px;
  text-transform: uppercase; letter-spacing: .4px;
}
.okr-status-badge.active { background: var(--green-light); color: var(--green); }
.okr-status-badge.draft { background: var(--surface2); color: var(--muted); }
.okr-status-badge.completed { background: var(--green-light); color: var(--green); }
.okr-status-badge.cancelled { background: var(--red-light); color: var(--red); }
.okr-status-badge.on-track { background: var(--green-light); color: var(--green); }
.okr-status-badge.at-risk { background: var(--yellow-light); color: var(--yellow); }
.okr-status-badge.off-track { background: var(--red-light); color: var(--red); }

.kr-list { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.kr-item { background: var(--bg); border-radius: 8px; padding: 10px 12px; }
.kr-title { font-size: 12px; font-weight: 600; color: var(--text); }
.kr-progress-bar { height: 5px; background: var(--border); border-radius: 3px; overflow: hidden; margin: 3px 0; }
.kr-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width .4s ease; }

/* ══ ROADMAP ════════════════════════════════════════════════════════ */
.roadmap-horizons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; min-height: calc(100vh - 180px); }
@media (max-width: 900px) { .roadmap-horizons { grid-template-columns: 1fr; } }
.horizon-column { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 14px; min-height: 300px; }
.horizon-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; padding-bottom:10px; border-bottom:1px solid var(--border); }
.horizon-header.horizon-now { border-bottom-color: var(--green); }
.horizon-header.horizon-next { border-bottom-color: var(--yellow); }
.horizon-header.horizon-later { border-bottom-color: var(--accent); }
.horizon-title { font-size:12.5px; font-weight:700; display:flex; align-items:center; gap:6px; }
.horizon-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.horizon-dot-now { background: var(--green); }
.horizon-dot-next { background: var(--yellow); }
.horizon-dot-later { background: var(--accent); }
.horizon-count { background: var(--card); color: var(--muted); font-size:11px; font-family:var(--mono); padding:2px 8px; border-radius:10px; border:1px solid var(--border); font-weight:700; }
.horizon-items { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.initiative-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 13px; box-shadow: var(--shadow-xs); transition: all .18s; cursor: grab; user-select: none; }
.initiative-card:hover { border-color: rgba(79,70,229,.3); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.initiative-card:active { cursor: grabbing; }
/* Drag-and-drop states */
.rd-clone { position:fixed; pointer-events:none; z-index:9999; opacity:.85; transform:rotate(2deg); box-shadow: var(--shadow-lg); }
.rd-source { opacity:.3; }
.rd-drop-zone { border:2px dashed var(--accent)!important; background:rgba(79,70,229,.04)!important; }
/* G6/G7/G8: roadmap view-toggle + timeline + dep-line overlay */
.roadmap-view-toggle .btn { background: transparent; color: var(--muted); }
.roadmap-view-toggle .btn.active { background: var(--accent); color: #fff; }
.roadmap-dep-svg { position:absolute; left:0; top:0; pointer-events:none; }
.rd-tl-wrap { background: var(--surface); border:1px solid var(--border); border-radius: var(--r-md); padding: 16px 18px; overflow: auto; grid-column: 1 / -1; width: 100%; box-shadow: var(--shadow-xs); max-height: 100%; align-self: start; }
.rd-tl-header { display:flex; align-items:stretch; height:36px; border-bottom:1px solid var(--border); margin-bottom:10px; padding-bottom:4px; }
.rd-tl-label-spacer { width: 280px; flex-shrink:0; display:flex; align-items:center; font-size:11px; font-weight:700; color: var(--muted); text-transform:uppercase; letter-spacing:.6px; padding-left:4px; }
.rd-tl-axis { position:relative; flex:1; height:32px; min-width: 640px; }
.rd-tl-tick { position:absolute; top:14px; font-size:10.5px; color: var(--muted); transform: translateX(-50%); white-space:nowrap; font-weight:500; }
.rd-tl-tick::before { content:''; position:absolute; top:-8px; left:50%; transform:translateX(-50%); width:1px; height:6px; background: var(--border); }
.rd-tl-gridline { position:absolute; top:32px; bottom:-100vh; width:1px; background: var(--border); opacity:.35; pointer-events:none; }
.rd-tl-today { position:absolute; top:6px; bottom:-100vh; width:2px; background: var(--red,#dc2626); opacity:.55; pointer-events:none; z-index:1; }
.rd-tl-today::after { content:'Today'; position:absolute; top:-4px; left:50%; transform:translateX(-50%); font-size:9px; font-weight:700; color:#fff; background: var(--red,#dc2626); padding:1px 5px; border-radius:8px; letter-spacing:.3px; }
.rd-tl-body { display:flex; flex-direction:column; gap:4px; }
.rd-tl-row { display:flex; align-items:center; gap:12px; min-height: 38px; padding: 2px 4px; border-radius: 6px; transition: background .12s ease; }
.rd-tl-row:hover { background: rgba(79,70,229,.04); }
.rd-tl-label { width:280px; flex-shrink:0; font-size:12px; display:flex; flex-direction:column; justify-content:center; gap:3px; overflow:hidden; padding-right:8px; }
.rd-tl-label-line { display:flex; align-items:center; gap:6px; min-width:0; }
.rd-tl-theme-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.rd-tl-horizon-pill { font-size:9px; font-weight:700; padding:1px 6px; border-radius:8px; letter-spacing:.4px; text-transform:uppercase; flex-shrink:0; }
.rd-tl-horizon-pill.h-now { background: var(--green-light,rgba(16,185,129,.12)); color: var(--green,#10b981); }
.rd-tl-horizon-pill.h-next { background: var(--yellow-light,rgba(234,179,8,.14)); color: var(--yellow,#ca8a04); }
.rd-tl-horizon-pill.h-later { background: var(--accent-light,rgba(79,70,229,.12)); color: var(--accent,#4f46e5); }
.rd-tl-title { font-weight:600; white-space:nowrap; text-overflow:ellipsis; overflow:hidden; color: var(--text); font-size:12.5px; cursor: pointer; }
.rd-tl-title:hover { color: var(--accent); }
.rd-tl-meta { font-size:10.5px; color: var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:flex; align-items:center; gap:6px; }
.rd-tl-meta-date { font-family: var(--mono,monospace); font-weight:600; color: var(--text-muted,var(--muted)); }
.rd-tl-track { position:relative; flex:1; height: 28px; background: rgba(0,0,0,.025); border-radius: 6px; min-width: 640px; overflow:hidden; }
.rd-tl-bar { position:absolute; top:3px; bottom:3px; min-width: 30px; background: var(--accent-light,rgba(79,70,229,.16)); border:1px solid var(--accent); border-radius: 5px; display:flex; align-items:center; padding:0 8px; cursor:pointer; font-size:11px; color: var(--accent); font-weight:600; overflow:hidden; box-shadow: 0 1px 2px rgba(0,0,0,.04); transition: filter .12s ease, box-shadow .12s ease; }
.rd-tl-bar:hover { filter: brightness(1.06); box-shadow: var(--shadow-sm); }
.rd-tl-bar.badge-green { background: rgba(16,185,129,.16); border-color: var(--green,#10b981); color: var(--green,#10b981); }
.rd-tl-bar.badge-blue { background: rgba(79,70,229,.16); border-color: var(--accent,#4f46e5); color: var(--accent,#4f46e5); }
.rd-tl-bar.badge-yellow { background: rgba(234,179,8,.18); border-color: var(--yellow,#ca8a04); color: var(--yellow,#ca8a04); }
.rd-tl-bar.badge-red { background: rgba(220,38,38,.16); border-color: var(--red,#dc2626); color: var(--red,#dc2626); }
.rd-tl-bar.badge-muted { background: rgba(100,116,139,.14); border-color: var(--muted,#64748b); color: var(--muted,#64748b); }
.rd-tl-bar-text { white-space:nowrap; text-overflow:ellipsis; overflow:hidden; }
.rd-tl-undated { margin-top:14px; padding-top:12px; border-top:1px dashed var(--border); display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.rd-tl-undated-label { font-size:11px; font-weight:700; color: var(--muted); text-transform:uppercase; letter-spacing:.6px; margin-right:6px; }
.rd-tl-chip { font-size:11px; padding:3px 9px; border-radius:10px; background: var(--surface2,var(--surface)); border:1px solid var(--border); cursor:pointer; transition: border-color .12s ease, color .12s ease; }
.rd-tl-chip:hover { border-color: var(--accent); color: var(--accent); }
.feature-chip { display: inline-block; font-size: 10px; padding: 2px 8px; border-radius: 10px; background: var(--accent-light); color: var(--accent); font-weight: 600; }
.feature-chip.feature-completed { background: var(--green-light); color: var(--green); }
.feature-chip.feature-in-progress { background: var(--blue-light, rgba(37,99,235,.1)); color: var(--accent); }
.feature-chip.feature-cancelled { background: var(--red-light); color: var(--red); }

/* ── Initiative card internals ─────────────────────────────────── */
.init-card-header { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:6px; }
.init-card-meta { display:flex; gap:4px; flex-wrap:wrap; align-items:center; }
.init-card-actions { display:flex; gap:3px; flex-shrink:0; }
.init-rice-badge { font-size:10px; background:var(--accent); color:var(--surface); padding:1px 7px; border-radius:10px; font-weight:700; }
.init-card-title { font-weight:600; font-size:13px; margin-bottom:4px; line-height:1.3; }
.init-card-desc { font-size:11px; color:var(--muted); margin-bottom:6px; line-height:1.4; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.init-card-links { display:flex; gap:4px; flex-wrap:wrap; margin-bottom:6px; }
.init-card-link-chip { font-size:10px; background:var(--surface2,var(--surface)); border:1px solid var(--border); color:var(--muted); padding:1px 7px; border-radius:10px; display:inline-flex; align-items:center; gap:3px; }
.init-doc-chip { background:var(--accent-light,rgba(37,99,235,.08)); color:var(--accent); border-color:transparent; }
.init-progress-row { margin:6px 0; }
.init-progress-label { display:flex; justify-content:space-between; font-size:11px; color:var(--muted); margin-bottom:3px; }
.init-features-list { display:flex; flex-direction:column; gap:2px; margin:6px 0; }
.init-feature-row { display:flex; justify-content:space-between; align-items:center; padding:3px 6px; border-radius:5px; background:var(--surface); }
.init-feature-row:hover { background:var(--bg-hover); }
.init-feature-left { display:flex; align-items:center; gap:5px; min-width:0; }
.init-feature-dot { width:7px; height:7px; border-radius:50%; flex-shrink:0; background:var(--muted); }
.init-feat-completed { background:var(--green)!important; }
.init-feat-in-progress { background:var(--accent)!important; }
.init-feat-planned { background:var(--blue,var(--accent))!important; }
.init-feat-cancelled { background:var(--red)!important; }
.init-feature-name { font-size:11px; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.init-feature-actions { display:flex; gap:2px; flex-shrink:0; opacity:0; transition:opacity .15s; }
.init-feature-row:hover .init-feature-actions { opacity:1; }
.init-add-feat-btn { margin-top:6px; width:100%; justify-content:center; }
/* Project execution progress block */
.init-proj-progress { background:var(--surface); border:1px solid var(--border); border-radius:6px; padding:7px 9px; margin:6px 0; }
.init-proj-progress-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:5px; gap:6px; }
.init-proj-progress-name { display:flex; align-items:center; gap:4px; font-size:11px; font-weight:600; color:var(--text); min-width:0; overflow:hidden; }
.init-proj-progress-name span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.init-proj-progress-right { display:flex; align-items:center; gap:5px; flex-shrink:0; }
.init-proj-pct { font-size:11px; font-weight:700; font-family:var(--mono); color:var(--accent); }
.init-proj-fill { background: linear-gradient(90deg, var(--accent), var(--green)); }
/* RICE section in modal */
.init-rice-section { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:12px; margin-bottom:12px; }
.init-rice-label { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); margin-bottom:8px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.init-rice-hint { font-weight:400; text-transform:none; letter-spacing:0; font-size:11px; color:var(--muted); }
.init-rice-score { font-size:12px; font-weight:700; color:var(--green); background:var(--green-light); padding:2px 10px; border-radius:10px; margin-left:auto; }

/* ══ USER PERSONAS ══════════════════════════════════════════════════ */
.persona-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.persona-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 20px; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
.persona-avatar {
  width: 56px; height: 56px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--purple, #7c3aed));
  color: var(--surface); font-weight: 800; font-size: 20px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 10px;
}
.persona-name { font-weight: 700; font-size: 15px; margin-bottom: 2px; }
.persona-role { font-size: 11px; color: var(--muted); margin-bottom: 8px; }
.persona-section { width: 100%; text-align: left; margin-bottom: 8px; }
.persona-section-label { font-size: 10px; text-transform: uppercase; letter-spacing: .6px; font-weight: 700; color: var(--muted); margin-bottom: 2px; }
.persona-section div { font-size: 12px; color: var(--text); }

.pain-point-item { padding: 10px 12px; border-radius: 8px; margin-bottom: 6px; border-left: 3px solid var(--border); background: var(--bg); }
.pain-point-item.pain-critical { border-color: var(--red); }
.pain-point-item.pain-high { border-color: var(--yellow); }
.pain-point-item.pain-medium { border-color: var(--accent); }
.pain-point-item.pain-low { border-color: var(--green); }

/* ══ CUSTOMER FEEDBACK ══════════════════════════════════════════════ */
.section-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); padding-bottom: 0; }
.tab-btn {
  padding: 8px 16px; font-size: 13px; font-weight: 600;
  background: none; border: none; border-bottom: 2px solid transparent;
  cursor: pointer; color: var(--muted); transition: color .15s, border-color .15s;
}
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-btn:hover { color: var(--text); }
.fr-card { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px; margin-bottom: 10px; }

/* ══ PRODUCT METRICS ════════════════════════════════════════════════ */
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.metric-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 18px; box-shadow: var(--shadow-sm);
}

/* ══ RELEASES ═══════════════════════════════════════════════════════ */
.release-card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 16px 18px; margin-bottom: 10px; box-shadow: var(--shadow-sm);
  transition: box-shadow .18s, border-color .18s;
}
.release-card:hover { border-color: rgba(79,70,229,.25); box-shadow: var(--shadow-md); }
.release-card-top { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; }
.release-card-left { flex:1; min-width:0; }
.release-card-actions { display:flex; gap:6px; flex-shrink:0; align-items:flex-start; }
.release-card-header { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; }
.release-version { font-family:var(--mono); font-size:14px; font-weight:800; color:var(--accent); background:var(--accent-light); padding:2px 10px; border-radius:6px; }
.release-name { font-size:13px; font-weight:600; color:var(--text); }
.release-project-chip { display:inline-flex; align-items:center; gap:4px; font-size:11px; color:var(--muted); background:var(--surface); border:1px solid var(--border); padding:2px 8px; border-radius:10px; margin-bottom:6px; }
.release-desc { font-size:12px; color:var(--muted); margin-bottom:6px; line-height:1.5; }
.release-dates { display:flex; gap:14px; flex-wrap:wrap; font-size:11px; color:var(--muted); }
.release-dates span { display:inline-flex; align-items:center; gap:3px; }
.changelog-content { padding: 12px 0; max-height: 400px; overflow-y: auto; font-size: 13px; line-height: 1.7; }
/* ── Changelog modal ─────────────────────────────────────────── */
.cl-modal { max-width: 640px; }
.cl-release-meta { display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:8px; padding:12px 14px; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); margin-bottom:12px; }
.cl-meta-left { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.cl-meta-title { font-size:13px; font-weight:600; color:var(--text); }
.cl-meta-right { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.cl-meta-date { display:inline-flex; align-items:center; gap:3px; font-size:11px; color:var(--muted); }
.cl-meta-released { color:var(--green); }
.cl-release-desc { font-size:12px; color:var(--muted); margin-bottom:12px; line-height:1.5; }
.cl-section-label { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:8px; }
.cl-notes-section { background:var(--surface); border-left:3px solid var(--accent); border-radius:0 var(--r-sm) var(--r-sm) 0; padding:10px 14px; margin-bottom:14px; font-size:12px; line-height:1.6; }
.cl-notes-body { color:var(--text); }
.cl-features-section { margin-top:4px; }
.cl-feature-list { display:flex; flex-direction:column; gap:2px; }
.cl-h2 { font-size:13px; font-weight:700; color:var(--text); padding:4px 0; display:none; }
.cl-type-header { margin:10px 0 4px; }
.cl-type-badge { display:inline-flex; align-items:center; font-size:10px; font-weight:700; padding:2px 10px; border-radius:10px; }
.cl-type-feature { background:var(--accent-light,rgba(79,70,229,.1)); color:var(--accent); }
.cl-type-enhance { background:rgba(16,185,129,.1); color:var(--green); }
.cl-type-bug { background:rgba(239,68,68,.1); color:var(--red); }
.cl-type-debt { background:rgba(217,119,6,.1); color:var(--yellow); }
.cl-type-research { background:rgba(139,92,246,.1); color:var(--purple); }
.cl-type-other { background:var(--surface2,var(--surface)); color:var(--muted); border:1px solid var(--border); }
.cl-item { display:flex; align-items:baseline; gap:8px; padding:5px 8px; border-radius:6px; }
.cl-item:hover { background:var(--bg-hover); }
.cl-item-dot { width:5px; height:5px; border-radius:50%; background:var(--accent); flex-shrink:0; margin-top:2px; }
.cl-item-title { font-size:12px; font-weight:600; color:var(--text); flex-shrink:0; }
.cl-item-desc { font-size:12px; color:var(--muted); }
.cl-spacer { height:4px; }
.cl-empty { display:flex; flex-direction:column; align-items:center; gap:8px; padding:28px 16px; color:var(--muted); font-size:12px; text-align:center; border:1px dashed var(--border); border-radius:var(--r-md); }
.cl-empty svg { opacity:.4; }

/* ══ HYPOTHESES ══════════════════════════════════════════════════════ */
.hypothesis-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  padding: 16px 18px; margin-bottom: 12px; box-shadow: var(--shadow-sm);
}
.hypothesis-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
@media (max-width: 700px) { .hypothesis-grid { grid-template-columns: 1fr; } }
.hyp-section { background: var(--bg); border-radius: 8px; padding: 10px 12px; }
.hyp-label { font-size: 10px; text-transform: uppercase; letter-spacing: .6px; font-weight: 700; color: var(--muted); margin-bottom: 4px; }
.hyp-section div { font-size: 12px; line-height: 1.5; }

/* ══ COMPETITORS ═════════════════════════════════════════════════════ */
.competitor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
.competitor-card {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 18px; box-shadow: var(--shadow-sm);
}
.swot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.swot-cell { background: var(--bg); border-radius: 8px; padding: 8px 10px; font-size: 12px; }
.swot-cell.swot-s { border-left: 3px solid var(--green); }
.swot-cell.swot-w { border-left: 3px solid var(--red); }
.swot-label { font-size: 10px; text-transform: uppercase; letter-spacing: .6px; font-weight: 700; color: var(--muted); margin-bottom: 3px; }

/* ══ EMPTY STATE ════════════════════════════════════════════════════ */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 48px 24px; color: var(--muted); font-size: 14px; text-align: center;
}

/* ══ DARK MODE ═══════════════════════════════════════════════════════ */
[data-theme="dark"] .okr-card,
[data-theme="dark"] .initiative-card,
[data-theme="dark"] .persona-card,
[data-theme="dark"] .fr-card,
[data-theme="dark"] .metric-card,
[data-theme="dark"] .release-card,
[data-theme="dark"] .hypothesis-card,
[data-theme="dark"] .competitor-card { background: var(--card); border-color: var(--border); }
[data-theme="dark"] .kr-item,
[data-theme="dark"] .pain-point-item,
[data-theme="dark"] .hyp-section,
[data-theme="dark"] .swot-cell { background: rgba(255,255,255,.04); }
[data-theme="dark"] .horizon-column { background: rgba(255,255,255,.02); }
[data-theme="dark"] .tab-btn { color: var(--muted); }
[data-theme="dark"] .tab-btn.active { color: var(--accent); }

/* ══ PRODUCT DOCS ═══════════════════════════════════════════════ */
/* Doc list grid — .content already provides padding:24px 26px */
.doc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px;}
.doc-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-md);padding:16px;cursor:pointer;transition:all .18s;display:flex;flex-direction:column;gap:8px;box-shadow:var(--shadow-xs);}
.doc-card:hover{border-color:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow-md);}
.doc-card-header{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.doc-card-del{margin-left:auto;background:none;border:none;cursor:pointer;color:var(--muted);padding:3px 5px;border-radius:var(--r-sm);opacity:0;transition:opacity .15s,color .15s;}
.doc-card:hover .doc-card-del{opacity:1;}
.doc-card-del:hover{color:var(--red);}
.doc-card-title{font-weight:700;font-size:14px;color:var(--text);line-height:1.4;word-break:break-word;}
.doc-card-meta{font-size:11px;color:var(--muted);font-family:var(--mono);}

/* Full-screen editor overlay */
.doc-editor-overlay{position:fixed;inset:0;background:var(--bg);z-index:200;display:none;flex-direction:column;}
.doc-editor-overlay.open{display:flex;animation:pageIn .2s ease both;}
/* Topbar matches .topbar exactly */
.doc-editor-topbar{display:flex;align-items:center;gap:12px;padding:0 24px;height:56px;border-bottom:1px solid var(--border);background:var(--surface);flex-shrink:0;box-shadow:var(--shadow-xs);}
.doc-editor-back{background:transparent;border:1.5px solid var(--border);color:var(--muted);font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:var(--r-sm);transition:all .18s;}
.doc-editor-back:hover{color:var(--text);border-color:var(--accent);background:var(--accent-light);}
.doc-editor-meta{display:flex;align-items:center;gap:10px;flex:1;min-width:0;}
.doc-editor-type-badge{flex-shrink:0;}
.doc-editor-title-input{flex:1;background:none;border:none;outline:none;font-size:15px;font-weight:700;color:var(--text);font-family:var(--font);letter-spacing:-.3px;min-width:0;}
.doc-editor-title-input::placeholder{color:var(--muted-light);}
.doc-editor-actions{display:flex;align-items:center;gap:8px;flex-shrink:0;}
/* Status select matches .filter-select */
.doc-editor-status-select{background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-sm);color:var(--text);font-family:var(--font);font-size:12.5px;padding:4px 10px;outline:none;cursor:pointer;transition:border-color .2s;}
.doc-editor-status-select:focus{border-color:var(--accent);}
/* Save indicator matches .topbar-date / .result-count */
.doc-save-indicator{font-size:11px;color:var(--muted);font-family:var(--mono);white-space:nowrap;background:var(--bg);padding:4px 10px;border-radius:20px;border:1px solid var(--border);}
.doc-editor-body{flex:1;overflow-y:auto;position:relative;}
.doc-editor-body::-webkit-scrollbar{width:5px;}
.doc-editor-body::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:3px;}
.doc-editor-body::-webkit-scrollbar-track{background:transparent;}
/* Content column: padding-left 24px so .block-actions (56px) sits inside
   the inset, and .doc-block text lands at 80px from the centered box edge
   — exactly where .doc-page-header titles + #prdChipRow chips sit. */
.doc-editor-content{max-width:760px;margin:0 auto;padding:8px 24px 80px;min-height:100%;counter-reset:list-counter;}

/* Blocks */
.doc-block{outline:none;caret-color:var(--text);color:var(--text);line-height:1.7;padding:3px 6px;border-radius:var(--r-sm);margin:1px 0;min-height:1.7em;word-break:break-word;transition:background .12s;}
.doc-block:empty::before{content:'Type / for commands…';color:var(--muted-light);pointer-events:none;}
.doc-block:hover,.doc-block:focus{background:var(--bg-hover);}
.doc-block-h1{font-size:2em;font-weight:700;letter-spacing:-.5px;margin-top:.6em;}
.doc-block-h2{font-size:1.5em;font-weight:700;letter-spacing:-.3px;margin-top:.5em;}
.doc-block-h3{font-size:1.2em;font-weight:700;letter-spacing:-.2px;margin-top:.4em;}
.doc-block-bullet{padding-left:1.6em;position:relative;}
.doc-block-bullet::before{content:'•';position:absolute;left:.4em;color:var(--muted);}
.doc-block-numbered{padding-left:1.6em;position:relative;counter-increment:list-counter;}
.doc-block-numbered::before{content:counter(list-counter)'.';position:absolute;left:.1em;color:var(--muted);}
.doc-block-quote{border-left:3px solid var(--accent);padding-left:14px;color:var(--muted);font-style:italic;margin:4px 0;}
.doc-block-callout{display:flex;gap:10px;align-items:flex-start;border-radius:var(--r-md);padding:12px 14px;margin:4px 0;}
.callout-icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-top:1px;}
.callout-text{flex:1;outline:none;caret-color:var(--text);color:var(--text);}
.doc-block-code{font-family:var(--mono);font-size:12.5px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;white-space:pre-wrap;tab-size:2;margin:4px 0;color:var(--text-2);}
.doc-block-divider{padding:8px 0;cursor:default;}
.doc-block-divider:hover,.doc-block-divider:focus{background:transparent;}
.doc-block-divider hr{border:none;border-top:1px solid var(--border);margin:0;}
.doc-block-todo{display:flex;align-items:flex-start;gap:8px;padding:3px 6px;}
.doc-block-todo:hover,.doc-block-todo:focus-within{background:var(--bg-hover);border-radius:var(--r-sm);}
.todo-check{flex-shrink:0;margin-top:3px;accent-color:var(--accent);}
.todo-text{flex:1;outline:none;caret-color:var(--text);color:var(--text);}

/* Slash command menu — matches .assignee-dropdown / .suggest-card panel style */
.slash-menu{position:absolute;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);min-width:210px;z-index:500;display:none;flex-direction:column;overflow:hidden;}
.slash-menu.open{display:flex;animation:fadeUp .15s cubic-bezier(.16,1,.3,1) both;}
.slash-menu-item{display:flex;align-items:center;gap:10px;padding:8px 14px;cursor:pointer;font-size:13px;color:var(--text);transition:background .12s;}
.slash-menu-item:hover,.slash-menu-item.active{background:var(--bg-hover);color:var(--accent);}
.slash-menu-icon{width:26px;height:26px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:var(--muted);background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);flex-shrink:0;}

/* Inline format toolbar */
.inline-toolbar{position:absolute;background:var(--surface);border:1.5px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-md);display:none;align-items:center;gap:2px;padding:4px 6px;z-index:500;}
.inline-toolbar.open{display:flex;animation:fadeUp .12s ease both;}
.inline-toolbar button{background:none;border:none;cursor:pointer;color:var(--text-2);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--r-sm);font-size:13px;font-family:var(--font);font-weight:700;transition:all .12s;}
.inline-toolbar button:hover{background:var(--bg-hover);color:var(--accent);}

/* Dark mode */
[data-theme="dark"] .doc-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .doc-card:hover{border-color:var(--accent);background:rgba(165,180,252,.04);}
[data-theme="dark"] .doc-editor-overlay{background:var(--bg);}
[data-theme="dark"] .doc-editor-topbar{background:var(--surface);border-color:var(--border);}
[data-theme="dark"] .doc-editor-status-select{background:var(--bg-input);border-color:var(--border);color:var(--text);}
[data-theme="dark"] .doc-block:hover,[data-theme="dark"] .doc-block:focus{background:var(--bg-hover);}
[data-theme="dark"] .doc-block-todo:hover,[data-theme="dark"] .doc-block-todo:focus-within{background:var(--bg-hover);}
[data-theme="dark"] .doc-block-code{background:var(--bg-input);border-color:var(--border);}
[data-theme="dark"] .doc-callout-info{background:color-mix(in srgb,var(--accent) 12%,transparent);}
[data-theme="dark"] .slash-menu,[data-theme="dark"] .inline-toolbar{background:var(--surface);border-color:var(--border);}
[data-theme="dark"] .slash-menu-icon{background:var(--bg);border-color:var(--border);}
[data-theme="dark"] .doc-editor-body::-webkit-scrollbar-thumb{background:var(--border);}
[data-theme="dark"] .doc-save-indicator{background:var(--bg);border-color:var(--border);}

/* Doc page header (Notion-style).
   padding-left 80px so the emoji icon + title share the same x-axis as
   the body block text — block-row's .block-actions (56px) + content
   padding-left (24px) lands the doc-block at +80px from the box edge. */
.doc-page-header { max-width:760px; margin:0 auto; padding:48px 24px 8px 80px; position:relative; }
/* PRD chip row (Health Check + Linked Hypothesis/Research). Same column
   geometry as page-header + content so chips don't float off to the left
   of the centered box. :empty hides the bar for non-PRD docs so no
   stray vertical space gets reserved. */
#prdChipRow { max-width:760px; margin:8px auto 0; padding:0 24px 0 80px; display:flex; flex-wrap:wrap; gap:6px; align-items:center; font-size:12px; }
#prdChipRow:empty { display:none; }
.doc-page-icon-wrap { position:relative; display:inline-block; margin-bottom:8px; }
.doc-page-icon { font-size:52px; line-height:1.1; cursor:pointer; background:none; border:none; padding:4px 6px; border-radius:var(--r-md); transition:background .15s; display:block; }
.doc-page-icon:hover { background:var(--bg-hover); }
.doc-emoji-picker { position:absolute; top:calc(100% + 6px); left:0; background:var(--surface); border:1.5px solid var(--border); border-radius:var(--r-lg); box-shadow:var(--shadow-lg); padding:12px; z-index:600; width:280px; display:none; }
.doc-emoji-picker.open { display:block; animation:fadeUp .15s cubic-bezier(.16,1,.3,1) both; }
.doc-emoji-picker-title { font-size:11px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.6px; margin-bottom:8px; }
.doc-emoji-grid { display:grid; grid-template-columns:repeat(8,1fr); gap:2px; }
.doc-emoji-btn { font-size:22px; cursor:pointer; background:none; border:none; padding:4px; border-radius:var(--r-sm); transition:background .12s; line-height:1.2; text-align:center; }
.doc-emoji-btn:hover { background:var(--bg-hover); }
.doc-page-title { font-size:2.5em; font-weight:800; color:var(--text); letter-spacing:-.6px; line-height:1.2; outline:none; caret-color:var(--text); word-break:break-word; min-height:1.2em; margin-bottom:16px; }
.doc-page-title:empty::before { content:attr(placeholder); color:var(--muted-light); pointer-events:none; }

/* Block row wrapper */
.block-row { display:flex; align-items:flex-start; gap:0; position:relative; }
.block-row:hover .block-actions, .block-row:focus-within .block-actions { opacity:1; }
.block-actions { display:flex; align-items:center; gap:1px; opacity:0; transition:opacity .15s; flex-shrink:0; padding-top:5px; width:52px; justify-content:flex-end; margin-right:4px; }
.block-add-btn { background:none; border:none; cursor:pointer; color:var(--muted); font-size:16px; line-height:1; width:22px; height:22px; display:flex; align-items:center; justify-content:center; border-radius:var(--r-sm); transition:all .12s; padding:0; }
.block-add-btn:hover { background:var(--bg-hover); color:var(--accent); }
.block-drag-handle { background:none; border:none; cursor:grab; color:var(--muted); width:22px; height:22px; display:flex; align-items:center; justify-content:center; border-radius:var(--r-sm); transition:all .12s; padding:0; }
.block-drag-handle:hover { background:var(--bg-hover); color:var(--text); }
.block-drag-handle:active { cursor:grabbing; }
.block-row .doc-block { flex:1; min-width:0; }
.dragging-source { opacity: 0.25; }

/* Dragging styles */
.block-drag-line { position:absolute; left:0; right:0; height:2px; background:var(--accent); border-radius:2px; pointer-events:none; z-index:400; }

/* Slash menu improvements */
.slash-menu { min-width:260px; max-height:400px; overflow-y:auto; }
.slash-menu-section { font-size:10px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:.7px; padding:10px 14px 4px; }
.slash-menu-info { display:flex; flex-direction:column; gap:1px; }
.slash-menu-name { font-size:13px; font-weight:600; color:var(--text); }
.slash-menu-desc { font-size:11px; color:var(--muted); }
.slash-menu-item { align-items:center; gap:10px; }
.slash-menu-item:hover .slash-menu-name, .slash-menu-item.active .slash-menu-name { color:var(--accent); }

/* Inline toolbar separator */
.inline-sep { width:1px; height:18px; background:var(--border); margin:0 2px; flex-shrink:0; }

/* New callout variants */
.doc-callout-info { background:color-mix(in srgb,var(--accent) 10%,transparent); border-left:3px solid var(--accent); }
.doc-callout-warning { background:color-mix(in srgb,var(--yellow) 10%,transparent); border-left:3px solid var(--yellow); }
.doc-callout-success { background:color-mix(in srgb,var(--green) 10%,transparent); border-left:3px solid var(--green); }

/* Image blocks */
.doc-block-image-wrap { position:relative; border-radius:var(--r-md); overflow:hidden; margin:4px 0; cursor:pointer; }
.doc-block-image-wrap:hover .doc-block-image-hint { opacity:1; }
.doc-block-img { display:block; max-width:100%; border-radius:var(--r-md); }
.doc-block-image-hint { position:absolute; bottom:8px; right:8px; background:rgba(0,0,0,.6); color:var(--surface); font-size:11px; padding:4px 10px; border-radius:20px; opacity:0; transition:opacity .15s; display:flex; align-items:center; gap:4px; cursor:pointer; }
.doc-block-image-placeholder { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; border:2px dashed var(--border); border-radius:var(--r-md); padding:32px; margin:4px 0; color:var(--muted); cursor:pointer; transition:border-color .15s; }
.doc-block-image-placeholder:hover { border-color:var(--accent); }
.doc-image-placeholder-text { font-size:13px; }
.doc-image-url-input { width:100%; max-width:360px; padding:6px 12px; border:1.5px solid var(--border); border-radius:var(--r-sm); font-family:var(--font); font-size:13px; color:var(--text); background:var(--bg-input); outline:none; margin-top:4px; }
.doc-image-url-input:focus { border-color:var(--accent); }

/* Word count footer */
.doc-word-count-bar { max-width:760px; margin:0 auto; padding:8px 24px 24px; font-size:11px; color:var(--muted); font-family:var(--mono); text-align:right; }

/* Doc card emoji icon */
.doc-card-icon { width:22px; height:22px; display:flex; align-items:center; justify-content:center; flex-shrink:0; font-size:20px; line-height:1; color:var(--text-2); }

/* Dark mode additions */
[data-theme="dark"] .doc-emoji-picker { background:var(--surface); border-color:var(--border); }
[data-theme="dark"] .doc-block-image-placeholder { border-color:var(--border); }
[data-theme="dark"] .doc-image-url-input { background:var(--bg-input); border-color:var(--border); color:var(--text); }

/* ── Doc Card Additions ─────────────────────────────────────────── */
.doc-card-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:auto;padding-top:8px;}
.doc-card-project{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--muted);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.doc-card-kickoff-btn{display:flex;align-items:center;gap:4px;padding:4px 10px;border-radius:var(--r-sm);border:1.5px solid var(--green-light);background:transparent;color:var(--green);font-size:11px;font-weight:600;font-family:var(--font);cursor:pointer;transition:background .15s,border-color .15s;white-space:nowrap;flex-shrink:0;}
.doc-card-kickoff-btn:hover{background:var(--green-light);}
.doc-card-btn{background:none;border:none;cursor:pointer;color:var(--muted);opacity:0;transition:opacity .15s,color .12s;padding:3px;display:flex;align-items:center;border-radius:var(--r-sm);}
.doc-card:hover .doc-card-btn{opacity:1;}
.doc-card-btn:hover{color:var(--accent);background:var(--bg-hover);}

/* ── Kickoff Requests Page ──────────────────────────────────────── */
.kickoff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;}
.kickoff-card{background:var(--card);border:1px solid var(--border);border-radius:var(--r-lg);padding:16px;cursor:pointer;transition:all .18s;display:flex;flex-direction:column;gap:8px;}
.kickoff-card:hover{border-color:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow-md);}
.kickoff-card-header{display:flex;align-items:center;gap:6px;}
.kickoff-card-badges{display:flex;align-items:center;gap:5px;flex:1;flex-wrap:wrap;}
.kickoff-card-del{margin-left:auto;background:none;border:none;cursor:pointer;color:var(--muted);opacity:0;transition:opacity .15s,color .12s;padding:2px;display:flex;align-items:center;}
.kickoff-card:hover .kickoff-card-del{opacity:1;}
.kickoff-card-del:hover{color:var(--red);}
.kickoff-card-title{font-weight:700;font-size:14px;color:var(--text);line-height:1.4;}
.kickoff-doc-ref-small,.kickoff-proj-ref{display:flex;align-items:center;gap:5px;font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.kickoff-card-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:auto;}
.kickoff-card-meta{font-size:11px;color:var(--muted);font-family:var(--mono);}
.kickoff-card-date{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--muted);font-family:var(--mono);}

/* Kickoff modal doc ref */
.kickoff-doc-ref{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--bg-hover);border-radius:var(--r-md);border:1px solid var(--border);margin-bottom:16px;font-size:13px;color:var(--text);font-weight:500;}

/* Kickoff detail modal */
.kickoff-detail-badges{display:flex;align-items:center;gap:8px;margin-bottom:14px;}
.kickoff-detail-desc{font-size:14px;color:var(--text-2);line-height:1.6;margin-bottom:14px;}
.kickoff-detail-grid{display:flex;flex-direction:column;gap:8px;margin-bottom:14px;}
.kickoff-detail-row{display:flex;align-items:baseline;gap:10px;font-size:13.5px;}
.kickoff-detail-label{font-size:11.5px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.4px;min-width:100px;flex-shrink:0;}
.kickoff-doc-ref-badge{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--text);}
.kickoff-detail-notes{padding:12px 14px;background:var(--bg-hover);border-radius:var(--r-md);border:1px solid var(--border);}
.kickoff-detail-notes p{font-size:13.5px;color:var(--text-2);line-height:1.6;margin:4px 0 0;}

[data-theme="dark"] .kickoff-card{background:var(--card);border-color:var(--border);}
[data-theme="dark"] .kickoff-card:hover{border-color:var(--accent);background:rgba(165,180,252,.04);}
[data-theme="dark"] .kickoff-doc-ref{background:var(--bg-input);border-color:var(--border);}
[data-theme="dark"] .kickoff-detail-notes{background:var(--bg-input);border-color:var(--border);}

/* Auto-linkified URLs inside user-entered text (descriptions, notes, comments…) */
.auto-link{color:var(--accent);text-decoration:underline;text-underline-offset:2px;word-break:break-all;}
.auto-link:hover{text-decoration:none;opacity:.85;}

/* ── Cmd+K button (topbar) ───────────────────────────────────────── */
#btnCmdK { border: 1px solid var(--border); border-radius: var(--radius-md, 8px); background: var(--card); color: var(--text); transition: background .15s; }
#btnCmdK:hover { background: var(--bg-hover); }
#btnCmdK .btn-label { font-feature-settings: "tnum"; }

/* ── Status badge intent fix: "Planning" no longer collides with "Critical" ─ */
/* "Planning" was yellow (same as Critical) — move to info/cyan. */
.badge.badge-planning,
.badge[data-status="Planning"],
.badge[data-status="planning"] {
  background: rgba(14,165,233,.12);
  color: var(--intent-info, #0ea5e9);
}

/* ── Empty state polish (used by window.renderEmptyState) ────────── */
.empty-state .btn { font-size: 13px; }
.empty-state[role="status"] { outline: none; }

/* ── Sub-tabs row: horizontal scroll on narrow viewports ─────────── */
@media (max-width: 768px) {
  .sub-tabs-bar { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .sub-tabs-row { white-space: nowrap; }
  .sub-tab { flex-shrink: 0; }
}

/* ══════════════════════════════════════════════════════════════════
   ── v3 EDITORIAL GLOBAL OVERRIDES (loads at end so cascade wins) ──
   ══════════════════════════════════════════════════════════════════ */

/* Use cream bg + Inter base on root */
html { background: var(--bg); }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Subtle scrollbar — editorial */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--radius-full);
  border: 2px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--muted); }
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }

/* Remove legacy heavy shadows on cards (border-first now) */
.card,
.chart-card,
.kpi-card {
  box-shadow: none !important;
}

/* Remove any backdrop-blur leftover */
.topbar,
.modal-overlay,
.dropdown,
.menu {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* Apply Inter to all inputs/selects/buttons baseline */
input, select, textarea, button {
  font-family: var(--font-body);
}

/* Heading defaults — Fraunces serif */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
}

/* Page title in topbar uses Fraunces */
#pageTitle {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 18px;
  letter-spacing: -0.015em;
}

/* A11y: keyboard focus ring for toggle switches (hidden checkbox + visible track span) */
input[role="switch"]:focus-visible + span {
  outline: 2px solid var(--brand, var(--accent));
  outline-offset: 2px;
  border-radius: 13px;
}

/* ===== /css/nexora-theme.css?v=2 ===== */
/* ═══════════════════════════════════════════════
   NEXORA THEME — Dark Mode Override Only
   Load AFTER app.css
   Light theme = original app.css (untouched)
   ═══════════════════════════════════════════════ */

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   DARK THEME — variable block moved to css/tokens.css
   (Consolidation Sprint / Day 4). This file now owns only
   component-scoped overrides (login card, topbar, inputs,
   cards, kanban, modal, etc.) which cannot live in a
   token file. Do NOT re-add `[data-theme="dark"] { --var:… }`
   here — canonical palette source is tokens.css.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

/* ── Dark: Loading ──────────────────────────── */
[data-theme="dark"] .loading { background: var(--bg) !important; color: var(--text) !important; }

/* ── Dark: Login ────────────────────────────── */
[data-theme="dark"] .login-card {
  background: rgba(22,22,31,0.85) !important;
  border: 1px solid rgba(255,255,255,0.06) !important;
  backdrop-filter: blur(40px) !important; -webkit-backdrop-filter: blur(40px) !important;
  box-shadow: var(--shadow-xl) !important;
}

[data-theme="dark"] .login-error { background: rgba(239,68,68,0.08) !important; border-color: rgba(239,68,68,0.25) !important; }
[data-theme="dark"] .demo-acc { background: var(--bg-input) !important; border-color: var(--border) !important; color: var(--text) !important; }
[data-theme="dark"] .demo-acc:hover { background: var(--accent-light) !important; border-color: var(--accent) !important; }

/* ── Dark: Topbar ─────────────────────────────
   Matches the light-mode glass recipe from v2/topbar.css: translucent
   surface + saturating blur, so both themes share the "floating" feel.
   No !important — v2/topbar.css uses color-mix() and can be overridden by
   normal cascade order (this file loads later). */
[data-theme="dark"] .topbar {
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom-color: var(--border);
}

/* ── Dark: Inputs ───────────────────────────── */
[data-theme="dark"] .form-input, [data-theme="dark"] .form-select,
[data-theme="dark"] .form-textarea, [data-theme="dark"] .assignee-tags,
[data-theme="dark"] .search-input, [data-theme="dark"] .filter-select,
[data-theme="dark"] .chat-input, [data-theme="dark"] .kb-search,
[data-theme="dark"] .kb-custom-select-btn, [data-theme="dark"] .kb-content-textarea,
[data-theme="dark"] .kb-transcript-lines, [data-theme="dark"] .kb-summary-content,
[data-theme="dark"] .doc-editor-status-select {
  background: var(--bg-input) !important; border-color: var(--border) !important; color: var(--text) !important;
}

[data-theme="dark"] .form-input:focus, [data-theme="dark"] .form-select:focus,
[data-theme="dark"] .form-textarea:focus, [data-theme="dark"] .assignee-tags:focus-within,
[data-theme="dark"] .chat-input:focus, [data-theme="dark"] .kb-search:focus {
  background: var(--surface) !important; border-color: var(--accent) !important; box-shadow: 0 0 0 3px rgba(129,140,248,.12) !important;
}

[data-theme="dark"] .form-select option, [data-theme="dark"] .filter-select option { background: var(--card) !important; color: var(--text) !important; }

/* ── Dark: Cards ────────────────────────────── */
[data-theme="dark"] .kpi-card, [data-theme="dark"] .chart-card,
[data-theme="dark"] .team-card, [data-theme="dark"] .eval-card,
[data-theme="dark"] .profile-card, [data-theme="dark"] .avail-kpi,
[data-theme="dark"] .suggest-card, [data-theme="dark"] .timeline-card,
[data-theme="dark"] .api-key-card, [data-theme="dark"] .tree-project-block {
  background: var(--card) !important; border-color: var(--border) !important;
}

[data-theme="dark"] .strip-item { background: var(--card) !important; }

/* ── Dark: Tables ───────────────────────────── */
[data-theme="dark"] .table-wrap { background: var(--card) !important; border-color: var(--border) !important; }
[data-theme="dark"] thead th { background: rgba(255,255,255,0.03) !important; }
[data-theme="dark"] tbody tr:hover td { background: rgba(255,255,255,0.03) !important; }

/* ── Dark: Kanban ───────────────────────────── */
[data-theme="dark"] .kanban-project-card, [data-theme="dark"] .gantt-project-card { background: linear-gradient(135deg, rgba(129,140,248,0.06), rgba(34,211,238,0.04)) !important; border-color: var(--border) !important; }
[data-theme="dark"] .kanban-cols, [data-theme="dark"] .gantt-wrap { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .kanban-col { background: rgba(255,255,255,0.02) !important; border-color: var(--border) !important; }
[data-theme="dark"] .kanban-count { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .task-card { background: var(--card) !important; border-color: var(--border) !important; }
[data-theme="dark"] .task-card:hover { border-color: rgba(129,140,248,0.25) !important; }
[data-theme="dark"] .task-card.task-card-overdue { border-color: rgba(252,165,165,0.35) !important; background: linear-gradient(135deg, rgba(252,165,165,0.06), var(--card)) !important; }
[data-theme="dark"] .kanban-progress-bar, [data-theme="dark"] .gantt-progress-bar,
[data-theme="dark"] .tree-progress-bar, [data-theme="dark"] .import-progress-bar,
[data-theme="dark"] .cat-bar-track { background: rgba(255,255,255,0.06) !important; }
[data-theme="dark"] .kd-clone { background: var(--card) !important; border-color: var(--border) !important; }

/* ── Dark: Modal / Drawer ───────────────────── */
[data-theme="dark"] .modal, [data-theme="dark"] .confirm-box { background: var(--card) !important; border: 1px solid var(--border) !important; }
[data-theme="dark"] .drawer { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .assignee-dropdown { background: var(--card) !important; border-color: var(--accent) !important; }
[data-theme="dark"] .assignee-dropdown-item:hover { background: rgba(129,140,248,0.08) !important; }
[data-theme="dark"] .assignee-dropdown-item.selected { background: rgba(196,181,253,0.10) !important; color: #c4b5fd !important; }
[data-theme="dark"] .type-tab { background: var(--bg-input) !important; border-color: var(--border) !important; color: var(--muted) !important; }

/* ── Dark: Toast ────────────────────────────── */
[data-theme="dark"] .toast { background: var(--card) !important; border-color: var(--border) !important; color: var(--text) !important; }
[data-theme="dark"] .toast.success { background: rgba(74,222,128,0.08) !important; border-color: rgba(74,222,128,0.25) !important; color: #4ade80 !important; }
[data-theme="dark"] .toast.error { background: rgba(252,165,165,0.08) !important; border-color: rgba(252,165,165,0.25) !important; color: #fca5a5 !important; }

/* ── Dark: Tabs ─────────────────────────────── */
[data-theme="dark"] .tab-btn.tab-active { background: var(--card) !important; color: var(--text) !important; }

/* ── Dark: Badges ───────────────────────────── */
[data-theme="dark"] .badge-green  { background: rgba(74,222,128,0.10) !important;  color: #4ade80 !important; }
[data-theme="dark"] .badge-blue   { background: rgba(96,165,250,0.10) !important;  color: #60a5fa !important; }
[data-theme="dark"] .badge-yellow { background: rgba(253,230,138,0.08) !important; color: #fde68a !important; }
[data-theme="dark"] .badge-red    { background: rgba(252,165,165,0.08) !important; color: #fca5a5 !important; }
[data-theme="dark"] .badge-purple { background: rgba(196,181,253,0.08) !important; color: #c4b5fd !important; }
[data-theme="dark"] .badge-gray   { background: rgba(255,255,255,0.06) !important; color: var(--muted) !important; }
[data-theme="dark"] .badge-teal   { background: rgba(94,234,212,0.08) !important;  color: #5eead4 !important; }
[data-theme="dark"] .badge-orange { background: rgba(253,186,116,0.08) !important; color: #fdba74 !important; }

/* ── Dark: Score / Activity / File ──────────── */
[data-theme="dark"] .score-pill.s1 { background: rgba(252,165,165,0.08) !important; color: #fca5a5 !important; }
[data-theme="dark"] .score-pill.s2 { background: rgba(253,186,116,0.08) !important; color: #fdba74 !important; }
[data-theme="dark"] .score-pill.s3 { background: rgba(253,230,138,0.08) !important; color: #fde68a !important; }
[data-theme="dark"] .score-pill.s4 { background: rgba(96,165,250,0.10) !important; color: #60a5fa !important; }
[data-theme="dark"] .score-pill.s5 { background: rgba(74,222,128,0.10) !important; color: #4ade80 !important; }
[data-theme="dark"] .score-btn { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .score-btn.selected { background: rgba(253,230,138,0.08) !important; color: #fde68a !important; }
[data-theme="dark"] .activity-icon.created { background: rgba(96,165,250,0.10) !important; color: #60a5fa !important; }
[data-theme="dark"] .activity-icon.updated { background: rgba(253,230,138,0.08) !important; color: #fde68a !important; }
[data-theme="dark"] .activity-icon.status  { background: rgba(74,222,128,0.10) !important; color: #4ade80 !important; }
[data-theme="dark"] .activity-icon.comment { background: rgba(196,181,253,0.08) !important; color: #c4b5fd !important; }
[data-theme="dark"] .activity-icon.deleted { background: rgba(252,165,165,0.08) !important; color: #fca5a5 !important; }
[data-theme="dark"] .file-ext-badge.pdf   { background: rgba(252,165,165,0.08) !important; color: #fca5a5 !important; }
[data-theme="dark"] .file-ext-badge.image { background: rgba(253,230,138,0.08) !important; color: #fde68a !important; }
[data-theme="dark"] .file-ext-badge.text  { background: rgba(96,165,250,0.10) !important; color: #60a5fa !important; }

/* ── Dark: Tags / Chips ─────────────────────── */
[data-theme="dark"] .assignee-tag { background: rgba(196,181,253,0.10) !important; color: #c4b5fd !important; border-color: rgba(196,181,253,0.2) !important; }
[data-theme="dark"] .type-badge.epic { background: rgba(196,181,253,0.10) !important; color: #c4b5fd !important; border-color: rgba(196,181,253,0.2) !important; }
[data-theme="dark"] .type-badge.task { background: rgba(96,165,250,0.10) !important; color: #60a5fa !important; border-color: rgba(96,165,250,0.2) !important; }
[data-theme="dark"] .person-chip.pm  { background: rgba(196,181,253,0.08) !important; color: #c4b5fd !important; border-color: rgba(196,181,253,0.15) !important; }
[data-theme="dark"] .person-chip.pmo { background: rgba(94,234,212,0.08) !important; color: #5eead4 !important; border-color: rgba(94,234,212,0.15) !important; }
[data-theme="dark"] .role-pill.manager { color: #c4b5fd !important; }
[data-theme="dark"] .role-pill.pm { background: rgba(96,165,250,0.10) !important; color: #60a5fa !important; }
[data-theme="dark"] .rqp.rqp-pm { background: rgba(96,165,250,0.06) !important; border-color: rgba(96,165,250,0.15) !important; color: #60a5fa !important; }
[data-theme="dark"] .obstacle-box { background: rgba(252,165,165,0.06) !important; border-color: rgba(252,165,165,0.15) !important; color: #fca5a5 !important; }
[data-theme="dark"] .solution-box { background: rgba(74,222,128,0.06) !important; border-color: rgba(74,222,128,0.15) !important; color: #4ade80 !important; }

/* ── Dark: AI Chat ──────────────────────────── */
[data-theme="dark"] .ai-panel, [data-theme="dark"] .ai-history-item, [data-theme="dark"] .ai-prompt-item { background: var(--card) !important; border-color: var(--border) !important; }
[data-theme="dark"] .ai-header { background: linear-gradient(90deg, var(--surface), var(--bg)) !important; }
[data-theme="dark"] .ai-sub-header, [data-theme="dark"] .quick-prompts { background: var(--surface) !important; }
[data-theme="dark"] .chat-messages { background: var(--bg) !important; }
[data-theme="dark"] .chat-input-row { background: var(--surface) !important; border-color: var(--border) !important; }
[data-theme="dark"] .msg-bubble { background: var(--card) !important; border-color: var(--border) !important; color: var(--text) !important; }
[data-theme="dark"] .msg.user .msg-bubble { background: linear-gradient(135deg, rgba(129,140,248,0.15), rgba(129,140,248,0.08)) !important; border-color: rgba(129,140,248,0.25) !important; color: var(--text) !important; }
[data-theme="dark"] .msg-bubble.error-bubble { background: rgba(252,165,165,0.06) !important; border-color: rgba(252,165,165,0.2) !important; }
[data-theme="dark"] .msg-avatar { background: linear-gradient(135deg, rgba(129,140,248,0.12), rgba(129,140,248,0.06)) !important; border-color: rgba(129,140,248,0.2) !important; }
[data-theme="dark"] .msg.user .msg-avatar { background: linear-gradient(135deg, rgba(34,211,238,0.12), rgba(34,211,238,0.06)) !important; border-color: rgba(34,211,238,0.2) !important; }
[data-theme="dark"] .qp { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .ai-history-item-del, [data-theme="dark"] .ai-prompt-edit, [data-theme="dark"] .ai-prompt-del { background: var(--bg-input) !important; }
[data-theme="dark"] .upload-zone, [data-theme="dark"] .proj-file-zone { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .upload-zone:hover, [data-theme="dark"] .proj-file-zone:hover { background: rgba(129,140,248,0.06) !important; border-color: var(--accent) !important; }
[data-theme="dark"] .upload-zone.has-file, [data-theme="dark"] .proj-file-zone.has-file { background: rgba(74,222,128,0.06) !important; border-color: rgba(74,222,128,0.2) !important; }
[data-theme="dark"] .upload-zone-wrap { background: var(--surface) !important; }
[data-theme="dark"] .upload-zone-icon { background: rgba(196,181,253,0.08) !important; }
[data-theme="dark"] .upload-clear { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .upload-clear:hover { border-color: rgba(252,165,165,0.4) !important; color: #fca5a5 !important; background: rgba(252,165,165,0.06) !important; }
[data-theme="dark"] .proj-file-chip { background: var(--bg-input) !important; }
[data-theme="dark"] .error-detail { background: var(--card) !important; }

/* ── Dark: Gantt / Avail / Misc ─────────────── */
[data-theme="dark"] .gantt-header-row, [data-theme="dark"] .gantt-header-row th { background: rgba(255,255,255,0.03) !important; }
[data-theme="dark"] .gantt-label-epic { color: #c4b5fd !important; }
[data-theme="dark"] .avail-timeline-wrap { background: var(--card) !important; border-color: var(--border) !important; }
[data-theme="dark"] .avail-member-row:hover, [data-theme="dark"] .avail-date-header { background: rgba(255,255,255,0.03) !important; }
[data-theme="dark"] .skill-chip { border-color: rgba(56,189,248,0.15) !important; }
[data-theme="dark"] .skill-filter-btn { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .pagination { background: var(--surface) !important; }
[data-theme="dark"] .pg-btn { background: var(--bg-input) !important; border-color: var(--border) !important; color: var(--muted) !important; }
[data-theme="dark"] .pg-btn:hover { border-color: var(--accent) !important; color: var(--accent) !important; }
[data-theme="dark"] .pg-size { background: var(--bg-input) !important; border-color: var(--border) !important; color: var(--text) !important; }
[data-theme="dark"] .tree-task, [data-theme="dark"] .tree-task-standalone { background: var(--card) !important; border-color: var(--border) !important; }
[data-theme="dark"] .tree-task:hover { background: rgba(255,255,255,0.03) !important; }
[data-theme="dark"] .tree-subtask { background: var(--surface) !important; }
[data-theme="dark"] .tree-subtask:hover { background: rgba(255,255,255,0.03) !important; }
[data-theme="dark"] .tree-project-stats { background: var(--surface) !important; }
[data-theme="dark"] .dl-btn { background: var(--bg-input) !important; border-color: var(--border) !important; }
[data-theme="dark"] .appraisal-summary { background: linear-gradient(135deg, var(--surface), var(--card)) !important; }
[data-theme="dark"] .mini-task-item:hover, [data-theme="dark"] .member-task-row:hover { background: rgba(129,140,248,0.06) !important; }
[data-theme="dark"] .doc-prompts { background: linear-gradient(90deg, rgba(129,140,248,0.06), rgba(34,211,238,0.04)) !important; }
[data-theme="dark"] .kb-graph-tooltip { background: rgba(22,22,31,0.95) !important; border-color: var(--border) !important; }
[data-theme="dark"] .kb-graph-tooltip .tt-title { color: var(--text) !important; }
[data-theme="dark"] .kb-graph-tooltip .tt-preview { color: var(--text-2) !important; }
[data-theme="dark"] .star.off { color: rgba(255,255,255,0.1) !important; }
[data-theme="dark"] .progress-track, [data-theme="dark"] .progress-track-sm { background: rgba(255,255,255,0.06) !important; }
[data-theme="dark"] #typeTab-Epic.active { background: #8b5cf6 !important; border-color: #8b5cf6 !important; }

/* Dark sidebar now driven by CSS vars (--sidebar-bg, --sidebar-border, --text, --muted).
   Only minimal tweaks remain — scrollbar + icon glow. */
[data-theme="dark"] .sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); }
[data-theme="dark"] .logo-icon { box-shadow: 0 4px 14px rgba(99,102,241,0.35); }

/* ── Dark: Scrollbars ───────────────────────── */
[data-theme="dark"] ::-webkit-scrollbar { width: 6px; height: 6px; }
[data-theme="dark"] ::-webkit-scrollbar-track { background: transparent; }
[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.14); }

/* ===== /css/a11y.css?v=2 ===== */
/* ============================================================
   a11y.css - Accessibility overrides for Nexora
   Loaded AFTER app.css. Do not edit app.css; this file wins
   by source order and (where needed) targeted specificity.
   ============================================================ */


/* ------------------------------------------------------------
   1. Contrast: bump --muted-light so small text meets WCAG AA
   ------------------------------------------------------------
   app.css uses --muted-light for hints, placeholders, empty
   states, etc. The defaults (var(--text-muted) light / var(--text-muted) dark)
   fail AA on the surface colors. Override globally — the
   token is only used for ancillary muted text.
   ------------------------------------------------------------ */
:root {
  --muted-light: #52525b; /* AA on #fafafa / #ffffff backgrounds */
}

html[data-theme="dark"] {
  --muted-light: #a1a1aa; /* AA on #0a0a0a / #18181b backgrounds */
}

/* Native placeholders inherit color reliably across browsers */
::placeholder { color: var(--muted-light); opacity: 1; }
::-webkit-input-placeholder { color: var(--muted-light); }
::-moz-placeholder { color: var(--muted-light); opacity: 1; }


/* ------------------------------------------------------------
   2. Reduced motion: honour prefers-reduced-motion
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Kill the press-down on buttons */
  .btn:active { transform: none !important; }

  /* Kill slide-in keyframes on chat msgs, toasts, modals */
  .aiw-msg,
  .toast,
  .modal,
  .modal-overlay {
    animation: none !important;
    transform: none !important;
  }
}


/* ------------------------------------------------------------
   3. Focus ring
   ------------------------------------------------------------
   MIGRATED (Consolidation Sprint / Day 6): the focus ring is
   now the unified halo in v3/a11y_fixes.css, driven by the
   `--ring-*` tokens declared in tokens.css. Component overrides
   redefine `--ring-color` locally (e.g. .btn-danger). This file
   no longer defines any `:focus-visible` rule to avoid
   competing with the unified halo.
   ------------------------------------------------------------ */


/* ------------------------------------------------------------
   4. Skip-to-content link
   ------------------------------------------------------------
   MIGRATED (Consolidation Sprint / Day 7): the v2 skip-link
   definition was superseded by the stronger v3/a11y_fixes.css
   version (z-index 99999, brand-tone background, stronger
   focus reveal). This file no longer defines .skip-link.
   ------------------------------------------------------------ */


/* ------------------------------------------------------------
   5. role="button" affordances on div-buttons
   ------------------------------------------------------------ */
[role="button"] { cursor: pointer; }
/* :focus-visible ring inherited from the unified halo in
   v3/a11y_fixes.css — no per-role override needed. */


/* ------------------------------------------------------------
   6. Disabled state: clearer + still allows tooltip on hover
   ------------------------------------------------------------ */
.btn:disabled,
.form-input:disabled,
.form-select:disabled,
.form-textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: auto; /* let tooltips/titles still fire */
}


/* ------------------------------------------------------------
   7. Touch targets: 44px min on coarse pointers (mobile)
   ------------------------------------------------------------ */
@media (pointer: coarse) {
  .btn        { min-height: 44px; }
  .btn-sm     { min-height: 36px; }
  .nav-item   { min-height: 44px; }
  .form-input,
  .form-select { min-height: 44px; }
}


/* ------------------------------------------------------------
   8. High-contrast mode (prefers-contrast: more)
   ------------------------------------------------------------ */
@media (prefers-contrast: more) {
  :root {
    --border: #000;
    --muted: #333;
  }
  html[data-theme="dark"] {
    --border: #fff;
    --muted: #ddd;
  }
}


/* ------------------------------------------------------------
   9. Screen-reader-only utility
   ------------------------------------------------------------ */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* ------------------------------------------------------------
   10. Modal stacking: ensure overlay sits above all content
   ------------------------------------------------------------ */
.modal-overlay:not([aria-hidden="true"]) {
  z-index: 9000;
}


/* ------------------------------------------------------------
   11. Always-visible scrollbars (macOS overlay-scrollbar fix)
   ------------------------------------------------------------ */
.kanban,
.table-wrap,
.content {
  scrollbar-width: thin;
  scrollbar-color: var(--muted-light) transparent;
}

.kanban::-webkit-scrollbar,
.table-wrap::-webkit-scrollbar,
.content::-webkit-scrollbar {
  height: 8px;
  width: 8px;
}

.kanban::-webkit-scrollbar-thumb,
.table-wrap::-webkit-scrollbar-thumb,
.content::-webkit-scrollbar-thumb {
  background: var(--muted-light);
  border-radius: 4px;
}

.kanban::-webkit-scrollbar-track,
.table-wrap::-webkit-scrollbar-track,
.content::-webkit-scrollbar-track {
  background: transparent;
}

/* ===== /css/mobile.css?v=5 ===== */
/* ============================================================
   mobile.css — Responsive refinements layered on top of app.css
   Breakpoints: 1280 / 900 / 600 / 400  (consolidated from 8 → 4)
   Mobile-first where it helps; max-width queries where shrinking.
   ============================================================ */

/* ---------- Global touch / safe-area defaults ---------- */
:root {
  --safe-top: env(safe-area-inset-top);
  --safe-bottom: env(safe-area-inset-bottom);
}

html {
  -webkit-text-size-adjust: 100%;
}

/* Hide scrollbars on horizontally-scrollable mobile strips */
.topbar,
.sub-tabs,
.kanban-cols {
  scrollbar-width: none;
}
.topbar::-webkit-scrollbar,
.sub-tabs::-webkit-scrollbar,
.kanban-cols::-webkit-scrollbar {
  display: none;
}

/* ============================================================
   Bottom nav (styled here, displayed only on mobile)
   ============================================================ */
.bottom-nav {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: var(--card);
  border-top: 1px solid var(--border);
  padding: 6px env(safe-area-inset-right)
    calc(6px + env(safe-area-inset-bottom)) env(safe-area-inset-left);
  justify-content: space-around;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.04);
}
.bottom-nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 4px;
  font-size: 10px;
  color: var(--muted);
  cursor: pointer;
  background: transparent;
  border: none;
  min-height: 48px;
  font-weight: 500;
  transition: color 0.15s ease;
}
.bottom-nav-item:hover {
  color: var(--text-2);
}
.bottom-nav-item.active {
  color: var(--accent);
}
.bottom-nav-item svg {
  width: 20px;
  height: 20px;
}

/* ============================================================
   Sub-tabs: horizontally scrollable with snap
   ============================================================ */
.sub-tabs {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.sub-tab {
  scroll-snap-align: start;
  flex-shrink: 0;
}

/* ============================================================
   ≤1280px — tighten dashboard grids a notch
   ============================================================ */
@media (max-width: 1280px) {
  .dash-grid-70-30 {
    grid-template-columns: 65% 35%;
  }
  .content {
    padding: 16px;
  }
}

/* ============================================================
   ≤900px — tablet & phone landscape consolidated.
   Merged in: former 1024 (tablet stacking), 768 (topbar/KPIs/tables),
   plus the global horizontal-overflow safety net and sidebar drawer.
   Where 768 and 1024 disagreed (KPIs, summary-strip), the
   lower breakpoint wins — i.e. the 768 values are kept.
   ============================================================ */
@media (max-width: 900px) {
  /* Global safety nets — prevent stray horizontal scrolling */
  html, body { overflow-x: hidden; }
  .main { overflow-x: hidden; max-width: 100vw; }
  .content { max-width: 100%; }
  .page-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    max-width: 60vw;
  }

  /* Dashboard grids stack (from former ≤1024) */
  .dash-grid-70-30,
  .dash-grid-2,
  .dash-grid-3 {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  /* KPI: 2 cols (former ≤768 wins over ≤1024's 3-col) */
  .kpi-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  /* Summary strip: 2 cols (former ≤768 wins over ≤1024's 3-col) */
  .summary-strip {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Sidebar becomes off-canvas drawer */
  .sidebar {
    position: fixed;
    left: -100%;
    top: 0;
    bottom: 0;
    width: 280px;
    z-index: 100;
    transition: left 0.25s ease;
    overflow-y: auto;
  }
  body.sidebar-open .sidebar {
    left: 0;
    box-shadow: var(--shadow-xl);
  }
  body.sidebar-open::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 99;
  }
  body.sidebar-open {
    overflow: hidden;
  }
  .main {
    margin-left: 0;
    width: 100%;
  }
  .sidebar-toggle {
    display: inline-flex !important;
  }

  /* Kanban: 4 status columns with horizontal scroll.
     240px min so cards stay readable (former ≤900 wins over
     ≤1024's 220px). User swipes to reach Done/Review on phone. */
  .kanban-cols {
    grid-template-columns: repeat(4, minmax(240px, 1fr));
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 12px;
  }

  /* Topbar: compact, horizontally scrollable for actions (from former ≤768) */
  .topbar {
    padding: 0 12px;
    padding-top: env(safe-area-inset-top);
    height: 52px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  .topbar-left,
  .topbar-right {
    flex-shrink: 0;
  }
  .topbar-date {
    display: none;
  }
  /* Icon-only buttons in topbar (collapse text labels) */
  .topbar .btn .btn-label,
  .topbar .btn-text {
    display: none;
  }
  .topbar .btn {
    padding: 0 10px;
  }

  /* Content padding tighter */
  .content {
    padding: 12px;
  }

  /* Bottom nav appears, main gets bottom padding for it */
  .bottom-nav {
    display: flex;
  }
  .main {
    padding-bottom: 64px;
  }

  /* Chart cards: trim inner padding so they don't waste screen space */
  .chart-card {
    padding: 16px;
  }
  /* Section-title gap from previous chart was tuned for desktop */
  .section-title {
    margin-top: 4px;
  }

  /* Tables scroll cleanly inside their wrap (from former ≤768) */
  .table-wrap {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  .table-wrap > table {
    /* Natural width so columns stay readable; wrap handles overflow */
    width: max-content;
    min-width: 100%;
  }
  .table-wrap thead th,
  .table-wrap tbody td {
    padding: 10px 12px;
    font-size: 12.5px;
    white-space: nowrap;
  }
  /* Pagination strip below tables should never push the page wide */
  [id$="Pagination"] {
    flex-wrap: wrap;
    gap: 6px;
    font-size: 12px;
  }

  /* Bottom-nav: ensure it doesn't overlap modal bottom action bar
     (from former ≤768) */
  body.modal-open .bottom-nav {
    display: none;
  }
}

/* ============================================================
   ≤600px — phone portrait: kanban carousel, modal full.
   Merged in: former 700 (KPI tighter) and 520 (single-col KPIs,
   tighter typography). 520's rules win where they conflict with
   600's, since 520 was the lower (more specific) breakpoint.
   ============================================================ */
@media (max-width: 600px) {
  /* KPI: tighter at phone portrait (from former ≤700, then ≤520
     forces single column with !important to override app.css). */
  .kpi-grid {
    grid-template-columns: 1fr !important;
    gap: 8px;
  }
  .kpi-card {
    padding: 12px;
  }
  /* Summary strip: 1 col (from former ≤520) */
  .summary-strip {
    grid-template-columns: 1fr;
  }
  .topbar .topbar-title,
  .topbar h1,
  .page-title {
    font-size: 15px;
  }
  .content {
    padding: 10px;
  }

  /* Opt-in "card mode" for tables tagged .table-stack — kept as escape
     hatch for tables that carry data-label attrs on every <td>. */
  .table-stack,
  .table-stack thead,
  .table-stack tbody,
  .table-stack tr,
  .table-stack th,
  .table-stack td {
    display: block;
    width: 100%;
  }
  .table-stack thead {
    display: none;
  }
  .table-stack tr {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 10px 12px;
    margin-bottom: 10px;
    box-shadow: var(--shadow-xs);
  }
  .table-stack td {
    border: none;
    padding: 4px 0;
    text-align: left;
    white-space: normal;
  }
  .table-stack td::before {
    content: attr(data-label) ':';
    font-weight: 600;
    color: var(--muted);
    margin-right: 8px;
  }
  .table-stack td:empty,
  .table-stack td[data-label='']::before {
    display: none;
  }

  /* Kanban: horizontal swipeable carousel */
  .kanban-cols {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 10px;
    padding-bottom: 8px;
  }
  .kanban-col {
    min-width: 85vw;
    scroll-snap-align: start;
    flex-shrink: 0;
  }
  /* Optional column-dots indicator (CSS-only stub) */
  .kanban-dots {
    display: flex;
    justify-content: center;
    gap: 6px;
    margin-top: 6px;
  }
  .kanban-dots span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--border);
  }
  .kanban-dots span.active {
    background: var(--accent);
  }

  /* Modal: full-screen sheet.
     iOS Safari's URL bar makes plain 100vh extend past the visible area, so
     the bottom action buttons get pushed off-screen and the inner scroll
     can't reach them. Use 100dvh (with vh fallback) and reserve room for
     safe-area-inset-bottom. Action bar is sticky so Save stays reachable
     regardless of how far the user has scrolled. */
  .modal-overlay {
    padding: 0;
    align-items: stretch;
  }
  .modal {
    max-width: 100vw !important;
    width: 100vw;
    height: 100vh;
    max-height: 100vh;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    padding: 16px;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .modal-header {
    position: sticky;
    top: 0;
    background: var(--card);
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
    z-index: 1;
  }
  .modal-footer,
  .modal-actions {
    position: sticky;
    bottom: 0;
    background: var(--card);
    padding: 12px 0;
    border-top: 1px solid var(--border);
    margin-top: auto;
    flex-shrink: 0;
    z-index: 2;
  }

  /* Filter toolbars wrap full-width */
  .toolbar {
    flex-wrap: wrap;
    gap: 8px;
  }
  .toolbar .search-box,
  .search-box {
    width: 100%;
    max-width: none;
    flex: 1 1 100%;
  }
  /* Toolbar selects: one full row each (from former ≤520 — wins
     over ≤600's 50% rule since 520 was the lower breakpoint). */
  .toolbar .filter-select,
  .filter-select {
    flex: 1 1 100%;
    min-width: 0;
  }
  /* Result-count pill wraps to its own line gracefully (from former ≤520) */
  .result-count {
    flex: 1 1 100%;
  }

  /* Form rows collapse to single column */
  .form-row {
    grid-template-columns: 1fr !important;
    gap: 10px;
  }

  /* Sub-tab strip: scroll-snap on phones for sticky-but-scrollable nav */
  .sub-tabs-bar { scroll-snap-type: x mandatory; padding-bottom: 4px; }
  .sub-tab { scroll-snap-align: start; min-height: 40px; padding: 8px 14px; }
  .sub-tab-active { box-shadow: inset 0 -2px 0 var(--accent); }

  /* Topbar Cmd+K: hide the "⌘K" hint label on phones (icon only) */
  #btnCmdK .btn-label { display: none; }
}

/* ============================================================
   ≤400px — tiny phones / foldables closed: extra compaction
   ============================================================ */
@media (max-width: 400px) {
  .content {
    padding: 8px;
  }
  .modal {
    padding: 12px;
  }
  .btn {
    padding: 0 10px;
  }
  .sidebar {
    width: 88vw;
  }
}

/* ============================================================
   Touch-friendly sizing for coarse pointers
   ============================================================ */
@media (pointer: coarse) {
  .btn-sm {
    min-height: 36px;
  }
  .btn {
    min-height: 44px;
  }
  a,
  button,
  [role='button'],
  .sub-tab,
  .filter-select,
  .bottom-nav-item {
    min-height: 44px;
  }
  input,
  select,
  textarea {
    min-height: 44px;
    font-size: 16px; /* prevent iOS auto-zoom on focus */
  }
}

/* ============================================================
   Reduced motion — kill the sidebar slide transition
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .sidebar {
    transition: none;
  }
}

/* ===== /css/print.css?v=1 ===== */
@media print {
  body {
    background: white !important;
    color: #000 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .sidebar,
  .topbar,
  .sub-tabs-bar,
  .bottom-nav,
  .skip-link,
  .toolbar,
  .kanban-controls,
  .nx-cmdpalette,
  .modal-overlay,
  .toast,
  .ai-widget-fab,
  .sv-menu,
  .exp-menu,
  .help-tooltip {
    display: none !important;
  }

  .main {
    margin-left: 0 !important;
    padding: 0 !important;
    width: 100% !important;
  }

  .content {
    padding: 0 !important;
  }

  .page {
    padding: 12mm !important;
    display: none;
  }

  .page.active {
    display: block !important;
  }

  .card,
  .kpi-card,
  .chart-card {
    break-inside: avoid;
    page-break-inside: avoid;
    box-shadow: none !important;
    border: 1px solid #ddd !important;
    background: white !important;
  }

  table {
    width: 100% !important;
    border-collapse: collapse !important;
    page-break-inside: auto;
  }

  thead {
    display: table-header-group;
  }

  tr {
    page-break-inside: avoid;
  }

  thead th {
    background: #f5f5f5 !important;
    color: #000 !important;
    border-bottom: 1px solid #999 !important;
  }

  td,
  th {
    padding: 6px 8px !important;
    font-size: 11px !important;
    border-bottom: 1px solid #eee !important;
    color: #000 !important;
  }

  a {
    color: inherit !important;
    text-decoration: none !important;
  }

  .badge,
  .pill {
    border: 1px solid #999 !important;
    padding: 1px 6px !important;
    background: transparent !important;
    color: #000 !important;
  }

  .print-header {
    display: block !important;
    margin-bottom: 16px;
    padding-bottom: 8px;
    border-bottom: 2px solid #000;
  }

  .print-header h1 {
    font-size: 18px;
    margin: 0;
    color: #000;
  }

  .print-header .meta {
    font-size: 11px;
    color: #555;
    margin-top: 4px;
  }

  @page {
    margin: 12mm 10mm;
    size: A4;
  }
}

/* ===== /css/polish.css?v=3 ===== */
/* ============================================================================
   polish.css — Nexora SaaS-grade polish layer
   Layered on top of app.css. Pure CSS, respects prefers-reduced-motion.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. Consistent kbd styling
   --------------------------------------------------------------------------- */
kbd, .kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  background: var(--bg-hover);
  color: var(--text-2);
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 5px;
  line-height: 1;
}
[data-theme="dark"] kbd,
[data-theme="dark"] .kbd {
  background: rgba(255, 255, 255, .06);
}

/* ---------------------------------------------------------------------------
   2. Help dot (info icon used by help.js)
   --------------------------------------------------------------------------- */
.help-dot,
button.help-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg-hover);
  color: var(--muted);
  border: none;
  padding: 0;
  cursor: help;
  font-size: 10px;
  font-weight: 700;
  margin-left: 6px;
  vertical-align: middle;
  line-height: 1;
  transition: background .15s, color .15s;
}
.help-dot:hover,
.help-dot:focus-visible {
  background: var(--accent-light);
  color: var(--accent);
  outline: none;
}

/* ---------------------------------------------------------------------------
   3. Consistent badge system
   --------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 99px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1.4;
  white-space: nowrap;
}
.badge-accent  { background: var(--accent-light);  color: var(--accent);  }
.badge-green   { background: var(--green-light);   color: var(--green);   }
.badge-yellow  { background: var(--yellow-light);  color: var(--yellow);  }
.badge-red     { background: var(--red-light);     color: var(--red);     }
.badge-purple  { background: var(--purple-light);  color: var(--purple);  }
.badge-muted   { background: var(--bg-hover);      color: var(--muted);   }
.badge-dot::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
   4. Menu dropdown system (saved_views, exporter, etc.)
   --------------------------------------------------------------------------- */
.nx-menu {
  position: absolute;
  min-width: 220px;
  max-width: 340px;
  padding: 4px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 90;
  animation: nxMenuPop .18s cubic-bezier(.16, 1, .3, 1) both;
  transform-origin: top left;
}
@keyframes nxMenuPop {
  from { opacity: 0; transform: translateY(-4px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
.nx-menu-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 13px;
  color: var(--text-2);
}
.nx-menu-item:hover,
.nx-menu-item:focus-visible {
  background: var(--bg-hover);
  color: var(--text);
  outline: none;
}
.nx-menu-item.active {
  background: var(--accent-light);
  color: var(--accent);
  font-weight: 600;
}
.nx-menu-item .kbd,
.nx-menu-item kbd {
  margin-left: auto;
}
.nx-menu-sep {
  height: 1px;
  background: var(--border-light);
  margin: 4px 0;
}
.nx-menu-section {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted-light);
  padding: 8px 12px 4px;
}
@media (prefers-reduced-motion: reduce) {
  .nx-menu { animation: none; }
}

/* ---------------------------------------------------------------------------
   5. Smoother card hover & focus
   --------------------------------------------------------------------------- */
/* Transition cheap properties only. Animating box-shadow triggers a paint
   on every frame and creates noticeable jank on pages with many cards
   (Today, Dashboard) — keep the visual change but apply it instantly. */
.card,
.kpi-card,
.chart-card {
  transition: transform .15s cubic-bezier(.16, 1, .3, 1),
              border-color .12s;
}
.card:hover { box-shadow: var(--shadow-md); }
.kpi-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}
[role="button"]:focus-visible,
.clickable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   6. Refined scrollbars
   --------------------------------------------------------------------------- */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 8px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--muted-light); }

/* ---------------------------------------------------------------------------
   7. Selection
   --------------------------------------------------------------------------- */
::selection {
  background: var(--accent-light);
  color: var(--accent-hover);
}

/* ---------------------------------------------------------------------------
   8. Entrance animations for new content
   --------------------------------------------------------------------------- */
@keyframes nxFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.nx-fade-in { animation: nxFadeIn .25s ease-out both; }

@keyframes nxSlideUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.nx-slide-up { animation: nxSlideUp .3s cubic-bezier(.16, 1, .3, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .nx-fade-in,
  .nx-slide-up { animation: none; }
}

/* ---------------------------------------------------------------------------
   9. Modal polish: entrance + scrim improvement
   --------------------------------------------------------------------------- */
.modal-overlay {
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.modal-overlay.open .modal,
.modal-overlay[style*="display: flex"] .modal,
.modal-overlay[style*="display:flex"] .modal {
  animation: nxModalPop .22s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes nxModalPop {
  from { opacity: 0; transform: translateY(8px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .modal-overlay.open .modal { animation: none; }
}

/* ---------------------------------------------------------------------------
   10. Toast polish (toast_undo.js)
   --------------------------------------------------------------------------- */
.nx-toast { animation: nxToastIn .28s cubic-bezier(.16, 1, .3, 1) both; }
.nx-toast.nx-toast-out { animation: nxToastOut .22s ease both; }
@keyframes nxToastIn  {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}
@keyframes nxToastOut {
  to { opacity: 0; transform: translateX(16px); }
}
@media (prefers-reduced-motion: reduce) {
  .nx-toast,
  .nx-toast.nx-toast-out { animation: none; }
}

/* ---------------------------------------------------------------------------
   11. Inline progress bars
   --------------------------------------------------------------------------- */
.nx-progress {
  width: 100%;
  height: 6px;
  background: var(--bg-hover);
  border-radius: 99px;
  overflow: hidden;
}
.nx-progress-bar {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
  transition: width .4s cubic-bezier(.16, 1, .3, 1);
}
.nx-progress.thin { height: 3px; }

/* ---------------------------------------------------------------------------
   12. Refined buttons (layer on existing .btn)
   --------------------------------------------------------------------------- */
.btn {
  transition: background .15s, box-shadow .15s, transform .08s, border-color .15s;
}
.btn:hover  { transform: translateY(-0.5px); }
.btn:active { transform: translateY(0); }
.btn-primary:hover { box-shadow: 0 4px 12px rgba(99, 102, 241, .28); }
.btn-success {
  background: var(--green);
  color: var(--surface);
  border: none;
}
.btn-success:hover { background: #047857; }
.btn-danger {
  background: var(--red);
  color: var(--surface);
  border: none;
}
.btn-danger:hover { background: #b91c1c; }
@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .btn:active { transform: none; }
}

/* ---------------------------------------------------------------------------
   13. Chip system (assignee/tag chips)
   --------------------------------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px 2px 4px;
  border-radius: 99px;
  background: var(--bg-hover);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
}
.chip-avatar {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent-light);
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.chip-remove {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 0 2px;
  font-size: 14px;
  line-height: 1;
}
.chip-remove:hover { color: var(--red); }

/* ---------------------------------------------------------------------------
   14. Tooltip polish (help.js)
   --------------------------------------------------------------------------- */
.help-tooltip {
  background: var(--text);
  color: var(--bg);
  font-size: 12px;
  line-height: 1.45;
  padding: 8px 11px;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
  max-width: 280px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(2px);
  transition: opacity .15s, transform .15s;
}
.help-tooltip.show {
  opacity: 1;
  transform: translateY(0);
}
.help-tooltip::after {
  content: '';
  position: absolute;
  bottom: -5px;
  left: 50%;
  margin-left: -5px;
  border: 5px solid transparent;
  border-top-color: var(--text);
  border-bottom: none;
}

/* ---------------------------------------------------------------------------
   15. Brand seam — intentionally skipped (sticky-in-flex can break layouts)
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   16. Dark mode tuning
   --------------------------------------------------------------------------- */
[data-theme="dark"] .modal-overlay {
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
[data-theme="dark"] .nx-menu {
  border-color: rgba(255, 255, 255, .08);
}
[data-theme="dark"] .badge-accent {
  background: rgba(165, 180, 252, .16);
}

/* ---------------------------------------------------------------------------
   17. Kanban polish — fix column wrap & horizontal-scroll affordance
   --------------------------------------------------------------------------- */
.kanban-cols {
  /* Always 4 status columns; let them scroll horizontally rather than wrap
     to a second row when the viewport is tight. Prevents the "messy" look
     where Done wraps under Backlog. */
  grid-auto-flow: column;
  scroll-snap-type: x proximity;
}
.kanban-cols > .kanban-col {
  scroll-snap-align: start;
  min-width: 240px;
}
/* Subtle edge fade when content overflows horizontally so users get a
   visual cue there's more to the right. */
.kanban-project-block {
  position: relative;
}
.kanban-project-block::after {
  content: '';
  position: absolute;
  right: 1px;
  top: 0;
  bottom: 0;
  width: 28px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--card) 80%);
  opacity: 0;
  transition: opacity .2s;
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
}
.kanban-cols::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}
.kanban-cols:hover::-webkit-scrollbar-thumb {
  background: var(--muted-light);
}
/* Make sure cards inside columns never push column wider than allocated. */
.kanban-col {
  min-width: 0;
}
.task-card {
  min-width: 0;
  max-width: 100%;
}
.task-card .task-title {
  word-break: break-word;
  overflow-wrap: anywhere;
}

/* ============================================================================
   Polish v4 — visual pass 2026-07 (login hero, KPI dedup, badge unify,
   empty states, card action hover-reveal). Added after design review.
   ============================================================================ */

/* ── Summary strip: from 5-col grid of duplicated stats to a
   tight breakdown-chip row (Planning / On Hold / Active Team).
   :has() lets us re-layout only when the new chip children exist,
   so any legacy caller still using .strip-item stays untouched. */
.summary-strip:has(.summary-chip) {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  background: transparent;
  border: none;
  padding: 0;
  border-radius: 0;
  overflow: visible;
  margin-bottom: 24px;
}
.summary-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-2);
  transition: border-color .15s, box-shadow .15s;
}
.summary-chip:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(0,0,0,.04));
}
.summary-chip-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.summary-chip-label {
  font-weight: 500;
  letter-spacing: .1px;
}
.summary-chip-val {
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.summary-chip-of {
  font-weight: 500;
  color: var(--muted);
}
[data-theme="dark"] .summary-chip {
  background: rgba(255,255,255,.03);
  border-color: var(--border);
}

/* ── Empty state variant: illustrated + CTA.
   Wrap element: <div class="empty-state empty-state-lg"> */
.empty-state-lg {
  padding: 56px 24px 60px;
  gap: 14px;
}
.empty-state-illus {
  width: 88px;
  height: 88px;
  border-radius: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--accent-light), var(--purple-light));
  color: var(--accent);
  box-shadow: 0 6px 24px rgba(99,102,241,.14);
  margin-bottom: 4px;
}
.empty-state-illus svg {
  width: 40px;
  height: 40px;
  stroke-width: 1.4;
}
.empty-state-lg .empty-state-title {
  font-size: 16px;
  color: var(--text);
  margin-bottom: 4px;
}
.empty-state-lg .empty-state-sub {
  max-width: 380px;
  color: var(--muted);
}
.empty-state-cta {
  margin-top: 12px;
}
[data-theme="dark"] .empty-state-illus {
  background: linear-gradient(135deg, rgba(99,102,241,.18), rgba(139,92,246,.18));
  box-shadow: 0 6px 24px rgba(0,0,0,.35);
}

/* Table empty row with illustrated body (Risk register) */
tr.empty-row-illus td {
  padding: 0 !important;
  background: transparent !important;
  border-bottom: none !important;
}
tr.empty-row-illus .empty-state-lg {
  padding: 48px 24px 52px;
}

/* Kanban column "No tasks" — dashed drop-zone with subtle icon */
.kanban-col-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 28px 12px;
  border: 1.5px dashed var(--border);
  border-radius: 10px;
  color: var(--muted);
  font-size: 12px;
  background: transparent;
  transition: border-color .15s, background .15s;
}
.kanban-col-empty svg {
  width: 22px;
  height: 22px;
  color: var(--muted-light);
  opacity: .7;
}
.kanban-col[data-col="Doing"] .kanban-col-empty:hover,
.kanban-col-empty:hover {
  border-color: var(--accent);
  color: var(--text-2);
  background: rgba(99,102,241,.03);
}
[data-theme="dark"] .kanban-col-empty {
  border-color: rgba(255,255,255,.09);
}
[data-theme="dark"] .kanban-col-empty:hover {
  background: rgba(99,102,241,.06);
}

/* ── Task-card action row: hover-reveal to reduce card noise.
   Full opacity on touch/coarse pointers so mobile users always see actions. */
@media (hover: hover) and (pointer: fine) {
  .task-card .task-actions {
    opacity: 0;
    transform: translateY(-2px);
    transition: opacity .18s ease, transform .18s ease;
    pointer-events: none;
  }
  .task-card:hover .task-actions,
  .task-card:focus-within .task-actions {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  /* Always show the primary "open details" action so cards still look tappable */
  .task-card .task-actions .nx-card-action:first-child {
    opacity: 1 !important;
    pointer-events: auto !important;
  }
}
@media (prefers-reduced-motion: reduce) {
  .task-card .task-actions {
    transition: opacity .01s;
    transform: none !important;
  }
}

/* ── LOGIN hero split + constellation background layer.
   Kicks in on ≥900px viewports; below that the existing centered card
   layout stays as-is (mobile-first).
   Purely additive: doesn't override existing .login-wrap / .login-card. */
.login-hero {
  display: none;
}
.constellation-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .55;
}
[data-theme="dark"] .constellation-bg {
  opacity: .8;
}
.constellation-bg .c-dot {
  fill: var(--accent);
}
.constellation-bg .c-line {
  stroke: var(--accent);
  stroke-width: 1;
  opacity: .35;
}
@media (min-width: 900px) {
  #loginScreen .login-shell {
    display: grid;
    grid-template-columns: 440px 440px;
    justify-items: stretch;
    gap: 64px;
    align-items: center;
    z-index: 1;
    position: relative;
  }
  #loginScreen .login-wrap {
    width: auto;
    max-width: none;
    margin: 0;
    justify-self: stretch;
  }
  .login-hero {
    display: block;
    width: 100%;
    color: var(--text);
    animation: fadeUp .55s cubic-bezier(.16,1,.3,1) both;
  }
  .login-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-light);
    padding: 5px 11px;
    border-radius: 999px;
    margin-bottom: 18px;
  }
  .login-hero-title {
    font-size: 40px;
    line-height: 1.08;
    letter-spacing: -.9px;
    font-weight: 700;
    color: var(--text);
    margin: 0 0 16px;
  }
  .login-hero-title em {
    font-style: normal;
    background: linear-gradient(135deg, var(--accent), var(--purple));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }
  .login-hero-sub {
    font-size: 15px;
    line-height: 1.6;
    color: var(--muted);
    max-width: 420px;
    margin: 0 0 26px;
  }
  .login-hero-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .login-hero-list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 13px;
    color: var(--text-2);
    line-height: 1.5;
  }
  .login-hero-list .check {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 6px;
    background: var(--green-light, rgba(16,185,129,.15));
    color: var(--green, #10b981);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
  }
  .login-hero-list .check svg {
    width: 12px;
    height: 12px;
    stroke-width: 2.5;
  }
  /* On split layout, brand block sits inside form column (compacted) */
  #loginScreen .login-brand {
    text-align: left;
    margin-bottom: 22px;
  }
  #loginScreen .login-brand .login-logo {
    margin: 0 0 12px;
  }
  #loginScreen .login-brand .login-title {
    font-size: 22px;
  }
}
[data-theme="dark"] .login-hero-eyebrow {
  background: rgba(99,102,241,.15);
}

/* ── Team card action row: hover-reveal (matches task card pattern).
   Kartu member sekarang punya edit/delete yang muncul saat hover, tidak
   berteriak di setiap card. Touch/coarse pointer tetap penuh. */
.team-card-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
  margin-left: 4px;
}
@media (hover: hover) and (pointer: fine) {
  .team-card .team-card-actions {
    opacity: 0;
    transition: opacity .18s ease;
  }
  .team-card:hover .team-card-actions,
  .team-card:focus-within .team-card-actions {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .team-card .team-card-actions {
    transition: none;
  }
}

/* ── Gantt: skeleton bar + Today pill + weekend polish
   makeBar() sudah emit .gantt-bar-skeleton untuk row tanpa tanggal.
   Ini memberinya visual "awaiting schedule" alih-alih baris kosong.  */
.gantt-bar-skeleton {
  background: repeating-linear-gradient(
    -45deg,
    rgba(148,163,184,.14) 0 6px,
    transparent 6px 12px
  );
  border-radius: 3px;
}
[data-theme="dark"] .gantt-bar-skeleton {
  background: repeating-linear-gradient(
    -45deg,
    rgba(148,163,184,.10) 0 6px,
    transparent 6px 12px
  );
}

/* ── Topbar date chip: proper "system stamp" component.
   Combines calendar icon + mono numerals in a subtle pill so it reads
   as an intentional timestamp badge, not orphan mono text. */
.topbar-date {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
  background: var(--bg);
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
  letter-spacing: .1px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  margin-right: 6px;
}
.topbar-date .topbar-date-icon {
  width: 12px;
  height: 12px;
  color: var(--muted);
  flex-shrink: 0;
}
.topbar-date .topbar-date-text {
  line-height: 1;
}
[data-theme="dark"] .topbar-date {
  background: rgba(255,255,255,.04);
  border-color: var(--border);
  color: var(--text-2);
}
[data-theme="dark"] .topbar-date .topbar-date-icon {
  color: var(--muted);
}

/* ===== /css/icon_standard.css?v=1 ===== */
/* ============================================================================
   icon_standard.css
   ----------------------------------------------------------------------------
   Canonical icon sizing system. Layered ON TOP of app.css to gradually
   standardize the ad-hoc `.icon-10` ... `.icon-30` zoo into a clean scale.

   STRATEGY:
     - Introduce a semantic xs/sm/md/lg/xl/2xl scale (additive).
     - Snap the noisiest legacy classes in the 10-15px range to canonical
       sizes via property override (visual polish without breaking markup).
     - Leave hero sizes (.icon-28, .icon-30) and the sidebar's .icon-17
       untouched — they are intentional.
   ============================================================================ */


/* ----------------------------------------------------------------------------
   1. CANONICAL SIZES (semantic scale)
   Use these on all new icons. Old numeric classes remain for back-compat.
   ---------------------------------------------------------------------------- */
.icon-xs  { width: 12px; height: 12px; }   /* metadata, badges, inline chips */
.icon-sm  { width: 14px; height: 14px; }   /* inline with body text         */
.icon-md  { width: 16px; height: 16px; }   /* default — buttons, list items */
.icon-lg  { width: 20px; height: 20px; }   /* section headers, KPI tiles    */
.icon-xl  { width: 24px; height: 24px; }   /* page-level prominence         */
.icon-2xl { width: 32px; height: 32px; }   /* hero, empty-state illustrations */


/* ----------------------------------------------------------------------------
   2. LEGACY SNAP-TO-GRID
   Quietly normalize odd sizes to the nearest canonical bucket.
   Higher specificity (.icon.icon-XX) so we win over app.css ordering.
   ---------------------------------------------------------------------------- */

/* 10-11 → xs (12px) */
.icon.icon-10,
.icon.icon-11 { width: 12px; height: 12px; }

/* 13 → sm (14px). 12 and 14 are already canonical. */
.icon.icon-13 { width: 14px; height: 14px; }

/* 15 → md (16px). 16 is already canonical. */
.icon.icon-15 { width: 16px; height: 16px; }

/* 21 → lg (20px). 20 is already canonical.
   22 left alone — intentionally used in KPI tiles. */
.icon.icon-21 { width: 20px; height: 20px; }

/* NOTE: .icon-17 (sidebar), .icon-22 (KPI), .icon-28, .icon-30 are deliberately
   NOT overridden — they are correct in their special contexts. */


/* ----------------------------------------------------------------------------
   3. UNIVERSAL SVG DEFAULTS
   Sensible defaults so icons sit nicely next to text without per-call CSS.
   ---------------------------------------------------------------------------- */
svg.icon,
svg[viewBox] {
  flex-shrink: 0;          /* never squish inside flex rows                 */
  vertical-align: middle;  /* align with adjacent text baseline-ish         */
}

svg.icon[stroke="currentColor"] {
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* ----------------------------------------------------------------------------
   4. STROKE WIDTH HINTS
   Most SVGs set stroke-width as an attribute, so this only applies where
   the SVG honors CSS. Smaller icons get a slightly heavier stroke for
   legibility; larger icons get a finer stroke for elegance.
   ---------------------------------------------------------------------------- */
.icon-xs,
.icon-sm,
.icon-md,
.icon-lg  { stroke-width: 1.75; }

.icon-xl,
.icon-2xl { stroke-width: 1.5; }


/* ----------------------------------------------------------------------------
   5. COLOR DEFAULTS
   Most SVGs already set stroke="currentColor" fill="none" inline.
   This is a safety net for ones that don't.
   ---------------------------------------------------------------------------- */
svg.icon:not([fill]) { fill: none; }
svg.icon:not([stroke]) { stroke: currentColor; }


/* ----------------------------------------------------------------------------
   6. MIGRATION HINT (commented)
   Recommended mapping when refactoring markup over time:
     .icon-10 / .icon-11           → .icon-xs
     .icon-12 / .icon-13 / .icon-14 → .icon-sm
     .icon-15 / .icon-16           → .icon-md
     .icon-20 / .icon-21           → .icon-lg
     .icon-22                      → keep (KPI), or .icon-lg
     .icon-17                      → keep (sidebar)
     .icon-28 / .icon-30           → keep (hero) or .icon-2xl
   ---------------------------------------------------------------------------- */

/* ===== /css/color_audit.css?v=3 ===== */
/* ============================================================================
 * Nexora — Color audit polish
 * ----------------------------------------------------------------------------
 * Many existing components have hex colors inline (e.g. `#3b82f6`, `#0ea5e9`).
 * This stylesheet maps those hard-coded values to CSS custom properties so the
 * dark theme (data-theme="dark") inherits them naturally. We don't touch JS;
 * just override visual properties through CSS specificity.
 * ========================================================================== */

/* Note: do NOT redefine --accent / --accent-light / --accent2 here.
   A previous version had `--accent: var(--accent, #6366f1)` which is a
   self-reference — CSS treats it as invalid and the variable evaluates
   to "initial" (empty string) in many contexts. That cascaded into
   invisible buttons (white-on-white New Task), missing avatar bgs,
   colorless tags, blank progress bars, etc. The canonical token
   definitions live in app.css :root — leave them alone. */

/* ── Override inline color="#xxx" common patterns where possible ──
   These cover the cases in app.js render functions where inline style
   hardcodes a hex color. We can't reach those without modifying app.js,
   but we add !important polish on key surfaces. */

/* Kanban project header bar (uses inline gradient #8b5cf6,#ec4899) */
.kanban-project-card span[style*="linear-gradient"] {
  background: linear-gradient(135deg, var(--purple, #8b5cf6), var(--pink, #ec4899)) !important;
}

/* Progress fills */
.kanban-progress-fill,
.progress-fill {
  background: linear-gradient(90deg, var(--accent), var(--accent2)) !important;
}

/* Old status colors used inline */
[style*="#3b82f6"][class*="task"] { color: var(--accent) !important; }
[style*="#8b5cf6"][class*="epic"] { color: var(--purple, #8b5cf6) !important; }
[style*="#10b981"][class*="subtask"] { color: var(--green, #10b981) !important; }

/* Email notification box (uses hardcoded #f0f9ff bg) */
#emailNotifBox {
  background: linear-gradient(135deg, var(--accent2-light, #e0f2fe), var(--accent2-light, #e0f2fe)) !important;
  border-color: var(--accent2, #0ea5e9) !important;
}
#emailNotifBox div[style*="background:#0ea5e9"] {
  background: var(--accent2, #0ea5e9) !important;
}

/* Type badges (use hardcoded #ede9fe, #d1fae5) */
.type-badge.epic,
[style*="background:#ede9fe"][class*="epic"] {
  background: var(--purple-light, #f5f3ff) !important;
  color: var(--purple, var(--purple)) !important;
  border-color: var(--purple-light, #c4b5fd) !important;
}
.type-badge.subtask,
[style*="background:#d1fae5"][class*="subtask"] {
  background: var(--green-light, #ecfdf5) !important;
  color: var(--green, #047857) !important;
  border-color: var(--green-light, #6ee7b7) !important;
}

/* Login error banner (uses hardcoded red palette) */
.login-error {
  background: var(--red-light, #fef2f2) !important;
  color: var(--red, var(--danger)) !important;
  border-color: var(--red, var(--danger)) !important;
}

/* ── Dark mode adjustments for previously-hardcoded surfaces ── */
[data-theme="dark"] #emailNotifBox {
  background: linear-gradient(135deg, rgba(14, 165, 233, 0.12), rgba(14, 165, 233, 0.06)) !important;
  border-color: rgba(14, 165, 233, 0.4) !important;
}
[data-theme="dark"] #emailNotifBox [style*="color:#0c4a6e"],
[data-theme="dark"] #emailNotifBox [style*="color:#0369a1"] {
  color: var(--accent2, #67e8f9) !important;
}

/* Risk Heatmap, Priority Matrix cells often use hex inline — patch them */
[data-theme="dark"] .heatmap-cell[style*="background:#"] {
  filter: brightness(0.85) saturate(0.9);
}

/* Common chart-card hover (was inline) */
.chart-card:hover { box-shadow: var(--shadow-md) !important; border-color: var(--accent-light) !important; }

/* Pill colors fix in dark mode */
[data-theme="dark"] .badge,
[data-theme="dark"] .pill {
  border-color: var(--border) !important;
}

/* Ensure all anchors use accent color, not browser-default blue */
a:not([class]) { color: var(--accent); }
a:not([class]):hover { color: var(--accent-hover, var(--accent)); }

/* ============================================================================
   Fix: in-page primary action buttons (btnNewTask, btnAddRisk, etc.) appear
   white-on-white on some configurations because no rule guarantees the
   accent background when polish.js's btn-saving shimmer overlay also
   targets them. Explicitly enforce indigo bg + white text on .btn-primary
   in all states so they remain readable even before hover.
   ============================================================================ */
.btn.btn-primary,
button.btn-primary {
  background-color: var(--accent, #6366f1) !important;
  color: var(--surface) !important;
  border: 1px solid var(--accent, #6366f1) !important;
}
.btn.btn-primary:hover,
button.btn-primary:hover {
  background-color: var(--accent-hover, #4f46e5) !important;
  border-color: var(--accent-hover, #4f46e5) !important;
  color: var(--surface) !important;
}
/* Dark mode parity — text becomes dark on lighter accent */
[data-theme="dark"] .btn.btn-primary,
[data-theme="dark"] button.btn-primary {
  background-color: var(--accent, var(--brand-hover)) !important;
  color: #0f172a !important;
  border-color: var(--accent, var(--brand-hover)) !important;
}
[data-theme="dark"] .btn.btn-primary:hover,
[data-theme="dark"] button.btn-primary:hover {
  background-color: var(--brand-active) !important;
  border-color: var(--brand-active) !important;
  color: #0f172a !important;
}
/* Disabled state still readable */
.btn.btn-primary:disabled,
button.btn-primary:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Defensive: the polish.js shimmer overlay `.btn-saving::after` previously
   used a translucent gradient sometimes confused with text color. Pin its
   background-color explicitly to none so it never paints solid white. */
.btn-saving::after {
  background-color: transparent !important;
}

/* ===== /css/v2/motion.css?v=4 ===== */
/* Nexora v4 motion — subtle life, ease-out, no bounce. */

@keyframes nx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes nx-fade-up {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes nx-scale-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes nx-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
@keyframes nx-pulse-glow {
  0%, 100% { box-shadow: 0 0 0 0 var(--brand-glow); }
  50%      { box-shadow: 0 0 0 8px transparent; }
}
@keyframes nx-spin {
  to { transform: rotate(360deg); }
}

.anim-fade-in   { animation: nx-fade-in  var(--d) var(--ease-out) both; }
.anim-fade-up   { animation: nx-fade-up  var(--d) var(--ease-out) both; }
.anim-scale-in  { animation: nx-scale-in var(--d) var(--ease-out) both; }
.anim-spin      { animation: nx-spin 600ms linear infinite; }
.anim-pulse     { animation: nx-pulse-glow 2s var(--ease) infinite; }
.anim-shimmer {
  background: linear-gradient(90deg, var(--bg-hover) 0%, var(--surface-soft) 50%, var(--bg-hover) 100%);
  background-size: 200% 100%;
  animation: nx-shimmer 1500ms linear infinite;
}

/* Default interactive transitions — bring back transform for subtle lift */
button, a, .nav-item, .card, .kpi-card, .chart-card, .badge,
input, select, textarea, .sub-tab, .task-card {
  transition:
    background-color var(--d-fast) var(--ease),
    color           var(--d-fast) var(--ease),
    border-color    var(--d-fast) var(--ease),
    box-shadow      var(--d-fast) var(--ease),
    transform       var(--d-fast) var(--ease);
}

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

/* ===== /css/v2/brand.css?v=4 ===== */
/* Nexora v3 brand mark — editorial-modern, restrained. */

.nx-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  transition: background-color var(--d-fast) var(--ease);
}
.nx-brand:hover { background: var(--bg-hover); }
.nx-brand:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.nx-brand svg { display: block; }

.nx-wordmark {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--text);
  font-feature-settings: 'ss01', 'ss02';
}

.sidebar.collapsed .nx-wordmark,
[data-sidebar="collapsed"] .nx-wordmark {
  display: none;
}

/* ===== /css/v2/legacy_buttons_forms.css?v=1 ===== */
/* ============================================================================
   Consolidated legacy buttons + forms (Wave 5 migration).
   Verbatim content of the former v2/buttons.css + v2/forms.css. Loads at the
   same cascade position both files used to load, so visual behavior is
   unchanged. v3/buttons.css and v3/forms.css still load after this file —
   non-!important rules here continue to defer to v3 as before.
   ============================================================================ */

/* Nexora v4 buttons — vibrant indigo, alive but professional. */

.btn,
button.btn,
a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 40px !important;
  padding: 0 var(--space-4) !important;
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em;
  line-height: 1;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: all var(--d-fast) var(--ease);
  box-shadow: 0 1px 2px rgba(15,15,30,.04);
}

.btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.btn:disabled,
.btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}

/* Default — secondary appearance */
.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  transform: translateY(-0.5px);
  box-shadow: 0 2px 6px rgba(15,15,30,.06);
}

/* PRIMARY — electric indigo, the hero CTA */
.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
  box-shadow: 0 1px 2px rgba(80,70,229,.20), inset 0 1px 0 rgba(255,255,255,0.12);
}
.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
  color: var(--surface);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -2px rgba(80,70,229,.30), inset 0 1px 0 rgba(255,255,255,0.15);
}
.btn-primary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(80,70,229,.30), 0 4px 12px -2px rgba(80,70,229,.30);
}
.btn-primary:disabled {
  background: var(--brand);
  border-color: var(--brand);
}

/* SECONDARY — bordered, gentle */
.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-secondary:hover {
  background: var(--bg-hover);
  transform: translateY(-0.5px);
}

/* GHOST */
.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border-color: transparent;
  box-shadow: none;
}
.btn-ghost:hover {
  background: var(--bg-hover);
  color: var(--text);
  transform: none;
  box-shadow: none;
}

/* DANGER */
.btn-danger {
  background: var(--danger);
  color: var(--surface);
  border-color: var(--danger);
  box-shadow: 0 1px 2px rgba(220,38,38,.20), inset 0 1px 0 rgba(255,255,255,0.12);
}
.btn-danger:hover {
  background: #B91C1C;
  border-color: #B91C1C;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -2px rgba(220,38,38,.30);
}

/* WARNING */
.btn-warning {
  background: var(--warning);
  color: var(--surface);
  border-color: var(--warning);
}
.btn-warning:hover {
  background: #C2410C;
  transform: translateY(-1px);
}

/* Sizes */
.btn-sm {
  height: 32px !important;
  padding: 0 var(--space-3) !important;
  font-size: 13px !important;
  border-radius: var(--radius-xs);
}
.btn-lg {
  height: 48px !important;
  padding: 0 var(--space-5) !important;
  font-size: 15px !important;
  border-radius: var(--radius-md);
}

.btn-icon { width: 40px !important; padding: 0 !important; }
.btn-icon.btn-sm { width: 32px !important; }

/* Topbar icon button */
.topbar-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 36px !important;
  min-width: 36px !important;
  padding: 0 var(--space-3) !important;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-2);
  cursor: pointer;
  font-family: var(--font-body);
  transition: all var(--d-fast) var(--ease);
}
.topbar-icon-btn:hover {
  background: var(--bg-hover);
  color: var(--text);
  border-color: var(--border);
}
.topbar-icon-btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* Nexora v4 forms — vibrant brand focus halo. */

input, select, textarea,
.form-control, .search-input, .filter-select {
  display: block;
  width: 100%;
  height: 40px !important;
  padding: 0 var(--space-3) !important;
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: all var(--d-fast) var(--ease);
  appearance: none;
  -webkit-appearance: none;
  box-shadow: 0 1px 2px rgba(15,15,30,.02);
}

textarea {
  min-height: 110px !important;
  padding: var(--space-3) !important;
  height: auto !important;
  line-height: 1.6;
  resize: vertical;
}

input:hover, select:hover, textarea:hover {
  border-color: var(--border-strong);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--shadow-focus), 0 1px 2px rgba(15,15,30,.02);
}

input::placeholder, textarea::placeholder {
  color: var(--muted);
  opacity: 1;
  font-family: var(--font-body);
}

input:disabled, select:disabled, textarea:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: var(--surface-soft);
}

select, .filter-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px !important;
}

.search-box {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: 0 1 320px;
}
.search-box .search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
  display: inline-flex;
}
.search-box .search-input { padding-left: 36px !important; }

.form-group { display: block; margin-bottom: var(--space-5); }
.form-label, label.form-label {
  display: block;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-2);
  margin-bottom: var(--space-2);
  letter-spacing: -0.005em;
}

.form-label.req::after, .req .form-label::after {
  content: '*';
  color: var(--danger);
  margin-left: 4px;
}

.form-error {
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--danger);
  margin-top: var(--space-1);
}

input[type="checkbox"], input[type="radio"] {
  width: 16px !important;
  height: 16px !important;
  padding: 0;
  accent-color: var(--brand);
  cursor: pointer;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
.form-row.full { grid-template-columns: 1fr; }
@media (max-width: 600px) {
  .form-row { grid-template-columns: 1fr; }
}

/* ===== /css/v2/sidebar.css?v=5 ===== */
/* Nexora v4 sidebar — prominent brand-color active state with left bar. */

aside, .sidebar {
  width: 244px;
  background: var(--bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: var(--space-5) var(--space-3);
  gap: 2px;
}

.sidebar .nav-section-label,
.sb-section-label {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: var(--space-4) var(--space-3) var(--space-2);
  margin-top: var(--space-3);
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 9px var(--space-3);
  border-radius: var(--radius-sm);
  font-family: var(--font-body) !important;
  font-size: 13.5px !important;
  font-weight: 500 !important;
  letter-spacing: -0.005em;
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
  background: transparent;
  border: none;
  text-align: left;
  width: 100%;
  transition: all var(--d-fast) var(--ease);
}

.nav-item:hover {
  background: var(--bg-hover);
  color: var(--text);
  transform: translateX(1px);
}

.nav-item:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.nav-item .nav-icon,
.nav-item svg {
  display: inline-flex;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: currentColor;
}

.nav-item .nav-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Active — brand bg-fade + brand text + LEFT BAR (Linear-style) */
.nav-item.active,
.nav-item[aria-current="page"] {
  background: var(--brand-fade) !important;
  color: var(--brand) !important;
  font-weight: 600 !important;
}
.nav-item.active::before,
.nav-item[aria-current="page"]::before {
  content: none;
}
.nav-item.active .nav-icon,
.nav-item.active svg { color: var(--brand) !important; }

.sidebar-user, .sb-user {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--border);
  cursor: pointer;
  box-shadow: var(--shadow-card);
}
.sidebar-user:hover {
  background: var(--bg-hover);
  border-color: var(--brand-strong);
}

.sidebar.collapsed, [data-sidebar="collapsed"] aside, [data-sidebar="collapsed"] .sidebar {
  width: 64px;
  padding: var(--space-5) var(--space-2);
}
.sidebar.collapsed .nav-label,
.sidebar.collapsed .sb-section-label,
[data-sidebar="collapsed"] .nav-label,
[data-sidebar="collapsed"] .sb-section-label { display: none; }
.sidebar.collapsed .nav-item,
[data-sidebar="collapsed"] .nav-item {
  justify-content: center;
  padding: 9px;
}

@media (max-width: 900px) {
  aside, .sidebar {
    background: var(--bg);
    box-shadow: var(--shadow-modal);
    border-right: 1px solid var(--border);
  }
}

/* ===== /css/v2/topbar.css?v=5 ===== */
/* Nexora v4 topbar — sticky, subtle depth shadow. */

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  height: 60px;
  padding: 0 var(--space-6);
  /* Glass surface — translucent white with saturating blur.
     Reads as "floating" instead of flat-attached to content. Dark mode gets
     its counterpart in nexora-theme.css. Fallback to solid --bg when the
     browser (or the user via prefers-reduced-transparency) opts out. */
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(15,15,30,.03), 0 4px 12px -4px rgba(15,15,30,.04);
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .topbar {
    background: var(--bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
@supports not (backdrop-filter: blur(1px)) {
  .topbar { background: var(--bg); }
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 1;
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ── Search button — icon-only on narrow screens, pill with hint on wider ──
   Replaces the tiny magnifying-glass icon-only button so the "⌘K" affordance
   is visible without needing to hover for the tooltip. Collapses back to
   icon-only under 900px to preserve topbar real estate. */
.topbar-search-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 32px;
  padding: 0 var(--space-3);
  background: var(--surface-soft);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 12px;
  transition: background var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
  min-width: 140px;
}
.topbar-search-btn:hover {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}
.topbar-search-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: currentColor;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.topbar-search-label {
  flex: 1;
  text-align: left;
  font-weight: 500;
}
.topbar-search-kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom-width: 1.5px;
  border-radius: var(--radius-xs);
  padding: 1px 5px;
  min-width: 28px;
  text-align: center;
  flex-shrink: 0;
}
@media (max-width: 900px) {
  .topbar-search-btn { min-width: 0; padding: 0 var(--space-2); }
  .topbar-search-label,
  .topbar-search-kbd { display: none; }
}

#pageTitle,
.topbar h1,
.topbar .page-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
  line-height: 1;
}

.topbar .breadcrumb, .topbar-breadcrumb {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--muted);
}
.topbar .breadcrumb a {
  color: var(--muted);
  text-decoration: none;
  transition: color var(--d-fast) var(--ease);
}
.topbar .breadcrumb a:hover { color: var(--brand); }

.topbar-date {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  padding: 0 var(--space-3);
  letter-spacing: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

#notifBellBtn .notif-badge,
.notif-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 16px;
  height: 16px;
  padding: 0 5px;
  font-size: 10px;
  font-weight: 700;
  color: var(--surface);
  background: var(--danger);
  border-radius: var(--radius-full);
  border: 2px solid var(--bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* #btnCmdK styling is now handled by .nx-icon-btn class in v2/icon-btn.css.
   The previous pill+border treatment has been retired in favor of the
   square icon-only button with hover tooltip. */

.topbar .project-selector,
.topbar [class*="proj-select"] {
  height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 13px;
  color: var(--text-2);
}

@media (max-width: 768px) {
  .topbar { height: 52px; padding: 0 var(--space-4); gap: var(--space-2); }
  .topbar-date { display: none; }
  .topbar .breadcrumb { display: none; }
  /* #btnCmdK label rule removed — button is now icon-only via .nx-icon-btn. */
}

/* ===== /css/v2/subtabs.css?v=9 ===== */
/* Nexora v3 sub-tabs — editorial bottom-border active state. */

.sub-tabs-bar {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 0 var(--space-7);
  /* Clip overflow so the row's full-bleed divider stays inside the bar
     bounds (extends edge-to-edge without leaking into sibling areas). */
  overflow-x: hidden;
  position: relative;
}

.sub-tabs {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.sub-tabs-row {
  display: flex;
  align-items: stretch;
  gap: var(--space-2);
  flex-wrap: nowrap;
  overflow-x: auto;
  /* Hide all scrollbars on sub-tabs row — no gray vertical/horizontal bar. */
  scrollbar-width: none;
}

.sub-tabs-row::-webkit-scrollbar { display: none; width: 0; height: 0; }

.sub-tabs-row-inner {
  /* Negative margin + compensating padding makes the row's BOX span
     beyond the bar's padding, so the border-top reaches edge-to-edge
     (parent bar's overflow:hidden clips the bleed). Children stay in
     place because padding offsets the negative margin. */
  margin-left: -100vw;
  margin-right: -100vw;
  padding-left: 100vw;
  padding-right: 100vw;
  padding-top: var(--space-2);
  margin-top: var(--space-2);
  border-top: 1px solid var(--border);
}

.sub-tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 44px;
  padding: 0 var(--space-4);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 450;
  letter-spacing: -0.005em;
  color: var(--muted);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
  margin-bottom: -1px;
}

.sub-tab:hover {
  color: var(--text);
}

.sub-tab:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.sub-tab.sub-tab-active,
.sub-tab[aria-selected="true"] {
  color: var(--brand);
  font-weight: 600;
  border-bottom-color: var(--brand);
}

/* Cluster row (2-tier nav, e.g. Product/Portfolio) — slightly more prominent */
.sub-tab-cluster {
  height: 48px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.010em;
}
.sub-tab-cluster.sub-tab-active {
  color: var(--brand);
  border-bottom-color: var(--brand);
}

@media (max-width: 600px) {
  .sub-tabs-bar { padding: 0 var(--space-5); }
  .sub-tab { height: 40px; padding: 0 var(--space-3); font-size: 13px; }
}

/* ===== /css/v2/modal.css?v=6 ===== */
/* Nexora v3 modals — editorial restraint, no blur, quiet motion. */

.modal-overlay {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(15, 15, 30, 0.45);
  padding: var(--space-5);
  z-index: 1000;
}

[data-theme="dark"] .modal-overlay,
html.dark .modal-overlay { background: rgba(0, 0, 0, 0.65); }

.modal-overlay.open,
.modal-overlay[style*="display: flex"],
.modal-overlay[style*="display:flex"],
.modal-overlay[style*="display: block"],
.modal-overlay[style*="display:block"] {
  display: flex;
  animation: nx-fade-in var(--d-fast) var(--ease) both;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-modal);
  padding: 0;
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - var(--space-7));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: nx-fade-up var(--d) var(--ease) both;
}

.modal-wide  { max-width: 720px; }
.modal-xwide { max-width: 960px; }
.modal-tall  { max-height: calc(100vh - var(--space-6)); }

.modal-title,
.modal-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6) var(--space-4);
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
  /* border-bottom removed — created unwanted divider lines between
   * the title and the form/body across kickoff detail, research note,
   * release, flag, experiment, NPS, and new-document modals. */
  flex-shrink: 0;
}
.modal-title svg { color: var(--brand); width: 20px; height: 20px; }

.modal-body { padding: var(--space-6); overflow-y: auto; flex: 1; }

.modal-actions,
.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--border);
  background: var(--bg);
  flex-shrink: 0;
}
.modal-actions .modal-actions-left { margin-right: auto; }

.modal-close,
.modal .close-btn {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--muted);
  border-radius: var(--radius-xs);
  cursor: pointer;
}
.modal-close:hover,
.modal .close-btn:hover { background: var(--bg-hover); color: var(--text); }

@media (max-width: 600px) {
  .modal-overlay { padding: 0; align-items: stretch; }
  .modal {
    max-width: 100%;
    max-height: 100dvh;
    border-radius: 0;
    border: none;
  }
}

/* ===== /css/v2/skeleton.css?v=4 ===== */
/* Nexora v3 skeleton — quiet shimmer, border-first cards. */

[data-nx-skeleton],
.nx-skeleton,
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-soft);
  border-radius: var(--radius-sm);
}

[data-nx-skeleton]::after,
.nx-skeleton::after,
.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255,255,255,0.55) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: nx-shimmer 1500ms linear infinite;
}

[data-theme="dark"] [data-nx-skeleton]::after,
[data-theme="dark"] .nx-skeleton::after,
html.dark [data-nx-skeleton]::after,
html.dark .nx-skeleton::after {
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255,255,255,0.05) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
}

/* ===== /css/v2/page.css?v=3 ===== */
/* Nexora v3 page layout — generous editorial whitespace. */

.page {
  padding: var(--space-6) var(--space-7);
  background: var(--bg);
  min-height: 100%;
}

@media (max-width: 900px) {
  .page { padding: var(--space-5) var(--space-5); }
}
@media (max-width: 600px) {
  .page { padding: var(--space-4); }
}

/* Inner content container — max-width for readable lines */
.page > .page-inner,
.page > .container {
  max-width: 1280px;
  margin: 0 auto;
}

/* Page hero / header row */
.page-hero,
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--border);
}

.page-hero h1,
.page-header h1 {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.020em;
  margin: 0 0 var(--space-1);
  color: var(--text);
}

.page-hero .subtitle,
.page-header .subtitle {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--muted);
  margin: 0;
  line-height: 1.55;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Sections within a page */
.page-section {
  margin-bottom: var(--space-7);
}
.page-section:last-child { margin-bottom: 0; }

/* Toolbar at top of list pages */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: 0;
  margin-bottom: var(--space-5);
}

/* Tight grid for KPI strips, etc. */
.grid-kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

/* Two-column responsive */
.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-5);
}

/* Body content prose */
.prose {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
  max-width: 720px;
}
.prose h1, .prose h2, .prose h3, .prose h4 {
  font-family: var(--font-display);
  margin-top: var(--space-6);
}
.prose p { margin-bottom: var(--space-4); }

/* ===== /css/v2/section.css?v=3 ===== */
/* Nexora v3 sections — editorial dividers, restrained, type-driven. */

/* Section with title + content */
section.nx-section,
.nx-section {
  margin-bottom: var(--space-7);
}

section.nx-section > header,
.nx-section > .nx-section-header,
.nx-section > header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--border);
}

section.nx-section > header > h2,
.nx-section > header > h2,
.nx-section > .nx-section-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
  line-height: 1.35;
}

.nx-section-desc {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--muted);
  margin: var(--space-1) 0 0;
  line-height: 1.5;
  max-width: 640px;
}

/* Horizontal rule — editorial hairline */
hr,
.nx-hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: var(--space-6) 0;
}

/* Strong divider — for major page sections */
.nx-hr-strong {
  border: none;
  border-top: 1px solid var(--border-strong);
  margin: var(--space-7) 0;
}

/* Quiet divider — for tight stacks */
.nx-hr-soft {
  border: none;
  border-top: 1px solid var(--border-soft);
  margin: var(--space-4) 0;
}

/* Editorial blockquote — pull quote feel */
blockquote,
.nx-quote {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 400;
  font-style: italic;
  letter-spacing: -0.015em;
  line-height: 1.45;
  color: var(--text);
  border-left: 3px solid var(--brand);
  padding-left: var(--space-5);
  margin: var(--space-6) 0;
}

/* Tiny labels above big numbers (Stripe Dashboard style) */
.eyebrow,
.nx-eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ===== /css/v2/data-viz.css?v=3 ===== */
/* Nexora v3 data visualization — editorial chart theming. */

/* Chart container */
.chart-card canvas,
.chart-card .chart,
canvas.chart {
  font-family: var(--font-body) !important;
}

/* Tables — editorial style */
table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--text);
}

thead th {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: transparent;
}

tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
  font-variant-numeric: tabular-nums;
}

tbody tr:hover { background: var(--bg-hover); }
tbody tr:last-child td { border-bottom: none; }

/* Numeric columns */
td.num,
td.numeric,
.cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  font-size: 13px;
}

/* Progress bar — slim, editorial */
.progress,
.progress-bar {
  width: 100%;
  height: 6px;
  background: var(--surface-soft);
  border-radius: var(--radius-full);
  overflow: hidden;
  position: relative;
}
.progress .fill,
.progress-bar .fill,
.progress > div {
  height: 100%;
  background: var(--brand);
  border-radius: var(--radius-full);
  transition: width var(--d) var(--ease);
}

/* KPI number — display family for emphasis */
.kpi-card .kpi-value,
.kpi-value {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.020em;
  line-height: 1.1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.kpi-card .kpi-label,
.kpi-label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--muted);
  margin-bottom: var(--space-2);
}
.kpi-card .kpi-delta,
.kpi-delta {
  font-family: var(--font-body);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  margin-top: var(--space-2);
}
.kpi-delta.positive { color: var(--success); }
.kpi-delta.negative { color: var(--danger); }

/* ===== /css/v2/dashboard.css?v=3 ===== */
/* Nexora v4 dashboard — KPI hero, brand-color numbers, alive. */

.kpi-card,
.chart-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md) !important;
  padding: var(--space-5) !important;
  box-shadow: var(--shadow-card) !important;
  transition: all var(--d-fast) var(--ease) !important;
  position: relative;
  overflow: hidden;
}

.kpi-card:hover,
.chart-card:hover {
  border-color: var(--brand-strong) !important;
  box-shadow: var(--shadow-elevated) !important;
  transform: translateY(-1px) !important;
}

/* KPI icon — colorful chip with subtle shadow */
.kpi-card-icon {
  width: 36px !important;
  height: 36px !important;
  border-radius: var(--radius-sm) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  margin-bottom: var(--space-4) !important;
  box-shadow: 0 1px 2px rgba(15,15,30,.04);
}

/* Color variants — VIBRANT (not muted) */
.kpi-card.blue   .kpi-card-icon { color: var(--info)    !important; background: var(--info-bg)    !important; }
.kpi-card.green  .kpi-card-icon { color: var(--success) !important; background: var(--success-bg) !important; }
.kpi-card.yellow .kpi-card-icon { color: var(--warning) !important; background: var(--warning-bg) !important; }
.kpi-card.red    .kpi-card-icon { color: var(--danger)  !important; background: var(--danger-bg)  !important; }
.kpi-card.purple .kpi-card-icon { color: var(--brand)   !important; background: var(--brand-fade) !important; }

/* KPI label — small, muted, uppercase eyebrow */
.kpi-card .kpi-label,
.kpi-card .label {
  font-family: var(--font-body) !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  margin-bottom: var(--space-2) !important;
}

/* KPI VALUE — Fraunces, BIG, BRAND color */
.kpi-card .kpi-value,
.kpi-card .value,
.kpi-card .number,
.kpi-card .count {
  font-family: var(--font-display) !important;
  font-size: 36px !important;
  font-weight: 500 !important;
  letter-spacing: -0.025em !important;
  line-height: 1.05 !important;
  color: var(--text) !important;
  font-variant-numeric: tabular-nums !important;
  margin-bottom: var(--space-2) !important;
}

/* When kpi-card has brand variant, value becomes brand color */
.kpi-card.purple .kpi-value,
.kpi-card.brand .kpi-value,
.kpi-card[data-emphasis="brand"] .kpi-value { color: var(--brand) !important; }
.kpi-card.green .kpi-value[data-trend="up"],
.kpi-card .kpi-value.success { color: var(--success) !important; }
.kpi-card.red .kpi-value[data-trend="down"],
.kpi-card .kpi-value.danger { color: var(--danger) !important; }

/* KPI delta (trend indicator) */
.kpi-card .kpi-delta,
.kpi-card .delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  letter-spacing: 0;
}
.kpi-card .kpi-delta.positive,
.kpi-card .delta.positive {
  color: var(--success);
  background: var(--success-bg);
}
.kpi-card .kpi-delta.negative,
.kpi-card .delta.negative {
  color: var(--danger);
  background: var(--danger-bg);
}

/* Chart title */
.chart-card .chart-title,
.chart-card h3,
.chart-card .title {
  font-family: var(--font-display) !important;
  font-size: 16px !important;
  font-weight: 500 !important;
  letter-spacing: -0.015em !important;
  color: var(--text) !important;
  margin: 0 0 var(--space-4) !important;
}

/* Dashboard grids */
.dashboard-grid,
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.dashboard-chart-row,
.chart-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}

/* ===== /css/v2/charts.css?v=2 ===== */
/* Nexora v4 chart cards — alive containers for vibrant charts. */

.chart-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md) !important;
  padding: var(--space-5) !important;
  box-shadow: var(--shadow-card) !important;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 320px;
  transition: all var(--d-fast) var(--ease) !important;
}

.chart-card:hover {
  border-color: var(--brand-strong) !important;
  box-shadow: var(--shadow-elevated) !important;
  transform: translateY(-1px) !important;
}

.chart-card .chart-title,
.chart-card h3,
.chart-card .title {
  font-family: var(--font-display) !important;
  font-size: 16px !important;
  font-weight: 500 !important;
  letter-spacing: -0.015em !important;
  color: var(--text) !important;
  margin: 0 !important;
  line-height: 1.35 !important;
}

.chart-card .chart-subtitle,
.chart-card .subtitle {
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--muted);
  margin-top: -4px;
}

.chart-card canvas {
  flex: 1;
  max-height: 280px;
  width: 100% !important;
  height: auto !important;
}

.chart-wrap,
.chart-container {
  flex: 1;
  position: relative;
  min-height: 260px;
}

.chart-card .chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-family: var(--font-body);
  font-size: 11.5px;
  color: var(--text-2);
  letter-spacing: 0.005em;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-soft);
}

.chart-card .chart-legend .legend-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: middle;
}

.chart-card .chart-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  font-family: var(--font-body);
  color: var(--muted);
  font-size: 13px;
}

/* KPI hero inside chart card (number + delta + caption) */
.chart-card .kpi-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-soft);
}
.chart-card .kpi-row .big {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.chart-card .kpi-row .delta {
  font-family: var(--font-body);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  padding: 2px 8px;
  border-radius: var(--radius-full);
}
.chart-card .kpi-row .delta.positive { color: var(--success); background: var(--success-bg); }
.chart-card .kpi-row .delta.negative { color: var(--danger);  background: var(--danger-bg); }

/* ===== /css/v2/kanban.css?v=4 ===== */
/* Nexora v3 kanban — editorial restyling. */

.kanban,
.kanban-board {
  display: flex;
  gap: var(--space-4);
  padding: 0 var(--space-1) var(--space-5);
  overflow-x: auto;
  overflow-y: visible;
  scrollbar-width: thin;
  align-items: flex-start; /* each column can have different height */
}

.kanban-col,
.kanban-column {
  flex: 1 1 280px;
  min-width: 280px;
  background: var(--surface-soft) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md) !important;
  padding: var(--space-4) !important;
  box-shadow: none !important;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* Allow column to grow naturally to show ALL task cards.
     Internal scroll only if column is taller than viewport. */
  max-height: none;
  overflow-y: visible;
}

.kanban-col-header,
.kanban-col > .header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}

.kanban-col-header .count {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--muted);
  padding: 1px 6px;
  background: var(--surface);
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
}

/* Task cards inside kanban */
.kanban-col .task-card,
.task-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-sm) !important;
  padding: var(--space-3) var(--space-4) !important;
  box-shadow: none !important;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color var(--d-fast) var(--ease) !important;
}

.kanban-col .task-card:hover,
.task-card:hover {
  border-color: var(--brand-strong) !important;
  transform: none !important;
  box-shadow: none !important;
}

.task-card .task-title,
.task-card .title {
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.4;
  color: var(--text);
  margin: 0;
}

.task-card .task-meta,
.task-card .meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 11.5px;
  color: var(--muted);
  flex-wrap: wrap;
}

.task-card .task-due,
.task-card .due {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

.task-card .task-due.overdue,
.task-card .overdue {
  color: var(--danger);
  font-weight: 600;
}

/* Overdue badge — quiet but clear */
.overdue-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--danger);
  background: var(--danger-bg);
  padding: 1px 6px;
  border-radius: var(--radius-xs);
  border: 1px solid rgba(180,62,62,0.18);
}

/* Avatar in task card */
.task-card .avatar-sm,
.task-card .assignee-avatar {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  font-size: 10px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-fade);
  color: var(--brand);
  border: 1px solid var(--surface);
}

/* Kanban controls (toolbar at top of kanban) */
.kanban-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}

/* ===== /css/v2/toolbar.css?v=4 ===== */
/* Nexora v3 toolbars — single-row alignment, no height mismatches. */

.toolbar,
.kanban-controls,
.filter-row,
.list-controls {
  display: flex !important;
  align-items: center !important;
  gap: var(--space-3) !important;
  flex-wrap: wrap !important;
  margin: 0 0 var(--space-5) !important;
  padding: 0 !important;
}

/* All direct children: force 40px (matches v3 btn + input) */
.toolbar > .btn,
.toolbar > .btn-sm,
.toolbar > .btn-lg,
.toolbar > button,
.toolbar > input,
.toolbar > select,
.toolbar > .search-box,
.toolbar > .filter-select,
.toolbar > .search-input,
.kanban-controls > .btn,
.kanban-controls > button,
.kanban-controls > input,
.kanban-controls > select,
.kanban-controls > .search-box,
.kanban-controls > .filter-select {
  height: 40px;
  margin: 0 !important;
  align-self: center;
}

/* .btn-sm explicitly stays 32 even inside toolbar (small actions) */
.toolbar > .btn.btn-sm,
.kanban-controls > .btn.btn-sm {
  height: 32px !important;
}

/* result count + status text inside toolbar */
.toolbar .result-count,
.toolbar .count,
.kanban-controls .result-count,
.kanban-controls .count {
  display: inline-flex;
  align-items: center;
  height: 40px;
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--muted);
  letter-spacing: 0.005em;
  white-space: nowrap;
  margin: 0 !important;
}

/* "+ New X" inline buttons should align right */
.toolbar > button[id^="btnNew"],
.toolbar > button[id^="btnAdd"],
.toolbar > .btn-primary {
  margin-left: auto !important;
}

/* When two primary actions exist, gap them */
.toolbar > button[id^="btnNew"] + button,
.toolbar > button[id^="btnAdd"] + button {
  margin-left: var(--space-2) !important;
}

/* Search box already sized via forms.css; keep flex behavior */
.toolbar > .search-box,
.kanban-controls > .search-box {
  flex: 0 1 320px;
  min-width: 200px;
  align-self: center;
}

/* Filter select width — wider so long project names aren't truncated.
   Also applies to .nx-fz-wrap (fuzzy-select replaces the native <select>). */
.toolbar > select,
.toolbar > .filter-select,
.toolbar > .nx-fz-wrap,
.kanban-controls > select,
.kanban-controls > .filter-select,
.kanban-controls > .nx-fz-wrap,
.list-controls > select,
.list-controls > .filter-select,
.list-controls > .nx-fz-wrap {
  width: auto !important;
  min-width: 200px !important;
  max-width: 340px !important;
  flex: 0 0 auto;
}

/* Project filter specifically often holds long names — give it more room */
.toolbar > #filterTaskProject,
.toolbar > #filterRiskProj,
.toolbar > #filterGanttProject,
.toolbar > #filterProj,
.toolbar > [id$="ProjectFilter"] {
  min-width: 240px !important;
  max-width: 360px !important;
}
/* Same rule for fuzzy-wrapped variants — target wrap that contains them */
.toolbar > .nx-fz-wrap:has(#filterTaskProject),
.toolbar > .nx-fz-wrap:has(#filterRiskProj),
.toolbar > .nx-fz-wrap:has(#filterGanttProject),
.toolbar > .nx-fz-wrap:has(#filterProj),
.kanban-controls > .nx-fz-wrap:has(#filterTaskProject) {
  min-width: 240px !important;
  max-width: 360px !important;
}

@media (max-width: 600px) {
  .toolbar,
  .kanban-controls {
    gap: var(--space-2) !important;
  }
  .toolbar > .search-box,
  .kanban-controls > .search-box {
    flex: 1 1 100%;
  }
}

/* ===== /css/v2/tables-lists.css?v=2 ===== */
/* NOTE TO ORCHESTRATOR: register this file in index.html as
   <link rel="stylesheet" href="css/v2/tables-lists.css?v=1">
   AFTER css/v2/charts.css and BEFORE css/v2/legacy-shim.css. */

/* Nexora v3 tables, lists, pagination — editorial restraint. */

/* Table wrapper */
.table-wrap,
.table-wrapper {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.table-wrap table,
.table-wrapper table {
  margin: 0;
}

/* Table base */
table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: 13.5px;
  color: var(--text);
}

thead th {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  text-align: left;
  padding: var(--space-3) var(--space-4) !important;
  border-bottom: 1px solid var(--border) !important;
  background: var(--surface) !important;
  white-space: nowrap;
}

tbody td {
  padding: var(--space-3) var(--space-4) !important;
  border-bottom: 1px solid var(--border-soft) !important;
  vertical-align: middle;
}

tbody tr:hover {
  background: var(--bg-hover);
}
tbody tr:last-child td { border-bottom: none !important; }

/* Numeric / monospace */
td.num, td.numeric, .cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  font-size: 13px;
}

/* Pagination row */
.pagination,
.table-pagination,
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--muted);
  border-top: 1px solid var(--border);
  background: var(--surface);
}

.pagination button,
.pager button {
  height: 32px !important;
  padding: 0 var(--space-3) !important;
  font-size: 12.5px !important;
}

/* Avatar — quiet, brand-tinted */
.avatar, .user-avatar, .avatar-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--brand-fade);
  color: var(--brand);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.005em;
  flex-shrink: 0;
}
.avatar-sm { width: 22px; height: 22px; font-size: 10px; }
.avatar-lg { width: 36px; height: 36px; font-size: 13px; }

/* Avatar group (stacked) */
.avatar-group {
  display: inline-flex;
  align-items: center;
}
.avatar-group .avatar,
.avatar-group .user-avatar {
  border: 1px solid var(--surface);
  margin-left: -6px;
}
.avatar-group .avatar:first-child,
.avatar-group .user-avatar:first-child { margin-left: 0; }

/* Chip / tag */
.chip, .tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 var(--space-3);
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  white-space: nowrap;
}

/* List items (project cards inline list) */
.list-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-soft);
  font-family: var(--font-body);
}
.list-item:last-child { border-bottom: none; }
.list-item:hover { background: var(--bg-hover); }
.list-item .title { font-size: 14px; font-weight: 500; color: var(--text); }
.list-item .meta { font-size: 12.5px; color: var(--muted); margin-left: auto; }

/* ===== /css/v2/hero.css?v=1 ===== */
/* Nexora v4 hero — big confident display moments. */

/* Page hero — large Fraunces, brand-color accent line */
.page-hero,
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-5) 0 var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--border);
  position: relative;
}

.page-hero::after,
.page-header::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 48px;
  height: 2px;
  background: var(--brand);
  border-radius: 1px;
}

.page-hero h1,
.page-header h1 {
  font-family: var(--font-display);
  font-size: 40px !important;
  font-weight: 500 !important;
  letter-spacing: -0.025em !important;
  line-height: 1.1 !important;
  margin: 0 0 var(--space-2) !important;
  color: var(--text);
}

.page-hero .subtitle,
.page-header .subtitle {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text-2);
  margin: 0;
  line-height: 1.6;
  max-width: 640px;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Eyebrow above hero title */
.page-hero .eyebrow,
.page-header .eyebrow {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: var(--space-2);
}

/* Greeting hero (Today page) */
.greeting-hero {
  padding: var(--space-7) var(--space-6) var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  margin-bottom: var(--space-6);
  position: relative;
  overflow: hidden;
}

.greeting-hero::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 240px;
  height: 240px;
  background: radial-gradient(circle at top right, var(--brand-fade) 0%, transparent 70%);
  pointer-events: none;
}

.greeting-hero .greet-text {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: var(--text);
  line-height: 1.15;
  margin-bottom: var(--space-2);
  position: relative;
}

.greeting-hero .greet-date {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--muted);
  margin-bottom: var(--space-3);
  letter-spacing: 0.005em;
}

.greeting-hero .greet-summary {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text-2);
  line-height: 1.6;
  position: relative;
}

/* Big numbers — KPI hero feel */
.big-number,
.hero-number {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 500;
  letter-spacing: -0.030em;
  line-height: 1;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}

.big-number.muted,
.hero-number.muted { color: var(--text-2); }

.big-number-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}

.big-number-label {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0.005em;
}

/* Hero CTA bar (Stripe-style) */
.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 48px;
  padding: 0 var(--space-5);
  background: var(--brand);
  color: var(--surface);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  transition: all var(--d-fast) var(--ease);
  box-shadow: var(--shadow-glow-soft);
}
.hero-cta:hover {
  background: var(--brand-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-glow);
}

@media (max-width: 600px) {
  .page-hero h1, .page-header h1 { font-size: 28px !important; }
  .greeting-hero .greet-text { font-size: 26px; }
  .big-number, .hero-number { font-size: 36px; }
}

/* ===== /css/v2/motion-life.css?v=2 ===== */
/* ════════════════════════════════════════════════════════════════════════
 * DEPRECATED — v2/motion-life.css
 * ────────────────────────────────────────────────────────────────────────
 * A9 (Wave/Agent 4): All unique rules from this file have been ported to
 *   static/css/v3/micro_interactions.css  (see sections 13–20)
 *
 * Reason for consolidation:
 *   • v2/motion-life.css and v3/micro_interactions.css both targeted the
 *     same motion/micro-interaction surface (cards, buttons, badges,
 *     progress, focus). Keeping two sources of truth led to drift and
 *     specificity races (note the !important spam that used to live here).
 *   • v3 is the canonical motion layer (loaded last in <head>, honors
 *     prefers-reduced-motion centrally, scoped via the --mi-* token set).
 *
 * Migration map (old selector → new home in v3/micro_interactions.css):
 *   .card.interactive:hover, a.card:hover, button.card:hover  → §13
 *   .btn-primary (+ :hover, :focus-visible)                   → §14
 *   .nav-item (+ :hover, .active::before)                     → §15
 *   .sub-tab::after, .sub-tab:hover::after                    → §16
 *   .progress / .progress-bar (+ .fill)                       → §17
 *   .nx-loading-dot + @keyframes nx-pulse-dot                 → §18
 *   .notif-badge   + @keyframes nx-badge-pulse                → §19
 *   .flash-success + @keyframes nx-flash-success              → §20
 *
 * Action for callers:
 *   • Remove any <link rel="stylesheet" href="static/css/v2/motion-life.css">
 *     from index.html / templates. v3/micro_interactions.css already covers
 *     everything that lived here.
 *   • This file intentionally has NO rules so it cannot conflict with v3.
 * ════════════════════════════════════════════════════════════════════════ */

/* ===== /css/v2/icon-btn.css?v=5 ===== */
/* Nexora v4 icon-only button — for topbar header actions.
   Square, minimal, with elegant custom tooltip on hover. */

.nx-icon-btn {
  position: relative;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 36px !important;
  min-width: 36px !important;
  height: 36px !important;
  padding: 0 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm, 8px) !important;
  color: var(--text-2);
  cursor: pointer;
  transition:
    background-color var(--d-fast, 180ms) var(--ease),
    border-color    var(--d-fast, 180ms) var(--ease),
    color           var(--d-fast, 180ms) var(--ease);
  font-family: var(--font-body) !important;
  font-size: 0 !important; /* hide any stray text */
  line-height: 1 !important;
  flex-shrink: 0;
}

.nx-icon-btn:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}

.nx-icon-btn:focus-visible {
  outline: none;
  border-color: var(--brand) !important;
  box-shadow: var(--shadow-focus, 0 0 0 3px rgba(80,70,229,0.18));
}

.nx-icon-btn:active {
  background: var(--surface-soft, var(--bg-hover)) !important;
}

.nx-icon-btn svg {
  width: 17px !important;
  height: 17px !important;
  stroke: currentColor;
  stroke-width: 1.75;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
  flex-shrink: 0;
}

/* Primary variant — NO solid background. Just brand-color icon stroke to
   visually hint "primary action" without becoming a colored block. Same
   chrome (transparent + hover bg) as every other icon button. */
.nx-icon-btn.nx-icon-primary {
  background: transparent !important;
  color: var(--brand) !important;
  border-color: transparent !important;
}
.nx-icon-btn.nx-icon-primary:hover {
  background: var(--brand-fade) !important;
  color: var(--brand) !important;
  border-color: var(--brand-strong) !important;
}
.nx-icon-btn.nx-icon-primary:active {
  background: var(--brand-strong) !important;
  color: var(--brand-hover) !important;
}

/* Danger variant */
.nx-icon-btn.nx-icon-danger:hover {
  color: var(--danger) !important;
  background: var(--danger-bg, rgba(220,38,38,0.08)) !important;
  border-color: rgba(220,38,38,0.18) !important;
}

/* ══════════════════════════════════════════════════════════════════
   Custom tooltip — fades in below icon on hover
   Uses [data-tooltip="..."] attribute
   ══════════════════════════════════════════════════════════════════ */

/* Scope tooltip to icon-style buttons only so it doesn't leak to nav-items
   (which have their own label visible) or other generic elements. */
.nx-icon-btn[data-tooltip],
button[data-tooltip].nx-icon-btn,
.qp[data-tooltip],
.dqp[data-tooltip] {
  position: relative;
}

/* Tooltip bubble */
.nx-icon-btn[data-tooltip]::after,
button[data-tooltip].nx-icon-btn::after,
.qp[data-tooltip]::after,
.dqp[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  padding: 5px 9px;
  background: var(--text, #1A1A1F);
  color: var(--bg, #FAFAF7);
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.35;
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-50%) translateY(-4px);
  transition:
    opacity 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 9999;
  box-shadow: 0 4px 16px -4px rgba(15,15,30,0.20), 0 2px 6px rgba(15,15,30,0.10);
}

/* Tooltip arrow (small triangle pointing up) */
.nx-icon-btn[data-tooltip]::before,
button[data-tooltip].nx-icon-btn::before,
.qp[data-tooltip]::before,
.dqp[data-tooltip]::before {
  content: '';
  position: absolute;
  top: calc(100% + 3px);
  left: 50%;
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid var(--text, #1A1A1F);
  transform: translateX(-50%) translateY(-2px);
  pointer-events: none;
  opacity: 0;
  transition:
    opacity 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 9999;
}

/* Show on hover + focus — scoped to icon-style buttons only */
.nx-icon-btn[data-tooltip]:hover::after,
.nx-icon-btn[data-tooltip]:focus-visible::after,
.nx-icon-btn[data-tooltip]:hover::before,
.nx-icon-btn[data-tooltip]:focus-visible::before,
.qp[data-tooltip]:hover::after,
.qp[data-tooltip]:hover::before,
.dqp[data-tooltip]:hover::after,
.dqp[data-tooltip]:hover::before {
  opacity: 1;
}
.nx-icon-btn[data-tooltip]:hover::after,
.nx-icon-btn[data-tooltip]:focus-visible::after,
.qp[data-tooltip]:hover::after,
.dqp[data-tooltip]:hover::after {
  transform: translateX(-50%) translateY(0);
}
.nx-icon-btn[data-tooltip]:hover::before,
.nx-icon-btn[data-tooltip]:focus-visible::before,
.qp[data-tooltip]:hover::before,
.dqp[data-tooltip]:hover::before {
  transform: translateX(-50%) translateY(0);
}

/* Tooltip position variants */
[data-tooltip-pos="top"]::after {
  top: auto;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
}
[data-tooltip-pos="top"]::before {
  top: auto;
  bottom: calc(100% + 3px);
  border-bottom: none;
  border-top: 5px solid var(--text, #1A1A1F);
  transform: translateX(-50%) translateY(2px);
}
[data-tooltip-pos="top"]:hover::after,
[data-tooltip-pos="top"]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}
[data-tooltip-pos="top"]:hover::before,
[data-tooltip-pos="top"]:focus-visible::before {
  transform: translateX(-50%) translateY(0);
}

/* Suppress tooltip on touch devices (mobile) — they don't have hover */
@media (hover: none) {
  [data-tooltip]::after,
  [data-tooltip]::before {
    display: none !important;
  }
}

/* When icon button is rightmost in topbar, shift tooltip slightly left so it doesn't clip */
.topbar-right .nx-icon-btn:last-child[data-tooltip]::after {
  left: auto;
  right: 0;
  transform: translateX(0) translateY(-4px);
}
.topbar-right .nx-icon-btn:last-child[data-tooltip]::before {
  left: auto;
  right: 13px;
  transform: translateX(0) translateY(-2px);
}
.topbar-right .nx-icon-btn:last-child[data-tooltip]:hover::after,
.topbar-right .nx-icon-btn:last-child[data-tooltip]:focus-visible::after {
  transform: translateX(0) translateY(0);
}
.topbar-right .nx-icon-btn:last-child[data-tooltip]:hover::before,
.topbar-right .nx-icon-btn:last-child[data-tooltip]:focus-visible::before {
  transform: translateX(0) translateY(0);
}

/* ══════════════════════════════════════════════════════════════════
   Toolbar pattern: LEFT (search/filter/info) + RIGHT (icon CTAs)
   Migrated buttons are nx-icon-btn — these rules ensure proper spacing.
   ══════════════════════════════════════════════════════════════════ */

/* Sequential icon CTAs in a row: 8px gap between them */
.nx-icon-btn + .nx-icon-btn,
.nx-icon-btn[id^="btnNew"] ~ .nx-icon-btn,
.nx-icon-btn[id^="btnAdd"] ~ .nx-icon-btn,
.nx-icon-btn[id^="btnExport"] ~ .nx-icon-btn {
  margin-left: 8px !important;
}

/* First icon CTA gets auto margin to push the group right */
.toolbar > .nx-icon-btn:not(.nx-icon-btn + .nx-icon-btn):first-of-type,
.kanban-controls > .nx-icon-btn:not(.nx-icon-btn + .nx-icon-btn):first-of-type {
  margin-left: auto !important;
}

/* Force toolbar to flex with proper alignment for left+right grouping */
.toolbar,
.kanban-controls,
.list-controls {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  flex-wrap: wrap !important;
}

/* Tooltip color contrast on warning/danger variants */
.nx-icon-btn.nx-icon-warning {
  background: var(--warning, var(--warning));
  color: var(--surface);
  border-color: var(--warning, var(--warning));
}
.nx-icon-btn.nx-icon-warning:hover {
  background: #C2410C;
  border-color: #C2410C;
  color: var(--surface);
}

/* ===== /css/v2/icons.css?v=1 ===== */
/* Nexora v4 icon size normalization — consistent svg sizes everywhere. */

svg.icon, .icon svg, [class*="icon-"] svg {
  stroke: currentColor;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

.icon-12, svg.icon-12 { width: 12px !important; height: 12px !important; stroke-width: 2 !important; }
.icon-13, svg.icon-13 { width: 13px !important; height: 13px !important; stroke-width: 1.85 !important; }
.icon-14, svg.icon-14 { width: 14px !important; height: 14px !important; stroke-width: 1.85 !important; }
.icon-15, svg.icon-15 { width: 15px !important; height: 15px !important; stroke-width: 1.85 !important; }
.icon-16, svg.icon-16 { width: 16px !important; height: 16px !important; stroke-width: 1.75 !important; }
.icon-17, svg.icon-17 { width: 17px !important; height: 17px !important; stroke-width: 1.75 !important; }
.icon-18, svg.icon-18 { width: 18px !important; height: 18px !important; stroke-width: 1.75 !important; }
.icon-20, svg.icon-20 { width: 20px !important; height: 20px !important; stroke-width: 1.75 !important; }
.icon-22, svg.icon-22 { width: 22px !important; height: 22px !important; stroke-width: 1.75 !important; }
.icon-24, svg.icon-24 { width: 24px !important; height: 24px !important; stroke-width: 1.5 !important; }

/* ===== /css/v2/tree-gantt.css?v=1 ===== */
/* Nexora v4 — Unified Project Tree + Gantt view.
   Left column: collapsible task hierarchy.
   Right column: synchronized gantt timeline (horizontal scroll). */

.tg-wrap {
  display: flex;
  background: var(--surface, var(--surface));
  border: 1px solid var(--border, var(--border));
  border-radius: var(--radius-md, 12px);
  box-shadow: var(--shadow-card, 0 1px 2px rgba(15,15,30,.04));
  overflow: hidden;
  max-height: calc(100vh - 200px);
  min-height: 400px;
  position: relative;
}

/* ── LEFT column: tree ─────────────────────────────────────── */
.tg-left {
  flex: 0 0 380px;
  min-width: 280px;
  max-width: 480px;
  border-right: 1px solid var(--border, var(--border));
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  background: var(--surface);
}

.tg-left::-webkit-scrollbar { width: 6px; }
.tg-left::-webkit-scrollbar-thumb {
  background: var(--border-strong, var(--muted-light));
  border-radius: 3px;
}

.tg-header {
  position: sticky;
  top: 0;
  z-index: 3;
  height: 40px;
  display: flex;
  align-items: center;
  padding: 0 16px;
  background: var(--bg, #FAFAF7);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-body, Inter, sans-serif);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted, var(--text-muted));
}

/* Tree row */
.tg-row {
  height: 36px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  border-bottom: 1px solid var(--border-soft, var(--border));
  cursor: pointer;
  font-family: var(--font-body, Inter, sans-serif);
  font-size: 13px;
  color: var(--text, var(--text));
  transition: background 120ms ease;
  user-select: none;
}
.tg-row:hover { background: var(--bg-hover, #F0EDE5); }

.tg-row .tg-chevron {
  width: 14px; height: 14px;
  flex-shrink: 0;
  color: var(--muted);
  transition: transform 180ms ease;
}
.tg-row.is-open .tg-chevron { transform: rotate(90deg); }
.tg-row.is-leaf .tg-chevron { visibility: hidden; }

.tg-row .tg-icon {
  width: 16px; height: 16px;
  flex-shrink: 0;
  color: var(--muted);
}

.tg-row .tg-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 400;
}

/* Level-specific styles */
.tg-row[data-level="project"] {
  background: var(--bg, #FAFAF7);
  font-weight: 600;
  font-family: var(--font-display, Fraunces, Georgia, serif);
  font-size: 14px;
  letter-spacing: -0.015em;
  border-bottom: 1px solid var(--border);
}
.tg-row[data-level="project"] .tg-icon { color: var(--text); }
.tg-row[data-level="project"]:hover { background: var(--bg-hover); }

.tg-row[data-level="epic"] {
  background: var(--brand-fade, rgba(80,70,229,0.06));
  font-weight: 500;
  padding-left: 32px;
}
.tg-row[data-level="epic"]:hover { background: var(--brand-strong, rgba(80,70,229,0.12)); }
.tg-row[data-level="epic"] .tg-icon { color: var(--brand, var(--brand)); }

.tg-row[data-level="task"]    { padding-left: 56px; font-size: 12.5px; }
.tg-row[data-level="subtask"] { padding-left: 80px; font-size: 12px; color: var(--text-2, var(--text)); }

.tg-row .tg-meta {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-left: auto;
  flex-shrink: 0;
}

/* ── RIGHT column: gantt timeline ─────────────────────────── */
.tg-right {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: auto;
  scrollbar-width: thin;
  position: relative;
  background: var(--surface);
}

.tg-right::-webkit-scrollbar { width: 6px; height: 6px; }
.tg-right::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.tg-right::-webkit-scrollbar-track { background: transparent; }

.tg-timeline {
  display: flex;
  flex-direction: column;
  min-width: 100%;
}

/* Sticky month-header row */
.tg-timeline-header {
  position: sticky;
  top: 0;
  z-index: 3;
  height: 40px;
  display: flex;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.tg-month {
  flex-shrink: 0;
  padding: 0 8px;
  display: flex;
  align-items: center;
  border-right: 1px solid var(--border-soft, var(--border));
  text-transform: uppercase;
  white-space: nowrap;
}

/* Bar row — same height as tree row for alignment */
.tg-bar-row {
  position: relative;
  height: 36px;
  border-bottom: 1px solid var(--border-soft, var(--border));
  background: linear-gradient(
    to right,
    var(--surface) 0,
    var(--surface) 100%
  );
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(var(--tg-day-width, 16px) * 7 - 1px),
    var(--border-soft, var(--border)) calc(var(--tg-day-width, 16px) * 7 - 1px),
    var(--border-soft, var(--border)) calc(var(--tg-day-width, 16px) * 7)
  );
}

.tg-bar {
  position: absolute;
  top: 8px;
  height: 20px;
  border-radius: 4px;
  background: var(--brand, var(--brand));
  color: var(--surface);
  font-size: 10.5px;
  font-weight: 500;
  display: flex;
  align-items: center;
  padding: 0 6px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: filter 120ms ease, transform 120ms ease;
}
.tg-bar:hover {
  filter: brightness(1.1);
  z-index: 5;
}

/* Bar variants by status */
.tg-bar[data-status="Done"]    { background: var(--success, var(--success)); }
.tg-bar[data-status="Doing"],
.tg-bar[data-status="In Progress"] { background: var(--info, var(--info)); }
.tg-bar[data-status="Review"]  { background: var(--warning, var(--warning)); }
.tg-bar[data-status="Backlog"],
.tg-bar[data-status="To Do"]   { background: var(--muted, var(--text-muted)); }
.tg-bar.is-overdue             { background: var(--danger, var(--danger)); }

/* Project-level bar is taller and more prominent */
.tg-bar[data-level="project"] {
  height: 24px;
  top: 6px;
  background: var(--text, #1A1A1F);
  font-weight: 600;
}

/* Epic-level bar - brand outlined */
.tg-bar[data-level="epic"] {
  height: 18px;
  top: 9px;
  background: var(--brand-fade, rgba(80,70,229,0.18));
  color: var(--brand);
  border: 1.5px solid var(--brand);
}

/* Today vertical line */
.tg-today-line {
  position: absolute;
  top: 40px;
  bottom: 0;
  width: 2px;
  background: var(--danger, var(--danger));
  opacity: 0.5;
  z-index: 2;
  pointer-events: none;
}
.tg-today-line::before {
  content: 'TODAY';
  position: absolute;
  top: -16px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--danger);
  color: var(--surface);
  font-size: 9px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
  letter-spacing: 0.04em;
}

/* Weekend column tint (within bar rows) — subtle */
.tg-weekend-tint {
  position: absolute;
  top: 40px;
  bottom: 0;
  background: rgba(15, 15, 30, 0.02);
  pointer-events: none;
  z-index: 1;
}

/* Empty state */
.tg-empty {
  padding: 48px 24px;
  text-align: center;
  font-family: var(--font-body);
  color: var(--muted);
  font-size: 13px;
}

/* Mobile fallback — stack columns, hide gantt */
@media (max-width: 760px) {
  .tg-wrap { flex-direction: column; max-height: none; }
  .tg-left { flex: 1 1 auto; max-width: none; border-right: none; border-bottom: 1px solid var(--border); }
  .tg-right { display: none; }
}

/* ===== /css/v2/legacy-shim.css?v=99 ===== */
/* Nexora v3 legacy shim — surgical overrides for legacy specificity wins. */

/* ── Kill hover-lift transforms everywhere (editorial: no lift) ──── */
.card:hover,
.kpi-card:hover,
.chart-card:hover,
.team-card:hover,
.nav-item:hover {
  transform: none !important;
}

/* ── Kill heavy box-shadows on cards (border-first) ─────────────── */
.kpi-card,
.chart-card,
.team-card {
  box-shadow: none !important;
}
.card:hover,
.kpi-card:hover,
.chart-card:hover,
.team-card:hover {
  box-shadow: none !important;
}

/* ── Force consistent border-radius (editorial 12) ──────────────── */
.kpi-card,
.chart-card,
.team-card {
  border-radius: var(--radius-md) !important;
}

/* ── Force consistent border color ──────────────────────────────── */
.kpi-card,
.chart-card {
  border-color: var(--border) !important;
}

/* ── Inline-style button overrides: enforce text legibility ────── */
/* Buttons with style="background:var(--xxx-light);color:var(--xxx)" lose
   readability against cream bg. Force border to make them visible. */
button[style*="background:var(--purple-light)"],
button[style*="background:var(--yellow-light)"],
button[style*="background:var(--red-light)"],
button[style*="background:var(--green-light)"] {
  border-radius: var(--radius-xs) !important;
}

/* ── Cancel backdrop-blur anywhere ─────────────────────────────── */
* {
  -webkit-backdrop-filter: none;
}
.topbar,
.dropdown,
.menu,
.popover {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* But keep modal overlay solid bg (set in v2/modal.css) */

/* ── Toolbars: enforce horizontal alignment ────────────────────── */
.toolbar,
.kanban-controls {
  display: flex !important;
  align-items: center !important;
  gap: var(--space-3) !important;
  flex-wrap: wrap !important;
}

.toolbar > button,
.toolbar > select,
.toolbar > input,
.kanban-controls > button,
.kanban-controls > select,
.kanban-controls > input {
  margin: 0 !important;
}

/* ── Heading font-family enforcement (Fraunces) ─────────────────── */
.section-title,
#pageTitle,
h1,
h2,
h3 {
  font-family: var(--font-display) !important;
}

/* ── Body text font-family enforcement (Inter) ──────────────────── */
body, p, span, div, td, th, li, label {
  font-family: var(--font-body);
}
input, select, textarea, button {
  font-family: var(--font-body) !important;
}

/* ── Tabular-num default on data cells & KPI numbers ──────────── */
.kpi-value, .kpi-card .value, .kpi-card .number,
table td, table th {
  font-variant-numeric: tabular-nums;
}

/* ── Avatar background fix (legacy hardcoded indigo) ────────────── */
.avatar {
  background: var(--brand-fade) !important;
  color: var(--brand) !important;
}

/* ══════════════════════════════════════════════════════════════════
   HIGH-SPECIFICITY OVERRIDES — defeat inline styles + ID rules
   ══════════════════════════════════════════════════════════════════ */

/* Universal button rules with ID-level specificity boost via attribute selector */
button[class~="btn"]:not(.btn-sm):not(.btn-lg):not(.btn-icon):not(.btn-full):not(.btn-block):not(.topbar-icon-btn) {
  height: 40px !important;
  min-height: 40px !important;
  padding: 0 var(--space-4) !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  font-family: var(--font-body) !important;
}

button[class~="btn-sm"] {
  height: 32px !important;
  min-height: 32px !important;
  padding: 0 var(--space-3) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
}

button[class~="btn-lg"] {
  height: 48px !important;
  min-height: 48px !important;
  padding: 0 var(--space-5) !important;
  font-size: 15px !important;
}

/* Topbar icon button family */
button.topbar-icon-btn {
  height: 36px !important;
  min-height: 36px !important;
  min-width: 36px !important;
  padding: 0 var(--space-3) !important;
  font-size: 13px !important;
}

/* Specific known-bad ID overrides */
#btnCmdK {
  height: 36px !important;
  padding: 0 var(--space-3) !important;
  font-size: 13px !important;
}
#sendBtn {
  height: 40px !important;
  padding: 0 var(--space-4) !important;
  font-size: 14px !important;
  font-weight: 500 !important;
}
#kbRecordBtn {
  height: 40px !important;
  padding: 0 var(--space-5) !important;
  font-size: 14px !important;
}

/* Force consistent font-size across body/inputs/labels */
body,
p,
span,
div,
td,
th,
li,
label {
  font-family: var(--font-body) !important;
}
body { font-size: 14.5px !important; }

input, select, textarea {
  font-size: 14px !important;
  font-family: var(--font-body) !important;
  height: 40px !important;
}
textarea { height: auto !important; min-height: 110px !important; }

/* Sidebar nav font */
.nav-item, .nav-label {
  font-size: 13.5px !important;
  font-family: var(--font-body) !important;
  font-weight: 450 !important;
}

/* Badge font sizes */
.type-badge {
  font-size: 11.5px !important;
  font-family: var(--font-body) !important;
}

/* Card-title / section-title / modal-title font-family lock */
.section-title,
#pageTitle,
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-display) !important;
}

/* Cancel all transform on hover (anti-bounce, anti-lift) */
*:hover { transform: none !important; }
.card:hover,
.kpi-card:hover,
.nav-item:hover,
.sub-tab:hover {
  transform: none !important;
}

/* ══════════════════════════════════════════════════════════════════
   FORM PADDING FIX — inputs no longer touch modal border
   ══════════════════════════════════════════════════════════════════ */

/* Modal: flex column with JS-injected .nx-modal-scroll wrapper.
   Pattern: [title] [scroll-area] [actions] — actions always reachable. */

.modal > .nx-modal-scroll {
  flex: 1 1 auto !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
  padding: 22px 28px !important;
  scrollbar-width: thin;
}
.modal > .nx-modal-scroll::-webkit-scrollbar { width: 6px; }
.modal > .nx-modal-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.modal > .nx-modal-scroll::-webkit-scrollbar-track { background: transparent; }

.modal > h1:first-child,
.modal > h2:first-child,
.modal > h3:first-child {
  flex: 0 0 auto !important;
  padding: 22px 28px 16px !important;
  margin: 0 !important;
  border-bottom: 1px solid var(--border) !important;
  background: var(--surface) !important;
}

.modal > .nx-modal-scroll > form {
  margin: 0 !important;
  padding: 0 !important;
}

/* Form row gap */

/* Input internal padding (skip date/time/inputs inside icon-wraps that
   need extra left padding for their absolute-positioned icon). */
.modal input:not([type="checkbox"]):not([type="radio"]):not([type="date"]):not([type="time"]):not([type="datetime-local"]),
.modal select,
.modal textarea {
  padding: 0 14px !important;
}
.modal textarea { padding: 12px 14px !important; }

/* Date/time inputs inside .date-wrap — left padding for icon, right padding
   for native browser calendar picker icon. */
.modal .date-wrap input[type="date"],
.modal .date-wrap input[type="time"],
.modal .date-wrap input[type="datetime-local"] {
  padding: 0 14px 0 38px !important;
}

/* Date/time inputs NOT inside .date-wrap (bare) — keep symmetric padding. */
.modal input[type="date"]:not(.date-wrap input),
.modal input[type="time"]:not(.date-wrap input),
.modal input[type="datetime-local"]:not(.date-wrap input) {
  padding: 0 14px !important;
}

/* Same treatment for inputs inside .input-wrap or .search-box (left icon).
   Applies to all .input-wrap inputs including login screen, not just modals. */
.modal .input-wrap input,
.modal .search-box input,
#loginScreen .input-wrap input {
  padding-left: 38px !important;
  padding-right: 14px !important;
}
/* Ensure input-icon stays vertically centered + correct color */
.input-wrap {
  position: relative !important;
}
.input-wrap .input-icon {
  position: absolute !important;
  left: 13px !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  color: var(--muted, #71717A) !important;
  pointer-events: none !important;
  display: flex !important;
  align-items: center !important;
}
.input-wrap .input-icon svg {
  width: 15px !important;
  height: 15px !important;
}

/* If form is wrapped in <form>, give it padding instead */
.modal > form {
  padding: 0 32px !important;
  margin: 0 !important;
}

/* Fixed-bottom action footer (flex item — last child of .modal) */
.modal > .modal-actions {
  flex: 0 0 auto !important;
  padding: 14px 28px !important;
  margin: 0 !important;
  border-top: 1px solid var(--border) !important;
  background: var(--surface) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: flex-end !important;
  gap: 10px !important;
  flex-wrap: wrap;
}

/* Modal with the new .modal-body wrapper (v3 modals): keep flex behavior */
.modal:has(.modal-body) > .modal-actions {
  position: static !important;
}

/* Mobile: full-screen sheet — actions still pinned to bottom */
@media (max-width: 600px) {
  .modal > .form-group,
  .modal > .form-row { margin-left: 20px !important; margin-right: 20px !important; }
  .modal > form { padding: 0 20px !important; }
  .modal > .modal-actions {
    padding: 14px 20px !important;
    padding-bottom: max(14px, env(safe-area-inset-bottom)) !important;
  }
}

/* ══════════════════════════════════════════════════════════════════
   RIGHT-ALIGN PRIMARY ACTION BUTTONS — universal across toolbars
   ══════════════════════════════════════════════════════════════════ */

/* Buttons matching these IDs always sit at the far right of their row.
   Covers: New / Add / Export / Import / Download / Save / Submit families.
   Works regardless of whether parent is .toolbar / .kanban-controls /
   .section-head / .page-header / generic <div style="display:flex">. */

/* Group 1: action initiators ("+ New", "+ Add", etc.) */
button[id^="btnNew"],
button[id^="btnAdd"],
button[id^="btnCreate"],
button[id^="btnExport"],
button[id^="btnImport"],
button[id^="btnDownload"],
button[id^="btnUpload"],
button[id^="btnGenerate"],
button[id^="btnSubmit"],
button[id^="btnConfirm"] {
  margin-left: auto !important;
}

/* Group 2: subsequent buttons IN THE SAME ROW after a "btnNew*"-class
   primary should NOT also have margin-left:auto (only first one gets it).
   They form a right-aligned button group. */
button[id^="btnNew"]  ~ button,
button[id^="btnAdd"]  ~ button,
button[id^="btnCreate"] ~ button,
button[id^="btnExport"] ~ button,
button[id^="btnDownload"] ~ button {
  margin-left: 8px !important;
}

/* Group 3: when a row contains a .btn-primary that is NOT after a btnNew/Add,
   push it right too — covers dynamic JS-rendered primary buttons that
   don't follow the btnNew* naming convention. */

/* Page-level action rows (e.g. button bar at top of a section) */
.page > .toolbar,
.page-section > .toolbar {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  flex-wrap: wrap !important;
}

/* Specific known exceptions: confirmImport in import flow is a CTA in a
   confined area where right-align would look odd — let it stay where it is. */
.import-bar > button[id^="btnConfirm"] {
  margin-left: 0 !important;
}

/* Ensure header/toolbar buttons have consistent height when grouped */
.toolbar > button,
.kanban-controls > button,
.section-head > button {
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════════
   Views button — match LEFT-side filter heights (40px not 32px)
   ══════════════════════════════════════════════════════════════════ */

.sv-btn,
button.sv-btn,
.toolbar > .sv-btn,
.kanban-controls > .sv-btn {
  height: 40px !important;
  min-height: 40px !important;
  padding: 0 12px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--text-2) !important;
  border-radius: var(--radius-sm, 8px) !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  /* Override the right-align auto-margin so Views stays with LEFT group */
  margin-left: 0 !important;
}

.sv-btn:hover,
button.sv-btn:hover {
  background: var(--bg-hover) !important;
  border-color: var(--border-strong) !important;
  color: var(--text) !important;
}

.sv-btn svg {
  width: 15px !important;
  height: 15px !important;
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════════
   Table action buttons (Edit/Delete/View in <td>)
   — borderless, icon-only, hover wash
   ══════════════════════════════════════════════════════════════════ */

td .btn svg,
td .btn-sm svg,
tbody td .btn svg,
tbody td .btn-sm svg {
  width: 15px !important;
  height: 15px !important;
  stroke-width: 1.75;
  display: block;
}

/* Variant-specific hover colors (semantic hint on hover) */

/* Tree view action buttons (similar pattern, also in detail tables) */

/* ══════════════════════════════════════════════════════════════════
   Toolbar order — uniform LEFT→RIGHT layout across all pages
   search → filters → Views → result count → ... → action CTAs
   ══════════════════════════════════════════════════════════════════ */

.toolbar,
.kanban-controls {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  flex-wrap: wrap !important;
}

/* 10 — Search box (always leftmost) */
.toolbar > .search-box,
.kanban-controls > .search-box,
.list-controls > .search-box { order: 10 !important; }

/* 20 — Filter selects (status, priority, project, etc.) */
.toolbar > select,
.toolbar > .filter-select,
.kanban-controls > select,
.kanban-controls > .filter-select,
.list-controls > select { order: 20 !important; }

/* 25 — Date pickers / numeric inputs used as filters */
.toolbar > input[type="date"],
.toolbar > input[type="number"],
.kanban-controls > input[type="date"] { order: 25 !important; }

/* 30 — Views button (sv-btn) — sits AFTER filters */
.toolbar > .sv-btn,
.kanban-controls > .sv-btn,
.list-controls > .sv-btn { order: 30 !important; }

/* 40 — Result count (right of Views, before the right-aligned action group) */
.toolbar > .result-count,
.toolbar > .count,
.toolbar > [id$="Count"],
.kanban-controls > .result-count,
.kanban-controls > .count,
.kanban-controls > [id$="Count"],
.list-controls > .result-count { order: 40 !important; }

/* 100 — Action buttons (auto pushed right via existing margin-left:auto rule) */
.toolbar > button[id^="btn"],
.toolbar > .exp-btn,
.toolbar > .nx-icon-btn,
.kanban-controls > button[id^="btn"],
.kanban-controls > .exp-btn,
.kanban-controls > .nx-icon-btn { order: 100 !important; }

/* ══════════════════════════════════════════════════════════════════
   Kanban card — type badge + action buttons
   ══════════════════════════════════════════════════════════════════ */

/* Type badge: smaller text, hairline border, muted v4 semantic colors */
.type-badge {
  display: inline-flex !important;
  align-items: center !important;
  gap: 3px !important;
  font-family: var(--font-body) !important;
  font-size: 9.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  padding: 1px 6px !important;
  border-radius: var(--radius-xs, 4px) !important;
  line-height: 1.2 !important;
  flex-shrink: 0;
}

.type-badge.epic {
  background: rgba(124,58,237,0.10) !important;
  color: #7C3AED !important;
  border: 1px solid rgba(124,58,237,0.20) !important;
}
.type-badge.task {
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
  border: 1px solid var(--brand-strong, rgba(80,70,229,0.22)) !important;
}
.type-badge.subtask {
  background: var(--success-bg, rgba(22,163,74,0.10)) !important;
  color: var(--success, #16A34A) !important;
  border: 1px solid rgba(22,163,74,0.22) !important;
}

/* Card action buttons (Detail / Eval / +Sub / Edit / Delete) — icon-only */
.task-card .nx-card-action,
.task-card button.nx-card-action {
  width: 28px !important;
  min-width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-xs, 6px) !important;
  color: var(--muted) !important;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease !important;
}

.task-card .nx-card-action:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}

.task-card .nx-card-action svg {
  width: 14px !important;
  height: 14px !important;
  stroke-width: 1.75;
}

/* Danger action — red hover tint */
.task-card .nx-card-action-danger:hover {
  background: var(--danger-bg, rgba(220,38,38,0.10)) !important;
  color: var(--danger, #DC2626) !important;
  border-color: rgba(220,38,38,0.22) !important;
}

/* Task-actions row alignment */
.task-card .task-actions {
  display: flex !important;
  align-items: center !important;
  gap: 4px !important;
  margin-top: 8px !important;
  padding-top: 8px !important;
  border-top: 1px solid var(--border-soft, var(--border)) !important;
}

/* ══════════════════════════════════════════════════════════════════
   NUCLEAR override — every <button> inside .task-card OR .task-actions
   forced to icon-only. Defeats any legacy CSS / inline style.
   ══════════════════════════════════════════════════════════════════ */

.task-card button,
.task-card .task-actions button,
.task-actions button {
  width: 28px !important;
  min-width: 28px !important;
  height: 28px !important;
  min-height: 28px !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: 6px !important;
  color: var(--muted) !important;
  font-size: 0 !important;          /* hides any stray text label */
  line-height: 1 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer;
  box-shadow: none !important;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease !important;
  flex: 0 0 auto !important;
}

.task-card button:hover,
.task-actions button:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
  transform: none !important;
}

/* Danger variant hover — red tint */
.task-card .nx-card-action-danger:hover,
.task-actions .nx-card-action-danger:hover {
  background: var(--danger-bg, rgba(220,38,38,0.10)) !important;
  color: var(--danger, #DC2626) !important;
  border-color: rgba(220,38,38,0.22) !important;
}

/* Force icon size inside card buttons */
.task-card button svg,
.task-actions button svg {
  width: 14px !important;
  height: 14px !important;
  stroke-width: 1.75 !important;
  display: block !important;
}

/* Action row layout */
.task-card .task-actions,
.task-actions {
  display: flex !important;
  align-items: center !important;
  gap: 4px !important;
  margin-top: 8px !important;
  padding-top: 8px !important;
  border-top: 1px solid var(--border-soft, var(--border)) !important;
  flex-wrap: wrap !important;
}

/* ══════════════════════════════════════════════════════════════════
   Project Tree — action buttons icon-only style (Gantt → Tree tab)
   Match the v4 kanban card action pattern. Defeat inline color styles.
   ══════════════════════════════════════════════════════════════════ */

.tree-action-btn,
button.tree-action-btn {
  width: 28px !important;
  min-width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: 6px !important;
  color: var(--muted) !important;
  font-size: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  cursor: pointer;
  box-shadow: none !important;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease !important;
}

.tree-action-btn:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
  transform: none !important;
}

/* Hover semantic — detect intent from inline color */
.tree-action-btn[style*="--purple"]:hover {
  background: rgba(124,58,237,0.10) !important;
  color: #7C3AED !important;
  border-color: rgba(124,58,237,0.22) !important;
}
.tree-action-btn[style*="--yellow"]:hover {
  background: var(--warning-bg, rgba(234,88,12,0.10)) !important;
  color: var(--warning, #EA580C) !important;
  border-color: rgba(234,88,12,0.22) !important;
}
.tree-action-btn[style*="--red"]:hover {
  background: var(--danger-bg, rgba(220,38,38,0.10)) !important;
  color: var(--danger, #DC2626) !important;
  border-color: rgba(220,38,38,0.22) !important;
}

.tree-action-btn svg {
  width: 13px !important;
  height: 13px !important;
  stroke-width: 1.75 !important;
  display: block !important;
}

/* "+ Add Task" primary button in project tree row — icon-only with brand tint */
.tree-add-task-btn,
button.tree-add-task-btn {
  width: 32px !important;
  height: 32px !important;
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
  border: 1px solid transparent !important;
  border-radius: 6px !important;
}
.tree-add-task-btn:hover {
  background: var(--brand-strong, rgba(80,70,229,0.22)) !important;
  color: var(--brand, #5046E5) !important;
  border-color: var(--brand, #5046E5) !important;
}
.tree-add-task-btn svg {
  width: 15px !important;
  height: 15px !important;
  stroke-width: 2 !important;
}

/* Tree actions row layout */
.tree-actions {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════════
   PROJECT TREE — v4 editorial restyling
   Replaces dark-gradient headers, purple-tinted rows, etc.
   ══════════════════════════════════════════════════════════════════ */

.tree-project-block {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md, 12px) !important;
  margin-bottom: 16px !important;
  overflow: hidden !important;
  box-shadow: var(--shadow-card, 0 1px 2px rgba(15,15,30,.04)) !important;
}

/* Project header — clean surface with hairline accent, NOT dark gradient */
.tree-project-header {
  background: var(--surface) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 14px 18px !important;
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  cursor: pointer;
  transition: background 150ms ease !important;
  filter: none !important;
}
.tree-project-header:hover {
  background: var(--bg-hover) !important;
  filter: none !important;
}

.tree-project-title {
  font-family: var(--font-display, 'Fraunces', serif) !important;
  font-size: 16px !important;
  font-weight: 500 !important;
  letter-spacing: -0.015em !important;
  color: var(--text) !important;
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.tree-project-toggle {
  color: var(--muted) !important;
  flex-shrink: 0;
  transition: transform 200ms ease !important;
}
.tree-project-toggle.open { transform: rotate(90deg) !important; }

/* Stats strip — quiet subtle bg with hairline */
.tree-project-stats {
  display: flex !important;
  align-items: center !important;
  gap: 20px !important;
  padding: 10px 18px !important;
  background: var(--surface-soft, var(--bg)) !important;
  border-bottom: 1px solid var(--border) !important;
  flex-wrap: wrap !important;
  font-family: var(--font-body) !important;
}

.tree-stat {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px !important;
  color: var(--muted) !important;
}
.tree-stat strong {
  color: var(--text) !important;
  font-weight: 600 !important;
  font-variant-numeric: tabular-nums;
}
.tree-stat svg { color: var(--muted) !important; }

/* Progress bar — brand color, no teal gradient */
.tree-progress-bar {
  height: 5px !important;
  background: var(--surface-soft, var(--bg-hover)) !important;
  border-radius: 9999px !important;
  overflow: hidden !important;
  width: 80px !important;
}
.tree-progress-fill {
  height: 100% !important;
  background: var(--brand, #5046E5) !important;
  border-radius: 9999px !important;
}

/* Epic row — subtle brand-fade tint, not flashy purple */
.tree-epic {
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 10px 18px !important;
  display: flex !important;
  align-items: flex-start !important;
  cursor: pointer;
  transition: background 150ms ease !important;
}
.tree-epic:hover {
  background: var(--brand-strong, rgba(80,70,229,0.12)) !important;
}
.tree-epic-toggle {
  width: 20px; height: 20px;
  color: var(--brand, #5046E5) !important;
  flex-shrink: 0;
  margin-right: 4px;
}
.tree-epic-icon {
  width: 22px !important; height: 22px !important;
  background: var(--brand, #5046E5) !important;
  border-radius: 5px !important;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  margin-right: 8px;
  color: #fff !important;
}
.tree-epic-icon svg { color: #fff !important; filter: none !important; }
.tree-epic-title {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
  letter-spacing: -0.005em;
}
.tree-epic-meta {
  display: flex; align-items: center; gap: 8px;
  margin-top: 4px; flex-wrap: wrap;
  font-size: 11.5px;
  color: var(--muted) !important;
}

/* Epic children container — subtle lighter bg */
.tree-epic-children {
  background: var(--surface) !important;
}

/* Task row */
.tree-task {
  background: var(--surface) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 9px 18px 9px 54px !important;
  display: flex; align-items: flex-start;
  transition: background 150ms ease !important;
}
.tree-task:hover { background: var(--bg-hover) !important; }
.tree-task .tree-task-title {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  color: var(--text) !important;
}

/* Subtask row — slight indent + softer */
.tree-subtask {
  background: var(--surface-soft, var(--bg)) !important;
  border-bottom: 1px solid var(--border) !important;
  padding-left: 80px !important;
}

/* ══════════════════════════════════════════════════════════════════
   GANTT CHART — v4 editorial restyling
   ══════════════════════════════════════════════════════════════════ */

.gantt-project-block { margin-bottom: 24px !important; }

.gantt-project-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-bottom: 2px solid var(--brand, #5046E5) !important;
  border-radius: var(--radius-md, 12px) var(--radius-md, 12px) 0 0 !important;
  padding: 16px 22px !important;
  box-shadow: var(--shadow-card, 0 1px 2px rgba(15,15,30,.04)) !important;
}

.gantt-project-card-title {
  font-family: var(--font-display, 'Fraunces', serif) !important;
  font-size: 16px !important;
  font-weight: 500 !important;
  letter-spacing: -0.015em !important;
  color: var(--text) !important;
}

.gantt-project-card-meta {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
  gap: 16px !important;
}

.gantt-project-progress { gap: 5px !important; }
.gantt-progress-bar {
  background: var(--surface-soft, var(--bg-hover)) !important;
  border-radius: 9999px !important;
  height: 6px !important;
}
.gantt-progress-fill {
  background: var(--brand, #5046E5) !important;
  border-radius: 9999px !important;
}

/* Gantt wrap = bottom half of card */
.gantt-wrap {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-top: none !important;
  border-radius: 0 0 var(--radius-md, 12px) var(--radius-md, 12px) !important;
  box-shadow: var(--shadow-card) !important;
}

/* Gantt legend dots — semantic v4 colors */
.gantt-legend-item {
  font-family: var(--font-body) !important;
  font-size: 11.5px !important;
  color: var(--muted) !important;
}
.gantt-legend-dot {
  width: 10px !important; height: 10px !important;
  border-radius: 3px !important;
}

/* Gantt area scrollbar */
.gantt-area::-webkit-scrollbar { height: 5px !important; }
.gantt-area::-webkit-scrollbar-thumb {
  background: var(--border-strong, #D8D4CB) !important;
  border-radius: 3px !important;
}

/* Row labels */
.gantt-row-label {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  color: var(--text-2, var(--text)) !important;
  border-right: 1px solid var(--border) !important;
  padding: 9px 16px !important;
}

/* Gantt bars — use semantic colors */
.gantt-bar {
  border-radius: 4px !important;
  background: var(--brand, #5046E5) !important;
  height: 22px !important;
}
.gantt-bar.done,
.gantt-bar[data-status="Done"] { background: var(--success, #16A34A) !important; }
.gantt-bar.doing,
.gantt-bar[data-status="Doing"] { background: var(--info, #2563EB) !important; }
.gantt-bar.review,
.gantt-bar[data-status="Review"] { background: var(--warning, #EA580C) !important; }
.gantt-bar.backlog,
.gantt-bar[data-status="Backlog"],
.gantt-bar.todo { background: var(--muted, #A1A1AA) !important; }
.gantt-bar.overdue,
.gantt-bar[data-overdue="1"] { background: var(--danger, #DC2626) !important; }

/* Dark mode tweaks */
[data-theme="dark"] .tree-project-header { background: var(--surface) !important; }
[data-theme="dark"] .tree-epic { background: rgba(129,140,248,0.10) !important; }
[data-theme="dark"] .tree-epic:hover { background: rgba(129,140,248,0.16) !important; }
[data-theme="dark"] .tree-project-stats { background: var(--surface-soft) !important; }

/* ═════════════════════════════════════════════════════════════════
   PRODUCT CARDS — Unified borderless icon-btn style for ANY button
   rendered inside Roadmap / Personas / Feedback / Metrics / Releases
   / Hypotheses / Competitors / Product Docs cards.
   Overrides legacy .btn .btn-warning .btn-danger .btn-ghost .btn-sm
   so all in-card actions look like the v4 nx-icon-btn pattern.
   ═════════════════════════════════════════════════════════════════ */
.init-add-feat-btn {
  /* Wipe legacy variant backgrounds + borders */
  background: transparent !important;
  border: 1px solid transparent !important;
  color: var(--muted, #71717A) !important;
  /* Square icon button geometry */
  width: 28px !important;
  height: 28px !important;
  min-width: 28px !important;
  padding: 0 !important;
  border-radius: 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 0 !important;
  /* Kill text labels — only icons visible */
  font-size: 0 !important;
  line-height: 0 !important;
  letter-spacing: 0 !important;
  box-shadow: none !important;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease !important;
  cursor: pointer !important;
}

/* Icon sizing inside card buttons — consistent 16px across cards */
.initiative-card button.btn svg,
.init-feature-actions button.btn svg,
.init-add-feat-btn svg,
.persona-card button.btn svg,
.feedback-card button.btn svg,
.fr-card button.btn svg,
.metric-card button.btn svg,
.release-card button.btn svg,
.release-card-actions button.btn svg,
.hypothesis-card button.btn svg,
.competitor-card button.btn svg,
.doc-card button.btn svg,
.okr-card button.btn svg,
.kr-item button.btn svg,
.team-card button.btn svg,
#page-team .action-cell button.btn svg,
#page-vendors .action-cell button.btn svg,
#page-skills .action-cell button.btn svg {
  width: 16px !important;
  height: 16px !important;
  stroke-width: 1.75 !important;
  display: block !important;
  flex-shrink: 0 !important;
}

/* Hover state — subtle bg fill */
.init-add-feat-btn:hover {
  background: var(--bg-hover, rgba(15,15,30,0.04)) !important;
  color: var(--text, #18181B) !important;
  border-color: var(--border, #E4E4E7) !important;
}

/* Variant tints carried over via class — Edit (warning) = brand,
   Delete (danger) = red. Visible on hover so the action is clear. */

/* "Add Feature" footer button on initiative cards — keep it inline-flex
   with a visible label since it lives outside the action row. */
.init-add-feat-btn {
  width: auto !important;
  min-width: 0 !important;
  padding: 6px 12px !important;
  font-size: 12px !important;
  line-height: 1 !important;
  gap: 6px !important;
  color: var(--brand, #5046E5) !important;
  border: 1px dashed var(--brand-strong, rgba(80,70,229,0.32)) !important;
  background: transparent !important;
  border-radius: 8px !important;
  font-weight: 500 !important;
}
.init-add-feat-btn:hover {
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  border-style: solid !important;
}

/* OKR "+ Key Result" button — keep visible label, treat as CTA (like Add Feature).
   Only the btn-primary inside .okr-card-header counts as the CTA; Edit/Delete remain icon-only. */
.okr-card .okr-card-header button.btn-primary svg {
  width: 14px !important;
  height: 14px !important;
}

/* Product Doc cards already use .doc-card-btn / .doc-card-del — those
   are not .btn but they need the same v4 borderless aesthetic. */
.doc-card .doc-card-btn,
.doc-card .doc-card-del {
  background: transparent !important;
  border: 1px solid transparent !important;
  width: 28px !important;
  height: 28px !important;
  padding: 0 !important;
  border-radius: 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--muted, #71717A) !important;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease !important;
}
.doc-card .doc-card-btn svg,
.doc-card .doc-card-del svg {
  width: 16px !important;
  height: 16px !important;
  stroke-width: 1.75 !important;
}
.doc-card .doc-card-btn:hover {
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  color: var(--brand, #5046E5) !important;
  border-color: var(--brand-strong, rgba(80,70,229,0.22)) !important;
}
.doc-card .doc-card-del:hover {
  background: rgba(220,38,38,0.06) !important;
  color: var(--danger, #DC2626) !important;
  border-color: rgba(220,38,38,0.22) !important;
}

/* ═════════════════════════════════════════════════════════════════
   ADMIN → MODULES — v4 normalization
   Renders dynamic cards with inline styles using legacy CSS vars
   (--accent-light, --yellow-light). Force v4 surfaces + brand indigo.
   ═════════════════════════════════════════════════════════════════ */
#page-modules { padding: 16px 0 !important; }

/* Header card */
#page-modules > #modulesAdminRoot > .card:first-child > div > div:first-child > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 17px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
#page-modules > #modulesAdminRoot > .card:first-child > div > div:first-child > div:last-child {
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  color: var(--muted) !important;
}

/* "X / Y enabled" badge — brand fade pill */

/* "Unsaved" pending badge — amber */

/* "Core · always on" lock badge */

/* Save / Discard / Reset buttons (Admin > Modules & Permissions) are
   now nx-icon-btn — just enforce disabled state */
#page-modules #modSaveBtn:disabled,
#page-modules #modResetBtn:disabled,
#page-permissions #permSaveBtn:disabled,
#page-permissions #permDiscardBtn:disabled,
#page-permissions #permResetBtn:disabled {
  opacity: 0.4 !important;
  cursor: not-allowed !important;
  filter: none !important;
}

/* ═════════════════════════════════════════════════════════════════
   PLATFORM PAGES — v4 normalization for all platform-* pages
   Tenants, Users, Sessions, AI Usage, Audit Log tables.
   ═════════════════════════════════════════════════════════════════ */
[id^="page-platform"] .toolbar > button {
  /* Inherit nx-icon-btn styles via class — for any leftover .btn */
  height: 32px !important;
}
/* Toolbar order — Platform toolbars miss the CSS order from .toolbar
   rules because they're dynamically rendered. Force right-align for
   action buttons (New, etc.). */
[id^="page-platform"] .toolbar > button.nx-icon-btn,
[id^="page-platform"] .toolbar > button[id^="btn"] {
  order: 100 !important;
  margin-left: auto !important;
}
[id^="page-platform"] .toolbar > .result-count {
  order: 40 !important;
  margin-left: 0 !important;
}
[id^="page-platform"] .toolbar > button.nx-icon-btn + button.nx-icon-btn,
[id^="page-platform"] .toolbar > .nx-icon-btn ~ .nx-icon-btn {
  margin-left: 4px !important;
}
/* Table action cells in Platform pages → borderless v4 icon buttons,
   matching Product card / Team table treatment. */
[id^="page-platform"] .action-cell,
[id^="page-platform"] td.action-cell {
  display: inline-flex !important;
  gap: 2px !important;
  align-items: center !important;
}
[id^="page-platform"] td button.nx-icon-btn {
  width: 28px !important;
  height: 28px !important;
}
/* Chart header (Tenant detail panel) — flatten + brand close button */
[id^="page-platform"] .chart-header {
  display: flex !important;
  align-items: flex-start !important;
  justify-content: space-between !important;
  gap: 12px !important;
  margin-bottom: 16px !important;
  padding-bottom: 12px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
[id^="page-platform"] .chart-title {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 16px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
[id^="page-platform"] .chart-subtitle {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
  margin-top: 2px !important;
}

/* Category group cards */
/* Category header band */
#page-modules #modGroups > .card > div:first-child {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 10px 16px !important;
}
#page-modules #modGroups > .card > div:first-child > span:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
  letter-spacing: 0.06em !important;
}
#page-modules #modGroups > .card > div:first-child > span:last-child {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  color: var(--muted) !important;
}

/* Module rows */
#page-modules .mod-row {
  padding: 12px 16px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  transition: background 120ms ease !important;
}
#page-modules .mod-row:hover {
  background: var(--bg) !important;
}
#page-modules .mod-row:last-child { border-bottom: none !important; }
#page-modules .mod-row > div > div:first-child {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#page-modules .mod-row > div > div:last-child {
  font-family: var(--mono, ui-monospace, monospace) !important;
  font-size: 11px !important;
  color: var(--muted) !important;
}
/* Checkbox accent → brand indigo */
#page-modules .mod-toggle {
  accent-color: var(--brand, #5046E5) !important;
  width: 16px !important;
  height: 16px !important;
}

/* ═════════════════════════════════════════════════════════════════
   PROJECT DETAIL PAGE — Overview tab vertical-line cleanup
   The grid has decorative card borders that visually stack into long
   vertical lines down the page. Soften + remove unwanted dividers.
   ═════════════════════════════════════════════════════════════════ */

/* Kill any pseudo-element vertical dividers on the grid wrapper itself. */
#projectDetailRoot .pd-grid::before,
#projectDetailRoot .pd-grid::after {
  display: none !important;
  content: none !important;
}
/* Project detail page — ensure every wrapper fills full width so the
   Overview grid matches the visual width of other tabs (Tasks, Risks,
   etc.) which naturally span 100%. */
#projectDetailRoot {
  max-width: none !important;
  width: 100% !important;
  margin: 0 !important;
}
#projectDetailRoot > div,
#projectDetailRoot #projDetailTabContent {
  width: 100% !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}
/* The Overview grid — fill full tab content width, dynamically split
   left:right with left flexing. Right column clamped 320px–600px. */
#projectDetailRoot .pd-grid {
  display: grid !important;
  width: 100% !important;
  max-width: 100% !important;
  grid-template-columns: minmax(0, 1fr) minmax(320px, clamp(320px, 33%, 600px)) !important;
  gap: 20px !important;
  box-sizing: border-box !important;
}
#projectDetailRoot .pd-grid > div,
#projectDetailRoot .pd-grid > aside {
  width: 100% !important;
  min-width: 0 !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}
/* Grid column wrappers — make sure left/right columns never carry borders
   or backgrounds (those create the perceived vertical line).
   Right column (aside) becomes a flex column so AI Summary grows to fill
   any vertical space, eliminating the empty gap at the bottom. */
#projectDetailRoot .pd-grid > div,
#projectDetailRoot .pd-grid > aside {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}
#projectDetailRoot .pd-grid {
  align-items: stretch !important;
}
/* Right column = grid row layout where AI Summary expands (1fr) and
   KPI Stack stays natural size (auto) at the bottom. This forces the
   AI card to fill any remaining vertical space so the right column
   matches the left column height exactly — zero dead air below. */
#projectDetailRoot .pd-grid > aside {
  display: grid !important;
  grid-template-rows: 1fr auto !important;
  grid-row-gap: 8px !important;
  align-self: stretch !important;
}
#projectDetailRoot .pd-grid > aside > .pd-ai {
  margin: 0 !important;
  /* Card content stacks vertically so the body can flex inside it. */
  display: flex !important;
  flex-direction: column !important;
  min-height: 0 !important;
}
#projectDetailRoot .pd-grid > aside > .pd-ai .pd-ai-body {
  flex: 1 1 auto !important;
  overflow-y: auto !important;
  min-height: 0 !important;
}
#projectDetailRoot .pd-grid > aside > .pd-kpi-stack {
  margin: 0 !important;
}
/* AI Summary card border — strip the colored accent border that draws a
   prominent vertical line on the card's left edge. Keep the bg tint. */
#projectDetailRoot .pd-ai {
  border: 1px solid var(--brand-strong, rgba(80,70,229,0.22)) !important;
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  box-shadow: none !important;
  /* Tight grouping — AI Summary flows directly into the KPI stack. */
  margin: 0 0 8px !important;
  padding: 14px 16px !important;
}
/* KPI stack — unified 8px rhythm with AI Summary above */
#projectDetailRoot .pd-kpi-stack {
  gap: 8px !important;
  margin-top: 0 !important;
}
#projectDetailRoot .pd-kpi {
  margin: 0 !important;
}
/* Section + KPI cards — soft 1px border, no left/right decoration. */
#projectDetailRoot .pd-section,
#projectDetailRoot .pd-kpi {
  border: 1px solid var(--border) !important;
  box-shadow: none !important;
  background: var(--surface, #fff) !important;
}
/* Hero card */
#projectDetailRoot .pd-hero {
  border: 1px solid var(--border) !important;
  background: var(--surface, #fff) !important;
  box-shadow: none !important;
}
/* Remove the horizontal divider above progress that some browsers render
   as a hairline gap looking like a stray line. */
#projectDetailRoot .pd-hero-progress {
  border-top: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}

/* ═════════════════════════════════════════════════════════════════
   TASK DETAIL & HISTORY DRAWER — v4 normalization
   The drawer rendered by openTaskDrawer() contains many tabs with
   forms and lists. Override legacy inline styles + drawer-tabs.
   ═════════════════════════════════════════════════════════════════ */
#taskDrawer {
  width: 580px !important;
}
#taskDrawer .drawer-header {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 16px 22px !important;
}
#taskDrawer .drawer-header > div:first-child > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 17px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
#taskDrawer .drawer-body {
  padding: 16px 22px !important;
  background: var(--surface) !important;
}

/* Inline Edit button in header (legacy btn-warning) → nx-icon-btn style */
#taskDrawer #drawerTaskBadges button.btn svg {
  width: 12px !important;
  height: 12px !important;
}

/* Drawer tabs (Updates / Comments / Time / etc.) */
#taskDrawer .drawer-tabs {
  display: flex !important;
  gap: 2px !important;
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  padding: 3px !important;
  border-radius: 10px !important;
  margin-bottom: 16px !important;
  /* overflow visible so tooltips can escape upward */
  overflow: visible !important;
  /* Distribute tabs evenly across full width */
  justify-content: space-between !important;
  position: relative !important;
}
#taskDrawer .drawer-tab {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  padding: 6px 10px !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: 7px !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  color: var(--muted) !important;
  cursor: pointer !important;
  transition: all 120ms ease !important;
  white-space: nowrap !important;
  position: relative !important;
}
#taskDrawer .drawer-tab svg {
  width: 12px !important;
  height: 12px !important;
}
/* Icon-only tab variant — flex 1 so all tabs share equal width
   across the full drawer-tabs container (no left-clumping). */
#taskDrawer .drawer-tab.is-icon-only {
  flex: 1 1 0 !important;
  min-width: 0 !important;
  height: 32px !important;
  padding: 0 !important;
  justify-content: center !important;
  align-items: center !important;
}
#taskDrawer .drawer-tab.is-icon-only svg {
  width: 15px !important;
  height: 15px !important;
}
/* Count badge for Evaluations tab — small dot in top-right corner */
#taskDrawer .drawer-tab.is-icon-only .tab-count {
  position: absolute !important;
  top: 2px !important;
  right: 2px !important;
  background: var(--brand, #5046E5) !important;
  color: #fff !important;
  font-family: var(--font-body) !important;
  font-size: 9px !important;
  font-weight: 700 !important;
  min-width: 14px !important;
  height: 14px !important;
  border-radius: 7px !important;
  padding: 0 4px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  line-height: 1 !important;
}
/* Tooltip on hover — positioned BELOW the tab. Drawer is position:fixed
   with transform (containing block) + drawer-body has overflow:auto, so
   tooltips above clip outside top edge. Below puts tooltip safely
   inside scrollable area where z-index can layer it above content. */
#taskDrawer .drawer-tab.is-icon-only[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  background: var(--text, #18181B);
  color: var(--card, #FFFFFF);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  padding: 5px 9px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease, transform 120ms ease;
  z-index: 999999;
  box-shadow: 0 4px 12px rgba(15,15,30,0.15);
}
#taskDrawer .drawer-tab.is-icon-only:hover::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* Tooltip arrow — triangle pointing UP to the tab */
#taskDrawer .drawer-tab.is-icon-only[data-tooltip]::before {
  content: '';
  position: absolute;
  top: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-bottom-color: var(--text, #18181B);
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease;
  z-index: 999999;
}
#taskDrawer .drawer-tab.is-icon-only:hover::before {
  opacity: 1;
}
#taskDrawer .drawer-tab:hover {
  color: var(--text) !important;
  background: var(--bg-hover) !important;
}
#taskDrawer .drawer-tab.active {
  background: var(--surface) !important;
  color: var(--brand, #5046E5) !important;
  font-weight: 600 !important;
  box-shadow: 0 1px 2px rgba(15,15,30,0.05) !important;
  border-color: var(--border) !important;
}

/* Tab content panels */
#taskDrawer .tab-content {
  display: none !important;
}
#taskDrawer .tab-content.active {
  display: block !important;
}

/* Drawer section labels — Fraunces small caps */
#taskDrawer .drawer-section-label {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  padding-bottom: 8px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  margin-bottom: 12px !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}
#taskDrawer .drawer-section-label svg {
  width: 13px !important;
  height: 13px !important;
  color: var(--brand) !important;
  flex-shrink: 0 !important;
}
#taskDrawer .drawer-section {
  margin-bottom: 20px !important;
}

/* Detail rows */
#taskDrawer .detail-row {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  padding: 7px 0 !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.05)) !important;
  font-size: 12px !important;
}
#taskDrawer .detail-row:last-child { border-bottom: none !important; }
#taskDrawer .detail-label {
  color: var(--muted) !important;
  font-family: var(--font-body) !important;
  font-weight: 500 !important;
}
#taskDrawer .detail-value {
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  font-weight: 600 !important;
  text-align: right !important;
}

/* "Add Update" form panel */
#taskDrawer .history-form {
  background: var(--bg, #FAFAF7) !important;
  border: 1px dashed var(--brand-strong, rgba(80,70,229,0.32)) !important;
  border-radius: 10px !important;
  padding: 14px !important;
}
#taskDrawer .history-form-title {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
  letter-spacing: -0.005em !important;
  margin-bottom: 12px !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}
#taskDrawer .history-form-title svg {
  width: 13px !important;
  height: 13px !important;
  color: var(--brand) !important;
}
#taskDrawer .history-form .form-label svg {
  width: 11px !important;
  height: 11px !important;
}

/* All buttons inside tab-content and sections → unified v4 */

/* Save Update / primary actions */

/* + Add Evaluation (btn-purple) — recolor to brand */
#taskDrawer .tab-content button.btn-purple {
  background: var(--brand, #5046E5) !important;
  border-color: var(--brand) !important;
  color: #fff !important;
}
#taskDrawer .tab-content button.btn-purple:hover {
  background: var(--brand) !important;
  color: #fff !important;
  filter: brightness(1.08) !important;
}

/* Danger (delete) */

/* Drawer close button */
#taskDrawer .drawer-close {
  background: transparent !important;
  border: 1px solid transparent !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  border-radius: 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--muted) !important;
  transition: all 120ms ease !important;
}
#taskDrawer .drawer-close:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}
#taskDrawer .drawer-close svg { width: 16px !important; height: 16px !important; }

/* No history / empty state */
#taskDrawer .no-history {
  color: var(--muted) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  text-align: center !important;
  padding: 24px !important;
  background: var(--bg) !important;
  border: 1px dashed var(--border) !important;
  border-radius: 10px !important;
}

/* ── UPDATES tab — timeline items ─────────────────────────────── */
#taskDrawer .timeline {
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
  position: relative !important;
}
#taskDrawer .timeline-item {
  position: relative !important;
  padding-left: 22px !important;
}
#taskDrawer .timeline-dot {
  position: absolute !important;
  left: 6px !important;
  top: 6px !important;
  width: 10px !important;
  height: 10px !important;
  border-radius: 50% !important;
  background: var(--brand, #5046E5) !important;
  border: 2px solid var(--surface, #fff) !important;
  box-shadow: 0 0 0 1px var(--brand-strong, rgba(80,70,229,0.32)) !important;
  z-index: 1 !important;
}
#taskDrawer .timeline-dot.has-obstacle {
  background: var(--orange, #ea580c) !important;
  box-shadow: 0 0 0 1px rgba(234,88,12,0.32) !important;
}
#taskDrawer .timeline-item:not(:last-child)::before {
  content: '' !important;
  position: absolute !important;
  left: 11px !important;
  top: 16px !important;
  bottom: -12px !important;
  width: 1px !important;
  background: var(--border-soft, rgba(15,15,30,0.08)) !important;
}
#taskDrawer .timeline-date {
  font-family: var(--font-body) !important;
  font-size: 10.5px !important;
  color: var(--muted) !important;
  margin-bottom: 6px !important;
  display: flex !important;
  align-items: center !important;
  gap: 4px !important;
  flex-wrap: wrap !important;
}
#taskDrawer .timeline-date svg {
  width: 11px !important;
  height: 11px !important;
}
#taskDrawer .timeline-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  padding: 12px !important;
  position: relative !important;
}
#taskDrawer .timeline-update {
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  color: var(--text) !important;
  line-height: 1.55 !important;
  word-break: break-word !important;
}
#taskDrawer .obstacle-box {
  background: rgba(234,88,12,0.06) !important;
  border-left: 3px solid var(--orange, #ea580c) !important;
  border-radius: 6px !important;
  padding: 8px 10px !important;
  margin-top: 8px !important;
  font-size: 12px !important;
  color: var(--text) !important;
  line-height: 1.5 !important;
}
#taskDrawer .solution-box {
  background: rgba(22,163,74,0.06) !important;
  border-left: 3px solid var(--success, #16A34A) !important;
  border-radius: 6px !important;
  padding: 8px 10px !important;
  margin-top: 6px !important;
  font-size: 12px !important;
  color: var(--text) !important;
  line-height: 1.5 !important;
}
#taskDrawer .obstacle-label,
#taskDrawer .solution-label {
  font-family: var(--font-body) !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  margin-bottom: 4px !important;
  display: flex !important;
  align-items: center !important;
  gap: 4px !important;
}
#taskDrawer .obstacle-label { color: var(--orange, #ea580c) !important; }
#taskDrawer .solution-label { color: var(--success, #16A34A) !important; }
#taskDrawer .obstacle-label svg,
#taskDrawer .solution-label svg { width: 11px !important; height: 11px !important; }
#taskDrawer .timeline-actions {
  display: flex !important;
  justify-content: flex-end !important;
  margin-top: 8px !important;
}
#taskDrawer .timeline-actions button.btn svg {
  width: 13px !important;
  height: 13px !important;
}

/* ── COMMENTS tab ─────────────────────────────────────────────── */
#taskDrawer #taskCommentsContainer > div[style*="display:flex;gap:8px"] {
  margin-bottom: 12px !important;
}
/* Avatar circle */
#taskDrawer #taskCommentsContainer > div > div[style*="border-radius:50%"][style*="background:var(--accent)"] {
  background: var(--brand, #5046E5) !important;
  color: #fff !important;
}
/* Comment input row */
#taskDrawer #taskCommentsContainer input[type="text"],
#taskDrawer #taskCommentsContainer input[id^="commentInput"] {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  border-radius: 8px !important;
  font-family: var(--font-body) !important;
  padding: 8px 12px !important;
  font-size: 12px !important;
  transition: border-color 120ms ease !important;
}
#taskDrawer #taskCommentsContainer input[type="text"]:focus {
  border-color: var(--brand) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}

/* ── TIME tab ─────────────────────────────────────────────────── */
#taskDrawer #taskTimeContainer input[type="number"],
#taskDrawer #taskTimeContainer input[type="text"] {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  border-radius: 8px !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  padding: 7px 10px !important;
}
#taskDrawer #taskTimeContainer input:focus {
  border-color: var(--brand) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}
/* Time entry list row borders */
#taskDrawer #taskTimeContainer > div[style*="border-bottom"] {
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}

/* ── DEPS / APPROVALS tabs ────────────────────────────────────── */

/* ── ACTIVITY LOG tab ─────────────────────────────────────────── */
#taskDrawer .activity-log-wrap {
  display: flex !important;
  flex-direction: column !important;
  gap: 4px !important;
}
#taskDrawer .activity-log-wrap > div {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  border-radius: 10px !important;
  padding: 10px 12px !important;
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  transition: background 120ms ease !important;
}
#taskDrawer .activity-log-wrap > div:hover {
  background: var(--surface) !important;
  border-color: var(--border) !important;
}
/* Activity icon circle */
#taskDrawer .activity-log-wrap > div > div:first-child {
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
}

/* Generic legacy var fallbacks inside drawer body */
#taskDrawer .drawer-body input[style*="--bg-secondary"],
#taskDrawer .drawer-body input[style*="--text-primary"] {
  background: var(--surface) !important;
  color: var(--text) !important;
}

/* Comments / Time / Deps / Approvals containers */
#taskDrawer #taskCommentsContainer,
#taskDrawer #taskTimeContainer,
#taskDrawer #taskDepsContainer,
#taskDrawer #taskApprovalsContainer {
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
}

/* Eval list */
#taskDrawer #taskEvalList > div {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  padding: 12px !important;
  margin-bottom: 8px !important;
}

/* ═════════════════════════════════════════════════════════════════
   PROJECT DETAIL DRAWER — v4 normalization
   Drawer rendered by openProjectDrawer() has many inline-styled sub-cards
   and buttons (Sprints/Milestones/Budgets/CRs/Retros). Override to v4.
   ═════════════════════════════════════════════════════════════════ */

/* Drawer container itself */
#projectDrawer {
  width: 560px !important;
}
#projectDrawer .drawer-header {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 18px 22px !important;
}
#projectDrawer .drawer-header > div:first-child > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
#projectDrawer .drawer-body {
  padding: 18px 22px !important;
  background: var(--surface) !important;
}

/* Section labels — Fraunces small caps */
#projectDrawer .drawer-section-label {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  padding-bottom: 8px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  margin-bottom: 12px !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}
#projectDrawer .drawer-section-label svg {
  width: 13px !important;
  height: 13px !important;
  color: var(--brand, #5046E5) !important;
  flex-shrink: 0 !important;
}
#projectDrawer .drawer-section {
  margin-bottom: 22px !important;
}

/* PM/PMO cards */
#projectDrawer .pm-pmo-cards {
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  gap: 10px !important;
}
#projectDrawer .pm-card {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  padding: 12px !important;
}
#projectDrawer .pm-card.is-pm {
  border-left: 3px solid var(--brand, #5046E5) !important;
}
#projectDrawer .pm-card.is-pmo {
  border-left: 3px solid var(--teal, #14b8a6) !important;
}
#projectDrawer .pm-card-type {
  font-family: var(--font-body) !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  color: var(--muted) !important;
  margin-bottom: 6px !important;
}
#projectDrawer .pm-avatar-sm {
  width: 32px !important;
  height: 32px !important;
  border-radius: 50% !important;
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 12px !important;
  font-weight: 700 !important;
  margin-bottom: 6px !important;
}
#projectDrawer .pm-name {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#projectDrawer .pm-role {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  color: var(--muted) !important;
  margin-top: 2px !important;
}

/* Detail rows (Project Info section) */
#projectDrawer .detail-row {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  padding: 8px 0 !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.05)) !important;
  font-size: 12px !important;
}
#projectDrawer .detail-row:last-child { border-bottom: none !important; }
#projectDrawer .detail-label {
  color: var(--muted) !important;
  font-family: var(--font-body) !important;
  font-weight: 500 !important;
}
#projectDrawer .detail-value {
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  font-weight: 600 !important;
  text-align: right !important;
}

/* All buttons inside drawer-section → v4 unified */

/* Primary (Activate / Create / Add) — brand fill */

/* Complete / Achieve (inline bg green) — recolor to v4 success */

/* Danger (× delete) — red ghost */

/* Sprint / Milestone item cards — fix var(--bg-secondary) undefined */
#projectDrawer .drawer-section div[style*="background:var(--bg-secondary)"] {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
}

/* "New Sprint" / "Add milestone" dashed-border form rows */
#projectDrawer .drawer-section div[style*="border:1px dashed"] {
  background: var(--bg, #FAFAF7) !important;
  border: 1px dashed var(--brand-strong, rgba(80,70,229,0.32)) !important;
  border-radius: 10px !important;
  padding: 12px !important;
}

/* Form inputs inside drawer (sprint name, dates, etc.) */

/* Mini task / risk items */
#projectDrawer .mini-task-item,
#projectDrawer .mini-risk-item {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  border-radius: 8px !important;
  padding: 10px 12px !important;
  margin-bottom: 6px !important;
}
#projectDrawer .mini-task-title,
#projectDrawer .mini-risk-title {
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
  margin-bottom: 4px !important;
}
#projectDrawer .mini-task-meta,
#projectDrawer .mini-risk-meta {
  display: flex !important;
  gap: 4px !important;
  flex-wrap: wrap !important;
}

/* Description box */
#projectDrawer .drawer-section div[style*="white-space:pre-wrap"] {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  padding: 12px !important;
  font-family: var(--font-body) !important;
  color: var(--text) !important;
  line-height: 1.6 !important;
}

/* Drawer close button → nx-icon-btn style */
#projectDrawer .drawer-close {
  background: transparent !important;
  border: 1px solid transparent !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  border-radius: 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--muted) !important;
  transition: all 120ms ease !important;
}
#projectDrawer .drawer-close:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}
#projectDrawer .drawer-close svg {
  width: 16px !important;
  height: 16px !important;
}

/* ═════════════════════════════════════════════════════════════════
   TODAY PAGE — v4 normalization (today.js renders everything via
   inline styles using legacy --accent purple. Override to v4 brand.)
   ═════════════════════════════════════════════════════════════════ */
#page-today .section-title {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 12.5px !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.08em !important;
  color: var(--muted) !important;
  margin: 24px 0 12px !important;
}

/* Greeting card */
#page-today > div > .card:first-child > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 26px !important;
  font-weight: 600 !important;
  letter-spacing: -0.02em !important;
  color: var(--text) !important;
}
#page-today > div > .card:first-child > div:nth-child(2) {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
}
#page-today > div > .card:first-child > div:nth-child(3) {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  color: var(--text-2, var(--text)) !important;
  font-weight: 400 !important;
}

/* Quick action buttons */

/* Task cards — flat v4 with brand left-border preserved (priority) */

/* Bucket column headers (Overdue / Due today / etc.) */
#page-today div[style*="display:flex"][style*="align-items:center"][style*="gap:6px"] > span[style*="background:var(--bg-hover)"] {
  background: var(--bg-hover, rgba(15,15,30,0.06)) !important;
  color: var(--text) !important;
  font-family: var(--mono, ui-monospace, monospace) !important;
}

/* Risk list card */
#page-today .card[style*="padding:0"][style*="overflow:hidden"] > div {
  transition: background 120ms ease !important;
}
#page-today .card[style*="padding:0"][style*="overflow:hidden"] > div:hover {
  background: var(--bg-hover) !important;
}

/* Project cards */
/* Project progress bar — brand fill */
#page-today .card[style*="cursor:pointer"][style*="padding:14px"] div[style*="background:var(--accent)"] {
  background: var(--brand, #5046E5) !important;
}

/* Accent text → brand */
#page-today [style*="color:var(--accent)"] {
  color: var(--brand, #5046E5) !important;
}

/* Empty state */
#page-today .empty-state {
  background: var(--surface) !important;
  border: 1px dashed var(--border-strong, #D4D4D8) !important;
  border-radius: 12px !important;
}
#page-today .empty-state-title {
  font-family: var(--font-body) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
#page-today .empty-state-sub {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
}

/* ═════════════════════════════════════════════════════════════════
   PROFILE PAGE — sub-tab nav + v4 card normalization
   For admin level, multiple config cards (Email/SMTP/Schedule/Telegram)
   are now organized into a segmented tab control at the top.
   ═════════════════════════════════════════════════════════════════ */
#page-profile {
  max-width: 880px !important;
  margin: 0 auto !important;
}

/* Profile tab nav (segmented pill control) */
.profile-tabs {
  display: flex !important;
  gap: 4px !important;
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border) !important;
  border-radius: 12px !important;
  padding: 4px !important;
  margin-bottom: 16px !important;
  overflow-x: auto !important;
  scrollbar-width: none !important;
}
.profile-tabs::-webkit-scrollbar { display: none !important; }

.profile-tab {
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  padding: 8px 14px !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: 8px !important;
  color: var(--muted, #71717A) !important;
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  cursor: pointer !important;
  transition: all 120ms ease !important;
  white-space: nowrap !important;
}
.profile-tab svg {
  width: 14px !important;
  height: 14px !important;
  flex-shrink: 0 !important;
}
.profile-tab:hover {
  color: var(--text) !important;
  background: var(--bg-hover, rgba(15,15,30,0.04)) !important;
}
.profile-tab.is-active {
  background: var(--surface, #fff) !important;
  border-color: var(--border) !important;
  color: var(--brand, #5046E5) !important;
  font-weight: 600 !important;
  box-shadow: 0 1px 2px rgba(15,15,30,0.04) !important;
}

/* Unified card v4 styling */
#page-profile .profile-card {
  background: var(--surface, #fff) !important;
  border: 1px solid var(--border) !important;
  border-radius: 12px !important;
  box-shadow: none !important;
  padding: 22px !important;
  margin-bottom: 16px !important;
}

/* Card header band (icon + title + subtitle) */
#page-profile .profile-card > div:first-child[style*="border-bottom"] {
  padding-bottom: 16px !important;
  margin-bottom: 18px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
/* Card header title (the bold "Email Notification Settings" etc.) */
#page-profile .profile-card > div:first-child > div:nth-child(2) > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 16px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
/* Card subtitle */
#page-profile .profile-card > div:first-child > div:nth-child(2) > div:last-child {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
}
/* Header icon round — flatten gradients to brand-fade */
#page-profile .profile-card > div:first-child > div:first-child[style*="border-radius:13px"] {
  background: var(--brand-fade, rgba(80,70,229,0.08)) !important;
  color: var(--brand) !important;
  box-shadow: none !important;
}
#page-profile .profile-card > div:first-child > div:first-child[style*="border-radius:13px"] svg {
  stroke: var(--brand, #5046E5) !important;
}

/* Info boxes (light blue/yellow/purple notice panels) — normalize to v4 */
#page-profile .profile-card div[style*="background:#f0f9ff"],
#page-profile .profile-card div[style*="background:#fffbeb"],
#page-profile .profile-card div[style*="background:#f5f3ff"],
#page-profile .profile-card div[style*="background:#e0f2fe"] {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.08)) !important;
  border-left: 3px solid var(--brand, #5046E5) !important;
  border-radius: 8px !important;
  color: var(--text) !important;
}
#page-profile .profile-card div[style*="background:#f0f9ff"] *,
#page-profile .profile-card div[style*="background:#fffbeb"] *,
#page-profile .profile-card div[style*="background:#f5f3ff"] *,
#page-profile .profile-card div[style*="background:#e0f2fe"] * {
  color: var(--text-2, var(--text)) !important;
}

/* Schedule inner row cards */
#page-profile #notifScheduleCard div[style*="background:var(--bg)"][style*="border-radius:10px"] {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  border-radius: 10px !important;
}

/* Toggle switches — brand color when checked */
#page-profile input[type="checkbox"]:checked + span[id$="Track"],
#page-profile input[type="checkbox"]:checked ~ span[id$="Track"] {
  background: var(--brand, #5046E5) !important;
}
#page-profile input[type="checkbox"]:checked + span[id$="Thumb"],
#page-profile input[type="checkbox"]:checked ~ span[id$="Thumb"] {
  left: 27px !important;
}
#page-profile input#nsOverdueEnabled:checked ~ span[id="nsOverdueThumb"],
#page-profile input#nsWeeklyEnabled:checked ~ span[id="nsWeeklyThumb"],
#page-profile input#nsDigestEnabled:checked ~ span[id="nsDigestThumb"] {
  left: 22px !important;
}

/* Save buttons — brand-filled v4 */

/* Unified form sizing across all profile tabs (Account/Email/SMTP/
   Schedule/Telegram) — override the various inline max-width attrs so
   inputs share one consistent width per card. */
#page-profile .profile-card input[type="text"],
#page-profile .profile-card input[type="email"],
#page-profile .profile-card input[type="password"],
#page-profile .profile-card input[type="number"],
#page-profile .profile-card select,
#page-profile .profile-card textarea {
  max-width: 100% !important;
  width: 100% !important;
  box-sizing: border-box !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  background: var(--surface) !important;
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-size: 13px !important;
  padding: 9px 12px !important;
  transition: border-color 120ms ease, box-shadow 120ms ease !important;
}
#page-profile .profile-card input:focus,
#page-profile .profile-card select:focus,
#page-profile .profile-card textarea:focus {
  border-color: var(--brand, #5046E5) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--brand-fade, rgba(80,70,229,0.10)) !important;
}
/* Form group consistent spacing */
/* Form rows (e.g., side-by-side date inputs) flex equally */
/* Toggle switch container — keep its natural width */
#page-profile .profile-card label[style*="cursor:pointer"][style*="width:50px"],
#page-profile .profile-card label[style*="cursor:pointer"][style*="width:44px"] {
  flex-shrink: 0 !important;
}

/* Password section label */
#page-profile .pw-section {
  margin-top: 22px !important;
  padding-top: 22px !important;
  border-top: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
#page-profile .pw-section-label {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
  color: var(--text) !important;
  margin-bottom: 14px !important;
}

/* Kanban board width parity with Risks data grid — every wrapper and
   inner element forced to 100% so the right edge lines up identically
   with Risks .table-wrap. Default flex-row of .kanban changed to column
   so per-project blocks stack vertically and span full width. */
#page-tasks > .toolbar,
#page-tasks > .kanban,
#page-tasks .kanban-project-block,
#page-tasks .kanban-project-card {
  width: 100% !important;
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  box-sizing: border-box !important;
}
.kanban,
.kanban-board {
  display: flex !important;
  flex-direction: column !important;
  padding: 0 !important;
  margin: 0 0 var(--space-5) !important;
  overflow: visible !important;
  width: 100% !important;
  box-sizing: border-box !important;
}
/* Columns row inside each project block — flex row, full width */
.kanban-project-block > .kanban-board,
.kanban-project-block > div:not(.kanban-project-card) {
  display: flex !important;
  flex-direction: row !important;
  gap: var(--space-3) !important;
  width: 100% !important;
  padding: 0 !important;
  margin: 0 !important;
  align-items: flex-start !important;
}

/* Restore: ONE bordered panel per project (project card + columns row).
   Columns stretch to fill panel height so the outer border never shows
   "stranded" past a short column's content. */
#page-tasks .kanban-project-block {
  background: var(--surface, #fff) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md, 12px) !important;
  padding: var(--space-4) !important;
  margin-bottom: var(--space-4) !important;
  overflow: hidden !important;
}
#page-tasks .kanban-project-card {
  border: none !important;
  border-radius: 0 !important;
  background: transparent !important;
  padding: 0 0 var(--space-3) !important;
  margin: 0 0 var(--space-3) !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
#page-tasks .kanban-col {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  min-height: 200px !important;
}
/* .kanban-cols is the grid container holding the 4 columns. App.css gives
   it a 1px border (sides + bottom, top:none) that visually framed the
   columns area. Per user, change to 0px so no outer frame is rendered. */
#page-tasks .kanban-cols {
  border: 0px solid var(--border) !important;
  border-top: none !important;
}

/* Availability bottom 2-col grid (Recommendations + Skill Matrix) —
   the right column's table-wrap was overflowing because grid items
   default to min-width:auto. Force min-width:0 so each side can shrink
   to its grid track and the table-wrap's overflow-x:auto kicks in. */
#page-availability > div[style*="grid-template-columns:1fr 1fr"] > div {
  min-width: 0 !important;
  max-width: 100% !important;
  overflow: hidden !important;
}
#page-availability #skillMatrixTable {
  width: 100% !important;
  table-layout: auto !important;
}
/* Columns row stretches all to equal height — fills panel bottom edge
   so the panel border never floats above empty space. */
#page-tasks .kanban-project-block > .kanban-board,
#page-tasks .kanban-project-block > div:not(.kanban-project-card) {
  align-items: stretch !important;
}

/* Kanban card overdue badge — compact, matches surrounding badges */
.task-card .overdue-badge,
.kanban-card .overdue-badge,
.overdue-badge {
  font-size: 9px !important;
  font-weight: 600 !important;
  letter-spacing: 0.03em !important;
  text-transform: uppercase !important;
  padding: 1px 5px !important;
  border-radius: 6px !important;
  gap: 3px !important;
  line-height: 1.4 !important;
  background: rgba(220,38,38,0.08) !important;
  color: var(--danger, #DC2626) !important;
  border: 1px solid rgba(220,38,38,0.20) !important;
  animation: none !important;
}
.overdue-badge svg {
  width: 8px !important;
  height: 8px !important;
  stroke-width: 2.5 !important;
}

/* ═════════════════════════════════════════════════════════════════
   AI QUICK CHAT WIDGET — v4 normalization
   Floating FAB + chat panel with header, suggests, messages, input.
   Override legacy purple gradients with brand indigo + flat surfaces.
   ═════════════════════════════════════════════════════════════════ */

/* FAB — solid brand circle, no gradient */
#aiWidgetFab {
  background: var(--brand, #5046E5) !important;
  border: 1px solid var(--brand) !important;
  color: #fff !important;
  box-shadow: 0 6px 20px -4px rgba(80,70,229,.40), 0 2px 6px rgba(15,15,30,.10) !important;
  transition: filter 150ms ease, transform 150ms ease !important;
}
#aiWidgetFab:hover {
  filter: brightness(1.08) !important;
  transform: translateY(-2px) scale(1.03) !important;
  box-shadow: 0 10px 26px -4px rgba(80,70,229,.50), 0 3px 8px rgba(15,15,30,.12) !important;
}
#aiWidgetFab:active { transform: scale(.96) !important; }
#aiWidgetFab svg {
  width: 22px !important;
  height: 22px !important;
  stroke-width: 1.75 !important;
}

/* Widget panel */
.ai-widget {
  background: var(--surface, #fff) !important;
  border: 1px solid var(--border) !important;
  border-radius: 14px !important;
  box-shadow: 0 18px 48px -12px rgba(15,15,30,.20), 0 4px 12px rgba(15,15,30,.06) !important;
}

/* Header */
.aiw-header {
  background: var(--bg, #FAFAF7) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 14px 16px !important;
}
.aiw-title-icon {
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
  border: 1px solid var(--brand-strong, rgba(80,70,229,0.22)) !important;
  border-radius: 10px !important;
}
.aiw-title-main {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-weight: 600 !important;
  font-size: 14px !important;
  letter-spacing: -0.015em !important;
  color: var(--text) !important;
}
.aiw-title-sub {
  font-family: var(--font-body) !important;
  color: var(--muted) !important;
}

/* Header action buttons — borderless v4 icon style */
.aiw-action-btn {
  width: 30px !important;
  height: 30px !important;
  border: 1px solid transparent !important;
  background: transparent !important;
  color: var(--muted) !important;
  border-radius: 8px !important;
  transition: all 120ms ease !important;
}
.aiw-action-btn:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}

/* Log/intro area */
.aiw-log { background: var(--surface) !important; }
.aiw-intro-title {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
}
.aiw-intro-sub {
  font-family: var(--font-body) !important;
  color: var(--muted) !important;
}

/* Suggest chip buttons — icon + text */
.aiw-suggest {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border) !important;
  color: var(--text-2, var(--text)) !important;
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  font-weight: 500 !important;
  padding: 9px 12px !important;
  border-radius: 10px !important;
  transition: all 120ms ease !important;
  text-align: left !important;
}
.aiw-suggest svg {
  width: 14px !important;
  height: 14px !important;
  flex-shrink: 0 !important;
  color: var(--brand, #5046E5) !important;
}
.aiw-suggest span {
  flex: 1 !important;
  min-width: 0 !important;
}
.aiw-suggest:hover {
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  border-color: var(--brand-strong, rgba(80,70,229,0.32)) !important;
  color: var(--brand, #5046E5) !important;
}

/* Chat messages */
.aiw-msg {
  font-family: var(--font-body) !important;
  line-height: 1.55 !important;
  border-radius: 12px !important;
}
/* Input row */
.aiw-input-row {
  background: var(--surface) !important;
  border-top: 1px solid var(--border) !important;
  padding: 12px 14px !important;
}
#aiWidgetInput {
  background: var(--bg, #FAFAF7) !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  border-radius: 10px !important;
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  padding: 9px 12px !important;
  transition: border-color 120ms ease, box-shadow 120ms ease !important;
}
#aiWidgetInput:focus {
  border-color: var(--brand, #5046E5) !important;
  box-shadow: 0 0 0 3px var(--brand-fade, rgba(80,70,229,0.10)) !important;
  background: var(--surface) !important;
}

/* Send button — brand solid */
#aiWidgetSendBtn {
  background: var(--brand, #5046E5) !important;
  border: 1px solid var(--brand) !important;
  color: #fff !important;
  border-radius: 10px !important;
  transition: filter 120ms ease, transform 120ms ease !important;
  box-shadow: none !important;
}
#aiWidgetSendBtn:hover {
  filter: brightness(1.08) !important;
  transform: none !important;
  box-shadow: 0 2px 6px rgba(80,70,229,.20) !important;
}
#aiWidgetSendBtn svg { width: 15px !important; height: 15px !important; }
#aiWidgetSendBtn:disabled {
  opacity: 0.45 !important;
  filter: none !important;
  cursor: not-allowed !important;
}

/* ═════════════════════════════════════════════════════════════════
   NOTIFICATIONS PANEL — solid surface, no transparency.
   ═════════════════════════════════════════════════════════════════ */
#notifPanel {
  background: var(--surface, #fff) !important;
  backdrop-filter: none !important;
}
#notifPanel #notifList > div {
  transition: background 120ms ease !important;
}
#notifPanel #notifList > div:hover {
  background: var(--bg-hover, rgba(15,15,30,0.04)) !important;
}
#notifPanel .nx-notif-mark-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 6px;
  font-family: var(--font-body, Inter, sans-serif);
  font-size: 11px;
  font-weight: 500;
  padding: 4px 10px;
  cursor: pointer;
  transition: all 120ms ease;
}
#notifPanel .nx-notif-mark-btn:hover {
  background: var(--brand-fade, rgba(80,70,229,0.06));
  color: var(--brand, #5046E5);
  border-color: var(--brand-strong, rgba(80,70,229,0.22));
}

/* When drawer is NOT in .open state, kill all pointer events so the
   off-screen drawer cannot intercept hover/click/etc. Prevents the
   "cursor near right edge → drawer pops back" behavior. */
#taskDrawer:not(.open),
#projectDrawer:not(.open),
#memberDrawer:not(.open) {
  pointer-events: none !important;
}
#drawerOverlayTask:not(.open),
#drawerOverlayProject:not(.open),
#drawerOverlayMember:not(.open) {
  pointer-events: none !important;
  display: none !important;
}

/* ═════════════════════════════════════════════════════════════════
   GLOBAL DRAWER GUARD — the task drawer kept appearing on random
   pages with empty body (no task selected). Force-hide whenever the
   body container is empty — drawer must have content to be visible.
   Same guard for project drawer. Auto-cleans stuck .open states.
   ═════════════════════════════════════════════════════════════════ */
body:has(#taskDrawerBody:empty) #taskDrawer,
body:has(#taskDrawerBody:empty) #drawerOverlayTask {
  display: none !important;
  transform: translateX(100%) !important;
  pointer-events: none !important;
}
body:has(#projectDrawerBody:empty) #projectDrawer,
body:has(#projectDrawerBody:empty) #drawerOverlayProject {
  display: none !important;
  transform: translateX(100%) !important;
  pointer-events: none !important;
}
body:has(#memberDrawerBody:empty) #memberDrawer,
body:has(#memberDrawerBody:empty) #drawerOverlayMember {
  display: none !important;
  transform: translateX(100%) !important;
  pointer-events: none !important;
}

/* Knowledge Base also force-hides ALL drawers (KB has no task/project
   refs). Belt-and-suspenders rule on top of empty-body guard above. */
body:has(#page-kb.active) .drawer,
body:has(#page-kb.active) .drawer-overlay {
  display: none !important;
}

/* ═════════════════════════════════════════════════════════════════
   KNOWLEDGE BASE — v4 normalization
   Fix: heavy border-right between app sidebar and kb-sidebar (visible
   as a thick separator). Solution: kb-sidebar uses page bg so it
   flows into the layout; replace hard border with soft hairline.
   ═════════════════════════════════════════════════════════════════ */
#page-kb .kb-layout {
  background: var(--surface, #fff) !important;
  height: calc(100vh - 80px) !important;
  border-radius: var(--radius-md, 12px) !important;
  border: 1px solid var(--border) !important;
  /* Wider sidebar column so search input + project pills don't crop. */
  grid-template-columns: 240px 1fr !important;
  overflow: hidden !important;
}
/* Both columns same surface tone — eliminates the visible color seam
   that previously made the sidebar look "wrapped" with a thick border. */
#page-kb .kb-sidebar {
  background: var(--surface, #fff) !important;
  border-right: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  min-width: 0 !important;
}
#page-kb .kb-main {
  background: var(--surface, #fff) !important;
  padding: 16px 20px !important;
  min-width: 0 !important;
  overflow-x: hidden !important;
}
/* Search input must respect sidebar width — explicit box-sizing. */
#page-kb .kb-search {
  box-sizing: border-box !important;
  max-width: 100% !important;
}
/* Note cards grid — auto-fit to main width so titles ("DSU Chatcommerce...")
   don't crop. Allow up to 2 columns on narrow widths. */
#page-kb .kb-notes-grid {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important;
  gap: 12px !important;
  width: 100% !important;
}
#page-kb .kb-note-card .kb-card-title {
  overflow-wrap: anywhere !important;
  word-break: break-word !important;
}
/* Editor title input — must wrap, not crop */
#page-kb .kb-title-input {
  width: 100% !important;
  box-sizing: border-box !important;
  white-space: normal !important;
}
#page-kb .kb-sidebar-section {
  padding: 12px 14px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
#page-kb .kb-sidebar-section:last-child { border-bottom: none !important; }
#page-kb .kb-sidebar-label {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.08em !important;
  color: var(--muted, #71717A) !important;
  margin-bottom: 8px !important;
}

/* Search input */
#page-kb .kb-search {
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  background: var(--surface) !important;
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-size: 12px !important;
  padding: 7px 10px !important;
  transition: border-color 120ms ease, box-shadow 120ms ease !important;
}
#page-kb .kb-search:focus {
  border-color: var(--brand, #5046E5) !important;
  background: var(--surface) !important;
  box-shadow: 0 0 0 3px var(--brand-fade, rgba(80,70,229,0.10)) !important;
}

/* Category filter rows */
#page-kb .kb-filter {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  padding: 6px 10px !important;
  border-radius: 7px !important;
  color: var(--text-2, var(--text)) !important;
}
#page-kb .kb-filter:hover {
  background: var(--bg-hover, rgba(15,15,30,0.04)) !important;
  color: var(--brand, #5046E5) !important;
}
#page-kb .kb-filter.active {
  background: var(--brand, #5046E5) !important;
  color: #fff !important;
  font-weight: 600 !important;
}
#page-kb .kb-pinned-item {
  padding: 5px 8px !important;
  font-size: 11.5px !important;
  border-radius: 6px !important;
  color: var(--text-2, var(--text)) !important;
}
#page-kb .kb-pinned-item:hover {
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
  color: var(--brand) !important;
}

/* Top tab bar */
#page-kb .kb-tab-bar {
  margin-bottom: 14px !important;
  padding-bottom: 12px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
#page-kb .kb-tabs {
  background: var(--bg) !important;
  padding: 3px !important;
  border-radius: 8px !important;
  gap: 2px !important;
}
#page-kb .kb-tab {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  padding: 5px 12px !important;
  border-radius: 6px !important;
  color: var(--muted) !important;
  background: transparent !important;
  box-shadow: none !important;
}
#page-kb .kb-tab:hover { color: var(--text) !important; }
#page-kb .kb-tab.active {
  background: var(--surface) !important;
  color: var(--brand, #5046E5) !important;
  font-weight: 600 !important;
  box-shadow: 0 1px 2px rgba(15,15,30,0.04) !important;
}

/* Notes toolbar (sort + per-page) */
#page-kb .kb-notes-toolbar {
  padding: 0 0 10px !important;
  margin-bottom: 12px !important;
  border-bottom: none !important;
}
#page-kb .kb-toolbar-label {
  font-family: var(--font-body) !important;
  font-size: 10.5px !important;
  color: var(--muted) !important;
  font-weight: 600 !important;
}
#page-kb .kb-toolbar-select {
  border: 1px solid var(--border) !important;
  border-radius: 6px !important;
  background: var(--surface) !important;
  font-size: 11.5px !important;
  padding: 4px 8px !important;
}
#page-kb .kb-toolbar-select:focus {
  border-color: var(--brand) !important;
}
#page-kb .kb-results-count {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
}

/* Note cards */
#page-kb .kb-notes-grid {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)) !important;
  gap: 12px !important;
}
#page-kb .kb-note-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  box-shadow: none !important;
  padding: 14px !important;
  transition: border-color 120ms ease, background 120ms ease !important;
}
#page-kb .kb-note-card:hover {
  border-color: var(--brand-strong, rgba(80,70,229,0.32)) !important;
  background: var(--bg) !important;
  transform: none !important;
  box-shadow: none !important;
}
#page-kb .kb-note-card .kb-card-title {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
}
#page-kb .kb-note-card .kb-card-preview {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
}
#page-kb .kb-note-card .kb-card-cat {
  font-family: var(--font-body) !important;
  font-size: 9.5px !important;
  letter-spacing: 0.06em !important;
}
#page-kb .kb-note-card .kb-pin-badge {
  color: var(--brand) !important;
}

/* Editor */
#page-kb .kb-editor-header {
  padding-bottom: 10px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
}
#page-kb .kb-title-input {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 22px !important;
  font-weight: 600 !important;
  letter-spacing: -0.02em !important;
  padding: 6px 0 !important;
}
/* Meeting Notes & Note Editor meta row — unified control sizing.
   Override app.css's max-width:200px so project names don't get cropped
   in fuzzy-select trigger; flex children grow equally; all controls
   share the same height for visual alignment. */
#page-kb .kb-meta-row {
  display: flex !important;
  gap: 10px !important;
  flex-wrap: wrap !important;
  align-items: stretch !important;
}
#page-kb .kb-meta-row > * {
  flex: 1 1 180px !important;
  min-width: 0 !important;
}
#page-kb .kb-meta-select,
#page-kb .kb-meta-input {
  max-width: none !important;
  width: 100% !important;
  height: 36px !important;
  box-sizing: border-box !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  font-family: var(--font-body) !important;
  font-size: 12.5px !important;
  padding: 0 12px !important;
  background: var(--surface) !important;
  color: var(--text) !important;
}
/* Custom select buttons (Audio Source / Language) — match native select
   dimensions exactly. */
#page-kb .kb-custom-select {
  display: flex !important;
  min-width: 0 !important;
}
#page-kb .kb-custom-select-btn.form-select.kb-meta-select {
  width: 100% !important;
  height: 36px !important;
  padding: 0 12px !important;
  font-size: 12.5px !important;
  border-radius: 8px !important;
  background: var(--surface) !important;
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  box-sizing: border-box !important;
}
#page-kb .kb-custom-select-btn .kb-csel-icon {
  width: 14px !important;
  height: 14px !important;
  flex-shrink: 0 !important;
  color: var(--muted) !important;
}
#page-kb .kb-custom-select-btn .kb-csel-chevron {
  width: 14px !important;
  height: 14px !important;
  flex-shrink: 0 !important;
  margin-left: auto !important;
  color: var(--muted) !important;
}
#page-kb .kb-custom-select-btn > span {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

/* Fuzzy-select trigger (when kb-meta-select is converted by fuzzy-select.js)
   — match the 36px height + padding of native select siblings. */
#page-kb .kb-meta-row .nx-fz-wrap {
  flex: 1 1 180px !important;
  min-width: 0 !important;
  display: block !important;
}
#page-kb .kb-meta-row .nx-fz-trigger {
  width: 100% !important;
  min-height: 36px !important;
  height: 36px !important;
  padding: 0 12px !important;
  font-size: 12.5px !important;
  font-family: var(--font-body) !important;
  border-width: 1px !important;
  border-radius: 8px !important;
  background: var(--surface) !important;
  box-sizing: border-box !important;
}
#page-kb .kb-meta-row .nx-fz-label {
  font-size: 12.5px !important;
}
#page-kb .kb-content-textarea {
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  background: var(--bg) !important;
  font-family: var(--mono, ui-monospace, monospace) !important;
  font-size: 13px !important;
  line-height: 1.7 !important;
}
#page-kb .kb-content-textarea:focus {
  border-color: var(--brand) !important;
  background: var(--surface) !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}
#page-kb .kb-backlinks {
  background: var(--bg) !important;
  border: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  border-radius: 8px !important;
}

/* AI menu dropdown */
#page-kb .kb-ai-menu {
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  box-shadow: 0 4px 12px rgba(15,15,30,0.08) !important;
}
#page-kb .kb-ai-menu-item {
  border-radius: 6px !important;
  font-size: 12px !important;
}
#page-kb .kb-ai-menu-item:hover {
  background: var(--brand-fade) !important;
  color: var(--brand) !important;
}

/* Custom select buttons (Audio src / Language) */
#page-kb .kb-custom-select-btn {
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  background: var(--surface) !important;
  font-size: 12px !important;
  padding: 6px 10px !important;
}
#page-kb .kb-custom-select-btn:focus {
  border-color: var(--brand) !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}
#page-kb .kb-custom-select-dropdown {
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  box-shadow: 0 4px 12px rgba(15,15,30,0.08) !important;
}

/* Graph canvas */
#page-kb .kb-graph-canvas {
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  box-shadow: none !important;
}
#page-kb .kb-graph-canvas:hover { box-shadow: none !important; }

/* Meeting view headers */
#page-kb .kb-meeting-header,
#page-kb .kb-summary-label,
#page-kb .kb-transcript-label {
  font-family: var(--font-body) !important;
}

/* ── Editor header & meeting header — all legacy .btn become v4 ──
   Covers Back (kb-editor-header > button), AI/Pin/Save/Delete
   (kb-editor-actions > button), meeting Back, save/copy actions. */
#page-kb .kb-editor-header button.btn svg,
#page-kb .kb-editor-actions button.btn svg,
#page-kb .kb-meeting-header button.btn svg,
#page-kb .kb-graph-controls button.btn svg,
#page-kb .kb-graph-toolbar button.btn svg {
  width: 14px !important;
  height: 14px !important;
  margin: 0 !important;
  vertical-align: middle !important;
  flex-shrink: 0 !important;
}
/* Active Pin state — icon turns brand color */
#page-kb #kbPinBtn.pinned {
  color: var(--brand) !important;
  border-color: var(--brand-strong) !important;
  background: var(--brand-fade) !important;
}
#page-kb #kbPinBtn.pinned svg {
  color: var(--brand) !important;
  fill: var(--brand-fade) !important;
}
/* Gap between editor action buttons */
#page-kb .kb-editor-actions { gap: 4px !important; }
/* Save (primary) inside editor header — brand-filled with label */
/* Delete (danger) — red text/hover */

/* ── Graph toolbar select dropdowns — inline styles use undefined
   v4 vars (--bg-secondary, --text-primary). Force v4 surface. */
/* Shared baseline for all graph toolbar selects — clean v4 chrome only. */
#page-kb .kb-graph-controls select,
#page-kb .kb-graph-select {
  background: var(--surface) !important;
  color: var(--text) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  font-family: var(--font-body) !important;
  font-weight: 500 !important;
  cursor: pointer !important;
  appearance: auto !important;
}

/* All Links filter — wider + smaller text per user request */
#page-kb #kbGraphFilter {
  font-size: 10.5px !important;
  padding: 4px 24px 4px 10px !important;
  height: 28px !important;
  min-width: 150px !important;
}

/* All Categories filter — default sizing */
#page-kb #kbGraphCatFilter {
  font-size: 11.5px !important;
  padding: 4px 24px 4px 10px !important;
  height: 28px !important;
  min-width: 120px !important;
}

/* fuzzy-select popup inside graph toolbar — extend wider than trigger
   so long labels ("Wiki Links", "Auto: Context") don't get ellipsed. */
#page-kb .kb-graph-controls .nx-fz-popup,
#page-kb .kb-graph-toolbar .nx-fz-popup {
  right: auto !important;
  min-width: 220px !important;
  width: max-content !important;
  max-width: 320px !important;
}
#page-kb .kb-graph-controls .nx-fz-item-label,
#page-kb .kb-graph-toolbar .nx-fz-item-label {
  font-size: 12px !important;
}
#page-kb .kb-graph-controls select:focus,
#page-kb #kbGraphFilter:focus,
#page-kb #kbGraphCatFilter:focus {
  border-color: var(--brand) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}

/* Graph toolbar layout — wrap into clean row */
#page-kb .kb-graph-toolbar {
  background: var(--bg) !important;
  border: 1px solid var(--border-soft) !important;
  border-radius: 10px !important;
  padding: 8px 10px !important;
  margin-bottom: 10px !important;
}
#page-kb .kb-graph-controls {
  gap: 4px !important;
}
#page-kb .kb-graph-info {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  color: var(--muted) !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important;
}

/* Graph legend — pull into clean horizontal chips */
#page-kb .kb-graph-legend {
  padding: 8px 12px !important;
  background: var(--bg) !important;
  border: 1px solid var(--border-soft) !important;
  border-radius: 10px !important;
  gap: 6px !important;
  margin-bottom: 10px !important;
}
#page-kb .kb-graph-legend-chip {
  font-family: var(--font-body) !important;
  font-size: 9.5px !important;
  font-weight: 600 !important;
  padding: 2px 8px !important;
  border-radius: 999px !important;
}

/* Restore proper editor textarea height — was 75vh, ensure layout
   doesn't crop it. Editor container needs to be flex parent.
   NOTE: `display: flex` WITHOUT !important so inline `style="display:none"`
   (from initial HTML + kbCloseEditor JS) keeps the editor hidden until
   kbOpenNote clears the inline style. */
#page-kb #kbEditor {
  display: flex;
  flex-direction: column !important;
  flex: 1 !important;
  min-height: 0 !important;
  overflow: hidden !important;
}
#page-kb .kb-editor-form {
  flex: 1 !important;
  min-height: 0 !important;
  overflow-y: auto !important;
}
#page-kb .kb-content-textarea {
  min-height: 60vh !important;
  flex: 1 !important;
}

/* Meeting actions row — primary button keeps label + brand fill */
#page-kb #kbRecordBtn,
#page-kb #kbSummaryBtn {
  background: var(--brand) !important;
  color: #fff !important;
  border: 1px solid var(--brand) !important;
  border-radius: 10px !important;
  padding: 8px 16px !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  height: auto !important;
  box-shadow: none !important;
}

/* Template modal */
.kb-tpl-modal-header {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  font-family: var(--font-display) !important;
}
.kb-tpl-modal-title {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
.kb-template-grid {
  gap: 10px !important;
  padding: 14px !important;
}

/* ═════════════════════════════════════════════════════════════════
   AI ASSISTANT PAGE — v4 normalization
   Flat surfaces · 1px borders · brand indigo accents · Inter/Fraunces.
   Overrides legacy gradients, accent-purple, 1.5px borders, shadows.
   ═════════════════════════════════════════════════════════════════ */
#page-ai .ai-panel {
  background: var(--surface, #fff) !important;
  border: 1px solid var(--border, #E4E4E7) !important;
  border-radius: var(--radius-md, 12px) !important;
  box-shadow: none !important;
}
#page-ai .ai-header {
  background: var(--bg, #FAFAF7) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 12px 16px !important;
  gap: 8px !important;
}
#page-ai .ai-header > div:nth-child(2) > div:first-child {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
#page-ai #aiModelBadge {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--muted) !important;
  font-family: var(--mono, ui-monospace, monospace) !important;
}
#page-ai .ai-dot {
  background: var(--success, #16A34A) !important;
  box-shadow: 0 0 0 3px rgba(22,163,74,0.15) !important;
}

/* Tab buttons — clean v4 pill style with brand indigo active */
#page-ai .ai-tab-btns { gap: 4px !important; }
#page-ai .ai-tab-btn {
  border: 1px solid transparent !important;
  background: transparent !important;
  color: var(--muted) !important;
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  padding: 5px 12px !important;
  border-radius: 8px !important;
  transition: all 120ms ease !important;
}
#page-ai .ai-tab-btn:hover {
  background: var(--bg-hover, rgba(15,15,30,0.04)) !important;
  color: var(--text) !important;
}
#page-ai .ai-tab-btn.active {
  background: var(--brand-fade, rgba(80,70,229,0.08)) !important;
  border-color: var(--brand-strong, rgba(80,70,229,0.22)) !important;
  color: var(--brand, #5046E5) !important;
}

/* Sub-header bands (History / Custom Prompts headers) */
#page-ai .ai-sub-header {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  font-family: var(--font-display) !important;
  font-size: 12px !important;
  letter-spacing: -0.01em !important;
  padding: 10px 16px !important;
}

/* Quick prompts row */
#page-ai .quick-prompts {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 10px 16px !important;
  gap: 6px !important;
}
#page-ai .qp {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  color: var(--muted) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  padding: 4px 10px !important;
  border-radius: 999px !important;
  letter-spacing: 0 !important;
  transition: all 120ms ease !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
}
#page-ai .qp:hover {
  border-color: var(--brand-strong) !important;
  color: var(--brand) !important;
  background: var(--brand-fade) !important;
}
#page-ai .qp svg { width: 11px !important; height: 11px !important; }

/* Doc prompts row (shown when file attached) */
#page-ai .doc-prompts {
  background: var(--brand-fade, rgba(80,70,229,0.04)) !important;
  border-bottom: 1px solid var(--brand-strong, rgba(80,70,229,0.18)) !important;
  padding: 8px 16px !important;
  gap: 6px !important;
}
#page-ai .doc-prompts-label {
  color: var(--brand) !important;
  font-family: var(--font-body) !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
}
#page-ai .dqp {
  background: var(--surface) !important;
  border: 1px solid var(--brand-strong) !important;
  color: var(--brand) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  padding: 4px 10px !important;
  border-radius: 999px !important;
  letter-spacing: 0 !important;
  transition: all 120ms ease !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
}
#page-ai .dqp:hover {
  background: var(--brand) !important;
  color: #fff !important;
  border-color: var(--brand) !important;
}

/* Role prompts bar */
#page-ai .role-prompts {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 8px 16px !important;
}
#page-ai .role-prompts-label {
  color: var(--muted) !important;
  font-family: var(--font-body) !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
}

/* Upload zone */
#page-ai .upload-zone-wrap {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 10px 16px !important;
}
#page-ai .upload-zone {
  background: var(--surface) !important;
  border: 1.5px dashed var(--border-strong, #D4D4D8) !important;
  border-radius: 10px !important;
  padding: 12px 14px !important;
  transition: all 150ms ease !important;
}
#page-ai .upload-zone:hover {
  border-color: var(--brand) !important;
  background: var(--brand-fade) !important;
}
#page-ai .upload-zone.has-file {
  border-color: var(--success) !important;
  background: rgba(22,163,74,0.04) !important;
  border-style: solid !important;
}
#page-ai .upload-zone-icon {
  background: var(--brand-fade) !important;
  border-radius: 8px !important;
}
#page-ai .upload-zone-label {
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  color: var(--text) !important;
}
#page-ai .upload-zone-sub {
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  color: var(--muted) !important;
}

/* Chat messages area */
#page-ai .chat-messages {
  background: var(--bg) !important;
  padding: 16px !important;
}
#page-ai .msg-bubble {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 12px !important;
  box-shadow: none !important;
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  line-height: 1.6 !important;
  padding: 12px 14px !important;
}
#page-ai .msg.user .msg-bubble {
  background: var(--brand-fade) !important;
  border-color: var(--brand-strong) !important;
  color: var(--text) !important;
}
#page-ai .msg-bubble.error-bubble {
  background: rgba(220,38,38,0.04) !important;
  border-color: rgba(220,38,38,0.22) !important;
  color: var(--danger) !important;
}

/* Chat input row */
#page-ai .chat-input-row {
  background: var(--surface) !important;
  border-top: 1px solid var(--border) !important;
}
#page-ai .chat-input {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  padding: 10px 14px !important;
  transition: border-color 120ms ease, background 120ms ease !important;
}
#page-ai .chat-input:focus {
  border-color: var(--brand) !important;
  background: var(--surface) !important;
  box-shadow: 0 0 0 3px var(--brand-fade) !important;
}

/* "Send" button — prominent square button, vertically centered with textarea. */
#page-ai #sendBtn {
  width: 48px !important;
  min-width: 48px !important;
  height: 48px !important;
  align-self: center !important;
  border-radius: 12px !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
#page-ai #sendBtn svg {
  width: 22px !important;
  height: 22px !important;
}
/* Active state on press */
#page-ai #sendBtn:active {
  transform: scale(0.96) !important;
}
/* Disabled state when no text yet */
#page-ai #sendBtn:disabled {
  opacity: 0.45 !important;
  cursor: not-allowed !important;
}

/* API key card */
#page-ai .api-key-card {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md) !important;
  box-shadow: none !important;
  padding: 18px !important;
  margin-bottom: 12px !important;
}
#page-ai .api-key-input-row {
  display: flex !important;
  gap: 8px !important;
  align-items: center !important;
}

/* History & Prompts list items */
#page-ai .ai-history-item,
#page-ai .ai-prompt-item {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  box-shadow: none !important;
  padding: 12px !important;
  transition: border-color 120ms ease, background 120ms ease !important;
}
#page-ai .ai-history-item:hover,
#page-ai .ai-prompt-item:hover {
  border-color: var(--brand-strong) !important;
  background: var(--brand-fade) !important;
}

/* Prompt form inline (Custom Prompts tab) */
#page-ai #aiPromptForm {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
}

/* Save/Cancel buttons inside the inline prompt form */

/* File ext badge — v4 muted style */
#page-ai .file-ext-badge {
  background: var(--brand-fade) !important;
  color: var(--brand) !important;
  font-family: var(--mono) !important;
  border-radius: 4px !important;
}

/* ═════════════════════════════════════════════════════════════════
   TEAM MEMBER CARDS — compact density (Members tab grid)
   Original cards used 24px padding, 48px avatar, 20px stat values.
   Slim down to fit 4-up on wide screens, keep all info legible.
   ═════════════════════════════════════════════════════════════════ */
.team-grid {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)) !important;
  gap: 12px !important;
  margin-bottom: 16px !important;
}
.team-card {
  padding: 14px !important;
  border-radius: var(--radius-md, 12px) !important;
}
.team-card-header {
  gap: 10px !important;
  margin-bottom: 10px !important;
}
/* All avatars unified — flat brand-fade bg with brand text. No purple
   gradient, no heavy shadow. Subtle inset ring as the only border. */
.team-avatar,
.s-avatar,
.profile-big-avatar,
.pm-avatar-sm,
.msg-avatar,
.suggest-avatar,
.avatar {
  background: var(--brand-fade, rgba(80,70,229,0.10)) !important;
  color: var(--brand, #5046E5) !important;
  box-shadow: inset 0 0 0 1px var(--brand-strong, rgba(80,70,229,0.22)) !important;
  border: none !important;
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
}

/* PMO variant — softer teal tint to differentiate from PM (brand) */
.pm-card.is-pmo .pm-avatar-sm {
  background: rgba(20, 184, 166, 0.10) !important;
  color: var(--teal, #14b8a6) !important;
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, 0.25) !important;
}

/* User message avatar in AI chat — subtle neutral instead of brand
   (so the AI "system" avatar with the logo SVG stands out) */
.msg.user .msg-avatar {
  background: var(--bg-hover, rgba(15,15,30,0.05)) !important;
  color: var(--text, #18181B) !important;
  box-shadow: inset 0 0 0 1px var(--border) !important;
}
/* AI Nexora avatar — keep its dark logo bg (handled by inline style),
   strip our brand-fade override since it has visual content not text. */
.msg-avatar[style*="background:#0C1428"],
.msg-avatar[style*="background: #0C1428"] {
  background: #0C1428 !important;
  box-shadow: none !important;
  color: #fff !important;
}
.team-avatar {
  width: 36px !important;
  height: 36px !important;
  border-radius: 10px !important;
  font-size: 13px !important;
}
.s-avatar {
  width: 34px !important;
  height: 34px !important;
  border-radius: 10px !important;
  font-size: 12.5px !important;
}
.profile-big-avatar {
  width: 64px !important;
  height: 64px !important;
  border-radius: 16px !important;
  font-size: 22px !important;
}
.team-card .team-name {
  font-size: 13px !important;
  font-weight: 600 !important;
  line-height: 1.25 !important;
}
.team-card .team-role {
  font-size: 11px !important;
  color: var(--muted) !important;
  margin-top: 1px !important;
}
.team-stats {
  gap: 6px !important;
  margin-top: 10px !important;
  padding-top: 10px !important;
}
.team-stat {
  padding: 5px 2px !important;
  border-radius: 6px !important;
}
.team-stat-val {
  font-size: 15px !important;
  font-weight: 700 !important;
}
.team-stat-label {
  font-size: 9px !important;
  margin-top: 1px !important;
}
.team-cap-bar { margin-top: 10px !important; }
.team-cap-bar .team-cap-label { font-size: 10.5px !important; }
.team-card .skill-chips {
  margin-top: 8px !important;
  gap: 4px !important;
}
.team-card .skill-chip {
  font-size: 9.5px !important;
  padding: 1px 6px !important;
}
.team-card .team-score-row {
  margin-top: 8px !important;
  font-size: 10.5px !important;
}
.team-card .team-score-val { font-size: 12px !important; }
/* Shrink the embedded action buttons in card header — already 28px via
   the unified rule, but keep tight gap with the name block. */
.team-card-header > div:last-child {
  gap: 2px !important;
}

/* "Click for full details →" CTA at bottom of team card */
.team-card .team-card-cta {
  font-family: var(--font-body, Inter, sans-serif) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  color: var(--brand, #5046E5) !important;
  margin-top: 10px !important;
  padding-top: 8px !important;
  border-top: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  cursor: pointer !important;
  transition: color 120ms ease !important;
}
.team-card .team-card-cta:hover {
  color: var(--text) !important;
}

/* ── MEMBER DETAIL DRAWER — v4 styling parity with project drawer ── */
#memberDrawer {
  width: 560px !important;
}
#memberDrawer .drawer-header {
  background: var(--bg) !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 18px 22px !important;
}
#memberDrawer .drawer-header > div:first-child > div:first-child {
  font-family: var(--font-body) !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  color: var(--muted) !important;
}
#memberDrawer .drawer-header > div:first-child > div:nth-child(2) {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}
#memberDrawer .drawer-body {
  padding: 18px 22px !important;
  background: var(--surface) !important;
}
#memberDrawer .drawer-section-label {
  font-family: var(--font-display, Fraunces, Georgia, serif) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
  padding-bottom: 8px !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.06)) !important;
  margin-bottom: 12px !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}
#memberDrawer .drawer-section-label svg {
  width: 13px !important;
  height: 13px !important;
  color: var(--brand) !important;
  flex-shrink: 0 !important;
}
#memberDrawer .drawer-section { margin-bottom: 20px !important; }
#memberDrawer .detail-row {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  padding: 8px 0 !important;
  border-bottom: 1px solid var(--border-soft, rgba(15,15,30,0.05)) !important;
  font-size: 12px !important;
}
#memberDrawer .detail-row:last-child { border-bottom: none !important; }
#memberDrawer .detail-label {
  color: var(--muted) !important;
  font-weight: 500 !important;
}
#memberDrawer .detail-value {
  color: var(--text) !important;
  font-weight: 600 !important;
  text-align: right !important;
}
#memberDrawer .member-proj-card {
  background: var(--bg) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  padding: 12px !important;
  margin-bottom: 8px !important;
}
#memberDrawer .member-proj-title {
  font-family: var(--font-body) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--text) !important;
  margin-bottom: 6px !important;
}
#memberDrawer .drawer-close {
  background: transparent !important;
  border: 1px solid transparent !important;
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
  border-radius: 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--muted) !important;
  transition: all 120ms ease !important;
}
#memberDrawer .drawer-close:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
}
#memberDrawer .drawer-close svg { width: 16px !important; height: 16px !important; }

/* Vendor "Rate" (star) button uses .btn-purple — give it a yellow/amber
   hover tint to match the rating semantic. */
#page-vendors .action-cell button.btn-purple:hover {
  color: var(--yellow, #EAB308) !important;
  border-color: rgba(234,179,8,0.30) !important;
  background: rgba(234,179,8,0.08) !important;
}

/* Availability skill filter pills — make them look like soft chip buttons,
   not raised primary buttons. They live in #skillFilterBtns rendered by JS. */
#skillFilterBtns button {
  background: transparent !important;
  border: 1px solid var(--border, #E4E4E7) !important;
  color: var(--muted, #71717A) !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  padding: 4px 10px !important;
  border-radius: 999px !important;
  height: auto !important;
  line-height: 1.4 !important;
  cursor: pointer !important;
  transition: all 120ms ease !important;
  box-shadow: none !important;
}
#skillFilterBtns button:hover {
  border-color: var(--brand-strong, rgba(80,70,229,0.32)) !important;
  color: var(--brand, #5046E5) !important;
  background: var(--brand-fade, rgba(80,70,229,0.06)) !important;
}
#skillFilterBtns button.active,
#skillFilterBtns button[data-active="true"] {
  background: var(--brand, #5046E5) !important;
  color: #fff !important;
  border-color: var(--brand, #5046E5) !important;
}

/* ===== /css/v2/empty_states.css?v=1 ===== */
/* ============================================================================
   Nexora v2 — Empty States
   Helpful, illustrated empty / zero / error / no-results placeholders.
   Replaces generic "no data" 13px text with a clear illustration + CTA.
   Uses design tokens: --text, --muted, --border, --brand, --surface, --danger.
   ============================================================================ */

/* ── Base container ───────────────────────────────────────────────────────── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 24px;
  max-width: 480px;
  margin: 0 auto;
  color: var(--text);
  gap: 0;
}

/* ── Illustration ─────────────────────────────────────────────────────────── */
/* Wrapper stays at full opacity so the two-plane treatment reads clearly:
   the .es-outline element carries its own stroke-opacity of ~.55 (visually
   the same "muted" tone the old blanket opacity: 0.6 achieved), and the
   .es-accent element renders at full coral saturation. */
.empty-state__illustration {
  width: 96px;
  height: 96px;
  margin-bottom: 20px;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.empty-state__illustration svg {
  width: 100%;
  height: 100%;
  display: block;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Two-plane illustration treatment — outline in muted currentColor, accent in
   --accent-coral. The accent is only ever on the ONE element that carries
   semantic meaning (plus, check, question mark, cloud slash, keyhole). */
.empty-state__illustration .es-outline {
  stroke: currentColor;
  stroke-opacity: 0.55;
}
.empty-state__illustration .es-accent  {
  stroke: var(--accent-coral);
  stroke-opacity: 1;
  stroke-width: 1.75;
}
/* Error empty-states swap the coral accent for danger red. */
.empty-state--error .empty-state__illustration .es-accent { stroke: var(--danger); }

/* ── Title ────────────────────────────────────────────────────────────────── */
.empty-state__title {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  margin: 0 0 8px 0;
  letter-spacing: -0.01em;
}

/* ── Description ──────────────────────────────────────────────────────────── */
.empty-state__description {
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted);
  margin: 0 0 20px 0;
  max-width: 360px;
}

/* ── Action buttons ───────────────────────────────────────────────────────── */
.empty-state__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.empty-state__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  border-radius: 8px;
  background: var(--brand);
  color: var(--surface);
  border: 1px solid var(--brand);
  cursor: pointer;
  text-decoration: none;
  transition: filter .15s ease, transform .15s ease;
  font-family: inherit;
}
.empty-state__cta:hover  { filter: brightness(1.05); }
.empty-state__cta:active { transform: translateY(1px); }
.empty-state__cta:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.empty-state__secondary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 0;
  padding: 8px 4px;
  font-size: 13px;
  font-weight: 500;
  color: var(--brand);
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
}
.empty-state__secondary:hover { text-decoration: underline; }
.empty-state__secondary:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── Variant: compact (cards, sidebars) ───────────────────────────────────── */
.empty-state--compact {
  padding: 24px 16px;
  max-width: 360px;
}
.empty-state--compact .empty-state__illustration {
  width: 64px;
  height: 64px;
  margin-bottom: 12px;
}
.empty-state--compact .empty-state__title       { font-size: 15px; margin-bottom: 4px; }
.empty-state--compact .empty-state__description { font-size: 13px; margin-bottom: 14px; }

/* ── Variant: inline (horizontal — toolbars, list rows) ───────────────────── */
.empty-state--inline {
  flex-direction: row;
  text-align: left;
  padding: 16px 20px;
  max-width: none;
  gap: 16px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  background: var(--surface);
}
.empty-state--inline .empty-state__illustration {
  width: 48px;
  height: 48px;
  margin: 0;
  flex-shrink: 0;
}
.empty-state--inline .empty-state__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.empty-state--inline .empty-state__title       { font-size: 14px; margin-bottom: 2px; }
.empty-state--inline .empty-state__description { font-size: 13px; margin-bottom: 0; text-align: left; }
.empty-state--inline .empty-state__actions     { margin-left: auto; }

/* ── Variant: error (red tint) ────────────────────────────────────────────── */
.empty-state--error .empty-state__illustration {
  color: var(--danger);
  opacity: 0.8;
}
.empty-state--error .empty-state__title { color: var(--danger); }

/* ── Variant: no-results (search context) ─────────────────────────────────── */
.empty-state--no-results {
  padding: 32px 24px;
}
.empty-state--no-results .empty-state__illustration { opacity: 0.5; }
.empty-state--no-results .empty-state__query {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--border);
  color: var(--text);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 12px;
  margin: 0 2px;
}

/* ── Reduced motion ───────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .empty-state__cta { transition: none; }
}

/* ===== /css/v2/icon_button_system.css?v=1 ===== */
/* ICON BUTTON SYSTEM — single source of truth, supersedes legacy-shim button rules
 * Use <button class="iconbtn iconbtn-md"> instead of generic .btn for icon-only triggers.
 *
 * Replaces fragmented button height definitions across:
 *   - static/css/app.css:200
 *   - static/css/v2/buttons.css:11
 *   - static/css/v2/legacy-shim.css:132
 *   - static/css/a11y.css:137
 *
 * Conventions:
 *   - WCAG 2.5.5 (mobile) compliant: minimum 44x44 touch target
 *   - Visual sizes: xs (24px), sm (32px), md (40px = default), lg (48px)
 *   - Mobile breakpoint forces 44x44 hit area regardless of visual size
 */

/* ---------- Base ---------- */
.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  border-radius: var(--r-md, 8px);
  cursor: pointer;
  transition: var(--tr-colors, all .12s ease-out);
}

.iconbtn:hover { background: var(--bg-hover); border-color: var(--border-strong, var(--accent)); }
.iconbtn:active { transform: translateY(1px); }
.iconbtn:disabled { opacity: .5; cursor: not-allowed; }
.iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Size variants ---------- */
.iconbtn-xs { width: 24px; height: 24px; }
.iconbtn-xs svg { width: 14px; height: 14px; }
.iconbtn-sm { width: 32px; height: 32px; }
.iconbtn-sm svg { width: 16px; height: 16px; }
.iconbtn-md { width: 40px; height: 40px; }
.iconbtn-md svg { width: 18px; height: 18px; }
.iconbtn-lg { width: 48px; height: 48px; }
.iconbtn-lg svg { width: 22px; height: 22px; }

/* ---------- Color variants ---------- */
.iconbtn-primary { background: var(--accent); color: var(--surface); border-color: var(--accent); }
.iconbtn-primary:hover { background: var(--accent-strong, var(--accent)); filter: brightness(1.1); }
.iconbtn-ghost { background: transparent; border-color: transparent; }
.iconbtn-ghost:hover { background: var(--bg-hover); }
.iconbtn-danger { color: var(--danger, var(--danger)); }
.iconbtn-danger:hover { background: var(--danger-bg, #fef2f2); border-color: var(--danger, var(--danger)); }

/* ---------- Mobile touch target — even xs/sm get 44x44 hit area via padding ---------- */
@media (pointer: coarse), (max-width: 768px) {
  .iconbtn-xs, .iconbtn-sm {
    position: relative;
  }
  .iconbtn-xs::before, .iconbtn-sm::before {
    content: '';
    position: absolute;
    inset: -10px;
    /* invisible hit area expansion */
  }
}

/* ---------- Tooltip on hover (data-tooltip attribute) ---------- */
.iconbtn[data-tooltip] { position: relative; }
.iconbtn[data-tooltip]:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: var(--card);
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  white-space: nowrap;
  z-index: var(--z-tooltip, 1500);
  pointer-events: none;
}

/* MIGRATION NOTES:
 * - Replace <button class="btn btn-icon"> with <button class="iconbtn iconbtn-md">
 * - Replace <button class="btn btn-sm btn-ghost"> for icons with <button class="iconbtn iconbtn-sm iconbtn-ghost">
 * - For tooltip: add data-tooltip="..." attribute
 * - For destructive: add iconbtn-danger
 * - This file OVERRIDES legacy button rules — load LAST in cascade
 */

/* WIRE-UP INSTRUCTIONS:
 * 1. Add the following line to static/index.html AFTER all other CSS <link> tags
 *    (it must load LAST so cascade overrides legacy rules):
 *
 *      <link rel="stylesheet" href="/css/v2/icon_button_system.css?v=1">
 *
 * 2. Wave 3 follow-up (DO NOT DO NOW):
 *    Remove icon button styles from static/css/v2/legacy-shim.css lines 132-140.
 *    Verify no regressions in:
 *      - Kanban card action buttons
 *      - Topbar quick-action icons
 *      - Modal close (X) buttons
 *      - Inline edit/delete row controls
 *
 * 3. Optional Wave 3 cleanup:
 *    - Audit static/css/app.css:200 for duplicate button height rules
 *    - Audit static/css/v2/buttons.css:11 for overlap with .iconbtn sizes
 *    - Audit static/css/a11y.css:137 for redundant focus-visible rules
 */

/* ===== /css/v2/tokens_unified.css?v=1 ===== */
/* ============================================================================
   tokens_unified.css — SINGLE SOURCE OF TRUTH for design tokens
   ----------------------------------------------------------------------------
   PURPOSE
     The project currently ships TWO competing :root token blocks:
       • static/css/tokens.css          — "Nexora v4" (Electric Indigo #5046E5,
                                          Fraunces display + Inter body)
       • static/css/app.css (L20–110)   — "Design System v8" (Indigo #6366f1,
                                          Inter only, warmer stone palette)

     These collide on every shared key (--bg, --surface, --border, --accent,
     --shadow-*, --green/red/yellow, --text, --muted, dark-mode overrides...)
     which means whichever file loads LAST wins — silently. The result is
     inconsistent brand color, surface tone, border weight, and shadow depth
     across pages depending on cascade order.

   STRATEGY
     This file merges both inventories into a single canonical :root block,
     picking the WINNER per token and adding backward-compat aliases so
     existing var(--legacy-name) references keep resolving. Load this file
     LAST in the cascade (after tokens.css AND after app.css) to neutralize
     the conflict without modifying either source. Wave 3 follow-up will
     delete the :root blocks from app.css and tokens.css.

   WINNERS — by category
     Brand        → tokens.css (Electric Indigo #5046E5 is more premium,
                                richer hover/active scale, has gradient & glow)
     Typography   → tokens.css (Fraunces serif display + Inter body pair is
                                the intentional editorial direction; app.css
                                has Inter only — strictly a subset)
     Spacing      → tokens.css (4-pt scale --space-1..10 is the documented
                                system; extended here to --space-0/11..16
                                for completeness, but core values match)
     Radius       → MERGED      (tokens.css has --radius-xs/sm/md/lg/full;
                                app.css has --r-sm/md/lg/xl. Keep BOTH
                                naming schemes — they're both used in the
                                codebase. Map --r-* → --radius-* values.)
     Shadow       → MERGED      (tokens.css has semantic names
                                --shadow-subtle/card/elevated/modal/focus/glow;
                                app.css has scale names --shadow-xs/sm/md/lg/xl.
                                Keep BOTH — semantic for new code, scale for
                                legacy. Values from tokens.css preferred
                                because the cool-indigo-tinted shadows
                                harmonize with Electric Indigo brand.)
     Surface/BG   → tokens.css (#FBFBFA cooler warm white vs app.css #fafaf9
                                stone-50 — tokens.css pairs better with the
                                indigo brand; warmth differential is minimal)
     Text         → IDENTICAL   (both use #18181B zinc-900 for --text — no
                                conflict; --text-2 differs slightly:
                                tokens.css #52525B vs app.css #3f3f46 →
                                pick tokens.css for lighter secondary
                                hierarchy, more breathable)
     Border       → tokens.css (#E4E4E7 zinc-200 vs app.css #e7e5e4 stone-200;
                                differential is one channel — pick tokens.css
                                to match its zinc text scale)
     Semantic     → tokens.css (vibrant #16A34A/#DC2626/#EA580C/#2563EB with
                                rgba *-bg variants — clearer hierarchy than
                                app.css's *-light hex pastels)
     Dark mode    → tokens.css (richer brand-fade/strong/glow scale, focus
                                shadow tuned to brand, multi-selector support:
                                [data-theme="dark"], html.dark, .dark-theme)

   BACKWARD-COMPAT ALIASES
     The codebase still uses these legacy names (from app.css v8). They are
     re-exported here as aliases to the canonical token so nothing breaks:
       --accent          → --brand
       --accent-hover    → --brand-hover
       --accent-light    → --brand-soft        (was indigo-50 pastel bg)
       --accent2         → --info
       --accent2-light   → --info-bg
       --green           → --success
       --green-light     → --success-bg
       --red             → --danger
       --red-light       → --danger-bg
       --yellow          → --warning
       --yellow-light    → --warning-bg
       --orange          → --accent-coral
       --orange-light    → --accent-coral-fade
       --r-sm/md/lg/xl   → mapped to --radius-sm/md/lg + new --radius-xl
       --font            → --font-body
       --mono            → --font-mono
       --border-light    → --border-soft
       --card            → --surface
       --card-elevated   → --surface (with elevated shadow; preserved name)
       --muted-light     → distinct lighter muted (kept as-is from app.css)
       --bg-input        → --surface-soft (close approximation)
       --bg-hover        → --bg-hover (canonical, exists in tokens.css)
       --bg-overlay      → kept from app.css (modal/sheet scrim)
       --sidebar-bg      → --bg (sidebar matched to canvas, light-on-light)
       --sidebar-border  → --border

   TEXT SCALE
     Neither source defined a --text-xs..4xl scale. Added here as the
     canonical type ramp so typography.css/v2 components can adopt it.

   ============================================================================ */

:root {
  /* ── TYPOGRAPHY ─────────────────────────────────────────────────────────── */
  --font-display: 'Fraunces', 'Georgia', 'Times New Roman', serif;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Legacy font aliases (app.css naming) */
  --font: var(--font-body);
  --mono: var(--font-mono);

  /* Type scale — canonical ramp (1.125 modular, base 14px) */
  --text-xs:   11px;
  --text-sm:   12px;
  --text-base: 14px;
  --text-lg:   16px;
  --text-xl:   18px;
  --text-2xl:  22px;
  --text-3xl:  28px;
  --text-4xl:  36px;

  --leading-tight:  1.2;
  --leading-snug:   1.35;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  /* Font weight scale */
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* ── SPACING — 4-pt scale ───────────────────────────────────────────────── */
  --space-0:  0;
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --space-9:  96px;
  --space-10: 128px;
  --space-11: 160px;
  --space-12: 192px;
  --space-13: 224px;
  --space-14: 256px;
  --space-15: 320px;
  --space-16: 384px;

  /* ── RADII ──────────────────────────────────────────────────────────────── */
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-xl:   20px;
  --radius-full: 9999px;

  /* Legacy radius aliases (app.css naming --r-*) */
  --r-xs: var(--radius-xs);
  --r-sm: var(--radius-sm);
  --r-md: var(--radius-md);
  --r-lg: var(--radius-lg);
  --r-xl: var(--radius-xl);

  /* ── SHADOWS ────────────────────────────────────────────────────────────── */
  /* Semantic names (tokens.css heritage) */
  --shadow-none:      none;
  --shadow-subtle:    0 1px 2px rgba(15,15,30,.04);
  --shadow-card:      0 1px 2px rgba(15,15,30,.04), 0 2px 4px rgba(15,15,30,.04);
  --shadow-elevated:  0 4px 12px -2px rgba(15,15,30,.08), 0 2px 6px rgba(15,15,30,.05);
  --shadow-modal:     0 24px 48px -12px rgba(15,15,30,.20), 0 8px 16px rgba(15,15,30,.06);
  --shadow-focus:     0 0 0 3px rgba(80,70,229,0.30);
  --shadow-glow:      0 0 0 4px rgba(80,70,229,0.16), 0 4px 12px -2px rgba(80,70,229,0.30);
  --shadow-glow-soft: 0 4px 24px -8px rgba(80,70,229,0.30);

  /* Scale names (app.css heritage — still used in many components) */
  --shadow-xs: 0 1px 2px rgba(15,15,30,.04);
  --shadow-sm: 0 1px 3px rgba(15,15,30,.06), 0 1px 2px rgba(15,15,30,.03);
  --shadow-md: 0 4px 12px rgba(15,15,30,.06), 0 2px 4px rgba(15,15,30,.03);
  --shadow-lg: 0 10px 28px rgba(15,15,30,.08), 0 4px 8px rgba(15,15,30,.04);
  --shadow-xl: 0 20px 56px rgba(15,15,30,.12), 0 8px 16px rgba(15,15,30,.05);

  /* ── MOTION ─────────────────────────────────────────────────────────────── */
  --ease:        cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  --d-instant: 0ms;
  --d-fast:    150ms;
  --d-normal:  240ms;
  --d:         240ms;        /* alias of --d-normal */
  --d-base:    180ms;        /* legacy from system_tokens.css */
  --d-slow:    320ms;
  --d-slower:  420ms;

  /* Transition presets — drop-in replacements for `transition: ...` */
  --tr-default:   all var(--d-fast) var(--ease-out);
  --tr-colors:
    color            var(--d-fast) var(--ease-out),
    background-color var(--d-fast) var(--ease-out),
    border-color     var(--d-fast) var(--ease-out);
  --tr-transform: transform var(--d-normal) var(--ease-out);

  /* ── Z-INDEX SCALE ──────────────────────────────────────────────────────── */
  --z-base:            1;
  --z-dropdown:        100;
  --z-sticky:          200;
  --z-fixed:           300;
  --z-overlay:         1000;
  --z-modal:           1100;
  --z-drawer:          1200;
  --z-popover:         1300;
  --z-toast:           1400;
  --z-tooltip:         1500;
  --z-command-palette: 1600;
  --z-max:             9999;

  /* ── BRAND — ELECTRIC INDIGO ────────────────────────────────────────────── */
  --brand:          #5046E5;
  --brand-hover:    #4338CA;
  --brand-active:   #3730A3;
  --brand-strong:   rgba(80,70,229,0.22);
  --brand-soft:     #EEF0FE;
  --brand-fade:     rgba(80,70,229,0.10);
  --brand-glow:     rgba(80,70,229,0.30);
  --brand-gradient: linear-gradient(135deg, #5046E5 0%, #7C3AED 100%);

  /* Secondary accent — warm coral (sparingly, for delight) */
  --accent-coral:      #F97316;
  --accent-coral-fade: rgba(249,115,22,0.10);
  --accent-coral-soft: #FFF3EA;

  /* ── SURFACE / CANVAS ───────────────────────────────────────────────────── */
  --bg:            #FBFBFA;
  --surface:       #FFFFFF;
  --surface-soft:  #F4F4F2;
  --surface-2:     #FFFFFF;
  --bg-hover:      #F0F0EE;
  --bg-input:      #FBFBFA;
  --bg-overlay:    rgba(28,25,23,.35);

  /* Card aliases (the codebase uses --card extensively) */
  --card:          var(--surface);
  --card-elevated: var(--surface);

  /* Sidebar (light-on-light, matched to canvas) */
  --sidebar-bg:     var(--bg);
  --sidebar-border: var(--border);

  /* ── TEXT ───────────────────────────────────────────────────────────────── */
  --text:        #18181B;
  --text-2:      #52525B;
  --text-muted:  #A1A1AA;
  --muted:       #A1A1AA;
  --muted-light: #D4D4D8;

  /* ── BORDER ─────────────────────────────────────────────────────────────── */
  --border:        #E4E4E7;
  --border-strong: #D4D4D8;
  --border-soft:   #F4F4F5;
  --border-light:  var(--border-soft);

  /* ── SEMANTIC ───────────────────────────────────────────────────────────── */
  --success:    #16A34A;
  --success-bg: rgba(22,163,74,0.10);
  --success-fade: rgba(22,163,74,0.06);

  --warning:    #EA580C;
  --warning-bg: rgba(234,88,12,0.10);
  --warning-fade: rgba(234,88,12,0.06);

  --danger:     #DC2626;
  --danger-bg:  rgba(220,38,38,0.10);
  --danger-fade: rgba(220,38,38,0.06);

  --info:       #2563EB;
  --info-bg:    rgba(37,99,235,0.10);
  --info-fade:  rgba(37,99,235,0.06);

  /* ── LEGACY ALIASES (preserved for backward compat) ─────────────────────── */
  --accent:        var(--brand);
  --accent-hover:  var(--brand-hover);
  --accent-light:  var(--brand-soft);
  --accent2:       var(--info);
  --accent2-light: var(--info-bg);

  --green:        var(--success);
  --green-light:  var(--success-bg);
  --red:          var(--danger);
  --red-light:    var(--danger-bg);
  --yellow:       var(--warning);
  --yellow-light: var(--warning-bg);
  --orange:       var(--accent-coral);
  --orange-light: var(--accent-coral-fade);
  --purple:       #7C3AED;
  --purple-light: rgba(124,58,237,0.10);
  --teal:         #0D9488;
  --teal-light:   rgba(13,148,136,0.10);
  --pink:         #DB2777;
  --pink-light:   rgba(219,39,119,0.10);

  --intent-success: var(--success);
  --intent-danger:  var(--danger);
  --intent-warning: var(--warning);
  --intent-info:    var(--info);
  --intent-neutral: var(--muted);

  color-scheme: light;
}

/* ============================================================================
   DARK MODE — Vercel/Linear-style dark with vibrant brand
   Multi-selector support so existing toggles keep working.
   ============================================================================ */
[data-theme="dark"],
html.dark,
.dark-theme {
  /* Brand — softer, lighter indigo for dark canvas */
  --brand:        #818CF8;
  --brand-hover:  #A5B4FC;
  --brand-active: #C7D2FE;
  --brand-fade:   rgba(129,140,248,0.14);
  --brand-strong: rgba(129,140,248,0.26);
  --brand-glow:   rgba(129,140,248,0.36);
  --brand-soft:   rgba(129,140,248,0.08);

  --accent-coral:      #FB923C;
  --accent-coral-fade: rgba(251,146,60,0.14);
  --accent-coral-soft: rgba(251,146,60,0.08);

  /* Surface */
  --bg:           #09090B;
  --surface:      #18181B;
  --surface-soft: #27272A;
  --surface-2:    #18181B;
  --bg-hover:     #27272A;
  --bg-input:     #18181B;
  --bg-overlay:   rgba(0,0,0,.55);

  --card:          var(--surface);
  --card-elevated: var(--surface);

  --sidebar-bg:     var(--bg);
  --sidebar-border: rgba(255,255,255,.08);

  /* Text */
  --text:        #FAFAFA;
  --text-2:      #D4D4D8;
  --text-muted:  #71717A;
  --muted:       #71717A;
  --muted-light: #52525B;

  /* Border */
  --border:        #27272A;
  --border-strong: #3F3F46;
  --border-soft:   #1F1F23;
  --border-light:  var(--border-soft);

  /* Semantic — slightly softer for dark canvas */
  --success-bg: rgba(22,163,74,0.16);
  --warning-bg: rgba(234,88,12,0.16);
  --danger-bg:  rgba(220,38,38,0.16);
  --info-bg:    rgba(37,99,235,0.16);

  /* Shadows — deeper for dark */
  --shadow-subtle:   0 1px 2px rgba(0,0,0,.30);
  --shadow-card:     0 1px 2px rgba(0,0,0,.40), 0 2px 4px rgba(0,0,0,.30);
  --shadow-elevated: 0 4px 12px -2px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.30);
  --shadow-modal:    0 24px 48px -12px rgba(0,0,0,.70), 0 8px 16px rgba(0,0,0,.40);
  --shadow-focus:    0 0 0 3px rgba(129,140,248,0.40);
  --shadow-glow:     0 0 0 4px rgba(129,140,248,0.20), 0 4px 12px -2px rgba(129,140,248,0.40);
  --shadow-glow-soft: 0 4px 24px -8px rgba(129,140,248,0.30);

  --shadow-xs: 0 1px 3px rgba(0,0,0,.3);
  --shadow-sm: 0 2px 6px rgba(0,0,0,.3);
  --shadow-md: 0 4px 16px rgba(0,0,0,.35);
  --shadow-lg: 0 10px 40px rgba(0,0,0,.45);
  --shadow-xl: 0 24px 64px rgba(0,0,0,.55);

  color-scheme: dark;
}

/* ============================================================================
   REDUCED MOTION — collapse durations to instant when user requests it
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --d-fast:   var(--d-instant);
    --d-normal: var(--d-instant);
    --d:        var(--d-instant);
    --d-base:   var(--d-instant);
    --d-slow:   var(--d-instant);
    --d-slower: var(--d-instant);
  }
}

/* ============================================================================
   WIRE-UP INSTRUCTIONS
   ----------------------------------------------------------------------------
   This file is the SINGLE source of truth for design tokens. To activate:

   1) In static/index.html, add the <link> AFTER both tokens.css and app.css,
      but BEFORE static/css/v2/legacy-shim.css (legacy-shim still needs to
      run last so component-level shims override final token values).

      Cascade order target:
        <link rel="stylesheet" href="static/css/tokens.css">       <!-- old -->
        <link rel="stylesheet" href="static/css/app.css">          <!-- old -->
        ... other component stylesheets ...
        <link rel="stylesheet" href="static/css/v2/tokens_unified.css">  <!-- NEW: load LAST among token sources -->
        <link rel="stylesheet" href="static/css/v2/legacy-shim.css">     <!-- still last in v2 chain -->

   2) Verify by opening DevTools and inspecting any element that uses
      var(--brand) — it must resolve to #5046E5 (light) or #818CF8 (dark).
      Likewise var(--accent) must alias to the same.

   3) Wave 3 follow-up (NOT in this commit):
        - Delete :root { ... } block from static/css/tokens.css (lines 5–105)
        - Delete :root { ... } block from static/css/app.css      (lines 20–110)
        - Delete [data-theme="dark"] override from both files
        - Re-test full app in both light and dark mode
        - Then this file can be moved to static/css/tokens.css to become THE
          canonical token file, replacing the old one entirely.

   4) Search for unmigrated legacy tokens after wave 3:
        grep -RIn 'var(--accent[^2-]'  static/      # should find few; aliased
        grep -RIn 'var(--r-'           static/      # should find many; aliased
        grep -RIn 'var(--green[^-]'    static/      # aliased to --success
   ============================================================================ */

/* ===== /css/v3/typography.css?v=2 ===== */
/* ============================================================================
   TYPOGRAPHY v3 — canonical heading scale, body, mono, link styles
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens_unified.css + system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible/:visited).
   Designed for BEM-ish single-class application. Bare element rules (h1..h6)
   are scoped to .v3-prose so they never bleed into legacy layouts.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   PAGE BASE — font-feature-settings + smoothing for editorial typography
   (ported from v2/typography.css during Wave 8 deprecation)
   ══════════════════════════════════════════════════════════════════════════ */

html, body {
  font-family: var(--font-body);
  font-feature-settings: 'cv05', 'cv11', 'ss01', 'ss03';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}


/* ══════════════════════════════════════════════════════════════════════════
   DISPLAY — hero / page heads (Fraunces serif)
   ══════════════════════════════════════════════════════════════════════════ */

.t-hero {
  font-family: var(--font-display);
  font-feature-settings: 'ss01', 'ss02';
  font-size: 48px;
  line-height: 1.10;
  letter-spacing: -0.030em;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}

.t-page-title {
  font-family: var(--font-display);
  font-feature-settings: 'ss01', 'ss02';
  font-size: 28px;
  line-height: 1.20;
  letter-spacing: -0.020em;
  font-weight: 500;
  color: var(--text);
  margin: 0;
}

.t-section {
  font-family: var(--font-display);
  font-feature-settings: 'ss01', 'ss02';
  font-size: 18px;
  line-height: 1.35;
  letter-spacing: -0.015em;
  font-weight: 500;
  color: var(--text);
  margin: 0;
}

.t-display {
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0;
}

.t-display-sm {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.018em;
  color: var(--text);
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   HEADINGS — h1..h6 scale (single-class form)
   ══════════════════════════════════════════════════════════════════════════ */

.t-h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.018em;
  color: var(--text);
  margin: 0;
}

.t-h2 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 500;
  line-height: var(--leading-snug);
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0;
}

.t-h3 {
  font-family: var(--font-body);
  font-size: var(--text-xl);
  font-weight: 600;
  line-height: var(--leading-snug);
  letter-spacing: -0.012em;
  color: var(--text);
  margin: 0;
}

.t-h4 {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: var(--leading-snug);
  letter-spacing: -0.008em;
  color: var(--text);
  margin: 0;
}

.t-h5 {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  line-height: var(--leading-normal);
  letter-spacing: -0.005em;
  color: var(--text);
  margin: 0;
}

.t-h6 {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: var(--leading-normal);
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text-2);
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   BODY TEXT — paragraph utilities
   ══════════════════════════════════════════════════════════════════════════ */

.t-body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: var(--leading-relaxed);
  color: var(--text);
  margin: 0;
}

.t-body-sm {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: var(--leading-normal);
  color: var(--text);
  margin: 0;
}

.t-body-lg {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: var(--leading-relaxed);
  color: var(--text);
  margin: 0;
}

.t-lead {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: var(--leading-relaxed);
  color: var(--text-2);
  margin: 0;
}

.t-muted {
  color: var(--muted);
}

.t-strong {
  font-weight: 600;
  color: var(--text);
}

.t-em {
  font-style: italic;
  color: inherit;
}


/* ══════════════════════════════════════════════════════════════════════════
   LABELS / EYEBROW / CAPTION
   ══════════════════════════════════════════════════════════════════════════ */

.t-eyebrow {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: var(--leading-normal);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
  margin: 0;
}

.t-caption {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: var(--leading-normal);
  color: var(--muted);
  margin: 0;
}

.t-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-2);
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   OVERLINE — uppercase eyebrow variant (ported from v2/typography.css).
   Larger than .t-eyebrow; used in card section heads + filter labels.
   ══════════════════════════════════════════════════════════════════════════ */

.t-overline {
  font-family: var(--font-body);
  font-size: 11px;
  line-height: 1.40;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   NUMERIC UTILITIES — tabular figures + mono variant
   (ported from v2/typography.css)
   ══════════════════════════════════════════════════════════════════════════ */

.tabular { font-variant-numeric: tabular-nums; }
.mono {
  font-family: var(--font-mono);
  font-feature-settings: 'tnum';
  font-size: 13px;
  letter-spacing: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   TABULAR-FIGURES ON-BY-DEFAULT
   ------------------------------------------------------------------------
   Any surface that renders numeric values which UPDATE at runtime (KPI
   cards, deltas, table numeric columns, progress %, sparklines, badge
   counts, EVM totals, notice metric slots) must use tabular figures so
   digits do not "jitter" as values change (0.66 → 0.83). Proportional
   figures are fine for prose — this rule targets only classes that carry
   values. Zero specificity war with legacy: this is a base rule that
   simply sets a font-variant-numeric on the target class; legacy rules
   that also set font-variant-numeric override cleanly by source order.
   ══════════════════════════════════════════════════════════════════════════ */

.kpi-value,
.kpi-delta,
.kpi-num,
.stat-value,
.stat-num,
.metric,
.metric-value,
.money,
.pct,
.percent,
.counter,
.counter-value,
.chart-value,
.delta,
.badge-count,
.notice-metric,
.risk-matrix-score,
.form-label-value,
td.num,
td.numeric,
td.money,
.tabular-auto,
.progress-label,
.progress-value,
[data-numeric],
[data-tabular] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}


/* ══════════════════════════════════════════════════════════════════════════
   SECTION TITLE — legacy `.section-title` editorial upgrade
   Ported from v2/typography.css with !important stripped. Wins over
   app.css via source-order; legacy-shim.css still enforces font-family.
   ══════════════════════════════════════════════════════════════════════════ */

.section-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--text);
  text-transform: none;
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-3);
  margin: var(--space-7) 0 var(--space-5);
}


/* ══════════════════════════════════════════════════════════════════════════
   CODE / MONO — inline + block
   ══════════════════════════════════════════════════════════════════════════ */

.t-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.t-code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-weight: 500;
  padding: 1px 6px;
  color: var(--text);
  background: var(--surface-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xs);
  white-space: nowrap;
}

.t-pre {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  padding: var(--space-3) var(--space-4);
  color: var(--text);
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow-x: auto;
  white-space: pre;
  margin: 0;
}

.t-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 2px 6px;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-xs);
  box-shadow: var(--shadow-subtle);
}


/* ══════════════════════════════════════════════════════════════════════════
   LINKS
   ══════════════════════════════════════════════════════════════════════════ */

.t-link {
  color: var(--brand);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  cursor: pointer;
  transition: var(--tr-colors);
}

.t-link:hover {
  color: var(--brand-hover);
  text-decoration-thickness: 2px;
}

.t-link:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.t-link:visited {
  color: var(--brand);
}

.t-link-subtle {
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px dashed var(--border-strong);
  transition: var(--tr-colors);
}

.t-link-subtle:hover {
  color: var(--text);
  border-bottom-color: var(--text-2);
}


/* ══════════════════════════════════════════════════════════════════════════
   LISTS
   ══════════════════════════════════════════════════════════════════════════ */

.t-list {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--text);
  padding-left: var(--space-5);
  margin: 0;
}

.t-list-tight {
  line-height: var(--leading-normal);
}

.t-list-none {
  list-style: none;
  padding-left: 0;
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   ALIGNMENT / WRAP UTILITIES
   ══════════════════════════════════════════════════════════════════════════ */

.t-left   { text-align: left; }
.t-right  { text-align: right; }
.t-center { text-align: center; }

.t-nowrap   { white-space: nowrap; }
.t-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.t-balance { text-wrap: balance; }
.t-pretty  { text-wrap: pretty; }


/* ══════════════════════════════════════════════════════════════════════════
   PROSE BLOCK — scoped element styling for rendered markdown / content
   ══════════════════════════════════════════════════════════════════════════ */

.v3-prose {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--text);
}

.v3-prose h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.018em;
  color: var(--text);
  margin: var(--space-5) 0 var(--space-3);
}

.v3-prose h2 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 500;
  line-height: var(--leading-snug);
  color: var(--text);
  margin: var(--space-5) 0 var(--space-3);
}

.v3-prose h3 {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--text);
  margin: var(--space-4) 0 var(--space-2);
}

.v3-prose p {
  margin: 0 0 var(--space-3);
}

.v3-prose ul,
.v3-prose ol {
  padding-left: var(--space-5);
  margin: 0 0 var(--space-3);
}

.v3-prose code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 1px 6px;
  background: var(--surface-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xs);
}

.v3-prose a {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.v3-prose a:hover {
  color: var(--brand-hover);
}


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .t-link,
  .t-link-subtle {
    transition: none;
  }
}


/* USAGE:
   <h1 class="t-display">Welcome back</h1>
   <p class="t-lead">A premium dashboard for portfolio leaders.</p>

   <h2 class="t-h2">Recent activity</h2>
   <p class="t-body">Body copy with <a class="t-link" href="#">a link</a>
      and an <code class="t-code">inline-token</code>.</p>

   <span class="t-eyebrow">Section</span>
   <p class="t-caption">Caption text below an image.</p>

   <kbd class="t-kbd">⌘</kbd> <kbd class="t-kbd">K</kbd>

   <pre class="t-pre">npm run build</pre>

   <article class="v3-prose">…rendered markdown…</article>
*/

/* ===== /css/v3/buttons.css?v=2 ===== */
/* ============================================================================
   BUTTONS v3 — canonical button system, supersedes v2/buttons.css + legacy .btn
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css and BEFORE v3/components.css (components.css will
   defer to this file for buttons once Agent 19 removes the duplicated block).
   Uses tokens_unified.css + system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible/:disabled).
   No descendant selectors — single-class + pseudo-states only.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   BASE — .btn neutral surface
   ══════════════════════════════════════════════════════════════════════════ */

.btn {
  /* Shape */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 9px var(--space-4);
  min-height: 36px;

  /* Type */
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.005em;
  white-space: nowrap;

  /* Surface */
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-subtle);

  /* Behavior */
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition: var(--tr-default);
  position: relative;
  overflow: hidden;
}

.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  filter: brightness(0.98);
}

.btn:active {
  transform: translateY(1px);
  box-shadow: none;
}

/* Focus ring is provided by the unified `:focus-visible` halo in
   v3/a11y_fixes.css; per-tone buttons override `--ring-color` below. */

.btn:disabled,
.btn-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   VARIANTS
   ══════════════════════════════════════════════════════════════════════════ */

.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
  box-shadow: var(--shadow-subtle);
}
.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
  color: var(--surface);
  filter: none;
}
/* Primary button uses default brand-tone ring — no override needed. */

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-secondary:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border-color: transparent;
  box-shadow: none;
}
.btn-ghost:hover {
  background: var(--bg-hover);
  color: var(--text);
  border-color: transparent;
  filter: none;
}

.btn-soft {
  background: var(--brand-soft);
  color: var(--brand);
  border-color: transparent;
  box-shadow: none;
}
.btn-soft:hover {
  background: var(--brand-fade);
  color: var(--brand-hover);
  filter: none;
}

.btn-outline {
  background: transparent;
  color: var(--brand);
  border-color: var(--brand);
  box-shadow: none;
}
.btn-outline:hover {
  background: var(--brand-soft);
  color: var(--brand-hover);
  border-color: var(--brand-hover);
  filter: none;
}

.btn-danger {
  background: var(--danger);
  color: var(--surface);
  border-color: var(--danger);
}
.btn-danger:hover {
  background: #B91C1C;
  border-color: #B91C1C;
  color: var(--surface);
  filter: none;
}
.btn-danger { --ring-color: color-mix(in srgb, var(--danger) 40%, transparent); }

.btn-danger-soft {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: transparent;
  box-shadow: none;
}
.btn-danger-soft:hover {
  background: var(--danger-fade);
  filter: none;
}

.btn-success {
  background: var(--success);
  color: var(--surface);
  border-color: var(--success);
}
.btn-success:hover {
  background: #15803D;
  border-color: #15803D;
  color: var(--surface);
  filter: none;
}
.btn-success { --ring-color: color-mix(in srgb, var(--success) 40%, transparent); }

.btn-warning {
  background: var(--warning);
  color: var(--surface);
  border-color: var(--warning);
}
.btn-warning:hover {
  background: #C2410C;
  border-color: #C2410C;
  color: var(--surface);
  filter: none;
}

.btn-link {
  background: transparent;
  color: var(--brand);
  border-color: transparent;
  box-shadow: none;
  padding: 0;
  min-height: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  border-radius: var(--radius-xs);
}
.btn-link:hover {
  color: var(--brand-hover);
  background: transparent;
  filter: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   SIZES
   ══════════════════════════════════════════════════════════════════════════ */

.btn-xs {
  padding: 4px var(--space-2);
  min-height: 24px;
  font-size: var(--text-xs);
  border-radius: var(--radius-xs);
  gap: 4px;
}

.btn-sm {
  padding: 6px var(--space-3);
  min-height: 30px;
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
}

.btn-md {
  /* default — alias of base */
  padding: 9px var(--space-4);
  min-height: 36px;
  font-size: var(--text-sm);
  border-radius: var(--radius-md);
}

.btn-lg {
  padding: 12px var(--space-5);
  min-height: 44px;
  font-size: var(--text-base);
  border-radius: var(--radius-md);
}

.btn-xl {
  padding: 14px var(--space-5);
  min-height: 52px;
  font-size: var(--text-lg);
  border-radius: var(--radius-lg);
}


/* ══════════════════════════════════════════════════════════════════════════
   ICON-ONLY & SHAPE MODIFIERS
   ══════════════════════════════════════════════════════════════════════════ */

.btn-icon {
  width: 36px;
  padding: 0;
  aspect-ratio: 1;
}
.btn-icon.btn-xs { width: 24px; }
.btn-icon.btn-sm { width: 30px; }
.btn-icon.btn-lg { width: 44px; }
.btn-icon.btn-xl { width: 52px; }

.btn-block {
  display: flex;
  width: 100%;
}

.btn-pill {
  border-radius: var(--radius-full);
}

.btn-square {
  border-radius: var(--radius-xs);
}


/* ══════════════════════════════════════════════════════════════════════════
   ICON-GHOST — 30×30 transparent square, muted at rest, tinted on hover.
   Single source of truth for the row-action / inline-icon pattern. Aliases
   (.nx-row-action, [id^="page-integration-"] .nx-icon-only) are kept for
   backward-compat until call sites migrate. Specificity stays at 0,1,0 at
   rest and 0,2,0 on :hover — NO !important. Replaces the 0,3,0 +
   !important block that previously lived in inline_migration.css:530-589.
   ══════════════════════════════════════════════════════════════════════════ */

.btn-icon-ghost,
.nx-row-action,
[id^="page-integration-"] .nx-icon-only {
  width: 30px;
  height: 30px;
  min-width: 30px;
  min-height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--text-2);
  border: 0;
  box-shadow: none;
  border-radius: 8px;
  flex-shrink: 0;
  transition: background-color .12s ease, color .12s ease;
  overflow: visible;
  cursor: pointer;
}

.btn-icon-ghost:hover,
.nx-row-action:hover,
[id^="page-integration-"] .nx-icon-only:hover {
  background: var(--bg-hover);
  color: var(--text);
  filter: none;
}

/* Focus ring inherited from unified `:focus-visible` halo in a11y_fixes.css. */

.btn-icon-ghost svg,
.nx-row-action svg,
[id^="page-integration-"] .nx-icon-only svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Variant tints — hover color only. Background stays var(--bg-hover). */
.btn-icon-ghost.danger:hover,
.nx-row-action.btn-danger:hover,
.btn.btn-danger.nx-row-action:hover {
  color: var(--danger);
}

.btn-icon-ghost.warning:hover,
.nx-row-action.btn-warning:hover,
.btn.btn-warning.nx-row-action:hover {
  color: var(--warning);
}

.btn-icon-ghost.success:hover,
.nx-row-action.btn-success:hover,
.btn.btn-success.nx-row-action:hover {
  color: var(--success);
}

.btn-icon-ghost.teal:hover,
.nx-row-action.btn-teal:hover,
.btn.btn-teal.nx-row-action:hover {
  color: var(--teal);
}

.btn-icon-ghost.primary:hover,
.nx-row-action.btn-primary:hover,
.btn.btn-primary.nx-row-action:hover {
  color: var(--brand);
}

.btn.btn-accent.nx-row-action:hover {
  color: var(--accent);
}

/* When .nx-row-action is combined with .btn + variant, the legacy
 * .btn.btn-X background rules outrank plain .nx-row-action. Restore
 * the muted-at-rest convention WITHOUT !important by mirroring the
 * specificity — 0,3,0 selector below matches 0,3,0 base. */
.btn.btn-primary.nx-row-action,
.btn.btn-warning.nx-row-action,
.btn.btn-danger.nx-row-action,
.btn.btn-success.nx-row-action,
.btn.btn-teal.nx-row-action,
.btn.btn-accent.nx-row-action {
  background: transparent;
  color: var(--text-2);
  border: 0;
  box-shadow: none;
}

.btn.btn-primary.nx-row-action:hover,
.btn.btn-warning.nx-row-action:hover,
.btn.btn-danger.nx-row-action:hover,
.btn.btn-success.nx-row-action:hover,
.btn.btn-teal.nx-row-action:hover,
.btn.btn-accent.nx-row-action:hover {
  background: var(--bg-hover);
}


/* ══════════════════════════════════════════════════════════════════════════
   LOADING STATE — spinner injected via ::before, label dims to transparent
   ══════════════════════════════════════════════════════════════════════════ */

.btn-loading {
  color: transparent;
  pointer-events: none;
  cursor: progress;
}

.btn-loading::before {
  content: '';
  position: absolute;
  width: 14px;
  height: 14px;
  top: 50%;
  left: 50%;
  margin: -7px 0 0 -7px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--radius-full);
  color: var(--text);
  animation: btnSpin var(--d-slower) linear infinite;
}

.btn-primary.btn-loading::before,
.btn-danger.btn-loading::before,
.btn-success.btn-loading::before,
.btn-warning.btn-loading::before {
  color: var(--surface);
}

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


/* ══════════════════════════════════════════════════════════════════════════
   GROUP — adjacent buttons join into a segmented control
   ══════════════════════════════════════════════════════════════════════════ */

.btn-group {
  display: inline-flex;
  align-items: stretch;
  gap: 0;
  border-radius: var(--radius-md);
}

.btn-group > .btn {
  border-radius: 0;
  margin-left: -1px;
}
.btn-group > .btn:first-child {
  border-top-left-radius: var(--radius-md);
  border-bottom-left-radius: var(--radius-md);
  margin-left: 0;
}
.btn-group > .btn:last-child {
  border-top-right-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
}
.btn-group > .btn:focus-visible,
.btn-group > .btn:hover {
  z-index: var(--z-base);
}


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .btn {
    transition: none;
  }
  .btn:active {
    transform: none;
  }
  .btn-loading::before {
    animation: none;
  }
}


/* USAGE:
   <button class="btn btn-primary">Save changes</button>
   <button class="btn btn-secondary">Cancel</button>
   <button class="btn btn-ghost btn-sm">Skip</button>
   <button class="btn btn-danger" disabled>Delete</button>
   <button class="btn btn-primary btn-loading">Saving…</button>
   <button class="btn btn-icon btn-ghost" aria-label="Close">×</button>

   <div class="btn-group">
     <button class="btn btn-secondary">Day</button>
     <button class="btn btn-secondary">Week</button>
     <button class="btn btn-secondary">Month</button>
   </div>

   <button class="btn btn-outline btn-block">Continue</button>
   <a class="btn btn-link" href="#">Learn more</a>
*/

/* ===== /css/v3/forms.css?v=1 ===== */
/* ============================================================================
   FORMS v3 — labels, inputs, textareas, selects, checkboxes, radios, switches,
   error states, hint text. Supersedes v2/forms.css and legacy .form-* rules.
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens_unified.css + system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible/:disabled/
   :checked/:invalid and ::placeholder/::before/::after).
   No descendant selectors beyond direct adjacent/sibling for compound widgets.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   FIELD WRAPPER — labelled control group
   ══════════════════════════════════════════════════════════════════════════ */

.field {
  display: block;
  margin-bottom: var(--space-4);
}

.field-inline {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.field-row-full {
  grid-template-columns: 1fr;
}

@media (max-width: 640px) {
  .field-row {
    grid-template-columns: 1fr;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   LABEL + HINT + ERROR
   ══════════════════════════════════════════════════════════════════════════ */

.label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-2);
  margin-bottom: 6px;
}

.label-required::after {
  content: '*';
  color: var(--danger);
  margin-left: 4px;
}

.label-optional::after {
  content: ' (optional)';
  color: var(--muted);
  font-weight: 400;
}

.hint {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: 1.4;
  color: var(--muted);
  margin-top: 4px;
}

.error-text {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.4;
  color: var(--danger);
  margin-top: 4px;
}


/* ══════════════════════════════════════════════════════════════════════════
   INPUT / TEXTAREA / SELECT — shared base
   ══════════════════════════════════════════════════════════════════════════ */

.input,
.textarea,
.select {
  display: block;
  width: 100%;
  padding: 9px var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: 1.4;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-subtle);
  transition: var(--tr-colors);
  appearance: none;
  -webkit-appearance: none;
}

.textarea {
  min-height: 96px;
  line-height: 1.6;
  resize: vertical;
  font-family: var(--font-body);
}

.input:hover,
.textarea:hover,
.select:hover {
  border-color: var(--border-strong);
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
}

.input:focus-visible,
.textarea:focus-visible,
.select:focus-visible {
  /* Halo ring comes from the unified `:focus-visible` selector in a11y_fixes.css.
     Border-color change stays — it is the field-level "focused" affordance. */
  border-color: var(--brand);
}

.input:disabled,
.textarea:disabled,
.select:disabled {
  background: var(--surface-soft);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.7;
}

.input:invalid,
.textarea:invalid,
.select:invalid {
  border-color: var(--danger);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}


/* ══════════════════════════════════════════════════════════════════════════
   ERROR STATE — opt-in via .input-error / .textarea-error / .select-error
   ══════════════════════════════════════════════════════════════════════════ */

.input-error,
.textarea-error,
.select-error {
  border-color: var(--danger);
  background: var(--danger-fade);
}
.input-error:focus,
.textarea-error:focus,
.select-error:focus {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-bg);
}

.input-success,
.textarea-success,
.select-success {
  border-color: var(--success);
}
.input-success:focus,
.textarea-success:focus,
.select-success:focus {
  border-color: var(--success);
  box-shadow: 0 0 0 3px var(--success-bg);
}


/* ══════════════════════════════════════════════════════════════════════════
   SIZES
   ══════════════════════════════════════════════════════════════════════════ */

.input-sm,
.select-sm,
.textarea-sm {
  padding: 6px var(--space-2);
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
}

.input-lg,
.select-lg,
.textarea-lg {
  padding: 12px var(--space-4);
  font-size: var(--text-lg);
}


/* ══════════════════════════════════════════════════════════════════════════
   SELECT — caret indicator
   ══════════════════════════════════════════════════════════════════════════ */

.select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-7);
}


/* ══════════════════════════════════════════════════════════════════════════
   INPUT WITH ADORNMENT (prefix/suffix slot)
   ══════════════════════════════════════════════════════════════════════════ */

.input-group {
  display: flex;
  align-items: stretch;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-subtle);
  transition: var(--tr-colors);
  overflow: hidden;
}

.input-group:hover {
  border-color: var(--border-strong);
}

.input-group:focus-within {
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
}

.input-group > .input {
  border: none;
  box-shadow: none;
  border-radius: 0;
  flex: 1 1 auto;
  min-width: 0;
}
.input-group > .input:focus,
.input-group > .input:focus-visible {
  outline: none;
  box-shadow: none;
  border: none;
}

.input-prefix,
.input-suffix {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--muted);
  background: var(--surface-soft);
  border: none;
  white-space: nowrap;
}

.input-prefix {
  border-right: 1px solid var(--border);
}
.input-suffix {
  border-left: 1px solid var(--border);
}


/* ══════════════════════════════════════════════════════════════════════════
   CHECKBOX & RADIO
   ══════════════════════════════════════════════════════════════════════════ */

.checkbox,
.radio {
  width: 16px;
  height: 16px;
  margin: 0;
  flex-shrink: 0;
  cursor: pointer;
  accent-color: var(--brand);
  vertical-align: middle;
}

.checkbox:disabled,
.radio:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Checkbox / radio focus ring inherited from unified `:focus-visible` halo. */

.check-group {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--text);
  cursor: pointer;
  user-select: none;
  padding: 4px 0;
}

.check-group:hover {
  color: var(--text);
}


/* ══════════════════════════════════════════════════════════════════════════
   SWITCH — toggle (built on <input type="checkbox"> + label)
   ══════════════════════════════════════════════════════════════════════════ */

.switch {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
  flex-shrink: 0;
  vertical-align: middle;
}

.switch-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: var(--z-base);
}

.switch-track {
  position: absolute;
  inset: 0;
  background: var(--border-strong);
  border-radius: var(--radius-full);
  transition: var(--tr-colors);
  pointer-events: none;
}

.switch-track::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: var(--surface);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-subtle);
  transition: transform var(--d-fast) var(--ease-out);
}

.switch-input:checked + .switch-track {
  background: var(--brand);
}

.switch-input:checked + .switch-track::before {
  transform: translateX(16px);
}

.switch-input:focus-visible + .switch-track {
  box-shadow: 0 0 0 var(--ring-offset) var(--surface),
              0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
}

.switch-input:disabled + .switch-track {
  opacity: 0.5;
  cursor: not-allowed;
}


/* ── Switch tone variants — used inline in notice panels (info/success). ── */
.switch-input:checked + .switch-track.switch-track-info,
.switch-info .switch-input:checked + .switch-track { background: var(--info); }
.switch-input:checked + .switch-track.switch-track-success,
.switch-success .switch-input:checked + .switch-track { background: var(--success); }


/* ── Legacy two-span switch (kept because JS refers to the thumb node
     by ID). Same visual as .switch but supports the
     <input> + <span.switch-track> + <span.switch-thumb> markup where the
     thumb is a real sibling element rather than a ::before pseudo. Consumers
     only need to keep `.checked` in sync — CSS drives the rest. ── */

.switch-lg {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
  flex-shrink: 0;
  cursor: pointer;
  vertical-align: middle;
}
.switch-lg > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: var(--z-base);
}
.switch-lg .switch-track {
  position: absolute;
  inset: 0;
  background: var(--border-strong);
  border-radius: var(--radius-full);
  transition: background var(--d-fast) var(--ease);
  pointer-events: none;
}
.switch-lg .switch-thumb {
  position: absolute;
  left: 3px;
  top: 3px;
  width: 18px;
  height: 18px;
  background: var(--surface);
  border-radius: 50%;
  box-shadow: var(--shadow-subtle);
  transition: transform var(--d-fast) var(--ease-out);
  pointer-events: none;
}
.switch-lg > input:checked ~ .switch-track { background: var(--info); }
.switch-lg > input:checked ~ .switch-thumb { transform: translateX(20px); }
.switch-lg > input:focus-visible ~ .switch-track {
  box-shadow: 0 0 0 var(--ring-offset) var(--surface),
              0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
}
.switch-lg > input:disabled ~ .switch-track {
  opacity: 0.5;
  cursor: not-allowed;
}
/* Tone variants */
.switch-lg.switch-brand   > input:checked ~ .switch-track { background: var(--brand); }
.switch-lg.switch-success > input:checked ~ .switch-track { background: var(--success); }
.switch-lg.switch-warning > input:checked ~ .switch-track { background: var(--warning); }


/* XL variant (50×26) — used for admin settings toggles. Same DOM as
   .switch-lg (input + track + thumb) — extra 6px of travel. */
.switch-xl {
  position: relative;
  display: inline-block;
  width: 50px;
  height: 26px;
  flex-shrink: 0;
  cursor: pointer;
  vertical-align: middle;
}
.switch-xl > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: var(--z-base);
}
.switch-xl .switch-track {
  position: absolute;
  inset: 0;
  background: var(--border-strong);
  border-radius: var(--radius-full);
  transition: background var(--d-fast) var(--ease);
  pointer-events: none;
}
.switch-xl .switch-thumb {
  position: absolute;
  left: 3px;
  top: 3px;
  width: 20px;
  height: 20px;
  background: var(--surface);
  border-radius: 50%;
  box-shadow: var(--shadow-subtle);
  transition: transform var(--d-fast) var(--ease-out);
  pointer-events: none;
}
.switch-xl > input:checked ~ .switch-track { background: var(--info); }
.switch-xl > input:checked ~ .switch-thumb { transform: translateX(24px); }
.switch-xl > input:focus-visible ~ .switch-track {
  box-shadow: 0 0 0 var(--ring-offset) var(--surface),
              0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
}
.switch-xl > input:disabled ~ .switch-track { opacity: 0.5; cursor: not-allowed; }
.switch-xl.switch-brand   > input:checked ~ .switch-track { background: var(--brand); }
.switch-xl.switch-success > input:checked ~ .switch-track { background: var(--success); }
.switch-xl.switch-warning > input:checked ~ .switch-track { background: var(--warning); }


/* ══════════════════════════════════════════════════════════════════════════
   FORM-LABEL INLINE — labels that host inline chips (EPIC / SPRINT / OKR),
   and secondary "(optional)" annotations. Replaces
   `style="display:flex;align-items:center;gap:6px"` in labels + the
   `<span style="color:var(--muted);font-weight:400;font-size:10px">`
   annotation pattern scattered through modal partials.
   ══════════════════════════════════════════════════════════════════════════ */

.form-label-inline {
  display: flex;
  align-items: center;
  gap: 6px;
}

.form-label-note {
  font-size: 10px;
  font-weight: 400;
  color: var(--muted);
}

.form-label-value {
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.form-hint-hidden { display: none; }

.range-full {
  width: 100%;
  accent-color: var(--brand);
}


/* ══════════════════════════════════════════════════════════════════════════
   FIELDSET / FORM SECTION
   ══════════════════════════════════════════════════════════════════════════ */

.fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: 0 0 var(--space-4);
  background: var(--surface);
}

.fieldset-legend {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-2);
  padding: 0 var(--space-2);
  margin-bottom: var(--space-2);
}


/* ══════════════════════════════════════════════════════════════════════════
   FORM ACTIONS — footer row
   ══════════════════════════════════════════════════════════════════════════ */

.form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-5);
}

.form-actions-between {
  justify-content: space-between;
}


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .input,
  .textarea,
  .select,
  .input-group,
  .switch-track,
  .switch-track::before {
    transition: none;
  }
}


/* USAGE:
   <div class="field">
     <label class="label label-required" for="name">Project name</label>
     <input class="input" id="name" type="text" placeholder="Acme migration">
     <span class="hint">Shown to the team on the dashboard.</span>
   </div>

   <div class="field">
     <label class="label" for="email">Email</label>
     <input class="input input-error" id="email" type="email" value="bad">
     <span class="error-text">Please enter a valid address.</span>
   </div>

   <div class="field-row">
     <div class="field">
       <label class="label">Status</label>
       <select class="select">
         <option>Active</option><option>Paused</option>
       </select>
     </div>
     <div class="field">
       <label class="label">Owner</label>
       <input class="input" type="text">
     </div>
   </div>

   <div class="field">
     <label class="label">URL</label>
     <div class="input-group">
       <span class="input-prefix">https://</span>
       <input class="input" type="text" value="example.com">
     </div>
   </div>

   <label class="check-group">
     <input class="checkbox" type="checkbox">
     <span>Remember me</span>
   </label>

   <label class="check-group">
     <span class="switch">
       <input class="switch-input" type="checkbox" checked>
       <span class="switch-track"></span>
     </span>
     <span>Enable notifications</span>
   </label>

   <fieldset class="fieldset">
     <legend class="fieldset-legend">Notifications</legend>
     …fields…
   </fieldset>

   <div class="form-actions">
     <button class="btn btn-ghost">Cancel</button>
     <button class="btn btn-primary">Save</button>
   </div>
*/

/* ===== /css/v3/badges.css?v=1 ===== */
/* ============================================================================
   BADGES v3 — status pills + dots + count chips. Supersedes v2/badges.css and
   the legacy .badge block embedded in v3/components.css.
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens_unified.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible).
   Single-class rules only — no descendant selectors.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   BASE — pill, 11px/600, neutral surface
   ══════════════════════════════════════════════════════════════════════════ */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.005em;
  color: var(--text-2);
  background: var(--surface-soft);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  white-space: nowrap;
  vertical-align: middle;
  transition: var(--tr-colors);
}


/* ══════════════════════════════════════════════════════════════════════════
   SEMANTIC VARIANTS — solid tinted background, low-contrast border
   ══════════════════════════════════════════════════════════════════════════ */

.badge-success {
  background: var(--success-bg);
  color: var(--success);
  border-color: rgba(22, 163, 74, 0.16);
}

.badge-warning {
  background: var(--warning-bg);
  color: var(--warning);
  border-color: rgba(234, 88, 12, 0.16);
}

.badge-danger {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: rgba(220, 38, 38, 0.16);
}

.badge-info {
  background: var(--info-bg);
  color: var(--info);
  border-color: rgba(37, 99, 235, 0.16);
}

.badge-neutral {
  background: var(--surface-soft);
  color: var(--text-2);
  border-color: var(--border);
}

.badge-brand {
  background: var(--brand-fade);
  color: var(--brand);
  border-color: var(--brand-strong);
}


/* ══════════════════════════════════════════════════════════════════════════
   SOLID VARIANTS — high-contrast (use for prominent statuses)
   ══════════════════════════════════════════════════════════════════════════ */

.badge-solid {
  color: var(--surface);
}

.badge-solid-success {
  background: var(--success);
  color: var(--surface);
  border-color: var(--success);
}

.badge-solid-warning {
  background: var(--warning);
  color: var(--surface);
  border-color: var(--warning);
}

.badge-solid-danger {
  background: var(--danger);
  color: var(--surface);
  border-color: var(--danger);
}

.badge-solid-info {
  background: var(--info);
  color: var(--surface);
  border-color: var(--info);
}

.badge-solid-brand {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}

.badge-solid-neutral {
  background: var(--text-2);
  color: var(--surface);
  border-color: var(--text-2);
}


/* ══════════════════════════════════════════════════════════════════════════
   OUTLINE VARIANTS — bordered only, transparent fill
   ══════════════════════════════════════════════════════════════════════════ */

.badge-outline {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text-2);
}

.badge-outline-success {
  background: transparent;
  color: var(--success);
  border-color: var(--success);
}

.badge-outline-warning {
  background: transparent;
  color: var(--warning);
  border-color: var(--warning);
}

.badge-outline-danger {
  background: transparent;
  color: var(--danger);
  border-color: var(--danger);
}

.badge-outline-info {
  background: transparent;
  color: var(--info);
  border-color: var(--info);
}

.badge-outline-brand {
  background: transparent;
  color: var(--brand);
  border-color: var(--brand);
}


/* ══════════════════════════════════════════════════════════════════════════
   SIZES
   ══════════════════════════════════════════════════════════════════════════ */

.badge-xs {
  padding: 1px 6px;
  font-size: 10px;
  letter-spacing: 0.02em;
}

.badge-sm {
  padding: 2px var(--space-2);
  font-size: var(--text-xs);
}

.badge-md {
  /* default alias */
  padding: 2px var(--space-2);
  font-size: var(--text-xs);
}

.badge-lg {
  padding: 4px var(--space-3);
  font-size: var(--text-sm);
}


/* ══════════════════════════════════════════════════════════════════════════
   SHAPE MODIFIERS
   ══════════════════════════════════════════════════════════════════════════ */

.badge-square {
  border-radius: var(--radius-xs);
}

.badge-rounded {
  border-radius: var(--radius-sm);
}


/* ══════════════════════════════════════════════════════════════════════════
   DOT — standalone status dot, or accent inside a badge
   ══════════════════════════════════════════════════════════════════════════ */

.badge-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
  vertical-align: middle;
}

.dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--muted);
  vertical-align: middle;
  flex-shrink: 0;
}

.dot-success { background: var(--success); }
.dot-warning { background: var(--warning); }
.dot-danger  { background: var(--danger); }
.dot-info    { background: var(--info); }
.dot-brand   { background: var(--brand); }
.dot-neutral { background: var(--muted); }

.dot-pulse {
  position: relative;
}
.dot-pulse::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
  background: currentColor;
  opacity: 0.4;
  animation: badgePulse 1.6s ease-out infinite;
}

@keyframes badgePulse {
  0%   { transform: scale(1);   opacity: 0.4; }
  100% { transform: scale(2.4); opacity: 0;   }
}


/* ══════════════════════════════════════════════════════════════════════════
   COUNT CHIP — circular numeric badge (notifications)
   ══════════════════════════════════════════════════════════════════════════ */

.badge-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  color: var(--surface);
  background: var(--danger);
  border: 1px solid var(--surface);
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.badge-count-brand   { background: var(--brand); }
.badge-count-success { background: var(--success); }
.badge-count-warning { background: var(--warning); }
.badge-count-info    { background: var(--info); }
.badge-count-neutral { background: var(--text-2); }


/* ══════════════════════════════════════════════════════════════════════════
   INTERACTIVE — anchor/button variant of badge
   ══════════════════════════════════════════════════════════════════════════ */

.badge-interactive {
  cursor: pointer;
  text-decoration: none;
}

.badge-interactive:hover {
  filter: brightness(0.97);
}

/* Badge focus ring inherited from unified `:focus-visible` halo in a11y_fixes.css. */


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .badge,
  .badge-interactive {
    transition: none;
  }
  .dot-pulse::after {
    animation: none;
  }
}


/* USAGE:
   <span class="badge badge-success">Active</span>
   <span class="badge badge-warning">Pending</span>
   <span class="badge badge-danger">Blocked</span>
   <span class="badge badge-info">In review</span>
   <span class="badge badge-neutral">Draft</span>
   <span class="badge badge-brand">Premium</span>

   <span class="badge badge-success">
     <i class="badge-dot"></i> Active
   </span>

   <span class="badge badge-solid-danger badge-lg">Critical</span>
   <span class="badge badge-outline-brand">Beta</span>
   <span class="badge badge-info badge-square">v3</span>

   <i class="dot dot-success"></i> Online
   <i class="dot dot-warning dot-pulse"></i> Connecting…

   <button class="btn btn-ghost btn-icon" aria-label="Inbox">
     <i class="icon-inbox"></i>
     <span class="badge-count">7</span>
   </button>

   <a class="badge badge-info badge-interactive" href="#">v3.2 release notes</a>
*/

/* ===== /css/v3/cards.css?v=1 ===== */
/* ============================================================================
   CARDS v3 — surface containers (header, body, footer, media). Supersedes
   v2/cards.css and the legacy .card block embedded in v3/components.css.
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens_unified.css + system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible/:active).
   No descendant selectors — every part is its own class.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   BASE — neutral surface card
   ══════════════════════════════════════════════════════════════════════════ */

.card {
  display: block;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-subtle);
  transition: var(--tr-default);
  text-decoration: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   ELEVATION VARIANTS
   ══════════════════════════════════════════════════════════════════════════ */

.card-flat {
  border-color: transparent;
  box-shadow: none;
}

.card-elevated {
  box-shadow: var(--shadow-elevated);
}

.card-floating {
  box-shadow: var(--shadow-modal);
  border-color: transparent;
}

.card-soft {
  background: var(--surface-soft);
  border-color: transparent;
  box-shadow: none;
}

.card-outline {
  background: transparent;
  border-color: var(--border-strong);
  box-shadow: none;
}

.card-tinted-brand {
  background: var(--brand-soft);
  border-color: var(--brand-strong);
}

.card-tinted-success {
  background: var(--success-bg);
  border-color: rgba(22,163,74,0.16);
}

.card-tinted-warning {
  background: var(--warning-bg);
  border-color: rgba(234,88,12,0.16);
}

.card-tinted-danger {
  background: var(--danger-bg);
  border-color: rgba(220,38,38,0.16);
}

.card-tinted-info {
  background: var(--info-bg);
  border-color: rgba(37,99,235,0.16);
}


/* ══════════════════════════════════════════════════════════════════════════
   DENSITY VARIANTS
   ══════════════════════════════════════════════════════════════════════════ */

.card-compact {
  padding: var(--space-4);
  border-radius: var(--radius-md);
}

.card-tight {
  padding: var(--space-3);
  border-radius: var(--radius-sm);
}

.card-roomy {
  padding: var(--space-7);
  border-radius: var(--radius-xl);
}

.card-flush {
  padding: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   INTERACTIVE — hoverable / linkable card
   ══════════════════════════════════════════════════════════════════════════ */

.card-interactive {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.card-interactive:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-elevated);
  transform: translateY(-1px);
}

.card-interactive:active {
  transform: translateY(0);
  box-shadow: var(--shadow-subtle);
}

/* Card focus ring inherited from unified `:focus-visible` halo in a11y_fixes.css. */


/* ══════════════════════════════════════════════════════════════════════════
   HEADER / BODY / FOOTER PARTS
   ══════════════════════════════════════════════════════════════════════════ */

.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-4);
}

.card-header-flush {
  padding: var(--space-4) var(--space-5);
  margin: 0;
}

.card-body {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--text);
}

.card-body-flush {
  padding: var(--space-5);
}

.card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  margin-top: var(--space-4);
}

.card-footer-flush {
  padding: var(--space-4) var(--space-5);
  background: var(--bg);
  margin: 0;
}

.card-footer-actions {
  justify-content: flex-end;
}


/* ══════════════════════════════════════════════════════════════════════════
   TITLE / META / DESCRIPTION
   ══════════════════════════════════════════════════════════════════════════ */

.card-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0 0 var(--space-2);
  line-height: 1.35;
}

.card-title-sm {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text);
  margin: 0 0 4px;
}

.card-subtitle {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-2);
  margin: 0 0 var(--space-2);
}

.card-meta {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--muted);
  margin: 0;
}

.card-description {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-2);
  line-height: 1.55;
  margin: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   MEDIA — image header (flush card)
   ══════════════════════════════════════════════════════════════════════════ */

.card-media {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
  background: var(--surface-soft);
}

.card-media-square {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.card-media-wide {
  aspect-ratio: 16 / 9;
  object-fit: cover;
}


/* ══════════════════════════════════════════════════════════════════════════
   STATUS STRIP — colored top accent
   ══════════════════════════════════════════════════════════════════════════ */

.card-accent-top {
  border-top: 3px solid var(--brand);
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
}

.card-accent-success { border-top-color: var(--success); }
.card-accent-warning { border-top-color: var(--warning); }
.card-accent-danger  { border-top-color: var(--danger);  }
.card-accent-info    { border-top-color: var(--info);    }
.card-accent-brand   { border-top-color: var(--brand);   }


/* ══════════════════════════════════════════════════════════════════════════
   GRID — convenience layout
   ══════════════════════════════════════════════════════════════════════════ */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-4);
}

.card-grid-tight {
  gap: var(--space-3);
}

@media (max-width: 640px) {
  .card-grid {
    grid-template-columns: 1fr;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   STATS CARD — KPI variant
   ══════════════════════════════════════════════════════════════════════════ */

.card-stat-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-2);
  letter-spacing: -0.005em;
  margin: 0 0 var(--space-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.card-stat-value {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 500;
  line-height: 1.1;
  color: var(--text);
  letter-spacing: -0.02em;
  margin: 0;
}

.card-stat-delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--success);
  margin-top: var(--space-2);
}

.card-stat-delta-down {
  color: var(--danger);
}


/* ══════════════════════════════════════════════════════════════════════════
   ERROR / DISABLED STATES
   ══════════════════════════════════════════════════════════════════════════ */

.card-error {
  border-color: var(--danger);
  background: var(--danger-fade);
}

.card-disabled {
  opacity: 0.6;
  pointer-events: none;
  cursor: not-allowed;
}


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .card,
  .card-interactive,
  .card-interactive:hover,
  .card-interactive:active {
    transition: none;
    transform: none;
  }
}


/* USAGE:
   <div class="card">
     <div class="card-header">
       <div>
         <h3 class="card-title">Project alpha</h3>
         <p class="card-subtitle">12 open tasks</p>
       </div>
       <span class="badge badge-success">On track</span>
     </div>
     <div class="card-body">
       <p>Body content explaining the project status.</p>
     </div>
     <div class="card-footer">
       <span class="card-meta">Updated 2h ago</span>
       <button class="btn btn-ghost btn-sm">Open</button>
     </div>
   </div>

   <a class="card card-compact card-interactive" href="/project/1">
     <h4 class="card-title-sm">Quick link</h4>
     <p class="card-description">Click to navigate.</p>
   </a>

   <div class="card card-flush">
     <img class="card-media card-media-wide" src="/img/cover.jpg" alt="">
     <div class="card-body-flush">
       <h3 class="card-title">With media</h3>
     </div>
   </div>

   <div class="card-grid">
     <div class="card card-accent-top card-accent-success">
       <p class="card-stat-label">Revenue</p>
       <p class="card-stat-value">$48.2k</p>
       <span class="card-stat-delta">+12.4%</span>
     </div>
     <div class="card card-accent-top card-accent-danger">
       <p class="card-stat-label">Churn</p>
       <p class="card-stat-value">3.1%</p>
       <span class="card-stat-delta card-stat-delta-down">+0.4%</span>
     </div>
   </div>

   <div class="card card-tinted-warning">
     <h4 class="card-title-sm">Heads up</h4>
     <p class="card-description">3 sprints behind schedule.</p>
   </div>
*/

/* ===== /css/v3/table.css?v=1 ===== */
/* ============================================================================
   TABLE v3 — canonical table styling, supersedes app.css/polish.css/v2 rules
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens.css + v2/system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:nth-child pseudo).
   Uses limited single-level descendant on .table thead/tbody (CSS structural
   pseudo-elements are necessary for table semantics — kept to .table > * only).
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   WRAPPER — rounded surface that clips overflow
   ══════════════════════════════════════════════════════════════════════════ */

.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}


/* ══════════════════════════════════════════════════════════════════════════
   BASE TABLE — borderless, 13px body, collapsed borders
   ══════════════════════════════════════════════════════════════════════════ */

.table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.4;
  color: var(--text);
}

/* Header cells — token-driven; single-level child of .table */
.table thead th {
  padding: 10px var(--space-3);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  text-align: left;
  color: var(--text-2);
  background: var(--surface-soft);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  vertical-align: middle;
}

/* Body cells */
.table tbody td {
  padding: 10px var(--space-3);
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
  color: var(--text);
}

.table tbody tr {
  transition: var(--tr-colors);
}

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

.table tbody tr:last-child td {
  border-bottom: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   CELL UTILITIES — alignment, numeric, actions
   ══════════════════════════════════════════════════════════════════════════ */

.table-cell-right {
  text-align: right;
}
.table-cell-center {
  text-align: center;
}

.table-cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text);
}

.table-actions {
  white-space: nowrap;
  text-align: right;
  width: 1%;
}

.table-cell-truncate {
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ══════════════════════════════════════════════════════════════════════════
   DENSITY & STYLE VARIANTS
   ══════════════════════════════════════════════════════════════════════════ */

/* Compact — tighter rows */
.table-compact thead th,
.table-compact tbody td {
  padding: 6px var(--space-2);
  font-size: 12px;
}

/* Comfortable — looser rows */
.table-comfortable thead th,
.table-comfortable tbody td {
  padding: var(--space-3) var(--space-4);
}

/* Bordered — visible cell borders */
.table-bordered {
  border: 1px solid var(--border);
}
.table-bordered thead th,
.table-bordered tbody td {
  border-right: 1px solid var(--border-soft);
}
.table-bordered thead th:last-child,
.table-bordered tbody td:last-child {
  border-right: none;
}

/* Striped — alternate row backgrounds */
.table-striped tbody tr:nth-child(odd) {
  background: var(--surface-soft);
}
.table-striped tbody tr:hover {
  background: var(--bg-hover);
}

/* Flush — no horizontal padding on edges */
.table-flush thead th:first-child,
.table-flush tbody td:first-child {
  padding-left: 0;
}
.table-flush thead th:last-child,
.table-flush tbody td:last-child {
  padding-right: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   STICKY HEADER — locks thead when scrolling .table-scroll
   ══════════════════════════════════════════════════════════════════════════ */

.table-sticky thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--surface-soft);
}


/* ══════════════════════════════════════════════════════════════════════════
   SORTABLE HEADER — visual affordance for sortable columns
   ══════════════════════════════════════════════════════════════════════════ */

.table-sortable {
  cursor: pointer;
  user-select: none;
  transition: var(--tr-colors);
}
.table-sortable:hover {
  color: var(--text);
  background: var(--bg-hover);
}
.table-sortable:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
}


/* ══════════════════════════════════════════════════════════════════════════
   ROW STATES — selected, disabled
   ══════════════════════════════════════════════════════════════════════════ */

.table-row-selected {
  background: var(--brand-fade);
}
.table-row-selected:hover {
  background: var(--brand-fade);
}

.table-row-disabled {
  opacity: 0.5;
  pointer-events: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   EMPTY STATE row inside table
   ══════════════════════════════════════════════════════════════════════════ */

.table-empty {
  padding: var(--space-7) var(--space-4);
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}


/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE STACK — transform table to card-stack on narrow viewports
   ══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .table-stack thead {
    display: none;
  }
  .table-stack tbody tr {
    display: block;
    padding: var(--space-3);
    border-bottom: 1px solid var(--border);
    background: var(--surface);
  }
  .table-stack tbody tr:last-child {
    border-bottom: none;
  }
  .table-stack tbody td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    padding: 6px 0;
    border-bottom: none;
    text-align: right;
  }
  .table-stack tbody td::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--text-2);
    text-align: left;
    flex-shrink: 0;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   WIRE-UP INSTRUCTIONS:
   Add to static/index.html inside <head>, AFTER legacy-shim.css so this
   file wins the cascade (override priority):

     <link rel="stylesheet" href="/css/v3/table.css?v=1">

   Recommended placement order (top -> bottom in <head>):
     1. tokens.css
     2. v2/system_tokens.css
     3. (all other v2/*.css and app.css)
     4. v2/legacy-shim.css
     5. v3/components.css
     6. v3/modal.css
     7. v3/table.css              <-- here

   USAGE:
     <div class="table-wrap table-scroll">
       <table class="table table-sticky">
         <thead><tr><th>Name</th><th class="table-cell-num">Count</th></tr></thead>
         <tbody>
           <tr>
             <td data-label="Name">Foo</td>
             <td class="table-cell-num" data-label="Count">42</td>
           </tr>
         </tbody>
       </table>
     </div>

   For mobile stack mode, add `table-stack` and ensure each <td data-label="…">.
   ══════════════════════════════════════════════════════════════════════════ */

/* ===== /css/v3/modal.css?v=7 ===== */
/* ============================================================================
   MODAL v3 — canonical modal, supersedes app.css/polish.css/v2/modal.css rules
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css. Uses tokens.css + v2/system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible + .open).
   No descendant selectors — only single-class rules and pseudo states.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   OVERLAY (scrim) — fixed full-viewport, centers child .modal
   ══════════════════════════════════════════════════════════════════════════ */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition:
    opacity var(--d-base) var(--ease-out),
    visibility 0s linear var(--d-base);
  visibility: hidden;
}

.modal-overlay.open {
  display: flex;
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--d-base) var(--ease-out),
    visibility 0s linear 0s;
  animation: modalOverlayFadeIn var(--d-base) var(--ease-out) both;
}

@keyframes modalOverlayFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}


/* ══════════════════════════════════════════════════════════════════════════
   MODAL — surface dialog
   ══════════════════════════════════════════════════════════════════════════ */

.modal {
  position: relative;
  z-index: var(--z-modal);

  /* Surface */
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);

  /* Sizing */
  width: 100%;
  max-width: 560px;
  max-height: 90vh;

  /* Layout */
  display: flex;
  flex-direction: column;
  overflow: hidden;

  /* Motion */
  animation: modalSlideUp var(--d-slow) var(--ease-out) both;
}

@keyframes modalSlideUp {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Size variants */
.modal-sm { max-width: 400px; }
.modal-wide { max-width: 800px; }
.modal-xl { max-width: 1100px; }
.modal-full {
  max-width: calc(100vw - var(--space-7));
  max-height: calc(100vh - var(--space-7));
}


/* ══════════════════════════════════════════════════════════════════════════
   HEADER — title row + close button
   ══════════════════════════════════════════════════════════════════════════ */

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  /* Padding compressed bottom-to-zero so the body's own top padding
   * controls the title→form gap. The previous symmetric 24px+24px
   * created ~48px of dead whitespace below the title (visible in user
   * issue images #28 vs #29 — modal-header version had a huge gap;
   * the legacy direct-title variant looked tight & correct). */
  padding: var(--space-5) var(--space-5) 0;
  /* border-bottom removed — created an unwanted divider line between
   * the title and the form/body across all modals (research, release,
   * feature flag, experiment, NPS, new doc, kickoff detail). */
  flex-shrink: 0;
}

/* Wave 17 — Agent 5 cleanup:
 * Deleted the specificity-hack rules that previously fought
 * legacy_replacement.css `.modal > .modal-header` border + padding.
 * Now that legacy_replacement.css has had its `border-bottom` removed
 * (see legacy_replacement.css line ~178), and the base `.modal-header`
 * rule above carries zero bottom-padding, the cascade is self-consistent
 * and no compensating selectors are needed. */

.modal-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--text);
  flex: 1 1 auto;
  min-width: 0;
}

.modal-subtitle {
  margin: 4px 0 0;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
  line-height: 1.4;
}


/* ══════════════════════════════════════════════════════════════════════════
   CLOSE BUTTON — icon button variant, sits in header
   ══════════════════════════════════════════════════════════════════════════ */

/* Positioned absolutely at top-right of the .modal container so partials
   don't need a .modal-header wrapper — one <button.modal-close> as first
   child of .modal is enough. Consumers hit Esc, click the scrim, OR click
   this X (Day 10 restore — accessibility parity with the Esc-close hint). */
.modal-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--muted);
  cursor: pointer;
  transition: var(--tr-colors);
}

.modal-close:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.modal-close:focus-visible {
  box-shadow: 0 0 0 var(--ring-offset) var(--surface),
              0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
}

/* Ensure the modal-title doesn't collide with the absolutely-positioned close
   button (32px + 12px offset = 44px reserved; use space-7 = 48px). */
.modal .modal-title { padding-right: var(--space-7); }

/* Verify the .modal is a positioning context — it already carries a
   `position: relative` via .modal itself (see line ~55 base rule). */


/* ══════════════════════════════════════════════════════════════════════════
   BODY — scrollable content area
   ══════════════════════════════════════════════════════════════════════════ */

.modal-body {
  padding: var(--space-5) var(--space-5);
  overflow-y: auto;
  flex: 1 1 auto;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
}

.modal-body-compact {
  padding: var(--space-4);
}

.modal-body-flush {
  padding: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   FOOTER — action row, right-aligned by default
   ══════════════════════════════════════════════════════════════════════════ */

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border);
  background: var(--bg);
  flex-shrink: 0;
}

.modal-footer-start {
  justify-content: flex-start;
}

.modal-footer-between {
  justify-content: space-between;
}


/* ══════════════════════════════════════════════════════════════════════════
   ESC HINT — a11y affordance that replaces the removed X-close button.
   Renders as a muted "Esc to close" string anchored to the left edge of
   the action row, so keyboard + screen-reader users still get a visible
   dismissal cue. Suppressed below 600px where space is tight.
   Wave 17 — Agent 5.
   ══════════════════════════════════════════════════════════════════════════ */

.modal-actions {
  position: relative;
}

.modal-actions::before {
  content: "Esc to close";
  position: absolute;
  left: var(--space-5);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: .04em;
  pointer-events: none;
}

@media (max-width: 600px) {
  .modal-actions::before { display: none; }
}


/* ══════════════════════════════════════════════════════════════════════════
   MOBILE — full-screen below 768px
   ══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .modal-overlay {
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
  }

  .modal {
    max-width: 100%;
    max-height: 100dvh;
    border-radius: 0;
    border: none;
    height: 100dvh;
  }

  .modal-sm,
  .modal-wide,
  .modal-xl,
  .modal-full {
    max-width: 100%;
    max-height: 100dvh;
    border-radius: 0;
    border: none;
  }

  .modal-header {
    padding: var(--space-4);
  }

  .modal-body {
    padding: var(--space-4);
  }

  .modal-footer {
    padding: var(--space-3) var(--space-4);
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   REDUCED MOTION — disable entrance animations
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .modal-overlay,
  .modal-overlay.open,
  .modal {
    animation: none;
    transition: none;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   WIRE-UP INSTRUCTIONS:
   Add to static/index.html inside <head>, AFTER legacy-shim.css so this
   file wins the cascade (override priority):

     <link rel="stylesheet" href="/css/v3/modal.css?v=1">

   Recommended placement order (top -> bottom in <head>):
     1. tokens.css
     2. v2/system_tokens.css
     3. (all other v2/*.css and app.css)
     4. v2/legacy-shim.css
     5. v3/components.css
     6. v3/modal.css              <-- here
     7. v3/table.css

   USAGE:
     <div class="modal-overlay open" role="dialog" aria-modal="true">
       <div class="modal modal-wide">
         <div class="modal-header">
           <h2 class="modal-title">Title</h2>
           <button class="modal-close" aria-label="Close">×</button>
         </div>
         <div class="modal-body">…</div>
         <div class="modal-footer">
           <button class="btn btn-ghost">Cancel</button>
           <button class="btn btn-primary">Save</button>
         </div>
       </div>
     </div>
   ══════════════════════════════════════════════════════════════════════════ */


/* ============================================================================
   LEGACY nx-{bl,rl,pr}-* MODAL CLASSES — consolidated (Day 10 lanjutan).
   Sources: page_baselines.js (200 callsites), page_resource_leveling.js
   (76), page_procurement.js (140). HTML/JS still ship the prefixed class
   names; here they share a single ruleset via grouped selectors. Only
   `max-width` differs per-suite (bl=960, rl=720, pr=760) and body density
   for rl (13 px, 60 vh) — everything else was byte-identical duplication.
   Renaming callsites is a follow-up sprint; this ships the visual
   consolidation without touching JS.
   ============================================================================ */

.nx-bl-modal-overlay,
.nx-rl-modal-overlay,
.nx-pr-modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg-overlay, rgba(0, 0, 0, 0.45));
  z-index: 9999;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 60px 16px;
  overflow: auto;
}

.nx-bl-modal,
.nx-rl-modal,
.nx-pr-modal {
  background: var(--surface, var(--card-bg, var(--bg, #fff)));
  width: 100%;
  border-radius: 12px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  border: 1px solid var(--border, #e5e7eb);
}
.nx-bl-modal { max-width: 960px; }
.nx-rl-modal { max-width: 720px; }
.nx-pr-modal { max-width: 760px; }

.nx-bl-modal-hd,
.nx-rl-modal-hd,
.nx-pr-modal-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}

.nx-bl-modal-hd h3,
.nx-rl-modal-hd h3,
.nx-pr-modal-hd h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
}

.nx-bl-modal-body,
.nx-rl-modal-body,
.nx-pr-modal-body {
  padding: 16px 18px;
  max-height: 70vh;
  overflow: auto;
}
/* Resource-leveling modal has denser content (billing table). */
.nx-rl-modal-body { max-height: 60vh; font-size: 13px; }

.nx-bl-modal-ft,
.nx-rl-modal-ft,
.nx-pr-modal-ft {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 16px;
  border-top: 1px solid var(--border, #e5e7eb);
}

.nx-bl-close,
.nx-rl-close,
.nx-pr-close {
  background: none;
  border: 0;
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  color: var(--muted, #667);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ===== /css/v3/components.css?v=1 ===== */
/* ============================================================================
   COMPONENTS v3 — single source of truth, supersedes all .btn .badge .card .form
   ----------------------------------------------------------------------------
   Load AFTER legacy-shim.css to win cascade. Uses tokens.css + v2/system_tokens.css.
   No !important. Specificity max 0,2,0 (only :hover/:focus-visible/:disabled pseudo).
   No descendant selectors (.parent .child) — only single-class rules.
   ============================================================================ */


/* ══════════════════════════════════════════════════════════════════════════
   BUTTONS
   ══════════════════════════════════════════════════════════════════════════ */

.btn {
  /* Base shape */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 9px var(--space-4);
  min-height: 36px;

  /* Typography */
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.005em;
  white-space: nowrap;

  /* Surface */
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-subtle);

  /* Behavior */
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition: var(--tr-default);
}

.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  filter: brightness(0.98);
}

.btn:active {
  transform: translateY(1px);
  box-shadow: none;
}

.btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

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

/* ── Variants ─────────────────────────────────────────────────────────────── */

.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
  box-shadow: var(--shadow-subtle);
}
.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
  color: var(--surface);
  filter: none;
}
.btn-primary:focus-visible {
  outline-color: var(--brand);
  box-shadow: var(--shadow-focus);
}

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-secondary:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border-color: transparent;
  box-shadow: none;
}
.btn-ghost:hover {
  background: var(--bg-hover);
  color: var(--text);
  border-color: transparent;
  filter: none;
}

.btn-danger {
  background: var(--danger);
  color: var(--surface);
  border-color: var(--danger);
}
.btn-danger:hover {
  background: #B91C1C;
  border-color: #B91C1C;
  color: var(--surface);
  filter: none;
}
.btn-danger:focus-visible {
  outline-color: var(--danger);
}

.btn-success {
  background: var(--success);
  color: var(--surface);
  border-color: var(--success);
}
.btn-success:hover {
  background: #15803D;
  border-color: #15803D;
  color: var(--surface);
  filter: none;
}
.btn-success:focus-visible {
  outline-color: var(--success);
}

.btn-warning {
  background: var(--warning);
  color: var(--surface);
  border-color: var(--warning);
}
.btn-warning:hover {
  background: #C2410C;
  border-color: #C2410C;
  color: var(--surface);
  filter: none;
}

/* ── Sizes ────────────────────────────────────────────────────────────────── */

.btn-xs {
  padding: 4px var(--space-2);
  min-height: 24px;
  font-size: 11px;
  border-radius: var(--radius-xs);
  gap: 4px;
}

.btn-sm {
  padding: 6px var(--space-3);
  min-height: 30px;
  font-size: 12px;
  border-radius: var(--radius-sm);
}

.btn-lg {
  padding: 12px var(--space-5);
  min-height: 44px;
  font-size: 14px;
  border-radius: var(--radius-md);
}

/* Icon-only square */
.btn-icon {
  width: 36px;
  padding: 0;
  aspect-ratio: 1;
}
.btn-icon.btn-xs { width: 24px; }
.btn-icon.btn-sm { width: 30px; }
.btn-icon.btn-lg { width: 44px; }

/* Full-width */
.btn-block {
  display: flex;
  width: 100%;
}


/* ══════════════════════════════════════════════════════════════════════════
   BADGES — pill, 11px/600, semantic variants
   ══════════════════════════════════════════════════════════════════════════ */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px var(--space-2);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.005em;
  color: var(--text-2);
  background: var(--surface-soft);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  white-space: nowrap;
  vertical-align: middle;
}

.badge-success {
  background: var(--success-bg);
  color: var(--success);
  border-color: rgba(22, 163, 74, 0.16);
}

.badge-warning {
  background: var(--warning-bg);
  color: var(--warning);
  border-color: rgba(234, 88, 12, 0.16);
}

.badge-danger {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: rgba(220, 38, 38, 0.16);
}

.badge-info {
  background: var(--info-bg);
  color: var(--info);
  border-color: rgba(37, 99, 235, 0.16);
}

.badge-neutral {
  background: var(--surface-soft);
  color: var(--text-2);
  border-color: var(--border);
}

.badge-brand {
  background: var(--brand-fade);
  color: var(--brand);
  border-color: var(--brand-strong);
}

/* Dot accent inside badge */
.badge-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
  display: inline-block;
}


/* ══════════════════════════════════════════════════════════════════════════
   CARDS — surface, border, padded
   ══════════════════════════════════════════════════════════════════════════ */

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-subtle);
  transition: var(--tr-default);
}

.card-elevated {
  box-shadow: var(--shadow-elevated);
}

.card-flat {
  border-color: transparent;
  box-shadow: none;
}

.card-soft {
  background: var(--surface-soft);
  border-color: transparent;
  box-shadow: none;
}

.card-interactive {
  cursor: pointer;
}
.card-interactive:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-elevated);
  transform: translateY(-1px);
}
.card-interactive:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.card-compact {
  padding: var(--space-4);
  border-radius: var(--radius-md);
}

.card-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--text);
  margin: 0 0 var(--space-3);
  line-height: 1.35;
}

.card-meta {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--muted);
}

.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-4);
}

.card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  margin-top: var(--space-4);
}


/* ══════════════════════════════════════════════════════════════════════════
   FORM CONTROLS
   ══════════════════════════════════════════════════════════════════════════ */

.form-input,
.form-select,
.form-textarea {
  display: block;
  width: 100%;
  padding: 9px var(--space-3);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-subtle);
  transition: var(--tr-colors);
  appearance: none;
  -webkit-appearance: none;
}

.form-textarea {
  min-height: 96px;
  line-height: 1.6;
  resize: vertical;
}

.form-input:hover,
.form-select:hover,
.form-textarea:hover {
  border-color: var(--border-strong);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
}

.form-input:disabled,
.form-select:disabled,
.form-textarea:disabled {
  background: var(--surface-soft);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.7;
}

.form-input:invalid,
.form-select:invalid,
.form-textarea:invalid {
  border-color: var(--danger);
}

.form-input::placeholder,
.form-textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* Select caret indicator */
.form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  padding-right: var(--space-7);
}

/* Sizes */
.form-input-sm,
.form-select-sm {
  padding: 6px var(--space-2);
  font-size: 13px;
  border-radius: var(--radius-sm);
}
.form-input-lg,
.form-select-lg {
  padding: 12px var(--space-4);
  font-size: 15px;
}

/* ── Form Layout Helpers ─────────────────────────────────────────────────── */

.form-group {
  display: block;
  margin-bottom: var(--space-4);
}

.form-label {
  display: block;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-2);
  margin-bottom: 6px;
}

.form-label-required::after {
  content: '*';
  color: var(--danger);
  margin-left: 4px;
}

.form-help {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--muted);
  margin-top: 4px;
}

.form-error {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--danger);
  margin-top: 4px;
}

/* Checkbox / radio scaled */
.form-checkbox,
.form-radio {
  width: 16px;
  height: 16px;
  accent-color: var(--brand);
  cursor: pointer;
  margin: 0;
}

/* Row of paired fields */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
.form-row-full {
  grid-template-columns: 1fr;
}

@media (max-width: 640px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   NOTICE — semantic callout panel (info / success / warning / danger).
   Replaces inline `style="background:#f0fdf4;border:1px solid #86efac;..."`
   patterns scattered across modals and settings pages so dark-mode inherits
   automatically. Naming avoids collision with .callout-* used by the doc
   block editor in app.css.
   ══════════════════════════════════════════════════════════════════════════ */

.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid;
  margin-bottom: var(--space-1);
}

.notice-info    { background: var(--info-bg);    border-color: color-mix(in srgb, var(--info)    30%, transparent); }
.notice-success { background: var(--success-bg); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.notice-warning { background: var(--warning-bg); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.notice-danger  { background: var(--danger-bg);  border-color: color-mix(in srgb, var(--danger)  30%, transparent); }
.notice-brand   { background: var(--brand-fade); border-color: color-mix(in srgb, var(--brand)   30%, transparent); }

.notice-icon {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #fff;
}
.notice-info    .notice-icon { background: var(--info); }
.notice-success .notice-icon { background: var(--success); }
.notice-warning .notice-icon { background: var(--warning); }
.notice-danger  .notice-icon { background: var(--danger); }
.notice-brand   .notice-icon { background: var(--brand); }

.notice-icon-sm { width: 20px; height: 20px; }

.notice-body { flex: 1; min-width: 0; }

.notice-title {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.35;
}
.notice-info    > .notice-body > .notice-title { color: var(--info); }
.notice-success > .notice-body > .notice-title { color: var(--success); }
.notice-warning > .notice-body > .notice-title { color: var(--warning); }
.notice-danger  > .notice-body > .notice-title { color: var(--danger); }
.notice-brand   > .notice-body > .notice-title { color: var(--brand); }

.notice-text {
  font-size: 11.5px;
  color: var(--text-2);
  margin-top: 2px;
  line-height: 1.55;
}

.notice-metric {
  margin-left: auto;
  font-size: 22px;
  font-weight: 900;
  font-family: var(--font-mono);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  align-self: center;
}
.notice-info    > .notice-metric { color: var(--info); }
.notice-success > .notice-metric { color: var(--success); }
.notice-warning > .notice-metric { color: var(--warning); }
.notice-danger  > .notice-metric { color: var(--danger); }
.notice-brand   > .notice-metric { color: var(--brand); }

.notice-sep {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid;
  font-size: 11.5px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.notice-info    .notice-sep { border-top-color: color-mix(in srgb, var(--info)    24%, transparent); color: var(--info); }
.notice-success .notice-sep { border-top-color: color-mix(in srgb, var(--success) 24%, transparent); color: var(--success); }
.notice-warning .notice-sep { border-top-color: color-mix(in srgb, var(--warning) 24%, transparent); color: var(--warning); }
.notice-danger  .notice-sep { border-top-color: color-mix(in srgb, var(--danger)  24%, transparent); color: var(--danger); }
.notice-brand   .notice-sep { border-top-color: color-mix(in srgb, var(--brand)   24%, transparent); color: var(--brand); }

/* Layout modifier: title/text on the left, control (switch/metric) on the right */
.notice-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.notice-row > * { min-width: 0; }

/* Standalone result banner slot (inline-status after form submit).
   Class-only replacement for legacy inline `style="display:none;..."`. */
.notice-banner {
  border-radius: var(--radius-sm);
  padding: 9px 14px;
  font-size: 12px;
  margin-top: 6px;
}
.notice-banner[hidden] { display: none; }
.notice-banner.notice-info    { background: var(--info-bg);    color: var(--info); }
.notice-banner.notice-success { background: var(--success-bg); color: var(--success); }
.notice-banner.notice-warning { background: var(--warning-bg); color: var(--warning); }
.notice-banner.notice-danger  { background: var(--danger-bg);  color: var(--danger); }

/* Density variant kept for grep-ability if a caller wants a labeled hook */
.notice-block { /* alias — currently no extra rules, reserved for future variants */ }

/* Inline SVG icon used when notice has no icon-square wrapper. Sized like a small chip icon. */
.notice-icon-inline {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}
.notice-info    > .notice-icon-inline { color: var(--info); }
.notice-success > .notice-icon-inline { color: var(--success); }
.notice-warning > .notice-icon-inline { color: var(--warning); }
.notice-danger  > .notice-icon-inline { color: var(--danger); }
.notice-brand   > .notice-icon-inline { color: var(--brand); }


/* ══════════════════════════════════════════════════════════════════════════
   RISK-MATRIX indicator — Probability × Impact result panel inside the
   Risk modal. Initial state is neutral (surface-soft); JS repaints the
   dot/score/border with tone colors via inline style based on RISK_MATRIX
   lookup (that JS-driven repaint is out of Day-1 scope).
   ══════════════════════════════════════════════════════════════════════════ */

.risk-matrix-box {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--bg);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-1);
  transition: background var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease);
}
.risk-matrix-dot {
  width: 42px;
  height: 42px;
  border-radius: var(--radius-md);
  background: var(--surface-soft);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  transition: background var(--d-fast) var(--ease);
}
.risk-matrix-body { flex: 1; min-width: 0; }
.risk-matrix-label { font-size: 12px; font-weight: 700; color: var(--text); }
.risk-matrix-desc  { font-size: 11px; color: var(--muted); margin-top: 2px; }
.risk-matrix-score {
  margin-left: auto;
  font-size: 22px;
  font-weight: 900;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   PREVIEW-LIST — scrollable list container used e.g. in the "Create Tasks
   from AI" modal. Token-driven surface so it inherits dark-mode correctly.
   ══════════════════════════════════════════════════════════════════════════ */

.preview-list {
  max-height: 250px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
}


/* ══════════════════════════════════════════════════════════════════════════
   CHART-ICON tones — semantic tint pairs (bg + fg) for the dashboard
   chart-card icon squares. Base `.chart-icon` lives in app.css; these
   modifiers replace inline `style="background:#ede9fe;color:#7c3aed"` etc.
   ══════════════════════════════════════════════════════════════════════════ */

.chart-icon-brand   { background: var(--brand-fade);        color: var(--brand); }
.chart-icon-info    { background: var(--info-bg);           color: var(--info); }
.chart-icon-success { background: var(--success-bg);        color: var(--success); }
.chart-icon-warning { background: var(--warning-bg);        color: var(--warning); }
.chart-icon-danger  { background: var(--danger-bg);         color: var(--danger); }
.chart-icon-purple  { background: color-mix(in srgb, var(--purple) 14%, transparent); color: var(--purple); }
.chart-icon-teal    { background: color-mix(in srgb, var(--teal)   14%, transparent); color: var(--teal); }


/* ══════════════════════════════════════════════════════════════════════════
   SETTINGS-HEADER-ICON — the 46px gradient icon square that heads each
   settings pane (Email / SMTP / Schedule / Telegram / OAuth). Gradients
   are brand-specific (e.g. Telegram uses Telegram-brand blue) so they stay
   as CSS-declared constants; keeping them here means HTML carries only a
   modifier class and dark-mode does not clobber intentional brand tones.
   ══════════════════════════════════════════════════════════════════════════ */

.settings-header-icon {
  width: 46px;
  height: 46px;
  border-radius: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: #fff;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--brand), var(--brand-hover));
  box-shadow: 0 3px 10px color-mix(in srgb, var(--brand) 30%, transparent);
}

.settings-header-icon-email {
  background: linear-gradient(135deg, #0EA5E9, #6366F1);
  box-shadow: 0 3px 10px rgba(14, 165, 233, 0.30);
}
.settings-header-icon-smtp {
  background: linear-gradient(135deg, #F59E0B, #EF4444);
  box-shadow: 0 3px 10px rgba(245, 158, 11, 0.30);
}
.settings-header-icon-schedule {
  background: linear-gradient(135deg, #8B5CF6, #6366F1);
  box-shadow: 0 3px 10px rgba(139, 92, 246, 0.30);
}
.settings-header-icon-telegram {
  background: linear-gradient(135deg, #0088CC, #229ED9);
  box-shadow: 0 3px 10px rgba(0, 136, 204, 0.30);
}

/* Row-wrapper for the "Enable X" toggle rows that sit inside a settings pane */
.settings-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}
.settings-toggle-row-title { font-size: 13px; font-weight: 700; }
.settings-toggle-row-sub   { font-size: 11.5px; color: var(--muted); margin-top: 2px; }


/* ══════════════════════════════════════════════════════════════════════════
   KB-GRAPH LEGEND tones — colored pills next to the knowledge-graph canvas.
   Palette is intentionally hardcoded because it MUST match the node/edge
   colors rendered by the canvas JS (kb-graph.js) — dark mode gracefully
   flattens these via the existing `[data-theme="dark"] .kb-graph-legend-chip`
   rule in app.css so the tones don't glare on dark canvas.
   ══════════════════════════════════════════════════════════════════════════ */

.kb-legend-meeting   { background: rgba(124, 58, 237, 0.10); color: #7C3AED; border-color: rgba(124, 58, 237, 0.20); }
.kb-legend-decision  { background: rgba(217, 119, 6,  0.10); color: #D97706; border-color: rgba(217, 119, 6,  0.20); }
.kb-legend-technical { background: rgba(2,  132, 199, 0.10); color: #0284C7; border-color: rgba(2,  132, 199, 0.20); }
.kb-legend-general   { background: rgba(16, 185, 129, 0.10); color: #10B981; border-color: rgba(16, 185, 129, 0.20); }
.kb-legend-wiki      { background: rgba(99, 102, 241, 0.08); color: #6366F1; border-color: rgba(99, 102, 241, 0.15); }
.kb-legend-tag       { background: rgba(16, 185, 129, 0.08); color: #10B981; border-color: rgba(16, 185, 129, 0.15); }
.kb-legend-ai        { background: rgba(245, 158, 11, 0.08); color: #F59E0B; border-color: rgba(245, 158, 11, 0.15); }
.kb-legend-manual    { background: rgba(139, 92,  246, 0.08); color: #8B5CF6; border-color: rgba(139, 92,  246, 0.15); }

.kb-legend-dot-meeting   { background: #7C3AED; }
.kb-legend-dot-decision  { background: #D97706; }
.kb-legend-dot-technical { background: #0284C7; }
.kb-legend-dot-general   { background: #10B981; }

.kb-legend-line { width: 10px; height: 2px; display: inline-block; vertical-align: middle; margin-right: 1px; }
.kb-legend-line-wiki   { background: #6366F1; }
.kb-legend-line-tag    { background: repeating-linear-gradient(90deg, #10B981 0 3px, transparent 3px 5px); height: 2px; }
.kb-legend-line-ai     { background: repeating-linear-gradient(90deg, #F59E0B 0 2px, transparent 2px 4px); height: 2px; }
.kb-legend-line-manual { background: #8B5CF6; }

.kb-legend-divider {
  width: 1px;
  height: 10px;
  background: var(--border);
  margin: 0 2px;
  align-self: center;
  opacity: .5;
}

.kb-legend-eyebrow {
  font-size: 8px;
  font-weight: 700;
  color: var(--muted);
  margin-right: 1px;
  letter-spacing: .05em;
  opacity: .7;
}

/* Force fixed dot size for kb-graph legend context (base .kb-graph-dot is 9px). */
.kb-graph-legend .kb-graph-dot { width: 6px; height: 6px; }


/* ══════════════════════════════════════════════════════════════════════════
   CHAT INPUT SURFACES — AI panel input bar + attached-file chip.
   Replaces inline `background:#fff` / `background:#f8fafc` / hex-tinted
   success-chip attachments in the chat input row.
   ══════════════════════════════════════════════════════════════════════════ */

.chat-input-row-stack {
  flex-direction: column;
  gap: 0;
  padding: 0;
}

.chat-attach-bar {
  padding: 6px 14px 0;
  background: var(--surface);
}
.chat-attach-bar[hidden] { display: none; }

.chat-attach-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--success-bg);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
  border-radius: 7px;
  padding: 4px 9px;
  font-size: 11px;
  color: var(--success);
  font-weight: 500;
}
.chat-attach-chip-size {
  color: color-mix(in srgb, var(--success) 70%, var(--muted));
  font-size: 10px;
}

.chat-input-bar {
  display: flex;
  gap: 9px;
  padding: 12px 16px;
  background: var(--surface);
  border-top: 1px solid var(--border);
}

.ai-prompt-form {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-soft);
  flex-shrink: 0;
}
.ai-prompt-form[hidden] { display: none; }


/* ══════════════════════════════════════════════════════════════════════════
   KR-CHECKIN SPARKLINE — inline bar visualization in the Key Result modal.
   ══════════════════════════════════════════════════════════════════════════ */

.kr-checkin-sparkline {
  margin: 8px 0 14px;
  height: 46px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 8px;
  display: flex;
  align-items: flex-end;
  gap: 3px;
}


/* ══════════════════════════════════════════════════════════════════════════
   MSG-AVATAR-BRAND — Nexora AI assistant avatar in the chat bubble. SVG mark
   embeds intentional brand indigo (#5046E5) so it stays recognizable across
   themes; wrapper background/border are tokenised so light/dark inherit.
   TODO(Day 2): replace inline SVG with <use href="/favicon.svg#logo-nexora">.
   ══════════════════════════════════════════════════════════════════════════ */

.msg-avatar-brand {
  background: var(--brand);
  border-color: var(--brand);
  padding: 0;
  overflow: hidden;
}
.msg-avatar-svg { width: 100%; height: 100%; display: block; }


/* ══════════════════════════════════════════════════════════════════════════
   LOGO-MARK — canonical Nexora mark rendered via <use href="#logo-nexora"/>.
   Base size 32px; -sm 30px, -lg naturally sized by parent (login logo).
   ══════════════════════════════════════════════════════════════════════════ */

.logo-mark {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
}
.logo-mark-sm { width: 30px; height: 30px; border-radius: 8px; }
.logo-mark-lg { width: 100%; height: 100%; border-radius: 16px; }


/* ══════════════════════════════════════════════════════════════════════════
   AI-PANEL header cluster — logo + title + model badge. Replaces the
   inline `style="display:flex;…"` group at the top of `.ai-panel > .ai-header`.
   ══════════════════════════════════════════════════════════════════════════ */

.ai-header-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
}

.ai-header-title-wrap {
  margin-left: 9px;
  min-width: 0;
}
.ai-header-title {
  font-size: 13px;
  font-weight: 600;
}

.ai-model-badge {
  font-size: 10px;
  color: var(--muted);
  background: var(--border);
  padding: 1px 7px;
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  flex-shrink: 0;
}


/* ══════════════════════════════════════════════════════════════════════════
   TODAY-HERO — editorial landing on the Today page.
   Fraunces display face, clamp() responsive size (40–64px), tight negative
   tracking. The greeter word ("Good morning,") uses coral for a warm accent
   against the mono-indigo brand. This is the one place in the app where the
   typography investment (Fraunces optical-size 9–144) actually sings.
   ══════════════════════════════════════════════════════════════════════════ */

.today-hero {
  padding: var(--space-7) 0 var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--border-soft);
}

.today-hero-eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 var(--space-2);
}

.today-hero-title {
  font-family: var(--font-display);
  font-feature-settings: 'ss01', 'ss02';
  font-size: clamp(40px, 6vw, 64px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.030em;
  color: var(--text);
  margin: 0 0 var(--space-3);
}

.today-hero-greeter {
  color: var(--accent-coral);
  font-style: italic;
}

.today-hero-summary {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-2);
  max-width: 62ch;
  margin: 0;
}

@media (max-width: 640px) {
  .today-hero { padding: var(--space-5) 0 var(--space-4); }
  .today-hero-title { font-size: clamp(32px, 8vw, 48px); }
}


/* ══════════════════════════════════════════════════════════════════════════
   NOTIF-BADGE — count pill on the notification bell in the topbar.
   Intentionally CORAL (not danger red): unread notifications are an
   "attention" signal, not an error. Red is reserved for actual errors
   (validation, failed API, overdue) so that when danger DOES appear,
   users register it as significant.
   ══════════════════════════════════════════════════════════════════════════ */

.notif-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  background: var(--accent-coral);
  color: #fff;
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  border-radius: 7px;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--accent-coral) 35%, transparent);
}
.notif-badge[hidden] { display: none; }


/* ══════════════════════════════════════════════════════════════════════════
   BTN-CORAL — secondary CTA that lives outside the mono-indigo brand ladder.
   Use for onboarding "Try this" cues, secondary upgrade prompts, and
   empty-state primary actions — places where "brand primary" would feel
   too heavy but a ghost button would feel invisible. Sparingly.
   ══════════════════════════════════════════════════════════════════════════ */

/* Specificity 0,2,0 chain is necessary — v2/legacy_buttons_forms.css defines
   a `button.btn` selector (0,1,1) that would otherwise reset `.btn-coral`
   (0,1,0) to `background: var(--surface)`. Using `.btn.btn-coral` bumps us
   above the legacy shim without needing `!important`. */
.btn.btn-coral {
  background: var(--accent-coral);
  color: #fff;
  border-color: var(--accent-coral);
  --ring-color: color-mix(in srgb, var(--accent-coral) 40%, transparent);
}
.btn.btn-coral:hover {
  background: color-mix(in srgb, var(--accent-coral) 88%, #000);
  border-color: color-mix(in srgb, var(--accent-coral) 88%, #000);
  color: #fff;
  filter: none;
}

.btn.btn-coral-soft {
  background: var(--accent-coral-fade);
  color: var(--accent-coral);
  border-color: transparent;
  box-shadow: none;
}
.btn.btn-coral-soft:hover {
  background: color-mix(in srgb, var(--accent-coral-fade) 60%, var(--accent-coral) 40%);
  filter: none;
}


/* ══════════════════════════════════════════════════════════════════════════
   EMPTY-STATE-CORAL — accent stroke/tint helper for empty-state illustrations.
   Apply to the outermost SVG or the highlight <path>/<line> to give the
   otherwise mono-indigo palette a warm hint. Optional, additive.
   ══════════════════════════════════════════════════════════════════════════ */

.empty-state-accent { color: var(--accent-coral); }
.empty-state-accent-soft { color: color-mix(in srgb, var(--accent-coral) 60%, var(--muted)); }


/* ══════════════════════════════════════════════════════════════════════════
   TAG-CHIP — tiny uppercase label chip used inline in form labels
   (EPIC / SPRINT / OKR markers). Replaces inline pill styles in
   partials/modals/task.html and similar.
   ══════════════════════════════════════════════════════════════════════════ */

.tag-chip {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.4;
  padding: 1px 7px;
  border-radius: var(--radius-full);
  border: 1px solid;
  text-transform: uppercase;
}
.tag-chip-info    { background: var(--info-bg);    color: var(--info);    border-color: color-mix(in srgb, var(--info)    30%, transparent); }
.tag-chip-success { background: var(--success-bg); color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.tag-chip-warning { background: var(--warning-bg); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.tag-chip-danger  { background: var(--danger-bg);  color: var(--danger);  border-color: color-mix(in srgb, var(--danger)  30%, transparent); }
.tag-chip-brand   { background: var(--brand-fade); color: var(--brand);   border-color: color-mix(in srgb, var(--brand)   30%, transparent); }
.tag-chip-purple  { background: color-mix(in srgb, var(--purple) 12%, transparent); color: var(--purple); border-color: color-mix(in srgb, var(--purple) 30%, transparent); }


/* ══════════════════════════════════════════════════════════════════════════
   DOT — inline colored dot used in type-tab labels (Task/Epic/Subtask ●).
   Replaces `<span style="color:#3b82f6;font-size:8px;line-height:1">●</span>`.
   ══════════════════════════════════════════════════════════════════════════ */

.dot {
  font-size: 8px;
  line-height: 1;
  display: inline-block;
}
.dot-info    { color: var(--info); }
.dot-success { color: var(--success); }
.dot-warning { color: var(--warning); }
.dot-danger  { color: var(--danger); }
.dot-brand   { color: var(--brand); }
.dot-purple  { color: var(--purple); }


/* ══════════════════════════════════════════════════════════════════════════
   WIRE-UP INSTRUCTIONS:
   Add to static/index.html inside <head>, AFTER legacy-shim.css so this
   file wins the cascade (override priority):

     <link rel="stylesheet" href="/css/v3/components.css?v=1">

   Recommended placement order (top -> bottom in <head>):
     1. tokens.css
     2. v2/system_tokens.css
     3. (all other v2/*.css and app.css)
     4. v2/legacy-shim.css
     5. v3/components.css         <-- here
     6. v3/modal.css
     7. v3/table.css
   ══════════════════════════════════════════════════════════════════════════ */

/* ===== /css/v2/contrast_fixes.css?v=1 ===== */
/* ══════════════════════════════════════════════════════════════════════════════
   contrast_fixes.css — WCAG 2.2 AA Color Contrast Remediation
   ──────────────────────────────────────────────────────────────────────────────
   Single-source override layer that fixes color contrast violations across the
   PM Dashboard UI. Loaded LAST in the cascade so it can override values defined
   in tokens.css, app.css, and any v2/* module CSS.

   ── WCAG references applied here ─────────────────────────────────────────────
   • WCAG 2.2 SC 1.4.3 Contrast (Minimum) Level AA
     Normal text (< 18pt regular / < 14pt bold)  ≥ 4.5:1
     Large  text (≥ 18pt regular / ≥ 14pt bold)  ≥ 3.0:1
   • WCAG 2.2 SC 1.4.11 Non-text Contrast
     UI components (borders, icons, focus rings) ≥ 3.0:1 against adjacent colors
   • WCAG 2.2 SC 2.4.7 Focus Visible
     Keyboard focus must produce a visible indicator distinguishable from the
     non-focused state (paired with SC 1.4.11 for the 3:1 ring contrast).

   ── Audit baseline (BEFORE) ──────────────────────────────────────────────────
   --muted        var(--text-muted) on var(--surface)  surface  → 4.59:1   (AA normal: marginal pass / small text FAIL)
   --muted-light  var(--text-muted) on var(--bg)  bg       → 2.60:1   (FAIL normal & small text)
   --muted        var(--text-muted) on #fafaf9  bg       → 4.50:1   (borderline; many 11–12 px usages → FAIL)
   .badge.badge-yellow  #d97706 on #fffbeb     → 3.95:1   (FAIL small text < 4.5:1)
   .badge.badge-red     var(--danger) on #fef2f2     → 4.36:1   (FAIL small text)
   .badge.badge-green   #059669 on #ecfdf5     → 3.80:1   (FAIL)
   a (default browser blue) on white            varies; many links lack underline
                                                          → FAIL SC 1.4.1 (not by color alone)
   :focus-visible (theme-dependent)             3px brand ring at 0.30 alpha
                                                          → ~2.2:1 against var(--surface) → FAIL SC 1.4.11

   ── Fix baseline (AFTER) ─────────────────────────────────────────────────────
   --muted        var(--text-2) on var(--surface)           → 7.23:1   PASS (AAA normal, AA small)
   --muted-light  #525B66 on var(--bg)           → 6.79:1   PASS (AAA normal, AA small)
   Dark theme --muted var(--text-muted) on var(--text)       → 7.39:1   PASS
   Dark theme --muted-light var(--muted-light) on var(--text) → 11.42:1  PASS
   badge-yellow #a16207 on #fef9c3             → 5.20:1   PASS
   badge-red    #991b1b on #fee2e2             → 7.10:1   PASS
   badge-green  #166534 on #dcfce7             → 6.36:1   PASS
   badge-blue   #1e40af on #dbeafe             → 7.32:1   PASS
   a:not(.btn) #1d4ed8 on var(--surface)               → 7.04:1   PASS (+ underline for SC 1.4.1)
   :focus-visible #1e40af 2px ring              → 7.32:1   PASS (SC 2.4.7 + 1.4.11)
   ══════════════════════════════════════════════════════════════════════════════ */


/* ── 1) Override muted text tokens (SC 1.4.3) ────────────────────────────────
   The previous `--muted` (var(--text-muted)) and `--muted-light` (var(--text-muted)) failed AA
   when used on small text (< 14 px / < 18.66 px regular). They are used in
   labels, meta rows, captions, tooltip body — all small-text contexts.
   We darken to the next zinc step that clears 7:1 (AAA) on the lightest
   surface used in the app, which gives headroom for nested translucent
   layers, hover surfaces, and dark-mode parity.                                */
:root {
  --muted:        #52525b;   /* was #71717a → 7.23:1 on #fff   */
  --muted-light:  #525B66;   /* was #a1a1aa → 6.79:1 on #FBFBFA */
  --text-muted:   #52525b;   /* alias for components that read --text-muted    */
  --text-muted-2: #71717a;   /* RESERVED: non-text decorative use only         */
}

/* Dark theme — invert the relationship, keep ≥ 7:1 on near-black surfaces.    */
[data-theme="dark"],
html.dark,
.dark-theme {
  --muted:        #a1a1aa;   /* was #71717a → 7.39:1 on #18181b */
  --muted-light:  #d4d4d8;   /* was #71717a → 11.42:1            */
  --text-muted:   #a1a1aa;
  --text-muted-2: #71717a;
}


/* ── 2) Badge variants — text on tinted background (SC 1.4.3) ────────────────
   Badges are typically rendered at 10.5–12 px — well under the 18 px large
   threshold — so they must clear 4.5:1, not 3:1. The "soft" variants in
   app.css pair a 600-weight saturated mid-tone foreground (#d97706, var(--danger),
   #059669) with an extremely pale tint (#fffbeb, #fef2f2, #ecfdf5) which
   sits at 3.8:1 – 4.4:1 → fail. We darken the text one Tailwind step and
   warm the background one step to comfortably clear 5:1.                     */
.badge.badge-yellow,
.badge.badge-warning,
.badge-warning {
  color: #a16207;            /* yellow-700 → 5.20:1 on #fef9c3 */
  background: #fef9c3;       /* yellow-100                     */
  border-color: #fde047;     /* yellow-300 → 3.05:1 non-text  */
}
.badge.badge-red,
.badge.badge-danger,
.badge-danger {
  color: #991b1b;            /* red-800 → 7.10:1 on #fee2e2 */
  background: #fee2e2;       /* red-100                      */
  border-color: #fecaca;     /* red-200                      */
}
.badge.badge-green,
.badge.badge-success,
.badge-success {
  color: #166534;            /* green-800 → 6.36:1 on #dcfce7 */
  background: #dcfce7;       /* green-100                      */
  border-color: #bbf7d0;     /* green-200                      */
}
.badge.badge-blue,
.badge.badge-info,
.badge-info {
  color: #1e40af;            /* blue-800 → 7.32:1 on #dbeafe */
  background: #dbeafe;       /* blue-100                      */
  border-color: #bfdbfe;     /* blue-200                      */
}

/* Dark-theme badge parity — flip to pale text on saturated dim background.    */
[data-theme="dark"] .badge.badge-yellow,
[data-theme="dark"] .badge.badge-warning,
[data-theme="dark"] .badge-warning {
  color: #fef9c3; background: rgba(161, 98, 7, 0.28); border-color: rgba(253, 224, 71, 0.40);
}
[data-theme="dark"] .badge.badge-red,
[data-theme="dark"] .badge.badge-danger,
[data-theme="dark"] .badge-danger {
  color: #fee2e2; background: rgba(153, 27, 27, 0.32); border-color: rgba(254, 202, 202, 0.40);
}
[data-theme="dark"] .badge.badge-green,
[data-theme="dark"] .badge.badge-success,
[data-theme="dark"] .badge-success {
  color: #dcfce7; background: rgba(22, 101, 52, 0.34); border-color: rgba(187, 247, 208, 0.40);
}
[data-theme="dark"] .badge.badge-blue,
[data-theme="dark"] .badge.badge-info,
[data-theme="dark"] .badge-info {
  color: #dbeafe; background: rgba(30, 64, 175, 0.34); border-color: rgba(191, 219, 254, 0.40);
}


/* ── 3) Small text needs the darker foreground (SC 1.4.3) ────────────────────
   Anything sized < 14 px must hit 4.5:1, not 3:1. App.css uses 10.5 – 12 px
   widely for meta rows, hints, and chips. Pull those to --text (var(--text))
   which is 16.94:1 on white — generous headroom for translucent surfaces.    */
.text-small,
.text-xs,
.text-11,
.text-12,
.form-hint,
.assignee-dropdown-empty,
.s-role,
.logo-sub,
.topbar-date {
  color: var(--text);
}

/* Meta rows / secondary captions — still secondary, but contrast-safe.       */
.text-meta,
.meta,
.page-sub,
.section-sub {
  color: var(--text-2);            /* zinc-600 → 7.23:1 on var(--surface) */
}
[data-theme="dark"] .text-meta,
[data-theme="dark"] .meta,
[data-theme="dark"] .page-sub,
[data-theme="dark"] .section-sub {
  color: var(--muted-light);            /* zinc-300 → 11.42:1 on var(--text) */
}


/* ── 4) Links — color + underline (SC 1.4.1 + 1.4.3) ─────────────────────────
   Color alone is not a sufficient differentiator (SC 1.4.1 Use of Color),
   so links also carry an underline. We exempt elements that already render
   a button/tab affordance.                                                    */
a:not(.btn):not(.nav-item):not(.tab):not(.sub-tab):not(.kanban-link) {
  color: #1d4ed8;            /* blue-700 → 7.04:1 on var(--surface) */
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
a:not(.btn):not(.nav-item):not(.tab):not(.sub-tab):not(.kanban-link):hover {
  color: #1e3a8a;            /* blue-900 → 11.13:1 on var(--surface) */
  text-decoration-thickness: 2px;
}
[data-theme="dark"] a:not(.btn):not(.nav-item):not(.tab):not(.sub-tab):not(.kanban-link) {
  color: #93c5fd;            /* blue-300 → 8.22:1 on var(--text) */
}
[data-theme="dark"] a:not(.btn):not(.nav-item):not(.tab):not(.sub-tab):not(.kanban-link):hover {
  color: #bfdbfe;            /* blue-200 → 11.43:1 on var(--text) */
}


/* ── 5) Focus visible — high-contrast ring (SC 2.4.7 + 1.4.11) ───────────────
   The original `--shadow-focus` is a 3 px brand ring at 0.30 alpha, which
   composites to ~2.2:1 against white — below the 3:1 non-text minimum.
   Use a solid blue-800 outline with offset so it is detectable on any
   surface, light or dark.                                                     */
*:focus-visible {
  outline: 2px solid #1e40af;     /* blue-800 → 7.32:1 on var(--surface) */
  outline-offset: 2px;
}
[data-theme="dark"] *:focus-visible {
  outline-color: #93c5fd;         /* blue-300 → 8.22:1 on var(--text) */
}

/* Buttons and primary brand surfaces — keep ring offset visible against
   non-white backgrounds by adding a thin contrasting halo via box-shadow.    */
.btn:focus-visible,
.btn-primary:focus-visible,
[role="button"]:focus-visible {
  outline: 2px solid #1e40af;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.85);
}
[data-theme="dark"] .btn:focus-visible,
[data-theme="dark"] .btn-primary:focus-visible,
[data-theme="dark"] [role="button"]:focus-visible {
  outline-color: #93c5fd;
  box-shadow: 0 0 0 4px rgba(9, 9, 11, 0.85);
}


/* ── 6) Placeholders — meet 4.5:1 (SC 1.4.3) ─────────────────────────────────
   `--muted-light` was the placeholder color → 2.6:1. Bump to zinc-600.       */
.form-input::placeholder,
.form-textarea::placeholder,
input::placeholder,
textarea::placeholder {
  color: var(--text-2);
  opacity: 1;                /* Firefox defaults placeholders to 0.54 alpha */
}
[data-theme="dark"] .form-input::placeholder,
[data-theme="dark"] .form-textarea::placeholder,
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
  color: var(--text-muted);
}


/* ── 7) Disabled state — clarify intent without dropping below 3:1 (SC 1.4.11)
   Disabled controls are exempt from 1.4.3 but still need a perceivable
   boundary. Use a deliberate desaturated tone, not the muted text token.    */
:disabled,
[aria-disabled="true"],
.is-disabled {
  color: #6b7280;            /* zinc-500 → 4.83:1 on var(--surface) (passes 4.5:1)   */
  cursor: not-allowed;
}


/* ══════════════════════════════════════════════════════════════════════════
   WIRE-UP INSTRUCTIONS
   ──────────────────────────────────────────────────────────────────────────
   1. Add the following <link> to /static/index.html INSIDE the <head>,
      as the LAST stylesheet (so it overrides app.css and every v2/* file):

         <link rel="stylesheet" href="css/v2/contrast_fixes.css?v=1">

      Place it directly AFTER the last v2 import (e.g. after icon-btn.css).
      Order matters: any sheet loaded after this one wins the cascade.

   2. Verify with automated tooling:
         • Open DevTools → Lighthouse → Accessibility audit.
         • Install axe DevTools extension → Run "Scan all of my page".
         • Confirm 0 contrast violations on /dashboard, /kanban, /availability.

   3. Spot-check the manual cases this file targets:
         • Sidebar nav meta labels (.s-role, .logo-sub)         → readable
         • Kanban card meta rows (.text-meta, .meta)            → readable
         • Status badges in tables (yellow / red / green / blue)→ readable
         • Form placeholders                                    → readable
         • Tab-key focus ring on buttons, inputs, nav items     → visible

   4. If a new component needs secondary text, prefer one of:
         color: var(--muted);          → AA-safe (7.2:1 on white)
         color: var(--text-muted-2);   → DECORATIVE ONLY (3:1, non-text use)
   ══════════════════════════════════════════════════════════════════════════ */

/* ===== /css/v3/a11y_fixes.css?v=1 ===== */
/* ══════════════════════════════════════════════════════════════════════════════
   a11y_fixes.css — Wave 4 additive accessibility fixes
   ──────────────────────────────────────────────────────────────────────────────
   This sheet is INTENTIONALLY additive and global. It does not touch any
   component's intrinsic look — it only adds focus, skip-link, hidden, touch-
   target, and reduced-motion safety nets that round-trip the issues called
   out in docs/A11Y_AUDIT_2026_06_07.md.

   Wire-up (Agent 19): add the following <link> to static/index.html INSIDE
   <head>, as the very last stylesheet so it wins the cascade over
   contrast_fixes.css and inline_migration.css:

       <link rel="stylesheet" href="css/v3/a11y_fixes.css?v=1">

   WCAG 2.2 SC referenced:
     • 1.3.1 Info and Relationships
     • 1.4.11 Non-text Contrast       (focus ring ≥ 3:1)
     • 1.4.13 Content on Hover/Focus  (dismissible/persistent)
     • 2.1.1 Keyboard                 (skip-link + focus visible)
     • 2.3.3 Animation from Interactions (reduced motion)
     • 2.4.1 Bypass Blocks            (skip-link)
     • 2.4.7 Focus Visible
     • 2.5.8 Target Size (Minimum)    (≥ 24 × 24 CSS px)
   ══════════════════════════════════════════════════════════════════════════════ */


/* ── 1) Skip-link (SC 2.4.1) ─────────────────────────────────────────────────
   Markup expected from Agent 9:
     <a class="a11y-skip-link" href="#mainContent">Skip to main content</a>
   The link is visually hidden until focused; on Tab it slides into view
   over the topbar. Uses a high-contrast brand background.                     */
.a11y-skip-link,
.skip-link {
  position: fixed;
  top: -64px;
  left: 12px;
  z-index: 99999;
  padding: 10px 16px;
  background: var(--brand-active, #1e40af);
  color: var(--surface);
  font: 600 14px/1.2 var(--font-body, system-ui, sans-serif);
  text-decoration: none;
  border-radius: 6px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.25);
  transition: top 120ms ease-out;
}
.a11y-skip-link:focus,
.a11y-skip-link:focus-visible,
.skip-link:focus,
.skip-link:focus-visible {
  top: 12px;
  outline: 3px solid var(--surface);
  outline-offset: 2px;
}


/* ── 2) Focus visible — brand-token aware (SC 2.4.7 + 1.4.11) ────────────────
   contrast_fixes.css already sets a 2 px blue-800 outline globally. We
   refine it here using the design-system brand token when available, and
   add a clearance halo so the ring is visible on busy backgrounds.            */
/* Unified halo focus ring — single source of truth. All interactive
   surfaces read from `--ring-*` tokens declared in tokens.css. The halo
   composition is:
     • inner surface-colored spacer (`--ring-offset` px) — carves a moat
       against the element's own background so the ring never touches
       the border directly.
     • outer brand-colored halo (`--ring-width` px) — the visible ring.
   Consumers only need a `:focus-visible` selector — everything else is
   token-driven. Per-component overrides simply redefine `--ring-color`
   on the element (e.g. danger buttons in v3/buttons.css). */
:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 var(--ring-offset) var(--surface),
    0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
  border-radius: inherit;
}
/* Suppress the surface-colored inner spacer on transparent-on-solid
   surfaces (sidebar/topbar) — the outer halo alone reads clearly there. */
.sidebar :focus-visible,
.topbar :focus-visible {
  box-shadow: 0 0 0 var(--ring-width) var(--ring-color);
}


/* ── 3) [aria-hidden="true"] hardening (SC 4.1.2) ────────────────────────────
   Visible-but-hidden elements confuse ATs. Force display:none whenever the
   ARIA-hidden attribute is set — EXCEPT for elements that are part of the
   loading/progress UI which intentionally render visually while hidden
   from ATs (those should use the .a11y-decor escape hatch).                   */
[aria-hidden="true"]:not(.a11y-decor):not(svg):not(path):not(circle):not(line):not(rect):not(polyline):not(polygon) {
  /* SVG children frequently carry aria-hidden purely as a hint and we
     do NOT want to nuke them. Same for the .a11y-decor escape hatch. */
  display: none;
}
/* .sr-only is defined once in a11y.css. `.a11y-visually-hidden` is an alias
   for callers that used the more explicit name; both share the same shape. */
.a11y-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* ── 4) Target size (SC 2.5.8) ───────────────────────────────────────────────
   Interactive controls must be at least 24 × 24 CSS px in their hit area.
   Many icon-only buttons render at 18 – 22 px today. Add a min-size that
   does not affect the visible glyph (the SVG inside keeps its size).         */
button,
[role="button"],
.icon-btn,
.btn-bare,
a.nav-item,
.profile-tab,
.kb-tab,
.ai-tab-btn {
  min-width: 24px;
  min-height: 24px;
}
/* Topbar and toolbar icon buttons are still visually tight; give them
   a transparent expanded hit-box via inline-block padding equalisation. */
.icon-btn:where(.icon-sm, .toolbar-icon) {
  min-width: 28px;
  min-height: 28px;
}


/* ── 5) Reduced motion enhancements (SC 2.3.3) ───────────────────────────────
   contrast_fixes.css already collapses durations. We additionally suppress
   parallax/scale loops, smooth-scroll, and CSS infinite animations.          */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms;
    animation-iteration-count: 1;
    transition-duration: 0.001ms;
    scroll-behavior: auto;
  }
  /* Hide the rotating spinner glyphs entirely; show a static label. */
  .spinner,
  .loading-spinner,
  .skeleton-pulse {
    animation: none;
  }
}


/* ── 6) Modal / dialog focus trap hint (SC 2.4.3) ────────────────────────────
   Until Agent 9 lands the JS focus-trap, mark any open modal so AT users
   at least get a visible focus ring on the dialog container itself.          */
.modal-overlay[style*="display:flex"]:focus-within,
.modal-overlay[style*="display: flex"]:focus-within,
.modal-overlay.is-open:focus-within {
  outline: 2px solid var(--brand-600, #1e40af);
  outline-offset: -2px;
}


/* ── 7) Keyboard-only affordances ────────────────────────────────────────────
   Restore the dotted focus outline on links that don't carry a button look
   so keyboard users can see selection while contrast_fixes.css's
   underline does the visual job for SC 1.4.1.                                 */
a:focus-visible {
  outline-offset: 4px;
}


/* ══════════════════════════════════════════════════════════════════════════
   END a11y_fixes.css
   ────────────────────────────────────────────────────────────────────────── */

/* ===== /css/v3/perf_hints.css?v=1 ===== */
/* ============================================================================
 * perf_hints.css  —  Non-blocking performance optimizations
 * Wave 4 / Agent 17  (2026-06-07)
 *
 * Goal: cheap, additive perf wins. No layout/visual side effects.
 * Loaded last (well, last for v3 perf layer). Pure CSS hints to the browser.
 * ========================================================================== */

/* --- 1. Font swap fallback for any locally-declared @font-face ------------ */
/* Index.html loads Google Fonts (already uses display=swap). This rule covers
 * any locally @font-face'd weights still using the default (block) behavior. */
@font-face {
  font-family: "InterFallback";
  src: local("Inter"), local("Arial"), local("Helvetica");
  font-display: swap;
}

/* If anyone declares @font-face without a display descriptor, the global
 * recommendation is `swap`. We can't retroactively edit other rules, but the
 * font-loading API + Inter/Fraunces requests in index.html already do this. */

/* --- 2. CSS containment on heavy, scroll-bound lists --------------------- */
/* `contain: layout paint` tells the engine these subtrees can be skipped for
 * layout/paint when offscreen and never affect the rest of the page.
 * Massive win on long Gantt rows, kanban boards, virtual tables. */
.kanban-cols,
.kanban-board,
.tree-gantt,
.tg-wrap,
.table-virtual,
.virtual-list,
.timeline-rows {
  contain: layout paint;
  /* Hint the browser to allocate a separate compositor layer when scrolling. */
  will-change: scroll-position;
}

/* Each kanban column / gantt row is also a containment boundary. */
.kanban-col,
.kanban-card,
.tg-row,
.gantt-row,
.tr-row {
  contain: layout style;
}

/* --- 3. content-visibility for offscreen blocks -------------------------- */
/* Modern browsers (Chrome 85+, Edge, Safari 18+) skip rendering work for
 * subtrees marked `content-visibility: auto` until they are near the viewport.
 * Safe on raster-heavy elements; `contain-intrinsic-size` reserves layout
 * space so scrollbar height doesn't jump.
 */
img,
video,
iframe {
  content-visibility: auto;
  contain-intrinsic-size: 1px 240px;
}

/* Apply to large card-shaped sections that often live below the fold. */
.chart-card,
.section-card,
.report-card,
.kpi-section,
.timeline-section {
  content-visibility: auto;
  contain-intrinsic-size: 1px 320px;
}

/* --- 4. Decode images async; reduce main-thread blocking ----------------- */
img {
  /* Modern attribute via CSS isn't possible; relies on HTML `decoding="async"
   * loading="lazy"`. We keep `image-rendering` safe defaults instead. */
  image-rendering: auto;
}

/* --- 5. Reduce paint work for motion-reduced users ---------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- 6. Hint compositor for sticky headers + sidebars ------------------- */
.sidebar,
.topbar,
.sub-tabs-bar {
  will-change: transform;
  transform: translateZ(0); /* promote to its own layer */
}

/* End perf_hints.css */

/* ===== /css/v3/integration_admin.css?v=1 ===== */
/* ============================================================================
   INTEGRATION ADMIN — shared styles for the six admin onboarding pages
   (Slack, Teams, Google, GitHub, Billing, PDP).
   ----------------------------------------------------------------------------
   OWNED BY: Wave 5 integration admin agents (7, 8, 9, 10, 11, 12).
   BE ADDITIVE ONLY. All rules MUST be scoped to the `.integration-admin-*`
   BEM namespace — never override common selectors (.btn, .card, .input, etc).
   Use only existing design tokens from tokens_unified.css.
   ============================================================================ */


/* ─── Page shell ─────────────────────────────────────────────────────────── */

.integration-admin {
  max-width: 880px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.integration-admin-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.integration-admin-title {
  font-family: var(--font-display, var(--font-body));
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-1);
  margin: 0;
}

.integration-admin-desc {
  font-size: var(--text-sm);
  color: var(--text-2);
  margin: 0;
  max-width: 60ch;
}


/* ─── Status card ────────────────────────────────────────────────────────── */

.integration-admin-status {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

.integration-admin-status__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--text-3, var(--text-2));
  flex: 0 0 auto;
}

.integration-admin-status__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.integration-admin-status__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-1);
}

.integration-admin-status__sub {
  font-size: var(--text-xs);
  color: var(--text-2);
}

.integration-admin-status.is-ok    { background: var(--success-bg); border-color: var(--success); }
.integration-admin-status.is-ok    .integration-admin-status__dot { background: var(--success); }
.integration-admin-status.is-mock  { background: var(--warning-bg); border-color: var(--warning); }
.integration-admin-status.is-mock  .integration-admin-status__dot { background: var(--warning); }
.integration-admin-status.is-down  { background: var(--danger-bg); border-color: var(--danger); }
.integration-admin-status.is-down  .integration-admin-status__dot { background: var(--danger); }


/* ─── Card container ─────────────────────────────────────────────────────── */

.integration-admin-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.integration-admin-card__title {
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-1);
  margin: 0 0 var(--space-2) 0;
}


/* ─── Setup wizard (ordered list of steps) ───────────────────────────────── */

.integration-admin-wizard {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.integration-admin-step {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-soft);
}

.integration-admin-step.is-done {
  opacity: 0.75;
}

.integration-admin-step__check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding-top: 2px;
}

.integration-admin-step__cb-label {
  font-size: var(--text-xs);
  color: var(--text-2);
  font-weight: 500;
  cursor: pointer;
}

.integration-admin-step__title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-1);
  margin: 0 0 4px 0;
}

.integration-admin-step__text {
  font-size: var(--text-sm);
  color: var(--text-2);
  margin: 0;
  line-height: 1.5;
}

@media (max-width: 640px) {
  .integration-admin-step {
    grid-template-columns: 1fr;
  }
}


/* ─── Form actions + hints + errors ──────────────────────────────────────── */

.integration-admin-form { display: contents; }

.integration-admin-hint {
  font-size: var(--text-xs);
  color: var(--text-2);
  margin: 4px 0 0 0;
}

.integration-admin-error {
  font-size: var(--text-sm);
  color: var(--danger);
  background: var(--danger-bg);
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
}

.integration-admin-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}


/* ─── Dispatch log table + status pills ──────────────────────────────────── */

.integration-admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.integration-admin-table th,
.integration-admin-table td {
  text-align: left;
  padding: 8px var(--space-2);
  border-bottom: 1px solid var(--border);
  color: var(--text-1);
  vertical-align: top;
}

.integration-admin-table th {
  font-weight: 600;
  color: var(--text-2);
  background: var(--surface-soft);
}

.integration-admin-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 600;
  background: var(--surface-soft);
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.integration-admin-pill--ok   { background: var(--success-bg); color: var(--success); }
.integration-admin-pill--mock { background: var(--warning-bg); color: var(--warning); }
.integration-admin-pill--fail { background: var(--danger-bg);  color: var(--danger);  }

.integration-admin-empty {
  font-size: var(--text-sm);
  color: var(--text-2);
  margin: 0;
}


/* ============================================================================
   Agent 8 — Google Workspace supplement
   ----------------------------------------------------------------------------
   Additive only. All rules live under the `.integration-admin-google-*`
   namespace so they cannot collide with Agent 7's shared base classes or
   sibling agents' integration namespaces.
   ============================================================================ */

/* Root wrapper (used by integration_google.js).  Stacks the header, status
   banners, admin checklist, user card, and per-service settings sections. */
.integration-admin-google-root {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 880px;
  margin: 0 auto;
  padding: var(--space-4);
}

.integration-admin-google-root h2 {
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--text-1);
}

.integration-admin-google-root h3 {
  font-size: var(--text-md, var(--text-sm));
  font-weight: 600;
  margin: 0;
  color: var(--text-1);
}

.integration-admin-google-root h4 {
  font-size: var(--text-sm);
  font-weight: 600;
  margin: 0 0 var(--space-2) 0;
  color: var(--text-1);
}

.integration-admin-google-root .integration-admin-lead {
  font-size: var(--text-sm);
  color: var(--text-2);
  margin: 4px 0 0 0;
}

/* Section wrapper used inside the google root for admin, user, calendar,
   drive blocks. */
.integration-admin-google-root .integration-admin-section {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.integration-admin-google-root .integration-admin-section-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.integration-admin-google-root .integration-admin-section-desc {
  font-size: var(--text-xs);
  color: var(--text-2);
  margin: 0;
  line-height: 1.5;
  max-width: 60ch;
}

/* Two-column admin grid (checklist | env-vars). */
.integration-admin-google-root .integration-admin-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (max-width: 720px) {
  .integration-admin-google-root .integration-admin-grid {
    grid-template-columns: 1fr;
  }
}

/* Google-specific accent for the connected state. */
.integration-admin-google-connected {
  border-left: 3px solid #4285f4; /* Google blue */
}

.integration-admin-google-disconnected {
  border-left: 3px dashed var(--border);
}

/* Stale-token warning banner — re-authorize soon. */
.integration-admin-google-stale {
  background: var(--warning-bg);
  color: var(--warning);
  border: 1px solid var(--warning);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-2);
  font-size: var(--text-sm);
  line-height: 1.45;
}

/* "Not configured on server" banner — same warn family. */
.integration-admin-google-not-configured {
  background: var(--warning-bg);
  color: var(--warning);
  border: 1px solid var(--warning);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

/* Setup checklist (admin tier). */
.integration-admin-google-checklist {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-2);
}

.integration-admin-google-checklist-item {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-soft);
}

.integration-admin-google-root .integration-admin-checklist-step {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-weight: 700;
  font-size: var(--text-xs);
  color: var(--text-1);
  display: flex;
  align-items: center;
  justify-content: center;
}

.integration-admin-google-root .integration-admin-checklist-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 4px;
}

.integration-admin-google-root .integration-admin-checklist-text {
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: 1.5;
}

.integration-admin-google-root .integration-admin-checklist-text code {
  font-size: 11px;
  background: var(--surface-soft);
  padding: 1px 4px;
  border-radius: 3px;
}

/* Env-var status list. */
.integration-admin-google-env-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-2);
}

.integration-admin-google-env-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  font-size: var(--text-sm);
}

.integration-admin-google-env-row code {
  font-size: var(--text-xs);
}

/* Generic Google badge sizing (used inside flex rows). */
.integration-admin-google-badge,
.integration-admin-google-root .integration-admin-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 600;
  background: var(--surface-soft);
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  flex: 0 0 auto;
}

.integration-admin-google-root .integration-admin-badge-ok {
  background: var(--success-bg);
  color: var(--success);
}
.integration-admin-google-root .integration-admin-badge-warn {
  background: var(--warning-bg);
  color: var(--warning);
}

/* Inline hints under each section. */
.integration-admin-google-hint {
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: 1.5;
  margin: 0;
}

.integration-admin-google-hint code {
  font-size: 11px;
  background: var(--surface-soft);
  padding: 1px 4px;
  border-radius: 3px;
}

/* Card rows inside the connected / disconnected user card. */
.integration-admin-google-root .integration-admin-card-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.integration-admin-google-root .integration-admin-card-row-block {
  flex-direction: column;
  align-items: flex-start;
}

.integration-admin-google-root .integration-admin-card-label {
  font-size: var(--text-xs);
  color: var(--text-2);
  min-width: 130px;
}

.integration-admin-google-root .integration-admin-card-value {
  font-size: var(--text-sm);
  color: var(--text-1);
  word-break: break-word;
}

.integration-admin-google-root .integration-admin-card-lead {
  font-size: var(--text-sm);
  color: var(--text-2);
  margin: 0;
  line-height: 1.5;
}

.integration-admin-google-root .integration-admin-bullet {
  font-size: var(--text-xs);
  color: var(--text-2);
  line-height: 1.6;
  margin: var(--space-2) 0;
  padding-left: var(--space-4);
}

.integration-admin-google-root .integration-admin-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* Scope chips inside connected card. */
.integration-admin-google-scope-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  padding: 0;
  margin: 6px 0 0 0;
}

.integration-admin-google-root .integration-admin-scope-chip {
  font-size: var(--text-xs);
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 8px;
  color: var(--text-1);
}

.integration-admin-google-root .integration-admin-scope-empty {
  color: var(--text-2);
  font-style: italic;
}

/* Button skin — reuses tokens, scoped to the google root so we don't clash. */
.integration-admin-google-root .integration-admin-btn {
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 6px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-1);
  cursor: pointer;
  line-height: 1.3;
}

.integration-admin-google-root .integration-admin-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.integration-admin-google-root .integration-admin-btn-primary {
  background: #1a73e8;
  border-color: #1a73e8;
  color: var(--surface);
}

.integration-admin-google-root .integration-admin-btn-secondary {
  background: var(--surface-soft);
}

.integration-admin-google-root .integration-admin-btn-danger {
  background: var(--danger-bg);
  border-color: var(--danger);
  color: var(--danger);
}

.integration-admin-google-root .integration-admin-btn-ghost {
  background: transparent;
}

/* Field rows for the calendar checkbox + drive folder picker. */
.integration-admin-google-root .integration-admin-field-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.integration-admin-google-root .integration-admin-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-1);
}

.integration-admin-google-root .integration-admin-checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-1);
  cursor: pointer;
}

.integration-admin-google-root .integration-admin-select {
  font: inherit;
  font-size: var(--text-sm);
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-1);
  min-width: 220px;
}

/* Warn block (re-used by stale + not-configured banners outside the
   specifically-styled cases). */
.integration-admin-google-root .integration-admin-warn {
  background: var(--warning-bg);
  color: var(--warning);
  border: 1px solid var(--warning);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

/* Loading skeleton (first-paint placeholder). */
.integration-admin-google-skeleton {
  margin-top: var(--space-3);
  height: 220px;
  border-radius: var(--radius-md);
  background: linear-gradient(
    90deg,
    var(--surface-soft) 0%,
    var(--surface-2) 50%,
    var(--surface-soft) 100%
  );
  background-size: 200% 100%;
  animation: integration-admin-google-skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes integration-admin-google-skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .integration-admin-google-skeleton { animation: none; }
}


/* ============================================================================
   Wave 6 / Agent B5 — Polish layer (additive only).
   Responsive stacking, dark-mode surface overrides, focus-visible outlines,
   shared loading skeleton, status badge variants.
   ============================================================================ */

/* ─── Responsive: stack form grids + tighten padding on phones ───────────── */
@media (max-width: 768px) {
  .integration-admin,
  .integration-admin-google-root {
    padding: var(--space-3) var(--space-3);
    gap: var(--space-3);
  }
  .integration-admin-card,
  .integration-admin-google-root .integration-admin-section {
    padding: var(--space-3);
  }
  .integration-admin-google-root .integration-admin-grid {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }
  .integration-admin-step,
  .integration-admin-google-checklist-item {
    grid-template-columns: 1fr;
  }
  .integration-admin-google-root .integration-admin-card-label {
    min-width: 0;
  }
  .integration-admin-google-root .integration-admin-select {
    min-width: 0;
    width: 100%;
  }
  .integration-admin-actions,
  .integration-admin-google-root .integration-admin-card-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .integration-admin-title { font-size: var(--text-xl); }
  .integration-admin-table { font-size: var(--text-xs); }
}

/* ─── Dark mode: surface tone refinement (tokens already swap, this just
       firms up contrast against neighbouring app chrome) ─────────────────── */
[data-theme="dark"] .integration-admin-card,
[data-theme="dark"] .integration-admin-status,
[data-theme="dark"] .integration-admin-google-root .integration-admin-section {
  background: var(--surface-2);
  border-color: var(--border);
}
[data-theme="dark"] .integration-admin-step,
[data-theme="dark"] .integration-admin-google-checklist-item,
[data-theme="dark"] .integration-admin-google-env-row {
  background: var(--surface-soft);
  border-color: var(--border);
}
[data-theme="dark"] .integration-admin-table th {
  background: var(--surface-soft);
  color: var(--text-2);
}
[data-theme="dark"] .integration-admin-google-root .integration-admin-btn {
  background: var(--surface-soft);
  border-color: var(--border);
  color: var(--text-1);
}
[data-theme="dark"] .integration-admin-google-root .integration-admin-scope-chip {
  background: var(--surface-2);
  border-color: var(--border);
}

/* ─── Focus-visible: 2px brand outline for every interactive element ────── */
.integration-admin a:focus-visible,
.integration-admin button:focus-visible,
.integration-admin input:focus-visible,
.integration-admin select:focus-visible,
.integration-admin textarea:focus-visible,
.integration-admin [role="button"]:focus-visible,
.integration-admin-google-root a:focus-visible,
.integration-admin-google-root button:focus-visible,
.integration-admin-google-root input:focus-visible,
.integration-admin-google-root select:focus-visible,
.integration-admin-google-root textarea:focus-visible,
.integration-admin-google-root [role="button"]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ─── Shared loading skeleton (page-level, matches google variant). ──────── */
.integration-admin-skeleton {
  display: block;
  width: 100%;
  min-height: 16px;
  border-radius: var(--radius-sm);
  background: linear-gradient(
    90deg,
    var(--surface-soft) 0%,
    var(--surface-2) 50%,
    var(--surface-soft) 100%
  );
  background-size: 200% 100%;
  animation: integration-admin-skeleton-shimmer 1.4s ease-in-out infinite;
}

.integration-admin-skeleton--block { height: 160px; }
.integration-admin-skeleton--line  { height: 12px; margin-block: 6px; }
.integration-admin-skeleton--title { height: 20px; width: 40%; }

@keyframes integration-admin-skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .integration-admin-skeleton { animation: none; }
}

/* ─── Status badge semantic variants ─────────────────────────────────────── */
.integration-admin-status--connected {
  background: var(--success-bg);
  border-color: var(--success);
  color: var(--success);
}
.integration-admin-status--connected .integration-admin-status__dot { background: var(--success); }

.integration-admin-status--mock {
  background: var(--warning-bg);
  border-color: var(--warning);
  color: var(--warning);
}
.integration-admin-status--mock .integration-admin-status__dot { background: var(--warning); }

.integration-admin-status--disconnected {
  background: var(--surface-soft);
  border-color: var(--border);
  color: var(--text-2);
}
.integration-admin-status--disconnected .integration-admin-status__dot { background: var(--text-3, var(--text-2)); }

.integration-admin-status--error {
  background: var(--danger-bg);
  border-color: var(--danger);
  color: var(--danger);
}
.integration-admin-status--error .integration-admin-status__dot { background: var(--danger); }

/* ===== /css/v3/inline_migration.css?v=21 ===== */
/* ============================================================
 * inline_migration.css — Wave 4 semantic HTML refactor (Agent 9)
 *
 * Purpose:
 *   1) `.btn-bare`  → strips browser button chrome so a <button> can
 *      visually replace <div onclick=…> / <span onclick=…> without
 *      regressing the look.
 *   2) `.u-*` utility classes → replacements for the most repeated
 *      inline `style="…"` attributes found in static/index.html.
 *
 *   Loaded LAST (after every other stylesheet) so utility classes win
 *   over legacy cascades. Keep selectors flat and specificity low so
 *   downstream files can still override when needed.
 * ============================================================ */

/* ---------- 1) Semantic button reset ----------
 * `.btn-bare` strips browser button chrome so a <button> can stand in for
 * the <div onclick=…>/<span onclick=…> it replaced WITHOUT regressing
 * visuals.
 *
 * IMPORTANT: this file is loaded LAST so it wins specificity ties. To
 * avoid clobbering the component class's own padding / font-size / color
 * etc., we use `:where(button.btn-bare)` for the reset rules. `:where()`
 * gives the rule zero specificity, so ANY component class on the same
 * element (`.slash-menu-item`, `.nav-item`, `.kb-filter`, etc.) will
 * still win for layout properties they set explicitly.
 *
 * The plain `.btn-bare` class (without :where) is used only for the
 * focus-visible outline and as a hook for `.btn-bare-block`.
 */
:where(button.btn-bare) {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: inherit;
  text-align: inherit;
}
.btn-bare:focus-visible {
  outline: 2px solid var(--accent, var(--brand));
  outline-offset: 2px;
  border-radius: 4px;
}

/* When the original was a block-level <div>, the button needs to fill its
 * row. We only widen — leave `display`/`gap`/`align-items` to the
 * component class so existing flex/grid layouts keep working. */
.btn-bare.btn-bare-block {
  width: 100%;
}

/* ---------- 2) Display utilities ---------- */
.u-hidden        { display: none !important; }
.u-flex          { display: flex; }
.u-flex-row      { display: flex; align-items: center; gap: 8px; }
.u-flex-row-12   { display: flex; align-items: center; gap: 12px; }
.u-flex-row-6    { display: flex; align-items: center; gap: 6px; }
.u-flex-between  { display: flex; align-items: center; justify-content: space-between; }
.u-flex-col      { display: flex; flex-direction: column; }
.u-flex-1        { flex: 1; }
.u-flex-1-mb0    { margin-bottom: 0; flex: 1; }
.u-mb-0          { margin-bottom: 0; }

/* ---------- 3) Spacing utilities ---------- */
.u-mt-2          { margin-top: 2px; }
.u-mt-4          { margin-top: 4px; }
.u-mt-6          { margin-top: 6px; }
.u-mt-8          { margin-top: 8px; }
.u-mt-10         { margin-top: 10px; }
.u-mt-12         { margin-top: 12px; }
.u-mb-10         { margin-bottom: 10px; }
.u-mb-12         { margin-bottom: 12px; }
.u-mb-14         { margin-bottom: 14px; }
.u-mb-16         { margin-bottom: 16px; }
.u-mb-18         { margin-bottom: 18px; }
.u-mb-20         { margin-bottom: 20px; }

/* ---------- 4) Grid helpers ---------- */
.u-grid-full     { grid-column: 1 / -1; }

/* ---------- 5) Width helpers ---------- */
.u-max-200       { max-width: 200px; }
.u-max-480       { max-width: 480px; }
.u-max-500       { max-width: 500px; }
.u-max-520       { max-width: 520px; }
.u-max-560       { max-width: 560px; }
.u-max-620       { max-width: 620px; }
.u-w-100         { width: 100px; }

/* ---------- 6) Typography helpers ---------- */
.u-text-muted        { color: var(--muted); }
.u-text-12-muted     { font-size: 12px; color: var(--muted); }
.u-text-11-muted     { font-size: 11px; color: var(--muted); }
.u-text-12           { font-size: 12px; }
.u-text-16-bold      { font-size: 16px; font-weight: 700; }
.u-text-17-bold      { font-size: 17px; font-weight: 700; }
.u-text-13-bold      { font-size: 13px; font-weight: 700; }
.u-label-tiny-cap    { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 600; margin-bottom: 6px; }
.u-label-mini-cap    { font-size: 10px; font-weight: 700; color: var(--text-2); text-transform: uppercase; letter-spacing: .5px; display: block; margin-bottom: 6px; }
.u-label-reset       { font-weight: 400; text-transform: none; letter-spacing: 0; }
.u-label-reset-muted { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); }

/* ---------- 7) SVG icon size helpers ---------- */
.u-svg-11          { width: 11px; height: 11px; flex-shrink: 0; }
.u-svg-12          { width: 12px; height: 12px; flex-shrink: 0; }
.u-svg-13          { width: 13px; height: 13px; flex-shrink: 0; }
.u-svg-14          { width: 14px; height: 14px; flex-shrink: 0; }
.u-svg-15          { width: 15px; height: 15px; flex-shrink: 0; }
.u-svg-16          { width: 16px; height: 16px; flex-shrink: 0; }
.u-svg-17          { width: 17px; height: 17px; flex-shrink: 0; }
.u-svg-18          { width: 18px; height: 18px; flex-shrink: 0; }
.u-svg-20          { width: 20px; height: 20px; flex-shrink: 0; }
.u-svg-22          { width: 22px; height: 22px; flex-shrink: 0; }

/* ---------- 7b) Flex row helpers (extend existing u-flex-row-12 further up) ---------- */
.u-flex-row-8      { display: flex; align-items: center; gap: 8px; }
.u-flex-row-10     { display: flex; align-items: center; gap: 10px; }
.u-flex-wrap       { flex-wrap: wrap; }

/* ---------- 7c) Semantic text tone overrides — for text nested inside a
   notice where the default color-2 read is too muted (e.g. "Chat ID: xxx"
   in the success-toned linked-state panel). Also carries tone into any SVG
   child that uses stroke="currentColor" or fill="currentColor" — enabling
   `class="u-tone-warning"` to replace inline `stroke="#ea580c"`. ---------- */
.u-tone-info,    .u-text-tone-info    { color: var(--info); }
.u-tone-success, .u-text-tone-success { color: var(--success); }
.u-tone-warning, .u-text-tone-warning { color: var(--warning); }
.u-tone-danger,  .u-text-tone-danger  { color: var(--danger); }
.u-tone-brand,   .u-text-tone-brand   { color: var(--brand); }
.u-tone-purple                        { color: var(--purple); }
.u-svg-mid-13      { width: 13px; height: 13px; vertical-align: middle; margin-right: 4px; }
.u-svg-mid-12      { width: 12px; height: 12px; vertical-align: middle; margin-right: 4px; }
.u-svg-mid-11      { width: 11px; height: 11px; vertical-align: middle; margin-right: 3px; }

/* ---------- 8) Section headers ---------- */
.u-section-header  { font-size: 13px; font-weight: 700; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.u-section-header-flush { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px; }

/* ---------- 9) Composite blocks ---------- */
.u-info-block {
  margin-bottom: 18px;
  padding: 16px;
  background: var(--bg);
  border-radius: 10px;
  border: 1px solid var(--border);
}

.u-flex-gap-12 { display: flex; gap: 12px; }
.u-flex-gap-8  { display: flex; gap: 8px; }
.u-flex-gap-6  { display: flex; gap: 6px; }

/* Empty state / muted placeholders */
.u-empty-center { color: var(--muted); font-size: 13px; text-align: center; padding: 32px; }

/* Inline SVG vertical-align helper (small leading icons in labels). */
.u-svg-inline-vmid { display: inline-block; vertical-align: middle; margin-right: 1px; }

/* Visually-hidden form control (used for custom switch / checkbox skins). */
.u-vh-input { opacity: 0; width: 0; height: 0; position: absolute; }

/* Audit-log filter sizing — auto width, smaller font. */
.u-w-auto-12 { width: auto; font-size: 12px; }

/* Custom switch primitives — used to replace three identical inline-style
 * patterns for accessible toggle switches in admin settings. */
.u-switch        { position: relative; display: inline-block; width: 44px; height: 24px; cursor: pointer; }
.u-switch-track  { position: absolute; inset: 0; background: var(--border-strong); border-radius: 12px; transition: background .25s ease, box-shadow .2s ease, outline-color .15s ease; }
.u-switch-thumb  { position: absolute; left: 2px; top: 2px; width: 20px; height: 20px; background: var(--surface); border-radius: 50%; transition: transform .25s ease, box-shadow .2s ease; box-shadow: 0 1px 4px rgba(0,0,0,.2); pointer-events: none; }

/* Checked state — track turns brand purple, thumb slides 20px right
 * (track 44px - 2px left inset - 2px right inset - 20px thumb = 20px travel). */
.u-switch input:checked ~ .u-switch-track { background: var(--brand, var(--brand)); }
.u-switch input:checked ~ .u-switch-thumb { transform: translateX(20px); }

/* Hover — subtle thumb lift for affordance. */
.u-switch:hover .u-switch-thumb { box-shadow: 0 2px 6px rgba(0,0,0,.25); }

/* Focus-visible — brand outline ring around the track when input is focused via keyboard. */
.u-switch input:focus-visible ~ .u-switch-track {
  box-shadow: 0 0 0 var(--ring-offset) var(--surface),
              0 0 0 calc(var(--ring-offset) + var(--ring-width)) var(--ring-color);
}

/* Disabled — dim the whole control and remove pointer affordance. */
.u-switch:has(input:disabled) { opacity: .5; cursor: not-allowed; }
.u-switch input:disabled ~ .u-switch-track,
.u-switch input:disabled ~ .u-switch-thumb { cursor: not-allowed; }

/* Reduced motion — honour user preference, snap rather than animate. */
@media (prefers-reduced-motion: reduce) {
  .u-switch-track, .u-switch-thumb { transition: none; }
}

/* ============================================================
 * Data-grid row-selection checkbox (injected by table_superpowers.js
 * as <input type="checkbox" aria-label="Select row|Select all"> inside
 * .tw-bulk-cell / .tw-bulk-head).
 *
 * Global "input, select, textarea { display:block; width:100%;
 * height:40px !important; }" earlier in the cascade was stretching
 * these into pill shapes (26x16 with border-radius 8px → oval). We
 * restore native rendering + brand accent so they read as proper
 * checkboxes in the project / task / risk / etc. data grids.
 * ============================================================ */
.tw-bulk-cell input[type="checkbox"],
.tw-bulk-head input[type="checkbox"],
.perm-cell,
.mod-toggle,
.nx-usage-cb,
input[type="checkbox"].perm-cell,
input[type="checkbox"].mod-toggle,
input[type="checkbox"].nx-usage-cb {
  appearance: auto !important;
  -webkit-appearance: auto !important;
  width: 16px !important;
  height: 16px !important;
  min-width: 16px;
  display: inline-block !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 3px !important;
  background: transparent !important;
  accent-color: var(--brand, var(--brand));
  vertical-align: middle;
  cursor: pointer;
}
.tw-bulk-cell input[type="checkbox"]:focus-visible,
.tw-bulk-head input[type="checkbox"]:focus-visible,
.perm-cell:focus-visible,
.mod-toggle:focus-visible,
.nx-usage-cb:focus-visible {
  outline: 2px solid var(--brand, var(--brand));
  outline-offset: 2px;
}

/* ============================================================
 * Data-grid action-cell buttons (Edit / Delete / Detail icons).
 *
 * Wave 7 Agent A1 deleted 215 legacy-shim Phase-2 selectors,
 * including the one that scoped .action-cell .btn-sm to 30x30
 * transparent. Without that, the universal legacy-shim rule
 * "button[class~='btn']:not(.btn-sm)..." paints them 40 px tall
 * with a 1 px border and white background. Restore the icon-only
 * convention with a global, scoped override that wins over the
 * legacy !important rules.
 *
 * Convention (matches projects-grid pre-Wave-7 baseline, .mtg-icon-btn,
 * .pd-hero-icon-btn): 30x30, transparent, muted zinc-600 icon at rest;
 * hover background bg-hover + semantic-tinted icon per variant.
 * ============================================================ */
.action-cell .btn,
.action-cell button.btn,
.action-cell .btn.btn-sm,
.action-cell button.btn.btn-sm {
  width: 30px !important;
  min-width: 30px !important;
  height: 30px !important;
  min-height: 30px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  color: var(--text-2, var(--text-2)) !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 8px !important;
  flex-shrink: 0;
  transition: background-color .12s ease, color .12s ease;
}
.action-cell .btn:hover {
  background: var(--bg-hover, var(--border-soft)) !important;
  color: var(--text, var(--text)) !important;
  filter: none !important;
}
.action-cell .btn.btn-warning:hover { color: rgb(234, 88, 12) !important; }
.action-cell .btn.btn-danger:hover  { color: rgb(220, 38, 38) !important; }
.action-cell .btn.btn-teal:hover    { color: var(--teal, var(--teal)) !important; }
.action-cell .btn.btn-accent:hover  { color: var(--brand, var(--brand)) !important; }
.action-cell .btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.action-cell .btn:focus-visible {
  outline: 2px solid var(--brand, var(--brand));
  outline-offset: 2px;
}

/* ============================================================
 * Icon-button overflow + stacking guarantee.
 *
 * v3 .btn base sets overflow:hidden, which clips the
 * data-tooltip ::after bubble on .nx-icon-btn. Restore visible.
 * Bump z-index on hover so tooltip wins over neighboring cards
 * that establish their own stacking context (e.g. .kpi-card with
 * :hover transform).
 * ============================================================ */
.action-cell .btn,
.nx-icon-btn,
.mtg-icon-btn,
.pd-hero-icon-btn,
.ai-prompt-edit,
.ai-prompt-del {
  overflow: visible !important;
}
.action-cell .btn:hover,
.action-cell .btn:focus-visible,
.nx-icon-btn:hover,
.nx-icon-btn:focus-visible,
.mtg-icon-btn:hover,
.mtg-icon-btn:focus-visible,
.pd-hero-icon-btn:hover,
.pd-hero-icon-btn:focus-visible,
.ai-prompt-edit:hover,
.ai-prompt-del:hover {
  z-index: 100 !important;
  position: relative;
}

/* Flip tooltip ABOVE the button — original CSS placed it BELOW which
 * overlaps cards/content following the button. ABOVE keeps it in the
 * empty toolbar/header area. Pseudo arrow flips too. */
.nx-icon-btn[data-tooltip]:not([data-tooltip-pos="bottom"])::after,
button[data-tooltip].nx-icon-btn:not([data-tooltip-pos="bottom"])::after {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
  transform: translateX(-50%) translateY(4px) !important;
}
.nx-icon-btn[data-tooltip]:hover:not([data-tooltip-pos="bottom"])::after,
.nx-icon-btn[data-tooltip]:focus-visible:not([data-tooltip-pos="bottom"])::after,
button[data-tooltip].nx-icon-btn:hover:not([data-tooltip-pos="bottom"])::after,
button[data-tooltip].nx-icon-btn:focus-visible:not([data-tooltip-pos="bottom"])::after {
  transform: translateX(-50%) translateY(0) !important;
}
/* Arrow points down when tooltip is above button. */
.nx-icon-btn[data-tooltip]:not([data-tooltip-pos="bottom"])::before,
button[data-tooltip].nx-icon-btn:not([data-tooltip-pos="bottom"])::before {
  top: auto !important;
  bottom: calc(100% + 2px) !important;
  border-top: 6px solid var(--text, #1A1A1F) !important;
  border-bottom: 0 !important;
  border-left: 6px solid transparent !important;
  border-right: 6px solid transparent !important;
}

/* Collapsed sidebar — hide every text label that the favorites module
 * (pin_favorites.js) renders. The base sidebar collapse rules only
 * target `.nav-label` and `.sb-section-label`, but favorites use a
 * different DOM:
 *   • .nav-favorites-head  → "★ Favorites" section header
 *   • .nx-fav-label        → per-item visible label text
 *   • .fav-star            → unpin button (only useful when expanded)
 *
 * Without these rules, the user sees truncated fragments like "FAVO"
 * (the header chopped) and "day☆" (a "Today" favorite leaking) inside
 * the 64px-wide collapsed rail. */
.sidebar.collapsed .nav-favorites-head,
[data-sidebar="collapsed"] .nav-favorites-head,
.sidebar.collapsed .nx-fav-label,
[data-sidebar="collapsed"] .nx-fav-label,
.sidebar.collapsed .fav-star,
[data-sidebar="collapsed"] .fav-star {
  display: none !important;
}
.sidebar.collapsed .nav-favorites .nav-item,
[data-sidebar="collapsed"] .nav-favorites .nav-item {
  justify-content: center !important;
  padding: 9px 0 !important;
  gap: 0 !important;
}
.sidebar.collapsed .nav-favorites,
[data-sidebar="collapsed"] .nav-favorites {
  padding: 6px 0 8px !important;
}

/* Toolbar / page tooltip clip fix.
 *
 * `.nx-icon-btn` tooltips are absolutely-positioned children of the
 * button (`::after` pseudo). When `data-tooltip-pos="bottom"` flips
 * the tooltip down INTO the page body, an ancestor with `overflow`
 * other than `visible` clips it. `.page` + `.toolbar` were defaulting
 * to the wrap/scroll behaviour and chopping tooltips on Portfolio,
 * Product, Feature Flags, Releases, Experiments and other tabbed
 * pages reported by the user.
 *
 * Reverting just the offending containers to `overflow: visible`
 * (without forcing them on the whole document) lets the tooltip
 * pseudo bleed past the toolbar / page boundary while still
 * respecting `.content { overflow-y:auto }` further up — which is
 * the layer that owns scroll. */
.page .toolbar,
.page > .toolbar {
  overflow: visible !important;
}
.page.active {
  overflow: visible !important;
}

/* ============================================================
 * Assistant AI → Prompts: .ai-prompt-edit + .ai-prompt-del icon
 * buttons. Match the borderless transparent convention used by
 * .action-cell .btn, .mtg-icon-btn, .pd-hero-icon-btn.
 * ============================================================ */
.ai-prompt-edit,
.ai-prompt-del {
  width: 30px !important;
  height: 30px !important;
  min-width: 30px !important;
  min-height: 30px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  color: var(--text-2, var(--text-2)) !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 8px !important;
  transition: background-color .12s ease, color .12s ease;
}
.ai-prompt-edit:hover {
  background: var(--bg-hover, var(--border-soft)) !important;
  color: var(--brand, var(--brand)) !important;
  border: 0 !important;
}
.ai-prompt-del:hover {
  background: var(--bg-hover, var(--border-soft)) !important;
  color: var(--red, var(--danger)) !important;
  border: 0 !important;
}
.ai-prompt-edit svg,
.ai-prompt-del svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.ai-prompt-edit:focus-visible,
.ai-prompt-del:focus-visible {
  outline: 2px solid var(--brand, var(--brand));
  outline-offset: 2px;
}

/* ============================================================
 * Wave 9 — Product menu cards: action buttons (Edit/Delete) inside
 * persona-card, metric-card, release-card, competitor-card,
 * hypothesis-card, okr-card, initiative-card, kr-item, research-card,
 * experiment-card, nps-card, feature-flag-card, product-doc-card,
 * feedback-card, customer-feedback-card should be icon-only
 * (transparent + muted at rest, semantic tint on hover) — matching
 * the .action-cell convention used elsewhere. Wave 7 Agent A1's
 * legacy-shim Phase-2 deletion removed the scoped rules that styled
 * these; reinstating here with a catch-all that targets any
 * .btn.btn-sm sitting inside a known product-entity card.
 * ============================================================ */
/* Use :has(>svg:only-child) so we only catch ICON-ONLY buttons,
 * leaving "+ Key Result", "+ Add Feature" etc. (which have text) alone. */
.okr-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.kr-item .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.initiative-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.persona-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.metric-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.release-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.competitor-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.hypothesis-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.experiment-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.nps-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.feature-flag-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.product-doc-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.research-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.feedback-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
.customer-feedback-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-okr .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-okr-tree .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-roadmap .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-personas .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-metrics .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-releases .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-competitors .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-hypotheses .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-experiments .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-nps .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-feature-flags .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-product-docs .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-research .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent),
#page-feedback .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent) {
  width: 30px !important;
  height: 30px !important;
  min-width: 30px !important;
  min-height: 30px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  color: var(--text-2, #52525B) !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 8px !important;
  flex-shrink: 0;
  overflow: visible !important;
  transition: background-color .12s ease, color .12s ease;
}
.okr-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.kr-item .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.initiative-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.persona-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.metric-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.release-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.competitor-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.hypothesis-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.experiment-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.nps-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.feature-flag-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.product-doc-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.research-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.feedback-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
.customer-feedback-card .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-okr .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-okr-tree .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-roadmap .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-personas .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-metrics .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-releases .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-competitors .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-hypotheses .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-experiments .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-nps .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-feature-flags .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-product-docs .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-research .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover,
#page-feedback .btn.btn-sm:where(.btn-warning,.btn-danger,.btn-teal,.btn-accent):hover {
  background: var(--bg-hover, #F4F4F5) !important;
  color: var(--text, #18181B) !important;
  filter: none !important;
}
/* Semantic hover tints — color the icon per variant. */
[id^="page-"] .btn.btn-sm.btn-warning:hover,
[class*="-card"] .btn.btn-sm.btn-warning:hover { color: rgb(234, 88, 12) !important; }
[id^="page-"] .btn.btn-sm.btn-danger:hover,
[class*="-card"] .btn.btn-sm.btn-danger:hover  { color: rgb(220, 38, 38) !important; }
[id^="page-"] .btn.btn-sm.btn-teal:hover,
[class*="-card"] .btn.btn-sm.btn-teal:hover    { color: var(--teal, #0D9488) !important; }
[id^="page-"] .btn.btn-sm.btn-accent:hover,
[class*="-card"] .btn.btn-sm.btn-accent:hover  { color: var(--brand, #5046E5) !important; }
[class*="-card"] .btn.btn-sm svg,
[id^="page-okr"] .btn.btn-sm svg,
[id^="page-roadmap"] .btn.btn-sm svg,
[id^="page-personas"] .btn.btn-sm svg,
[id^="page-metrics"] .btn.btn-sm svg,
[id^="page-releases"] .btn.btn-sm svg,
[id^="page-competitors"] .btn.btn-sm svg,
[id^="page-hypotheses"] .btn.btn-sm svg,
[id^="page-experiments"] .btn.btn-sm svg,
[id^="page-nps"] .btn.btn-sm svg,
[id^="page-feature-flags"] .btn.btn-sm svg,
[id^="page-product-docs"] .btn.btn-sm svg,
[id^="page-research"] .btn.btn-sm svg,
[id^="page-feedback"] .btn.btn-sm svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ============================================================
 * Wave 8 — Catch-all for new page modules (#page-integration-*).
 *
 * Every Wave 6-8 page module (comm_plans, quality_gates, approvals,
 * time_entries, weekly_report, escalation_rules,
 * notification_preferences, dispatch_log, baselines, resource_leveling,
 * procurement, activation_funnel, webhook_test, ai_usage, integration
 * admins) renders inside #page-integration-<slug>. Force 16x16 brand
 * checkbox + provide .nx-row-action icon-only convention used by
 * Wave 8 row-action conversions.
 * ============================================================ */
[id^="page-integration-"] input[type="checkbox"],
[id^="page-integration-"] input[type="radio"] {
  appearance: auto !important;
  -webkit-appearance: auto !important;
  width: 16px !important;
  height: 16px !important;
  min-width: 16px;
  min-height: 16px;
  display: inline-block !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 3px !important;
  background: transparent !important;
  accent-color: var(--brand, #5046E5);
  vertical-align: middle;
  cursor: pointer;
  flex: 0 0 auto;
}
[id^="page-integration-"] input[type="checkbox"]:focus-visible,
[id^="page-integration-"] input[type="radio"]:focus-visible {
  outline: 2px solid var(--brand, #5046E5);
  outline-offset: 2px;
}
/* Moved to v3/buttons.css — see .btn-icon-ghost */

/* Wave 10: .setup-group-* (in-page tab host) + .nav-integration-item +
 * the alias block for nx-np-btn / nx-pr-add / nx-*-close were removed
 * after the refactor that moved Integrations / Notifications / Planning /
 * Compliance to native MENU_GROUPS + .sub-tab. Modal close X styling is
 * now handled by each module's inline <style> block (was already the
 * case — the scoped aliases here were dead code). */

/* Wave 10 — bug fix: integration_slack / integration_google /
 * integration_teams add a .integration-admin class to their PAGE
 * container, and integration_admin.css sets `.integration-admin {
 * display: flex }`. Since both `.page` and `.integration-admin` have
 * the same specificity (one class), but `.integration-admin` happens
 * to load LATER in the cascade, it overrode `.page { display:none }`.
 * Result: navigating Slack → GitHub left BOTH pages visible —
 * stacked, with GitHub appearing below Slack on the same scroll.
 * Force non-active pages hidden with !important so any future module
 * that adds display:flex/grid to its container can't leak. */
.page:not(.active) {
  display: none !important;
}

/* Repeated card / section header with bottom border separator (4 copies in admin settings). */
.u-settings-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

/* ============================================================
 * NOTE: roles+keyboard activation
 * Elements that we COULD NOT convert from <div onclick> to <button>
 * (because they wrap other interactives) get `role="button"`,
 * `tabindex="0"` and `data-key-activate="true"`. The
 * keyboard_activate.js module routes Enter/Space presses into the
 * existing onclick handler for those elements.
 * ============================================================ */
[data-key-activate]:focus-visible {
  outline: 2px solid var(--accent, var(--brand));
  outline-offset: 2px;
  border-radius: 4px;
}

/* ============================================================
 * Project-Detail hero action buttons (Edit, Export PDF) — icon-only,
 * transparent + muted at rest, semantic tint on hover. Same
 * convention as meetings .mtg-icon-btn and the projects-grid action
 * cell: clean icon affordance with hover-revealed intent.
 *
 * Legacy-shim.css:123 forces .btn → 40px height + 0 padding + font-
 * weight:500 !important; this scoped override re-shapes only the
 * .pd-hero-icon-btn marker class without bleeding to other buttons.
 * ============================================================ */
.pd-hero-actions .pd-hero-icon-btn {
  width: 32px !important;
  height: 32px !important;
  min-height: 32px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  border-radius: 8px !important;
  background: transparent !important;
  color: var(--text-2, var(--text-2)) !important;
  border: 0 !important;
  box-shadow: none !important;
  flex-shrink: 0;
  transition: background-color .12s ease, color .12s ease;
}
/* Edit — brand purple on hover (primary action) */
.pd-hero-actions .pd-hero-icon-btn--edit:hover {
  background: rgba(80, 70, 229, .10) !important;
  color: var(--brand, var(--brand)) !important;
  filter: none !important;
}
/* Export PDF — neutral hover (utility action) */
.pd-hero-actions .pd-hero-icon-btn--pdf:hover {
  background: var(--bg-hover, var(--border-soft)) !important;
  color: var(--text, var(--text)) !important;
  filter: none !important;
}
.pd-hero-actions .pd-hero-icon-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* ============================================================
 * Meeting card icon buttons — transparent + muted at rest, semantic
 * color on hover. Matches projects-grid action-cell convention.
 * (Box-shadow killed to remove the "border-like" subtle outline that
 * v3 .btn base applied via var(--shadow-subtle).)
 * ============================================================ */
.mtg-icon-btn {
  width: 30px !important;
  height: 30px !important;
  min-height: 30px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  border-radius: 8px !important;
  background: transparent !important;
  color: var(--text-2, var(--text-2)) !important;
  border: 0 !important;
  box-shadow: none !important;
  flex-shrink: 0;
  transition: background-color .12s ease, color .12s ease;
}
.mtg-icon-btn:hover {
  background: var(--bg-hover, var(--border-soft)) !important;
  color: var(--text, var(--text)) !important;
  filter: none !important;
}
.mtg-icon-btn.btn-warning:hover {
  background: rgba(234, 88, 12, .10) !important;
  color: rgb(234, 88, 12) !important;
}
.mtg-icon-btn.btn-danger:hover {
  background: rgba(220, 38, 38, .10) !important;
  color: rgb(220, 38, 38) !important;
}
.mtg-icon-btn.mtg-detail-btn--lesson:hover {
  background: rgba(13, 148, 136, .10) !important;
  color: var(--teal, var(--teal)) !important;
}
.mtg-icon-btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ----------------------------------------------------------------------------
 * Sidebar section-header chevron — defensive size clamp
 * ----------------------------------------------------------------------------
 * sidebar_v2.css declares `.nav-v2 .nav-section-chevron { width: 12px; ... }`
 * but a stale browser/SW cache (the file ships at ?v=1 and has been pinned for
 * a long time) was serving an older copy without the rule on at least one
 * user's machine — every section header rendered with a viewBox-stretched
 * chevron the size of the whole button row.
 *
 * Belt-and-suspenders: pin the size unconditionally here. inline_migration.css
 * is the LAST stylesheet in the cascade, and `!important` only competes with
 * its own past self — no other rule in the codebase sets these properties.
 * Why: an oversized chevron is an obvious visual regression; we accept the
 * higher specificity cost to make sure it can never happen again regardless
 * of cache / load-order conditions.
 * How to apply: any future change to chevron sizing must update BOTH
 * sidebar_v2.css and this block (or remove this block once the cache risk
 * is gone).
 * ------------------------------------------------------------------------- */
.nav-section-chevron,
.nav-section-header svg.nav-section-chevron,
.nav-section-header > svg {
  width: 12px !important;
  height: 12px !important;
  flex-shrink: 0;
}

/* ===== /css/v3/sidebar_v2.css?v=2 ===== */
/* ─────────────────────────────────────────────────────────────────
 * sidebar_v2.css — Wave 7 / Agent A3
 *
 * Flattens the 12-item sidebar into 6 collapsible sections.
 * Loaded AFTER static/css/v2/sidebar.css so the new section styles
 * win where they overlap; the legacy .nav-item baseline (icons,
 * focus ring, hover lift, active brand-fade + left bar) is reused.
 *
 * DOM contract (rendered in static/index.html sidebar):
 *
 *   <nav class="nav nav-v2" role="navigation" aria-label="Primary">
 *     <section class="nav-section" data-section="plan" aria-expanded="true">
 *       <button class="nav-section-header" aria-expanded="true"
 *               aria-controls="nav-sec-plan">
 *         <svg class="nav-section-chevron">…</svg>
 *         <span class="nav-section-label">Plan</span>
 *       </button>
 *       <ul class="nav-section-list" id="nav-sec-plan" role="list">
 *         <li><button class="nav-item …" data-page|data-group="…">…</button></li>
 *         …
 *       </ul>
 *     </section>
 *     …
 *   </nav>
 * ───────────────────────────────────────────────────────────────── */

/* Only apply v2 sidebar layout when the new .nav-v2 marker is present.
 * Keeps coexistence safe if any embedded view falls back to old markup. */
.sidebar .nav.nav-v2 {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Allow the panel to scroll independently of the user card pinned at
   * the bottom of .sidebar (which uses margin-top:auto). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Tame the scrollbar in WebKit so it doesn't clash with the brand strip */
  scrollbar-width: thin;
  scrollbar-color: var(--border-light, var(--border)) transparent;
  padding-right: 2px;
}
.sidebar .nav.nav-v2::-webkit-scrollbar { width: 6px; }
.sidebar .nav.nav-v2::-webkit-scrollbar-thumb {
  background: var(--border-light, var(--border));
  border-radius: 3px;
}

/* ── Section container ───────────────────────────────────────────── */
.nav-v2 .nav-section {
  display: flex;
  flex-direction: column;
  margin-top: 2px;
}
.nav-v2 .nav-section + .nav-section { margin-top: 6px; }

/* ── Section header (the collapsible row) ────────────────────────── */
.nav-v2 .nav-section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px var(--space-3, 12px);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm, 8px);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted, #6b7280);
  cursor: pointer;
  user-select: none;
  text-align: left;
  transition: background var(--d-fast, 120ms) var(--ease, ease),
              color var(--d-fast, 120ms) var(--ease, ease);
}
.nav-v2 .nav-section-header:hover {
  background: var(--bg-hover, rgba(0,0,0,0.04));
  color: var(--text, #1f2937);
}
.nav-v2 .nav-section-header:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus, 0 0 0 2px var(--brand, var(--brand)));
}

/* Chevron rotates 0deg (collapsed) → 90deg (expanded) */
.nav-v2 .nav-section-chevron {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: currentColor;
  transition: transform var(--d-fast, 160ms) var(--ease, ease);
  transform: rotate(0deg);
}
.nav-v2 .nav-section[aria-expanded="true"] > .nav-section-header
  .nav-section-chevron {
  transform: rotate(90deg);
}

.nav-v2 .nav-section-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Propagate active state UP: section header turns brand-tinted when any
 * descendant nav-item carries .active. Set by the inline script on
 * showPage() (via the existing app.js call) — see index.html. */
.nav-v2 .nav-section.has-active > .nav-section-header {
  color: var(--brand, var(--brand));
}
.nav-v2 .nav-section.has-active > .nav-section-header
  .nav-section-chevron {
  color: var(--brand, var(--brand));
}

/* ── Child list (the collapsible body) ───────────────────────────── */
/* Smooth expand/collapse via the grid-template-rows trick:
 *   1fr → expanded, 0fr → collapsed, animatable.
 * The grid track height is driven by the single <li> inside; that <li>
 * must have min-height:0 so the 0fr row actually collapses to zero. */
.nav-v2 .nav-section-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--d-base, 220ms) var(--ease, ease);
}
.nav-v2 .nav-section[aria-expanded="false"] > .nav-section-list {
  grid-template-rows: 0fr;
}
.nav-v2 .nav-section-list > li {
  margin: 0;
  padding: 0;
  min-height: 0;     /* critical for 0fr collapse */
  overflow: hidden;
}
.nav-v2 .nav-section-list .nav-section-list-inner {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 2px 0 4px 0;
}

/* Items: the .nav-item button still inherits the legacy skin from
 * static/css/v2/sidebar.css. We only adjust indentation here so the
 * children visually sit under the section header. */
.nav-v2 .nav-section-list .nav-item {
  padding-left: 22px; /* aligns child labels with the section label text */
}

/* Respect reduced-motion: cut the height animation + chevron spin. */
@media (prefers-reduced-motion: reduce) {
  .nav-v2 .nav-section-list { transition: none; }
  .nav-v2 .nav-section-chevron { transition: none; }
  .nav-v2 .nav-section-header { transition: none; }
}

/* ── Collapsed sidebar (icon-only) compatibility ─────────────────── */
.sidebar.collapsed .nav-v2 .nav-section-header,
[data-sidebar="collapsed"] .sidebar .nav-v2 .nav-section-header {
  /* Hide section headers entirely in collapsed mode — the icon-only
   * children of each section remain visible (legacy behaviour). */
  display: none;
}
.sidebar.collapsed .nav-v2 .nav-section,
[data-sidebar="collapsed"] .sidebar .nav-v2 .nav-section {
  /* Force-expand children in collapsed mode so icons remain clickable. */
}
.sidebar.collapsed .nav-v2 .nav-section[aria-expanded="false"]
  > .nav-section-list,
[data-sidebar="collapsed"] .sidebar .nav-v2
  .nav-section[aria-expanded="false"] > .nav-section-list {
  grid-template-rows: 1fr;
}
.sidebar.collapsed .nav-v2 .nav-section-list .nav-item,
[data-sidebar="collapsed"] .sidebar .nav-v2 .nav-section-list .nav-item {
  padding-left: 9px; /* reset to legacy collapsed padding */
}

/* When app.js hides a child via _setVis or applyModuleGating
 * (display:none on .nav-item), if every child of a section is hidden,
 * collapse the section header too. JS toggles .nav-section-empty. */
.nav-v2 .nav-section.nav-section-empty { display: none; }


/* ══════════════════════════════════════════════════════════════════════════
   Left-bar active affordance — reinstated (Consolidation Sprint / Day 8).
   Historic v2/sidebar.css + v3/micro_interactions.css both set
   `.nav-item.active::before { content: none }` which killed the left bar.
   For the 244px sidebar a single background-tint affordance reads weakly;
   the 2px brand bar (Linear/Notion pattern) restores hierarchy without
   adding density. This file loads AFTER both suppressors, so equal
   specificity resolves in our favour by source order.
   ══════════════════════════════════════════════════════════════════════════ */

.nav-v2 .nav-item {
  position: relative;
}
.nav-v2 .nav-item.active::before,
.nav-v2 .nav-item[aria-current="page"]::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 2px;
  background: var(--brand);
  transition: transform var(--mi-dur-fast, 140ms) var(--mi-ease, ease);
}
/* When the sidebar is collapsed (icon-only), the -8px offset would clip; slide
   the bar back into the padding gutter (2px from the left edge). */
.sidebar.collapsed .nav-v2 .nav-item.active::before,
[data-sidebar="collapsed"] .sidebar .nav-v2 .nav-item.active::before {
  left: 2px;
}

/* ===== /css/v3/micro_interactions.css?v=2 ===== */
/* ─────────────────────────────────────────────────────────────────────────
 * Nexora v3 · Wave 7 · Agent A10
 * micro_interactions.css — additive delight layer.
 *
 * Loaded last in <head> so it can refine (never replace) existing motion.
 * All animations honor `prefers-reduced-motion: reduce` via the gate at the
 * bottom of the file. Keep this file < 8 KB; no images, no @imports.
 * ───────────────────────────────────────────────────────────────────────── */

/* ===== Tunable tokens ====================================================
 * Local-only — do NOT override the design-system tokens in tokens.css. */
:root {
  --mi-ease: cubic-bezier(.16, 1, .3, 1);          /* gentle decel */
  --mi-ease-bounce: cubic-bezier(.34, 1.56, .64, 1);
  --mi-dur-fast: 140ms;
  --mi-dur-base: 200ms;
  --mi-dur-slow: 320ms;
  --mi-elev-y: 2px;
  --mi-focus-ring: var(--brand-600, #5046e5);
}

/* ===== 1 · Page transition ================================================
 * app.css already declares `.page.active { animation: pageIn .2s ease both }`.
 * We don't re-declare the keyframes; we only refine the timing function
 * via a secondary animation that piggy-backs on the existing rule. */
.page.active {
  animation-timing-function: var(--mi-ease);
  will-change: opacity, transform;
}
.page.active > * {
  animation: mi-fade-in var(--mi-dur-base) var(--mi-ease) both;
}
@keyframes mi-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== 2 · Card hover · subtle elevation + 2px lift ======================
 * Scoped to cards that already opt-in to hover via existing rule families.
 * We do NOT add hover to .modal-overlay or sidebar items. */
.card:not(.no-hover):not([aria-disabled="true"]),
.kpi-card,
.dashboard-card,
.kanban-card,
.project-card {
  transition:
    transform var(--mi-dur-fast) var(--mi-ease),
    box-shadow var(--mi-dur-fast) var(--mi-ease),
    border-color var(--mi-dur-fast) var(--mi-ease);
}
.card:not(.no-hover):not([aria-disabled="true"]):hover,
.kpi-card:hover,
.dashboard-card:hover,
.kanban-card:hover,
.project-card:hover {
  transform: translateY(calc(var(--mi-elev-y) * -1));
  box-shadow: 0 6px 20px rgba(20, 24, 50, .08), 0 2px 6px rgba(20, 24, 50, .04);
}
[data-theme="dark"] .card:not(.no-hover):not([aria-disabled="true"]):hover,
[data-theme="dark"] .kpi-card:hover,
[data-theme="dark"] .dashboard-card:hover,
[data-theme="dark"] .kanban-card:hover,
[data-theme="dark"] .project-card:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35), 0 2px 6px rgba(0, 0, 0, .25);
}

/* ===== 3 · Button active · scale(.97) =====================================
 * Already declared in app.css ln 201 & v3/buttons.css ln 55 — we ONLY tune
 * the easing to match the rest of the language (no redeclare of transform). */
.btn { transition: transform var(--mi-dur-fast) var(--mi-ease),
                   background-color var(--mi-dur-fast) var(--mi-ease),
                   box-shadow var(--mi-dur-fast) var(--mi-ease); }

/* ===== 4 · Modal open · fade + scale-up 0.95 → 1 ==========================
 * Works alongside existing overlayIn animation; targets the inner .modal. */
.modal-overlay.open .modal,
.modal-overlay[style*="display: flex"] .modal,
.modal-overlay[style*="display:flex"] .modal,
.modal-overlay[style*="display: block"] .modal,
.modal-overlay[style*="display:block"] .modal {
  animation: mi-modal-in var(--mi-dur-base) var(--mi-ease) both;
}
.modal-overlay.mi-closing .modal {
  animation: mi-modal-out var(--mi-dur-fast) var(--mi-ease) both;
}
@keyframes mi-modal-in {
  from { opacity: 0; transform: scale(.95); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes mi-modal-out {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(.95); }
}

/* ===== 5 · Toast queue · slide-in from top-right w/ bounce ================
 * Production .toast is bottom-right (legacy). New queue uses a separate
 * container `#mi-toast-stack` so we don't touch existing behavior. */
#mi-toast-stack {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  max-width: min(380px, calc(100vw - 36px));
}
.mi-toast {
  pointer-events: auto;
  background: var(--surface, var(--surface));
  border: 1px solid var(--border, #e6e7eb);
  border-left: 3px solid var(--brand-600, var(--brand));
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(20, 24, 50, .14), 0 2px 6px rgba(20, 24, 50, .06);
  padding: 11px 14px 11px 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text, #111);
  display: flex;
  align-items: flex-start;
  gap: 9px;
  animation: mi-toast-in 360ms var(--mi-ease-bounce) both;
  will-change: transform, opacity;
}
.mi-toast.mi-toast--success { border-left-color: var(--success); }
.mi-toast.mi-toast--error   { border-left-color: var(--danger); }
.mi-toast.mi-toast--warn    { border-left-color: #d97706; }
.mi-toast.mi-toast--info    { border-left-color: var(--brand-600, var(--brand)); }
.mi-toast.mi-out { animation: mi-toast-out 220ms var(--mi-ease) both; }
.mi-toast-icon { flex: 0 0 16px; line-height: 1; margin-top: 1px; }
.mi-toast-body { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.mi-toast-close {
  background: transparent; border: 0; color: var(--muted, #6b7280);
  cursor: pointer; padding: 2px 4px; font-size: 14px; line-height: 1;
  border-radius: 4px;
}
.mi-toast-close:hover { color: var(--text, #111); background: rgba(0,0,0,.05); }
[data-theme="dark"] .mi-toast { background: var(--surface, #15181f); color: var(--text, #f3f4f6); }
[data-theme="dark"] .mi-toast-close:hover { background: rgba(255,255,255,.08); }
@keyframes mi-toast-in {
  from { opacity: 0; transform: translate3d(24px, -8px, 0) scale(.96); }
  60%  { opacity: 1; transform: translate3d(-2px, 0, 0) scale(1.01); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes mi-toast-out {
  from { opacity: 1; transform: translate3d(0, 0, 0); }
  to   { opacity: 0; transform: translate3d(24px, -4px, 0); }
}

/* ===== 6 · Skeleton shimmer · improve timing ==============================
 * The keyframes `nx-shimmer` already exist (motion.css). We only tune the
 * duration on existing skeleton selectors to feel less jittery (1.5s → 1.8s)
 * and add a tiny stagger so adjacent skeletons don't pulse in lockstep. */
[data-nx-skeleton]::after,
.nx-skeleton::after,
.skeleton::after {
  animation-duration: 1800ms !important;
  animation-timing-function: ease-in-out !important;
}
.skeleton:nth-child(odd)::after,
.nx-skeleton:nth-child(odd)::after { animation-delay: 120ms; }
.skeleton:nth-child(3n)::after,
.nx-skeleton:nth-child(3n)::after  { animation-delay: 240ms; }

/* ===== 7 · Focus ring · subtle 2px brand outline w/ offset ================
 * a11y_fixes.css already supplies a base 2px ring. We add an offset + smooth
 * appearance so it doesn't snap. Keyboard-only (`:focus-visible`). */
:focus-visible {
  outline-offset: 2px;
  transition: outline-color var(--mi-dur-fast) var(--mi-ease),
              box-shadow   var(--mi-dur-fast) var(--mi-ease);
}
.btn:focus-visible,
.form-input:focus-visible,
.nav-item:focus-visible,
.sub-tab:focus-visible {
  box-shadow: 0 0 0 4px rgba(80, 70, 229, .14);
}

/* ===== 8 · Status badge · pulse for "needs attention" ====================
 * Opt-in via `.badge.mi-attention` or `data-mi-attention="true"`. JS will
 * stamp this on badges whose numeric content > 0 (open risks, overdue, …). */
.badge.mi-attention,
[data-mi-attention="true"] {
  position: relative;
  animation: mi-badge-pulse 2.2s var(--mi-ease) infinite;
}
.badge.mi-attention::after,
[data-mi-attention="true"]::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  box-shadow: 0 0 0 0 currentColor;
  opacity: .55;
  pointer-events: none;
  animation: mi-badge-ring 2.2s var(--mi-ease) infinite;
}
@keyframes mi-badge-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}
@keyframes mi-badge-ring {
  0%   { box-shadow: 0 0 0 0   currentColor; opacity: .45; }
  70%  { box-shadow: 0 0 0 8px currentColor; opacity: 0; }
  100% { box-shadow: 0 0 0 0   currentColor; opacity: 0; }
}

/* ===== 9 · Tab switch · underline slides between active tabs =============
 * The .sub-tab active state already shows a bottom border. We add a single
 * sliding indicator that JS positions to the active tab. Container needs
 * the .mi-tabs hook (added by JS on first sight). */
.mi-tabs { position: relative; }
.mi-tabs-indicator {
  position: absolute;
  bottom: 0;
  height: 2px;
  background: var(--brand-600, var(--brand));
  border-radius: 2px 2px 0 0;
  transition: transform var(--mi-dur-base) var(--mi-ease),
              width     var(--mi-dur-base) var(--mi-ease),
              opacity   var(--mi-dur-fast) var(--mi-ease);
  pointer-events: none;
  opacity: 0;
  will-change: transform, width;
}
.mi-tabs.mi-tabs-ready .mi-tabs-indicator { opacity: 1; }

/* ===== 10 · Sidebar group expand · smooth height ==========================
 * Collapsible group wrappers use the data-mi-collapse attribute (set by JS).
 * Height transitions need a max-height fallback because `height: auto` can't
 * animate. JS sets --mi-collapse-h on open. */
[data-mi-collapse] {
  overflow: hidden;
  transition: max-height var(--mi-dur-slow) var(--mi-ease),
              opacity    var(--mi-dur-base) var(--mi-ease);
  max-height: var(--mi-collapse-h, 0);
}
[data-mi-collapse="open"] { opacity: 1; }
[data-mi-collapse="closed"] { max-height: 0 !important; opacity: 0; }

/* ===== 11 · Success ripple + checkmark on form save ======================
 * Drawn via JS on top of a host element. */
.mi-success-ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(22, 163, 74, .18);
  pointer-events: none;
  transform: scale(0);
  animation: mi-ripple 600ms var(--mi-ease) both;
}
@keyframes mi-ripple {
  0%   { transform: scale(0);   opacity: .9; }
  100% { transform: scale(2.4); opacity: 0; }
}
.mi-success-check {
  position: absolute;
  width: 22px; height: 22px;
  pointer-events: none;
  color: var(--success);
  opacity: 0;
  animation: mi-check-pop 700ms var(--mi-ease-bounce) both;
}
@keyframes mi-check-pop {
  0%   { opacity: 0; transform: scale(.4) rotate(-12deg); }
  60%  { opacity: 1; transform: scale(1.08) rotate(0); }
  100% { opacity: 0; transform: scale(1) rotate(0); }
}

/* ===== 12 · Confetti canvas host =========================================
 * Inserted by JS as a full-viewport overlay; transparent + non-interactive. */
.mi-confetti-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 99999;
  background: transparent;
}

/* ════════════════════════════════════════════════════════════════════════
 * A9 (Wave/Agent 4) — Consolidated from v2/motion-life.css.
 * The v2 file is now a deprecation stub. Rules below are the unique
 * subset that did NOT already exist in this v3 file. Keep this section
 * grouped together so future cleanup can spot it easily.
 * ════════════════════════════════════════════════════════════════════════ */

/* 13 · Interactive cards — opt-in gentle lift on hover ====================
 * v2 had explicit selectors for cards that are clickable. v3 §2 already
 * covers .card / .kpi-card / .dashboard-card / .kanban-card / .project-card,
 * but does NOT match anchors/buttons rendered as cards or the .interactive
 * opt-in marker. Add those here. */
.card.interactive:hover,
.card[role="button"]:hover,
a.card:hover,
button.card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-elevated);
  border-color: var(--brand-strong);
}

/* 14 · Primary button — focus halo + lift ================================= */
.btn-primary {
  position: relative;
  box-shadow: 0 1px 2px rgba(15,15,30,.08), inset 0 1px 0 rgba(255,255,255,0.10);
}
.btn-primary:hover {
  transform: translateY(-0.5px);
  box-shadow: var(--shadow-glow-soft);
}
.btn-primary:focus-visible {
  outline: none;
  box-shadow: var(--shadow-glow), var(--shadow-focus);
}

/* 15 · Sidebar nav-item — subtle pull on hover ============================
 * Uses transform on hover; v3 didn't have this. The ::before suppression
 * preserves an alternate active-indicator style. */
.nav-item {
  position: relative;
  transition: all var(--mi-dur-fast) var(--mi-ease);
}
.nav-item:hover {
  transform: translateX(1px);
}
.nav-item.active::before {
  content: none;
}

/* 16 · Sub-tab underline grow on hover ====================================
 * Distinct from the sliding indicator in §9 — this is the per-tab hover
 * affordance for tab containers that haven't been hooked by mi-tabs JS. */
.sub-tab {
  position: relative;
}
.sub-tab::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 50%;
  width: 0;
  height: 2px;
  background: var(--brand);
  transition: width var(--mi-dur-fast) var(--mi-ease), left var(--mi-dur-fast) var(--mi-ease);
}
.sub-tab:hover::after {
  width: 100%;
  left: 0;
}

/* 17 · Progress bar — brand gradient fill ================================= */
.progress,
.progress-bar {
  height: 6px;
  background: var(--surface-soft);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.progress .fill,
.progress-bar .fill,
.progress > div {
  height: 100%;
  background: var(--brand-gradient);
  border-radius: var(--radius-full);
  transition: width var(--d-slow) var(--ease-out);
  position: relative;
}

/* 18 · Loading dots — three-dot pulse ===================================== */
.nx-loading-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  margin: 0 2px;
  animation: nx-pulse-dot 1.4s var(--mi-ease) infinite;
}
.nx-loading-dot:nth-child(2) { animation-delay: 0.2s; }
.nx-loading-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes nx-pulse-dot {
  0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
  40%           { opacity: 1;   transform: scale(1); }
}

/* 19 · Notification badge — outward pulse =================================
 * Distinct from the §8 mi-badge-pulse (scale based). This uses an expanding
 * box-shadow ring keyed off the danger colour for unread counters. */
.notif-badge {
  animation: nx-badge-pulse 2s var(--mi-ease) infinite;
}
@keyframes nx-badge-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220,38,38,0.40); }
  50%      { box-shadow: 0 0 0 6px transparent; }
}

/* 20 · Save success — one-shot green halo ================================= */
.flash-success {
  animation: nx-flash-success 1.2s var(--mi-ease) both;
}
@keyframes nx-flash-success {
  0%   { box-shadow: 0 0 0 0 rgba(22,163,74,0); }
  40%  { box-shadow: 0 0 0 6px rgba(22,163,74,0.20); }
  100% { box-shadow: 0 0 0 0 rgba(22,163,74,0); }
}

/* Reduced-motion: extend the existing §gate above. The browser already
 * matches these selectors in the `prefers-reduced-motion` media query
 * via universal disabling at the bottom of the file? No — that gate is
 * scoped to specific selectors. Add the new ones here. */
@media (prefers-reduced-motion: reduce) {
  .card.interactive:hover,
  .card[role="button"]:hover,
  a.card:hover,
  button.card:hover,
  .btn-primary:hover,
  .nav-item,
  .nav-item:hover,
  .sub-tab::after,
  .nx-loading-dot,
  .notif-badge,
  .flash-success {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
}

/* ───────────────────────────────────────────────────────────────────────
 * Reduced-motion override — last in the file so it always wins.
 * Disables animations and removes transforms (keeps state changes but
 * makes them instant + non-vestibular). */
@media (prefers-reduced-motion: reduce) {
  .page.active,
  .page.active > *,
  .card:not(.no-hover):hover,
  .kpi-card:hover,
  .dashboard-card:hover,
  .kanban-card:hover,
  .project-card:hover,
  .modal-overlay.open .modal,
  .modal-overlay.mi-closing .modal,
  .mi-toast,
  .mi-toast.mi-out,
  .badge.mi-attention,
  [data-mi-attention="true"],
  .badge.mi-attention::after,
  [data-mi-attention="true"]::after,
  .mi-tabs-indicator,
  [data-mi-collapse],
  .mi-success-ripple,
  .mi-success-check {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
  .mi-confetti-canvas { display: none !important; }
  /* Skeletons keep a static low-contrast band rather than shimmering. */
  [data-nx-skeleton]::after,
  .nx-skeleton::after,
  .skeleton::after {
    animation: none !important;
  }
}

/* ===== /css/v3/dark_mode_polish.css?v=3 ===== */
/* ============================================================================
   DARK MODE POLISH v3 — Wave 6 / Agent B4 + Wave 7 / A9 + Wave 8 / A8
   ----------------------------------------------------------------------------
   REFACTORED Wave 17 / Agent 6: the original file was a flat list of 46+
   enumerated findings interleaving cards, charts, gantt, kanban, forms, etc.
   This pass GROUPS rules into 5 logical sections (no rules removed, no
   color values changed — only structure + section dividers added). Inline
   comments preserve original audit numbering for traceability.

   PURPOSE
     Additive-only overrides that fix dark-mode contrast + hardcoded colors
     introduced by Wave 4/5 v3 components. Load LAST among v3 stylesheets so
     [data-theme="dark"] selectors win without.

   TABLE OF CONTENTS
     § 1. CARDS / SURFACES / BORDERS
     § 2. CHARTS (chart_helpers, Chart.js, KPI palette, SVG/D3)
     § 3. GANTT + TIMELINE + CRITICAL PATH
     § 4. KANBAN + TASK CARDS + BADGES + HEATMAPS
     § 5. FORMS + MODALS + BUTTONS + MISC

   USAGE: <link rel="stylesheet" href="/css/v3/dark_mode_polish.css"> AFTER all
   other v3 CSS (components.css, typography.css, buttons.css, forms.css,
   badges.css, cards.css, modal.css, table.css, integration_admin.css).
   Recommended placement in static/index.html <head>:

       ... all v2 / legacy-shim / app.css ...
       <link rel="stylesheet" href="/css/v3/components.css">
       <link rel="stylesheet" href="/css/v3/typography.css">
       <link rel="stylesheet" href="/css/v3/buttons.css">
       <link rel="stylesheet" href="/css/v3/forms.css">
       <link rel="stylesheet" href="/css/v3/badges.css">
       <link rel="stylesheet" href="/css/v3/cards.css">
       <link rel="stylesheet" href="/css/v3/modal.css">
       <link rel="stylesheet" href="/css/v3/table.css">
       <link rel="stylesheet" href="/css/v3/integration_admin.css">
       <link rel="stylesheet" href="/css/v3/dark_mode_polish.css">  <-- here
   ============================================================================ */


/* ============================================================================
   § 1. CARDS / SURFACES / BORDERS
   ----------------------------------------------------------------------------
   Rule originals: B4 #9, #11, #12, "card-tinted bonus", "badge semantic
   borders bonus", "t-code/t-pre bonus", "table-striped bonus";
   A9 #21, #23, #25.
   ============================================================================ */

/* [B4 #9] v3/cards.css:178-179 (.card-footer-flush { background: var(--bg); })
   In dark, --bg is DARKER than --surface, so the flush footer appears as a
   black bar inside a grey card — inverted from light-mode intent. Override
   to var(--surface-soft) for the expected "slightly recessed" reading in
   dark. */
[data-theme="dark"] .card-footer-flush {
  background: var(--surface-soft);
}


/* [B4 #11] v3/badges.css:268 (.badge-count border: 1px solid var(--surface))
   The "ring" around count chips uses --surface — in dark this is the SAME
   color as most parent cards, so the visual "punched-out" effect
   disappears. Override to var(--bg) (the canvas) for separation. */
[data-theme="dark"] .badge-count {
  border-color: var(--bg);
}


/* [B4 #12] v3/typography.css:233 (.t-kbd border-bottom-width: 2px)
   Bottom border uses --border-strong in dark — fine, but the overall key
   looks flat because --surface (key bg) ≈ --surface-soft (key shadow). Add
   a tiny inset highlight for chiseled feel. */
[data-theme="dark"] .t-kbd {
  box-shadow:
    var(--shadow-subtle),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
}


/* [B4 bonus] card-tinted-* — tinted-bg cards re-tint for dark.
   Tinted backgrounds use --*-bg which already gets a 1.6x alpha bump in
   tokens_unified.css dark block (lines 325-328). But the matching borders
   in cards.css:65-81 are hardcoded rgba — bump them too for parity. */
[data-theme="dark"] .card-tinted-success { border-color: rgba(22,163,74,0.32); }
[data-theme="dark"] .card-tinted-warning { border-color: rgba(234,88,12,0.32); }
[data-theme="dark"] .card-tinted-danger  { border-color: rgba(220,38,38,0.32); }
[data-theme="dark"] .card-tinted-info    { border-color: rgba(37,99,235,0.32); }


/* [B4 bonus] t-code / t-pre — slightly lift bg from --surface-soft so inline
   code reads as distinct from a tinted card. In light --surface-soft is
   already a hair darker than card; in dark they're identical (--surface-soft
   vs parent --surface is fine, but nested inside a .card-soft they
   collide). */
[data-theme="dark"] .card-soft .t-code,
[data-theme="dark"] .card-soft .t-pre {
  background: var(--bg);
  border-color: var(--border-strong);
}


/* [B4 bonus] table-striped odd rows in dark — bump to slight tint.
   tokens_unified.css gives --surface-soft a faint elevation in dark; on a
   table-wrap with --surface this is fine, but contrast with hover bg-hover
   (--surface-soft — IDENTICAL) means the hover effect vanishes on striped
   odd rows. Override hover to a brighter row tint. */
[data-theme="dark"] .table-striped tbody tr:hover {
  background: #2F2F33;
}


/* [A9 #21] legacy app.css hardcoded --surface backgrounds on upload/tree
   zones (app.css:748, 790, 1111, 1113). These are used in modals and side
   panels; in dark they render as bright white panels. */

/* DARK FIX: app.css:748 .proj-file-zone background:var(--surface) */
[data-theme="dark"] .proj-file-zone,
[data-theme="dark"] .upload-zone {
  background: var(--surface);
  border-color: var(--border-strong);
}

/* DARK FIX: app.css:802 .upload-clear background:var(--surface) */
[data-theme="dark"] .upload-clear {
  background: var(--surface-soft);
  border-color: var(--border-strong);
  color: var(--text-muted);
}

/* DARK FIX: app.css:826 .dl-btn background:var(--surface) */
[data-theme="dark"] .dl-btn {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text-2);
}

/* DARK FIX: app.css:1111-1113 .tree-task / .tree-task-standalone background:var(--surface) */
[data-theme="dark"] .tree-task,
[data-theme="dark"] .tree-task-standalone {
  background: var(--surface);
  border-bottom-color: var(--border-soft);
}

/* DARK FIX: app.css:819 .dqp background:var(--surface) (quick-pick chip) */
[data-theme="dark"] .dqp {
  background: var(--surface);
  border-color: var(--border-strong);
}


/* [A9 #23] .loading splash screen uses background:var(--surface) — visible at
   startup if user has dark mode pref but page is still loading. */

/* DARK FIX: app.css:118 .loading background:var(--surface) visible at startup in dark */
[data-theme="dark"] .loading {
  background: var(--bg);
  color: var(--text);
}


/* [A9 #25] kd-clone drag preview app.css:1023 background:var(--surface) —
   the floating clone during keyboard-driven drag-drop becomes a bright tile
   on dark surface. */

/* DARK FIX: app.css:1023 .kd-clone background:var(--surface) drag preview */
[data-theme="dark"] .kd-clone {
  background: var(--surface);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  border: 1px solid var(--border-strong);
}


/* ============================================================================
   § 2. CHARTS (chart_helpers, Chart.js, KPI palette, SVG/D3)
   ----------------------------------------------------------------------------
   Rule originals: A9 #20; A8 #44, #45.
   ============================================================================ */

/* [A9 #20] Chart.js canvases — default chart palettes use saturated colors
   that work on light. In dark mode the grid lines/axes default to dark grey
   which becomes invisible. The actual fix lives in JS chart configs, but we
   can hint via CSS variables that downstream chart wrappers read. */

/* DARK FIX: chart.js wrappers — expose grid + tick colors via variables
   so chart_configs.js can read them when in dark mode. */
[data-theme="dark"] {
  --chart-grid: rgba(255, 255, 255, 0.06);
  --chart-tick: #A1A1AA;
  --chart-label: #D4D4D8;
}


/* [A8 #44] chart_helpers.js:40 `C.grid = 'rgba(231,229,228,.9)'` is a hard
   light-mode grey grid color used by any chart that reaches into legacy `C`
   directly instead of the theme-aware CHART_PALETTE. In dark this renders
   as bright off-white grid lines on a dark canvas. The C object is set at
   module init and DOES NOT re-resolve on theme change — so we can't fix the
   rgba string from CSS. BUT chart-card containers in dark have a subtle
   haze that helps; the more practical fix is to ensure any chart-card
   canvas in dark gets a slight backdrop tint so grid lines (when they DO
   leak through) blend in.
   Also re-expose --chart-grid / --chart-tick (set in [A9 #20] above) on the
   chart-card scope so authors can opt-in via `getComputedStyle(canvas)`. */

/* DARK FIX: chart_helpers.js:40 legacy C.grid rgba(231,229,228,.9) bright in dark
   — provide a CSS variable downstream charts can read instead. */
[data-theme="dark"] .chart-card,
[data-theme="dark"] .chart-wrap,
[data-theme="dark"] .chart-container {
  --chart-grid: rgba(255, 255, 255, 0.06);
  --chart-tick: #A1A1AA;
  --chart-label: #D4D4D8;
  --chart-tooltip-bg: var(--surface-soft);
  --chart-tooltip-fg: var(--text);
}


/* [A8 #45] chart_helpers.js:41 `C.text = '#71717a'` (zinc-500) is used for
   axis labels via legacy palette. zinc-500 on dark canvas reads ~3.9:1
   (fail AA for small text < 18pt). The CHART_PALETTE.muted() resolves from
   --muted CSS var so theme-aware charts are fine — but legacy call sites
   bypass this. Provide a CSS class hook that overrides any chart-rendered
   <text> SVG element to use --chart-tick.
   Chart.js renders to canvas (not SVG) so this only catches D3-based charts
   (priority matrix, dependency graph, etc.). */

/* DARK FIX: chart_helpers.js:41 C.text=#71717a fails AA on dark; catch D3 text nodes */
[data-theme="dark"] .chart-card svg text,
[data-theme="dark"] .chart-wrap svg text,
[data-theme="dark"] svg.d3-chart text {
  fill: var(--chart-tick, #A1A1AA);
}
[data-theme="dark"] .chart-card svg .axis line,
[data-theme="dark"] .chart-card svg .axis path,
[data-theme="dark"] .chart-wrap svg .axis line,
[data-theme="dark"] .chart-wrap svg .axis path {
  stroke: var(--chart-grid, rgba(255, 255, 255, 0.06));
}


/* ============================================================================
   § 3. GANTT + TIMELINE + CRITICAL PATH
   ----------------------------------------------------------------------------
   Rule originals: A9 #13; A8 #28, #29, #30, #31, #32, #33.
   ============================================================================ */

/* [A9 #13] Gantt project-level bar uses --text → flips to near-white in dark
   v2/tree-gantt.css:226 (.tg-bar[data-level="project"] { background: var(--text, #1A1A1F) })
   In light: --text is a near-black (dark bar reads as authoritative).
   In dark : --text is near-WHITE (bar on dark canvas — totally inverts the
              intent and visually dominates everything else on the row).
   Fix: anchor project-level bars to a stable dark slate that contrast-pops
   without nuking the rest of the row. Use --text-2 (zinc-600) — "PM
   authority neutral". */

/* DARK FIX: v2/tree-gantt.css:226 — project-level bar background flips to near-white in dark */
[data-theme="dark"] .tg-bar[data-level="project"] {
  background: var(--text-2);
  color: var(--text);
}


/* [A8 #28] v2/tree-gantt.css:43 .tg-header background:var(--bg,#FAFAF7)
   Inline fallback `#FAFAF7` (warm bone) only fires if --bg is unresolved,
   but in dark mode the tree-gantt is loaded WITHOUT a dark variant defined
   for tg-* tokens. The sticky header therefore renders --bg, which works
   but the bottom border uses --border creating a near-invisible 1px line.
   Re-anchor border to --border-strong and add a tiny inset highlight so the
   sticky header reads as "elevated". */

/* DARK FIX: v2/tree-gantt.css:43,153 — sticky headers blend into bars in dark */
[data-theme="dark"] .tg-header,
[data-theme="dark"] .tg-timeline-header {
  border-bottom-color: var(--border-strong);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.02);
}


/* [A8 #29] v2/tree-gantt.css:265-272 .tg-weekend-tint background uses a
   FIXED rgba(15,15,30,0.02) — a sliver of near-black at 2% alpha. On LIGHT
   bg this barely tints the weekend columns; on DARK bg (--bg is already
   near-black) it is COMPLETELY invisible. Need to invert to rgba(255,255,
   255,…) so the tint shows up at all. */

/* DARK FIX: v2/tree-gantt.css:270 .tg-weekend-tint rgba(15,15,30,.02) invisible on dark canvas */
[data-theme="dark"] .tg-weekend-tint {
  background: rgba(255, 255, 255, 0.025);
}


/* [A8 #30] v2/tree-gantt.css:181-187 .tg-bar-row repeating-linear-gradient
   uses --border-soft for weekly column dividers. In dark --border-soft is
   sufficiently visible BUT the background `var(--surface) 0 100%` is the
   row's solid base — fine. The issue is the GRADIENT MASK doesn't include a
   dark variant: when bar-row is empty of bars, it reads as a flat slab
   identical to .tg-right. Bump the gradient color to --border-strong so
   week-grid stays visible. */

/* DARK FIX: v2/tree-gantt.css:181-187 weekly grid lines too faint on dark */
[data-theme="dark"] .tg-bar-row {
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(var(--tg-day-width, 16px) * 7 - 1px),
    var(--border-strong) calc(var(--tg-day-width, 16px) * 7 - 1px),
    var(--border-strong) calc(var(--tg-day-width, 16px) * 7)
  );
}


/* [A8 #31] v2/tree-gantt.css:195-196 .tg-bar `color: var(--surface)` — bar
   labels are WHITE in light (good on brand bg). In dark --surface resolves
   to zinc-800 → labels render as DARK GREY on brand-light bg → ~1.9:1,
   totally fails AA. Force tg-bar label to remain near-white.
   Also covers status variants (Doing/Done/Review/Backlog) which all set
   only `background` and inherit color from the base rule. */

/* DARK FIX: v2/tree-gantt.css:196 .tg-bar color:var(--surface) flips to dark in dark mode */
[data-theme="dark"] .tg-bar,
[data-theme="dark"] .tg-bar[data-status="Done"],
[data-theme="dark"] .tg-bar[data-status="Doing"],
[data-theme="dark"] .tg-bar[data-status="In Progress"],
[data-theme="dark"] .tg-bar[data-status="Review"],
[data-theme="dark"] .tg-bar[data-status="Backlog"],
[data-theme="dark"] .tg-bar[data-status="To Do"],
[data-theme="dark"] .tg-bar.is-overdue {
  color: #F8FAFC;  /* near-white, ~7:1 on saturated bars */
}


/* [A8 #32] v2/tree-gantt.css:234-237 .tg-bar[data-level="epic"] keeps
   `color: var(--brand)`. In dark --brand is light indigo on a `--brand-fade`
   (rgba 0.18) bg — light text on light-tinted bg = ~3:1 fail. Replace text
   color with a brighter shade and slightly bump the tint background for
   contrast room. */

/* DARK FIX: v2/tree-gantt.css:234-237 epic bar light-on-light contrast fail in dark */
[data-theme="dark"] .tg-bar[data-level="epic"] {
  background: rgba(165, 180, 252, 0.18);
  color: #E0E7FF;  /* indigo-100 ~ 6.8:1 on tinted bg */
  border-color: var(--brand);
}


/* [A8 #33] v2/tree-gantt.css:250-263 .tg-today-line::before "TODAY" pill
   uses `color: var(--surface)` on `background: var(--danger)`. Same flip as
   [A8 #31] — pill becomes dark text on red in dark mode. Force white. */

/* DARK FIX: v2/tree-gantt.css:257 .tg-today-line label color:var(--surface) flips dark */
[data-theme="dark"] .tg-today-line::before {
  color: #F8FAFC;
}


/* ============================================================================
   § 4. KANBAN + TASK CARDS + BADGES + HEATMAPS
   ----------------------------------------------------------------------------
   Rule originals: B4 "badge semantic borders bonus";
   A9 #16, #17; A8 #34, #35, #36, #37, #38, #39, #40, #41, #42, #43, #46.
   ============================================================================ */

/* [B4 bonus] badge semantic borders — same alpha-bump principle as
   card-tinted-* in § 1. */
[data-theme="dark"] .badge-success { border-color: rgba(22,163,74,0.32); }
[data-theme="dark"] .badge-warning { border-color: rgba(234,88,12,0.32); }
[data-theme="dark"] .badge-danger  { border-color: rgba(220,38,38,0.32); }
[data-theme="dark"] .badge-info    { border-color: rgba(37,99,235,0.32); }


/* [A9 #16] deadline-days / overdue-badge — --danger on --bg gives only
   ~3.67:1 (fails AA 4.5:1 for normal text < 18pt). The chip IS small/
   secondary, so brightening to --danger-2 / lighter red lifts ratio above
   threshold without changing semantic. Captured on Dashboard "27 overdue"
   and "59d overdue". */

/* DARK FIX: app.css:465 .overdue-badge / div.deadline-days red on dark < 4.5:1 */
[data-theme="dark"] .deadline-days,
[data-theme="dark"] .overdue-badge,
[data-theme="dark"] .strip-val[style*="DC2626"],
[data-theme="dark"] [class*="overdue"]:not(.tg-bar) {
  color: #F87171;  /* red-400 — ~5.7:1 on var(--bg) */
}


/* [A9 #17] dashboard strip-val purple on --surface → 3.11:1 fail.
   Lift to violet-400 (#A78BFA) which reads ~6.1:1. */

/* DARK FIX: dashboard strip-val purple text fails AA on dark surface */
[data-theme="dark"] .strip-val {
  /* Inline styles often set color; bump nested elements too. */
  filter: none;
}
[data-theme="dark"] .strip-val[style*="7c3aed"],
[data-theme="dark"] .strip-val[style*="7C3AED"] {
  color: #A78BFA;
}


/* [A8 #34] app.css:455 .kanban-cols background:var(--card) is overridden by
   the v2/kanban.css :15 rule that sets `background: var(--surface-soft)
`. In dark --surface-soft is fine for columns BUT the WRAPPER
   .kanban-cols inherits app.css var(--card) — and at line 1442 there IS an
   override to var(--surface). However, the kanban-cols border (--border)
   reads as a hairline that visually MERGES with .kanban-project-card above
   it (also --border). Strengthen separation. */

/* DARK FIX: app.css:455 .kanban-cols / project-card seam invisible in dark */
[data-theme="dark"] .kanban-cols {
  border-color: var(--border-strong);
  border-top-color: transparent;
}
[data-theme="dark"] .kanban-project-card {
  border-color: var(--border-strong);
  border-bottom-color: var(--border-soft);
}


/* [A8 #35] app.css:454 .kanban-progress-fill uses
   `linear-gradient(90deg, var(--info), var(--teal))` — both vars resolve to
   their dark-mode brighter swatches BUT the underlying .kanban-progress-bar
   bg is `var(--border)`. The gradient endpoints (--info/--teal) visually
   merge with the brand-tinted .kanban-project-card. Bump bar bg. */

/* DARK FIX: app.css:453 .kanban-progress-bar bg blends with tinted card in dark */
[data-theme="dark"] .kanban-progress-bar {
  background: rgba(255, 255, 255, 0.08);
}


/* [A8 #36] v2/kanban.css:55 .kanban-col-header .count uses `background:
   var(--surface)` — at line 1444 in app.css this is dark-overridden to
   --bg-input for .kanban-count, but the v2 selector .kanban-col-header
   .count is DIFFERENT and not covered. In dark this chip becomes a bright
   square. Match the dark variant of kanban-count. */

/* DARK FIX: v2/kanban.css:55 .kanban-col-header .count background:var(--surface) bright in dark */
[data-theme="dark"] .kanban-col-header .count {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--border-strong);
  color: var(--text-muted);
}


/* [A8 #37] v2/kanban.css:146 .task-card .avatar-sm border uses `var(--surface)`
   which in dark is zinc-800. The avatar sits on .task-card (also zinc-800)
   so the border is INVISIBLE — ring effect lost. Override to --bg for
   "punched out of canvas" feel matching Wave 6 [B4 #11]. */

/* DARK FIX: v2/kanban.css:146 .task-card avatar border:var(--surface) blends in dark */
[data-theme="dark"] .task-card .avatar-sm,
[data-theme="dark"] .task-card .assignee-avatar {
  border-color: var(--bg);
}


/* [A8 #38] v2/kanban.css:130 .overdue-badge border rgba(180,62,62,0.18) is
   muddy red on dark canvas. Bump alpha + shift to red-500 hue for parity
   with [A9 #16] (badge color was raised but border stayed muddy). */

/* DARK FIX: v2/kanban.css:130 .overdue-badge border muddy in dark */
[data-theme="dark"] .overdue-badge {
  border-color: rgba(248, 113, 113, 0.32);
}


/* [A8 #39] app.css:463 .task-card.task-card-overdue background uses
   `linear-gradient(135deg, var(--red-light), var(--surface))`. In dark
   --red-light is alpha-bumped (Wave 6 tokens block) but --surface is
   zinc-800 while the dark override at app.css:471 changes the gradient to
   `rgba(239,68,68,.08), var(--card)`. That covers the bg — but the
   `border-color: #fca5a5` and `border-left: 3px solid var(--danger)` from
   line 463 are NOT overridden. The pink-200 right border reads garish on
   dark; drop the explicit hex to use --danger via inheritance. */

/* DARK FIX: app.css:463 .task-card-overdue hardcoded #fca5a5 border garish in dark */
[data-theme="dark"] .task-card.task-card-overdue {
  border-color: rgba(248, 113, 113, 0.42);
  border-left-color: #F87171;  /* matches [A9 #16] red-400 */
}


/* [A8 #40] features.js:2694 Risk Heatmap cells use HARDCODED inline pastels:
     sev>=15 → var(--red-light)   (alpha-bumped — ok)
     sev>=9  → #fef3c7  (amber-100, glaringly bright on dark)
     sev>=4  → #dbeafe  (blue-100, glaringly bright on dark)
     sev<4   → var(--green-light)  (alpha-bumped — ok)
   The text color uses #b45309 / #1d4ed8 (amber-700 / blue-700) which on
   those pastel BGs fails AA in dark (~2.1:1).
   The existing rule color_audit.css:80 applies `filter: brightness(0.85)
   saturate(0.9)` but that's a band-aid — at brightness 0.85 the 100-shade
   pastel is still ~#d8c69a, still wrong direction in dark.
   PROPER fix: target #heatmapGrid cells by inline-style attribute selectors
   and replace bg+color outright. */

/* DARK FIX: features.js:2694 risk-heatmap inline pastels unreadable in dark */
[data-theme="dark"] #heatmapGrid > div[style*="#fef3c7"] {
  background: rgba(234, 179, 8, 0.18);
  color: #FBBF24;  /* amber-400 ~ 6.4:1 */
}
[data-theme="dark"] #heatmapGrid > div[style*="#dbeafe"] {
  background: rgba(59, 130, 246, 0.18);
  color: #60A5FA;  /* blue-400 ~ 5.6:1 */
}
/* sev>=15 uses var(--red-light) — already alpha-bumped, but ensure text reads */
[data-theme="dark"] #heatmapGrid > div[style*="var(--red-light)"],
[data-theme="dark"] #heatmapGrid > div[style*="--red-light"] {
  color: #F87171;
}
/* sev<4 uses var(--green-light) — same logic */
[data-theme="dark"] #heatmapGrid > div[style*="var(--green-light)"],
[data-theme="dark"] #heatmapGrid > div[style*="--green-light"] {
  color: #4ADE80;  /* green-400 ~ 7:1 */
}
/* Axis labels (Impact 1-5 / Prob 1-5) use color:var(--muted) which is already
   readable in dark, so no override needed for those. */


/* [A8 #41] stakeholder_matrix.js:217-224 .stk-heat injects its own <style>
   with HARDCODED light colors:
     th: background:#f8fafc, color:#475569
     td borders: var(--border, #eef0f3) — fallback only
     .arrow.flat color:#94a3b8
   None of this respects [data-theme="dark"]. Override the table. */

/* DARK FIX: stakeholder_matrix.js:220-224 .stk-heat hardcoded slate colors in dark */
[data-theme="dark"] .stk-heat th {
  background: var(--surface-soft);
  color: var(--text-2);
}
[data-theme="dark"] .stk-heat th,
[data-theme="dark"] .stk-heat td {
  border-bottom-color: var(--border-soft);
}
[data-theme="dark"] .stk-heat .arrow.flat {
  color: var(--text-muted);
}
[data-theme="dark"] .stk-heat .arrow.up {
  color: #4ADE80;
}
[data-theme="dark"] .stk-heat .arrow.down {
  color: #F87171;
}


/* [A8 #42] activity_insights.js:303-308 .nx-ai-heatmap cells use hardcoded
   blue ramp (#bfdbfe / #60a5fa / #2563eb / #1e3a8a). In dark the L1 and L4
   endpoints are catastrophic:
     L1 (#bfdbfe blue-200): super bright on dark → eye-stabby
     L4 (#1e3a8a blue-900): MERGES with dark canvas → invisible
   Re-ramp around alpha rgba so the LOW end is barely visible and the HIGH
   end is brand-saturated — preserves the "more activity = warmer" intent. */

/* DARK FIX: activity_insights.js:303-308 .nx-ai-heat-cell light blue ramp in dark */
[data-theme="dark"] .nx-ai-heat-cell {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.03);
}
[data-theme="dark"] .nx-ai-heat-cell[data-l="1"] { background: rgba(99, 102, 241, 0.20); }
[data-theme="dark"] .nx-ai-heat-cell[data-l="2"] { background: rgba(99, 102, 241, 0.40); }
[data-theme="dark"] .nx-ai-heat-cell[data-l="3"] { background: rgba(129, 140, 248, 0.65); }
[data-theme="dark"] .nx-ai-heat-cell[data-l="4"] { background: rgba(165, 180, 252, 0.95); }


/* [A8 #43] activity_insights.js:310 .nx-ai-badge uses
   `background: linear-gradient(135deg,#fef3c7,#fde68a)` + `color:#92400e` —
   pastel cream gradient with amber-800 text. In dark this is a bright
   yellow shock on a dark page. Match the alpha-bump pattern from [A8 #40]. */

/* DARK FIX: activity_insights.js:310 .nx-ai-badge pastel cream gradient in dark */
[data-theme="dark"] .nx-ai-badge {
  background: linear-gradient(135deg, rgba(234, 179, 8, 0.18), rgba(234, 179, 8, 0.10));
  border-color: rgba(234, 179, 8, 0.32);
  color: #FBBF24;
}


/* [A8 #46] features.js:2697 heatmap cells set `border-radius: var(--r-sm)`
   inline but no border. On dark the cells with alpha-bumped backgrounds
   look "floaty" without a hairline. Add a subtle 1px ring so each cell
   reads as a discrete tile rather than a translucent splotch. */

/* DARK FIX: features.js:2697 heatmap cells need separation ring in dark */
[data-theme="dark"] #heatmapGrid > div[style*="padding:14px"] {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}


/* ============================================================================
   § 5. FORMS + MODALS + BUTTONS + MISC
   ----------------------------------------------------------------------------
   Rule originals: B4 #1, #2, #3, #4, #5, #6, #7, #8, #10, "modal overlay
   bonus"; A9 #14, #15, #18, #19, #22, #24, #26, #27.
   ============================================================================ */

/* [B4 #1-3] solid colored button hovers — lift saturation in dark.
     #1: v3/components.css:115-116  (.btn-danger:hover, also buttons.css:148)
         Hardcoded #B91C1C hover (red-700) loses contrast on dark canvas —
         text-on-bg drops to ~3.4:1. Fix: hover to #EF4444 (red-500).
     #2: v3/components.css:130, buttons.css:174 (.btn-success:hover #15803D)
         green-700 hover too dark on dark canvas. Lighten to #22C55E.
     #3: v3/components.css:146, buttons.css:189 (.btn-warning:hover #C2410C)
         Orange-700 is muddy on dark; lift to var(--accent-coral). */

[data-theme="dark"] .btn-danger:hover {
  background: #EF4444;
  border-color: #EF4444;
}

[data-theme="dark"] .btn-success:hover {
  background: #22C55E;
  border-color: #22C55E;
}

[data-theme="dark"] .btn-warning:hover {
  background: var(--accent-coral);
  border-color: var(--accent-coral);
}


/* [B4 #4] primary text-on-brand contrast (white-on-indigo-400 fails AA).
   v3/components.css:71,79,111,126,140 — .btn-primary/danger/success/warning
   hardcode `color: var(--surface)`. In dark, --brand resolves to light
   indigo — white text on light-indigo only hits 2.6:1. Override
   .btn-primary text to #0B0B14 (near-black) for AA contrast on indigo-400.
   Solid danger/success/warning remain white-on-saturated and read fine. */

[data-theme="dark"] .btn-primary {
  color: #0B0B14;
}
[data-theme="dark"] .btn-primary:hover {
  color: #0B0B14;
}


/* [B4 #5] spinner color follows overridden primary text.
   v3/buttons.css:304 (.btn-loading::before { color: var(--text); })
   For .btn-primary in dark the spinner should match #0B0B14 to align with
   overridden label color. */

[data-theme="dark"] .btn-primary.btn-loading::before {
  color: #0B0B14;
}


/* [B4 #6] form-select caret — boost stroke for dark surfaces.
   v3/forms.css:222, components.css:410 (.form-select / .select caret)
   Inline SVG embeds stroke='%23A1A1AA' (zinc-400). In dark, --muted renders
   caret too light vs dark surface (~2.1:1). Replace via data-uri override
   using zinc-300 for proper visibility. */

[data-theme="dark"] .form-select,
[data-theme="dark"] .select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23D4D4D8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}


/* [B4 #7-8] integration_admin hardcoded Google blue — soften in dark.
     #7: v3/integration_admin.css:334 (.integration-admin-google-connected)
         Hardcoded #4285f4 (Google Blue) accent border feels disconnected
         in dark. Soften to #5B9BFF in dark for better blend.
     #8: v3/integration_admin.css:570-573 (.integration-admin-btn-primary)
         Hardcoded #1a73e8 bg + white text "punches" too hard in dark —
         desaturate to #4285F4 in dark and keep var(--surface) text. */

[data-theme="dark"] .integration-admin-google-connected {
  border-left-color: #5B9BFF;
}

[data-theme="dark"] .integration-admin-google-root .integration-admin-btn-primary {
  background: #4285F4;
  border-color: #4285F4;
  color: var(--surface);
}


/* [B4 #10] button loading spinner — add subtle backdrop ring for soft variants.
   v3/buttons.css:301 (.btn-loading::before border 2px solid currentColor)
   On neutral .btn (no variant), currentColor=text — fine. But .btn-soft,
   .btn-outline, .btn-danger-soft inherit brand/danger color which in dark
   is the LIGHT swatch — spinner blends into background subtly. Add a faint
   backdrop ring for legibility. */

[data-theme="dark"] .btn-soft.btn-loading::before,
[data-theme="dark"] .btn-outline.btn-loading::before,
[data-theme="dark"] .btn-danger-soft.btn-loading::before {
  border-color: currentColor;
  border-right-color: transparent;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
}


/* [B4 bonus] modal overlay — deeper scrim in dark for clearer focus. */

[data-theme="dark"] .modal-overlay {
  background: rgba(0, 0, 0, 0.72);
}


/* [A9 #14] inline-editor wrapper `nx-editable.editing` injects --accent-light
   bg via JS (modules/inline_edit.js:121). In dark this resolves to
   rgba(129,140,248,0.08) which is fine on its own, but the CHILD <select>
   editor inherits user-agent white background unless explicitly themed.
   Probe captured rgb(255,255,255) bg on the editor input/select.
   Fix: explicitly theme nx-editor select + input in dark to match surface
   tokens (the JS rule already sets bg:var(--card) but ::picker UA bg leaks
   on <select> elements). Force ALL form children inside .nx-editable. */

/* DARK FIX: js/modules/inline_edit.js:121-122 — native select inside editing cell renders white */
[data-theme="dark"] .nx-editable.editing,
[data-theme="dark"] .nx-editable .nx-editor,
[data-theme="dark"] .nx-editable.editing select,
[data-theme="dark"] .nx-editable.editing input {
  background-color: var(--surface);
  color: var(--text);
  border-color: var(--brand);
  color-scheme: dark;
}


/* [A9 #15] tw-bulk row checkboxes (table-superpowers.js injects <input
   type="checkbox">). Native checkboxes default to UA white in dark mode
   unless `color-scheme: dark` is declared on the root or input itself.
   Probe captured rgb(255,255,255) bg on .tw-bulk-cell/.tw-bulk-head inputs
   across Projects / Tasks / Risks tables.
   Fix: opt the entire dark theme into UA dark form rendering. Targeted to
   form controls only so we don't disrupt content backgrounds. */

/* DARK FIX: js/modules/table_superpowers.js:284 — UA white checkboxes in dark tables */
[data-theme="dark"] input[type="checkbox"],
[data-theme="dark"] input[type="radio"],
[data-theme="dark"] .tw-bulk-cell input,
[data-theme="dark"] .tw-bulk-head input {
  color-scheme: dark;
  accent-color: var(--brand);
}


/* [A9 #18] table anchor links — <a> inside td inherits --brand (--info blue)
   from default link styles. On --surface this is 3.43:1 (FAIL). Probe
   captured rgb(37,99,235) anchors in Risks "Response" cell. Lift to
   blue-400 for ≥5:1. */

/* DARK FIX: anchor color --info on dark surface < 4.5:1 contrast */
[data-theme="dark"] td a:not([class]),
[data-theme="dark"] td a.cell-link,
[data-theme="dark"] tbody a:not([class*="btn"]) {
  color: #60A5FA;  /* blue-400 ~ 5.6:1 */
}


/* [A9 #19] SVG icons with hardcoded stroke="var(--surface)" or stroke="white"
   appear throughout (action buttons, menu icons). In dark mode they're fine
   AGAINST dark backgrounds — but when the icon sits inside a .btn-warning
   or .btn-danger (saturated bg) the white fill is correct, while inside
   neutral-bg buttons like .btn-bare on top of surface, white stroke can
   feel too "loud". Soften neutral-context white icons to --text. No CSS
   knob exists to recolor inline stroke="var(--surface)" without targeting
   each SVG, so this fix is intentionally narrow. */

/* DARK FIX: inline SVG stroke="var(--surface)" inside neutral buttons reads loud */
[data-theme="dark"] .btn-bare svg[stroke="var(--surface)"],
[data-theme="dark"] .btn-ghost svg[stroke="var(--surface)"] {
  stroke: var(--text);
}


/* [A9 #22] app.css:967 .suggest-card.urgent background:#fffbf5 — a pastel
   warm-white that becomes glaringly bright in dark. */

/* DARK FIX: app.css:967 .suggest-card.urgent pastel #fffbf5 in dark */
[data-theme="dark"] .suggest-card.urgent {
  background: rgba(234, 88, 12, 0.08);
  border-color: rgba(234, 88, 12, 0.32);
}


/* [A9 #24] import preview rows app.css:1077 .row-error background:#fff1f2
   is a pastel pink unreadable on dark canvas. */

/* DARK FIX: app.css:1077 #importPreviewTable .row-error background pastel pink */
[data-theme="dark"] #importPreviewTable tbody tr.row-error {
  background: rgba(220, 38, 38, 0.12);
}


/* [A9 #26] tooltip/popover surfaces — when these are dynamically injected
   they often default to var(--surface) via inline styles. Provide a global
   override on common selectors used by features.js notification dropdown. */

/* DARK FIX: js/features.js:158 notification dropdown background:var(--surface) fallback */
[data-theme="dark"] .notification-card[style*="background:var(--surface)"],
[data-theme="dark"] .notification-card[style*="background: var(--surface)"] {
  background: var(--surface);
  border-color: var(--border-strong);
}


/* [A9 #27] exporter menu (js/modules/exporter.js:265) background:var(--surface)
   fallback when --card doesn't resolve. In dark always force surface. */

/* DARK FIX: js/modules/exporter.js:265 dropdown menu falls to var(--surface) fallback in dark */
[data-theme="dark"] .exporter-menu,
[data-theme="dark"] [class*="dropdown-menu"][style*="background:var(--card,var(--surface))"] {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}


/* ============================================================================
   END dark_mode_polish.css
   Refactored Wave 17 / Agent 6: 5 logical sections, no rule changes.
   Bump cache: /css/v3/dark_mode_polish.css?v=3
   ============================================================================ */

/* ===== /css/v3/legacy_replacement.css?v=2 ===== */
/* =====================================================================
   v3/legacy_replacement.css
   ---------------------------------------------------------------------
   Wave 8 — Agent A2
   Goal: provide v3-native equivalents for the still-needed compound /
   scoped selectors currently living in static/css/v2/legacy-shim.css
   (filter: deletion_phase == 2 AND used_in_html|used_in_js == true).

   Base classes (.btn, .btn-primary, .card, .modal-*, .form-*) already
   live in v3/buttons.css / v3/cards.css / v3/modal.css / v3/forms.css /
   v3/components.css. This file only covers the *compound / scoped*
   patterns the shim layers on top — table-action buttons, drawer-scoped
   button rules, modal scroll-area layout, kanban / page-scoped primaries,
   etc.

   Rules:
     - Design tokens ONLY (no hex literals).
     - No !important — relies on cascade order (load AFTER legacy-shim).
     - Selectors mirror the legacy-shim ones 1:1 so removing legacy-shim
       is a drop-in swap.
   ===================================================================== */


/* === Toolbar / kanban-controls layout ============================= */
.toolbar,
.kanban-controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.toolbar > .btn,
.toolbar > button,
.toolbar > select,
.toolbar > input,
.kanban-controls > .btn,
.kanban-controls > button,
.kanban-controls > select,
.kanban-controls > input {
  margin: 0;
}

/* Primary action right-alignment — first .btn-primary in a toolbar row */
.toolbar > .btn-primary:first-of-type,
.kanban-controls > .btn-primary:first-of-type,
.list-controls > .btn-primary:first-of-type,
.section-head > .btn-primary:first-of-type,
.page-header > .btn-primary:first-of-type,
.page-hero > .btn-primary:first-of-type {
  margin-left: auto;
}

/* Platform pages: any toolbar .btn aligns flush */
[id^="page-platform"] .toolbar > .btn {
  margin: 0;
}


/* === Table cell action buttons (Edit / Delete / View in <td>) ===== */
/* Icon-only, borderless, hover wash — the kanban/list "..." button vibe. */
td .btn,
td .btn-sm,
td button.btn,
tbody td .btn,
tbody td .btn-sm {
  background: transparent;
  border: none;
  box-shadow: none;
  width: 30px;
  height: 30px;
  min-width: 30px;
  min-height: 30px;
  padding: 0;
  font-size: 0;
  color: var(--muted);
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 150ms ease, color 150ms ease;
  margin: 0 2px;
  vertical-align: middle;
}

td .btn:hover,
td .btn-sm:hover,
tbody td .btn:hover,
tbody td .btn-sm:hover {
  background: var(--bg-hover);
  color: var(--text);
}

td .btn svg,
td .btn-sm svg,
tbody td .btn svg,
tbody td .btn-sm svg {
  width: 15px;
  height: 15px;
  stroke-width: 1.75;
  display: block;
}

/* Variant-specific hover tints inside cells */
td .btn-primary:hover,
tbody td .btn-primary:hover {
  background: var(--brand-fade);
  color: var(--brand);
}

td .btn-warning:hover,
tbody td .btn-warning:hover {
  background: var(--warning-bg);
  color: var(--warning);
}

td .btn-danger:hover,
tbody td .btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
}


/* === Tree / task row action buttons =============================== */
.tree-row .btn,
.tree-row button.btn-sm,
.task-row .btn,
.task-row button.btn-sm,
.task-tree-row .btn {
  background: transparent;
  border: none;
  box-shadow: none;
}


/* === Section / card / modal titles — display font ================ */
.section-title,
.card-title,
.modal-title {
  font-family: var(--font-display);
}


/* === Modal — flex column with scroll area ========================= */
/* Mirrors the legacy `.modal > .nx-modal-scroll` flex pattern. */
.modal {
  display: flex;
  flex-direction: column;
  padding: 0;
  max-height: 90vh;
  overflow: hidden;
}

.modal > .nx-modal-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-5) var(--space-6);
  scrollbar-width: thin;
}
.modal > .nx-modal-scroll::-webkit-scrollbar { width: 6px; }
.modal > .nx-modal-scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}
.modal > .nx-modal-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.modal > .modal-title,
.modal > .modal-header,
.modal > h1:first-child,
.modal > h2:first-child,
.modal > h3:first-child {
  flex: 0 0 auto;
  padding: var(--space-5) var(--space-6) var(--space-4);
  margin: 0;
  /* Wave 17 — Agent 5: `border-bottom: 1px solid var(--border)` removed.
   * The divider reintroduced an unwanted hairline between the title and
   * the form/body across user-reported modals (kickoff detail, new
   * research note, new release, new flag, new experiment, NPS, new doc),
   * forcing modal.css to ship a specificity-hack to defeat it. Removing
   * the border here makes the cascade self-consistent and let modal.css
   * drop the `.modal-overlay .modal > .modal-header` compat block. */
  background: var(--surface);
}

.modal > .nx-modal-scroll > .form-group,
.modal > .nx-modal-scroll > .form-row {
  margin: 0 0 var(--space-4);
  padding: 0;
}
.modal > .nx-modal-scroll > .form-group:last-child,
.modal > .nx-modal-scroll > .form-row:last-child {
  margin-bottom: 0;
}

.modal > .nx-modal-scroll > form {
  margin: 0;
  padding: 0;
}

.modal .form-row,
.modal-body .form-row {
  gap: var(--space-4);
}

/* <form> directly inside the modal (no scroll wrapper) */
.modal > form {
  padding: 0 var(--space-6);
  margin: 0;
}
.modal > form > .form-group,
.modal > form > .form-row {
  margin-left: 0;
  margin-right: 0;
}

/* Pinned bottom action footer */
.modal > .modal-actions,
.modal > .modal-footer {
  flex: 0 0 auto;
  padding: var(--space-3) var(--space-6);
  margin: 0;
  border-top: 1px solid var(--border);
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* v3 .modal-body wrapper variant */
.modal:has(.modal-body) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal > .modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--space-5) var(--space-6);
  margin: 0;
}
.modal:has(.modal-body) > .modal-title,
.modal:has(.modal-body) > .modal-header,
.modal:has(.modal-body) > .modal-actions,
.modal:has(.modal-body) > .modal-footer {
  position: static;
}


/* === Input wraps inside modal (icon-prefixed inputs) ============== */
.input-wrap {
  position: relative;
}
.input-wrap .form-input,
.input-wrap input.form-input,
.modal .input-wrap input,
.modal .search-box input {
  padding-left: 38px;
  padding-right: var(--space-3);
}
.input-wrap .input-icon {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
  display: flex;
  align-items: center;
}
.input-wrap .input-icon svg {
  width: 15px;
  height: 15px;
}


/* === Task drawer — scoped form + button rules ===================== */
#taskDrawer .history-form .form-label,
#taskDrawer .tab-content .form-label {
  color: var(--text-2);
}

#taskDrawer .history-form .form-input,
#taskDrawer .history-form .form-textarea,
#taskDrawer .tab-content .form-input,
#taskDrawer .tab-content .form-textarea {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
}
#taskDrawer .history-form .form-input:focus,
#taskDrawer .history-form .form-textarea:focus,
#taskDrawer .tab-content .form-input:focus,
#taskDrawer .tab-content .form-textarea:focus {
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
  outline: none;
}

#taskDrawer .history-form button.btn,
#taskDrawer .tab-content button.btn,
#taskDrawer .timeline-actions button.btn,
#taskDrawer #drawerTaskBadges button.btn,
#taskDrawer #taskApprovalsContainer button.btn,
#taskDrawer #taskDepsContainer button.btn,
#taskDrawer #taskCommentsContainer button.btn,
#taskDrawer #taskTimeContainer button.btn {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
#taskDrawer .history-form button.btn:hover,
#taskDrawer .tab-content button.btn:hover,
#taskDrawer #drawerTaskBadges button.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

#taskDrawer .history-form button.btn-primary,
#taskDrawer .tab-content button.btn-primary,
#taskDrawer #taskApprovalsContainer button.btn-primary,
#taskDrawer #taskCommentsContainer button.btn-primary,
#taskDrawer #taskDepsContainer button.btn-primary,
#taskDrawer #taskTimeContainer button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#taskDrawer .history-form button.btn-primary:hover,
#taskDrawer .tab-content button.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}

#taskDrawer .history-form button.btn-danger,
#taskDrawer .tab-content button.btn-danger {
  background: var(--surface);
  color: var(--danger);
  border-color: var(--danger);
}
#taskDrawer .tab-content button.btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}


/* === Project drawer — scoped form + button rules ================== */
#projectDrawer .drawer-section input.form-input {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
}
#projectDrawer .drawer-section input.form-input:focus {
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
  outline: none;
}

#projectDrawer .drawer-section button.btn {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
#projectDrawer .drawer-section button.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

#projectDrawer .drawer-section button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#projectDrawer .drawer-section button.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}

#projectDrawer .drawer-section button.btn-danger {
  background: var(--surface);
  color: var(--danger);
  border-color: var(--danger);
}
#projectDrawer .drawer-section button.btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}

/* Inline "approve / save" success-tinted buttons via inline style hint */
#projectDrawer .drawer-section button.btn[style*="background:var(--green)"] {
  background: var(--success);
  color: var(--surface);
  border-color: var(--success);
}
#projectDrawer .drawer-section button.btn[style*="background:var(--green)"]:hover {
  background: var(--success);
  filter: brightness(0.95);
}


/* === KB editor / meeting / graph toolbar buttons ================== */
#page-kb .kb-editor-actions button.btn,
#page-kb .kb-editor-header button.btn,
#page-kb .kb-graph-controls button.btn,
#page-kb .kb-graph-toolbar button.btn,
#page-kb .kb-meeting-header button.btn {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
#page-kb .kb-editor-actions button.btn:hover,
#page-kb .kb-editor-header button.btn:hover,
#page-kb .kb-graph-controls button.btn:hover,
#page-kb .kb-graph-toolbar button.btn:hover,
#page-kb .kb-meeting-header button.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

#page-kb .kb-editor-actions button.btn-primary,
#page-kb .kb-meeting-actions button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#page-kb .kb-editor-actions button.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}

#page-kb .kb-editor-actions button.btn-danger {
  background: var(--surface);
  color: var(--danger);
  border-color: var(--danger);
}
#page-kb .kb-editor-actions button.btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}

#page-kb .kb-meeting-actions button.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border: 1px solid transparent;
}


/* === AI page — prompt form buttons ================================ */
#page-ai #aiPromptForm button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#page-ai #aiPromptForm button.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border: 1px solid transparent;
}
#page-ai #aiPromptForm button.btn-ghost:hover {
  background: var(--bg-hover);
  color: var(--text);
}


/* === Profile page — card-scoped form + buttons ==================== */
#page-profile .profile-card .form-group {
  margin-bottom: var(--space-4);
}
#page-profile .profile-card .form-group:last-child {
  margin-bottom: 0;
}
#page-profile .profile-card .form-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
#page-profile .profile-card div[style*="display:flex"][style*="gap:12px"] > .form-group {
  flex: 1 1 0;
  min-width: 0;
}
#page-profile .profile-card .form-group .form-label {
  color: var(--text-2);
  font-weight: 500;
}

#page-profile .profile-card .form-input,
#page-profile .profile-card .form-select,
#page-profile .profile-card .form-textarea,
#page-profile .profile-card input.form-input[style*="max-width"],
#page-profile .profile-card select.form-select[style*="max-width"] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
}
#page-profile .profile-card .form-input:focus,
#page-profile .profile-card .form-select:focus,
#page-profile .profile-card .form-textarea:focus {
  border-color: var(--brand);
  box-shadow: var(--shadow-focus);
  outline: none;
}

#page-profile .profile-card button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#page-profile .profile-card button.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}
#page-profile .profile-card button.btn-ghost {
  background: transparent;
  color: var(--text-2);
  border: 1px solid transparent;
}
#page-profile .profile-card button.btn-ghost:hover {
  background: var(--bg-hover);
  color: var(--text);
}


/* === PMO entity cards — uniform action button styling ============= */
/* Covers: competitor / doc / feedback / fr / hypothesis / initiative /
   kr-item / metric / okr / persona / release / release-card-actions /
   team / init-feature-actions cards. */
.competitor-card button.btn,
.doc-card button.btn,
.feedback-card button.btn,
.fr-card button.btn,
.hypothesis-card button.btn,
.init-feature-actions button.btn,
.initiative-card button.btn,
.kr-item button.btn,
.metric-card button.btn,
.okr-card button.btn,
.persona-card button.btn,
.release-card button.btn,
.release-card-actions button.btn,
.team-card button.btn,
#page-skills .action-cell button.btn,
#page-team .action-cell button.btn,
#page-vendors .action-cell button.btn {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
.competitor-card button.btn:hover,
.doc-card button.btn:hover,
.feedback-card button.btn:hover,
.fr-card button.btn:hover,
.hypothesis-card button.btn:hover,
.init-feature-actions button.btn:hover,
.initiative-card button.btn:hover,
.kr-item button.btn:hover,
.metric-card button.btn:hover,
.okr-card button.btn:hover,
.persona-card button.btn:hover,
.release-card button.btn:hover,
.release-card-actions button.btn:hover,
.team-card button.btn:hover,
#page-skills .action-cell button.btn:hover,
#page-team .action-cell button.btn:hover,
#page-vendors .action-cell button.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

.competitor-card button.btn-warning:hover,
.feedback-card button.btn-warning:hover,
.fr-card button.btn-warning:hover,
.hypothesis-card button.btn-warning:hover,
.initiative-card button.btn-warning:hover,
.kr-item button.btn-warning:hover,
.metric-card button.btn-warning:hover,
.okr-card button.btn-warning:hover,
.persona-card button.btn-warning:hover,
.release-card button.btn-warning:hover,
.release-card-actions button.btn-warning:hover,
.team-card button.btn-warning:hover,
#page-skills .action-cell button.btn-warning:hover,
#page-team .action-cell button.btn-warning:hover,
#page-vendors .action-cell button.btn-warning:hover {
  background: var(--warning-bg);
  color: var(--warning);
  border-color: var(--warning);
}

.competitor-card button.btn-danger:hover,
.feedback-card button.btn-danger:hover,
.fr-card button.btn-danger:hover,
.hypothesis-card button.btn-danger:hover,
.initiative-card button.btn-danger:hover,
.kr-item button.btn-danger:hover,
.metric-card button.btn-danger:hover,
.okr-card button.btn-danger:hover,
.persona-card button.btn-danger:hover,
.release-card button.btn-danger:hover,
.release-card-actions button.btn-danger:hover,
.team-card button.btn-danger:hover,
#page-skills .action-cell button.btn-danger:hover,
#page-team .action-cell button.btn-danger:hover,
#page-vendors .action-cell button.btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}

/* OKR card primary CTA */
.okr-card .okr-card-header button.btn-primary {
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
.okr-card .okr-card-header button.btn-primary:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}


/* === Task card hover (danger action zone) ========================= */
.task-actions .btn-danger:hover,
.task-card .btn-danger:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: var(--danger);
}


/* === Today page — module / KPI card styling ======================= */
#page-today > div > .card:first-child[style*="linear-gradient"] {
  border-radius: var(--radius-lg);
}
#page-today .card[style*="border-left:3px solid"] {
  border-left-width: 3px;
  border-left-style: solid;
  border-radius: var(--radius-md);
  background: var(--surface);
}
#page-today .card[style*="border-left:3px solid"]:hover {
  background: var(--bg-hover);
}
#page-today .card[style*="padding:0"][style*="overflow:hidden"] {
  padding: 0;
  overflow: hidden;
}
#page-today .card[style*="cursor:pointer"][style*="padding:14px"] {
  cursor: pointer;
  padding: var(--space-3);
  transition: background-color 150ms ease, border-color 150ms ease;
}
#page-today .card[style*="cursor:pointer"][style*="padding:14px"]:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}
#page-today button.btn[style*="font-weight:600"] {
  font-weight: 600;
  background: var(--brand);
  color: var(--surface);
  border-color: var(--brand);
}
#page-today button.btn[style*="font-weight:600"]:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
}


/* === Modules page — group card styling ============================ */
#page-modules > #modulesAdminRoot > .card:first-child {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
#page-modules #modGroups > .card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

/* Inline-styled badges in modules admin — token-equivalent rendering */
#page-modules .badge[style*="--accent-light"] {
  background: var(--brand-soft);
  color: var(--brand);
  border-color: var(--brand-strong);
}
#page-modules .badge[style*="--yellow-light"] {
  background: var(--warning-bg);
  color: var(--warning);
  border-color: var(--warning);
}
#page-modules .badge[style*="--bg-hover"] {
  background: var(--bg-hover);
  color: var(--text-2);
  border-color: var(--border);
}


/* === Availability page — split-grid table wrapper ================= */
#page-availability > div[style*="grid-template-columns:1fr 1fr"] .table-wrap {
  min-width: 0;
  overflow: auto;
}


/* === Mobile — modal sheet rules =================================== */
@media (max-width: 600px) {
  .modal {
    max-height: 100dvh;
    width: 100%;
    border-radius: 0;
  }
  .modal > .modal-title {
    padding: var(--space-4) var(--space-4) var(--space-3);
  }
  .modal > .form-group,
  .modal > .form-row {
    margin-left: var(--space-4);
    margin-right: var(--space-4);
  }
  .modal > form {
    padding: 0 var(--space-4);
  }
  .modal > .modal-actions,
  .modal > .modal-footer {
    padding: var(--space-3) var(--space-4);
    padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
  }
}


/* USAGE:
   Load this file in <head> AFTER v2/legacy-shim.css and AFTER all other
   v3/*.css per static/css/v3/_load_order.txt (between v3/modal.css and
   v3/components.css, or LAST in the v3 chain — both work since these
   selectors don't conflict with the base v3 component primitives).

   Wave 8 owner (Tech Lead) will wire the <link rel="stylesheet"> tag
   into static/index.html as part of review.
*/

/* ===== /css/v3/comm_plans.css?v=1 ===== */
/* ============================================================================
 * Nexora — Communication Plans page (PMBOK 10.1)
 * Wave 7, Agent B2 — scoped under .cmp-page to avoid leakage.
 * Pairs with static/js/modules/page_comm_plans.js
 * ========================================================================= */

.cmp-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px 20px 24px;
  min-height: 100%;
  color: var(--text, #1f2937);
}

/* ── Top bar ─────────────────────────────────────────────────────────────── */
.cmp-page .cmp-topbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.cmp-page .cmp-topbar__left { min-width: 240px; }
.cmp-page .cmp-topbar__right {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}
.cmp-page .cmp-title {
  margin: 0 0 4px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.cmp-page .cmp-sub {
  margin: 0;
  color: var(--muted, #6b7280);
  font-size: 13px;
  max-width: 56ch;
}

/* ── Layout grid: list + preview ─────────────────────────────────────────── */
.cmp-page .cmp-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 380px);
  gap: 16px;
  align-items: start;
}
@media (max-width: 960px) {
  .cmp-page .cmp-layout { grid-template-columns: 1fr; }
}

.cmp-page .cmp-list-wrap { min-width: 0; }
.cmp-page .cmp-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
  outline: none;
}

/* ── Card ────────────────────────────────────────────────────────────────── */
.cmp-page .cmp-card {
  background: var(--surface, var(--surface));
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, transform .05s ease;
  box-shadow: 0 1px 0 rgba(0,0,0,0.02);
  outline: none;
}
.cmp-page .cmp-card:hover {
  border-color: var(--accent, var(--info));
  box-shadow: 0 4px 12px rgba(37,99,235,0.08);
}
.cmp-page .cmp-card:focus-visible {
  border-color: var(--accent, var(--info));
  box-shadow: 0 0 0 3px rgba(37,99,235,0.25);
}
.cmp-page .cmp-card.is-active {
  border-color: var(--accent, var(--info));
  background: linear-gradient(180deg, rgba(37,99,235,0.06), transparent 60%);
}
.cmp-page .cmp-card.is-draft {
  background: repeating-linear-gradient(
    -45deg,
    var(--surface, var(--surface)) 0 8px,
    rgba(0,0,0,0.02) 8px 12px
  );
}
.cmp-page .cmp-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.cmp-page .cmp-card__title {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.cmp-page .cmp-card__title strong {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmp-page .cmp-card__status {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #6b7280);
}
.cmp-page .cmp-card.is-draft .cmp-card__status { color: var(--warn, #d97706); }
.cmp-page .cmp-card__chan {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted, #6b7280);
  background: var(--surface-2, #f3f4f6);
  padding: 4px 8px;
  border-radius: 999px;
  flex-shrink: 0;
}
.cmp-page .cmp-chan-icon { width: 14px; height: 14px; }
.cmp-page .cmp-card__row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.cmp-page .cmp-card__meta {
  justify-content: space-between;
  font-size: 12px;
  color: var(--muted, #6b7280);
}
.cmp-page .cmp-card__owner {
  font-size: 12px;
  color: var(--text, #1f2937);
  max-width: 50%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmp-page .cmp-card__foot {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  padding-top: 4px;
  border-top: 1px dashed var(--border, #e5e7eb);
  margin-top: 2px;
}
.cmp-page .cmp-card__foot .btn { padding: 4px 8px; font-size: 12px; }
.cmp-page .cmp-card__foot .cmp-danger { color: var(--danger, var(--danger)); }

/* Badges (fallback if v3/badges.css doesn't ship these tones) */
.cmp-page .badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.6;
  background: var(--surface-2, #f3f4f6);
  color: var(--text, #1f2937);
  border: 1px solid var(--border, #e5e7eb);
}
.cmp-page .badge-soft     { background: var(--surface-2, #f3f4f6); }
.cmp-page .badge-info     { background: rgba(37,99,235,0.10); color: var(--info); border-color: rgba(37,99,235,0.20); }
.cmp-page .badge-muted    { background: var(--surface-2, #f3f4f6); color: var(--muted, #6b7280); }
.cmp-page .badge-warn     { background: rgba(217,119,6,0.10); color: var(--warning); border-color: rgba(217,119,6,0.25); }
.cmp-page .badge-critical { background: rgba(220,38,38,0.10); color: var(--danger); border-color: rgba(220,38,38,0.25); }
.cmp-page .muted { color: var(--muted, #6b7280); font-size: 12px; }

/* ── Empty state ─────────────────────────────────────────────────────────── */
.cmp-page .cmp-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 40px 20px;
  background: var(--surface, var(--surface));
  border: 1px dashed var(--border, #e5e7eb);
  border-radius: 12px;
}
.cmp-page .cmp-empty-svg { width: 200px; max-width: 70%; height: auto; margin-bottom: 12px; }
.cmp-page .cmp-empty__title { margin: 0 0 4px; font-size: 16px; font-weight: 600; }
.cmp-page .cmp-empty__sub   { margin: 0 0 14px; color: var(--muted, #6b7280); font-size: 13px; }
.cmp-page .cmp-empty__cta   { margin-top: 4px; }
.cmp-page .cmp-loading {
  grid-column: 1 / -1;
  padding: 32px;
  text-align: center;
  color: var(--muted, #6b7280);
  font-size: 13px;
}

/* ── Preview pane ────────────────────────────────────────────────────────── */
.cmp-page .cmp-preview {
  background: var(--surface, var(--surface));
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  padding: 16px;
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 96px);
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.cmp-page .cmp-preview__placeholder {
  color: var(--muted, #6b7280);
  font-size: 13px;
  padding: 24px 0;
  text-align: center;
}
.cmp-page .cmp-preview__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.cmp-page .cmp-preview__title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmp-page .cmp-preview__meta {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 16px;
  margin: 0;
  padding: 10px;
  background: var(--surface-2, #f9fafb);
  border-radius: 8px;
  font-size: 12px;
}
.cmp-page .cmp-preview__meta dt {
  color: var(--muted, #6b7280);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 2px;
}
.cmp-page .cmp-preview__meta dd {
  margin: 0;
  font-size: 13px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.cmp-page .cmp-preview__msg {
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface);
}
.cmp-page .cmp-preview__msg-head {
  padding: 8px 12px;
  background: var(--surface-2, #f3f4f6);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted, #6b7280);
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.cmp-page .cmp-preview__msg-body {
  padding: 14px;
  font-size: 13px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-wrap: break-word;
  color: var(--text, #1f2937);
}
.cmp-page .cmp-preview__hist h4 {
  margin: 0 0 6px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #6b7280);
}
.cmp-page .cmp-preview__hist-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
}
.cmp-page .cmp-preview__hist-list li {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px dashed var(--border, #e5e7eb);
}
.cmp-page .cmp-preview__hist-list li:last-child { border-bottom: 0; }

/* ── Modal (scoped overrides on top of v3/modal.css) ─────────────────────── */
.cmp-modal-overlay .cmp-modal { max-width: 760px; }
.cmp-modal-overlay .cmp-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 20px;
}
.cmp-modal-overlay .field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 640px) {
  .cmp-modal-overlay .field-row { grid-template-columns: 1fr; }
}
.cmp-modal-overlay .cmp-audience-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 6px 12px;
  padding: 10px;
  background: var(--surface-2, #f9fafb);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 8px;
  max-height: 180px;
  overflow: auto;
}
.cmp-modal-overlay .cmp-chk {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
}
.cmp-modal-overlay .cmp-chk input { margin: 0; }
.cmp-modal-overlay .cmp-hint {
  display: block;
  font-weight: 400;
  font-size: 11px;
  color: var(--muted, #6b7280);
  margin-top: 2px;
}

/* ── Dark-mode polish ────────────────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  .cmp-page .cmp-card.is-draft {
    background: repeating-linear-gradient(
      -45deg,
      var(--surface, #1f2937) 0 8px,
      rgba(255,255,255,0.03) 8px 12px
    );
  }
  .cmp-page .cmp-preview__msg { background: var(--surface, #1f2937); }
}
[data-theme="dark"] .cmp-page .cmp-card.is-draft {
  background: repeating-linear-gradient(
    -45deg,
    var(--surface, #1f2937) 0 8px,
    rgba(255,255,255,0.03) 8px 12px
  );
}
[data-theme="dark"] .cmp-page .cmp-preview__msg { background: var(--surface, #1f2937); }
