/* ════════════════════════════════════════════════════════════════
   BASELINE — original user.css
   ════════════════════════════════════════════════════════════════ */
/* Custom typography. Abermono carries the ELEVATE brand wordmark
   in the sidebar and every page header (h1–h6). `font-display: swap`
   so the page text renders in the fallback monospace immediately
   and re-paints once the OTF lands — avoids invisible-text-flash
   on first paint. */
@font-face {
    font-family: 'abermono';
    src: url('/static/fonts/abermono-regular.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

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

/* Cross-document view-transitions removed 2026-05-25 — the
   browser's snapshot of the incoming document was being taken
   before the inline theme-init script in <head> could apply the
   `body.light` class, so transitions read as a dark→light→dark
   flicker on every navigation. Revisit only after the theme-init
   moves to a `<script>` that runs synchronously against <body>
   (or after the theme class lives on <html> instead). */

:root {
    /* Dark theme — default. The user app uses a `body.light` opt-in
       to mirror the existing public-dashboard pattern; per-page CSS
       (learn.css, dashboard.css, streams.css) reads these vars so
       the toggle reaches every var-driven surface in one switch. */
    --bg: #0a0e17;
    --bg-card: #111827;
    --bg-hover: #1a2332;
    --surface-alt: #1a2332;        /* alias for --bg-hover; some templates use this name */
    --border: #1f2937;
    --border-hover: #374151;
    --text: #e0e0e0;
    --text-muted: #6b7280;
    --text-dim: #4b5563;
    --accent: #60a5fa;
    --accent-hover: #3b82f6;
    --white: #f0f0f0;
    --green: #34d399;
    --red: #f87171;
    --amber: #f59e0b;

    /* Width of the right-edge activity stream pane (DD-021). Mirrored
       in `.activity-stream { width }` and `.app-layout { padding-right }`
       so a single change keeps the pane and the gutter in sync. */
    --activity-stream-width: 320px;
}

body.light {
    /* Light theme — slate scale + slightly deeper accent so the
       muted blue still reads against a near-white background.
       Greens / reds / amber unchanged for status semantics. */
    --bg: #f8fafc;
    --bg-card: #ffffff;
    --bg-hover: #f1f5f9;
    --surface-alt: #f1f5f9;        /* alias for --bg-hover; templates using --surface-alt now flip too */
    --border: #e2e8f0;
    --border-hover: #cbd5e1;
    --text: #0f172a;
    --text-muted: #475569;
    --text-dim: #597daf;
    --accent: #2563eb;
    --accent-hover: #1d4ed8;
    --white: #0f172a;
    --green: #047857;
    --red: #b91c1c;
    --amber: #b45309;
}

/* Theme toggle icon swap — show moon in dark mode, sun in light
   mode. Applies to the legacy `.theme-toggle` AND the persistent
   navbar action. */
.theme-toggle .theme-icon-light,
.navbar-action .theme-icon-light { display: none; }
body.light .theme-toggle .theme-icon-dark,
body.light .navbar-action .theme-icon-dark { display: none; }
body.light .theme-toggle .theme-icon-light,
body.light .navbar-action .theme-icon-light { display: inline-flex; }

/* Persistent top nav-bar — part of the base skeleton, always
   rendered on every authenticated page so the chrome doesn't
   shift between pages. Lives in document flow (not fixed) so it
   participates in the layout grid and never overlaps content.
   No bottom border: the navbar is the skeleton's top strip,
   not a visual separator between zones. Future chrome
   (notification bell, profile menu, package switcher) joins this
   row; today it's just the theme toggle. */
.app-navbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 1.25rem;
    min-height: 56px;
    background: var(--bg);
    transition: padding-left 0.18s ease;
}
/* When the sidebar is collapsed, the floating hamburger sits at
   left: 8px — which crashes into the navbar title (HOME / STREAMS).
   Nudge the title-zone right by 2rem so the hamburger has clearance.
   The right-side chrome (theme toggle) stays pinned by the
   justify-content: space-between rule. */
.app-layout.sidebar-collapsed .app-navbar {
    padding-left: calc(1.25rem + 2rem);
}
.app-navbar__title-zone {
    /* Left zone — page title + subtitle. min-width:0 lets long
       titles truncate cleanly rather than push the chrome actions
       off-screen. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
    line-height: 1.15;
}
.app-navbar__title {
    font-family: 'abermono', ui-monospace, SFMono-Regular, monospace;
    font-size: 0.95rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.app-navbar__subtitle {
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 0.15rem;
}
.navbar-action {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.35rem 0.45rem;
    line-height: 0;
    transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.navbar-action:hover {
    color: var(--text);
    border-color: var(--border-hover);
    background: var(--bg-hover);
}
.navbar-action:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.18);
}

/* Sidebar footer — onboarding indicator (when active) + Logout.
   Theme toggle migrated out; Logout is now a centered text
   anchor rather than an icon button.
   No `margin-top: auto` here — the .sidebar-profile--bottom
   above already claims all the column slack, and we want the
   logout row to sit IMMEDIATELY below Profile, not also fight
   for slack (two siblings with `margin-top: auto` split it
   50/50 which leaves Profile halfway down the sidebar). */
.sidebar-theme-toggle-row {
    padding: 0.6rem 1rem 0.8rem;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ===== Light-mode contrast overrides ============================
   The default declarations elsewhere pair pastel text with dark
   tinted backgrounds — invisible on white. Each rule below flips
   text + background to a darker / lighter pair so the same semantic
   intent reads on light pages. Status-colour intent (green=ok,
   red=bad, amber=warn) preserved across modes. */

body.light .system-status-badge.running         { background: #d1fae5; color: #065f46; }
body.light .system-status-badge.stopped         { background: var(--bg-hover); color: var(--text-dim); }
body.light .system-stat-green                   { color: #047857; }
body.light .system-stat-red                     { color: #b91c1c; }

body.light .collection-status-badge.success    { background: #d1fae5; color: #065f46; }
body.light .collection-status-badge.unchanged  { background: #dbeafe; color: #1e40af; }
body.light .collection-status-badge.error      { background: #fee2e2; color: #991b1b; }
body.light .collection-entry.new   .collection-entry-badge { background: #d1fae5; color: #065f46; }
body.light .collection-entry.known .collection-entry-badge { background: var(--bg-hover); color: var(--text-dim); }

body.light .article-state-badge.approved        { background: #d1fae5; color: #065f46; }
body.light .article-state-badge.rejected        { background: #fee2e2; color: #991b1b; }
body.light .article-state-badge.unprocessed     { background: #fef3c7; color: #92400e; }
body.light .article-state-badge.skipped         { background: var(--bg-hover); color: var(--text-muted); }

/* Article-listing pill outcomes (baselined / pipeline-rejected).
   Default rules set only `color`, leaving text invisible on white.
   Light mode lifts a faint background tint into the pill to give
   the same prominence as the dark-mode text+dot pairing. */
body.light .pill-baseline-baselined { color: #047857; background: #ecfdf5; border-color: #a7f3d0; }
body.light .pill-baseline-legacy    { color: #1e40af; background: #eff6ff; border-color: #bfdbfe; }
body.light .pill-baseline-pending   { color: #92400e; background: #fffbeb; border-color: #fde68a; }
body.light .pill-baseline-rejected  { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
body.light .pill-baseline-failed    { color: #b45309; background: #fffbeb; border-color: #fde68a; }
body.light .pill-pipeline-ran        { color: #047857; background: #ecfdf5; border-color: #a7f3d0; }
body.light .pill-pipeline-failed     { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
body.light .pill-pipeline-gate       { color: #92400e; background: #fffbeb; border-color: #fde68a; }
body.light .pill-pipeline-incomplete { color: #92400e; background: #fffbeb; border-color: #fde68a; }

/* Reports list — topic + status badges live as inline <style> in
   reports_list.html. Override centrally so all pill/badge fixes
   stay in one place. */
body.light .topic-badge       { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
body.light .status-badge.status-draft      { background: #f1f5f9; color: #334155; border-color: #cbd5e1; }
body.light .status-badge.status-generating { background: #fef3c7; color: #92400e; border-color: #fcd34d; }
body.light .status-badge.status-ready      { background: #d1fae5; color: #047857; border-color: #6ee7b7; }
body.light .status-badge.status-failed     { background: #fee2e2; color: #991b1b; border-color: #fca5a5; }

/* Activity-stream type chips. */
body.light .activity-type-article    { background: #dbeafe; color: #1e3a8a; }
body.light .activity-type-task       { background: var(--bg-hover); color: var(--text-muted); }
body.light .activity-type-pipeline   { background: #d1fae5; color: #065f46; }
body.light .activity-type-collection { background: #fef3c7; color: #92400e; }

/* Threat-actor pills on the article detail page — `red on red`
   inline-style original blended into itself. Now: solid red border,
   readable on both modes via theme-driven background + text. */
.threat-actor-pill {
    background: rgba(220, 38, 38, 0.18);
    color: #fecaca;
    border: 1px solid #dc2626;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
}
.threat-actor-pill:hover {
    background: rgba(220, 38, 38, 0.30);
    color: #fff;
}
body.light .threat-actor-pill {
    background: #fee2e2;
    color: #991b1b;
    border-color: #fca5a5;
}
body.light .threat-actor-pill:hover {
    background: #fecaca;
    color: #7f1d1d;
}

/* Investigate → Sectors target/neutral bar. The default uses dark
   navy + dark red, both legible on dark mode but the navy nearly
   matches the white card and the red feels heavy. Use clearer mid-
   blue + warm red on light mode. */
body.light .sector-card-bar         { background: #cbd5e1; }
body.light .sector-card-bar-fill    { background: #3b82f6; }
body.light .sector-card-bar-target  { background: #dc2626; }

/* Sources stat cards / generic stat-card — bg-card is pure white
   in light mode, which gives no visual separation from the white
   page background. Lift the cards onto a subtle slate panel so the
   coloured numbers (working green, failing red, stale amber) read
   against a calmer surface. */
body.light .stat-card {
    background: #f8fafc;
    border-color: #e2e8f0;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

/* Direct page — gap-finder + matched-value chips. Defaults use
   rgba(<color>, 0.12) which on white renders as a faint wash
   indistinguishable from the surrounding text. Lift each tint and
   darken the text. */
body.light .chip-tag      { background: #dbeafe; color: #1e40af; border-color: #bfdbfe; }
body.light .chip-topical  { background: #f3e8ff; color: #6b21a8; border-color: #e9d5ff; }
body.light .chip-gap      { background: #d1fae5; color: #065f46; border-color: #a7f3d0; }
body.light .btn-detail    { background: #dbeafe; color: #1e40af; border-color: #bfdbfe; }
body.light .btn-detail:hover { background: #bfdbfe; }

/* Topic-match pill (Tasks-covering-these-gaps + Hit-by-signals
   tables on the Direct page). Same pastel-on-dark default —
   light-mode equivalent uses a clearly-darker text on a tinted
   background rather than colour-on-colour. */
body.light .topic-match-pill.tag        { background: #dbeafe; color: #1e40af; }
body.light .topic-match-pill.keyword    { background: #fef3c7; color: #92400e; }
body.light .topic-match-pill.technique  { background: #d1fae5; color: #065f46; }

/* Match `html` bg to the theme bg so the brief between-document
   gap that browsers show on cross-document navigation (where the
   old document has been torn down and the new one's CSS hasn't
   yet applied) reads as the theme background instead of browser-
   default white. The head-level theme-init script writes
   `data-theme` on <html> synchronously, so this selector applies
   on the first paint before any redirect /unload. */
html { background: var(--bg); }
html[data-theme="light"] { background: #f8fafc; }

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
}

/* Headers use the abermono brand face across the entire user app
   so the ELEVATE wordmark + every page H1 share one typographic
   identity. Falls back to the platform monospace stack while the
   OTF loads (font-display: swap on @font-face above), then
   re-paints once the brand face is available. */
h1, h2, h3, h4, h5, h6 {
    font-family: 'abermono', ui-monospace, SFMono-Regular, monospace;
    letter-spacing: 0.02em;
}

/* Layout: sidebar + main + activity-stream (DD-021).

   The activity-stream pane participates as a real flex child rather
   than overlaying with `position: fixed`. This means the main-content
   STRUCTURALLY cannot be obscured — the layout has to make 320px of
   room or shrink the main-content to fit. The previous approach
   reserved a `padding-right` gutter on .app-layout and let the pane
   sit on top, which silently failed whenever a page's children
   extended past their nominal width. */
.app-layout {
    display: flex;
    min-height: 100vh;
}

/* Right-side column wrapper — stacks the persistent app-navbar
   above the main content area. Flex column so navbar stays at
   its natural height and main-content fills the rest. flex:1
   so the column claims all horizontal space the sidebar leaves
   behind. min-width:0 prevents flex children with overflowing
   content from blowing the column out wider than the viewport.

   NB: No `flex: 1` on `> .main-content` — the shorthand sets
   `flex-basis: 0%` which OVERRIDES `.main-content--full`'s
   `height: 100vh` on viewport-fitted pages (streams, dashboard).
   Without the rule, .main-content takes its natural size:
   .main-content--full = 100vh (per its own rule), default
   .main-content = content-sized (multi-page scroll). Both
   behave correctly. */
.app-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* Sidebar */
.sidebar {
    width: 220px;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    background: var(--bg-card);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 1rem 0;
    flex-shrink: 0;
}
.sidebar-brand {
    /* ELEVATE wordmark in abermono, bold + larger so it reads as
       the brand mark rather than competing with sidebar text. The
       face only ships a regular cut; CSS `font-weight: 700` asks
       the browser to synthesise the bold (Firefox/Chrome do this
       cleanly for monospace shapes). */
    font-family: 'abermono', ui-monospace, SFMono-Regular, monospace;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--accent);
    padding: 0 1.2rem 1rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.5rem;
}

/* Identity card at the top of the sidebar — initials avatar +
 * name/email/role. Click anywhere to open /app/profile (where the
 * avatar-upload UI will live; for now the avatar is initials-on-a-
 * coloured-disc). Background colour is generated from the email
 * seed via a tiny CSS-only hash (the inline style on the avatar in
 * base.html — see also the runtime `data-seed` hook). */
.sidebar-profile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    padding: 0.9rem 0.8rem;
    margin: 0 0.4rem 0.8rem;
    border-radius: 8px;
    text-decoration: none;
    color: var(--text);
    background: var(--bg-card, rgba(255,255,255,0.03));
    border: 1px solid transparent;
    transition: border-color 120ms ease, background 120ms ease;
    text-align: center;
}
.sidebar-profile:hover {
    border-color: var(--accent);
}
.sidebar-profile--bottom {
    /* Sidebar-bottom variant — pushed to the very bottom of the
       flex column so it sits flush above the logout row. The
       `margin-top: auto` absorbs all the slack between the last
       sidebar group and the bottom chrome; the logout row (which
       also carries `margin-top: auto`) takes nothing extra and
       lands directly below Profile. Trailing margin dropped so
       the row spacing is owned by the logout row's top border. */
    margin-top: auto;
    margin-bottom: 0.4rem;
}

/* "View organisation →" link tucked under the profile card.
   Small, muted text — chrome, not nav — so it reads as a quick
   way out of the profile-card context without competing with
   the avatar block above it. */
.sidebar-profile-orglink {
    display: block;
    margin: 0 0.4rem 0.4rem;
    padding: 0.4rem 0.8rem;
    font-size: 0.72rem;
    text-align: center;
    color: var(--text-muted);
    text-decoration: none;
    border-radius: 6px;
    transition: color 120ms ease, background 120ms ease;
}
.sidebar-profile-orglink:hover {
    color: var(--accent);
    background: var(--bg-hover);
}
.sidebar-profile.active {
    border-color: var(--accent);
    background: var(--bg-elevated, rgba(96, 165, 250, 0.08));
}
.sidebar-profile-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    flex-shrink: 0;
    text-transform: uppercase;
}
.sidebar-profile-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    min-width: 0;
    line-height: 1.25;
    gap: 0.1rem;
}
.sidebar-profile-name {
    color: var(--text);
    font-size: 0.88rem;
    font-weight: 500;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sidebar-profile-email {
    color: var(--text-muted);
    font-size: 0.72rem;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sidebar-profile-role {
    color: var(--accent);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-top: 0.2rem;
}

.sidebar-group { margin-bottom: 0.5rem; }
.sidebar-group-label {
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    padding: 0.5rem 1.2rem 0.2rem;
}
.sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 1.2rem;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.85rem;
    transition: color 0.15s, background 0.15s;
}
.sidebar-link:hover { color: var(--text); background: var(--bg-hover); }
.sidebar-link.active { color: var(--accent); background: rgba(96, 165, 250, 0.08); border-right: 2px solid var(--accent); }
.sidebar-icon { font-size: 0.9rem; width: 1.2rem; text-align: center; }
.sidebar-bottom {
    border-top: 1px solid var(--border);
    padding-top: 0.5rem;
    margin-top: 0.5rem;
}

/* Admin zone — wraps the three admin sub-groups (Operate / Configure
   / Tenants) with a single top border + zone caption so the user
   sees one "this is admin" cue instead of three. The sub-groups
   inside use the regular `.sidebar-group-label` styling. */
.sidebar-admin-zone {
    border-top: 1px solid var(--border);
    padding-top: 0.4rem;
    margin-top: 0.5rem;
}
.sidebar-admin-caption {
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    padding: 0.2rem 1.2rem 0.4rem;
    opacity: 0.8;
}

/* Main content. Default cap is the comfortable reading-line for
   prose pages (article detail, requirement editor, etc). Pages that
   want the full viewport — e.g. the dashboard streams rail — opt in
   with `{% block main_content_modifier %}main-content--full{% endblock %}`
   which lifts the cap and reduces side padding. */
.main-content {
    flex: 1;
    /* `min-width: 0` overrides flex's default `min-width: auto` (which
       computes to min-content). Without it, a wide child — a table, a
       long unbreakable token, a horizontally-scrolling rail — would
       force the flex item wider than its allotted space, pushing the
       activity-stream sibling off-viewport and producing a horizontal
       scrollbar on the page. */
    min-width: 0;
    padding: 2rem;
    /* No artificial cap — fill the available column. Prose pages that
       want a narrow reading measure constrain themselves internally
       (e.g. `.learn-page` caps at 1200px; `.learn-section` at 72ch).
       The cap-everywhere-by-default was removed 2026-05-25 per the
       dogfood pass: ultra-wide displays were left with empty gutters. */
}
.main-content.main-content--full {
    max-width: none;
    padding: 1rem;
    /* Constrain the home/dashboard page to exactly the viewport
       height, then let the page-header take its natural height and
       the rail (or any other primary content) flex-fill the rest.
       Eliminates the double-scroll problem where both the column
       body AND the page itself were scrollable because the rail's
       height was a calc-guess rather than measured-fit. */
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.main-content.main-content--full > .page-header {
    flex: 0 0 auto;
}
.main-content.main-content--full > * {
    /* Last child of the flex column (typically the streams rail) gets
       the remaining height. `min-height: 0` is the "let me actually
       shrink below my content height" escape hatch flex needs to
       avoid pushing past the viewport. */
    min-height: 0;
}

/* Page header — canonical chrome.
 *
 * Every top-level page renders the same five-zone toolbar. The zones
 * read left-to-right in order of mental priority:
 *
 *   [ back ] [ title-block ] [ views ]      [ actions ] [ overflow ]
 *      ↑          ↑             ↑                ↑           ↑
 *      |          |             |                |           |
 *      nav      identity   view-switch    primary CTA(s)   meta-ops
 *
 *   - .page-header__back     — single back-nav link (← Foo). Optional.
 *   - .page-header__title    — h1 + optional status pill / page-meta.
 *   - .page-header__views    — segmented control (Cards/Narrative,
 *                              Sources/Collections, etc.). Optional.
 *   - .page-header__actions  — primary + secondary actions, RIGHT
 *                              edge (Draft Report, New Stream, …).
 *   - .page-header__overflow — destructive / rare CRUD (Rename,
 *                              Delete, Duplicate). Behind a `⋯` menu.
 *
 * Pages that don't have a back-nav simply omit `.page-header__back`;
 * the grid collapses cleanly. Same for any other zone. Don't invent
 * page-specific toolbar markup — extend the zones if a real new
 * affordance recurs across pages, otherwise keep it inside one of
 * the existing zones. See [[feedback_page_chrome_pattern]].
 */
.page-header {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}
.page-header h1 { font-size: 1.4rem; color: var(--white); }
.page-header__back {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.85rem;
    padding: 0.2rem 0.4rem;
    margin-left: -0.4rem;  /* visual gutter alignment */
    border-radius: 4px;
    transition: background 100ms ease, color 100ms ease;
}
.page-header__back:hover {
    background: var(--bg-elevated, rgba(255,255,255,0.06));
    color: var(--text);
}
.page-header__title {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-width: 0;  /* allow truncation in flex parents */
}
.page-header__title h1 {
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Inline subtitle alongside the h1 — single-line explanation of
 * what the page is. For pages where the secondary copy belongs
 * with the title rather than as a separate stacked row. */
.page-header__inline-meta {
    color: var(--text-muted);
    font-size: 0.8rem;
    max-width: 70ch;
    line-height: 1.4;
}
.page-header__views {
    display: inline-flex;
    align-items: center;
    background: var(--bg-elevated, rgba(255,255,255,0.04));
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 2px;
}
.page-header__view-btn {
    background: transparent;
    border: 0;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.82rem;
    padding: 0.25rem 0.7rem;
    border-radius: 4px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}
.page-header__view-btn:hover { color: var(--text); }
.page-header__view-btn.is-active {
    background: var(--bg-card);
    color: var(--white);
}
.page-header__spacer { flex: 1 1 auto; }
.page-header__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}
.page-header__overflow { position: relative; }
.page-header__overflow-btn {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 0.25rem 0.55rem;
    border-radius: 4px;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: background 100ms ease, color 100ms ease;
}
.page-header__overflow-btn:hover {
    background: var(--bg-elevated, rgba(255,255,255,0.06));
    color: var(--text);
}
.page-header__overflow-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    min-width: 180px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.28);
    padding: 4px;
    z-index: 50;
}
.page-header__overflow-item {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    padding: 0.4rem 0.6rem;
    border-radius: 4px;
    cursor: pointer;
}
.page-header__overflow-item:hover {
    background: var(--bg-elevated, rgba(255,255,255,0.06));
}
.page-header__overflow-item--danger { color: var(--danger, #f87171); }
.page-header__overflow-sep {
    height: 1px;
    background: var(--border);
    margin: 4px 0;
}
.page-meta { font-size: 0.75rem; color: var(--text-muted); }

/* Section */
.section { margin-bottom: 2rem; }
.section h2 { font-size: 0.95rem; color: var(--white); margin-bottom: 0.8rem; }

/* Stat cards */
.stat-cards {
    display: flex;
    gap: 1rem;
    margin-bottom: 2rem;
}
.stat-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.2rem 1.5rem;
    min-width: 140px;
}
.stat-value { font-size: 2rem; font-weight: 700; color: var(--accent); }
.stat-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }

/* Feed cards */
.feed-cards { display: flex; flex-direction: column; gap: 0.6rem; }
.feed-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    transition: border-color 0.15s;
}
.feed-card:hover { border-color: var(--border-hover); }
.feed-card-header { display: flex; justify-content: space-between; align-items: center; }
.feed-card-title { font-size: 0.9rem; font-weight: 600; color: var(--white); }
.feed-card-entries { font-size: 0.7rem; color: var(--text-muted); }
.feed-card-subtitle { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.2rem; }
.feed-card-actions { margin-top: 0.4rem; }

/* Empty state */
.empty-state {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--text-muted);
}
.empty-icon { font-size: 2.5rem; margin-bottom: 0.5rem; }
.empty-state h3 { font-size: 1.1rem; color: var(--white); margin-bottom: 0.3rem; }
.empty-state p { font-size: 0.85rem; margin-bottom: 1rem; }

/* Buttons */
.btn {
    background: var(--bg-hover);
    color: var(--text);
    border: 1px solid var(--border-hover);
    border-radius: 4px;
    padding: 0.3rem 0.8rem;
    font-size: 0.8rem;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn-small { font-size: 0.7rem; padding: 0.2rem 0.6rem; }
.btn-primary {
    background: var(--accent-hover);
    color: #fff;
    border-color: var(--accent-hover);
}
/* `.btn:hover` (above) sets `color: var(--accent)` for the secondary
   variant — but that selector also matches a primary button, which
   would then render accent-coloured text on an accent-coloured
   background (invisible). Pin the primary's text + border colours
   explicitly so the cascade can't fight us. */
.btn-primary:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
/* Disabled state — applies to both .btn and .btn-primary. Hover is
   suppressed too so the button doesn't tease an action it can't take. */
.btn:disabled,
.btn:disabled:hover {
    opacity: 0.45;
    cursor: not-allowed;
    border-color: var(--border);
    color: var(--text-muted);
}
.btn-primary:disabled,
.btn-primary:disabled:hover {
    background: var(--surface-alt);
    color: var(--text-muted);
}

/* Forms */
.form-field { margin-bottom: 1rem; }
.form-field label {
    display: block;
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
}
.form-field input {
    width: 100%;
    background: var(--border);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    color: var(--text);
    font-size: 0.9rem;
}
.form-field input:focus { outline: none; border-color: var(--accent); }
.form-field select, .form-select {
    width: 100%;
    background: var(--border);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    color: var(--text);
    font-size: 0.9rem;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%239ca3af' d='M2 4l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.8rem center;
    cursor: pointer;
}
.form-field select:focus { outline: none; border-color: var(--accent); }
.toggle-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text);
}
.toggle-label input[type="checkbox"] {
    width: auto;
    accent-color: var(--green);
}

/* System monitor tabs */
.system-tabs {
    display: flex;
    gap: 0.3rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.5rem;
}
.system-tab {
    padding: 0.4rem 0.8rem;
    font-size: 0.78rem;
    font-weight: 500;
    border-radius: 6px 6px 0 0;
    border: 1px solid transparent;
    border-bottom: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.system-tab:hover { color: var(--text); }
.system-tab.active { background: var(--bg-card); color: var(--white); border-color: var(--border); }
.system-tab-badge {
    font-size: 0.6rem;
    font-weight: 700;
    background: #7f1d1d;
    color: #fca5a5;
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    margin-left: 0.3rem;
}
.system-tab-panel { }

/* System monitor */
.system-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.system-table th {
    text-align: left; font-size: 0.65rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-dim); padding: 0.3rem 0.5rem;
    border-bottom: 1px solid var(--border);
}
.system-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); color: var(--text); }
.system-table tbody tr:hover { background: var(--bg-hover); }
.system-service-name { font-weight: 600; color: var(--white); font-family: monospace; }
.system-required-dot { color: var(--accent); font-size: 0.7rem; margin-left: 0.2rem; }
.system-mono { font-family: monospace; font-size: 0.75rem; color: var(--text-muted); }
.system-desc { color: var(--text-muted); font-size: 0.75rem; }
.system-status-badge {
    display: inline-block; font-size: 0.65rem; font-weight: 700;
    padding: 0.1rem 0.4rem; border-radius: 3px;
}
.system-status-badge.running { background: #064e3b; color: #6ee7b7; }
.system-status-badge.stopped { background: var(--border); color: var(--text-dim); }

.system-stats-row { display: flex; gap: 0.8rem; flex-wrap: wrap; }
.system-stat {
    background: var(--bg-hover); border-radius: 8px; padding: 0.7rem 1rem;
    min-width: 100px; text-align: center;
}
.system-stat-value { font-size: 1.4rem; font-weight: 700; color: var(--white); }
.system-stat-green { color: #6ee7b7; }
.system-stat-red { color: #fca5a5; }
.system-stat-label { font-size: 0.65rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 0.15rem; }

.system-section-label {
    font-size: 0.65rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--text-dim); margin-bottom: 0.4rem;
}
.system-group-card {
    background: var(--bg-hover); border-radius: 6px;
    padding: 0.5rem 0.7rem; margin-bottom: 0.4rem;
}
.system-group-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.3rem; }
.system-group-name { font-weight: 600; font-family: monospace; font-size: 0.8rem; color: var(--white); }
.system-pending-badge {
    font-size: 0.6rem; font-weight: 700; padding: 0.1rem 0.35rem;
    border-radius: 3px; background: #7f1d1d; color: #fca5a5;
}
.system-pending-badge.small { font-size: 0.55rem; padding: 0.05rem 0.25rem; }
.system-consumer {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.15rem 0 0.15rem 0.8rem; font-size: 0.75rem;
}
.system-consumer-name { font-family: monospace; color: var(--text); }
.system-consumer-idle { color: var(--text-dim); font-size: 0.7rem; }

.system-event-types { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.system-event-type {
    display: flex; align-items: center; gap: 0.3rem;
    background: var(--bg-hover); border-radius: 4px; padding: 0.2rem 0.5rem;
}
.system-event-type-name { font-family: monospace; font-size: 0.7rem; color: var(--text); }
.system-event-type-count { font-size: 0.65rem; font-weight: 700; color: var(--text-muted); }

.system-error-card {
    background: #1a0a0a;
    border: 1px solid #451a1a;
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.4rem;
}
.system-error-card-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.2rem;
}
.system-error-source-link {
    color: var(--white);
    font-weight: 600;
    font-size: 0.8rem;
    text-decoration: none;
}
.system-error-source-link:hover { color: var(--accent); }
.system-error-message {
    font-size: 0.78rem;
    color: #fca5a5;
    line-height: 1.4;
    margin-bottom: 0.2rem;
}
.system-error-msg {
    font-size: 0.72rem;
    color: #fca5a5;
    max-width: 300px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.system-error-msg:hover { white-space: normal; overflow: visible; }
.system-failure-count {
    font-weight: 700;
    color: #fca5a5;
    font-size: 0.85rem;
}

/* Source article list */
.source-article-list { display: flex; flex-direction: column; gap: 0.2rem; }
.source-article-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0;
    font-size: 0.8rem;
    border-bottom: 1px solid var(--border);
}
.source-article-item:last-child { border-bottom: none; }
.source-article-title {
    color: var(--text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
.source-article-title:hover { color: var(--accent); }
.source-article-date {
    font-size: 0.7rem;
    color: var(--text-dim);
    flex-shrink: 0;
    font-family: monospace;
}

.source-filter-add-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}
.source-filter-input {
    flex: 1;
    background: var(--border);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    color: var(--text);
    font-size: 0.85rem;
}
.source-filter-input:focus { outline: none; border-color: var(--accent); }
.title-filter-entries { display: flex; flex-direction: column; gap: 0.4rem; }
.title-filter-entry {
    background: var(--bg-hover);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
}
.title-filter-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.title-filter-pattern { font-size: 0.85rem; font-weight: 600; color: var(--white); }
.title-filter-count {
    font-size: 0.65rem;
    color: var(--text-muted);
    background: var(--border);
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
}
.title-filter-remove {
    background: none;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0 0.2rem;
}
.title-filter-remove:hover { color: #fca5a5; }
.title-filter-matches { margin-top: 0.4rem; }
.title-filter-matches-toggle {
    font-size: 0.7rem;
    color: var(--text-dim);
    cursor: pointer;
    list-style: none;
}
.title-filter-matches-toggle::-webkit-details-marker { display: none; }
.title-filter-matches-toggle::before { content: '+ '; }
.title-filter-matches[open] .title-filter-matches-toggle::before { content: '- '; }
.title-filter-matches-toggle:hover { color: var(--text-muted); }
.title-filter-match-list { margin-top: 0.3rem; }
.title-filter-match {
    padding: 0.15rem 0;
    font-size: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}
.title-filter-match-title { color: var(--text); }
.title-filter-match-url { color: var(--text-dim); font-size: 0.65rem; }

.system-pipeline-status {
    font-size: 0.6rem;
    font-weight: 700;
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
    text-transform: uppercase;
}
.system-pipeline-status.gate_failed { background: #7f1d1d; color: #fca5a5; }
.system-pipeline-status.failed { background: #4a1d1d; color: var(--red); }

/* Activity feed */
.activity-feed { display: flex; flex-direction: column; }
.activity-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.3rem 0;
    font-size: 0.75rem;
    border-bottom: 1px solid var(--border);
}
.activity-item:last-child { border-bottom: none; }
.activity-group-summary {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.2rem 0; font-size: 0.75rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-hover); padding-left: 0.3rem; border-radius: 3px;
}
.activity-group-count {
    display: inline-block; background: var(--accent); color: var(--bg);
    font-size: 0.6rem; font-weight: 700; padding: 0.1rem 0.4rem;
    border-radius: 8px;
}
.activity-time {
    font-family: monospace;
    font-size: 0.7rem;
    color: var(--text-dim);
    flex-shrink: 0;
    width: 55px;
    margin-right: 0.45rem;
}
.activity-type {
    font-size: 0.6rem;
    font-weight: 600;
    padding: 0.15rem 0.45rem;
    border-radius: 3px;
    flex-shrink: 0;
    white-space: nowrap;
    min-width: fit-content;
}
.activity-type-article { background: #1e3a5f; color: #93c5fd; }
.activity-type-task { background: var(--border); color: var(--text-muted); }
.activity-type-pipeline { background: #064e3b; color: #6ee7b7; }
.activity-type-collection { background: #78350f; color: #fcd34d; }
.activity-detail {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
.activity-source {
    font-size: 0.65rem;
    color: var(--text-dim);
    flex-shrink: 0;
}
.activity-extra {
    font-size: 0.65rem;
    color: var(--text-muted);
    font-family: monospace;
    flex-shrink: 0;
}

/* Security events */
.security-ip-list { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.security-ip-item {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--bg-hover);
    border-radius: 4px;
    padding: 0.2rem 0.5rem;
    font-size: 0.78rem;
}
.security-ip { font-family: monospace; color: var(--white); font-weight: 600; }
.security-ip-count { font-size: 0.65rem; color: var(--text-muted); }
.security-type-badge {
    font-size: 0.6rem;
    font-weight: 600;
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
    background: #7f1d1d;
    color: #fca5a5;
    white-space: nowrap;
}

/* Mastodon queue */
.mastodon-queue-list { display: flex; flex-direction: column; }
.mastodon-queue-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}
.mastodon-queue-item:last-child { border-bottom: none; }
.mastodon-queue-info { flex: 1; min-width: 0; }
.mastodon-queue-title { font-size: 0.85rem; color: var(--white); }
.mastodon-queue-meta {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.15rem;
    flex-wrap: wrap;
}
.queue-checkbox { width: auto; accent-color: var(--green); flex-shrink: 0; }

.system-refresh-bar {
    display: flex; align-items: center; gap: 0.5rem;
    font-size: 0.7rem; color: var(--text-dim);
}
.system-refresh-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--amber); display: inline-block;
    transition: background 0.2s;
}
@keyframes fadeIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: translateY(0); } }

/* Login page */
.login-body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: var(--bg);
}
.login-container { width: 100%; max-width: 380px; padding: 1rem; }
.login-brand {
    text-align: center;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--accent);
    margin-bottom: 2rem;
}
.login-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 2rem;
}
.login-card h2 {
    font-size: 1.1rem;
    color: var(--white);
    text-align: center;
    margin-bottom: 1.5rem;
}
.login-error {
    color: var(--red);
    font-size: 0.8rem;
    text-align: center;
    margin-bottom: 1rem;
}
.btn-login {
    width: 100%;
    padding: 0.6rem;
    background: var(--accent-hover);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    margin-top: 0.5rem;
}
.btn-login:hover { background: var(--accent); }
.btn-passkey {
    background: var(--bg-hover); border: 1px solid var(--border); color: var(--text);
}
.btn-passkey:hover { background: #334155; }
.login-footer {
    text-align: center;
    margin-top: 1.5rem;
}
.login-footer a { color: var(--text-muted); font-size: 0.8rem; text-decoration: none; }
.login-footer a:hover { color: var(--accent); }

/* Tags */
.tag-pill {
    font-size: 0.65rem;
    padding: 0.1rem 0.4rem;
    background: var(--border);
    color: var(--text-muted);
    border-radius: 3px;
    display: inline-block;
}
.tag-pill.small { font-size: 0.6rem; }

/* Card sections */
.card-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.2rem;
    margin-bottom: 1rem;
}
.card-section h2 { font-size: 0.85rem; color: var(--white); margin-bottom: 0.6rem; }
.card-section-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 0.8rem;
}
.maintenance-task {
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border);
}
.maintenance-task:last-child { border-bottom: none; }
.maintenance-task-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.8rem;
    margin-bottom: 0.3rem;
}
.maintenance-task-name {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 0.1rem;
}
.section-hint { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.8rem; }

/* Form helpers */
.form-row { display: flex; gap: 1rem; margin-bottom: 0.8rem; flex-wrap: wrap; }
.form-actions { margin-top: 1rem; }
.inline-form-row { display: flex; gap: 0.8rem; align-items: flex-end; }
.muted { color: var(--text-dim) !important; }

/* App-wide form-input theme (added 2026-05-15). Before this, every
   form template rolled its own and most relied on browser defaults
   that vanished against the page background in dark mode. The rule
   below is scoped to `.form-row` so legacy bespoke inputs elsewhere
   keep their existing styling — opt-in by class. */
.form-row input[type="text"],
.form-row input[type="email"],
.form-row input[type="password"],
.form-row input[type="number"],
.form-row input[type="search"],
.form-row input[type="url"],
.form-row select,
.form-row textarea,
.form-input {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.5rem 0.65rem;
    color: var(--text);
    font: inherit;
    font-size: 0.9rem;
    line-height: 1.4;
    width: 100%;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.form-row input[type="text"]:hover,
.form-row input[type="email"]:hover,
.form-row input[type="password"]:hover,
.form-row input[type="number"]:hover,
.form-row input[type="search"]:hover,
.form-row input[type="url"]:hover,
.form-row select:hover,
.form-row textarea:hover,
.form-input:hover {
    border-color: var(--border-hover);
}
.form-row input[type="text"]:focus,
.form-row input[type="email"]:focus,
.form-row input[type="password"]:focus,
.form-row input[type="number"]:focus,
.form-row input[type="search"]:focus,
.form-row input[type="url"]:focus,
.form-row select:focus,
.form-row textarea:focus,
.form-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent);
}
.form-row input[disabled],
.form-row select[disabled],
.form-row textarea[disabled],
.form-input[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}
.form-row textarea, .form-input textarea { resize: vertical; min-height: 5rem; }
.form-row label {
    display: block;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    margin-bottom: 0.25rem;
}
.form-row .form-help, .form-help {
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
    line-height: 1.4;
}
.form-help code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    background: var(--bg-hover);
    color: var(--text);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
}
.form-row.form-row--block { flex-direction: column; align-items: stretch; }
.form-row.form-row--inline-checkbox { flex-direction: row; align-items: center; gap: 0.5rem; }
.form-row.form-row--inline-checkbox label { margin-bottom: 0; text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 0.85rem; color: var(--text); }
.form-status { font-size: 0.85rem; color: var(--text-muted); }
.form-status--error { color: var(--red); }
.form-status--ok { color: var(--green); }
fieldset.form-row {
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.85rem 1rem 1rem;
    background: color-mix(in srgb, var(--bg-card) 60%, transparent);
}
fieldset.form-row legend {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    padding: 0 0.35rem;
}

/* Checkbox */
.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--text);
    cursor: pointer;
    padding: 0.3rem 0;
}
.checkbox-label input[type="checkbox"] { accent-color: var(--accent); }
.category-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.2rem; }

/* Feed URL */
.feed-url-row { display: flex; gap: 0.5rem; }
.feed-url-row input { flex: 1; }
.feed-card-cats { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-top: 0.3rem; }

/* Search */
.search-bar { display: flex; gap: 0.8rem; margin-bottom: 1.5rem; }
.search-bar input { flex: 1; background: var(--border); border: 1px solid var(--border-hover); border-radius: 6px; padding: 0.6rem 0.8rem; color: var(--text); font-size: 0.9rem; }
.search-bar input:focus { outline: none; border-color: var(--accent); }
.search-advanced { margin-bottom: 1rem; }
.search-advanced-toggle {
    font-size: 0.7rem;
    color: var(--text-dim);
    cursor: pointer;
    list-style: none;
}
.search-advanced-toggle::-webkit-details-marker { display: none; }
.search-advanced-toggle::before { content: '+ '; }
.search-advanced[open] .search-advanced-toggle::before { content: '- '; }
.search-advanced-toggle:hover { color: var(--text-muted); }
.search-advanced-options {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-top: 0.5rem;
    padding: 0.6rem 0.8rem;
    background: var(--bg-hover);
    border-radius: 6px;
}
.search-option {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    color: var(--text);
    cursor: pointer;
    flex-wrap: wrap;
}
.search-option input[type="checkbox"] { width: auto; accent-color: var(--green); }
.search-option-hint {
    font-size: 0.7rem;
    color: var(--text-dim);
    width: 100%;
    padding-left: 1.4rem;
    margin-top: -0.2rem;
}
.results-count { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 1rem; }

/* Articles */
.article-list { display: flex; flex-direction: column; gap: 0.4rem; }
.article-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.article-card summary {
    padding: 0.7rem 1rem;
    cursor: pointer;
    list-style: none;
}
.article-card summary::-webkit-details-marker { display: none; }
.article-card[open] { border-color: var(--border-hover); }
.article-title { font-size: 0.85rem; color: var(--white); font-weight: 500; margin-bottom: 0.2rem; }
.article-meta { display: flex; gap: 0.5rem; align-items: center; }
.article-date { font-size: 0.65rem; color: var(--text-dim); }
.article-detail { padding: 0 1rem 0.8rem; }
.article-summary { font-size: 0.8rem; color: var(--text); line-height: 1.5; margin-bottom: 0.5rem; }
.article-tags { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-bottom: 0.5rem; }
.article-link { font-size: 0.8rem; color: var(--accent); text-decoration: none; }
.article-link:hover { text-decoration: underline; }

/* Sources */
.sources-toolbar { display: flex; gap: 0.8rem; align-items: center; margin-bottom: 0.5rem; }
.sources-toolbar .search-bar { margin-bottom: 0; }
.search-dropdown-item {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.5rem 0.8rem; cursor: pointer;
    border-bottom: 1px solid var(--border);
    text-decoration: none; color: var(--text);
}
.search-dropdown-item:hover { background: var(--bg-hover); }
.search-dropdown-new {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.5rem 0.8rem; cursor: pointer;
    border-bottom: 1px solid var(--border);
}
.search-dropdown-new:hover { background: var(--bg-hover); }
.search-dropdown-new:last-child, .search-dropdown-item:last-child { border-bottom: none; }
.source-filter-details { margin-bottom: 1rem; }
.source-filter-toggle {
    font-size: 0.7rem;
    color: var(--text-dim);
    cursor: pointer;
    list-style: none;
}
.source-filter-toggle::-webkit-details-marker { display: none; }
.source-filter-toggle::before { content: '+ '; }
.source-filter-details[open] .source-filter-toggle::before { content: '- '; }
.source-filter-toggle:hover { color: var(--text-muted); }
.source-filter-options {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.4rem;
}
.source-filter-btn {
    padding: 0.25rem 0.6rem;
    font-size: 0.7rem;
    font-weight: 500;
    border-radius: 4px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.source-filter-btn:hover { border-color: var(--border-hover); color: var(--text); }
.source-filter-btn.active { background: var(--bg-hover); color: var(--white); border-color: var(--border-hover); }
.add-collection-info {
    background: var(--bg-hover);
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.8rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.source-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.6rem; }
.source-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem 0.8rem;
    text-decoration: none;
    display: block;
    transition: border-color 0.15s;
}
.source-card:hover { border-color: var(--accent); }
.source-card-header { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.3rem; }
.source-card-icon { width: 20px; height: 20px; border-radius: 3px; flex-shrink: 0; }
.source-card { position: relative; }
.source-card-name { font-size: 0.85rem; font-weight: 500; color: var(--white); }
.source-status-icon {
    position: absolute;
    top: 0.4rem;
    right: 0.5rem;
    font-size: 0.6rem;
    width: 14px;
    height: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
}
.source-status-icon.valid { color: var(--green); }
.source-status-icon.warn { color: var(--amber); }
.source-status-icon.invalid { color: var(--red); }
.source-status-icon.stale-feed { color: var(--amber); }
.source-status-icon.unchecked { color: var(--text-dim); font-size: 0.55rem; }
.source-card-url { font-size: 0.65rem; color: var(--text-dim); display: block; word-break: break-all; }
.source-archived { opacity: 0.45; }
.system-stat.clickable { cursor: pointer; transition: border-color 0.15s; border: 1px solid transparent; border-radius: 8px; }
.system-stat.clickable:hover { border-color: var(--accent); }
.source-archived:hover { opacity: 0.7; }

/* Source detail */
.source-detail-header { display: flex; gap: 0.8rem; align-items: center; margin-bottom: 1.2rem; }
.source-detail-icon { width: 40px; height: 40px; border-radius: 6px; flex-shrink: 0; }
.source-detail-url { font-size: 0.8rem; color: var(--accent); text-decoration: none; }
.source-detail-url:hover { text-decoration: underline; }

/* Textarea */
.form-textarea {
    width: 100%;
    background: var(--border);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
    resize: vertical;
}
.form-textarea:focus { outline: none; border-color: var(--accent); }

.url-field-row { display: flex; gap: 0.5rem; }
.url-field-row input { flex: 1; }

/* Source validation */
.validate-progress {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    padding: 0.3rem 0;
}
.validate-spinner {
    width: 14px;
    height: 14px;
    border: 2px solid var(--border-hover);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }
.validate-elapsed {
    font-size: 0.7rem;
    color: var(--text-dim);
    margin-left: auto;
    font-family: monospace;
}
.validate-status { font-size: 0.85rem; font-weight: 600; margin-bottom: 0.3rem; }
.validate-status.valid { color: var(--green); }
.validate-status.invalid { color: var(--red); }
.validate-type { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.4rem; }
.validate-status.warn { color: var(--amber); }
.validate-hint { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.5rem; }
.validate-error { font-size: 0.8rem; color: var(--red); }
.validate-suggestions { margin-top: 0.6rem; }
.validate-suggestion-label { font-size: 0.7rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.4rem; }
.validate-suggestion { background: var(--bg-hover); border-radius: 6px; padding: 0.6rem; margin-bottom: 0.4rem; }
.validate-suggestion-header { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.2rem; }
.validate-suggestion-title { font-size: 0.85rem; font-weight: 500; color: var(--white); }
.validate-suggestion-url { font-size: 0.65rem; color: var(--text-dim); word-break: break-all; margin-bottom: 0.3rem; }

/* Collection log */
.collection-log-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
}
.collection-log-table th {
    text-align: left;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    padding: 0.3rem 0.5rem;
    border-bottom: 1px solid var(--border);
}
.collection-log-table td {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    vertical-align: top;
}
.collection-log-table tbody tr:hover { background: var(--bg-hover); }
.collection-time { color: var(--text-muted); white-space: nowrap; }
.collection-duration { color: var(--text-muted); white-space: nowrap; }
.collection-error { color: var(--red); font-size: 0.72rem; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.collection-error:hover { white-space: normal; overflow: visible; }
.collection-status-badge {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 700;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
}
.collection-status-badge.success { background: #064e3b; color: #6ee7b7; }
.collection-status-badge.unchanged { background: #1e3a5f; color: #93c5fd; }
.collection-status-badge.error { background: #7f1d1d; color: #fca5a5; }

/* Collection entries */
.collection-entries-row td { padding: 0; border-bottom: 1px solid var(--border); }
.collection-entries-details { padding: 0.2rem 0.5rem 0.4rem; }
.collection-entries-summary {
    font-size: 0.7rem;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.2rem 0;
}
.collection-entries-summary:hover { color: var(--accent); }
.collection-entries { padding: 0.2rem 0; }
.collection-entry {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.15rem 0;
    font-size: 0.75rem;
}
.collection-entry-badge {
    font-size: 0.6rem;
    font-weight: 700;
    padding: 0.05rem 0.3rem;
    border-radius: 2px;
    flex-shrink: 0;
}
.collection-entry.new .collection-entry-badge { background: #064e3b; color: #6ee7b7; }
.collection-entry.known .collection-entry-badge { background: var(--border); color: var(--text-dim); }
.collection-entry-link {
    color: var(--text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.collection-entry-link:hover { color: var(--accent); }
.collection-entry.known .collection-entry-link { color: var(--text-muted); }

/* Selector discovery */
.selector-code {
    font-family: monospace;
    font-size: 0.78rem;
    background: var(--bg-hover);
    padding: 0.15rem 0.4rem;
    border-radius: 3px;
    color: #93c5fd;
}
.selector-samples { margin-top: 0.3rem; }
.selector-sample { font-size: 0.75rem; padding: 0.1rem 0; }
.selector-sample-link { color: var(--text-muted); text-decoration: none; }
.selector-sample-link:hover { color: var(--accent); }

/* Enrich */
.enrich-fields { display: flex; flex-direction: column; gap: 0.5rem; }
.enrich-field { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.enrich-label { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); width: 80px; flex-shrink: 0; }
.enrich-value { font-size: 0.85rem; color: var(--white); flex: 1; }
.enrich-desc { font-size: 0.8rem; color: var(--text); }
.enrich-signals { font-size: 0.7rem; color: var(--text-dim); }
.validate-articles { display: flex; flex-direction: column; gap: 0.2rem; }
.validate-article { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; padding: 0.2rem 0; }
.validate-article-title { font-size: 0.8rem; color: var(--accent); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.validate-article-title:hover { text-decoration: underline; }
.validate-article-date { font-size: 0.65rem; color: var(--text-dim); white-space: nowrap; flex-shrink: 0; }

/* Alerts */
.alert {
    padding: 0.6rem 1rem;
    border-radius: 6px;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}
.alert-error { background: #1a0a0a; border: 1px solid #7f1d1d; color: var(--red); }
.alert-success { background: #0a1a0f; border: 1px solid #064e3b; color: var(--green); }
.alert-warn { background: #1a1400; border: 1px solid #78350f; color: var(--amber); }
.alert-exists { background: #1a1400; border: 1px solid #78350f; color: var(--amber); display: flex; align-items: center; flex-wrap: wrap; gap: 0.3rem; }

/* Light-theme alert overrides — the dark-theme defaults above use
   near-black backgrounds with bright accent text, which on light bg
   land as opaque dark blocks with poor contrast. Re-tint to tinted
   surfaces with darker accent text for adequate contrast. */
body.light .alert-error { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
body.light .alert-success { background: #f0fdf4; border-color: #bbf7d0; color: #166534; }
body.light .alert-warn { background: #fffbeb; border-color: #fde68a; color: #92400e; }
body.light .alert-exists { background: #fffbeb; border-color: #fde68a; color: #92400e; }

/* Article filter tabs (legacy class kept for the few pages still
   using it; new Articles surface uses .article-filter-bar below). */
.article-filters {
    display: flex;
    gap: 0.3rem;
    margin-bottom: 1rem;
}
.filter-tab {
    padding: 0.4rem 0.8rem;
    font-size: 0.78rem;
    font-weight: 500;
    border-radius: 6px;
    border: 1px solid var(--border);
    color: var(--text-muted);
    text-decoration: none;
    transition: all 0.15s;
}
.filter-tab:hover { border-color: var(--border-hover); color: var(--text); }
.filter-tab.active { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.filter-tab.small { padding: 0.25rem 0.6rem; font-size: 0.68rem; }

/* Modern filter bar — chips left, sort segment + toggles right.
   Used by /app/articles after the dogfood UX pass; pattern is reusable
   on any list page with one primary filter axis + secondary options. */
.article-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin-bottom: 0.9rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--border);
}
.article-filter-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.article-filter-meta {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 0.4rem;
    margin-left: auto;
}
.filter-chip {
    display: inline-flex; align-items: center;
    height: 26px;
    padding: 0 0.65rem;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--text-muted);
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 999px;
    text-decoration: none;
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.filter-chip:hover {
    color: var(--text);
    border-color: var(--border-hover);
    background: var(--bg-hover);
}
.filter-chip.is-active {
    background: var(--accent);
    color: var(--bg);
    border-color: var(--accent);
}
.filter-chip--toggle {
    font-size: 0.7rem;
}
.filter-chip--toggle.is-active {
    /* Warm tint when on — signals "you've widened the view past the
       safe default", not "this is the primary filter selection". */
    background: rgba(245, 158, 11, 0.18);
    color: #fbbf24;
    border-color: rgba(245, 158, 11, 0.45);
}
body.light .filter-chip--toggle.is-active {
    background: #fffbeb; color: #b45309; border-color: #fde68a;
}

/* Segmented control for sort. Two pills sharing one rounded shell. */
.article-filter-segment {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: 999px;
    overflow: hidden;
}
.segment-btn {
    padding: 0 0.7rem;
    height: 26px;
    display: inline-flex; align-items: center;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-muted);
    background: transparent;
    text-decoration: none;
    border-right: 1px solid var(--border);
    transition: background 120ms ease, color 120ms ease;
}
.segment-btn:last-child { border-right: none; }
.segment-btn:hover { color: var(--text); background: var(--bg-hover); }
.segment-btn.is-active {
    background: var(--accent);
    color: var(--bg);
}

/* Status dot — tiny coloured circle that replaces the row of pills.
   Sits to the left of the article title; hover surfaces the verbose
   underlying status verbatim via `title=…`. */
.status-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    margin-right: 0.55rem;
    vertical-align: middle;
    flex-shrink: 0;
}
.status-dot--green  { background: #10b981; box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.18); }
.status-dot--orange { background: var(--amber); box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18); }
.status-dot--red    { background: #ef4444; box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.18); }
.status-dot--grey   { background: var(--text-muted); box-shadow: 0 0 0 2px rgba(107, 114, 128, 0.18); }

/* Article list — day-grouped, single-line rows. Pattern:
       TODAY
       •  source.com  Title (bold)  Summary snippet...      15:28
       •  source.com  Title (bold)  Summary snippet...      14:02
       YESTERDAY
       •  source.com  Title (bold)  Summary snippet...      22:14
   Source / title / snippet share one truncatable row; the time is
   pinned right. Click anywhere on the row to expand the detail. */
.article-list { display: flex; flex-direction: column; }

.day-header {
    margin: 1.1rem 0 0.4rem;
    padding: 0 0.2rem 0.3rem;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
.day-header:first-child { margin-top: 0.2rem; }

.article-row {
    border-bottom: 1px solid var(--border);
    transition: background 100ms ease;
}
.article-row:hover { background: var(--bg-hover); }
.article-row[open] { background: var(--bg-hover); }

.article-row__summary {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.5rem;
    cursor: pointer;
    list-style: none;
    min-width: 0;
}
.article-row__summary::-webkit-details-marker { display: none; }

.article-row__favicon {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    border-radius: 3px;
    object-fit: contain;
    /* Hidden by JS onerror when the source doesn't expose
       /favicon.ico; keeps the layout slot intact (visibility:hidden,
       not display:none) so titles stay aligned. */
}

.article-row__source {
    /* Fixed-width column so titles align across rows regardless of
       source-domain length. 20ch fits long-tail domains like
       `krebsonsecurity.com` (16ch) with a little headroom; longer
       hosts get ellipsis. */
    flex: 0 0 20ch;
    width: 20ch;
    font-size: 0.78rem;
    color: var(--text-muted);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.article-row__title {
    /* Title gets priority over the snippet — natural content width up
       to a generous cap (no truncation until the title is really
       long). `flex: 0 1 auto` keeps the title at its natural size but
       lets it shrink if absolutely needed. `min-width: 6ch` keeps the
       title from collapsing to nothing on extremely wide snippets.
       No longer a link — clicking the row toggles expansion. The
       "Open article →" button in the expanded panel handles
       navigation. */
    flex: 0 1 auto;
    min-width: 6ch;
    color: var(--text);
    font-weight: 700;
    font-size: 0.86rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.article-row__snippet {
    /* Snippet fills the remaining horizontal space and shrinks
       (ellipsis) before the title does. `min-width: 0` is required
       for flex children to actually shrink below their text content. */
    flex: 1 1 0;
    min-width: 0;
    color: var(--text-muted);
    font-size: 0.82rem;
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.entry-detail-actions {
    /* Primary action row in the expanded Incoming row. Default
       variant (--footer) sits at the bottom of the expanded view,
       below all the metadata / summary / pipeline-state content,
       so the user reads the article context before deciding where
       to go next. */
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.entry-detail-actions--footer {
    /* Footer placement — pad the top so it visually separates from
       whatever section ended above (summary, content preview, etc).
       Border-top is intentional: it reads as a closing rail rather
       than another inline content block. */
    margin: 1rem 0 0;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
}
.entry-detail-actions__external {
    background: transparent;
    color: var(--text-muted);
    border-color: var(--border);
}
.entry-detail-actions__external:hover {
    color: var(--text);
    border-color: var(--border-hover);
}


.article-row__time {
    flex-shrink: 0;
    font-size: 0.74rem;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Article state badges */
.article-state-badge {
    display: inline-block;
    font-size: 0.55rem;
    font-weight: 600;
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    vertical-align: middle;
}
.article-state-badge.approved { background: #064e3b; color: #6ee7b7; }
.article-state-badge.rejected { background: #7f1d1d; color: #fca5a5; }
.article-state-badge.unprocessed { background: #78350f; color: #fcd34d; }
.article-state-badge.skipped { background: var(--bg-hover); color: #94a3b8; }

/* View-only banner — rendered above any editor surface where the
   calling user lacks write permission on the resource. Driven by
   the unified GET /api/auth/me/permissions endpoint via the
   _macros/view_mode_banner.html macro. */
.view-mode-banner {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.7rem 1rem;
    margin: 0 0 1rem 0;
    background: rgba(245, 158, 11, 0.08);
    border: 1px solid rgba(245, 158, 11, 0.45);
    border-left: 4px solid var(--amber);
    border-radius: 4px;
    color: var(--text);
    font-size: 0.85rem;
    line-height: 1.5;
}
.view-mode-icon {
    font-size: 1.05rem;
    line-height: 1;
    color: var(--amber);
}
.view-mode-text strong { color: var(--amber); }
.view-mode-reason {
    color: var(--text-dim);
    font-size: 0.78rem;
    margin-left: 0.3rem;
}

/* When an editor surface is in view-only mode, neutralise every
   primary-button + form-input visually so the user can browse
   without misleading affordances. Pages opt in by adding
   `view-mode-readonly` to the root container; the rules below match
   every button (except a few opt-out classes) and every input /
   textarea / select inside it. The Test Pipeline button keeps its
   color since reading is still allowed; Save/Clear/Delete-style
   actions are visibly muted. */
.view-mode-readonly button:not(.view-mode-allow):not([type=button][onclick*="close"]):not(.btn-small) {
    opacity: 0.45 !important;
    cursor: not-allowed !important;
    filter: grayscale(40%);
}
.view-mode-readonly button:not(.view-mode-allow):not(.btn-small):hover {
    background: inherit !important;
}
/* HTML disabled attribute already prevents clicks; this enforces
   the same on JS-driven buttons that bypass the disabled attr. */
.view-mode-readonly button[disabled] {
    pointer-events: none;
}
.view-mode-readonly input:not([type=button]):not([type=submit]),
.view-mode-readonly textarea,
.view-mode-readonly select {
    background: rgba(255,255,255,0.02) !important;
    color: var(--text-dim) !important;
    cursor: not-allowed !important;
}
/* Pipeline builder needs canvas pan + wheel zoom to work even in
   view-only mode (read-only is "look around freely"); only the
   nodes/ports/palette become non-interactive. */
.view-mode-readonly .pb-chip { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.view-mode-readonly .pb-port { pointer-events: none; opacity: 0.5; }
.view-mode-readonly .pb-node-header { cursor: default; }

/* Column-aligned summary rows for `.entry-list` cards. Used by the
   Tasks list and Pipelines list so Name / Scope pill / Description
   align vertically across rows — short names no longer drag the pill
   leftward. The header row above the `.entry-list` shares the same
   grid template so labels line up with data.

   Version was removed from the folded summary 2026-04-27 — visible
   inside the expanded card only. Reduces row noise; analysts scan
   by name + scope, not version. */
.entry-list-header,
.entry-cols {
    display: grid;
    grid-template-columns:
        minmax(180px, 1.4fr)   /* name */
        90px                    /* scope pill */
        minmax(0, 2.4fr);       /* description (truncates) */
    gap: 1rem;
    align-items: center;
}
.entry-list-header {
    padding: 0.45rem 0.85rem;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 700;
    color: var(--text-dim);
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.25rem;
}
.entry-cols {
    padding: 0.6rem 0.85rem;
}
.entry-col-name {
    font-weight: 600;
    font-size: 0.88rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.entry-col-pill {
    display: flex;
    align-items: center;
}
.entry-col-version {
    font-size: 0.72rem;
    color: var(--text-dim);
}
.entry-col-desc {
    font-size: 0.78rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Hidden-row classes for the Tasks list. The page is rendered with
   every row in the DOM; the filter (search/scope) and the paginator
   (page-size + page-number) each set their own hide flag, and a row
   is invisible if either flag is set. Independent classes mean the
   two concerns don't fight — the filter doesn't have to know what
   page is current, and the paginator doesn't have to track the
   filter's state. */
.entry-item.row-filtered,
.entry-item.row-paged {
    display: none;
}

/* Per-group paginator strip — sits below each group's rows (or below
   the rendered page count when the group is short). Populated
   client-side by paginateTasks(). Hidden until JS runs and decides
   whether more than one page is needed. */
.entry-paginator {
    display: none;
    align-items: center;
    gap: 0.4rem;
    margin: 0.5rem 0 0.8rem;
    padding-left: 0.85rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}
.entry-paginator.has-pages {
    display: flex;
    flex-wrap: wrap;
}
.entry-paginator-info {
    margin-right: 0.5rem;
    color: var(--text-dim);
}
.entry-paginator-btn {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 0.2rem 0.55rem;
    font-size: 0.72rem;
    cursor: pointer;
    line-height: 1.4;
    user-select: none;
}
.entry-paginator-btn:hover:not([disabled]) {
    border-color: var(--accent);
    color: var(--accent);
}
.entry-paginator-btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}
.entry-paginator-btn.active {
    background: rgba(96, 165, 250, 0.15);
    color: var(--accent);
    border-color: var(--accent);
}

/* Storage / scope pills — used on the Tasks list and admin Pipelines
   list to flag DB-vs-YAML storage and SYSTEM-vs-ORG ownership at a
   glance. Was previously inline in admin_pipelines.html, lifted to
   the global stylesheet so the new /app/tasks page (and any future
   list view that surfaces task/pipeline rows) gets the same
   colour-coding for free. */
.pb-storage-pill {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 3px;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.4;
    white-space: nowrap;
}
.pb-pill-yaml {
    background: rgba(245, 158, 11, 0.15);
    color: #fbbf24;
    border: 1px solid rgba(245, 158, 11, 0.4);
}
.pb-pill-db {
    background: rgba(96, 165, 250, 0.15);
    color: var(--accent);
    border: 1px solid rgba(96, 165, 250, 0.4);
}
.pb-pill-org {
    background: rgba(168, 85, 247, 0.15);
    color: #c084fc;
    border: 1px solid rgba(168, 85, 247, 0.4);
}
.pb-pill-system {
    background: rgba(52, 211, 153, 0.12);
    color: var(--green);
    border: 1px solid rgba(52, 211, 153, 0.4);
}

/* DD-019 baseline-status pill — used on article detail + list cards.
   Color-coded so admins can scan the queue at a glance: complete (green),
   legacy (blue), pending (yellow), rejected (red), failed (orange). */
.baseline-pill {
    display: inline-block;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 700;
    padding: 0.12rem 0.45rem;
    border-radius: 3px;
    border: 1px solid var(--border);
    background: var(--surface-alt);
    color: var(--text-muted);
    font-family: monospace;
    line-height: 1.4;
}
.baseline-pill-complete { color: #6ee7b7; border-color: rgba(16,185,129,0.4); background: rgba(16,185,129,0.08); }
.baseline-pill-legacy   { color: #93c5fd; border-color: rgba(59,130,246,0.4); background: rgba(59,130,246,0.08); }
.baseline-pill-pending  { color: #fcd34d; border-color: rgba(245,158,11,0.4); background: rgba(245,158,11,0.08); }
.baseline-pill-rejected { color: #fca5a5; border-color: rgba(239,68,68,0.4); background: rgba(239,68,68,0.08); }
.baseline-pill-failed   { color: #fbbf24; border-color: rgba(245,158,11,0.5); background: rgba(245,158,11,0.12); }

/* Article-state pill — compact dot + label. Used to surface two
   independent dimensions (baseline outcome + customer pipeline
   outcome) without the visual weight of the legacy baseline-pill.
   The colored dot is the at-a-glance signal; the label is the
   precise meaning. Two pills can sit side-by-side without competing
   with surrounding metadata. */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.6rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 0.08rem 0.4rem;
    border-radius: 2px;
    line-height: 1.4;
    color: var(--text-dim);
    background: rgba(255,255,255,0.02);
    border: 1px solid rgba(255,255,255,0.06);
    text-transform: none;
    white-space: nowrap;
}
.pill::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.85;
    flex-shrink: 0;
}
/* Baseline outcomes — what the platform's baseline tier decided. */
.pill-baseline-baselined { color: #6ee7b7; }
.pill-baseline-legacy    { color: #93c5fd; }
.pill-baseline-pending   { color: #fcd34d; }
.pill-baseline-rejected  { color: #fca5a5; }
.pill-baseline-failed    { color: #fbbf24; }
/* Customer pipeline outcomes — what the configured pipelines did
   AFTER baseline let the article through. Independent dimension. */
.pill-pipeline-ran        { color: #6ee7b7; }
.pill-pipeline-failed     { color: var(--red); }
.pill-pipeline-gate       { color: #fcd34d; }
.pill-pipeline-incomplete { color: #fcd34d; }

/* Baseline-output chips on the article-detail page. Topical-focus
   gets a distinct accent (the matcher-relevant axis); baseline tags
   stay neutral so they don't compete visually with promoted canonical
   tags rendered alongside. */
.entry-tag-topical {
    background: rgba(59,130,246,0.08);
    border: 1px solid rgba(59,130,246,0.3);
    color: #93c5fd;
}
.entry-tag-baseline {
    background: var(--surface-alt);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-family: monospace;
    font-size: 0.72rem;
}

/* DD-026 — category is the overarching axis (single primary badge,
   bolder accent); topic is the subtype (chip-strip alongside, tied to
   the registry vocabulary). */
.entry-tag-category {
    background: rgba(168,85,247,0.10);
    border: 1px solid rgba(168,85,247,0.45);
    color: #d8b4fe;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.05em;
}
.entry-tag-topic {
    background: rgba(34,197,94,0.08);
    border: 1px solid rgba(34,197,94,0.3);
    color: #86efac;
}

/* Generic typed-render output for AI task results.
   See espresso.utils.output_render — purely structural inference,
   no per-task knowledge. The macro emits `.trender-*` classes; this
   stylesheet gives them sensible defaults that can be overridden
   by any host page if needed. */
.trender { font-size: 0.85rem; color: var(--text); line-height: 1.55; }
.trender-section { margin: 0.5rem 0; }
.trender-section-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 700;
    color: var(--text-dim);
    margin-bottom: 0.2rem;
}
.trender-section-body {
    padding-left: 0.7rem;
    border-left: 2px solid rgba(255,255,255,0.06);
}
.trender-field {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.15rem 0;
}
.trender-field-label {
    font-weight: 600;
    color: var(--text-muted);
    min-width: 8rem;
}
.trender-field-value { color: var(--text); }
.trender-bool.yes { color: var(--green); font-weight: 700; }
.trender-bool.no { color: var(--red); font-weight: 700; }
.trender-number { font-variant-numeric: tabular-nums; }
.trender-inline { color: var(--text); }
.trender-paragraph {
    margin: 0.3rem 0;
    color: var(--text);
    white-space: pre-wrap;
}
.trender-markdown { margin: 0.3rem 0; color: var(--text); }
.trender-markdown p { margin: 0.4rem 0; }
.trender-markdown ol, .trender-markdown ul { margin: 0.4rem 0 0.4rem 1.2rem; }
.trender-markdown li { margin: 0.15rem 0; }
.trender-markdown code {
    background: rgba(255,255,255,0.06);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    font-size: 0.78rem;
}
.trender-markdown a { color: var(--accent); }
.trender-markdown strong { color: var(--white); }
.trender-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0.2rem 0;
}
.trender-chip {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    background: rgba(96,165,250,0.12);
    color: var(--accent);
    border: 1px solid rgba(96,165,250,0.25);
    border-radius: 3px;
    font-size: 0.72rem;
}
.trender-bullets {
    margin: 0.3rem 0 0.3rem 1.2rem;
    padding: 0;
}
.trender-bullets li { margin: 0.2rem 0; }
.trender-cards {
    counter-reset: trender-card;
    list-style: none;
    margin: 0.4rem 0;
    padding: 0;
}
.trender-card {
    counter-increment: trender-card;
    background: rgba(255,255,255,0.03);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 0.5rem 0.7rem 0.5rem 2.2rem;
    margin-bottom: 0.4rem;
    position: relative;
}
.trender-card::before {
    content: counter(trender-card) ".";
    position: absolute;
    left: 0.7rem;
    top: 0.5rem;
    font-weight: 700;
    color: var(--text-dim);
}

/* Rejection card */
.rejection-card {
    background: #1a0a0a;
    border: 1px solid #7f1d1d;
    border-radius: 8px;
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.8rem;
}
.rejection-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
}
.rejection-icon { color: #fca5a5; font-size: 0.9rem; }
.rejection-title {
    font-size: 0.78rem;
    font-weight: 600;
    color: #fca5a5;
}
.rejection-task {
    padding: 0.5rem 0.6rem;
    background: #1f0f0f;
    border-radius: 6px;
    margin-bottom: 0.4rem;
}
.rejection-task:last-child { margin-bottom: 0; }
.rejection-task-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.3rem;
}
.rejection-task-name {
    font-size: 0.75rem;
    font-weight: 700;
    color: #fca5a5;
    font-family: monospace;
}
.rejection-task-model {
    font-size: 0.6rem;
    color: var(--text-dim);
    background: #2a1515;
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
}
.rejection-reason {
    font-size: 0.8rem;
    color: var(--text);
    line-height: 1.5;
}
.rejection-factors {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.3rem;
}
.rejection-factor {
    font-size: 0.7rem;
    background: #2a1515;
    color: var(--text-muted);
    padding: 0.15rem 0.4rem;
    border-radius: 3px;
}
.rejection-raw {
    font-size: 0.75rem;
    color: var(--text-muted);
    font-family: monospace;
}

/* Incomplete card */
.incomplete-card {
    background: #1a1400;
    border: 1px solid #78350f;
    border-radius: 8px;
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.8rem;
}
.incomplete-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.incomplete-icon { color: #fcd34d; font-size: 0.9rem; }
.incomplete-title {
    font-size: 0.78rem;
    font-weight: 600;
    color: #fcd34d;
}
.incomplete-tasks {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.5rem;
}
.incomplete-task-pill {
    font-size: 0.65rem;
    font-weight: 600;
    padding: 0.15rem 0.45rem;
    border-radius: 3px;
    font-family: monospace;
}
.incomplete-task-pill.passed { background: #064e3b; color: #6ee7b7; }
.incomplete-task-pill.failed { background: #7f1d1d; color: #fca5a5; }
.incomplete-task-pill.skipped { background: var(--border); color: var(--text-dim); }

/* Article state: incomplete */
.article-state-badge.incomplete { background: #78350f; color: #fcd34d; }
.article-state-badge.failed { background: #4a1d1d; color: var(--red); }

/* Article detail meta */
.article-meta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.5rem;
    margin-bottom: 0.8rem;
    padding: 0.5rem;
    background: var(--bg-hover);
    border-radius: 6px;
    font-size: 0.8rem;
}
.article-meta-label {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    display: block;
    margin-bottom: 0.1rem;
}

/* Investigate */
.investigate-tabs {
    display: flex;
    gap: 0.3rem;
    margin-bottom: 1.2rem;
}
.investigate-tab {
    padding: 0.4rem 0.8rem;
    font-size: 0.78rem;
    font-weight: 500;
    border-radius: 6px;
    border: 1px solid var(--border);
    color: var(--text-muted);
    text-decoration: none;
    transition: all 0.15s;
}
.investigate-tab:hover { border-color: var(--border-hover); color: var(--text); }
.investigate-tab.active { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.investigate-tab.disabled { color: var(--text-dim); cursor: default; border-color: var(--border); opacity: 0.5; }
.investigate-tab.disabled:hover { border-color: var(--border); color: var(--text-dim); }
.investigate-summary { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 1rem; }

/* Sector list */
.sector-list { display: flex; flex-direction: column; gap: 0.4rem; }
.sector-card {
    display: block;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.8rem;
    text-decoration: none;
    transition: border-color 0.15s;
}
.sector-card:hover { border-color: var(--accent); }
.sector-card-header { display: flex; justify-content: space-between; align-items: center; }
.sector-card-name { font-size: 0.9rem; font-weight: 600; color: var(--white); }
.sector-card-count { font-size: 1.1rem; font-weight: 700; color: var(--white); }
.sector-card-meta {
    display: flex;
    gap: 0.5rem;
    font-size: 0.7rem;
    color: var(--text-dim);
    margin-top: 0.15rem;
}
.sector-gics { font-family: monospace; }
.sector-card-bar {
    height: 4px;
    background: var(--border);
    border-radius: 2px;
    margin-top: 0.4rem;
    position: relative;
    overflow: hidden;
}
.sector-card-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: #1e3a5f;
    border-radius: 2px;
}
.sector-card-bar-target {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: #7f1d1d;
    border-radius: 2px;
}
.sector-card-stats {
    display: flex;
    gap: 0.8rem;
    font-size: 0.65rem;
    color: var(--text-dim);
    margin-top: 0.3rem;
}

/* Sector detail */
.sector-article-list { display: flex; flex-direction: column; }
.sector-article-item {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}
.sector-article-item:last-child { border-bottom: none; }
.sector-article-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.sector-article-title {
    color: var(--text);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sector-article-title:hover { color: var(--accent); }
.sector-article-date {
    font-size: 0.7rem;
    color: var(--text-dim);
    font-family: monospace;
    flex-shrink: 0;
}
.sector-article-evidence {
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-top: 0.2rem;
    line-height: 1.4;
}
.sector-inferred-badge {
    font-size: 0.6rem;
    color: var(--text-dim);
    background: var(--border);
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
}

/* Topics */
.topic-list { display: flex; flex-direction: column; gap: 0.5rem; }
.topic-card {
    display: block;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    text-decoration: none;
    transition: border-color 0.15s;
}
.topic-card:hover { border-color: var(--accent); }
.topic-card-header { display: flex; justify-content: space-between; align-items: center; }
.topic-card-name { font-size: 0.95rem; font-weight: 600; color: var(--white); }
.topic-card-count { font-size: 0.75rem; color: var(--text-muted); }
.topic-card-desc { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.3rem; line-height: 1.4; }
.topic-description { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 1rem; line-height: 1.5; }

.topic-facet-list { display: flex; flex-direction: column; gap: 0.3rem; }
.topic-facet-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 0.6rem;
    background: var(--bg-hover);
    border-radius: 6px;
}
.topic-facet-name { font-size: 0.85rem; font-weight: 500; color: var(--white); }
.topic-facet-desc { font-size: 0.72rem; color: var(--text-dim); margin-top: 0.1rem; }
.topic-facet-count { font-size: 0.75rem; color: var(--text-muted); flex-shrink: 0; }

.topic-package-list { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.topic-package-item {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--bg-hover);
    border-radius: 4px;
    padding: 0.25rem 0.5rem;
    font-size: 0.78rem;
}
.topic-package-name { font-weight: 600; font-family: monospace; color: var(--white); }
.topic-package-versions { font-size: 0.65rem; color: var(--text-dim); font-family: monospace; }

.topic-article-matches { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-top: 0.2rem; }
.topic-match-pill {
    font-size: 0.6rem;
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
    font-weight: 600;
}
.topic-match-pill.tag { background: #1e3a5f; color: #93c5fd; }
.topic-match-pill.keyword { background: #78350f; color: #fcd34d; }
.topic-match-pill.technique { background: #064e3b; color: #6ee7b7; }

.entry-title-link { color: inherit; text-decoration: none; }
.entry-title-link:hover { color: var(--accent); }

/* Article detail page */
.article-pipeline-run {
    background: var(--bg-hover);
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.4rem;
}
.article-pipeline-run-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.article-task-card {
    background: var(--bg-hover);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 0.4rem;
}
.article-task-summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    cursor: pointer;
    list-style: none;
}
.article-task-summary::-webkit-details-marker { display: none; }
.article-task-card[open] { border-color: var(--border-hover); }
.article-task-name {
    font-weight: 600;
    font-family: monospace;
    font-size: 0.82rem;
    color: var(--white);
}
.article-task-detail {
    padding: 0 0.7rem 0.5rem;
    border-top: 1px solid var(--border);
}
.article-task-result { margin-top: 0.4rem; }
.article-task-field {
    display: flex;
    gap: 0.5rem;
    padding: 0.2rem 0;
    font-size: 0.78rem;
    border-bottom: 1px solid var(--border);
}
.article-task-field:last-child { border-bottom: none; }
.article-task-field-key {
    font-weight: 600;
    color: var(--text-muted);
    min-width: 120px;
    flex-shrink: 0;
    font-family: monospace;
    font-size: 0.72rem;
}
.article-task-field-value {
    color: var(--text);
    word-break: break-word;
    white-space: pre-wrap;
}

/* Activity feed article link */
.activity-article {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 200px;
}
.activity-article:hover { color: var(--accent); }

/* Feed entry list */
.entry-list { display: flex; flex-direction: column; gap: 0.3rem; }

.entry-divider {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    padding: 0.8rem 0 0.3rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.2rem;
}
.entry-divider:first-child { padding-top: 0; }

.entry-item {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    transition: border-color 0.15s;
}
.entry-item:hover { border-color: var(--border-hover); }
.entry-item[open] { border-color: var(--border-hover); }

/* Read state */
.entry-item.read { opacity: 0.55; }
.entry-item.read .entry-title { font-weight: 400; font-size: 0.8rem; }
.entry-item.read .entry-meta { display: none; }
.entry-item.read:hover { opacity: 0.8; }
.entry-item.read[open] { opacity: 1; }
.entry-item.read[open] .entry-meta { display: flex; }

/* New entries indicator */
.new-indicator {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    background: var(--accent);
    color: var(--bg);
    cursor: pointer;
    margin-left: 0.5rem;
    animation: pulse-new 1.5s ease-in-out infinite;
}
@keyframes pulse-new { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }

.entry-summary {
    padding: 0.6rem 0.8rem;
    cursor: pointer;
    list-style: none;
}
.entry-summary::-webkit-details-marker { display: none; }

.entry-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.article-status-dot {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6rem;
    border-radius: 50%;
    cursor: help;
}
.article-status-dot.approved { color: #6ee7b7; }
.article-status-dot.rejected { color: #fca5a5; }
.article-status-dot.failed { color: var(--red); }
.article-status-dot.incomplete { color: #fcd34d; }
.article-status-dot.unprocessed { color: var(--text-dim); }

.entry-date-end {
    flex-shrink: 0;
    font-size: 0.65rem;
    color: var(--text-dim);
    white-space: nowrap;
    font-family: var(--mono);
}

.entry-date-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 36px;
    flex-shrink: 0;
}
.entry-date-day { font-size: 0.9rem; font-weight: 700; color: var(--white); line-height: 1.1; }
.entry-date-month { font-size: 0.5rem; text-transform: uppercase; color: var(--text-muted); letter-spacing: 0.05em; }
.entry-date-time { font-size: 0.5rem; color: var(--text-dim); }

.entry-favicon {
    width: 20px;
    height: 20px;
    border-radius: 3px;
    flex-shrink: 0;
}
.entry-favicon-placeholder {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    color: var(--text-dim);
    background: var(--border);
    border-radius: 3px;
    flex-shrink: 0;
}

.entry-info { flex: 1; min-width: 0; }
.entry-title {
    font-size: 0.85rem;
    color: var(--white);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.entry-meta {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    font-size: 0.6rem;
}
.entry-category {
    color: var(--text-muted);
}
.entry-source { color: var(--text-dim); }
.entry-date { color: var(--text-dim); }

/* Entry detail (expanded) */
.entry-detail {
    padding: 0 0.8rem 0.8rem;
    padding-left: 2.4rem;  /* align with title (favicon + gap) */
}
.entry-section { margin-bottom: 0.6rem; }
.entry-section-label {
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-dim);
    margin-bottom: 0.2rem;
}
.entry-section-content {
    font-size: 0.85rem;
    color: var(--text);
    line-height: 1.6;
}
.entry-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem;
    margin: 0.5rem 0;
}
.entry-tag {
    font-size: 0.65rem;
    padding: 0.1rem 0.4rem;
    background: var(--border);
    color: var(--text-muted);
    border-radius: 3px;
    text-decoration: none;
    transition: background 0.1s, color 0.1s;
}
.entry-tag:hover { background: var(--accent); color: var(--bg); }

.reader-source-link { font-size: 0.8rem; color: var(--accent); text-decoration: none; display: block; margin-top: 0.3rem; }
.reader-source-link:hover { text-decoration: underline; }

/* Feed card as link */
.feed-card-link { text-decoration: none; display: block; }
.feed-card-link:hover { border-color: var(--accent); }

/* Reports */
.report-list { display: flex; flex-direction: column; gap: 0.5rem; }
.report-card {
    display: block;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.8rem 1rem;
    text-decoration: none;
    transition: border-color 0.15s;
}
.report-card:hover { border-color: var(--accent); }
.report-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.3rem; }
.report-type-badge {
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    background: #1e3a5f;
    color: #93c5fd;
}
.report-date { font-size: 0.7rem; color: var(--text-dim); }
.report-title { font-size: 0.9rem; color: var(--white); font-weight: 500; }

/* Report detail view */
.report-view {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.5rem;
}
.report-view-header { display: flex; gap: 0.8rem; align-items: center; margin-bottom: 1rem; }
/* Report body typography — canonical ruleset for `.report-content`.
 * Renders markdown-derived report bodies (report_detail.html,
 * report_detail_v2.html, workbench section renders). Theme-aware:
 * every color references `--text`/`--text-muted`/`--border`/`--bg-card`
 * so `body.light` re-skinning happens through the token layer.
 * Per-feature overrides (footnotes, dd040 citations) live further
 * down the file and only set the differing properties. */
.report-content { font-size: 0.9rem; color: var(--text); line-height: 1.7; }
.report-content h1 { font-size: 1.3rem; color: var(--text); margin-block: 1.5rem 0.5rem; }
.report-content h2 { font-size: 1.1rem; color: var(--text); margin-block: 1.2rem 0.4rem; }
.report-content h3 { font-size: 0.95rem; color: var(--text); margin-block: 1rem 0.3rem; }
.report-content p { margin-block-end: 0.6rem; }
.report-content ul, .report-content ol { margin-block: 0.4rem 0.6rem; padding-inline-start: 1.5rem; }
.report-content li { margin-block-end: 0.2rem; }
.report-content code { background: var(--border); padding-block: 0.1rem; padding-inline: 0.3rem; border-radius: 3px; font-size: 0.85em; }
.report-content pre { background: var(--bg-card); padding: 0.8rem; border-radius: 6px; overflow-x: auto; margin-block: 0.6rem; }
.report-content pre code { background: none; padding: 0; }
.report-content a { color: var(--accent); }
.report-content table { border-collapse: collapse; width: 100%; margin-block: 0.6rem; }
.report-content th, .report-content td { border: 1px solid var(--border); padding-block: 0.4rem; padding-inline: 0.6rem; font-size: 0.85rem; }
.report-content th { background: var(--border); color: var(--text-muted); text-align: left; }

/* Custom select */
.custom-select { position: relative; }
.custom-select-trigger {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--border);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--text);
    transition: border-color 0.15s;
}
.custom-select-trigger:hover { border-color: var(--accent); }
.custom-select-arrow { color: var(--text-muted); font-size: 0.7rem; }
.custom-select-options {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--bg-hover);
    border: 1px solid var(--border-hover);
    border-radius: 6px;
    z-index: 10;
    max-height: 240px;
    overflow-y: auto;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.custom-select-option {
    padding: 0.5rem 0.8rem;
    cursor: pointer;
    transition: background 0.1s;
}
.custom-select-option:hover { background: var(--bg-hover); }
.custom-select-option.selected { background: rgba(96, 165, 250, 0.1); border-left: 2px solid var(--accent); }
.option-name { font-size: 0.85rem; color: var(--white); font-weight: 500; }
.option-desc { font-size: 0.7rem; color: var(--text-muted); margin-top: 0.1rem; }

/* Stage timeline (SSE) */
.stage-timeline { display: flex; flex-direction: column; gap: 0.4rem; }

.stage-block {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.stage-block.active { border-color: var(--amber); }
.stage-block.passed { border-color: var(--green); border-color: #064e3b; }
.stage-block.failed { border-color: var(--red); border-color: #7f1d1d; }

.stage-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.8rem;
    cursor: pointer;
    list-style: none;
}
.stage-header::-webkit-details-marker { display: none; }

.stage-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.stage-dot.pending { background: var(--border-hover); }
.stage-dot.active { background: var(--amber); animation: pulse 1s ease-in-out infinite; }
.stage-dot.passed { background: var(--green); }
.stage-dot.failed { background: var(--red); }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

.stage-label { font-size: 0.9rem; color: var(--white); font-weight: 500; flex: 1; }
.stage-block.pending .stage-label { color: var(--text-muted); }

.stage-badge {
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
}
.stage-badge.active { background: #78350f; color: #fde68a; }
.stage-badge.passed { background: #064e3b; color: #6ee7b7; }
.stage-badge.failed { background: #7f1d1d; color: #fca5a5; }

.stage-tasks {
    padding: 0 0.8rem 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.stage-task {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.2rem 0 0.2rem 1rem;
    font-size: 0.8rem;
}
.task-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
}
.task-dot.pending { background: var(--border-hover); }
.task-dot.passed { background: var(--green); }
.task-dot.failed { background: var(--red); }
.task-name { color: var(--text); }
.stage-task.pending .task-name { color: var(--text-dim); }

.event-badge {
    font-size: 0.55rem;
    font-weight: 700;
    text-transform: uppercase;
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
}
.event-badge.passed { background: #064e3b; color: #6ee7b7; }
.event-badge.failed { background: #7f1d1d; color: #fca5a5; }

/* Topbar — was the DD-014 email + Profile/Logout strip; 2026-05-19
 * turned into a breadcrumb. The right edge can carry current-page
 * metadata (e.g. "Last touched X") so the analyst's eye reaches
 * orientation info before scanning the body. */
.topbar {
    /* Contextual breadcrumb chrome — only renders on pages that
     * explicitly populate `breadcrumb_section` / `breadcrumb_meta`
     * blocks (~5 of 60 templates). Lives inside main-content,
     * below the persistent app-navbar. Two-column flex: crumbs
     * left, meta right. No bottom border — the navbar already
     * delimits the chrome zone above and pages should feel
     * continuous, not striped. */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
    font-size: 0.8rem;
}
.topbar-crumbs {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.topbar-crumb {
    display: inline-flex;
    align-items: center;
}
.topbar-crumb-link {
    color: var(--text-muted);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.72rem;
    transition: color 0.15s ease;
}
.topbar-crumb-link:hover { color: var(--accent); }
.topbar-crumb-text {
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.72rem;
}
.topbar-crumb-sep {
    color: var(--text-dim);
    font-size: 0.9rem;
    line-height: 1;
}
.topbar-crumb--current {
    color: var(--text);
    font-weight: 500;
    font-size: 0.85rem;
}
.topbar-meta {
    color: var(--text-muted);
    font-size: 0.75rem;
    white-space: nowrap;
}

/* Sidebar — Profile entry + Logout pairs with the theme toggle.
 * Both are chrome actions, not nav, so they live below the regular
 * Learn group and above the bottom theme strip. */
.sidebar-account-group {
    margin-top: 0.4rem;
}
.sidebar-logout-btn {
    /* Centered text label, no icon. Slightly muted by default; the
       border + hover treatment make it read as an action without
       shouting for attention. */
    display: block;
    width: 100%;
    text-align: center;
    padding: 0.5rem 0.75rem;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: transparent;
    transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.sidebar-logout-btn:hover {
    color: var(--text);
    border-color: var(--border-hover);
    background: var(--bg-hover);
}

/* Sources tab strip (DD-014, 2026-04-25 fold) */
.sources-tabs {
    display: flex;
    gap: 0.2rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 1.2rem;
}
.sources-tab {
    padding: 0.6rem 1.1rem;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.85rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.15s, border-color 0.15s;
}
.sources-tab:hover { color: var(--text); }
.sources-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    font-weight: 600;
}

/* Empty state (DD-014) */
.empty-state {
    text-align: center;
    padding: 3rem 1.5rem;
    max-width: 540px;
    margin: 2rem auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.empty-state-icon {
    font-size: 2.4rem;
    color: var(--accent);
    margin-bottom: 0.8rem;
}
.empty-state-title {
    font-size: 1.1rem;
    color: var(--text);
    margin: 0 0 0.6rem;
}
.empty-state-body {
    color: var(--text-muted);
    line-height: 1.5;
    margin: 0 0 1.4rem;
    font-size: 0.9rem;
}
.empty-state-action {
    display: inline-block;
    padding: 0.55rem 1.1rem;
    background: var(--accent);
    color: var(--bg);
    text-decoration: none;
    border-radius: 4px;
    font-size: 0.85rem;
    font-weight: 600;
    transition: opacity 0.15s;
}
.empty-state-action:hover { opacity: 0.85; }
.empty-state-link {
    display: block;
    margin-top: 0.9rem;
    color: var(--text-muted);
    font-size: 0.8rem;
    text-decoration: none;
}
.empty-state-link:hover { color: var(--accent); }

/* Mobile */
@media (max-width: 768px) {
    .sidebar { width: 60px; }
    .sidebar-brand { font-size: 0.7rem; padding: 0 0.5rem 0.8rem; text-align: center; }
    .sidebar-link { padding: 0.5rem; justify-content: center; font-size: 0; }
    .sidebar-link .sidebar-icon { font-size: 1.1rem; }
    .main-content { padding: 1rem; }
    .stat-cards { flex-direction: column; }
    .topbar { flex-wrap: wrap; }
    .topbar-greeting { font-size: 0; }  /* hide on mobile, keep links */
}

/* ─── Trial countdown banner (Launch 1.1 Slice 5) ─────────────────
   Surfaces on every authenticated page when the account is in
   state=trial. Three tones drive urgency:
     ok     — >7 days remaining
     warn   — 3-7 days remaining
     urgent — <=2 days remaining
*/
.trial-banner {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.9rem;
    border-radius: 4px;
    font-size: 0.85rem;
    line-height: 1.4;
    margin-bottom: 0.8rem;
    border: 1px solid;
}
.trial-banner-icon {
    font-size: 1rem;
    line-height: 1;
}
.trial-banner-msg { flex: 1; }
.trial-banner--ok {
    background: rgba(56, 189, 248, 0.10);
    color: #7dd3fc;
    border-color: rgba(56, 189, 248, 0.30);
}
.trial-banner--warn {
    background: rgba(251, 191, 36, 0.10);
    color: #fcd34d;
    border-color: rgba(251, 191, 36, 0.35);
}
.trial-banner--urgent {
    background: rgba(220, 38, 38, 0.15);
    color: #fca5a5;
    border-color: rgba(220, 38, 38, 0.40);
}

/* ─── Status pills — generic state vocabulary ──────────────────────
   Reusable across admin tables / lists where a row has a discrete
   workflow state (pending / approved / rejected / waitlisted / info).
   Pair the JS / template with `.status-pill .status-pill--<state>`
   so the theme toggle reaches every surface in one switch.

   Each variant defines color + background + border for BOTH dark
   (default) and light (`body.light`) themes. New states should
   follow the same pair-of-blocks structure — never use hardcoded
   pastel hex inline.
*/
.status-pill {
    display: inline-block;
    font-size: 0.62rem;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    border: 1px solid transparent;
    font-family: inherit;
    letter-spacing: 0.02em;
    line-height: 1.5;
}
/* Dark theme — pastel text on tinted background. */
.status-pill--pending    { color: #fcd34d; background: rgba(252,211,77,0.10); border-color: rgba(252,211,77,0.35); }
.status-pill--approved   { color: #6ee7b7; background: rgba(110,231,183,0.10); border-color: rgba(110,231,183,0.35); }
.status-pill--rejected   { color: #fca5a5; background: rgba(252,165,165,0.10); border-color: rgba(252,165,165,0.35); }
.status-pill--waitlisted { color: #93c5fd; background: rgba(147,197,253,0.10); border-color: rgba(147,197,253,0.35); }
.status-pill--info       { color: var(--accent); background: rgba(96,165,250,0.10); border-color: rgba(96,165,250,0.35); }
/* Light theme — saturated text on pale tint. Mirrors the existing
   .article-state-badge / .collection-status-badge palette so the
   admin section reads as one design family. */
body.light .status-pill--pending    { color: #92400e; background: #fef3c7; border-color: #fde68a; }
body.light .status-pill--approved   { color: #065f46; background: #d1fae5; border-color: #a7f3d0; }
body.light .status-pill--rejected   { color: #991b1b; background: #fee2e2; border-color: #fecaca; }
body.light .status-pill--waitlisted { color: #1e40af; background: #dbeafe; border-color: #bfdbfe; }
body.light .status-pill--info       { color: #1d4ed8; background: #eff6ff; border-color: #bfdbfe; }

/* Demand-dashboard count colours — same five-tone vocabulary,
   different surface (single coloured text on the card's --bg-card,
   no pill). Keep the values aligned with .status-pill--* hues so the
   page reads as one palette.
*/
.demand-count--pending    { color: #fcd34d; }
.demand-count--waitlisted { color: #93c5fd; }
.demand-count--approved   { color: #6ee7b7; }
.demand-count--rejected   { color: #fca5a5; }
body.light .demand-count--pending    { color: #92400e; }
body.light .demand-count--waitlisted { color: #1e40af; }
body.light .demand-count--approved   { color: #065f46; }
body.light .demand-count--rejected   { color: #991b1b; }

/* .btn-danger — referenced by admin_packages.js + others but never
   defined. Adding now so red intent reads consistently across both
   themes. Pairs with .status-pill--rejected colour vocabulary.
*/
.btn-danger {
    color: #fca5a5;
    border-color: rgba(248, 113, 113, 0.35);
}
.btn-danger:hover {
    color: #fecaca;
    background: rgba(248, 113, 113, 0.10);
    border-color: rgba(248, 113, 113, 0.55);
}
body.light .btn-danger {
    color: #b91c1c;
    border-color: #fecaca;
}
body.light .btn-danger:hover {
    color: #991b1b;
    background: #fef2f2;
    border-color: var(--red);
}

/* ── /app/search hero layout ──────────────────────────────────────
   Idle state (no query yet): the input host is vertically centered
   in the viewport, single input front-and-centre. Once the user
   types anything, JS adds `.search-hero--active` and the input
   slides to the top of the page so the results panel below it has
   room to breathe. No inline grammar tutorial; the typeahead
   reveals prefixes as needed. */
.search-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 70vh;
    transition: min-height 0.25s ease;
}
.search-hero__host {
    width: 100%;
    max-width: 720px;
}
.search-hero--active {
    justify-content: flex-start;
    min-height: auto;
    padding-top: 1.5rem;
}

/* ── article-row payload-type pill ────────────────────────────────
   Tiny monospace pill that surfaces the article's payload provenance
   (what format the original was BEFORE ingest normalized it to
   text). Only renders when payload_type ≠ 'url' — every URL-fetched
   article (the bulk of today's corpus) stays unbadged. Mild colour
   per type so the eye can pick out provenance at a glance without
   the row turning into a rainbow. */
.article-row__type-pill {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    height: 18px;
    padding: 0 0.45rem;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    border-radius: 4px;
    border: 1px solid var(--border);
    background: var(--bg-hover);
    color: var(--text-muted);
}
.article-row__type-pill--pdf {
    color: #c2410c;
    background: rgba(249, 115, 22, 0.10);
    border-color: rgba(249, 115, 22, 0.35);
}
.article-row__type-pill--text {
    color: var(--text-muted);
}
.article-row__type-pill--api {
    color: #1d4ed8;
    background: rgba(59, 130, 246, 0.10);
    border-color: rgba(59, 130, 246, 0.35);
}
.article-row__type-pill--webhook {
    color: #7c3aed;
    background: rgba(139, 92, 246, 0.10);
    border-color: rgba(139, 92, 246, 0.35);
}
body.light .article-row__type-pill--pdf {
    color: #9a3412;
    background: #fff7ed;
    border-color: #fdba74;
}
body.light .article-row__type-pill--api {
    color: #1e40af;
    background: #eff6ff;
    border-color: #bfdbfe;
}
body.light .article-row__type-pill--webhook {
    color: #5b21b6;
    background: #f5f3ff;
    border-color: #c4b5fd;
}

/* ════════════════════════════════════════════════════════════════
   STREAMS — merged from streams.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* DD-025 — Output Streams (dashboard timelines).
   Row-based vertical nav on the LEFT (one row per stream), single
   full-width content pane on the right. The nav sits beside the
   primary app sidebar (which is collapsible via the chevron in the
   top-left of base.html). Cards in the active pane are slightly
   wider than the previous Tweetdeck-style column rail so summaries
   have more reading room. */

/* Streams palette — locally scoped because the original colours were
   GitHub-Primer, not the product palette in user.css. Defining them
   as vars here lets the body.light theme switch flip the entire
   page without per-selector overrides. */
:root {
    --dd025-bg:              #0d1117;
    --dd025-surface:         #161b22;
    --dd025-surface-hover:   #21262d;
    --dd025-surface-elev:    #11161d;
    --dd025-border:          #30363d;
    --dd025-text:            #c9d1d9;
    --dd025-text-bright:     #f0f6fc;
    --dd025-text-muted:      #8b949e;
    --dd025-text-dim:        #6e7681;
    --dd025-accent:          #58a6ff;
    --dd025-accent-hover:    #388bfd;
    --dd025-accent-strong:   #1f6feb;
    --dd025-accent-tint:     #1f6feb22;
    --dd025-accent-deep:     #0c2d6b22;
    --dd025-danger:          #ff7b72;
    --dd025-danger-tint:     #ff7b7211;
    --dd025-success:         #3fb950;
    --dd025-error:           #f87171;
    --dd025-warning:         #d29922;
    --dd025-warning-tint:    #d2992211;
    --dd025-warning-border:  #d2992233;
    --dd025-chip-blue:       #93c5fd;
    --dd025-chip-purple:     #d8b4fe;
    --dd025-chip-green:      #86efac;
}

body.light {
    --dd025-bg:              #f8fafc;
    --dd025-surface:         #ffffff;
    --dd025-surface-hover:   #f1f5f9;
    --dd025-surface-elev:    #f8fafc;
    --dd025-border:          #cbd5e1;
    --dd025-text:            #1e293b;
    --dd025-text-bright:     #0f172a;
    --dd025-text-muted:      #475569;
    --dd025-text-dim:        #94a3b8;
    --dd025-accent:          #2563eb;
    --dd025-accent-hover:    #1d4ed8;
    --dd025-accent-strong:   #1d4ed8;
    --dd025-accent-tint:     #dbeafe;
    --dd025-accent-deep:     #eff6ff;
    --dd025-danger:          #b91c1c;
    --dd025-danger-tint:     #fee2e2;
    --dd025-success:         #047857;
    --dd025-error:           #b91c1c;
    --dd025-warning:         #92400e;
    --dd025-warning-tint:    #fef3c7;
    --dd025-warning-border:  #fcd34d;
    --dd025-chip-blue:       #1e40af;
    --dd025-chip-purple:     #6b21a8;
    --dd025-chip-green:      #065f46;
}

.dd025-rail {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 12px;
    /* Flex-fill the remaining height inside `.main-content--full`
       (a 100vh-constrained flex column). Makes the column body the
       SOLE scroll surface — no more page-and-column double-scroll.
       `min-height: 0` lets flex shrink below natural content height. */
    flex: 1 1 auto;
    min-height: 0;
    margin-bottom: 0;
}

/* Streams nav — vertical column of clickable rows on the left side
   of the rail. Each row is one stream. */
.dd025-streams-nav {
    /* Nav width = width of the LONGEST stream name (capped at 260),
       so adding/removing streams doesn't reshuffle the column widths.
       `width: max-content` measures the children, `max-width` bounds
       it for hostile inputs. Items inside reflow to multi-line when
       a single name pushes against the max. */
    flex: 0 0 max-content;
    width: max-content;
    min-width: 180px;
    max-width: 260px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px 0;
    overflow-y: auto;
    overflow-x: hidden;
    border-right: 1px solid var(--dd025-border);
}

.dd025-streams-nav-item {
    display: flex;
    /* Align top so a wrapping multi-line title sits flush with the
       accent dot rather than centring around it. */
    align-items: flex-start;
    gap: 8px;
    padding: 8px 12px;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    color: var(--dd025-text-muted);
    font-size: 0.88rem;
    font-weight: 500;
    cursor: pointer;
    text-align: left;
    width: 100%;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.dd025-streams-nav-item:hover {
    background: var(--dd025-surface);
    color: var(--dd025-text);
}
.dd025-streams-nav-item.is-active {
    background: var(--dd025-surface);
    border-left-color: var(--col-accent, var(--dd025-accent));
    color: var(--dd025-text-bright);
}

.dd025-streams-nav-accent {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--col-accent, var(--dd025-border));
    flex: 0 0 auto;
    /* Nudge down so the dot lines up with the cap height of the first
       line of the (possibly multi-line) title rather than the very
       top of its line box. */
    margin-top: 6px;
}
.dd025-streams-nav-title {
    /* Multi-line wrap on long names rather than truncation. The nav
       container caps width at 260px so wrapping is bounded; word-break
       handles unbreakable strings (long URLs, etc.) without overflowing. */
    flex: 1 1 auto;
    white-space: normal;
    word-break: break-word;
    line-height: 1.3;
}
.dd025-streams-nav-count {
    color: var(--dd025-text-dim);
    font-size: 0.72rem;
    flex: 0 0 auto;
    min-width: 22px;
    text-align: right;
}
.dd025-streams-nav-newcount {
    background: var(--dd025-accent);
    color: var(--dd025-bg);
    font-size: 0.65rem;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 8px;
    flex: 0 0 auto;
    min-width: 22px;
    text-align: center;
}

.dd025-streams-nav-add {
    padding: 8px;
    border-top: 1px solid var(--dd025-surface-hover);
    margin-top: 6px;
}
/* The shared `.dd025-add-tile` is sized for the legacy Tweetdeck
   rail (280px fixed). Inside the streams nav it must shrink to fit
   the column width — otherwise it overflows past the nav's right
   border line into the article pane. */
.dd025-streams-nav-add .dd025-add-tile {
    flex: 1 1 auto;
    width: 100%;
    height: auto;
    padding: 8px 10px;
    font-size: 0.82rem;
    box-sizing: border-box;
}

.dd025-pane {
    /* Active stream content sits flush against the nav (left-aligned),
       not centred in the rail — so the column-card visually attaches
       to the nav row that selected it instead of floating in space. */
    flex: 1 1 auto;
    overflow: hidden;
    display: flex;
    justify-content: flex-start;
}
.dd025-empty-pane {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dd025-empty-message {
    text-align: center;
    color: var(--text-muted);
    font-size: 0.85rem;
}
.dd025-empty-message p { margin: 0 0 0.4rem; }
.dd025-empty-link {
    color: var(--accent);
    text-decoration: none;
    font-size: 0.8rem;
}
.dd025-empty-link:hover { text-decoration: underline; }

.dd025-col {
    /* Single column, slightly wider than the old 420px Tweetdeck size
       so card content has more room to breathe. Capped at 720 to keep
       line lengths readable on wide monitors. */
    flex: 1 1 auto;
    width: 100%;
    max-width: 720px;
    height: 100%;
    background: var(--dd025-surface);
    border: 1px solid var(--dd025-border);
    /* Per-column identity strip on top — the JS sets `--col-accent`
       inline on the section element via a uid-seeded palette pick. */
    border-top: 3px solid var(--col-accent, var(--dd025-border));
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}

.dd025-col-header {
    flex: 0 0 auto;
    padding: 10px 12px;
    border-bottom: 1px solid var(--dd025-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    background: var(--dd025-bg);
    /* The whole column is draggable — but the header is the natural
       drag handle visually. Browsers fall back to grabbing the column
       body if the user starts the drag below the header anyway. */
    cursor: grab;
}
.dd025-col-header:active { cursor: grabbing; }

.dd025-col--dragging {
    opacity: 0.45;
}
.dd025-col--drop-target {
    outline: 2px dashed var(--dd025-accent);
    outline-offset: -2px;
}

.dd025-col-title {
    font-weight: 600;
    color: var(--dd025-text-bright);
    font-size: 0.95rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
}

.dd025-col-count {
    color: var(--dd025-text-muted);
    font-size: 0.75rem;
    flex: 0 0 auto;
}
/* Filter-active variant — a hint of accent so the user always sees at
   a glance that this column has read items hidden, without the meta
   pill row needing to be open. */
.dd025-col-count.is-filtered {
    color: var(--dd025-accent);
    background: var(--dd025-accent-tint);
    padding: 1px 7px;
    border-radius: 999px;
    font-weight: 500;
}

/* Disclosure arrow on the far left of the column header — toggles the
   meta-pill row below (unread / read counts). Default-collapsed
   keeps the column body tight; user can flip it open per column and
   the choice persists in localStorage. */
.dd025-col-disclosure {
    background: none;
    border: none;
    color: var(--dd025-text-dim);
    cursor: pointer;
    padding: 3px 6px;
    margin-right: 4px;
    font-size: 0.95rem;
    line-height: 1;
    flex: 0 0 auto;
    border-radius: 4px;
    transition: color 100ms ease, background-color 100ms ease;
}
.dd025-col-disclosure:hover { color: var(--dd025-text); background: var(--dd025-surface-hover); }

.dd025-col-menu {
    background: none;
    border: none;
    color: var(--dd025-text-muted);
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 1.1rem;
}
.dd025-col-menu:hover { color: var(--dd025-text-bright); background: var(--dd025-surface-hover); }

/* Column-options kebab dropdown — anchored absolute to the column
   header. The header has `position: relative` already implicitly via
   the new-pill positioning context, but force it explicitly here. */
.dd025-col-header { position: relative; }
.dd025-col-menu-dropdown {
    position: absolute;
    top: calc(100% + 2px);
    right: 6px;
    background: var(--dd025-surface);
    border: 1px solid var(--dd025-border);
    border-radius: 6px;
    padding: 4px 0;
    min-width: 200px;
    z-index: 30;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    cursor: default;
}
.dd025-col-menu-item {
    background: transparent;
    border: none;
    color: var(--dd025-text);
    padding: 7px 12px;
    text-align: left;
    cursor: pointer;
    font-size: 0.82rem;
    display: flex;
    align-items: center;
    gap: 8px;
    transition: background-color 100ms ease, color 100ms ease;
}
.dd025-col-menu-item:hover { background: var(--dd025-surface-hover); color: var(--dd025-text-bright); }
.dd025-col-menu-item--danger { color: var(--dd025-danger); }
.dd025-col-menu-item--danger:hover { background: var(--dd025-danger-tint); color: var(--dd025-danger); }
.dd025-col-menu-check {
    width: 14px;
    flex: 0 0 14px;
    color: var(--dd025-accent);
    font-weight: 700;
    text-align: center;
}
.dd025-col-menu-sep {
    height: 1px;
    background: var(--dd025-surface-hover);
    margin: 4px 0;
}
/* Section header inside the column kebab menu. Used to group the
   recency-window radio-style items under a "Window" label so the
   menu's hierarchy is legible. */
.dd025-col-menu-section {
    color: var(--dd025-text-dim);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 6px 12px 2px;
    font-weight: 600;
}

/* Recency-window badge in the column header. Always visible so the
   analyst knows the column is bounded to the last N days without
   opening the menu. Acts as a click-target — fires the same toggle
   as the kebab so the picker is one click away. */
.dd025-col-recency {
    background: var(--dd025-surface-hover);
    border: 1px solid var(--dd025-border);
    color: var(--dd025-text-muted);
    cursor: pointer;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 500;
    flex: 0 0 auto;
    line-height: 1.5;
    transition: background-color 100ms ease, color 100ms ease, border-color 100ms ease;
}
.dd025-col-recency:hover {
    color: var(--dd025-text-bright);
    background: var(--dd025-surface);
    border-color: var(--dd025-accent);
}
/* Visual cue that the user is on something other than the default
   30-day window — they explicitly opted into 60/90, mark it so the
   eye notices without making the badge loud. */
.dd025-col-recency.is-custom {
    color: var(--dd025-accent);
    border-color: var(--dd025-accent);
    background: var(--dd025-accent-tint);
}

/* Read/unread pill — sits at the top of the column body, above the
   suggestion banner / articles. Click toggles hide_read. is-active
   when hide_read is on, with an inset look. */
.dd025-col-pill {
    align-self: flex-start;
    background: transparent;
    border: 1px solid var(--dd025-border);
    color: var(--dd025-text-muted);
    padding: 3px 10px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.7rem;
    font-weight: 500;
    margin: 4px 4px 8px;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.dd025-col-pill:hover {
    background: var(--dd025-surface-hover);
    color: var(--dd025-text);
    border-color: var(--dd025-accent);
}
.dd025-col-pill.is-active {
    background: var(--dd025-accent-tint);
    border-color: var(--dd025-accent-strong);
    color: var(--dd025-accent);
}

/* Column action bar — sits between the header and the article body.
   Holds column-scoped buttons (Mark all as read for now; more later).
   Always rendered so the row's vertical reservation stays stable
   regardless of whether actions are enabled. */
.dd025-col-actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 10px;
    border-bottom: 1px solid var(--dd025-surface-hover);
    background: var(--dd025-bg);
}
.dd025-col-action {
    background: transparent;
    border: 1px solid var(--dd025-border);
    color: var(--dd025-text-muted);
    padding: 3px 10px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.72rem;
    font-weight: 500;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.dd025-col-action:hover:not(.is-disabled) {
    background: var(--dd025-surface-hover);
    border-color: var(--dd025-accent);
    color: var(--dd025-text);
}
.dd025-col-action.is-disabled,
.dd025-col-action:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.dd025-col-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.dd025-card {
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-surface-hover);
    /* Border-left thickened — colour set per-card from JS as
       rgba(<col-accent>, 0.30 + 0.70 * heat) so column identity +
       match strength both read at a glance without conflicting. */
    border-left-width: 3px;
    border-radius: 6px;
    padding: 12px 14px 8px;
    cursor: pointer;
    transition: border-color 120ms ease, opacity 120ms ease;
    display: block;
    color: inherit;
    text-decoration: none;
    position: relative;
}
.dd025-card:hover { border-color: var(--dd025-accent); }

/* "Just arrived" pulse — articles that landed in this stream while
   the user was viewing another stream. CSS-only fade: the keyframes
   pulse twice over the first ~3 seconds, then settle to the normal
   card appearance for the remaining 3 seconds. `animation-fill-mode:
   forwards` pins the final state so a re-render mid-animation
   (column expand, kebab toggle) doesn't replay it from full intensity. */
.dd025-card--just-arrived {
    position: relative;
    animation: dd025-card-just-arrived 6s ease-out forwards;
}
@keyframes dd025-card-just-arrived {
    0% {
        box-shadow: 0 0 0 2px var(--dd025-accent),
                    0 0 18px rgba(96, 165, 250, 0.55);
        background: color-mix(in srgb, var(--dd025-accent) 14%, var(--dd025-surface));
    }
    25% {
        box-shadow: 0 0 0 1px var(--dd025-accent),
                    0 0 6px rgba(96, 165, 250, 0.30);
        background: color-mix(in srgb, var(--dd025-accent) 7%, var(--dd025-surface));
    }
    50% {
        box-shadow: 0 0 0 2px var(--dd025-accent),
                    0 0 18px rgba(96, 165, 250, 0.55);
        background: color-mix(in srgb, var(--dd025-accent) 14%, var(--dd025-surface));
    }
    100% {
        box-shadow: 0 0 0 0 transparent, 0 0 0 transparent;
        background: var(--dd025-surface);
    }
}
@media (prefers-reduced-motion: reduce) {
    .dd025-card--just-arrived {
        animation: none !important;
        box-shadow: 0 0 0 2px var(--dd025-accent);
    }
}

/* "Already opened" — fold + heavily dim. State persists in
   localStorage so the affordance survives reloads. Expanded cards
   fully bright (analyst is reading them now); only the collapsed-
   and-seen cards collapse to a title-only line so the column
   skim-flow stays focused on unread items. Hover lifts toward
   readable so the analyst can re-engage. */
.dd025-card--seen:not(.dd025-card--expanded) {
    opacity: 0.40;
    padding: 6px 10px 6px 12px;
}
.dd025-card--seen:not(.dd025-card--expanded):hover {
    opacity: 0.85;
}
/* Hide the heavy parts — only the title remains visible. The byline
   avatar / source name / time, the summary excerpt, and the matched-
   tag chip strip all collapse out. */
.dd025-card--seen:not(.dd025-card--expanded) .dd025-card-byline,
.dd025-card--seen:not(.dd025-card--expanded) .dd025-card-summary,
.dd025-card--seen:not(.dd025-card--expanded) .dd025-card-chips {
    display: none;
}
.dd025-card--seen:not(.dd025-card--expanded) .dd025-card-title {
    /* Single-line clamp, smaller weight. The full title is still
       reachable via title attribute / hover-to-expand. */
    -webkit-line-clamp: 1;
    font-size: 0.82rem;
    font-weight: 400;
    margin-bottom: 0;
}

/* DD-025 grouping suggestion banner — surfaces above the column body
   when the platform's auto-detection finds a meaningful cluster and
   the user hasn't already configured grouping or dismissed this key. */
.dd025-sugg-banner {
    background: linear-gradient(135deg, var(--dd025-accent-strong)18, #a371f718);
    border: 1px solid var(--dd025-accent-strong)44;
    border-radius: 6px;
    padding: 8px 10px;
    margin: 0 0 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.78rem;
}
.dd025-sugg-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.dd025-sugg-label {
    color: var(--dd025-text);
    font-weight: 500;
}
.dd025-sugg-preview {
    color: var(--dd025-text-muted);
    font-size: 0.72rem;
}
.dd025-sugg-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.dd025-sugg-btn {
    background: transparent;
    border: 1px solid var(--dd025-border);
    color: var(--dd025-text);
    padding: 4px 10px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.72rem;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.dd025-sugg-btn:hover {
    background: var(--dd025-surface-hover);
    border-color: var(--dd025-accent);
}
.dd025-sugg-btn--accept {
    background: var(--dd025-accent-strong);
    border-color: var(--dd025-accent-strong);
    color: #ffffff;
    font-weight: 500;
}
.dd025-sugg-btn--accept:hover { background: var(--dd025-accent-hover); border-color: var(--dd025-accent-hover); }

/* "Show me" suggestion-preview modal. Listed candidates the rule
   would group: title, source · published, snippet. Pure preview —
   accept lives back on the banner. */
.dd025-sugg-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 1100;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 6vh 1rem 2rem;
}
.dd025-sugg-modal-dialog {
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-border);
    border-radius: 10px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
    width: min(720px, 96vw);
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.dd025-sugg-modal-header {
    position: relative;
    padding: 14px 48px 14px 18px;
    border-bottom: 1px solid var(--dd025-border);
    background: var(--dd025-surface);
}
.dd025-sugg-modal-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--dd025-text-bright);
    line-height: 1.35;
}
.dd025-sugg-modal-subtitle {
    margin-top: 3px;
    color: var(--dd025-text-muted);
    font-size: 0.78rem;
}
.dd025-sugg-modal-close {
    position: absolute;
    top: 8px;
    right: 8px;
    background: transparent;
    border: none;
    color: var(--dd025-text-muted);
    cursor: pointer;
    font-size: 1.4rem;
    line-height: 1;
    padding: 4px 10px;
    border-radius: 6px;
}
.dd025-sugg-modal-close:hover {
    background: var(--dd025-surface-hover);
    color: var(--dd025-text-bright);
}
.dd025-sugg-modal-body {
    overflow-y: auto;
    padding: 6px 0;
    flex: 1 1 auto;
}
.dd025-sugg-modal-cluster-label {
    padding: 10px 18px 4px;
    color: var(--dd025-text-dim);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.dd025-sugg-modal-row {
    padding: 10px 18px;
    border-bottom: 1px solid var(--dd025-border);
}
.dd025-sugg-modal-row:last-child { border-bottom: none; }
.dd025-sugg-modal-row-title {
    color: var(--dd025-text-bright);
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.35;
}
.dd025-sugg-modal-row-meta {
    margin-top: 2px;
    color: var(--dd025-text-muted);
    font-size: 0.74rem;
}
.dd025-sugg-modal-row-snippet {
    margin-top: 6px;
    color: var(--dd025-text);
    font-size: 0.82rem;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.dd025-sugg-modal-empty {
    padding: 24px 20px;
    color: var(--dd025-text-muted);
    font-size: 0.85rem;
    font-style: italic;
    text-align: center;
}

/* Grouped-card wrapper — primary card on top, expand pill below,
   siblings indented when expanded. The wrap is a "raised tray":
   slightly lighter than the column body (var(--dd025-surface)) and tinted with
   the column's own accent at very low alpha so the group both reads
   as a contained unit AND inherits a hint of column identity. The
   inside cards (var(--dd025-bg) background) stay darker so they pop forward
   against the tray. */
.dd025-group-wrap {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 4px 4px 6px;
    /* `--dd025-group-tray-fallback` controls the colour mixed under the
       column accent — a slightly-lighter-than-body tint that reads as
       a "raised tray". Override in body.light for the bright theme. */
    border: 1px solid color-mix(in srgb, var(--col-accent, var(--dd025-accent)) 18%, var(--dd025-group-border-base, #2a323b));
    border-radius: 6px;
    background: color-mix(in srgb, var(--col-accent, var(--dd025-accent)) 4%, var(--dd025-group-tray-base, #1d242e));
}
body.light {
    --dd025-group-border-base: #cbd5e1;
    --dd025-group-tray-base:   #f1f5f9;
}
.dd025-group-pill {
    background: transparent;
    border: 1px dashed var(--dd025-border);
    color: var(--dd025-text-muted);
    padding: 5px 12px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.72rem;
    align-self: flex-start;
    margin-left: 8px;
    transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;
}
.dd025-group-pill:hover {
    border-color: var(--dd025-accent);
    color: var(--dd025-accent);
    background: var(--dd025-accent-strong)11;
}
.dd025-group-pill.is-open {
    border-style: solid;
    border-color: var(--dd025-accent);
    color: var(--dd025-accent);
}
.dd025-card--sibling {
    margin-left: 10px;
    border-left-width: 2px;
}

.dd025-bucket-divider {
    color: var(--dd025-text-dim);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 8px 4px 4px;
    margin: 4px 0 2px;
    border-bottom: 1px solid var(--dd025-surface-hover);
}
/* No top margin / padding above the very first divider so the column
   body doesn't get an awkward gap at the top. */
.dd025-col-body > .dd025-bucket-divider:first-child {
    padding-top: 2px;
    margin-top: 0;
}

.dd025-card-byline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

.dd025-card-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex: 0 0 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--dd025-text-bright);
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    object-fit: cover;
    background-color: var(--dd025-surface-hover);
}
.dd025-card-avatar--favicon {
    background-color: #ffffff;
    background-size: 70%;
    background-position: center;
    background-repeat: no-repeat;
}

.dd025-card-byline-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    overflow: hidden;
    flex: 1 1 auto;
}
.dd025-card-byline-name {
    color: var(--dd025-text);
    font-size: 0.78rem;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd025-card-byline-time {
    color: var(--dd025-text-dim);
    font-size: 0.7rem;
}

.dd025-card-title {
    color: var(--dd025-text-bright);
    font-size: 0.95rem;
    line-height: 1.35;
    margin-bottom: 6px;
    font-weight: 500;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

.dd025-card-summary {
    color: var(--dd025-text-muted);
    font-size: 0.8rem;
    line-height: 1.4;
    margin-bottom: 10px;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}
.dd025-card-summary--full {
    display: block;
    -webkit-line-clamp: unset;
    overflow: visible;
}

.dd025-card--expanded {
    background: var(--dd025-surface-elev);
    border-color: var(--dd025-accent)66;
}
.dd025-card--expanded .dd025-card-title {
    -webkit-line-clamp: unset;
    overflow: visible;
    display: block;
}

.dd025-card-details {
    border-top: 1px solid var(--dd025-surface-hover);
    padding-top: 10px;
    margin-bottom: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.78rem;
}
.dd025-card-detail-row {
    display: flex;
    gap: 10px;
    color: var(--dd025-text-muted);
    align-items: baseline;
}
.dd025-card-detail-label {
    color: var(--dd025-text-dim);
    flex: 0 0 70px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.dd025-card-detail-link {
    color: var(--dd025-accent);
    text-decoration: none;
    word-break: break-all;
    overflow-wrap: anywhere;
}
.dd025-card-detail-link:hover { text-decoration: underline; }

.dd025-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 10px;
}

.dd025-chip {
    background: var(--dd025-surface-hover);
    color: var(--dd025-text-muted);
    padding: 1px 6px;
    border-radius: 8px;
    font-size: 0.65rem;
    border: 1px solid transparent;
}
.dd025-chip-matched {
    color: var(--dd025-accent);
    border-color: var(--dd025-accent-strong)55;
    background: var(--dd025-accent-deep);
}

/* DD-027 — package-tier chip rows on the expanded card. The label
   column reuses dd025-card-detail-label so widths line up with the
   "Published" / "Original" rows above. Pills inherit the same neutral
   gray as the baseline chips above them; the only thing that stands
   out is the matched-blue chip (override below) so an analyst's eye
   immediately lands on the values that put the article in this
   column. */
.dd025-card-pkg-row { align-items: flex-start; }
.dd025-card-pkg-label { padding-top: 2px; }
.dd025-card-pkg-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    flex: 1;
}
/* Matched chip class wins regardless of which family the chip is in;
   no per-prefix accent so non-matched values stay quiet. */
.dd025-chip-pkg.dd025-chip-matched {
    background: var(--dd025-accent-deep);
    border-color: var(--dd025-accent-strong)55;
    color: var(--dd025-accent);
}

/* DD-026 v2 — baseline category + topic rows on the expanded card.
   Reuse the package-row container CSS (.dd025-card-pkg-row + .dd025-card-pkg-chips)
   so the prefix-label column lines up with sector / actor below. The
   non-matched chip stays the same neutral gray as a tag/topical chip;
   only the matched override (.dd025-chip-baseline.dd025-chip-matched)
   lights up in blue. */
.dd025-chip-baseline.dd025-chip-matched {
    background: var(--dd025-accent-deep);
    border-color: var(--dd025-accent-strong)55;
    color: var(--dd025-accent);
}

/* DD-028 — admin-only "decisions" row on the expanded card. Approved
   chips read green; rejected chips read red. They use the same
   .dd025-chip-baseline shape as the category/topic rows above so the
   visual rhythm of the expanded card stays consistent — only the
   colour family changes per status, signalling "diagnostic" rather
   than "filter dimension". */
.dd025-chip-decision-approved {
    background: rgba(63, 185, 113, 0.10);
    border-color: rgba(63, 185, 113, 0.45);
    color: var(--dd025-success);
}
.dd025-chip-decision-rejected {
    background: rgba(248, 81, 73, 0.10);
    border-color: rgba(248, 81, 73, 0.45);
    color: var(--dd025-error);
}

/* DD-027 — section header in the streams typeahead dropdown. Groups
   suggestions by dimension (sectors, topics, tags, …) so an analyst
   looking for an industry sees every sector together rather than
   mixed in by global popularity. Non-selectable; keyboard navigation
   skips them automatically because they aren't `.dd025-typeahead-item`. */
.dd025-typeahead-section {
    padding: 6px 10px 3px 10px;
    font-size: 0.6rem;
    font-weight: 600;
    color: var(--dd025-text-dim);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-top: 1px solid var(--dd025-surface-hover);
}
.dd025-typeahead-section:first-child { border-top: 0; }

/* Transient placeholder while a typeahead query is debouncing or
   in flight. Same indent as items so the row doesn't jump when
   results arrive; muted color signals "not interactive yet".
   Italic vs the bold uppercase section headers above so the two
   non-clickable row types read as visually different. */
.dd025-typeahead-loading {
    padding: 8px 10px;
    color: var(--dd025-text-muted);
    font-size: 0.85rem;
    font-style: italic;
}

/* Save button busy state — disabled attribute already styles the
   button gray, this just guarantees we don't get a hover-flicker
   from `.btn-streams-primary:hover` while the network is in flight. */
.btn-streams-primary[disabled],
.btn-streams-primary[disabled]:hover {
    opacity: 0.65;
    cursor: progress;
}

.dd025-col-empty {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--dd025-text-muted);
    text-align: center;
    padding: 1rem;
    font-size: 0.85rem;
}

.dd025-add-tile {
    flex: 0 0 280px;
    width: 280px;
    height: 100%;
    background: transparent;
    border: 1px dashed var(--dd025-border);
    border-radius: 6px;
    color: var(--dd025-text-muted);
    cursor: pointer;
    font-size: 0.95rem;
    transition: border-color 120ms ease, color 120ms ease;
}
.dd025-add-tile:hover { border-color: var(--dd025-accent); color: var(--dd025-accent); }

.dd025-new-pill {
    position: absolute;
    top: 50px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--dd025-accent-strong);
    color: white;
    border-radius: 14px;
    padding: 3px 10px;
    font-size: 0.7rem;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
    border: none;
}

/* Filter editor modal */

.dd025-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.dd025-modal {
    background: var(--dd025-surface);
    border: 1px solid var(--dd025-border);
    border-radius: 6px;
    width: 820px;
    max-width: 95vw;
    max-height: 90vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.dd025-modal-header {
    padding: 14px 18px;
    border-bottom: 1px solid var(--dd025-border);
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.dd025-modal-header h2 { margin: 0; font-size: 1.1rem; color: var(--dd025-text-bright); }

.dd025-modal-body { padding: 18px; }

.dd025-modal-footer {
    padding: 14px 18px;
    border-top: 1px solid var(--dd025-border);
    display: flex;
    /* Space-between so the destructive Delete button sits on the
       far left and the safe Cancel/Save pair sits on the far right.
       Visually separates the "remove this entirely" affordance from
       the routine save/cancel controls so a misclick is harder. */
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
.dd025-modal-footer-actions {
    display: flex;
    gap: 8px;
}

.dd025-form-row { margin-bottom: 16px; }
.dd025-form-row label {
    display: block;
    margin-bottom: 6px;
    color: var(--dd025-text-muted);
    font-size: 0.8rem;
    font-weight: 500;
}
/* Direct child only — without `>` this rule also styles the chip
   input's typing field (which is nested two levels deep inside
   `.dd025-chip-input`), painting an inner border + background that
   reads as a "box in the box" inside the chip input. The chip
   input has its own minimal style for the inner <input> already. */
.dd025-form-row > input[type="text"] {
    width: 100%;
    padding: 8px 10px;
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-border);
    color: var(--dd025-text-bright);
    border-radius: 4px;
    font-size: 0.9rem;
}

.dd025-chip-input {
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-border);
    border-radius: 4px;
    padding: 6px 8px;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
    min-height: 36px;
    cursor: text;
    position: relative;
}
.dd025-chip-input input {
    flex: 1 0 80px;
    background: transparent;
    border: none;
    color: var(--dd025-text-bright);
    outline: none;
    font-size: 0.85rem;
    padding: 2px 4px;
}
.dd025-selected-chip {
    background: var(--dd025-accent-tint);
    color: var(--dd025-accent);
    border: 1px solid var(--dd025-accent-strong)55;
    border-radius: 10px;
    padding: 1px 8px 1px 10px;
    font-size: 0.75rem;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.dd025-selected-chip button {
    background: none;
    border: none;
    color: var(--dd025-accent);
    cursor: pointer;
    font-size: 0.9rem;
    padding: 0 2px;
    line-height: 1;
}

.dd025-typeahead {
    /* `position: fixed` so the dropdown escapes the modal's
       `overflow-y: auto` clipping (and any future modal layout that
       constrains height). JS sets top/left/width on render based on
       the input's getBoundingClientRect. z-index 1000 sits above the
       modal backdrop (.dd025-modal-backdrop has no explicit z-index,
       but inherits stacking context — 1000 is the safe high-water
       mark for app-level overlays). */
    position: fixed;
    margin-top: 2px;
    background: var(--dd025-surface);
    border: 1px solid var(--dd025-border);
    border-radius: 4px;
    max-height: 240px;
    overflow-y: auto;
    z-index: 1000;
    display: none;
}
.dd025-typeahead.open { display: block; }

.dd025-typeahead-item {
    padding: 8px 10px;
    cursor: pointer;
    color: var(--dd025-text);
    font-size: 0.85rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.dd025-typeahead-item:hover,
.dd025-typeahead-item.active {
    background: var(--dd025-accent-tint);
    color: var(--dd025-accent);
}
.dd025-typeahead-meta {
    color: var(--dd025-text-dim);
    font-size: 0.7rem;
    margin-left: 8px;
}

/* DD-026 v2 — unified prefix-chip filter editor styling. The chip's
   prefix tag is muted; the value stays bright. Per-prefix accent on the
   border picks up the same hue family as the article-detail Category /
   Topics chips so the filter editor and the rendered article speak the
   same visual language. */
.dd025-chip-prefix {
    color: var(--dd025-text-dim);
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-right: 2px;
}
.dd025-chip-value {
    font-weight: 500;
}
.dd025-selected-chip.dd025-prefix-tag {
    background: var(--dd025-accent-strong)1a;
    border-color: var(--dd025-accent-strong)55;
    color: var(--dd025-accent);
}
.dd025-selected-chip.dd025-prefix-topical {
    background: rgba(59,130,246,0.10);
    border-color: rgba(59,130,246,0.45);
    color: var(--dd025-chip-blue);
}
.dd025-selected-chip.dd025-prefix-category {
    background: rgba(168,85,247,0.10);
    border-color: rgba(168,85,247,0.45);
    color: var(--dd025-chip-purple);
}
.dd025-selected-chip.dd025-prefix-topic {
    background: rgba(34,197,94,0.10);
    border-color: rgba(34,197,94,0.45);
    color: var(--dd025-chip-green);
}

/* Typeahead-row prefix badge — same colour family as the chip but
   smaller/badge-like so the dropdown remains scannable. */
.dd025-typeahead-prefix {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-right: 8px;
    min-width: 56px;
    text-align: center;
}
.dd025-typeahead-prefix.dd025-prefix-tag      { background: var(--dd025-accent-tint); color: var(--dd025-accent); }
.dd025-typeahead-prefix.dd025-prefix-topical  { background: rgba(59,130,246,0.15); color: var(--dd025-chip-blue); }
.dd025-typeahead-prefix.dd025-prefix-category { background: rgba(168,85,247,0.15); color: var(--dd025-chip-purple); }
.dd025-typeahead-prefix.dd025-prefix-topic    { background: rgba(34,197,94,0.15); color: var(--dd025-chip-green); }

.dd025-typeahead-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dd025-form-help {
    color: var(--dd025-text-dim);
    font-size: 0.7rem;
    margin-top: 4px;
}

.dd025-error {
    color: var(--dd025-danger);
    font-size: 0.8rem;
    margin-bottom: 8px;
}
.dd025-warning {
    color: var(--dd025-warning);
    font-size: 0.8rem;
    margin-bottom: 8px;
    padding: 8px 10px;
    background: var(--dd025-warning-tint);
    border: 1px solid var(--dd025-warning-border);
    border-radius: 4px;
}

.btn-streams-primary {
    background: var(--dd025-accent-strong);
    color: white;
    border: 1px solid var(--dd025-accent-strong);
    border-radius: 4px;
    padding: 6px 14px;
    font-size: 0.85rem;
    cursor: pointer;
}
.btn-streams-primary:hover { background: var(--dd025-accent-hover); }
.btn-streams-secondary {
    background: transparent;
    color: var(--dd025-text);
    border: 1px solid var(--dd025-border);
    border-radius: 4px;
    padding: 6px 14px;
    font-size: 0.85rem;
    cursor: pointer;
}
.btn-streams-secondary:hover { background: var(--dd025-surface-hover); }
.btn-streams-danger {
    background: transparent;
    color: var(--dd025-danger);
    border: 1px solid var(--dd025-danger)44;
    border-radius: 4px;
    padding: 6px 14px;
    font-size: 0.85rem;
    cursor: pointer;
}
.btn-streams-danger:hover { background: var(--dd025-danger-tint); }

@media (max-width: 768px) {
    .dd025-rail {
        flex-direction: column;
        height: auto;
        max-height: none;
        overflow-x: hidden;
        overflow-y: visible;
    }
    .dd025-col {
        flex: 0 0 auto;
        width: 100%;
        max-width: 100%;
        height: auto;
        max-height: 70vh;
    }
    .dd025-add-tile {
        flex: 0 0 auto;
        width: 100%;
        height: 60px;
    }
}

/* ─── DD-032 — Save-for-later bookmark + popover ──────────────── */

.dd025-card-bookmark {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 2px;
    background: transparent;
    border: none;
    color: var(--dd025-text-dim);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: color 120ms ease, background 120ms ease;
}
.dd025-card-bookmark:hover {
    color: var(--dd025-accent);
    background: var(--dd025-surface-hover);
}
.dd025-card-bookmark--filled {
    color: var(--dd025-accent);
}
.dd025-card-bookmark--open {
    color: var(--dd025-accent);
    background: var(--dd025-surface-hover);
}

.dd025-bookmark-pop {
    position: absolute;
    top: 38px;
    right: 10px;
    z-index: 50;
    width: 320px;
    background: var(--dd025-surface-elev);
    border: 1px solid var(--dd025-accent);
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    cursor: default;
}

.dd025-bookmark-pop-note {
    display: flex;
    flex-direction: column;
    gap: 4px;
    border-top: 1px solid var(--dd025-surface-hover);
    padding-top: 8px;
}
.dd025-bookmark-pop-note-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    color: var(--dd025-text-dim);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.dd025-bookmark-pop-note-status {
    font-size: 0.7rem;
    color: var(--dd025-text-dim);
    text-transform: none;
    letter-spacing: 0;
    font-style: italic;
}
.dd025-bookmark-pop-note-status--saved {
    color: var(--dd025-accent);
}
.dd025-bookmark-pop-note-status--error {
    color: #d97070;
}
.dd025-bookmark-pop-textarea {
    width: 100%;
    min-height: 64px;
    resize: vertical;
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-surface-hover);
    border-radius: 4px;
    color: var(--dd025-text);
    font-size: 0.82rem;
    font-family: inherit;
    line-height: 1.4;
    padding: 6px 8px;
    box-sizing: border-box;
}
.dd025-bookmark-pop-textarea:focus {
    outline: none;
    border-color: var(--dd025-accent);
}

.dd025-bookmark-pop-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 200px;
    overflow-y: auto;
}

.dd025-bookmark-pop-empty {
    color: var(--dd025-text-dim);
    font-size: 0.78rem;
    padding: 8px 6px;
    text-align: center;
    font-style: italic;
}

.dd025-bookmark-pop-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    background: transparent;
    border: none;
    border-radius: 4px;
    color: var(--dd025-text);
    font-size: 0.82rem;
    text-align: left;
    cursor: pointer;
    transition: background 100ms ease;
}
.dd025-bookmark-pop-row:hover:not(:disabled) {
    background: var(--dd025-surface-hover);
}
.dd025-bookmark-pop-row:disabled {
    opacity: 0.6;
    cursor: progress;
}
.dd025-bookmark-pop-row--in {
    color: var(--dd025-text-bright);
}
.dd025-bookmark-pop-check {
    flex: 0 0 14px;
    width: 14px;
    color: var(--dd025-accent);
    font-weight: 600;
    text-align: center;
}
.dd025-bookmark-pop-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dd025-bookmark-pop-creator {
    display: flex;
    gap: 4px;
    border-top: 1px solid var(--dd025-surface-hover);
    padding-top: 6px;
}
.dd025-bookmark-pop-input {
    flex: 1 1 auto;
    min-width: 0;
    background: var(--dd025-bg);
    border: 1px solid var(--dd025-surface-hover);
    border-radius: 4px;
    color: var(--dd025-text);
    font-size: 0.78rem;
    padding: 4px 6px;
}
.dd025-bookmark-pop-input:focus {
    outline: none;
    border-color: var(--dd025-accent);
}
.dd025-bookmark-pop-create {
    flex: 0 0 auto;
    background: var(--dd025-accent);
    border: none;
    border-radius: 4px;
    color: var(--dd025-bg);
    font-size: 0.75rem;
    font-weight: 600;
    padding: 4px 8px;
    cursor: pointer;
}
.dd025-bookmark-pop-create:disabled {
    opacity: 0.6;
    cursor: progress;
}
.dd025-bookmark-pop-error {
    color: #d97070;
    font-size: 0.72rem;
    padding: 2px 4px;
}

/* ════════════════════════════════════════════════════════════════
   COLLECTIONS — merged from collections.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* DD-032 Phase 4a — Collections index + workbench. */

/* ──────────────────────────────────────────────────────────────
   Index (/app/collections)
   ────────────────────────────────────────────────────────────── */

.dd032-collections-index {
    max-width: 1100px;
    margin: 0 auto;
}

.dd032-loading {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--text-muted);
}

.dd032-empty {
    padding: 2rem 1.5rem;
    text-align: center;
    color: var(--text-muted);
    border: 1px dashed var(--bg-hover);
    border-radius: 8px;
    background: var(--bg-card);
    margin-bottom: 1.5rem;
}
.dd032-empty p {
    margin: 0;
    line-height: 1.55;
    max-width: 40rem;
    margin-left: auto;
    margin-right: auto;
}

.dd032-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.dd032-tile {
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--bg-hover);
    border-radius: 8px;
    padding: 1.1rem 1.2rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 120ms ease, transform 120ms ease;
}
.dd032-tile:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}

.dd032-tile-header {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
}

.dd032-tile-name {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dd032-tile-pill {
    background: rgba(96, 165, 250, 0.12);
    color: var(--accent);
    font-size: 0.65rem;
    padding: 0.15rem 0.45rem;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    flex: 0 0 auto;
}

.dd032-tile-meta {
    display: flex;
    gap: 0.8rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-bottom: 0.6rem;
}

.dd032-tile-preview {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}
.dd032-tile-preview--empty {
    font-style: italic;
    color: var(--text-dim);
}

/* "+ New collection" creator block */
.dd032-creator {
    background: var(--bg-card);
    border: 1px solid var(--bg-hover);
    border-radius: 8px;
    padding: 1.1rem 1.2rem;
}
.dd032-creator-label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 0.6rem;
}
.dd032-creator-row {
    display: flex;
    gap: 0.6rem;
}
.dd032-creator-input {
    flex: 1 1 auto;
    background: var(--bg);
    border: 1px solid var(--bg-hover);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.95rem;
    padding: 0.55rem 0.8rem;
}
.dd032-creator-input:focus {
    outline: none;
    border-color: var(--accent);
}
.dd032-creator-button {
    flex: 0 0 auto;
    background: var(--accent);
    color: var(--bg);
    border: none;
    border-radius: 6px;
    padding: 0.55rem 1rem;
    font-weight: 600;
    cursor: pointer;
}
.dd032-creator-button:hover { background: var(--accent-hover); }
.dd032-creator-button:disabled { opacity: 0.55; cursor: progress; }
.dd032-creator-error {
    margin-top: 0.6rem;
    font-size: 0.82rem;
    color: #ef4444;
}

/* ──────────────────────────────────────────────────────────────
   Workbench (/app/collections/{uid})
   ────────────────────────────────────────────────────────────── */

.dd032-workbench {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 1rem;
}

/* Header block */
.dd032-wb-header {
    border-bottom: 1px solid var(--bg-hover);
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
}

.dd032-wb-titlerow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.dd032-wb-titlecol {
    display: flex;
    align-items: baseline;
    gap: 0.8rem;
}

.dd032-wb-name {
    margin: 0;
    font-size: 1.55rem;
    font-weight: 600;
    color: var(--text);
    cursor: text;
    border-radius: 4px;
    padding: 0.1rem 0.3rem;
    margin-left: -0.3rem;
    transition: background 0.12s ease;
}

.dd032-wb-name:hover {
    background: rgba(255, 255, 255, 0.04);
}

.dd032-wb-pill {
    background: rgba(96, 165, 250, 0.12);
    color: var(--accent);
    font-size: 0.7rem;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.dd032-wb-rename-input {
    background: var(--bg);
    border: 1px solid var(--accent);
    border-radius: 6px;
    color: var(--text);
    font-size: 1.55rem;
    font-weight: 600;
    padding: 0.3rem 0.6rem;
    width: 24rem;
    max-width: 100%;
}

/* Article-rail head — sits above the cards. Hosts `+ Add sources`
 * (content-mutation belongs WITH the content, not in the page
 * toolbar). Label and action sit together on the left so the row
 * reads as one unit — stranding the button on the far right of a
 * wide deck made the connection between them ambiguous. */
.dd032-wb-rail-head {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.8rem;
    padding: 0.4rem 0 0.6rem 0;
    border-bottom: 1px solid var(--border, var(--bg-hover));
    margin-bottom: 0.8rem;
}
.dd032-wb-rail-head-label {
    color: var(--text-muted);
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.dd032-wb-articles {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* `.dd032-wb-action*` retained for the Draft-Report modal buttons
 * (and any other in-page modal that still uses them). Page-chrome
 * actions now use `.btn .btn-small` / `.btn-primary`. */
.dd032-wb-action {
    background: transparent;
    border: 1px solid var(--bg-hover);
    color: var(--text-muted);
    border-radius: 6px;
    padding: 0.35rem 0.7rem;
    font-size: 0.82rem;
    cursor: pointer;
    transition: border-color 120ms ease, color 120ms ease;
}
.dd032-wb-action:hover {
    border-color: var(--accent);
    color: var(--accent);
}
.dd032-wb-action--danger:hover {
    border-color: #ef4444;
    color: #ef4444;
}
.dd032-wb-action--primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--bg);
}
.dd032-wb-action--primary:hover {
    background: transparent;
    color: var(--accent);
}
.dd032-wb-action--primary:disabled {
    opacity: 0.55;
    cursor: progress;
}

/* Header right-side detail. Sits between the primary actions and
 * the overflow ⋯ menu. The previous `dd032-wb-meta` row (under the
 * title) duplicated info already shown elsewhere; this is the
 * timestamp only. */
.dd032-wb-last-touched {
    color: var(--text-muted);
    font-size: 0.78rem;
    white-space: nowrap;
}

/* Inline "saving…" indicator next to article-note labels. */
.dd032-wb-saving {
    color: var(--accent);
    font-size: 0.78rem;
    font-style: italic;
}

.dd032-wb-error {
    margin-top: 0.6rem;
    color: #ef4444;
    font-size: 0.85rem;
}

/* Overview section — sticky at the top of the scroll container.
 * Combines document count, "+ Add documents" button, and the
 * Working Note. Replaces the standalone working-note sticky block
 * and the rail-head row that used to sit above the deck. */
.dd032-wb-overview {
    position: sticky;
    top: 0;
    z-index: 10;
    margin-bottom: 1.4rem;
    background: var(--bg-card);
    border: 1px solid var(--bg-hover);
    border-left: 3px solid var(--accent);
    border-radius: 8px;
    padding: 0.85rem 1rem 1rem;
    box-shadow: 0 6px 14px -4px rgba(0, 0, 0, 0.45),
                0 2px 4px rgba(0, 0, 0, 0.25);
}
.dd032-wb-overview::before {
    /* Mask the viewport-top sliver above the rounded corners so
     * scrolling cards don't briefly show through. */
    content: '';
    position: absolute;
    left: -1px;
    right: -1px;
    top: -0.6rem;
    height: 0.6rem;
    background: var(--bg);
    pointer-events: none;
}
.dd032-wb-overview-head {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin-bottom: 0.7rem;
}
.dd032-wb-overview-count {
    flex: 1;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.dd032-wb-overview-note {
    /* Note sits below the head row inside the same sticky card. */
}

/* Inline Explore section retired 2026-05-19 in favour of an
 * off-canvas drawer (see `.dd032-wb-fd-*`). The deck owns the
 * viewport on first paint; the drawer is summoned via the
 * Filter / Explore button in the Overview head. */

/* Overview action cluster — Filter button + Add documents button. */
.dd032-wb-overview-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.dd032-wb-filter-btn {
    position: relative;
}
.dd032-wb-filter-btn--open {
    background: var(--accent);
    color: var(--bg);
    border-color: var(--accent);
}
.dd032-wb-filter-btn-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.1rem;
    padding: 0 0.3rem;
    margin-left: 0.4rem;
    background: var(--accent);
    color: var(--bg);
    font-size: 0.7rem;
    font-weight: 700;
    border-radius: 99px;
    line-height: 1;
}
.dd032-wb-filter-btn--open .dd032-wb-filter-btn-badge {
    background: var(--bg);
    color: var(--accent);
}

/* Off-canvas Filter / Explore drawer. Backdrop is a fixed overlay
 * that catches outside clicks; the panel slides in from the
 * right edge. Both fade/translate together when state flips.
 * `pointer-events: none` on the closed backdrop is critical —
 * without it the invisible overlay would block clicks on the
 * deck. */
.dd032-wb-fd-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: opacity 200ms ease, visibility 200ms;
    z-index: 100;
    pointer-events: none;
}
.dd032-wb-fd-backdrop--open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.dd032-wb-fd-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(420px, 100vw);
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    box-shadow: -10px 0 30px -10px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 200ms ease;
}
.dd032-wb-fd-panel--open {
    transform: translateX(0);
}
.dd032-wb-fd-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.9rem 1rem;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.dd032-wb-fd-title {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
}
.dd032-wb-fd-close {
    background: transparent;
    border: 0;
    color: var(--text-muted);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
}
.dd032-wb-fd-close:hover {
    background: var(--bg-hover);
    color: var(--text);
}
.dd032-wb-fd-body {
    flex: 1;
    overflow-y: auto;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

/* Work-product-structure section — header above the document deck. */
.dd032-wb-deck-heading {
    margin: 0 0 0.7rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.dd032-wb-working-label {
    display: block;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}
.dd032-wb-working-hint {
    color: var(--text-dim);
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.78rem;
    font-weight: 400;
    font-style: italic;
}
.dd032-wb-working-textarea {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--bg-hover);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.95rem;
    line-height: 1.55;
    padding: 0.7rem 0.9rem;
    resize: vertical;
    font-family: inherit;
}
.dd032-wb-working-textarea:focus {
    outline: none;
    border-color: var(--accent);
}

/* Article cards */
.dd032-wb-loading {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--text-muted);
}

.dd032-wb-empty {
    padding: 2rem 1.5rem;
    text-align: center;
    color: var(--text-muted);
    border: 1px dashed var(--bg-hover);
    border-radius: 8px;
    background: var(--bg-card);
}
.dd032-wb-empty p {
    margin: 0;
    line-height: 1.55;
    max-width: 38rem;
    margin-left: auto;
    margin-right: auto;
}

.dd032-wb-cards {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
/* Click-to-expand hint shown once above the deck — the cards
 * themselves are intentionally minimal (no per-card chevron), so
 * this one-liner carries the affordance for the whole list. */
.dd032-wb-cards-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    font-style: italic;
    padding: 0 0.1rem 0.3rem;
}

.dd032-wb-card {
    background: var(--bg-card);
    border: 1px solid var(--bg-hover);
    border-left: 3px solid var(--accent);
    border-radius: 6px;
    padding: 0.6rem 0.9rem;
    cursor: pointer;
    transition: border-color 120ms ease;
}
.dd032-wb-card--expanded {
    /* Extra right padding reserves space for the × remove button
     * in the top-right corner so it can't collide with the date
     * pill on the title row. */
    padding: 0.9rem 1rem 0.7rem 1rem;
}
/* Title row of an expanded card explicitly reserves right space
 * for the × button. Padding alone on the card wasn't enough — the
 * date pill is `flex-shrink: 0` and was being rendered into the
 * area the × occupies. This forces the date pill to stop with a
 * clear gap. */
.dd032-wb-card--expanded .dd032-wb-card-titlerow {
    padding-right: 2.5rem;
}
.dd032-wb-card:hover {
    border-color: var(--accent);
}
.dd032-wb-card--expanded {
    background: var(--bg-hover);
}
.dd032-wb-card--loading {
    opacity: 0.55;
    cursor: progress;
}

.dd032-wb-card-byline {
    display: flex;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-bottom: 0.4rem;
}
.dd032-wb-card-source { font-weight: 500; color: var(--text); }
.dd032-wb-card-sep { opacity: 0.5; }

/* Title row — inline layout: [ date pill ] [ title (flex) ]
 * [ source pill ]. Pills are vertically centered against the
 * title; the summary line sits directly below this row. */
.dd032-wb-card-titlerow {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.3rem;
}
.dd032-wb-card-title {
    flex: 1;
    min-width: 0;
    color: var(--text);
    font-size: 0.95rem;
    line-height: 1.35;
    font-weight: 500;
}

/* Favicon on the far-left of the title row. Plain icon wrapped in
 * a container so we can attach a hover-popover with source
 * details next to it. The wrapper is the hover target; the
 * popover is positioned absolutely so it doesn't push the title
 * around. */
.dd032-wb-card-favicon-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    cursor: default;
    outline: none;
}
.dd032-wb-card-favicon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    border-radius: 2px;
}
.dd032-wb-card-favicon--placeholder {
    display: inline-block;
}

/* Source popover. Sits flush below the favicon (no gap that
 * would break the hover) with a transparent `::before` extending
 * upward over the favicon so the cursor can travel from icon to
 * popover without leaving the hover area. Stays visible while
 * the cursor is anywhere over the wrapper OR the popover (CSS
 * keeps the popover inside the wrapper, so :hover on the wrapper
 * covers both regions). */
.dd032-wb-source-pop {
    position: absolute;
    top: 100%;
    left: -0.5rem;
    z-index: 20;
    /* Wide-and-shallow: prefer horizontal space over vertical
     * stack height. Description sits on one tight 2-line clamp;
     * the two action links sit on a single row at the bottom. */
    width: 26rem;
    max-width: 32rem;
    padding: 0.6rem 0.8rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 6px 16px -4px rgba(0, 0, 0, 0.4),
                0 2px 4px rgba(0, 0, 0, 0.2);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-2px);
    transition: opacity 120ms ease, transform 120ms ease, visibility 120ms;
    pointer-events: none;
}
/* Transparent hover-bridge above the popover that covers the
 * favicon + a small buffer. Keeps the cursor inside the wrapper's
 * hover region as it moves from the icon into the popover. */
.dd032-wb-source-pop::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -1.5rem;
    height: 1.5rem;
    background: transparent;
}
.dd032-wb-card-favicon-wrap:hover .dd032-wb-source-pop,
.dd032-wb-card-favicon-wrap:focus-within .dd032-wb-source-pop {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto;
}
.dd032-wb-source-pop-name {
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.3;
}
.dd032-wb-source-pop-host {
    color: var(--text-muted);
    font-size: 0.7rem;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    margin-top: 0.2rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd032-wb-source-pop-desc {
    margin-top: 0.35rem;
    color: var(--text);
    font-size: 0.78rem;
    line-height: 1.4;
    /* 2-line clamp keeps the popover shallow; wider width
     * (26rem) gives enough horizontal room that 2 lines fit
     * roughly 30-40 words of description. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
.dd032-wb-source-pop-desc--empty {
    color: var(--text-muted);
    font-style: italic;
}
.dd032-wb-source-pop-meta {
    margin-top: 0.4rem;
    display: flex;
    gap: 0.4rem;
    font-size: 0.7rem;
}
.dd032-wb-source-pop-meta-k {
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.dd032-wb-source-pop-meta-v {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
/* Action links sit side-by-side at the bottom rather than
 * stacked so the popover stays shallow. */
.dd032-wb-source-pop-actions {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    margin-top: 0.5rem;
}
.dd032-wb-source-pop-link {
    color: var(--accent);
    text-decoration: none;
    font-size: 0.78rem;
}
.dd032-wb-source-pop-link--external {
    color: var(--text-muted);
}
.dd032-wb-source-pop-link:hover {
    text-decoration: underline;
    color: var(--accent);
}
/* Date on the far-right of the title row — bold short form. */
.dd032-wb-card-date {
    flex-shrink: 0;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
}

/* Collapsed state — single-line ellipsised summary excerpt under
 * the title. Stays dense so the deck reads as a list, not a feed.
 * Expanded blows out to a full paragraph block with normal flow. */
.dd032-wb-card-summary {
    color: var(--text-muted);
    font-size: 0.82rem;
    line-height: 1.4;
    margin-bottom: 0;
    /* Indent past the favicon column so the summary text aligns
     * with where the title begins (16px favicon + 0.6rem flex
     * gap ≈ 1.6rem; round to 1.8rem for breathing room). */
    padding-left: 1.8rem;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dd032-wb-card-summary--full {
    display: block;
    -webkit-line-clamp: unset;
    overflow: visible;
    font-size: 0.88rem;
    line-height: 1.5;
    margin-bottom: 0.4rem;
    padding-left: 1.8rem;
}

.dd032-wb-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.3rem;
}
.dd032-wb-card-chip {
    background: rgba(96, 165, 250, 0.08);
    color: var(--accent);
    font-size: 0.72rem;
    padding: 0.15rem 0.45rem;
    border-radius: 4px;
}
.dd032-wb-card-chip--more {
    background: transparent;
    color: var(--text-muted);
}

/* Per-card insights rows — one row per category surfaced by the
   analyst's subscribed packages. Each category carries its own
   accent (CSS var `--insight-accent` set via [data-category-slug])
   so the eye groups by category without reading the label first.
   Categories the engine doesn't know about fall through to the
   neutral default tint. */
.dd032-wb-card-insights {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.9rem;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--border, rgba(148, 163, 184, 0.18));
}
.dd032-wb-card-insight-row {
    display: grid;
    grid-template-columns: 10.5rem 1fr;
    gap: 1.25rem;
    align-items: start;
    --insight-accent: 148, 163, 184;        /* neutral fallback */
}
.dd032-wb-card-insight-label {
    font-size: 0.66rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding-top: 0.2rem;
    position: relative;
    padding-left: 0.7rem;
    white-space: nowrap;
}
.dd032-wb-card-insight-label::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.4rem;
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: rgb(var(--insight-accent));
}
.dd032-wb-card-insight-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}
.dd032-wb-card-insight-chip {
    background: rgba(var(--insight-accent), 0.10);
    color: var(--text);
    font-size: 0.72rem;
    line-height: 1.1;
    padding: 0.18rem 0.5rem;
    border-radius: 4px;
    border: 1px solid rgba(var(--insight-accent), 0.22);
}
.dd032-wb-card-insight-chip--more {
    background: transparent;
    border-color: transparent;
    color: var(--text-muted);
}

/* Per-category accents. Slugs are computed JS-side from the
   server-supplied category string (lowercase, dash-separated). Add
   a row here when a new package surfaces a new category. */
.dd032-wb-card-insight-row[data-category-slug="threat-actors"] {
    --insight-accent: 239, 68, 68;          /* red — adversary */
}
.dd032-wb-card-insight-row[data-category-slug="mitre-techniques"] {
    --insight-accent: 168, 85, 247;         /* purple — TTPs */
}
.dd032-wb-card-insight-row[data-category-slug="sectors"] {
    --insight-accent: 34, 197, 94;          /* green — context */
}
.dd032-wb-card-insight-row[data-category-slug="companies"] {
    --insight-accent: 59, 130, 246;         /* blue — entities */
}
.dd032-wb-card-insight-row[data-category-slug="products"] {
    --insight-accent: 20, 184, 166;         /* teal — assets */
}
.dd032-wb-card-insight-row[data-category-slug="vulnerabilities"] {
    --insight-accent: 245, 158, 11;         /* amber — weakness */
}

/* Tighter columns on narrow viewports — the 8.5rem label column
   eats too much when the card itself is narrow. Below 720px the
   label sits above its chip row. */
@media (max-width: 720px) {
    .dd032-wb-card-insight-row {
        grid-template-columns: 1fr;
        gap: 0.25rem;
    }
}

/* Card expanded section */
.dd032-wb-card-expanded {
    margin-top: 0.8rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--bg-hover);
}

.dd032-wb-card-note {
    margin-bottom: 0.8rem;
}
.dd032-wb-card-note-label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 0.35rem;
}
.dd032-wb-card-note-loading {
    color: var(--text-dim);
    font-style: italic;
    font-size: 0.82rem;
    padding: 0.5rem 0;
}
.dd032-wb-card-note-textarea {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--bg-hover);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.5;
    padding: 0.55rem 0.75rem;
    resize: vertical;
    font-family: inherit;
}
.dd032-wb-card-note-textarea:focus {
    outline: none;
    border-color: var(--accent);
}

/* Expanded-card action row — View Details / Open Original Page
 * on the left, spacer, move-to-section dropdown at the far right.
 * Action affordances now use the global `.btn` styles (`.btn-primary`
 * for the View Details CTA) so they read as buttons, not link
 * text. The legacy `.dd032-wb-card-action` muted-link styling is
 * retained as a fallback for any non-styled action that may still
 * appear in this row. */
.dd032-wb-card-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}
.dd032-wb-card-actions-spacer {
    flex: 1 1 auto;
}
.dd032-wb-card-action {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.dd032-wb-card-action-icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    display: inline-block;
    vertical-align: -2px;
}
.dd032-wb-card-actions .dd032-wb-card-section-select {
    margin: 0;
}

/* Top-right × — remove this article from the Work Product. Only
 * rendered when the card is expanded so collapsed-scan mode
 * doesn't show destructive controls. Hover turns danger-red to
 * reinforce intent. */
.dd032-wb-card {
    position: relative;
}
.dd032-wb-card-remove {
    position: absolute;
    top: 0.4rem;
    right: 0.5rem;
    z-index: 2;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
}
.dd032-wb-card-remove:hover {
    background: var(--danger, #ef4444);
    border-color: var(--danger, #ef4444);
    color: #fff;
}

@media (max-width: 720px) {
    .dd032-tiles {
        grid-template-columns: 1fr;
    }
    .dd032-wb-titlerow {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* ──────────────────────────────────────────────────────────────
   Phase 4b — Synthesis rail + filter bar
   ────────────────────────────────────────────────────────────── */

.dd032-wb-body {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: 1.6rem;
    align-items: start;
}
.dd032-wb-body--norail {
    grid-template-columns: 1fr;
}
/* Rail-collapsed pattern reshaped 2026-05-19 — the rail no longer
 * renders at all when collapsed; the `--norail` modifier on the
 * body wrapper (set by the JS render path when state.filterRail
 * Collapsed is true) drops to single-column so cards get full
 * width. The "▾ Filters" button that brings the rail back lives
 * in the rail-head row (see `.dd032-wb-rail-pill`). */

.dd032-wb-rail {
    /* Inline rail inside the Explore section — no longer sticky
     * or capped, no longer in its own column. Background omitted
     * so the rail blends with the Explore section's own panel. */
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
}
/* Rail-pill — horizontal "▾ Filters" toggle that sits in the
 * rail-head row when the rail is collapsed. Clicking expands the
 * rail back into its column position. */
.dd032-wb-rail-pill {
    /* Pulls towards the right neighbour (the "+ Add documents"
     * button) so the row reads as a single action cluster. */
    white-space: nowrap;
}
/* Rail-head actions group — collects every right-side button into
 * one cluster so spacing is even regardless of which buttons are
 * present (the rail-pill only appears when collapsed). */
.dd032-wb-rail-head-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
/* Header row inside the expanded rail — "Filter" label on the
 * left, collapse chevron on the right. Replaces the inner
 * group-label so the chevron has somewhere to live. */
.dd032-wb-rail-toprow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.7rem;
}
.dd032-wb-rail-toprow-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
}
.dd032-wb-rail-collapse {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: 4px;
    padding: 0.15rem 0.45rem;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: color 100ms ease, border-color 100ms ease;
}
.dd032-wb-rail-collapse:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.dd032-wb-rail-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
}
.dd032-wb-rail-hint {
    margin: 0 0 1rem;
    font-size: 0.78rem;
    color: var(--text-dim);
    line-height: 1.45;
    font-style: italic;
}
.dd032-wb-rail-section {
    margin-bottom: 1rem;
}
.dd032-wb-rail-section-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-muted);
    margin-bottom: 0.4rem;
}
.dd032-wb-rail-chips {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.dd032-wb-rail-chip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    background: transparent;
    border: 1px solid var(--bg-hover);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.85rem;
    padding: 0.3rem 0.55rem;
    cursor: pointer;
    text-align: left;
    transition: border-color 120ms ease, background 120ms ease;
}
.dd032-wb-rail-chip:hover {
    border-color: var(--accent);
}
.dd032-wb-rail-chip--active {
    background: rgba(96, 165, 250, 0.14);
    border-color: var(--accent);
    color: var(--accent);
}
.dd032-wb-rail-chip-value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}
.dd032-wb-rail-chip-count {
    flex: 0 0 auto;
    font-size: 0.72rem;
    color: var(--text-muted);
    background: var(--bg);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
}
.dd032-wb-rail-chip--active .dd032-wb-rail-chip-count {
    background: rgba(96, 165, 250, 0.22);
    color: var(--accent);
}
.dd032-wb-rail-empty {
    color: var(--text-dim);
    font-size: 0.82rem;
    font-style: italic;
}

/* Active-filter summary bar above the cards */
.dd032-wb-filterbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: 0.6rem;
    padding: 0.5rem 0.7rem;
    background: rgba(96, 165, 250, 0.06);
    border: 1px solid rgba(96, 165, 250, 0.18);
    border-radius: 6px;
    font-size: 0.82rem;
}
.dd032-wb-filterbar-label {
    color: var(--text-muted);
    font-size: 0.78rem;
}
.dd032-wb-filterchip {
    background: rgba(96, 165, 250, 0.14);
    color: var(--accent);
    border: 1px solid transparent;
    border-radius: 4px;
    padding: 0.18rem 0.5rem;
    font-size: 0.78rem;
    cursor: pointer;
}
.dd032-wb-filterchip:hover {
    background: rgba(96, 165, 250, 0.24);
}
.dd032-wb-filter-clear {
    margin-left: auto;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 0.78rem;
    cursor: pointer;
    text-decoration: underline;
}
.dd032-wb-filter-clear:hover { color: var(--accent); }
.dd032-wb-filter-empty {
    padding: 1.2rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.88rem;
    border: 1px dashed var(--bg-hover);
    border-radius: 6px;
}

/* Explore-data panel — sits between header and timeline in cards
 * mode. Holds the "Explore data" toggle and (when open) the
 * task-first field picker. The free-text search input retired
 * 2026-05-19; only the toggle + drawer remain. */
.dd032-wb-querybar {
    /* Bounding box removed 2026-05-19 — the toggle button + drawer
     * sit inside the off-canvas filter panel now, which already
     * provides the container chrome. A double-bordered nested
     * panel read as noise. */
    margin-bottom: 0;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
}
.dd032-wb-querybar-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}
.dd032-wb-query-fields-toggle {
    padding: 0.45rem 0.8rem;
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.85rem;
    cursor: pointer;
}
.dd032-wb-query-fields-toggle:hover,
.dd032-wb-query-fields-toggle--open {
    color: var(--accent);
    border-color: var(--accent);
}

.dd032-wb-query-fields-drawer {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
}
.dd032-wb-query-fields-loading,
.dd032-wb-query-fields-empty {
    color: var(--text-muted);
    font-size: 0.82rem;
    padding: 0.3rem 0;
}
.dd032-wb-query-hint {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-bottom: 0.6rem;
}
.dd032-wb-query-field-group {
    margin-bottom: 0.4rem;
}

/* Expandable task row — click to reveal fields underneath. */
.dd032-wb-explore-task {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.6rem;
    background: var(--bg-hover);
    border: 1px solid var(--border);
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
    transition: border-color 100ms ease;
}
.dd032-wb-explore-task:hover {
    border-color: var(--accent);
}
.dd032-wb-explore-task--open {
    border-color: var(--accent);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    margin-bottom: 0;
}
.dd032-wb-explore-chev {
    color: var(--text-muted);
    font-size: 0.85rem;
    width: 0.9rem;
    text-align: center;
}
.dd032-wb-explore-task-name {
    flex: 1;
    min-width: 0;
    font-size: 0.85rem;
    color: var(--text);
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd032-wb-explore-task-count {
    font-size: 0.72rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.dd032-wb-query-field-rows {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.4rem 0.5rem;
    background: var(--bg-card);
    border: 1px solid var(--accent);
    border-top: 0;
    border-radius: 0 0 4px 4px;
    margin-bottom: 0.4rem;
}
.dd032-wb-query-field-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.32rem 0.5rem;
    background: var(--bg-hover);
    color: var(--text);
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 0.78rem;
}
.dd032-wb-query-field-row .dd032-wb-query-field-path {
    flex: 1;
    min-width: 0;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd032-wb-query-field-kind {
    font-size: 0.68rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.dd032-wb-query-field-presence {
    font-size: 0.72rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.dd032-wb-query-field-add {
    padding: 0.18rem 0.55rem;
    background: transparent;
    color: var(--accent);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.72rem;
    cursor: pointer;
}
.dd032-wb-query-field-add:hover:not(:disabled) {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.dd032-wb-query-field-add--pinned {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
/* Pinned-button hover-swap: "✓ Pinned" at rest, "✕ Remove?" on
 * hover so the click outcome is obvious. The button reads as a
 * full danger action — solid red fill, bold text, white glyph —
 * so the analyst sees a button, not a link. */
.dd032-wb-query-field-add--pinned .dd032-wb-query-field-add-hover {
    display: none;
}
.dd032-wb-query-field-add--pinned:hover .dd032-wb-query-field-add-default {
    display: none;
}
.dd032-wb-query-field-add--pinned:hover .dd032-wb-query-field-add-hover {
    display: inline;
}
.dd032-wb-query-field-add--pinned:hover {
    background: var(--danger, #ef4444);
    border-color: var(--danger, #ef4444);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.25);
}
/* Prefix the hover label with an `✕` glyph so the
 * danger-action shape is obvious even at a glance. */
.dd032-wb-query-field-add-hover::before {
    content: '✕ ';
}
.dd032-wb-query-field-add--empty,
.dd032-wb-query-field-add:disabled {
    color: var(--text-muted);
    cursor: not-allowed;
    opacity: 0.55;
}

/* DD-038 Phase C.2 — pinned-field chip bar above the cards */
.dd032-wb-pinned-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
    padding: 0.5rem 0.7rem;
    background: rgba(96, 165, 250, 0.08);
    border: 1px solid rgba(96, 165, 250, 0.22);
    border-radius: 6px;
    font-size: 0.82rem;
}
.dd032-wb-pinned-label {
    font-size: 0.78rem;
    color: var(--text-muted);
}
.dd032-wb-pinned-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.5rem;
    background: var(--bg-card);
    color: var(--accent);
    border: 1px solid var(--accent);
    border-radius: 4px;
    font-size: 0.78rem;
}
.dd032-wb-pinned-chip-path {
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
}
.dd032-wb-pinned-chip-count {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.dd032-wb-pinned-chip-remove {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.1rem;
    cursor: pointer;
}
.dd032-wb-pinned-chip-remove:hover {
    color: var(--accent);
}
.dd032-wb-pinned-clear {
    margin-left: auto;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 0.78rem;
    cursor: pointer;
    text-decoration: underline;
}
.dd032-wb-pinned-clear:hover { color: var(--accent); }

/* DD-038 Phase C.4 — pinned-projection mode on article cards.
   Per-pin block is a small subtitle (path) above a row of value
   chips. No bullet/dot — the structure carries the hierarchy. */
.dd032-wb-card-insights--pinned {
    margin-top: 0.7rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--border, rgba(148, 163, 184, 0.18));
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.dd032-wb-pinned-block {
    display: block;
}
.dd032-wb-pinned-pathline {
    margin: 0 0 0.2rem 0;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
}
.dd032-wb-pinned-values {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}
.dd032-wb-pinned-value {
    background: rgba(96, 165, 250, 0.10);
    color: var(--text);
    font-size: 0.8rem;
    line-height: 1.2;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    border: 1px solid rgba(96, 165, 250, 0.22);
}
.dd032-wb-pinned-value--miss {
    background: transparent;
    color: var(--text-muted);
    font-style: italic;
    border-style: dashed;
}

/* DD-038 Phase C.5 — co-listed sibling pin grouping. When two+
   pins share a list-of-objects anchor, render one row per item
   so analyst sees vulnerability_1.cve next to its severity, etc.,
   instead of two disjoint chip strips. Each item carries a shaded
   bounding box so #1 and #2 are unambiguous at a glance. */
.dd032-wb-pinned-block--grouped {
    padding: 0.4rem 0;
}
.dd032-wb-pinned-itemrows {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.4rem;
}
.dd032-wb-pinned-itemrow {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.6rem 0.7rem 0.55rem 0.7rem;
    background: rgba(96, 165, 250, 0.05);
    border: 1px solid rgba(96, 165, 250, 0.16);
    border-radius: 6px;
}
.dd032-wb-pinned-itemrow-marker {
    flex-shrink: 0;
    min-width: 1.8rem;
    padding: 0.22rem 0.45rem;
    border-radius: 3px;
    background: rgba(96, 165, 250, 0.22);
    color: var(--accent);
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    font-size: 0.72rem;
    font-weight: 600;
    text-align: center;
    line-height: 1.2;
    align-self: center;
}
.dd032-wb-pinned-itemrow-cells {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem 1.2rem;
    flex: 1;
}
.dd032-wb-pinned-itemcell {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
    min-width: 8rem;
}
.dd032-wb-pinned-itemcell-label {
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    font-size: 0.65rem;
    font-weight: 400;
    color: var(--text-muted);
    text-transform: lowercase;
}
.dd032-wb-pinned-itemcell-value {
    background: var(--bg-card, rgba(255, 255, 255, 0.65));
    color: var(--text);
    font-size: 0.8rem;
    line-height: 1.2;
    padding: 0.2rem 0.55rem;
    border-radius: 4px;
    border: 1px solid rgba(96, 165, 250, 0.30);
    display: inline-block;
    width: fit-content;
}
.dd032-wb-pinned-itemcell-value--miss {
    background: transparent;
    color: var(--text-muted);
    font-style: italic;
    border-style: dashed;
}

@media (max-width: 900px) {
    .dd032-wb-body {
        grid-template-columns: 1fr;
    }
    .dd032-wb-rail {
        position: static;
        max-height: none;
    }
    .dd032-wb-querybar-row {
        flex-wrap: wrap;
    }
    .dd032-wb-query-input {
        flex-basis: 100%;
    }
}

/* ──────────────────────────────────────────────────────────────
   Phase 4c — view-mode toggle, timeline strip, narrative mode
   ────────────────────────────────────────────────────────────── */

/* View-mode toggle moved to the canonical `.page-header__views`
 * zone in user.css. Old `.dd032-wb-mode*` rules removed. */

/* Timeline strip — universal data, sits above the body. */
.dd032-wb-timeline {
    margin: 1.4rem 0;
    padding: 0.9rem 1rem;
    background: var(--bg-card);
    border: 1px solid var(--bg-hover);
    border-radius: 8px;
}
.dd032-wb-timeline-header {
    margin-bottom: 0.5rem;
}
.dd032-wb-timeline-hint {
    margin: 0.2rem 0 0;
    font-size: 0.78rem;
    color: var(--text-dim);
    font-style: italic;
}
.dd032-wb-timeline-svg-wrap {
    width: 100%;
    height: 70px;
}
.dd032-wb-timeline-svg {
    width: 100%;
    height: 100%;
    display: block;
}
.dd032-wb-tl-bar {
    fill: var(--accent);
    fill-opacity: 0.55;
    cursor: pointer;
    transition: fill-opacity 120ms ease;
}
.dd032-wb-tl-bar:hover {
    fill-opacity: 0.9;
}
.dd032-wb-tl-bar--active {
    fill: var(--accent);
    fill-opacity: 1;
}
.dd032-wb-timeline-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 0.3rem;
    font-size: 0.7rem;
    color: var(--text-muted);
    font-family: ui-monospace, monospace;
}

/* Narrative-mode CSS retired 2026-05-19 with the view switcher.
   `.dd032-wb-card-note-add` retained as a subtle affordance — the
   reveal-on-click pattern survives even though it no longer has a
   narrative-mode gate. */
.dd032-wb-card-note-add {
    background: transparent;
    border: 1px dashed var(--bg-hover);
    color: var(--text-muted);
    border-radius: 4px;
    padding: 0.35rem 0.7rem;
    font-size: 0.78rem;
    cursor: pointer;
    transition: border-color 120ms ease, color 120ms ease;
}
.dd032-wb-card-note-add:hover {
    border-color: var(--accent);
    color: var(--accent);
    border-style: solid;
}

/* DD-040 Phase 3a — section blocks. Renders only when the WP has
   visible sections (i.e. zero or one-default-unlabeled hides the
   chrome per Q1 lock). Each section is a header (label + question
   + actions) followed by its article cards. Unsorted bucket uses
   a softer style so it reads as "loose articles, not a real
   section". */
.dd032-wb-section {
    /* Card-like container so sections read as distinct blocks
     * instead of bleeding into each other. The header gets a
     * shaded strip; the body shows cards on the card surface. */
    margin-bottom: 1.4rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}
.dd032-wb-section:last-of-type {
    margin-bottom: 0.4rem;
}
.dd032-wb-section-header {
    padding: 0.7rem 0.9rem;
    background: var(--bg-hover);
    border-bottom: 1px solid var(--border);
}
.dd032-wb-section--folded .dd032-wb-section-header {
    border-bottom: 0;
}
.dd032-wb-section-titlerow {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}
.dd032-wb-section-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
}
.dd032-wb-section-title--unsorted {
    font-weight: 400;
    color: var(--text-muted);
    font-style: italic;
}
/* Section actions cluster (edit/delete/reorder buttons). Sits in
 * the middle of the title row — pushed right by the spacer-free
 * row but BEFORE the count, which gets its own auto-margin so it
 * lands at the far right. */
.dd032-wb-section-actions {
    margin-left: auto;
    display: flex;
    gap: 0.3rem;
}
/* Document count lives at the very far right of the title row.
 * `order: 99` keeps it last visually even when actions push it
 * around; quiet styling so it reads as metadata, not a label. */
.dd032-wb-section-count {
    margin-left: auto;
    order: 99;
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* Section body — holds the working note + cards. Padding lives
 * here rather than on the section itself so the header strip
 * butts edge-to-edge against the section border. */
.dd032-wb-section > :not(.dd032-wb-section-header) {
    padding-left: 0.9rem;
    padding-right: 0.9rem;
}
.dd032-wb-section > .dd032-wb-card:first-of-type {
    margin-top: 0.7rem;
}
.dd032-wb-section > .dd032-wb-card:last-of-type {
    margin-bottom: 0.9rem;
}
.dd032-wb-section-edit,
.dd032-wb-section-delete,
.dd032-wb-section-confirm-delete,
.dd032-wb-section-cancel-delete,
.dd032-wb-section-save,
.dd032-wb-section-cancel {
    padding: 0.22rem 0.6rem;
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.74rem;
    cursor: pointer;
}
.dd032-wb-section-edit:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.dd032-wb-section-delete:hover,
.dd032-wb-section-confirm-delete {
    color: #e07d7d;
    border-color: #e07d7d;
}
.dd032-wb-section-confirm-delete {
    background: rgba(224, 125, 125, 0.10);
}
.dd032-wb-section-save {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.dd032-wb-section-save:hover {
    filter: brightness(1.1);
}
.dd032-wb-section-question {
    margin: 0.25rem 0 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
    font-style: italic;
}
.dd032-wb-section-hint {
    margin: 0.3rem 0 0 0;
    font-size: 0.75rem;
    color: var(--text-muted);
}
.dd032-wb-section-empty {
    margin: 0.5rem 0 0.5rem 0;
    padding: 0.7rem;
    border: 1px dashed var(--border);
    border-radius: 4px;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.82rem;
}

/* Inline section edit form (label + question). */
.dd032-wb-section-edit-label {
    width: 100%;
    padding: 0.4rem 0.6rem;
    font-size: 0.95rem;
    background: var(--bg-input, var(--bg-card));
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    margin-bottom: 0.4rem;
}
.dd032-wb-section-edit-question {
    width: 100%;
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    background: var(--bg-input, var(--bg-card));
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-family: inherit;
    resize: vertical;
    margin-bottom: 0.4rem;
}
.dd032-wb-section-edit-actions {
    display: flex;
    gap: 0.4rem;
}

/* Section creator at the bottom of the cards column. */
.dd032-wb-section-creator {
    display: flex;
    gap: 0.4rem;
    margin-top: 1rem;
    padding-top: 0.8rem;
    border-top: 1px dashed var(--border);
}
.dd032-wb-section-create-input {
    flex: 1;
    padding: 0.4rem 0.7rem;
    font-size: 0.88rem;
    background: var(--bg-input, var(--bg-card));
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
}
.dd032-wb-section-create-input:focus {
    border-color: var(--accent);
    outline: none;
}
.dd032-wb-section-create-btn {
    padding: 0.4rem 0.85rem;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 4px;
    font-size: 0.85rem;
    cursor: pointer;
}
.dd032-wb-section-create-btn:hover:not(:disabled) {
    filter: brightness(1.1);
}
.dd032-wb-section-create-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* DD-040 Phase 3b — per-section working note + move-to-section
   selector on article cards. */
.dd032-wb-section-notewrap {
    margin-top: 0.55rem;
}
.dd032-wb-section-note-label {
    display: block;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
}
.dd032-wb-section-note-saving {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-muted);
    font-style: italic;
}
.dd032-wb-section-note {
    width: 100%;
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    line-height: 1.4;
    background: var(--bg-input, var(--bg-card));
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-family: inherit;
    resize: vertical;
}
.dd032-wb-section-note:focus {
    outline: none;
    border-color: var(--accent);
}

/* Section selector on the article-card byline. Small + unobtrusive
   — sits at the right edge of the byline, visible without
   expanding the card. */
.dd032-wb-card-section-select {
    margin-left: auto;
    padding: 0.12rem 0.4rem;
    font-size: 0.72rem;
    background: var(--bg-input, var(--bg-card));
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 3px;
    max-width: 12rem;
}
.dd032-wb-card-section-select:hover {
    color: var(--text);
    border-color: var(--accent);
}
.dd032-wb-card-section-select:disabled {
    opacity: 0.6;
    cursor: progress;
}
/* The byline is now flex; ensure the source/saved spans don't push
   the select past the edge on narrow cards. */
.dd032-wb-card-byline {
    flex-wrap: wrap;
}

/* DD-040 Phase 3c — section reorder + fold toggle. The unicode
   chevrons (▾ ▸) render as narrow glyphs at default font-size;
   bumped to 1.2rem + body-text colour so they're scannable
   without straining. The hit target is generous via the padding.*/
.dd032-wb-section-fold-toggle {
    flex-shrink: 0;
    padding: 0.1rem 0.55rem;
    background: transparent;
    border: none;
    color: var(--text);
    font-size: 1.2rem;
    cursor: pointer;
    line-height: 1;
}
.dd032-wb-section-fold-toggle:hover {
    color: var(--accent);
}
.dd032-wb-section-title {
    cursor: pointer;
    user-select: none;
}
.dd032-wb-section-title:hover {
    color: var(--accent);
}
/* When folded, the section's separator border tightens so the page
   doesn't bloat with empty space below a collapsed header. */
.dd032-wb-section--folded {
    padding-bottom: 0.2rem;
}
.dd032-wb-section--folded .dd032-wb-section-header {
    margin-bottom: 0;
}

/* Reorder buttons — same baseline styling as edit/delete but with
   a unicode arrow glyph. Disabled state for top/bottom + while a
   reorder PUT is in flight. */
/* Up/down button CSS retired 2026-05-19 — drag-to-reorder is the
 * primary affordance now (see `[draggable]` + dragstart/drop
 * handlers on `.dd032-wb-section`). */

/* Drag-to-reorder visual feedback. A draggable section shows the
 * grab cursor on its header (the section body keeps default
 * cursor so reading a card doesn't feel weird). The dragged
 * section dims to half opacity; a drop target gets a clear
 * accent ring so the analyst sees where it'll land. */
.dd032-wb-section[draggable="true"] > .dd032-wb-section-header {
    cursor: grab;
}
.dd032-wb-section--dragging {
    opacity: 0.45;
}
.dd032-wb-section--drophover {
    outline: 2px dashed var(--accent);
    outline-offset: -2px;
}

/* ── DD-040 Phase 6 — Draft Report modal ─────────────────────────── */

.dd040-draft-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    z-index: 100;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 4rem 1rem 2rem;
    overflow-y: auto;
}
.dd040-draft-modal {
    /* --surface isn't defined in user.css; the modal was rendering
     * see-through. --bg-card is the panel token used by the rest of
     * the workbench chrome (article cards, section blocks, etc.). */
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);
    width: min(640px, 100%);
    max-height: calc(100vh - 6rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.dd040-draft-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border);
}
.dd040-draft-modal-header h2 {
    margin: 0;
    font-size: 1.1rem;
    color: var(--text);
}
.dd040-draft-close {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1.6rem;
    line-height: 1;
    padding: 0.1rem 0.5rem;
    cursor: pointer;
    border-radius: 4px;
}
.dd040-draft-close:hover {
    color: var(--text);
    background: var(--bg-hover);
}
.dd040-draft-body {
    padding: 1rem 1.25rem 1.25rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}
.dd040-draft-section-group {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.dd040-draft-h {
    font-size: 0.75rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.dd040-draft-topic-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.4rem;
}
.dd040-draft-topic {
    text-align: left;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    cursor: pointer;
    color: var(--text);
    transition: border-color 120ms ease, background 120ms ease;
}
.dd040-draft-topic:hover {
    border-color: var(--accent);
}
.dd040-draft-topic--active {
    border-color: var(--accent);
    background: var(--bg-hover);
}
.dd040-draft-topic-title {
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.15rem;
}
.dd040-draft-topic-desc {
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.35;
}
.dd040-draft-params {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.dd040-draft-param {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.dd040-draft-param-label {
    font-size: 0.78rem;
    color: var(--text-muted);
}
.dd040-draft-input {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: 0.88rem;
    padding: 0.4rem 0.55rem;
    font-family: inherit;
}
.dd040-draft-input:focus {
    outline: none;
    border-color: var(--accent);
}
.dd040-draft-section-list {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.4rem 0.55rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.dd040-draft-section {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.88rem;
    color: var(--text);
    cursor: pointer;
}
.dd040-draft-section input[type="checkbox"] {
    accent-color: var(--accent);
    cursor: pointer;
}
.dd040-draft-section-unsorted {
    color: var(--text-muted);
    font-style: italic;
}
.dd040-draft-empty {
    color: var(--text-muted);
    font-size: 0.85rem;
    font-style: italic;
    padding: 0.5rem 0;
}
.dd040-draft-error {
    color: #ef4444;
    font-size: 0.82rem;
    padding: 0.3rem 0;
}
.dd040-draft-footer {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--border);
}
.dd040-draft-footer-buttons {
    display: flex;
    gap: 0.55rem;
    justify-content: flex-end;
}

/* ════════════════════════════════════════════════════════════════
   DASHBOARD — merged from dashboard.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* Phase 0 foundation cleanup 2026-05-27 — the original dashboard.css
   declared `*`, bare `body`, bare `header`, bare `footer`, and a
   `body.light` foundation override. Those poured into the merged
   user.css and bled onto every authenticated surface (cream bg, 1400-
   max-width column, navigation-flash transition). The foundation
   selectors are owned by BASELINE; the dashboard's layout intent now
   lives on `.o-dashboard-shell`, which dashboard.html wraps its
   content in. Component rules (cards, banners, summary-bar, etc.)
   stay as they were — those reach their markup via dashboard-
   specific class names and don't bleed. */

.o-dashboard-shell {
    /* Centered fixed-max column with breathing room. Uses logical
       properties per the design-system contract so RTL future-flips
       cleanly. The background transition was originally on bare body
       and animated on every navigation — gone here, the surface
       background is now owned by html/body in BASELINE which doesn't
       transition. */
    max-inline-size: 1400px;
    margin-inline: auto;
    padding-block: 2rem;
    padding-inline: 2rem;
}

.o-dashboard-shell header { margin-bottom: 2rem; position: relative; }
.o-dashboard-shell header h1 { font-size: 1.8rem; color: var(--white); margin-bottom: 0.3rem; }
.o-dashboard-shell header .subtitle { color: var(--text-muted); font-size: 0.85rem; }
.theme-toggle {
    position: absolute;
    top: 0;
    right: 0;
    background: none;
    border: 1px solid var(--border-hover);
    border-radius: 4px;
    color: var(--text-muted);
    font-size: 1.1rem;
    cursor: pointer;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-icon-light { display: none; }
body.light .theme-icon-dark { display: none; }
body.light .theme-icon-light { display: inline; }

/* Breaking Banner */
.breaking-banner {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.6rem 1rem;
    background: #1a0a0a;
    border: 1px solid #dc2626;
    border-radius: 6px;
    margin-bottom: 0.6rem;
    cursor: pointer;
    animation: pulse-border 2s ease-in-out infinite;
}
@keyframes pulse-border { 0%, 100% { border-color: #dc2626; } 50% { border-color: #7f1d1d; } }
.breaking-banner:hover { background: #1f0f0f; }
.breaking-label {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #fff;
    background: #dc2626;
    padding: 0.15rem 0.5rem;
    border-radius: 3px;
    white-space: nowrap;
    animation: pulse-bg 2s ease-in-out infinite;
}
@keyframes pulse-bg { 0%, 100% { background: #dc2626; } 50% { background: #991b1b; } }
.breaking-summary {
    font-size: 0.85rem;
    color: #fca5a5;
    font-weight: 500;
}
.breaking-detail {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 6px 6px;
    margin-top: -0.6rem;
    margin-bottom: 0.6rem;
    padding: 0.6rem 1rem;
}
.breaking-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.5rem; }
.breaking-article {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.2rem 0;
}
.breaking-title {
    font-size: 0.8rem;
    color: var(--accent);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.breaking-title:hover { text-decoration: underline; }
.breaking-date { font-size: 0.65rem; color: var(--text-dim); white-space: nowrap; }

/* Happening Now Banner */
.happening-banner {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.5rem 1rem;
    background: #1a1012;
    border: 1px solid #7f1d1d;
    border-radius: 6px;
    margin-bottom: 1rem;
    cursor: pointer;
    transition: background 0.15s;
}
.happening-banner:hover { background: #1f1418; }
.happening-label {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #ef4444;
    white-space: nowrap;
}
.happening-summary {
    font-size: 0.8rem;
    color: #d1d5db;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.happening-detail {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 6px 6px;
    margin-top: -1rem;
    margin-bottom: 1rem;
    padding: 0.8rem 1rem;
}
.happening-item {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}
.happening-item:last-child { border-bottom: none; }
.happening-cves { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; margin-bottom: 0.2rem; }
.happening-cve {
    font-family: monospace;
    font-size: 0.7rem;
    font-weight: 700;
    color: #fca5a5;
    background: #7f1d1d;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    text-decoration: none;
}
.happening-cve:hover { background: #991b1b; color: #fff; }
.happening-title {
    display: block;
    font-size: 0.8rem;
    color: var(--accent);
    text-decoration: none;
    line-height: 1.4;
}
.happening-title:hover { text-decoration: underline; }
.happening-evidence {
    font-size: 0.7rem;
    color: var(--text-muted);
    line-height: 1.3;
    margin-top: 0.15rem;
}
.happening-date { font-size: 0.65rem; color: var(--text-dim); }
.happening-source-count {
    font-size: 0.65rem; font-weight: 600;
    color: #fbbf24; background: #422006;
    padding: 0.1rem 0.4rem; border-radius: 3px;
    text-transform: uppercase; letter-spacing: 0.04em;
}
.happening-sources { margin-top: 0.4rem; }
.happening-sources > summary {
    font-size: 0.7rem; color: #9ca3af; cursor: pointer; user-select: none;
}
.happening-sources > summary:hover { color: #d1d5db; }
.happening-sources[open] > summary { color: #d1d5db; margin-bottom: 0.25rem; }
.happening-source-link {
    display: flex; gap: 0.5rem; align-items: baseline;
    padding: 0.15rem 0; font-size: 0.75rem;
    color: #cbd5e1; text-decoration: none;
}
.happening-source-link:hover { color: #f3f4f6; text-decoration: underline; }
.happening-source-date { font-size: 0.65rem; color: var(--text-muted); min-width: 4.5rem; }
.happening-source-title { flex: 1; }

.summary-bar {
    display: flex;
    gap: 2rem;
    margin-bottom: 2rem;
    padding: 1rem 1.5rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
}

.summary-stat { text-align: center; }
.summary-stat .value { font-size: 1.8rem; font-weight: 700; color: var(--accent); }
.summary-stat .label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }

/* Dashboard sections */
.dash-section {
    margin-bottom: 2rem;
    padding-top: 1.2rem;
    border-top: 1px solid var(--border);
}
.dash-section:first-of-type { border-top: none; padding-top: 0; }
.dash-section-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 0.8rem;
}
.dash-section-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
}
.dash-section-meta { font-size: 0.7rem; color: var(--text-muted); }

/* Top Story */
.top-story-section { margin-bottom: 1.5rem; }
.top-story-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 0.5rem;
}
.top-story-label {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
}
.top-story-period { font-size: 0.7rem; color: var(--text-muted); }
.story-card {
    background: var(--bg-card);
    border: 1px solid var(--border-hover);
    border-left: 3px solid var(--accent);
    border-radius: 8px;
    padding: 1.2rem;
}
.story-card.archived {
    border-left-color: var(--border-hover);
    padding: 0.8rem 1.2rem;
    margin-top: 0.5rem;
}
.story-card.archived .story-headline { font-size: 0.95rem; }
.story-card.archived .story-narrative { font-size: 0.8rem; color: #9ca3af; }
.story-archive-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.3rem;
}
.story-headline {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--white);
    margin-bottom: 0.5rem;
    line-height: 1.4;
}
.story-narrative {
    font-size: 0.85rem;
    color: #d1d5db;
    line-height: 1.6;
    margin-bottom: 0.8rem;
}
.story-signals {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
    margin-bottom: 0.6rem;
}
.story-signal { font-size: 0.7rem; color: var(--text-muted); }
.story-count { font-size: 0.75rem; font-weight: 600; color: var(--accent); }
.story-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
}
.story-themes { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.story-archive { margin-bottom: 1.5rem; }
.story-archive > summary {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
    margin-top: 0.5rem;
}
.story-archive > summary::-webkit-details-marker { display: none; }
.story-archive > summary::before { content: "+ "; }
.story-archive[open] > summary::before { content: "− "; }
.story-archive-note { font-size: 0.7rem; color: var(--text-dim); margin-bottom: 0.5rem; }
.story-card.no-story { border-left-color: var(--border-hover); }
.story-no-signal { font-size: 0.8rem; color: var(--text-muted); font-style: italic; }

/* Tab Navigation */
.tab-bar {
    display: flex;
    gap: 0;
    margin-bottom: 1.5rem;
    border-bottom: 2px solid var(--border);
}
.tab-bar .tab {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0.6rem 1.2rem;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: color 0.15s, border-color 0.15s;
}
.tab-bar .tab:hover { color: #d1d5db; }
.tab-bar .tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }

.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.section-header {
    display: flex;
    align-items: baseline;
    gap: 0.8rem;
    margin: 1.5rem 0 1rem;
}
.section-header h2 { font-size: 1rem; color: #9ca3af; font-weight: 600; }
.section-note { font-size: 0.75rem; color: var(--text-dim); }

.sparse-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }

.card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.2rem;
    transition: border-color 0.15s;
}
.card.sparse { padding: 0.8rem; opacity: 0.8; }
.card.sparse .count { font-size: 1.4rem; }
.card.sparse .mini-bars { height: 24px; }
.card:hover { border-color: var(--border-hover); }
.card.significant { border-color: #ef4444; border-width: 2px; }
.card.elevated { border-color: var(--amber); border-width: 2px; }
.card.shifting { border-color: #a78bfa; border-width: 2px; }
.card.declining { border-color: var(--accent-hover); }

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.card .name {
    font-size: 0.85rem;
    color: #9ca3af;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card .count {
    font-size: 2rem;
    font-weight: 700;
    color: var(--white);
}

.card .count-label {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-muted);
}

.stats-row {
    display: flex;
    gap: 0.8rem;
    margin: 0.4rem 0;
    flex-wrap: wrap;
}

.stats-row .stat {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.status-badge {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    white-space: nowrap;
}
.status-badge.significant { background: #7f1d1d; color: #fca5a5; }
.status-badge.elevated { background: #78350f; color: #fde68a; }
.status-badge.shifting { background: #4c1d95; color: #c4b5fd; }
.status-badge.declining { background: #1e3a5f; color: #93c5fd; }
.status-badge.normal { background: var(--border); color: var(--text-muted); }

.card .trend-row { display: flex; gap: 1rem; align-items: center; margin-top: 0.3rem; }
.card .trend { font-size: 0.85rem; font-weight: 600; }
.trend.rising { color: var(--green); }
.trend.falling { color: var(--red); }
.trend.stable { color: var(--text-muted); }
.shift { font-size: 0.75rem; font-weight: 600; }
.shift.up { color: var(--green); }
.shift.down { color: var(--red); }

.card .mini-bars {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 32px;
    margin-top: 0.8rem;
}

.card .mini-bar {
    flex: 1;
    background: var(--accent-hover);
    border-radius: 2px;
    min-height: 2px;
    transition: opacity 0.1s;
}
.card .mini-bar.clickable { cursor: pointer; }
.card .mini-bar.clickable:hover { opacity: 0.7; }
.card.significant .mini-bar { background: #ef4444; }
.card.elevated .mini-bar { background: var(--amber); }
.card.shifting .mini-bar { background: #a78bfa; }

.card-details {
    margin-top: 0.6rem;
    border-top: 1px solid var(--border);
    padding-top: 0.4rem;
}
.card-details summary {
    font-size: 0.7rem;
    color: var(--text-muted);
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    list-style: none;
}
.card-details summary::before { content: "+ "; }
.card-details[open] summary::before { content: "− "; }
.card-details summary::-webkit-details-marker { display: none; }
.card-details .stats-row { margin-top: 0.4rem; }

.contributing {
    margin-top: 0.8rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
}

.contributing-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    margin-bottom: 0.3rem;
}

.contributing-article {
    display: block;
    font-size: 0.75rem;
    color: var(--accent);
    text-decoration: none;
    padding: 0.15rem 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.contributing-article:hover { text-decoration: underline; }

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}

.data-table th {
    text-align: left;
    padding: 0.75rem 1rem;
    background: var(--border);
    color: #9ca3af;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.data-table th.num { text-align: right; }

.data-table td {
    padding: 0.6rem 1rem;
    border-top: 1px solid var(--border);
    font-size: 0.9rem;
}
.data-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table tr:hover { background: var(--bg-hover); }

/* Threat Actor Mapping */
.actor-table-wrap { margin-bottom: 2rem; }
.actor-table .actor-name { font-weight: 600; color: var(--white); vertical-align: top; min-width: 220px; max-width: 360px; }
.actor-table .actor-name-line { white-space: nowrap; }
.actor-table .actor-type {
    font-size: 0.72rem; font-weight: 500; color: var(--accent);
    text-transform: uppercase; letter-spacing: 0.05em; margin-top: 0.15rem;
}
.actor-table .actor-aliases {
    font-size: 0.78rem; font-weight: 400; color: #9aa0a6;
    margin-top: 0.25rem; line-height: 1.3;
}
.actor-table .actor-activity {
    font-size: 0.8rem; font-weight: 400; color: #c5c8cc;
    margin-top: 0.4rem; line-height: 1.4;
}
.actor-archetypes { display: flex; flex-wrap: wrap; gap: 0.3rem; vertical-align: top; }
.tag.actor-archetype { background: #1e293b; color: #94a3b8; font-size: 0.7rem; transition: background 0.1s; }
.tag.actor-archetype.clickable { cursor: pointer; }
.tag.actor-archetype.clickable:hover { background: #334155; color: #e2e8f0; }
.actor-count { color: var(--text-muted); }

/* State-Sponsored Nation Cards */
.nation-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}
.nation-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.2rem;
}
.nation-card:hover { border-color: var(--border-hover); }
.nation-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.8rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--border);
}
.nation-name { font-size: 1.1rem; font-weight: 700; color: var(--white); }
.nation-count { font-size: 0.8rem; color: var(--accent); font-weight: 600; }
.nation-section { margin-bottom: 0.6rem; }
.nation-label {
    display: block;
    font-size: 0.65rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.3rem;
}
.nation-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tag.actor-tag { background: var(--bg-hover); color: #c4b5fd; }
.tag.archetype-tag { background: #1e293b; color: #94a3b8; }

/* CVE Tracker */
.cve-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.8rem;
    margin-bottom: 2rem;
}
.cve-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.8rem;
}
.cve-card.new { border-color: var(--green); border-width: 2px; }
.cve-card.spiking { border-color: #ef4444; border-width: 2px; }
.cve-card.persistent { border-color: var(--amber); }
/* CVE card header: stack the CVE id (title) above the CVSS + type
   badges so a narrow card doesn't push the badges off the side. The
   ID line sits flush left; the badge row sits below with a small gap. */
.cve-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    margin-bottom: 0.4rem;
}
.cve-header-right { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.cvss-badge {
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
}
.cvss-badge.critical { background: #7f1d1d; color: #fca5a5; }
.cvss-badge.high { background: #78350f; color: #fde68a; }
.cvss-badge.medium { background: #1e3a5f; color: #93c5fd; }
.cvss-badge.low { background: var(--border); color: var(--text-muted); }
.cve-description {
    font-size: 0.7rem;
    color: #9ca3af;
    line-height: 1.4;
    margin-bottom: 0.4rem;
}
.cve-id { font-size: 0.8rem; font-weight: 700; color: var(--white); font-family: monospace; text-decoration: none; }
.cve-id:hover { color: var(--accent); text-decoration: underline; }
.cve-signal {
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
}
.cve-signal.new { background: #064e3b; color: #6ee7b7; }
.cve-signal.spiking { background: #7f1d1d; color: #fca5a5; }
.cve-signal.persistent { background: #78350f; color: #fde68a; }
.cve-signal.active { background: var(--border); color: var(--text-muted); }
.cve-products { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-bottom: 0.4rem; }
.cve-products .tag { font-size: 0.65rem; background: #1e3a5f; color: #93c5fd; }
.cve-stats { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.cve-stats .stat { font-size: 0.65rem; color: var(--text-muted); }
.cve-card .card-details { margin-top: 0.4rem; border-top: 1px solid var(--border); padding-top: 0.3rem; }

/* Article Overlay */
.overlay-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    z-index: 100;
}
.overlay-card {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(640px, 90vw);
    max-height: 80vh;
    overflow-y: auto;
    background: var(--bg-hover);
    border: 1px solid var(--border-hover);
    border-radius: 12px;
    padding: 1.5rem;
    z-index: 101;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.overlay-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1rem;
}
.overlay-header h3 {
    font-size: 1rem;
    color: var(--white);
    line-height: 1.4;
}
.overlay-close {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.5rem;
    cursor: pointer;
    padding: 0;
    line-height: 1;
    flex-shrink: 0;
}
.overlay-close:hover { color: var(--white); }
.overlay-summary {
    font-size: 0.85rem;
    color: #d1d5db;
    line-height: 1.6;
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--border);
}
.overlay-meta { display: flex; flex-direction: column; gap: 0.6rem; }
.overlay-field { }
.overlay-label {
    font-size: 0.65rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    display: block;
    margin-bottom: 0.3rem;
}
.overlay-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tag {
    font-size: 0.7rem;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    background: var(--border);
    color: #9ca3af;
}
.tag.sector { background: #1e3a5f; color: #93c5fd; }
.tag.entity { background: #1a332e; color: #6ee7b7; }
.tag.mitre { background: #3b1f2b; color: #fca5a5; }
.overlay-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 1rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--border);
}
.overlay-date { font-size: 0.75rem; color: var(--text-muted); }
.overlay-link {
    font-size: 0.8rem;
    color: var(--accent);
    text-decoration: none;
}
.overlay-link:hover { text-decoration: underline; }

/* Week popover articles */
.week-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    padding-bottom: 0.8rem;
    margin-bottom: 0.4rem;
    border-bottom: 1px solid var(--border);
}
.week-article {
    display: block;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    color: inherit;
}
.week-article:last-child { border-bottom: none; }
.week-article:hover { background: var(--bg-card); margin: 0 -1.5rem; padding-left: 1.5rem; padding-right: 1.5rem; }
.week-article-title { font-size: 0.85rem; color: var(--accent); line-height: 1.4; }
.week-article-date { font-size: 0.7rem; color: var(--text-muted); margin-top: 0.15rem; }
.week-empty { font-size: 0.85rem; color: var(--text-muted); padding: 1rem 0; }

/* Timeline */
.btn-timeline {
    background: none;
    border: 1px solid var(--border-hover);
    color: var(--accent);
    font-size: 0.7rem;
    padding: 0.2rem 0.6rem;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
}
.btn-timeline:hover { border-color: var(--accent); }

.timeline-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    z-index: 200;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 2rem;
    overflow-y: auto;
}
.timeline-panel {
    background: var(--bg-card);
    border: 1px solid var(--border-hover);
    border-radius: 12px;
    padding: 1.5rem;
    max-width: 700px;
    width: 100%;
    max-height: 85vh;
    overflow-y: auto;
}
.timeline-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 0.3rem;
}
.timeline-header h3 { font-size: 1rem; color: var(--white); line-height: 1.4; }
.timeline-subtitle { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 1rem; }

.timeline-track {
    position: relative;
    padding-left: 1.5rem;
}
.timeline-track::before {
    content: '';
    position: absolute;
    left: 5px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--border);
}

.timeline-entry {
    position: relative;
    padding-bottom: 1rem;
}
.timeline-dot {
    position: absolute;
    left: -1.5rem;
    top: 0.3rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--border-hover);
    border: 2px solid var(--bg-card);
    z-index: 1;
}
.timeline-entry.novelty-high .timeline-dot { background: var(--green); }
.timeline-entry.novelty-medium .timeline-dot { background: var(--accent); }
.timeline-entry.novelty-low .timeline-dot { background: var(--text-dim); }

.timeline-content { padding-left: 0.5rem; }
.timeline-date { font-size: 0.65rem; color: var(--text-muted); margin-bottom: 0.15rem; }
.timeline-title {
    display: block;
    font-size: 0.8rem;
    color: var(--text);
    text-decoration: none;
    line-height: 1.4;
}
.timeline-title:hover { color: var(--accent); text-decoration: underline; }

.timeline-new {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem;
    margin-top: 0.3rem;
    align-items: center;
}
.timeline-novelty-badge {
    font-size: 0.6rem;
    font-weight: 700;
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
    margin-right: 0.2rem;
}
.timeline-novelty-badge.high { background: #064e3b; color: #6ee7b7; }
.timeline-novelty-badge.medium { background: #1e3a5f; color: #93c5fd; }
.timeline-novelty-badge.low { background: var(--border); color: var(--text-muted); }

.o-dashboard-shell footer {
    margin-top: 2rem;
    text-align: center;
    color: var(--text-dim);
    font-size: 0.75rem;
}

/* ==================== Light Theme ==================== */
/* Phase 0 2026-05-27 — removed bare-body cream foundation override
   (`body.light { background: #faf9f6; color: #1a1a1a }`) plus the
   bare-element light-mode overrides for header/footer/theme-toggle.
   BASELINE's `body.light` already flips `--bg`, `--text`,
   `--text-muted`, `--text-dim`, `--accent`, `--border-hover` —
   the dashboard's `.o-dashboard-shell` chrome reads those vars now
   so the theme switch reaches the dashboard surface in one move. */

body.light .breaking-banner { background: #fef2f2; border-color: #dc2626; }
body.light .breaking-banner:hover { background: #fee2e2; }
body.light .breaking-summary { color: #991b1b; }
body.light .breaking-detail { background: #fff; border-color: #e5e5e5; }
body.light .breaking-title { color: #1d4ed8; }

body.light .happening-banner { background: #fef2f2; border-color: #fecaca; }
body.light .happening-banner:hover { background: #fee2e2; }
body.light .happening-summary { color: #333; }
body.light .happening-detail { background: #fff; border-color: #e5e5e5; }
body.light .happening-item { border-bottom-color: #f0f0f0; }
body.light .happening-cve { background: #fef2f2; color: #991b1b; }
body.light .happening-title { color: #1d4ed8; }
body.light .happening-evidence { color: #666; }

body.light .summary-bar { background: #fff; border-color: #e5e5e5; }
body.light .summary-stat .value { color: #1d4ed8; }
body.light .summary-stat .label { color: #666; }

body.light .dash-section { border-top-color: #e5e5e5; }
body.light .dash-section-title { color: #1d4ed8; }
body.light .dash-section-meta { color: #999; }

body.light .tab-bar { border-bottom-color: #ddd; }
body.light .tab-bar .tab { color: #888; }
body.light .tab-bar .tab:hover { color: #333; }
body.light .tab-bar .tab.active { color: #1d4ed8; border-bottom-color: #1d4ed8; }

body.light .card { background: #fff; border-color: #e5e5e5; }
body.light .card:hover { border-color: #ccc; }
body.light .card .name { color: #444; }
body.light .card .count { color: #111; }
body.light .card .count-label { color: #888; }
body.light .card.significant { border-color: #dc2626; }
body.light .card.elevated { border-color: #d97706; }
body.light .card.shifting { border-color: #7c3aed; }
body.light .card.declining { border-color: #2563eb; }
body.light .card .mini-bar { background: #2563eb; }
body.light .card.significant .mini-bar { background: #dc2626; }
body.light .card.elevated .mini-bar { background: #d97706; }
body.light .card.shifting .mini-bar { background: #7c3aed; }

body.light .status-badge.significant { background: #fef2f2; color: #991b1b; }
body.light .status-badge.elevated { background: #fffbeb; color: #92400e; }
body.light .status-badge.shifting { background: #f5f3ff; color: #5b21b6; }
body.light .status-badge.declining { background: #eff6ff; color: #1e40af; }
body.light .status-badge.normal { background: #f3f4f6; color: #6b7280; }

body.light .stats-row .stat { color: #888; }
body.light .card-details { border-top-color: #e5e5e5; }
body.light .card-details summary { color: #888; }
body.light .contributing { border-top-color: #e5e5e5; }
body.light .contributing-label { color: #888; }
body.light .contributing-article { color: #1d4ed8; }

body.light .data-table { background: #fff; border-color: #e5e5e5; }
body.light .data-table th { background: #f9fafb; color: #666; }
body.light .data-table td { border-top-color: #f0f0f0; color: #333; }
body.light .data-table tr:hover { background: #f9fafb; }

body.light .story-card { background: #fff; border-color: #e5e5e5; border-left-color: #1d4ed8; }
body.light .story-headline { color: #111; }
body.light .story-narrative { color: #444; }
body.light .story-card.archived { border-left-color: #ddd; }
body.light .story-card.archived .story-headline { color: #666; }
body.light .story-card.archived .story-narrative { color: #888; }
body.light .top-story-label { color: #1d4ed8; }
body.light .story-count { color: #1d4ed8; }
body.light .story-signal { color: #888; }

body.light .tag { background: #f3f4f6; color: #555; }
body.light .tag.sector { background: #eff6ff; color: #1e40af; }
body.light .tag.entity { background: #ecfdf5; color: #065f46; }
body.light .tag.mitre { background: #fef2f2; color: #991b1b; }
body.light .tag.actor-tag { background: #f5f3ff; color: #5b21b6; }
body.light .tag.archetype-tag { background: #f3f4f6; color: #555; }

body.light .nation-card { background: #fff; border-color: #e5e5e5; }
body.light .nation-header { border-bottom-color: #e5e5e5; }
body.light .nation-name { color: #111; }
body.light .nation-count { color: #1d4ed8; }
body.light .nation-label { color: #888; }

body.light .cve-card { background: #fff; border-color: #e5e5e5; }
body.light .cve-id { color: #111; }
body.light .cve-description { color: #666; }
body.light .cve-stats .stat { color: #888; }
body.light .cvss-badge.critical { background: #fef2f2; color: #991b1b; }
body.light .cvss-badge.high { background: #fffbeb; color: #92400e; }
body.light .cvss-badge.medium { background: #eff6ff; color: #1e40af; }
body.light .cve-products .tag { background: #eff6ff; color: #1e40af; }

body.light .actor-table .actor-name { color: #111; }
body.light .actor-count { color: #888; }
body.light .tag.actor-archetype.clickable:hover { background: #e5e7eb; color: #111; }

body.light .overlay-backdrop { background: rgba(0, 0, 0, 0.4); }
body.light .overlay-card { background: #fff; border-color: #ddd; }
body.light .overlay-header h3 { color: #111; }
body.light .overlay-summary { color: #444; border-bottom-color: #e5e5e5; }
body.light .overlay-footer { border-top-color: #e5e5e5; }
body.light .overlay-link { color: #1d4ed8; }
body.light .week-article-title { color: #1d4ed8; }
body.light .week-article:hover { background: #f9fafb; }
body.light .week-tags { border-bottom-color: #e5e5e5; }
body.light .week-article { border-bottom-color: #f0f0f0; }

body.light .btn-timeline { border-color: #ccc; color: #1d4ed8; }
body.light .timeline-overlay { background: rgba(0, 0, 0, 0.4); }
body.light .timeline-panel { background: #fff; border-color: #ddd; }
body.light .timeline-header h3 { color: #111; }
body.light .timeline-track::before { background: #e5e5e5; }
body.light .timeline-dot { border-color: #fff; }
body.light .timeline-title { color: #333; }
body.light .timeline-title:hover { color: #1d4ed8; }

/* ==================== Mobile Responsive ==================== */
@media (max-width: 768px) {
    .o-dashboard-shell { padding-block: 1rem; padding-inline: 1rem; }
    .o-dashboard-shell header h1 { font-size: 1.3rem; }
    .theme-toggle { top: -0.2rem; }

    .breaking-banner { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
    .breaking-summary { white-space: normal; }

    .happening-banner { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
    .happening-summary { white-space: normal; }

    .cards-grid { grid-template-columns: 1fr; }
    .sparse-grid { grid-template-columns: repeat(2, 1fr); }

    .story-headline { font-size: 1rem; }
    .story-narrative { font-size: 0.8rem; }

    .tab-bar { overflow-x: auto; -webkit-overflow-scrolling: touch; }

    .data-table { font-size: 0.75rem; }
    .data-table th, .data-table td { padding: 0.4rem 0.5rem; }

    .nation-grid { grid-template-columns: 1fr; }
    .cve-grid { grid-template-columns: 1fr; }

    .overlay-card { width: 95vw; max-height: 90vh; padding: 1rem; }
    .timeline-panel { padding: 1rem; max-height: 90vh; }
    .timeline-overlay { padding: 0.5rem; }
}
body.light .section-header h2 { color: #444; }
body.light .section-note { color: #999; }
body.light .trend.rising { color: #059669; }
body.light .trend.falling { color: #dc2626; }
body.light .trend.stable { color: #888; }
body.light .shift.up { color: #059669; }
body.light .shift.down { color: #dc2626; }

/* ════════════════════════════════════════════════════════════════
   DEMO — merged from demo.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* ──────────────────────────────────────────────────────────────
   Public demo page styles.

   Layout:
   1. /demo page chrome — hero + disclaimer + launchpad cards
   2. Modal overlay — backdrop + panel containing a simulated
      ELEVATE app shell (top header + sidebar + main content)
   3. In-modal screens (Sources, Streams) where the state machine
      renders the active walkthrough step

   Theme-aware: every colour uses the theme tokens from public.css
   (`--bg`, `--surface`, `--surface-2`, `--text`, `--text-muted`,
   `--accent`, `--border`). No hex inline.
   ────────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────
   1. /demo page chrome
   ───────────────────────────────────────────────────────────── */

/* Hero */
.lp-demo-hero { text-align: center; padding: 3rem 1.5rem 1.5rem; }
.lp-demo-hero .lp-section-title { margin-left: auto; margin-right: auto; }
.lp-demo-hero .lp-section-lede {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}
.lp-demo-hero__chrome {
    display: inline-block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--accent);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border);
    padding: 0.35rem 0.8rem;
    border-radius: 999px;
    margin-bottom: 1.2rem;
}
body.light .lp-demo-hero__chrome {
    background: rgba(37, 99, 235, 0.06);
    border-color: rgba(37, 99, 235, 0.18);
}

/* Disclaimer banner */
.lp-demo-disclaimer {
    max-width: 880px;
    margin: 0 auto 3rem;
    display: flex;
    gap: 0.9rem;
    align-items: flex-start;
    padding: 1rem 1.2rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 8px;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-muted);
}
.lp-demo-disclaimer__icon {
    flex-shrink: 0;
    font-size: 1.1rem;
    line-height: 1.4;
    color: var(--accent);
}
.lp-demo-disclaimer__body strong { color: var(--text); }
.lp-demo-disclaimer__body em { font-style: italic; color: var(--text); }

/* Launchpad cards */
.lp-demo-launchpad { padding: 1rem 1.5rem 4rem; }
.lp-demo-launchpad-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.4rem;
    max-width: 1000px;
    margin: 0 auto;
}
@media (max-width: 800px) {
    .lp-demo-launchpad-grid { grid-template-columns: 1fr; }
}

/* Single-card layout: one entry into a unified walkthrough.
   Caps the card width so it doesn't stretch to 1000px alone, and
   re-asserts margin auto so the cap centers within .lp-section
   (the base rule sets margin auto too, but we keep it explicit here
   so the intent reads at the modifier site). */
.lp-demo-launchpad-grid--single {
    grid-template-columns: 1fr;
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
}

/* Single-card hero treatment: the card itself centers its content
   so the visual flow continues from the centered hero above. The
   default two-card layout leaves content flex-start aligned (that
   reads as symmetric side-by-side cards); single-card needs to
   read as a centered call-to-action, matching the hero. */
.lp-demo-launchpad-grid--single .lp-demo-launchpad-card {
    text-align: center;
    align-items: center;
}
.lp-demo-launchpad-grid--single .lp-demo-launchpad-card .lp-cta {
    align-self: center;
}
/* Bulleted list looks awkward when each item is text-centered (the
   bullet floats away from the text). Keep the list left-aligned but
   center the BLOCK so it sits under the centered prose. */
.lp-demo-launchpad-grid--single .lp-demo-launchpad-card__steps {
    text-align: left;
    width: max-content;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
}
.lp-demo-launchpad-card {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    padding: 1.8rem 1.6rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.lp-demo-launchpad-card--soon { opacity: 0.7; }
.lp-demo-launchpad-card__label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--text-muted);
}
.lp-demo-launchpad-card__title {
    font-size: 1.4rem;
    font-weight: 600;
    margin: 0;
    color: var(--text);
    line-height: 1.3;
}
.lp-demo-launchpad-card__lede {
    font-size: 0.9rem;
    color: var(--text-muted);
    line-height: 1.55;
    margin: 0;
}
.lp-demo-launchpad-card__steps {
    list-style: none;
    padding: 0;
    margin: 0.3rem 0 0.8rem;
    font-size: 0.85rem;
    color: var(--text-muted);
    line-height: 1.7;
}
.lp-demo-launchpad-card__steps li {
    padding-left: 1.2rem;
    position: relative;
}
.lp-demo-launchpad-card__steps li::before {
    content: "→";
    position: absolute;
    left: 0;
    color: var(--accent);
}
.lp-demo-launchpad-card .lp-cta { align-self: flex-start; }

/* Outro CTA (renamed from .lp-demo-cta-section to avoid collision
   with the .lp-demo-cta button class used inside the state machine) */
.lp-demo-outro {
    text-align: center;
    max-width: 720px;
    margin: 0 auto;
    padding-bottom: 4rem;
}
.lp-demo-outro .lp-section-title,
.lp-demo-outro .lp-section-lede {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}
.lp-demo-outro__buttons {
    display: flex;
    gap: 0.8rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1.2rem;
}

/* ─────────────────────────────────────────────────────────────
   2. Modal overlay
   ───────────────────────────────────────────────────────────── */

.lp-demo-modal {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}
.lp-demo-modal[hidden] { display: none; }

.lp-demo-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(2px);
}
body.light .lp-demo-modal__backdrop { background: rgba(15, 23, 42, 0.55); }

.lp-demo-modal__panel {
    position: relative;
    width: min(96vw, 1180px);
    height: min(92vh, 760px);
    display: flex;
    flex-direction: column;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
    overflow: hidden;
}

/* Modal header (above the simulated app chrome) */
.lp-demo-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.7rem 1rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.lp-demo-modal__nav-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: 1;
    min-width: 0;
}
.lp-demo-modal__step-info {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex: 1;
}
.lp-demo-modal__step {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--text-muted);
}
.lp-demo-modal__step-label {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
}
.lp-demo-modal__nav-btn {
    padding: 0.4rem 0.8rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.8rem;
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease;
}
.lp-demo-modal__nav-btn:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--accent);
}
.lp-demo-modal__nav-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.lp-demo-modal__header-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}
.lp-demo-modal__restart {
    padding: 0.4rem 0.7rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text-muted);
    font-size: 0.78rem;
    cursor: pointer;
    line-height: 1;
}
.lp-demo-modal__restart:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.lp-demo-modal__close {
    padding: 0.4rem 0.7rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text-muted);
    font-size: 0.9rem;
    cursor: pointer;
    line-height: 1;
}
.lp-demo-modal__close:hover {
    color: var(--text);
    border-color: var(--text-muted);
}

/* Simulated app chrome (sidebar + main) */
.lp-demo-modal__chrome {
    flex: 1;
    display: flex;
    min-height: 0;
}

/* Sidebar */
.lp-demo-modal__sidebar {
    width: 220px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
}
.lp-demo-modal__brand {
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--accent);
    padding: 1rem 1.2rem 1.2rem;
    border-bottom: 1px solid var(--border);
}
.lp-demo-modal__nav {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.8rem 0.5rem;
    flex: 1;
}
.lp-demo-modal__nav-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0.8rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 5px;
    color: var(--text-muted);
    font-size: 0.88rem;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
    position: relative;
}
.lp-demo-modal__nav-item:hover:not(:disabled) {
    background: var(--bg);
    color: var(--text);
}
.lp-demo-modal__nav-item--active {
    background: var(--bg);
    color: var(--text);
    border-color: var(--border);
    font-weight: 600;
}
.lp-demo-modal__nav-item:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.lp-demo-modal__nav-icon {
    flex-shrink: 0;
    width: 1.1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
}
.lp-demo-modal__nav-item--active .lp-demo-modal__nav-icon {
    color: var(--accent);
}
.lp-demo-modal__nav-badge {
    margin-left: auto;
    background: var(--accent);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    line-height: 1.4;
}
.lp-demo-modal__nav-item--pulse-hint {
    animation: lpDemoPulse 1.4s ease-in-out infinite;
}
.lp-demo-modal__sidebar-footer {
    padding: 0.7rem 1.2rem;
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    border-top: 1px solid var(--border);
    text-align: center;
}

/* Main content area */
.lp-demo-modal__main {
    flex: 1;
    overflow-y: auto;
    padding: 1.8rem 2rem;
    background: var(--bg);
}

/* ─────────────────────────────────────────────────────────────
   3. In-modal screens
   ───────────────────────────────────────────────────────────── */

.lp-demo-screen { display: flex; flex-direction: column; gap: 1.2rem; }
.lp-demo-screen__crumb {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
    margin-bottom: 0.2rem;
}
.lp-demo-screen__title {
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--text);
    margin: 0;
}
.lp-demo-screen__lede {
    font-size: 0.9rem;
    color: var(--text-muted);
    line-height: 1.6;
    margin: 0;
}
.lp-demo-screen__hint {
    font-size: 0.8rem;
    color: var(--accent);
    font-style: italic;
    margin: 0;
}

/* Empty state */
.lp-demo-screen__empty {
    margin-top: 1rem;
    padding: 2rem 1.5rem;
    background: var(--surface);
    border: 1px dashed var(--border);
    border-radius: 8px;
    text-align: center;
    color: var(--text-muted);
}

/* Primary action button (used inside the modal main area) */
.lp-demo-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 1.1rem;
    background: var(--accent);
    color: #fff;
    border: 1px solid var(--accent);
    border-radius: 6px;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    transition: transform 0.12s ease, background 0.12s ease;
    align-self: flex-start;
}
.lp-demo-btn:hover { transform: translateY(-1px); }
.lp-demo-btn--ghost {
    background: transparent;
    color: var(--text);
    border-color: var(--border);
}
.lp-demo-btn--ghost:hover { border-color: var(--accent); color: var(--accent); }
.lp-demo-btn--pulse-hint {
    animation: lpDemoPulse 1.4s ease-in-out infinite;
}

/* Add-source form */
.lp-demo-form {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    padding: 1.4rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.lp-demo-form__label {
    font-size: 0.78rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}
.lp-demo-form__field {
    padding: 0.6rem 0.8rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-family: monospace;
    font-size: 0.85rem;
}
.lp-demo-form__actions {
    display: flex;
    gap: 0.6rem;
    justify-content: flex-end;
    margin-top: 0.3rem;
}

/* Source card */
.lp-demo-source-card {
    display: flex;
    gap: 0.9rem;
    align-items: flex-start;
    padding: 1rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.lp-demo-source-card--active { border-color: var(--accent); }
.lp-demo-source-card__icon {
    flex-shrink: 0;
    font-size: 1.2rem;
    color: var(--accent);
    line-height: 1.4;
}
.lp-demo-source-card__body { flex: 1; min-width: 0; }
.lp-demo-source-card__name {
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.25rem;
}
.lp-demo-source-card__url {
    font-family: monospace;
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
    word-break: break-all;
}
.lp-demo-source-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    align-items: center;
    font-size: 0.78rem;
    color: var(--text-muted);
}
.lp-demo-source-card__tag {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.7rem;
    color: var(--text);
}
.lp-demo-source-card__status {
    color: var(--text-muted);
    font-style: italic;
}
.lp-demo-source-card__status--live {
    color: var(--accent);
    font-style: normal;
    font-weight: 600;
}
.lp-demo-source-card__status--collecting {
    color: var(--accent);
    font-style: normal;
}

/* "... and N more articles" hint at the bottom of the Incoming list */
.lp-demo-articles-more {
    padding: 0.8rem 1rem;
    margin-top: 0.4rem;
    background: var(--surface);
    border: 1px dashed var(--border);
    border-radius: 6px;
    font-size: 0.8rem;
    color: var(--text-muted);
    font-style: italic;
    text-align: center;
}

/* Stream filter chips in the config form + meta row */
.lp-demo-stream-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.3rem 0;
}
.lp-demo-chip--selected {
    background: rgba(37, 99, 235, 0.12) !important;
    border-color: rgba(37, 99, 235, 0.30) !important;
    color: var(--accent) !important;
}
body.light .lp-demo-chip--selected {
    background: rgba(37, 99, 235, 0.10) !important;
    border-color: rgba(37, 99, 235, 0.25) !important;
}
.lp-demo-stream-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    padding: 0.7rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 0.4rem;
}
.lp-demo-stream-meta__label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    margin-right: 0.2rem;
}

/* Article card (Streams view) */
.lp-demo-articles {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.lp-demo-article-card {
    padding: 0.95rem 1.05rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    transition: opacity 0.18s ease, border-color 0.18s ease, transform 0.12s ease;
}
.lp-demo-article-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.lp-demo-article-card__meta-text {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.lp-demo-article-card__status {
    font-size: 0.7rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
}
.lp-demo-article-card__status--unprocessed {
    border-color: var(--accent);
    color: var(--accent);
}
.lp-demo-article-card__status--enriched {
    background: rgba(34, 197, 94, 0.12);
    border-color: rgba(34, 197, 94, 0.35);
    color: rgb(34, 197, 94);
}
body.light .lp-demo-article-card__status--enriched {
    background: rgba(34, 197, 94, 0.10);
    color: rgb(22, 163, 74);
}
.lp-demo-article-card__title {
    font-weight: 600;
    color: var(--text);
    font-size: 0.92rem;
    line-height: 1.4;
}
.lp-demo-article-card__note {
    font-size: 0.75rem;
    color: var(--text-muted);
    font-style: italic;
}
/* Every rendered article card is clickable (drills to article
   detail). Subtle hover affordance — no pulsing animation, because
   if everything pulses nothing does. */
.lp-demo-article-card--clickable {
    cursor: pointer;
    transition: border-color 120ms ease, transform 120ms ease, background 120ms ease;
}
.lp-demo-article-card--clickable:hover,
.lp-demo-article-card--clickable:focus-visible {
    border-color: var(--accent);
    transform: translateY(-1px);
    outline: none;
}
.lp-demo-article-card--queued {
    opacity: 0.5;
    cursor: default;
}

/* Article detail dynamic view — off-spine sideways exploration
   reachable from any article card in Incoming, Stream, or WP
   stages. */
.lp-demo-article-detail {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin: 1.2rem 0;
    padding: 1.2rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.lp-demo-article-detail__row {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lp-demo-article-detail__label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
}
.lp-demo-article-detail__placeholder {
    margin: 1rem 0 1.4rem;
    padding: 1rem 1.2rem;
    background: var(--bg-elev);
    border: 1px dashed var(--border);
    border-radius: 8px;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
    font-style: italic;
}

/* Chips */
.lp-demo-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.1rem;
}
.lp-demo-chips--enrich { margin-top: 0.25rem; }
.lp-demo-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    line-height: 1.5;
    border: 1px solid transparent;
}
.lp-demo-chip--baseline {
    background: var(--bg);
    color: var(--text-muted);
    border-color: var(--border);
}
.lp-demo-chip--package {
    background: rgba(37, 99, 235, 0.10);
    color: var(--accent);
    border-color: rgba(37, 99, 235, 0.25);
}
.lp-demo-chip--package strong { color: var(--accent); font-weight: 600; }
body.light .lp-demo-chip--package {
    background: rgba(37, 99, 235, 0.08);
    border-color: rgba(37, 99, 235, 0.20);
}

/* Clickable chips (baseline tags) — click filters the Stream by
   that tag. Subtle lift on hover so the affordance is visible
   without the chip screaming for attention. */
.lp-demo-chip--clickable {
    cursor: pointer;
    transition: transform 80ms ease, box-shadow 80ms ease, border-color 80ms ease;
}
.lp-demo-chip--clickable:hover,
.lp-demo-chip--clickable:focus-visible {
    transform: translateY(-1px);
    border-color: var(--accent);
    color: var(--text);
    outline: none;
}

/* Filter banner shown above the article list when a stream filter
   is active. Sits between the live-status line and the cards so
   visitors can scan from "filtered by X · N of M" straight into
   the matching cards. */
.lp-demo-stream-filter-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0.8rem 0;
    padding: 0.55rem 0.9rem;
    background: var(--bg-elev);
    border: 1px solid var(--accent);
    border-radius: 6px;
    font-size: 0.85rem;
    color: var(--text);
}
.lp-demo-stream-filter-banner strong {
    color: var(--accent);
    font-weight: 600;
}
.lp-demo-stream-filter-banner .lp-demo-btn {
    padding: 0.25rem 0.65rem;
    font-size: 0.78rem;
}

/* ── WP walkthrough — stream picker ──────────────────────── */
.lp-demo-stream-picker { display: flex; flex-direction: column; gap: 0.5rem; }
.lp-demo-stream-picker__row {
    display: flex;
    gap: 0.8rem;
    align-items: flex-start;
    padding: 0.9rem 1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.lp-demo-stream-picker__row--selected { border-color: var(--accent); }
.lp-demo-stream-picker__icon {
    flex-shrink: 0;
    font-size: 1.1rem;
    color: var(--accent);
    line-height: 1.4;
}
.lp-demo-stream-picker__body { flex: 1; min-width: 0; }
.lp-demo-stream-picker__name {
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.2rem;
}
.lp-demo-stream-picker__meta {
    font-size: 0.78rem;
    color: var(--text-muted);
}

/* ── WP walkthrough — mini article list (compact) ──────── */
.lp-demo-mini-articles {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.lp-demo-mini-articles--nested {
    margin-top: 0.5rem;
    padding-left: 1rem;
    border-left: 2px solid var(--border);
}
.lp-demo-mini-article {
    display: grid;
    grid-template-columns: 8rem 5.5rem 1fr;
    gap: 0.7rem;
    align-items: baseline;
    padding: 0.4rem 0.5rem;
    font-size: 0.82rem;
    border-radius: 4px;
}
.lp-demo-mini-article:hover { background: var(--surface); }
.lp-demo-mini-article--clickable { cursor: pointer; }
.lp-demo-mini-article--clickable:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    background: var(--surface);
}
.lp-demo-mini-article__src {
    font-weight: 600;
    color: var(--accent);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.lp-demo-mini-article__date {
    color: var(--text-muted);
    font-size: 0.75rem;
}
.lp-demo-mini-article__title {
    color: var(--text);
    line-height: 1.4;
}

/* ── WP walkthrough — section proposal blocks ──────────── */
.lp-demo-sections {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.lp-demo-section-block {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.9rem 1rem;
}
.lp-demo-section-block__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 0.4rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px dashed var(--border);
}
.lp-demo-section-block__title {
    font-weight: 600;
    color: var(--text);
    font-size: 0.95rem;
}
.lp-demo-section-block__blurb {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* ── WP walkthrough — generated report view ────────────── */
.lp-demo-report {
    display: flex;
    flex-direction: column;
    gap: 1.4rem;
    margin: 0.4rem 0 1rem;
}
.lp-demo-report-section {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.1rem 1.2rem;
}
.lp-demo-report-section__title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
    margin: 0 0 0.7rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
}
.lp-demo-report-section__body p {
    margin: 0 0 0.6rem;
    color: var(--text);
    font-size: 0.92rem;
    line-height: 1.65;
}
.lp-demo-report-section__body p:last-child { margin-bottom: 0; }
.lp-demo-report-section__generating {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.85rem;
    padding: 0.6rem 0;
}
.lp-demo-citations {
    margin-top: 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--border);
    font-size: 0.75rem;
    color: var(--text-muted);
    font-style: italic;
}

/* ── Stream-status pulse indicator (used in stream live +
   generation status) ───────────────────────────────────── */
.lp-demo-stream-status {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.6rem 0.9rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.82rem;
    color: var(--text);
}
.lp-demo-stream-status__pulse {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: var(--accent);
    animation: lpDemoBlink 1.2s ease-in-out infinite;
    flex-shrink: 0;
}
.lp-demo-stream-status__pulse--done {
    animation: none;
    background: rgb(34, 197, 94);
}
@keyframes lpDemoBlink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

/* ── Output formats — PDF + Dashboard tabbed previews ─────── */
.lp-demo-formats {
    margin: 1.4rem 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.3rem 1.4rem;
}
.lp-demo-formats__header {
    margin-bottom: 1rem;
}
.lp-demo-formats__title {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
}
.lp-demo-formats__lede {
    margin: 0;
    font-size: 0.85rem;
    color: var(--text-muted);
    line-height: 1.55;
}
.lp-demo-formats__tabs {
    display: flex;
    gap: 0.4rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 1.1rem;
}
.lp-demo-formats__tab {
    padding: 0.55rem 1rem;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-muted);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    margin-bottom: -1px;
}
.lp-demo-formats__tab:hover { color: var(--text); }
.lp-demo-formats__tab--active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.lp-demo-format__caption {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin-top: 0.9rem;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--border);
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.55;
    flex-wrap: wrap;
}

/* PDF preview — faux paper card */
.lp-demo-pdf {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.lp-demo-pdf__page {
    background: #f7f6f1;
    color: #1a1a1a;
    border: 1px solid #d8d4c4;
    border-radius: 4px;
    padding: 2rem 2.2rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
    font-family: Georgia, 'Times New Roman', serif;
}
body.light .lp-demo-pdf__page {
    background: #fbfaf6;
    border-color: #d0ccbc;
}
.lp-demo-pdf__brand-row {
    display: flex;
    justify-content: space-between;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    color: #8a7a55;
    text-transform: uppercase;
    margin-bottom: 1rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid #d8d4c4;
}
.lp-demo-pdf__brand-block { font-weight: 700; }
.lp-demo-pdf__title {
    margin: 0 0 1.2rem;
    font-size: 1.4rem;
    color: #1a1a1a;
    line-height: 1.25;
    font-weight: 700;
}
.lp-demo-pdf__toc {
    background: rgba(0, 0, 0, 0.03);
    border-left: 3px solid #8a7a55;
    padding: 0.6rem 0.9rem;
    margin-bottom: 1.3rem;
    font-size: 0.82rem;
}
.lp-demo-pdf__toc-label {
    display: block;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 0.65rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #8a7a55;
    margin-bottom: 0.3rem;
}
.lp-demo-pdf__toc ol {
    margin: 0;
    padding-left: 1.2rem;
    color: #1a1a1a;
}
.lp-demo-pdf__toc li { margin: 0.1rem 0; }
.lp-demo-pdf__excerpt h4 {
    margin: 0 0 0.4rem;
    font-size: 0.95rem;
    color: #1a1a1a;
}
.lp-demo-pdf__excerpt p {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.65;
    color: #2a2a2a;
}
.lp-demo-pdf__footer {
    display: flex;
    justify-content: space-between;
    margin-top: 1.4rem;
    padding-top: 0.7rem;
    border-top: 1px solid #d8d4c4;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 0.65rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: #8a7a55;
}

/* Dashboard preview — grid of mini cards with live indicator */
.lp-demo-dash {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.lp-demo-dash__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.7rem 1rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.lp-demo-dash__title {
    font-weight: 600;
    color: var(--text);
    font-size: 0.95rem;
}
.lp-demo-dash__live {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 600;
}
.lp-demo-dash__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.7rem;
}
@media (max-width: 900px) {
    .lp-demo-dash__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .lp-demo-dash__grid { grid-template-columns: 1fr; }
}
.lp-demo-dash__card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.9rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-height: 130px;
}
.lp-demo-dash__card--wide {
    grid-column: 1 / -1;
}
.lp-demo-dash__card-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-muted);
}
.lp-demo-dash__big {
    font-size: 2.4rem;
    font-weight: 700;
    color: var(--accent);
    line-height: 1;
}
.lp-demo-dash__sub {
    font-size: 0.78rem;
    color: var(--text);
    line-height: 1.45;
}
.lp-demo-dash__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.82rem;
}
.lp-demo-dash__list li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    color: var(--text);
}
.lp-demo-dash__count {
    color: var(--accent);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.lp-demo-dash__bars {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.lp-demo-dash__bar {
    display: grid;
    grid-template-columns: 5.5rem 1fr 1.2rem;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.75rem;
}
.lp-demo-dash__bar-label { color: var(--text); }
.lp-demo-dash__bar-track {
    height: 0.5rem;
    background: var(--surface);
    border-radius: 3px;
    overflow: hidden;
    position: relative;
}
.lp-demo-dash__bar-fill {
    display: block;
    height: 100%;
    background: var(--accent);
    border-radius: 3px;
}
.lp-demo-dash__bar-val {
    color: var(--accent);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.lp-demo-dash__headlines {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.lp-demo-dash__headlines li {
    display: flex;
    gap: 0.6rem;
    font-size: 0.8rem;
    line-height: 1.45;
}
.lp-demo-dash__headline-src {
    flex-shrink: 0;
    width: 7rem;
    color: var(--accent);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.lp-demo-dash__headline-title {
    color: var(--text);
}

/* ── Just-arrived article highlight ───────────────────────── */
.lp-demo-article-card--just-arrived {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
    animation: lpDemoFadeInUp 0.35s ease both, lpDemoFlash 2.8s ease forwards;
}
@keyframes lpDemoFlash {
    0%   { box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.45); }
    40%  { box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.30); }
    100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0); }
}

/* Final summary */
.lp-demo-summary {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 6px;
    padding: 1rem 1.2rem;
    color: var(--text-muted);
    line-height: 1.6;
    margin-top: 1rem;
}
.lp-demo-summary p { margin: 0 0 0.6rem; }
.lp-demo-summary p:last-child { margin-bottom: 0; }
.lp-demo-summary__actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 1.2rem;
}

/* ─────────────────────────────────────────────────────────────
   Animations
   ───────────────────────────────────────────────────────────── */

@keyframes lpDemoFadeInUp {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}
.lp-demo-fade-in {
    animation: lpDemoFadeInUp 0.32s ease both;
}

@keyframes lpDemoPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0.45); }
    50%      { box-shadow: 0 0 0 6px rgba(37, 99, 235, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .lp-demo-fade-in,
    .lp-demo-article-card--clickable,
    .lp-demo-btn--pulse-hint,
    .lp-demo-modal__nav-item--pulse-hint {
        animation: none;
    }
}

/* ─────────────────────────────────────────────────────────────
   Responsive
   ───────────────────────────────────────────────────────────── */

@media (max-width: 800px) {
    .lp-demo-launchpad-card { padding: 1.4rem 1.2rem; }
    .lp-demo-modal__panel { height: 96vh; }
    .lp-demo-modal__chrome { flex-direction: column; }
    .lp-demo-modal__sidebar {
        width: 100%;
        flex-shrink: 0;
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
    .lp-demo-modal__nav { flex-direction: row; flex-wrap: wrap; padding: 0.5rem; }
    .lp-demo-modal__nav-item { flex: 1 0 auto; }
    .lp-demo-modal__sidebar-footer { display: none; }
    .lp-demo-modal__main { padding: 1.2rem; }
    .lp-demo-modal__header { flex-wrap: wrap; }
    .lp-demo-modal__nav-row { flex: 1 1 100%; order: 2; }
    .lp-demo-modal__close { order: 1; margin-left: auto; }
}

/* ════════════════════════════════════════════════════════════════
   PUBLIC — merged from public.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* Public landing CSS — deliberately separate from user.css. The
   public surface should feel lighter and more declarative than the
   signed-in app chrome; reusing the app's heavier tokens would drag
   in dashboard-like density we don't want for a marketing read.

   Mirrors the app's dark-default + body.light opt-in pattern so the
   theme toggle behaves the same way on both sides.

   Phase 0 foundation cleanup 2026-05-27 — the original public.css
   declared a SECOND :root + body.light pair (redefining --bg, --text,
   --border, --text-muted, --text-dim, --accent) plus bare `*`, bare
   `html, body`, and bare `a` rules. Those landed AFTER the BASELINE
   foundation in the merged file and silently overrode it on every
   authenticated page (cream bg, wrong text colour, kill-the-link-
   colour anchors). Foundation is now owned by BASELINE; the public-
   only additive vars (--bg-elev, --surface, --border-strong,
   --text-soft, --accent-deep, --accent-glow, --max-width,
   --section-pad-y, --radius, --transition) keep their values here
   but no longer reach beyond .o-public-shell. Public-page-specific
   font-family / antialiasing / link reset moved to .o-public-shell
   which public/*.html now wraps content in. */

:root {
    /* Public-only additive vars. Do NOT redeclare --bg / --text /
       --accent / --border / --text-muted / --text-dim — those are
       BASELINE-owned. The values that USED to live here were the
       conflicting overrides that caused the bleed. */
    --bg-elev: #11141a;
    --surface: #161a22;
    --border-strong: #2b313c;
    --text-soft: #cbd5e1;
    --accent-deep: #2563eb;
    --accent-glow: rgba(96, 165, 250, 0.18);
    --max-width: 1100px;
    --section-pad-y: 5rem;
    --radius: 10px;
    --transition: 0.18s ease;
}

body.light {
    /* Public-only additive var overrides for light mode. Same rule
       as above — no --bg / --text / --accent etc. here; BASELINE
       owns the swap. */
    --bg-elev: #ffffff;
    --surface: #ffffff;
    --border-strong: #cbd5e1;
    --text-soft: #1e293b;
    --accent-deep: #1d4ed8;
    --accent-glow: rgba(37, 99, 235, 0.12);
}

.o-public-shell {
    /* Public-page layout wrapper. Owns the public surface's
       typography + font-smoothing without poaching the bare
       body element. Foundation (background/color) flows from
       BASELINE through `body`, so we don't redeclare it. */
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", system-ui, sans-serif;
    font-size: 17px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Public-page anchor reset — links inherit color from their text
   context rather than carrying a default user-agent blue. Scoped
   to .o-public-shell so it doesn't reach the authenticated app. */
.o-public-shell a { color: inherit; text-decoration: none; }

/* ─── Top bar ──────────────────────────────────────────────────── */

.lp-topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 2rem;
    background: rgba(11, 13, 18, 0.7);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
}
body.light .lp-topbar {
    background: rgba(251, 252, 254, 0.78);
}
.lp-brand {
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--text);
}
/* Top-level nav layout. Three logical clusters as direct children:
   1. .lp-topbar-nav__content — Solution Packages · Pricing · Demo
   2. .lp-topbar-nav__auth    — Sign in + Request trial (pushed right
                                via margin-left: auto)
   3. .lp-theme-toggle         — bare icon, lowest visual weight, far right */
.lp-topbar-nav {
    display: flex;
    align-items: center;
    flex: 1;
    margin-left: 2rem;
    gap: 1rem;
}
.lp-topbar-nav__content {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.lp-topbar-nav__sep {
    color: var(--text-dim);
    font-size: 0.9rem;
    user-select: none;
}
.lp-topbar-nav__auth {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-left: auto;  /* floats auth + everything after to the right */
}

/* Content nav links — equal weight, the main marketing IA. */
.lp-link {
    color: var(--text-muted);
    font-size: 0.9rem;
    transition: color var(--transition);
}
.lp-link:hover { color: var(--text); }
.lp-link--active { color: var(--text); }

/* Sign in — visually secondary to content nav. Same color as content
   links but smaller, and no hover lift. Reads as "I already have an
   account" rather than "explore the product". */
.lp-link-quiet {
    color: var(--text-dim);
    font-size: 0.82rem;
    transition: color var(--transition);
}
.lp-link-quiet:hover { color: var(--text-soft); }

/* Theme toggle — bare icon, no chrome. Lowest visual weight on the
   topbar. Anchored at the far right as a tools cluster. */
.lp-theme-toggle {
    background: transparent;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    padding: 0.25rem 0.4rem;
    font-size: 1rem;
    line-height: 1;
    transition: color var(--transition);
}
.lp-theme-toggle:hover { color: var(--accent); }
.lp-theme-icon-light { display: none; }
body.light .lp-theme-icon-dark { display: none; }
body.light .lp-theme-icon-light { display: inline; }

/* Hamburger button — hidden on desktop, revealed at the mobile
   breakpoint (see the @media block in `Mobile tweaks` near the
   bottom of this file). */
.lp-topbar-menu-btn {
    display: none;
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    width: 2.2rem;
    height: 2.2rem;
    padding: 0;
    cursor: pointer;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    transition: border-color var(--transition);
}
.lp-topbar-menu-btn:hover { border-color: var(--border-strong); }
.lp-topbar-menu-btn__bar {
    display: block;
    width: 1.1rem;
    height: 2px;
    background: var(--text-muted);
    border-radius: 1px;
}
.lp-topbar-menu-btn[aria-expanded="true"] .lp-topbar-menu-btn__bar {
    background: var(--text);
}

/* ─── CTA buttons ──────────────────────────────────────────────── */

.lp-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.7rem 1.3rem;
    border-radius: 8px;
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    transition: background var(--transition), border-color var(--transition), transform var(--transition);
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}
.lp-cta-primary {
    background: var(--accent);
    color: #021026;
    border-color: var(--accent);
}
.lp-cta-primary:hover {
    background: var(--accent-deep);
    border-color: var(--accent-deep);
    color: #fff;
    transform: translateY(-1px);
}
body.light .lp-cta-primary { color: #fff; }
.lp-cta-secondary {
    background: transparent;
    color: var(--text);
    border-color: var(--border-strong);
}
.lp-cta-secondary:hover {
    border-color: var(--accent);
    color: var(--accent);
}
.lp-cta-small { padding: 0.45rem 0.95rem; font-size: 0.82rem; }
.lp-cta-large { padding: 0.95rem 2rem; font-size: 1rem; }

/* ─── Hero ─────────────────────────────────────────────────────── */

.lp-hero {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 6rem 2rem 4rem;
    text-align: center;
    position: relative;
    /* Allow the canvas to fill the hero box without spilling into
       the topbar / next section. */
    overflow: hidden;
}
.lp-hero-flow {
    /* Ambient background layer — sits behind the tagline + subtitle
       + CTAs. Sized via JS to match the hero box and the device DPR
       so circles render crisp on retina. The CSS reserves space and
       tints the layer; the canvas paint is JS-driven. */
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    /* Moderate opacity so the headline stays the focal point. The
       per-particle alpha values inside the loop already keep the
       motion subtle; this is an extra dial we can adjust without
       editing JS. */
    opacity: 0.85;
}
@media (prefers-reduced-motion: reduce) {
    /* When motion is off the canvas stays empty (the JS bails
       early). Hide it entirely so it doesn't even reserve a
       layout box that could affect text positioning. */
    .lp-hero-flow { display: none; }
}
.lp-hero::before {
    /* Subtle accent-glow behind the tagline — sits well in dark mode,
       fades nearly invisible in light mode where it would compete
       with the page surface. Sits BELOW the canvas (z-index: 0),
       canvas at z-index 1, text at z-index 2; layered glow → motion
       → headline reads coherently. */
    content: '';
    position: absolute;
    top: 4rem; left: 50%;
    width: 60%; height: 14rem;
    background: radial-gradient(ellipse at center, var(--accent-glow), transparent 70%);
    transform: translateX(-50%);
    pointer-events: none;
    z-index: 0;
}
.lp-hero-flow { z-index: 1; }
body.light .lp-hero::before { opacity: 0.4; }
.lp-hero-tagline {
    position: relative;
    z-index: 2;
    margin: 0;
    font-size: clamp(2.4rem, 5vw, 3.6rem);
    line-height: 1.08;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--text);
}
.lp-hero-subtitle {
    position: relative;
    z-index: 2;
    max-width: 38rem;
    margin: 1.4rem auto 0;
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--text-soft);
}
.lp-hero-actions {
    position: relative;
    z-index: 2;
    margin-top: 2.2rem;
    display: flex;
    justify-content: center;
    gap: 0.8rem;
    flex-wrap: wrap;
}

/* ─── Section frame ────────────────────────────────────────────── */

.lp-section {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--section-pad-y) 2rem;
    border-top: 1px solid var(--border);
}
.lp-section-title {
    margin: 0 0 1.4rem;
    font-size: clamp(1.3rem, 2.4vw, 1.7rem);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text);
}
.lp-section-lede {
    /* `max-width: 42rem` is a reading-column cap — the box should
       sit centered within its parent so `text-align: center` parents
       produce visually-centered ledes. Without auto L/R margin the
       box hugged the left edge and we kept manually overriding it
       per-section (lp-products, lp-demo, lp-compound, lp-pricing-cta,
       lp-sp-cta, lp-sp-other all added the override; lp-pricing-hero,
       lp-pricing-commercial, lp-sp-hero, lp-sp-resell were missed
       and rendered visibly off-center on wide viewports). Default to
       centered; sections that want a left-aligned reading column can
       override with `margin-left: 0`. */
    margin: 0 auto;
    max-width: 42rem;
    font-size: 1.02rem;
    line-height: 1.65;
    color: var(--text-soft);
}
.lp-section-lede strong { color: var(--text); font-weight: 600; }

.lp-section-note {
    /* Smaller, more muted note that sits between a lede and the
       content. Used on /landing under the Deliverables hero to make
       the "this is a sample, not the catalogue" framing visible
       without crowding the lede. */
    margin: 0.4rem auto 0;
    max-width: 42rem;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
    text-align: center;
}
.lp-section-note strong { color: var(--text); font-weight: 600; }

/* ─── Legal / long-form prose ──────────────────────────────────────
   Privacy + Terms pages. A measure-constrained reading column centered
   in the .lp-section. Descendant element styling follows the established
   prose-exception pattern (same shape as `.report-content` near line
   3094): we style bare h2/h3/p/ul/li *within* .lp-legal because the
   content is author-written long-form prose, not composed components.
   Theme-aware (vars only) so light + dark both read comfortably. */
.lp-legal {
    max-inline-size: 70ch;
    margin-inline: auto;
}
.lp-legal h2 {
    margin-block: 2rem 0.6rem;
    font-size: 1.2rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text);
}
.lp-legal h3 {
    margin-block: 1.4rem 0.4rem;
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--text);
}
.lp-legal p {
    margin-block: 0 0.9rem;
    font-size: 0.98rem;
    line-height: 1.6;
    color: var(--text-soft);
}
.lp-legal p strong { color: var(--text); font-weight: 600; }
.lp-legal ul {
    margin-block: 0.4rem 1rem;
    padding-inline-start: 1.4rem;
    color: var(--text-soft);
}
.lp-legal li {
    margin-block-end: 0.5rem;
    line-height: 1.6;
}
.lp-legal li strong { color: var(--text); font-weight: 600; }
.lp-legal a,
.lp-legal .lp-link { color: var(--accent); }
.lp-legal a:hover,
.lp-legal .lp-link:hover { color: var(--accent-hover); }

/* "Last updated …" line — quiet, sits under the title. */
.lp-legal__meta {
    margin-block: 0 1.6rem;
    font-size: 0.85rem;
    color: var(--text-dim);
}

/* Interim-notice callout — a subtle bordered panel with a left accent
   stripe. Distinct from body prose but deliberately calm (no danger
   colour); reads as "context", not "warning". */
.lp-legal__notice {
    margin-block: 0 2rem;
    padding-block: 1rem;
    padding-inline: 1.1rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-inline-start: 3px solid var(--accent);
    border-radius: 8px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-muted);
}

/* ─── Work-product cards ──────────────────────────────────────── */

/* "What you could be shipping." — four expandable cards in a 2x2
   grid (4-across on very wide screens, 1-column on mobile). The
   default view is a thumbnail with a kicker, title, and tagline;
   the <details> open state reveals the section breakdown and the
   source archetypes that feed it. Native <details> means it works
   without JS and the content is fully indexable.
*/
.lp-products {
    text-align: center;
}
.lp-products .lp-section-title {
    margin-bottom: 0.8rem;
}
.lp-products .lp-section-lede {
    margin: 0 auto 2rem;
    text-align: center;
}
.lp-products-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1.2rem;
    max-width: var(--max-width);
    margin: 0 auto;
    text-align: left;
}
@media (min-width: 1100px) {
    .lp-products-grid {
        /* Cap at 4-across for tidy two-row 2x2 on standard desktops,
           4-across hairline rows on very wide screens. */
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    }
}
.lp-product-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.4rem 1.4rem 1.2rem;
    transition: border-color var(--transition), background var(--transition),
        transform var(--transition), box-shadow var(--transition);
    cursor: pointer;
}
.lp-product-card:hover {
    border-color: var(--border-strong);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px var(--shadow-soft);
}
.lp-product-card[open] {
    border-color: var(--accent);
    background: linear-gradient(180deg, var(--surface) 0%, var(--accent-glow) 100%);
}
.lp-product-summary {
    list-style: none;
    /* Strip the default details marker; we render our own affordance
       in the title row so the chevron sits beside the card title
       rather than at column-0 of the row. */
}
.lp-product-summary::-webkit-details-marker { display: none; }
.lp-product-kicker {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
    margin-bottom: 0.6rem;
}
.lp-product-title {
    margin: 0 0 0.4rem;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
    /* Chevron affordance — rotates 90° when the details opens, hinting
       at the expand-collapse interaction. CSS-only, no JS. */
    position: relative;
    padding-right: 1.5rem;
}
.lp-product-title::after {
    content: '';
    position: absolute;
    right: 0.2rem;
    top: 50%;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--text-muted);
    border-bottom: 2px solid var(--text-muted);
    transform: translateY(-65%) rotate(-45deg);
    transition: transform var(--transition), border-color var(--transition);
}
.lp-product-card[open] .lp-product-title::after {
    transform: translateY(-25%) rotate(45deg);
    border-color: var(--accent);
}
.lp-product-tagline {
    margin: 0;
    color: var(--text-soft);
    font-size: 0.9rem;
    line-height: 1.5;
}
.lp-product-detail {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
    display: grid;
    gap: 0.9rem;
}
.lp-product-detail h4 {
    margin: 0 0 0.4rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}
.lp-product-detail ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
.lp-product-detail ul li {
    padding: 0.15rem 0 0.15rem 1rem;
    position: relative;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text);
}
.lp-product-detail ul li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.7rem;
    width: 0.35rem;
    height: 1px;
    background: var(--accent);
}
.lp-product-detail p {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--text-soft);
}

/* Package footer — surfaced inside each open card. Connects the
   work-product story on the landing to the Solution Packages page,
   so the visitor can step through from "this looks like my work"
   to "ah, that's the package I want".

   Pattern: small uppercase label "From package" + a chip-style link
   carrying the package name. The chip pattern visually separates the
   package name from the surrounding metadata so it reads as a tag,
   not a sentence — particularly important when the package name is
   itself a comma-separated phrase ("Investigation, due diligence and
   forensics") that would otherwise read as a noun-pile inside
   "From the X package". */
.lp-product-package {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px dashed var(--border);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
}
.lp-product-package__label {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    font-weight: 600;
}
.lp-product-package__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.85rem;
    color: var(--text-soft);
    transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.lp-product-package__chip::after {
    content: "→";
    color: var(--accent);
    transition: transform var(--transition);
}
.lp-product-package__chip:hover {
    border-color: var(--accent);
    color: var(--text);
    background: var(--accent-glow);
}
.lp-product-package__chip:hover::after {
    transform: translateX(2px);
}

/* ─── Demo section (landing CTA pointing at /demo) ────────────── */

/* The landing's lp-demo section used to be a tabbed per-vertical
   demo strip; it's now a single section pointing at the standalone
   /demo page. The supporting tradecraft-picker / vertical-pane /
   demo-card / demo-chip / demo-arrow rule families were removed
   when the markup was. */
.lp-demo .lp-section-title { text-align: center; }
.lp-demo .lp-section-lede { margin-left: auto; margin-right: auto; text-align: center; }
.lp-demo .lp-section-cta { text-align: center; margin-top: 1.5rem; }

/* ─── Modal ────────────────────────────────────────────────────── */

.lp-modal {
    position: fixed;
    inset: 0;
    z-index: 1500;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}
.lp-modal[aria-hidden="false"] {
    display: flex;
    animation: lp-modal-in 0.2s ease;
}
@keyframes lp-modal-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.lp-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(4px);
}
body.light .lp-modal-backdrop {
    background: rgba(15, 23, 42, 0.45);
}
.lp-modal-card {
    position: relative;
    width: min(720px, 100%);
    max-height: 90vh;
    overflow-y: auto;
    background: var(--bg-elev);
    border: 1px solid var(--border-strong);
    border-radius: 14px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
    color: var(--text);
}
body.lp-modal-open { overflow: hidden; }

.lp-modal-header {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.6rem 1.8rem 1rem;
    border-bottom: 1px solid var(--border);
    position: relative;
}
.lp-modal-stage {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--accent);
}
.lp-modal-stage-enriched {
    color: var(--accent);
}
.lp-modal-title {
    margin: 0;
    font-size: 1.3rem;
    font-weight: 600;
    line-height: 1.3;
    padding-right: 2.5rem;
}
.lp-modal-close {
    position: absolute;
    top: 1rem; right: 1rem;
    background: transparent;
    border: 0;
    color: var(--text-muted);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.25rem 0.55rem;
    border-radius: 6px;
    transition: background var(--transition), color var(--transition);
}
.lp-modal-close:hover {
    background: var(--surface);
    color: var(--text);
}

.lp-modal-body {
    padding: 1.4rem 1.8rem 1.8rem;
    font-size: 0.95rem;
    line-height: 1.6;
}
.lp-modal-lede {
    margin: 0 0 1.4rem;
    color: var(--text-soft);
}
.lp-modal-subtitle {
    margin: 1.5rem 0 0.6rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

.lp-modal-data {
    display: grid;
    grid-template-columns: 9rem 1fr;
    gap: 0.4rem 1rem;
    margin: 0;
    font-size: 0.9rem;
}
.lp-modal-row { display: contents; }
.lp-modal-row dt {
    color: var(--text-muted);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    align-self: center;
}
.lp-modal-row dd {
    margin: 0;
    color: var(--text);
    word-break: break-word;
}
.lp-modal-row dd code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.82rem;
    background: var(--surface);
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
}

.lp-modal-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lp-modal-list li {
    padding: 0.5rem 0.8rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.9rem;
    color: var(--text-soft);
}
.lp-modal-list-routes li strong { color: var(--accent); margin-right: 0.4rem; }

.lp-modal-prose p,
.lp-modal-prose-tight {
    margin: 0 0 0.9rem;
    color: var(--text-soft);
}
.lp-modal-prose-tight { margin-bottom: 0.4rem; }
.lp-modal-prose p:last-child { margin-bottom: 0; }

.lp-modal-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.4rem 0 0;
}
.lp-modal-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem 0.65rem;
    border-radius: 12px;
    font-size: 0.78rem;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
}
.lp-modal-chip em {
    font-style: normal;
    font-size: 0.68rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.lp-modal-chip-org    { border-color: rgba(96,165,250,0.45); }
.lp-modal-chip-person { border-color: rgba(167,139,250,0.45); }
.lp-modal-chip-money  { border-color: rgba(52,211,153,0.45); }
.lp-modal-chip-place  { border-color: rgba(251,191,36,0.45); }

@media (max-width: 600px) {
    .lp-modal-data { grid-template-columns: 1fr; gap: 0.1rem 0; }
    .lp-modal-row dt { margin-top: 0.6rem; }
    .lp-modal-row dt:first-child { margin-top: 0; }
    .lp-modal-card { width: 100%; max-height: 95vh; }
    .lp-modal-header { padding: 1.3rem 1.3rem 0.8rem; }
    .lp-modal-body { padding: 1.1rem 1.3rem 1.5rem; }
}

/* ─── Compound-value section (Cluster → Synthesis → Delivered) ── */

.lp-compound .lp-section-title { text-align: center; }
.lp-compound .lp-section-lede { margin-left: auto; margin-right: auto; text-align: center; }

.lp-compound-row {
    display: grid;
    grid-template-columns: 1.1fr auto 1fr auto 1.1fr;
    align-items: stretch;
    gap: 0.6rem;
    margin-top: 2rem;
}
.lp-compound-block {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.3rem 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    min-height: 16rem;
}
.lp-compound-stage {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--accent);
}
.lp-compound-block-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
}
.lp-compound-block-meta {
    margin-top: auto;
    font-size: 0.74rem;
    color: var(--text-muted);
}
.lp-compound-arrow {
    align-self: center;
    color: var(--text-dim);
}

/* Cluster — list of mini articles. */
.lp-compound-mini-list {
    list-style: none;
    margin: 0; padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.78rem;
    line-height: 1.35;
    color: var(--text-soft);
    flex: 1;
}
.lp-compound-mini-item {
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-elev);
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}
.lp-compound-mini-item-seen {
    border-color: rgba(96,165,250,0.55);
    background: rgba(96,165,250,0.10);
}
body.light .lp-compound-mini-item-seen {
    border-color: rgba(37,99,235,0.55);
    background: rgba(37,99,235,0.08);
}
.lp-compound-mini-tag {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent);
    background: var(--surface);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    flex-shrink: 0;
}
.lp-compound-mini-more {
    border-style: dashed;
    color: var(--text-muted);
    background: transparent;
    text-align: center;
    justify-content: center;
}

/* Synthesis — derived analysis card. */
.lp-compound-synth { color: var(--accent); }
.lp-compound-synth .lp-compound-block-title { color: var(--text); }
.lp-compound-synth-stat {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin: 0.5rem 0 0;
}
.lp-compound-synth-num {
    font-size: 2.4rem;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.02em;
    line-height: 1;
}
.lp-compound-synth-pct {
    font-size: 1.5rem;
    font-weight: 600;
    margin-left: 0.1rem;
}
.lp-compound-synth-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.lp-compound-spark {
    margin: 0.4rem 0;
    color: var(--accent);
}
.lp-compound-synth-foot {
    font-size: 0.78rem;
    color: var(--text-soft);
    margin-top: auto;
    line-height: 1.5;
}

/* Delivered — three buttons stacked. */
.lp-compound-deliveries {
    background: linear-gradient(180deg, rgba(96,165,250,0.06) 0%, var(--surface) 60%);
    border-color: rgba(96,165,250,0.45);
}
body.light .lp-compound-deliveries {
    background: linear-gradient(180deg, rgba(37,99,235,0.06) 0%, var(--surface) 60%);
    border-color: rgba(37,99,235,0.45);
}
.lp-compound-delivery {
    appearance: none;
    -webkit-appearance: none;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 0.9rem;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    color: inherit;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    width: 100%;
    transition: border-color var(--transition), transform var(--transition), background var(--transition);
}
.lp-compound-delivery:hover {
    border-color: var(--accent);
    transform: translateX(2px);
    background: var(--surface);
}
.lp-compound-delivery:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.lp-compound-delivery-icon {
    color: var(--accent);
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px; height: 32px;
    background: rgba(96,165,250,0.10);
    border-radius: 6px;
}
body.light .lp-compound-delivery-icon { background: rgba(37,99,235,0.10); }
.lp-compound-delivery-title {
    display: block;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text);
}
.lp-compound-delivery-meta {
    display: block;
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-top: 0.1rem;
}

@media (max-width: 880px) {
    .lp-compound-row {
        grid-template-columns: 1fr;
        gap: 0.6rem;
    }
    .lp-compound-arrow {
        justify-self: center;
        transform: rotate(90deg);
    }
}

/* ─── Mocked work-product surfaces inside delivery modals ───────── */

/* Report PDF mock — paper-look card. */
.lp-mock-doc {
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.6rem 1.8rem;
    font-size: 0.92rem;
    line-height: 1.55;
    color: var(--text-soft);
}
body.light .lp-mock-doc { background: #fdfdfd; }
.lp-mock-doc-meta {
    display: flex;
    justify-content: space-between;
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
    gap: 0.5rem;
}
.lp-mock-doc-title {
    margin: 0 0 0.2rem;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--text);
}
.lp-mock-doc-subtitle {
    font-size: 0.85rem;
    color: var(--text-muted);
    margin-bottom: 1rem;
}
.lp-mock-doc-h4 {
    margin: 1.3rem 0 0.5rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent);
}
.lp-mock-doc-p { margin: 0 0 0.8rem; }
.lp-mock-doc-foot { font-size: 0.8rem; color: var(--text-muted); }
.lp-mock-doc-ul {
    margin: 0 0 0.8rem;
    padding-left: 1.2rem;
}
.lp-mock-doc-ul li { margin-bottom: 0.25rem; }
.lp-mock-doc-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.5rem 0 0.8rem;
    font-size: 0.85rem;
}
.lp-mock-doc-table th,
.lp-mock-doc-table td {
    text-align: left;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
}
.lp-mock-doc-table th {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    background: var(--surface);
}

/* Dashboard mock — metric tiles + heatmap + feed list. */
.lp-mock-dash {
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.3rem 1.4rem;
}
.lp-mock-dash-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 0.7rem;
    margin-bottom: 1.4rem;
}
.lp-mock-dash-metric {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem 0.8rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.lp-mock-dash-metric-num {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--text);
}
.lp-mock-dash-metric-up { color: var(--green); }
body.light .lp-mock-dash-metric-up { color: #047857; }
.lp-mock-dash-metric-lbl {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.lp-mock-dash-h {
    margin: 1.2rem 0 0.5rem;
    font-size: 0.74rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.lp-mock-dash-heat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem;
}
.lp-mock-dash-heat-row {
    display: grid;
    grid-template-columns: 6.5rem repeat(4, 1fr);
    gap: 0.3rem;
    margin-bottom: 0.3rem;
}
.lp-mock-dash-heat-row:last-of-type { margin-bottom: 0.5rem; }
.lp-mock-dash-heat-label {
    font-size: 0.78rem;
    color: var(--text-soft);
    align-self: center;
}
.lp-mock-dash-heat-cell {
    border-radius: 4px;
    padding: 0.4rem 0;
    text-align: center;
    font-size: 0.78rem;
    color: var(--text);
    font-weight: 600;
    background: rgba(96,165,250,0.08);
    border: 1px solid var(--border);
}
.lp-mock-dash-heat-cell[data-i="0"] { background: rgba(96,165,250,0.04); color: var(--text-muted); }
.lp-mock-dash-heat-cell[data-i="1"] { background: rgba(96,165,250,0.16); }
.lp-mock-dash-heat-cell[data-i="2"] { background: rgba(96,165,250,0.32); }
.lp-mock-dash-heat-cell[data-i="3"] { background: rgba(96,165,250,0.55); color: #021026; }
.lp-mock-dash-heat-cell[data-i="4"] { background: rgba(96,165,250,0.85); color: #021026; }
body.light .lp-mock-dash-heat-cell[data-i="0"] { background: rgba(37,99,235,0.04); color: var(--text-muted); }
body.light .lp-mock-dash-heat-cell[data-i="1"] { background: rgba(37,99,235,0.14); }
body.light .lp-mock-dash-heat-cell[data-i="2"] { background: rgba(37,99,235,0.30); color: #fff; }
body.light .lp-mock-dash-heat-cell[data-i="3"] { background: rgba(37,99,235,0.55); color: #fff; }
body.light .lp-mock-dash-heat-cell[data-i="4"] { background: rgba(37,99,235,0.80); color: #fff; }
.lp-mock-dash-heat-cols {
    display: grid;
    grid-template-columns: 6.5rem repeat(4, 1fr);
    gap: 0.3rem;
    font-size: 0.7rem;
    color: var(--text-muted);
    text-align: center;
    margin-top: 0.2rem;
}
.lp-mock-dash-feed {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.lp-mock-dash-feed li {
    padding: 0.55rem 0.8rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.85rem;
    color: var(--text-soft);
    display: flex;
    gap: 0.7rem;
    align-items: baseline;
}
.lp-mock-dash-feed li:last-child { border-bottom: 0; }
.lp-mock-dash-feed-time {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    flex-shrink: 0;
    width: 4.5rem;
}

/* Feed JSON mock — code block. */
.lp-mock-code {
    background: #0b0d12;
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    padding: 1rem 1.2rem;
    font-size: 0.8rem;
    line-height: 1.55;
    color: #cbd5e1;
    overflow-x: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
body.light .lp-mock-code {
    background: #f8fafc;
    color: #0f172a;
    border-color: var(--border);
}

/* ─── Use-case cards ───────────────────────────────────────────── */

.lp-cases-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1.2rem;
    margin-top: 1.6rem;
}
.lp-case-card {
    padding: 1.6rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color var(--transition), transform var(--transition);
}
.lp-case-card:hover {
    border-color: var(--border-strong);
    transform: translateY(-2px);
}
.lp-case-kicker {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
    margin-bottom: 0.7rem;
}
.lp-case-body {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--text-soft);
}

/* ─── Flow diagram — Sources → Your Tasks → Work Products ─────── */

/* Three stage boxes laid out horizontally with plain text arrows
   between them. Mobile collapses to a vertical stack with the
   arrows rotated 90°. */
.lp-flow .lp-section-title {
    text-align: center;
}
.lp-flow-stages {
    display: flex;
    align-items: stretch;
    gap: 1rem;
    max-width: var(--max-width);
    margin: 0 auto;
    flex-wrap: wrap;
    justify-content: center;
}
.lp-flow-stage {
    flex: 1 1 220px;
    min-width: 220px;
    max-width: 320px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.6rem 1.4rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: border-color var(--transition), box-shadow var(--transition),
        transform var(--transition);
}
.lp-flow-stage:hover {
    border-color: var(--accent);
    box-shadow: 0 8px 28px var(--shadow-soft);
    transform: translateY(-2px);
}
.lp-flow-stage-title {
    margin: 0 0 0.6rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.lp-flow-stage-desc {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-soft);
}
.lp-flow-arrow {
    align-self: center;
    flex: 0 0 auto;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--accent);
    opacity: 0.7;
    user-select: none;
}

@media (prefers-reduced-motion: reduce) {
    .lp-flow-stage:hover {
        transform: none;
    }
}

@media (max-width: 720px) {
    .lp-flow-stages {
        flex-direction: column;
        align-items: stretch;
    }
    .lp-flow-stage {
        max-width: none;
    }
    .lp-flow-arrow {
        transform: rotate(90deg);
        align-self: center;
        padding: 0.2rem 0;
    }
}

/* ─── Why-partner list ─────────────────────────────────────────── */

.lp-why-list {
    list-style: none;
    padding: 0;
    margin: 1.4rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 1.2rem;
}
.lp-why-list li {
    padding: 1.3rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    font-size: 0.97rem;
    line-height: 1.6;
    color: var(--text-soft);
}
.lp-why-list strong {
    display: block;
    color: var(--text);
    margin-bottom: 0.3rem;
    font-weight: 600;
}

/* ─── CTA section ──────────────────────────────────────────────── */

.lp-cta-section {
    text-align: center;
}
.lp-cta-section .lp-section-title {
    margin-bottom: 0.7rem;
}
.lp-cta-lede {
    max-width: 36rem;
    margin: 0 auto 2rem;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--text-soft);
}

/* ─── Footer ───────────────────────────────────────────────────── */

.lp-footer {
    border-top: 1px solid var(--border);
    margin-top: 4rem;
}
.lp-footer-inner {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.lp-footer-brand {
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--text);
}
.lp-footer-meta {
    font-size: 0.85rem;
    color: var(--text-muted);
}
.lp-footer-link {
    font-size: 0.85rem;
    color: var(--text-muted);
    transition: color var(--transition);
}
.lp-footer-link:hover { color: var(--text); }
/* Footer nav cluster — sits opposite brand/meta via .lp-footer-inner's
   space-between; wraps to its own row on narrow viewports, and stacks
   left-aligned with the rest when .lp-footer-inner goes column at 640px. */
.lp-footer-links {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.25rem;
}

/* ─── Mobile tweaks ────────────────────────────────────────────── */

/* Topbar switches to hamburger + dropdown below 768px. The desktop
   structure (3 clusters with margin-left:auto on auth) collapses to
   a vertical stack:
     [content nav links — stacked]
     ──────── divider ────────
     Sign in (small)
     [Request trial — full-width filled]
     ◐ theme toggle (small, own row)
   The inline dot separators between content links are hidden — they
   only make sense in the horizontal layout. */
@media (max-width: 768px) {
    .lp-topbar { flex-wrap: wrap; }
    .lp-topbar-menu-btn { display: inline-flex; }
    .lp-topbar-nav {
        display: none;
        flex-basis: 100%;
        flex-direction: column;
        align-items: stretch;
        margin-left: 0;
        gap: 0;
        padding: 0.8rem 0 0.4rem;
        margin-top: 0.8rem;
        border-top: 1px solid var(--border);
    }
    .lp-topbar-menu-btn[aria-expanded="true"] + .lp-topbar-nav {
        display: flex;
    }
    /* Content cluster: stack links, hide dots */
    .lp-topbar-nav__content {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
    }
    .lp-topbar-nav__sep { display: none; }
    .lp-topbar-nav .lp-link {
        padding: 0.7rem 0.6rem;
        font-size: 1rem;
        color: var(--text-soft);
        border-radius: 6px;
    }
    .lp-topbar-nav .lp-link:hover { background: var(--bg-elev); color: var(--text); }
    /* Divider between content cluster and auth cluster */
    .lp-topbar-nav__auth {
        flex-direction: column;
        align-items: stretch;
        gap: 0.6rem;
        margin-left: 0;
        margin-top: 0.8rem;
        padding-top: 0.8rem;
        border-top: 1px solid var(--border);
    }
    .lp-topbar-nav__auth .lp-link-quiet {
        padding: 0.5rem 0.6rem;
        font-size: 0.95rem;
    }
    .lp-topbar-nav__auth .lp-cta {
        align-self: stretch;
        text-align: center;
    }
    /* Theme toggle on its own row at the bottom */
    .lp-topbar-nav .lp-theme-toggle {
        align-self: flex-start;
        margin-top: 0.8rem;
        padding: 0.5rem 0.6rem;
    }
}

@media (max-width: 640px) {
    .lp-topbar { padding: 0.8rem 1.2rem; }
    .lp-section { padding: 3rem 1.2rem; }
    /* Make the hero tall enough for the vertical-flow animation to
       have room to breathe — particles need to travel from the top
       edge through the filter-membrane to the output strip at the
       bottom. `min-height` is set in viewport units so the canvas
       always fills the screen below the topbar. */
    .lp-hero {
        padding: 3.5rem 1.2rem 2.5rem;
        min-height: calc(100vh - 4rem);
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .lp-hero-tagline { font-size: 2.1rem; line-height: 1.12; }
    .lp-footer-inner { flex-direction: column; align-items: flex-start; }
}


/* ─── Trial-request form ────────────────────────────────────────
   Public /request-trial form — same .lp-* vocabulary as the
   landing page so theming + chrome stay consistent. Section
   wraps a single column; honeypot field is visually hidden but
   reachable by bots that POST every input.
*/
.lp-trial-form,
.lp-trial-thanks {
    max-width: 640px;
    margin: 0 auto;
    padding: 4rem 1.5rem;
}
.lp-form {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: 2rem;
}
.lp-form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}
@media (max-width: 640px) {
    .lp-form-row { grid-template-columns: 1fr; }
}
.lp-form-field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lp-form-field label {
    font-size: 0.85rem;
    color: var(--text);
    font-weight: 500;
}
.lp-form-field small {
    font-size: 0.75rem;
    color: var(--text-muted);
}
.lp-form-field input[type="text"],
.lp-form-field input[type="email"],
.lp-form-field textarea {
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem 0.9rem;
    font: inherit;
    width: 100%;
    box-sizing: border-box;
    transition: border-color var(--transition);
}
.lp-form-field input:focus,
.lp-form-field textarea:focus {
    outline: none;
    border-color: var(--accent);
}
.lp-form-fieldset {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.2rem 1.2rem;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lp-form-fieldset legend {
    font-size: 0.9rem;
    font-weight: 600;
    padding: 0 0.5rem;
}
.lp-form-fieldset-hint {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin: 0 0 0.5rem 0;
}
.lp-form-checkbox {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.35rem 0;
    font-size: 0.9rem;
    cursor: pointer;
}
.lp-form-checkbox input { accent-color: var(--accent); }
.lp-form-actions {
    display: flex;
    align-items: center;
    gap: 1.2rem;
    margin-top: 0.5rem;
}
.lp-form-flash {
    padding: 0.8rem 1rem;
    border-radius: 6px;
    background: rgba(220, 38, 38, 0.12);
    color: #fca5a5;
    border: 1px solid rgba(220, 38, 38, 0.3);
    font-size: 0.9rem;
    margin-bottom: 1rem;
}
/* Honeypot — visually hidden but reachable by accessibility-naive
   scrapers. position+left ensures it's never visible to humans on
   any viewport. */
.lp-form-honeypot {
    position: absolute !important;
    left: -10000px !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
}

/* Radio variant — mirrors .lp-form-checkbox shape so the commercial
   vs internal intent question on /request-trial reads the same as
   the line-of-work multi-select above it. */
.lp-form-radio {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.4rem 0;
    font-size: 0.9rem;
    cursor: pointer;
    line-height: 1.45;
}
.lp-form-radio input { accent-color: var(--accent); margin-top: 0.25rem; }

/* ─── Pricing page ─────────────────────────────────────────────── */

.lp-pricing-hero {
    text-align: center;
    padding: 4rem 1.5rem 2.5rem;
}
.lp-pricing-hero .lp-section-title {
    font-size: 2.2rem;
    line-height: 1.15;
    margin: 0 0 1rem 0;
}
.lp-pricing-hero .lp-section-lede {
    max-width: 640px;
    margin: 0 auto;
}

.lp-pricing-tiers { padding: 2rem 1.5rem 3rem; }
.lp-pricing-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.2rem;
    max-width: 1280px;
    margin: 0 auto;
}
@media (max-width: 1100px) {
    .lp-pricing-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
    .lp-pricing-grid { grid-template-columns: 1fr; }
}

.lp-pricing-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.6rem 1.4rem 1.4rem;
    display: flex;
    flex-direction: column;
    position: relative;
}
.lp-pricing-card--featured {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}
.lp-pricing-card__badge {
    position: absolute;
    top: -0.7rem;
    right: 1rem;
    background: var(--accent);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.2rem 0.6rem;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.lp-pricing-card__name {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.6rem;
}
.lp-pricing-card__price {
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
    margin-bottom: 0.4rem;
}
.lp-pricing-card__amount {
    font-size: 2rem;
    font-weight: 700;
    color: var(--text);
}
.lp-pricing-card__period {
    font-size: 0.85rem;
    color: var(--text-muted);
}
.lp-pricing-card__tagline {
    font-size: 0.82rem;
    color: var(--text-muted);
    margin-bottom: 1.2rem;
    line-height: 1.4;
}
.lp-pricing-card__features {
    list-style: none;
    padding: 0;
    margin: 0 0 1.4rem 0;
    flex: 1;
}
.lp-pricing-card__features li {
    font-size: 0.85rem;
    line-height: 1.5;
    padding: 0.35rem 0;
    border-bottom: 1px dashed var(--border);
    color: var(--text);
}
.lp-pricing-card__features li:last-child { border-bottom: none; }
.lp-pricing-card__features strong { color: var(--text); font-weight: 600; }

.lp-pricing-packages,
.lp-pricing-commercial {
    text-align: center;
    padding: 2.5rem 1.5rem;
    max-width: 720px;
    margin: 0 auto;
}

.lp-pricing-faq {
    max-width: 760px;
    margin: 0 auto;
    padding: 3rem 1.5rem;
}
.lp-faq-item {
    border-bottom: 1px solid var(--border);
    padding: 0.9rem 0;
}
.lp-faq-item summary {
    cursor: pointer;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--text);
    padding: 0.3rem 0;
}
.lp-faq-item summary:hover { color: var(--accent); }
.lp-faq-item p {
    font-size: 0.85rem;
    color: var(--text-muted);
    line-height: 1.6;
    margin: 0.5rem 0 0 0;
}

.lp-pricing-cta {
    text-align: center;
    padding: 3.5rem 1.5rem 5rem;
}
/* Lede has max-width: 42rem; auto-margin so the box centers within
   the section, not just the text within the box. */
.lp-pricing-cta .lp-section-lede {
    margin-left: auto;
    margin-right: auto;
}
.lp-pricing-cta__buttons {
    display: flex;
    gap: 0.8rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1.2rem;
}

.lp-link--active { color: var(--accent); }

/* ─── Solution Packages page ───────────────────────────────────── */

.lp-sp-hero {
    text-align: center;
    padding: 4rem 1.5rem 2.5rem;
}
.lp-sp-hero .lp-section-title {
    font-size: 2.2rem;
    line-height: 1.15;
    margin: 0 0 1rem 0;
}
.lp-sp-hero .lp-section-lede {
    max-width: 640px;
    margin: 0 auto;
}

.lp-sp-anatomy {
    padding: 3rem 1.5rem;
    max-width: 1080px;
    margin: 0 auto;
}
.lp-sp-anatomy .lp-section-title {
    text-align: center;
    margin-bottom: 2rem;
}
.lp-sp-anatomy-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.2rem;
}
@media (max-width: 900px) {
    .lp-sp-anatomy-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .lp-sp-anatomy-grid { grid-template-columns: 1fr; }
}
.lp-sp-anatomy-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.5rem 1.3rem 1.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.lp-sp-anatomy-item:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}
.lp-sp-anatomy-icon {
    font-size: 1.9rem;
    line-height: 1;
}
.lp-sp-anatomy-item h3 {
    font-size: 1rem;
    margin: 0;
    color: var(--text);
    font-weight: 600;
    line-height: 1.3;
}
.lp-sp-anatomy-item p {
    font-size: 0.85rem;
    color: var(--text-muted);
    line-height: 1.55;
    margin: 0;
    flex: 1;
}

.lp-sp-curation .lp-section-title {
    text-align: center;
    margin-bottom: 0.6rem;
}
.lp-sp-curation .lp-section-lede {
    text-align: center;
    max-width: 760px;
    margin: 0 auto 2rem;
}
.lp-sp-curation-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 2rem;
}
@media (max-width: 1000px) {
    .lp-sp-curation-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .lp-sp-curation-grid { grid-template-columns: 1fr; }
}
.lp-sp-curation-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.2rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lp-sp-curation-item h3 {
    font-size: 0.95rem;
    margin: 0;
    color: var(--text);
    font-weight: 600;
    line-height: 1.3;
}
.lp-sp-curation-item p {
    font-size: 0.85rem;
    color: var(--text-muted);
    line-height: 1.55;
    margin: 0;
}
.lp-sp-curation-closer {
    text-align: center;
    max-width: 760px;
    margin: 0 auto;
}

.lp-sp-resell {
    text-align: center;
    padding: 2.5rem 1.5rem;
    max-width: 720px;
    margin: 0 auto;
    background: var(--surface);
    border-radius: 12px;
}
.lp-sp-resell .lp-section-title {
    font-size: 1.6rem;
}
.lp-sp-resell em { color: var(--accent); font-style: normal; font-weight: 600; }

.lp-sp-tiles {
    padding: 3.5rem 1.5rem;
    max-width: 1280px;
    margin: 0 auto;
}
.lp-sp-tiles .lp-section-title { text-align: center; margin-bottom: 2rem; }
.lp-sp-tile-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.2rem;
}
@media (max-width: 800px) {
    .lp-sp-tile-grid { grid-template-columns: 1fr; }
}
.lp-sp-tile {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.5rem 1.5rem 1.4rem;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.lp-sp-tile:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}
/* Featured tile — same accent treatment as the pricing card.
   Explicit modifier class so the rule works in browsers without
   :has() support, and matches the .lp-pricing-card--featured
   convention. */
.lp-sp-tile--featured {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}
.lp-sp-tile--featured:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}
.lp-sp-tile h3 {
    font-size: 1.05rem;
    margin: 0;
    color: var(--text);
    line-height: 1.3;
    font-weight: 600;
}
.lp-sp-tile p {
    font-size: 0.88rem;
    color: var(--text-muted);
    line-height: 1.55;
    margin: 0;
    flex: 1;
}
.lp-sp-tile .lp-link {
    font-size: 0.85rem;
    align-self: flex-start;
    margin-top: 0.2rem;
}
/* Lifted badge — sits ABOVE the tile edge so it reads as a real
   banner, not text inside the card. Mirrors .lp-pricing-card__badge
   positioning so the two pages feel like one family. */
.lp-sp-tile__badge {
    position: absolute;
    top: -0.7rem;
    right: 1rem;
    background: var(--accent);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 600;
    padding: 0.2rem 0.6rem;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    z-index: 1;
}
.lp-sp-other {
    text-align: center;
    margin: 1.8rem auto 0;  /* auto L/R so the 42rem-capped box itself
                               is centered, not just the text within */
    color: var(--text-muted);
}

.lp-sp-cta {
    text-align: center;
    padding: 3.5rem 1.5rem 5rem;
}
.lp-sp-cta .lp-section-title,
.lp-sp-cta .lp-section-lede {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

/* ════════════════════════════════════════════════════════════════
   OMNIBAR — merged from omnibar.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* Omnipresent search bar — slide-down modal triggered from the
 * topbar. Mounts on every authenticated page via base.html.
 *
 * v1 scope: Articles-only. Prefixes (tag/topic/category/topical/
 * actor/sector) scope WITHIN articles via the multi-search backend.
 * Clicking a result hard-navigates to /app/articles/{uid}, with
 * the query stashed in history.state so Back restores the modal. */

/* ── Trigger (lives in the topbar) ───────────────────────────────── */
.omnibar-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem 0.3rem 0.55rem;
    background: var(--bg-card, var(--bg-hover));
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-muted);
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.omnibar-trigger:hover,
.omnibar-trigger:focus-visible {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--accent);
    outline: none;
}
.omnibar-trigger-icon {
    width: 0.85rem;
    height: 0.85rem;
    flex: 0 0 auto;
}
.omnibar-trigger-label {
    font-weight: 500;
}
.omnibar-trigger-shortcut {
    font-family: monospace;
    font-size: 0.7rem;
    padding: 0.05rem 0.32rem;
    border-radius: 3px;
    background: var(--bg, rgba(0, 0, 0, 0.08));
    color: var(--text-muted);
    border: 1px solid var(--border);
}

/* ── Modal backdrop + panel ──────────────────────────────────────── */
.omnibar-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: none;
    background: rgba(0, 0, 0, 0.45);
    /* Modal slides down from the top; backdrop fades in. */
    opacity: 0;
    transition: opacity 140ms ease;
}
.omnibar-overlay--open {
    display: block;
    opacity: 1;
}

.omnibar-panel {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, -100%);
    /* Sized generously when results are present — results take real
     * estate, and the panel doubles as the analyst's article landing
     * surface (read the title + summary without opening the article).
     * Caps at 92vw so smaller screens still get most of the
     * viewport. */
    width: min(960px, 92vw);
    margin-top: 4vh;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Compact when idle — the input plus a row of empty-state space
     * is all we need; a tall empty modal felt overwhelming. The
     * `--expanded` modifier (added by JS while searching or when
     * hits are present) snaps the panel to a generous fixed height
     * for scanning. Height transitions so the growth is felt. */
    height: min(11rem, 88vh);
    transition: transform 180ms cubic-bezier(0.4, 0, 0.2, 1),
                height 220ms cubic-bezier(0.4, 0, 0.2, 1);
}
.omnibar-panel--expanded {
    height: min(720px, 88vh);
}
.omnibar-overlay--open .omnibar-panel {
    transform: translate(-50%, 0);
}

/* Inline mount — the panel sits directly in the host page rather
 * than floating over an overlay. Drop every modal-specific style
 * (centered absolute positioning, slide-down transform, shadow,
 * compact-then-grow height curve). The host container decides the
 * panel's width; the panel takes its natural height up to a sane
 * cap with internal scroll on the results pane (same as the modal's
 * `--expanded` state, so result density matches across modes). */
.omnibar-panel--inline {
    position: static;
    transform: none;
    width: 100%;
    margin-top: 0;
    box-shadow: none;
    height: auto;
    max-height: min(70vh, 800px);
    transition: none;
}

/* ── Search row ──────────────────────────────────────────────────── */
.omnibar-search-row {
    position: relative;
    border-bottom: 1px solid var(--border);
}
.omnibar-input {
    width: 100%;
    padding: 1.1rem 1.3rem 1.1rem 3rem;
    background: transparent;
    border: 0;
    color: var(--text);
    font-size: 1.05rem;
    outline: none;
    font-family: inherit;
}
.omnibar-input::placeholder {
    color: var(--text-muted);
}
.omnibar-search-icon {
    position: absolute;
    left: 1.1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1.05rem;
    height: 1.05rem;
    color: var(--text-muted);
    pointer-events: none;
}
.omnibar-close {
    position: absolute;
    right: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    color: var(--text-muted);
    font-size: 1.4rem;
    line-height: 1;
    padding: 0.3rem 0.5rem;
    cursor: pointer;
    border-radius: 4px;
}
.omnibar-close:hover {
    background: var(--bg-hover);
    color: var(--text);
}

/* ── Typeahead dropdown ──────────────────────────────────────────── */
.omnibar-typeahead {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 1px;
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    max-height: 280px;
    overflow-y: auto;
    z-index: 5;
    display: none;
}
.omnibar-typeahead.open { display: block; }
.omnibar-ta-item {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    padding: 0.45rem 1.1rem;
    cursor: pointer;
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.35;
}
.omnibar-ta-item--active,
.omnibar-ta-item:hover {
    background: var(--bg-hover);
}
.omnibar-ta-prefix {
    color: var(--accent);
    font-family: monospace;
    font-size: 0.78rem;
    flex: 0 0 auto;
    min-width: 4rem;
}
.omnibar-ta-value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.omnibar-ta-count {
    color: var(--text-muted);
    font-size: 0.72rem;
    flex: 0 0 auto;
}
.omnibar-ta-empty {
    padding: 0.6rem 1.1rem;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-style: italic;
}
.omnibar-ta-empty code,
.omnibar-ta-empty kbd {
    font-style: normal;
    font-family: monospace;
    background: var(--bg-hover);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    border: 1px solid var(--border);
    font-size: 0.85em;
}

/* ── Chip bar ────────────────────────────────────────────────────── */
.omnibar-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    padding: 0.55rem 1.1rem;
    border-bottom: 1px solid var(--border);
}
.omnibar-chips:empty { display: none; }
.omnibar-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.18rem 0.55rem;
    border-radius: 10px;
    font-size: 0.78rem;
    background: rgba(96, 165, 250, 0.12);
    color: var(--accent);
    border: 1px solid rgba(96, 165, 250, 0.35);
}
.omnibar-chip--free_text {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border);
    font-family: monospace;
}
.omnibar-chip-pfx {
    color: var(--text-muted);
    font-family: monospace;
    font-size: 0.72rem;
}
.omnibar-chip-remove {
    background: transparent;
    border: 0;
    color: inherit;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    opacity: 0.65;
}
.omnibar-chip-remove:hover { opacity: 1; }

/* ── Results list ────────────────────────────────────────────────── */
.omnibar-results {
    /* Grows to fill the remaining panel height. min-height:0 lets
     * the inner overflow-y actually scroll inside the flex parent
     * instead of pushing the panel taller than max-height. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0.4rem 0.55rem 0.7rem 0.55rem;
}
.omnibar-result {
    display: block;
    padding: 0.55rem 0.85rem;
    border-radius: 6px;
    cursor: pointer;
    color: var(--text);
    text-decoration: none;
    transition: background 80ms ease;
    border-bottom: 1px solid transparent;
}
.omnibar-result + .omnibar-result {
    /* Subtle row separator so the eye can chunk results without the
     * panel feeling like one big block. */
    border-top: 1px solid var(--border);
    margin-top: 1px;
}
.omnibar-result:hover,
.omnibar-result--active {
    background: var(--bg-hover);
}
.omnibar-result-title {
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.3;
    /* Bumped from 0.18rem so the meta row (date · source · matched)
     * has a visible breathing gap below the title rather than
     * crowding it. */
    margin-bottom: 0.4rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.omnibar-result-meta {
    color: var(--text-muted);
    font-size: 0.74rem;
    display: flex;
    align-items: center;
    /* Generous gap so the source pill doesn't bump straight into the
     * date on one side or the matched-dims label on the other. */
    gap: 0.9rem;
    flex-wrap: wrap;
}
.omnibar-result-source {
    /* Source chip: favicon + hostname with a subtle surface, slight
     * inset. Stands out from the surrounding bare-text meta bits. */
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.15rem 0.55rem 0.15rem 0.4rem;
    background: var(--bg-hover);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-weight: 500;
    line-height: 1.4;
}
.omnibar-result-favicon {
    width: 14px;
    height: 14px;
    display: block;
    flex: 0 0 auto;
    /* Round the icon a touch so it sits comfortably inside the pill;
     * a square logo on a pill background otherwise looks pasted-on. */
    border-radius: 3px;
}
.omnibar-result-dims {
    color: var(--accent);
    font-style: italic;
    /* Push to the far right of the meta row — date + source live on
     * the left, matched-dims is supplementary "why did this hit"
     * info that belongs at the edge so the eye doesn't have to
     * track past it to read the source. */
    margin-left: auto;
}
.omnibar-result-summary {
    color: var(--text-muted);
    font-size: 0.82rem;
    margin-top: 0.3rem;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.omnibar-state {
    padding: 1.4rem 1.2rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.88rem;
    line-height: 1.5;
    font-style: italic;
}
/* Result-count label above the hit list. Quiet meta — the eye
 * shouldn't lock onto it, but the count is useful context once
 * the analyst trusts the search is doing what they meant. */
.omnibar-count {
    padding: 0.4rem 0.85rem 0.55rem;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.35rem;
}


/* ════════════════════════════════════════════════════════════════
   LEARN — merged from learn.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* Learn — Intelligence Cycle and other in-platform educational pages.
   Reuses the product palette from user.css. Layout is master/detail:
   a vertical stack of phase buttons on the left, an expanded panel
   on the right. Animations are restrained — hover lift, soft accent
   on the active step, slide-fade reveal when the panel content
   changes. Honours prefers-reduced-motion. */

.learn-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem 1.5rem 4rem;
}

.learn-lede {
    font-size: 0.92rem;
    line-height: 1.55;
    color: var(--text-muted);
    margin: 0.5rem 0 1.5rem;
}

/* ----------------------- Two-column layout ------------------------ */

.cycle-layout {
    display: grid;
    grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
    gap: 1.5rem;
    align-items: stretch;        /* let the panel column match stack height */
    margin-bottom: 1.5rem;
}

/* ----------------------- Stack of phase buttons ------------------- */

.cycle-stack {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.cycle-step { margin: 0; }

.cycle-step-btn {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    background: var(--bg-card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem 0.9rem;
    cursor: pointer;
    text-align: left;
    transition:
        border-color 160ms ease,
        background 160ms ease,
        transform 160ms ease;
    font: inherit;
}

.cycle-step-btn:hover {
    border-color: var(--border-hover);
    background: var(--bg-hover);
    transform: translateX(2px);
}
.cycle-step-btn:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.18);
}

.cycle-step.is-active .cycle-step-btn {
    border-color: var(--accent);
    box-shadow: inset 3px 0 0 0 var(--accent),
                0 0 0 1px rgba(96, 165, 250, 0.20);
}

.cycle-step-num {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-dim);
    letter-spacing: 0.06em;
    flex-shrink: 0;
    width: 1.3rem;
    text-align: center;
}
.cycle-step.is-active .cycle-step-num { color: var(--accent); }

.cycle-step-body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
.cycle-step-name {
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text);
}
.cycle-step-tag {
    font-size: 0.72rem;
    color: var(--text-muted);
    line-height: 1.35;
}

/* ----------------------- Panel area (right column) --------------- */

.phase-panel-area {
    position: relative;
    /* The grid stretches us to the stack's height; pass that down via
       flex so the empty state fills the column exactly — no
       min-height, otherwise we'd over-shoot the stack on short
       layouts. */
    display: flex;
    flex-direction: column;
}

.phase-panel-empty {
    flex: 1 1 auto;             /* fill the available column height */
    background: var(--bg-card);
    border: 1px dashed var(--border-hover);
    border-radius: 8px;
    padding: 3rem 2rem;
    text-align: center;
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;    /* centre vertically when stretched */
    gap: 0.6rem;
    box-sizing: border-box;
}
.phase-panel-area.is-engaged .phase-panel-empty { display: none; }

.phase-panel-empty-icon {
    font-size: 2rem;
    color: var(--accent);
    opacity: 0.6;
    line-height: 1;
}
.phase-panel-empty-title {
    margin: 0;
    font-size: 1rem;
    color: var(--text);
    font-weight: 600;
}
.phase-panel-empty-hint {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.55;
    max-width: 420px;
}

.phase-panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.4rem 1.6rem 1.6rem;
    animation: phase-panel-reveal 280ms cubic-bezier(0.2, 0.8, 0.25, 1);
    transform-origin: left center;
}

@keyframes phase-panel-reveal {
    from { opacity: 0; transform: translateX(-8px); }
    to   { opacity: 1; transform: translateX(0); }
}

.phase-panel[hidden] { display: none; }

.phase-panel-header {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
}
.phase-panel-header h2 {
    margin: 0;
    font-size: 1.15rem;
    color: var(--text);
}

.phase-panel-num {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--accent);
    letter-spacing: 0.06em;
}

.phase-tagline {
    font-size: 0.92rem;
    color: var(--text-muted);
    margin: 0.5rem 0 1rem;
    font-style: italic;
}

.phase-section { margin-top: 1.1rem; }
.phase-section h3 {
    margin: 0 0 0.4rem;
    font-size: 0.68rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
}
.phase-section p {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--text);
}

.phase-links {
    list-style: none;
    margin: 0;
    padding: 0;
}
.phase-links li {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
    transition: padding-left 150ms ease;
}
.phase-links li:hover { padding-left: 0.4rem; }
.phase-links li:last-child { border-bottom: none; }
.phase-links a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}
.phase-links a:hover { text-decoration: underline; }
.phase-link-blurb {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.5;
}

/* ----------------------- Loop-back caption ----------------------- */

.cycle-loopback {
    margin: 1.5rem 0 0;
    font-size: 0.78rem;
    color: var(--text-dim);
    line-height: 1.5;
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
}
.cycle-loopback-icon {
    color: var(--accent);
    font-size: 1.05rem;
}

/* ----------------------- Mobile fallback ------------------------- */

@media (max-width: 720px) {
    .cycle-layout {
        grid-template-columns: 1fr;
        gap: 1rem;
    }
    .phase-panel-area { min-height: auto; }
    .phase-panel-empty { padding: 2rem 1rem; }
}

/* ----------------------- Reduced motion -------------------------- */

@media (prefers-reduced-motion: reduce) {
    .cycle-step-btn,
    .phase-panel,
    .phase-links li {
        animation: none !important;
        transition: none !important;
    }
}

/* ----------------------- Long-form learn pages -------------------- */
/* Used by learn_work_products.html and any other prose-heavy
   concept pages. Two-column max width with comfortable reading
   measure; section blocks get vertical rhythm and a subtle
   accent rail on the left to chunk the page visually. */

.learn-page > .learn-lede {
    font-size: 1.05rem;
    line-height: 1.65;
    color: var(--text);
    margin: 0.75rem 0 2rem;
}

.learn-section {
    max-width: 72ch;
    margin: 1.75rem 0;
    padding: 1.1rem 1.25rem 1.1rem 1.5rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 6px;
}

.learn-section h2 {
    margin: 0 0 0.65rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.learn-section p {
    margin: 0 0 0.85rem;
    line-height: 1.65;
    color: var(--text);
    font-size: 0.95rem;
}

.learn-section p:last-child { margin-bottom: 0; }

.learn-section ul,
.learn-section ol {
    margin: 0 0 0 1.25rem;
    padding: 0;
    line-height: 1.6;
}

.learn-section li {
    margin: 0.45rem 0;
    color: var(--text);
    font-size: 0.95rem;
}

.learn-section li strong {
    color: var(--accent);
    font-weight: 600;
}

.learn-section ol li {
    margin: 0.55rem 0;
    padding-left: 0.25rem;
}

.learn-section em {
    color: var(--text-muted);
    font-style: normal;
    background: rgba(96, 165, 250, 0.08);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    font-size: 0.92em;
}

.learn-section--package {
    border-left-color: var(--accent-warm, #f59e0b);
}

/* ════════════════════════════════════════════════════════════════
   INTENT-SEARCH-DRAWER — merged from intent_search_drawer.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* DD-040 Phase 6 v2/B4 — Article search drawer (deterministic v2).
 * Right-side overlay with prefix-chip input + canonical-list
 * typeahead + multi-search results. Theme-token-driven so it lives
 * in both light + dark cleanly. */

.isd-drawer {
    position: fixed;
    inset: 0;
    z-index: 1100;
}
.isd-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
}
.isd-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(720px, 96vw);
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: isd-slide 140ms ease-out;
}
@keyframes isd-slide {
    from { transform: translateX(40px); opacity: 0.2; }
    to   { transform: translateX(0); opacity: 1; }
}

.isd-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.9rem 1.1rem;
    border-bottom: 1px solid var(--border);
}
.isd-head-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
}
.isd-close {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 4px;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.isd-close:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.isd-panel-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.isd-help {
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.5;
}
.isd-help code {
    background: var(--bg-hover);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    color: var(--accent);
    font-size: 0.85em;
}
.isd-help kbd {
    background: var(--bg-hover);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 0.05rem 0.3rem;
    font-family: monospace;
    font-size: 0.85em;
}

/* Input row + typeahead — search input is the centre of attention. */
.isd-search-row {
    position: relative;
}
.isd-search-input {
    width: 100%;
    font-family: monospace;
    font-size: 0.9rem;
}
.isd-typeahead {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 0.2rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
    max-height: 280px;
    overflow-y: auto;
    z-index: 10;
    display: none;
}
.isd-typeahead.open { display: block; }
.isd-ta-item {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.4rem 0.7rem;
    cursor: pointer;
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.3;
}
.isd-ta-item--active,
.isd-ta-item:hover {
    background: var(--bg-hover);
}
.isd-ta-prefix {
    color: var(--accent);
    font-family: monospace;
    font-size: 0.8rem;
    flex: 0 0 auto;
    min-width: 4rem;
}
.isd-ta-value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.isd-ta-count {
    color: var(--text-muted);
    font-size: 0.72rem;
    flex: 0 0 auto;
}
.isd-ta-empty {
    padding: 0.55rem 0.75rem;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-style: italic;
    line-height: 1.45;
}
.isd-ta-empty code {
    background: var(--bg-hover);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    color: var(--accent);
    font-style: normal;
    font-size: 0.85em;
}
.isd-ta-empty kbd {
    background: var(--bg-hover);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 0.05rem 0.3rem;
    font-family: monospace;
    font-style: normal;
    font-size: 0.85em;
}
.isd-ta-empty strong {
    color: var(--text);
    font-style: normal;
}

/* Chips bar — committed filters. */
.isd-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.isd-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.5rem;
    border-radius: 10px;
    font-size: 0.78rem;
    background: rgba(96, 165, 250, 0.12);
    color: var(--accent);
    border: 1px solid rgba(96, 165, 250, 0.35);
}
.isd-chip--free_text {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border);
    font-family: monospace;
}
.isd-chip-pfx {
    color: var(--text-muted);
    font-family: monospace;
    font-size: 0.72rem;
}
.isd-chip-remove {
    background: transparent;
    border: 0;
    color: inherit;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    opacity: 0.65;
}
.isd-chip-remove:hover { opacity: 1; }

/* Results list. Two sections may appear: actionable (new) hits
 * first, then a muted heading + dim section for documents
 * already in this Work Product. */
.isd-results {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.isd-results-section {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.isd-results-section--existing {
    opacity: 0.55;
}
.isd-results-heading {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--border);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}
.isd-results-heading-count {
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.isd-hit--existing {
    cursor: not-allowed;
}
.isd-hit--existing:hover {
    background: var(--bg-card);
}
.isd-hit--existing .isd-hit-checkbox {
    cursor: not-allowed;
}
.isd-hit {
    display: flex;
    gap: 0.65rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    background: var(--bg-card);
    transition: background 100ms ease, border-color 100ms ease;
}
.isd-hit:hover { background: var(--bg-hover); }
.isd-hit--selected {
    border-color: var(--accent);
    background: rgba(96, 165, 250, 0.06);
}
.isd-hit-checkbox {
    flex: 0 0 auto;
    margin-top: 0.2rem;
    cursor: pointer;
}
.isd-hit-body {
    flex: 1 1 auto;
    min-width: 0;
}
.isd-hit-title {
    color: var(--text);
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.3;
}
.isd-hit-meta {
    color: var(--text-muted);
    font-size: 0.74rem;
    margin-top: 0.18rem;
}
.isd-hit-score {
    color: var(--accent);
    font-weight: 600;
}
.isd-hit-dims {
    color: var(--text-muted);
    font-style: italic;
}
.isd-hit-summary {
    color: var(--text-muted);
    font-size: 0.82rem;
    margin-top: 0.35rem;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.isd-empty {
    padding: 1.4rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.88rem;
    background: var(--bg);
    border: 1px dashed var(--border);
    border-radius: 6px;
    line-height: 1.5;
}
.isd-error {
    padding: 0.6rem 0.85rem;
    background: rgba(220, 38, 38, 0.10);
    border: 1px solid rgba(220, 38, 38, 0.4);
    color: var(--red);
    border-radius: 6px;
    font-size: 0.85rem;
}

.isd-footer {
    flex: 0 0 auto;
    padding: 0.85rem 1.1rem;
    border-top: 1px solid var(--border);
    background: var(--bg-card);
}
.isd-footer-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.8rem;
    flex-wrap: wrap;
}
.isd-footer-inner .isd-error { flex: 1 1 auto; }

/* ════════════════════════════════════════════════════════════════
   REPORT-COMPOSE — merged from report_compose.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* DD-040 Phase 6 v2/B3b.1 — Report Compose+Preview page. */

.dd040-compose {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1rem 1.5rem 2rem;
    max-width: 1080px;
    margin: 0 auto;
}

.dd040-compose-header {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.dd040-compose-titlerow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.dd040-compose-title {
    margin: 0;
    font-size: 1.3rem;
    color: var(--text);
}
.dd040-compose-help {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.88rem;
    line-height: 1.5;
}

.dd040-compose-loading,
.dd040-compose-empty {
    padding: 2rem;
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
    background: var(--bg-card);
    border: 1px dashed var(--border);
    border-radius: 8px;
}

.dd040-compose-error {
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid #ef4444;
    border-radius: 6px;
    padding: 0.6rem 0.85rem;
    color: #ef4444;
    font-size: 0.85rem;
}

.dd040-compose-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.dd040-compose-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    transition: border-color 120ms ease;
}
.dd040-compose-card--open {
    border-color: var(--accent);
}

/* Section header — the click target for fold/unfold. Strong visual
 * hierarchy: a left-aligned number badge, the title in bold, the
 * intent question as a subtitle, all framed by a band that's
 * distinct from the body editor. */
.dd040-compose-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 1.1rem;
    gap: 0.8rem;
    cursor: pointer;
    user-select: none;
    background: var(--bg-card);
    transition: background 100ms ease;
}
.dd040-compose-head:hover {
    background: var(--bg-hover);
}
.dd040-compose-card--open .dd040-compose-head {
    border-bottom: 1px solid var(--border);
}
.dd040-compose-head-left {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    flex: 1 1 auto;
    min-width: 0;  /* allow ellipsis on title */
}
.dd040-compose-head-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 0 0 auto;
}
.dd040-compose-num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.4rem;
    height: 2.4rem;
    padding: 0 0.65rem;
    border-radius: 6px;
    background: var(--bg-hover);
    color: var(--accent);
    font-weight: 700;
    font-size: 1rem;
    border: 1px solid var(--border);
}
.dd040-compose-head-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    flex: 1 1 auto;
}
.dd040-compose-head-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dd040-compose-head-question {
    font-size: 0.82rem;
    color: var(--text-muted);
    font-style: italic;
    line-height: 1.35;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dd040-compose-chevron {
    color: var(--text-muted);
    font-size: 0.9rem;
    transition: transform 120ms ease;
}

/* Section body — the editor surface that only renders when expanded. */
.dd040-compose-body {
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    background: var(--bg);
    border-top: 0;
}

.dd040-compose-card-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.dd040-compose-title-input {
    flex: 1 1 auto;
    font-size: 1.05rem;
    font-weight: 600;
}

.dd040-compose-status {
    flex: 0 0 auto;
    font-size: 0.75rem;
    font-style: italic;
}
.dd040-compose-status--saving {
    color: var(--text-muted);
}
.dd040-compose-status--error {
    color: #ef4444;
}

.dd040-compose-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.dd040-compose-field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}
@media (max-width: 700px) {
    .dd040-compose-field-row {
        grid-template-columns: 1fr;
    }
}

.dd040-compose-label {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

/* Textarea-specific knobs only — .form-input owns the colour /
 * border / focus story. Resize handle + min-height are textarea
 * conventions the canonical class doesn't enforce. */
.dd040-compose-textarea {
    resize: vertical;
    min-height: 4.5rem;
}
.dd040-compose-mode {
    width: auto;
}
.dd040-compose-tasks-input {
    width: 100%;
}

.dd040-compose-hint {
    font-size: 0.72rem;
    color: var(--text-muted);
    line-height: 1.4;
}

/* Free-standing footer — no card chrome, no drop shadow. The button
 * uses the app-wide .btn .btn-primary style so it harmonises with
 * every other primary action across the app. */
.dd040-compose-footer {
    margin-top: 1.2rem;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.8rem;
    flex-wrap: wrap;
}
.dd040-compose-footer .dd040-compose-error {
    flex: 1 1 auto;
    margin-right: 0.8rem;
}

/* ── Save-state pill (top-right of header) ──────────────────────── */
.dd040-compose-titlerow-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.dd040-compose-savepill {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 10px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    border: 1px solid var(--border);
    background: var(--bg-hover);
    color: var(--text-muted);
}
.dd040-compose-savepill--saved {
    background: rgba(34, 197, 94, 0.10);
    border-color: rgba(34, 197, 94, 0.35);
    color: var(--green);
}
.dd040-compose-savepill--saving {
    background: rgba(245, 158, 11, 0.10);
    border-color: rgba(245, 158, 11, 0.35);
    color: var(--amber);
}
.dd040-compose-savepill--dirty {
    background: var(--bg-hover);
    color: var(--text-muted);
}
.dd040-compose-savepill--error {
    background: rgba(220, 38, 38, 0.10);
    border-color: rgba(220, 38, 38, 0.4);
    color: var(--red);
}

/* ── Task-name typeahead popover ────────────────────────────────── */
/* Positioned absolutely against viewport (position:fixed) by JS so
 * it escapes any parent overflow clipping. Themed with the app-wide
 * tokens so it matches every other dropdown / select / popover. */
.dd040-ta-pop {
    position: fixed;
    z-index: 1000;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    max-height: 260px;
    overflow-y: auto;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
    display: none;
    font-size: 0.85rem;
}
.dd040-ta-pop.open { display: block; }
.dd040-ta-item {
    padding: 0.4rem 0.7rem;
    cursor: pointer;
    color: var(--text);
    line-height: 1.3;
}
.dd040-ta-item--active,
.dd040-ta-item:hover {
    background: var(--bg-hover);
    color: var(--accent);
}
.dd040-ta-empty {
    padding: 0.5rem 0.7rem;
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.82rem;
}

/* Status slot inside section cards — sized so layout doesn't jitter
 * when 'Saving…' / error appears or disappears. */
.dd040-compose-status-slot {
    flex: 0 0 auto;
    min-width: 4.5rem;
    text-align: right;
}

/* ── Configuration drawer (top of page) ────────────────────────────
 * The "Configuration" view holds all report-level knobs: model
 * picker, max tokens, temperature, concurrency, and the
 * "first section is summary" toggle. Collapsed by default; clicking
 * the header reveals the body. Same visual language as the section
 * cards below so the page reads as one consistent surface. */

.dd040-compose-cfg {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    transition: border-color 120ms ease;
}
.dd040-compose-cfg--open {
    border-color: var(--accent);
}
.dd040-compose-cfg-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1.1rem;
    cursor: pointer;
    user-select: none;
    background: var(--bg-card);
    transition: background 100ms ease;
}
.dd040-compose-cfg-head:hover {
    background: var(--bg-hover);
}
.dd040-compose-cfg--open .dd040-compose-cfg-head {
    border-bottom: 1px solid var(--border);
}
.dd040-compose-cfg-icon {
    font-size: 1.1rem;
    color: var(--accent);
    flex: 0 0 auto;
}
.dd040-compose-cfg-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    flex: 0 0 auto;
}
.dd040-compose-cfg-summary {
    flex: 1 1 auto;
    font-size: 0.82rem;
    color: var(--text-muted);
    font-family: monospace;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd040-compose-cfg-body {
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    background: var(--bg);
}
.dd040-compose-cfg-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
}
.dd040-compose-cfg-row {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--border);
}
.dd040-compose-cfg-toggle-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.92rem;
    color: var(--text);
}
.dd040-compose-cfg-checkbox {
    /* Native checkbox is fine; just align with the text baseline.
     * Hard to theme cross-browser without an SVG swap, so keep it
     * simple and let the OS theme rendering carry. */
    width: 1rem;
    height: 1rem;
    cursor: pointer;
}

/* ── Bound sources (per-section expandable + preview drawer) ────────
 * Makes the section→article bindings inspectable without leaving the
 * Compose page. The analyst can verify that renaming a section
 * hasn't drifted the bound article set away from the new intent. */

.dd040-sources {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-card);
    overflow: hidden;
}
.dd040-sources-head {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.55rem 0.75rem;
    cursor: pointer;
    user-select: none;
    transition: background 100ms ease;
}
.dd040-sources-head:hover { background: var(--bg-hover); }
.dd040-sources-label {
    font-weight: 600;
    color: var(--text);
    font-size: 0.88rem;
}
.dd040-sources-mode {
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--text-muted);
    font-family: monospace;
}
.dd040-sources-body { padding: 0; }
.dd040-sources-empty {
    padding: 0.85rem 1rem;
    font-size: 0.82rem;
    color: var(--text-muted);
    font-style: italic;
    line-height: 1.45;
    border-top: 1px solid var(--border);
}
.dd040-sources-loading {
    padding: 0.85rem 1rem;
    font-size: 0.82rem;
    color: var(--text-muted);
    border-top: 1px solid var(--border);
}
.dd040-sources-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border-top: 1px solid var(--border);
}
.dd040-sources-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.75rem;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    transition: background 100ms ease;
}
.dd040-sources-item:last-child { border-bottom: 0; }
.dd040-sources-item:hover { background: var(--bg-hover); }
.dd040-sources-num {
    flex: 0 0 auto;
    color: var(--accent);
    font-weight: 700;
    font-size: 0.82rem;
    min-width: 2rem;
    font-family: monospace;
}
.dd040-sources-item-body {
    flex: 1 1 auto;
    min-width: 0;
}
.dd040-sources-item-title {
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd040-sources-item-meta {
    color: var(--text-muted);
    font-size: 0.72rem;
    margin-top: 0.1rem;
}
.dd040-sources-item-arrow {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* ── Preview drawer ────────────────────────────────────────────────
 * Right-side overlay that loads the full article without navigating
 * away. Backdrop dims the page; Esc / click-outside / X all close. */

.dd040-preview-drawer {
    position: fixed;
    inset: 0;
    z-index: 1100;
}
.dd040-preview-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
}
.dd040-preview-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(640px, 96vw);
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: dd040-preview-slide 140ms ease-out;
}
@keyframes dd040-preview-slide {
    from { transform: translateX(40px); opacity: 0.2; }
    to   { transform: translateX(0); opacity: 1; }
}
.dd040-preview-head {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.9rem 1.1rem;
    border-bottom: 1px solid var(--border);
}
.dd040-preview-head-text {
    flex: 1 1 auto;
    min-width: 0;
}
.dd040-preview-head-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1.3;
}
.dd040-preview-head-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.2rem;
}
.dd040-preview-close {
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 4px;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.dd040-preview-close:hover {
    background: var(--bg-hover);
    color: var(--text);
}
.dd040-preview-summary,
.dd040-preview-content {
    padding: 1rem 1.1rem;
    border-bottom: 1px solid var(--border);
}
.dd040-preview-summary p {
    margin: 0.3rem 0 0 0;
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.5;
}
.dd040-preview-content {
    flex: 1 1 auto;
    overflow: auto;
}
.dd040-preview-content-text {
    margin: 0.3rem 0 0 0;
    color: var(--text);
    font-size: 0.85rem;
    line-height: 1.5;
    white-space: pre-wrap;
    font-family: inherit;
    background: transparent;
    border: 0;
    padding: 0;
}
.dd040-preview-foot {
    display: flex;
    gap: 0.5rem;
    padding: 0.8rem 1.1rem;
}

/* ════════════════════════════════════════════════════════════════
   TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* ============================================================
   Task Inspector — extracted from pipeline_builder.html
   ============================================================

   These rules are the subset of the .pb-* namespace that
   render the tabbed task editor (header with name/dirty/Save/
   Test buttons, Prompt/Output Template/Gating tabs, pass
   criteria editor, output template tree editor, Generate-
   from-Intent card, Test-run view).

   Kept byte-identical to the inline <style> block in
   pipeline_builder.html so the visual builder's look is
   preserved exactly. The builder loads this file AND its
   canvas-only styles (which live in the inline block); this
   file is the portable inspector skin that the standalone
   task editor mounts without the canvas CSS.

   Namespace: .pb-* — same as the inline block so HTML authored
   for the visual builder Just Works when mounted standalone.
   ============================================================ */

/* ============================================================
   Inspector — modal popup over the canvas (or standalone mount)
   ============================================================ */
.pb-inspector-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 999;
    display: none;
    align-items: center;
    justify-content: center;
    animation: pb-fade-in 0.12s ease-out;
}
.pb-inspector-backdrop.pb-open { display: flex; }
@keyframes pb-fade-in { from { opacity: 0; } to { opacity: 1; } }

.pb-inspector {
    width: 90vw;
    max-width: 1100px;
    height: 88vh;
    max-height: 920px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
}

.pb-inspector-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 1.1rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-hover);
}
.pb-inspector-head h3 {
    margin: 0;
    font-size: 0.95rem;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text);
    flex: 1;
    font-weight: 600;
}
.pb-inspector-close {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    width: 30px; height: 30px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0;
}
.pb-inspector-close:hover { color: var(--text); border-color: var(--accent); }

.pb-inspector-body {
    overflow-y: auto;
    flex: 1;
    padding: 1.2rem 1.4rem;
    font-size: 0.84rem;
}
.pb-inspector-body h4 {
    margin: 1.4rem 0 0.5rem 0;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    font-weight: 600;
}
.pb-inspector-body h4:first-child { margin-top: 0; }

.pb-inspector-body label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
    margin-top: 0.7rem;
}
.pb-inspector-body input,
.pb-inspector-body select,
.pb-inspector-body textarea {
    width: 100%;
    padding: 0.5rem 0.65rem;
    background: var(--bg);
    border: 1px solid var(--border-hover);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.85rem;
    box-sizing: border-box;
    font-family: inherit;
}
.pb-inspector-body textarea {
    font-family: ui-monospace, monospace;
    font-size: 0.78rem;
    min-height: 140px;
    resize: vertical;
    line-height: 1.5;
}
.pb-inspector-body input:focus,
.pb-inspector-body select:focus,
.pb-inspector-body textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--bg-card);
}

.pb-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}

.pb-criterion {
    display: grid;
    grid-template-columns: 1fr 60px 70px 22px;
    gap: 0.3rem;
    margin-bottom: 0.35rem;
    align-items: center;
}
.pb-criterion input { font-size: 0.72rem; padding: 0.25rem 0.4rem; }
.pb-criterion-remove {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 3px;
    font-size: 0.7rem;
    padding: 0;
    height: 22px;
}
.pb-criterion-remove:hover { color: var(--red); border-color: var(--red); }

.pb-add-criterion {
    margin-top: 0.4rem;
    background: transparent;
    border: 1px dashed var(--border);
    color: var(--text-muted);
    padding: 0.35rem 0.5rem;
    width: 100%;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.7rem;
}
.pb-add-criterion:hover { color: var(--accent); border-color: var(--accent); }

.pb-empty {
    color: var(--text-muted);
    font-size: 0.75rem;
    font-style: italic;
    padding: 1rem;
    text-align: center;
}

/* Task inspector — sticky header with the task name, stepper,
   dirty indicator and Save button. */
.pb-task-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--bg-card);
    margin: -1.2rem -1.4rem 1.2rem -1.4rem;
    padding: 0.9rem 1.4rem 0.75rem 1.4rem;
    border-bottom: 1px solid var(--border);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    isolation: isolate;
}
.pb-task-header-label {
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
    display: block;
}
.pb-task-header-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}
.pb-task-header-row:last-child { margin-bottom: 0; }
.pb-task-header-name {
    flex: 1;
    padding: 0.5rem 0.7rem !important;
    font-size: 0.95rem !important;
    font-weight: 600;
    background: var(--bg) !important;
    border: 1px solid var(--border-hover) !important;
    border-radius: 5px;
    color: var(--text);
}
.pb-task-header-name:focus {
    outline: none !important;
    border-color: var(--accent) !important;
}
.pb-task-dirty-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.55rem;
    background: rgba(245, 158, 11, 0.14);
    border: 1px solid rgba(245, 158, 11, 0.45);
    color: var(--amber);
    border-radius: 12px;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.pb-task-header-spacer { flex: 1; }
.pb-task-save-btn {
    padding: 0.5rem 1rem !important;
    background: var(--accent) !important;
    color: #0a0e17 !important;
    border: none !important;
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.82rem !important;
    font-weight: 600;
    width: auto !important;
    transition: opacity 120ms;
    white-space: nowrap;
}
.pb-task-save-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
.pb-task-test-btn {
    padding: 0.5rem 0.9rem !important;
    background: transparent !important;
    color: var(--green) !important;
    border: 1px solid var(--green) !important;
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.78rem !important;
    font-weight: 600;
    width: auto !important;
    transition: background 120ms, opacity 120ms;
    white-space: nowrap;
    margin-right: 0.5rem;
}
.pb-task-test-btn:hover:not(:disabled) {
    background: rgba(52, 211, 153, 0.12) !important;
}
.pb-task-test-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}
.pb-task-header-def-hint {
    font-size: 0.68rem;
    color: var(--text-muted);
    margin-top: 0.3rem;
}

/* Sub-tab row (Prompt / Output Template / Gating) */
.pb-task-tabs {
    display: flex;
    gap: 0.2rem;
    margin: 0.9rem 0 0.7rem 0;
    border-bottom: 1px solid var(--border);
}
.pb-task-tab {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 0.5rem 0.85rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    transition: color 120ms, border-color 120ms;
}
.pb-task-tab:hover { color: var(--text); }
.pb-task-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* ============================================================
   Output template tree editor
   ============================================================ */
.pb-tt-starters {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}
.pb-tt-starter {
    flex: 1 1 0;
    background: transparent;
    border: 1px dashed var(--border);
    color: var(--text-muted);
    padding: 0.3rem 0.4rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.68rem;
    min-width: 0;
}
.pb-tt-starter:hover { color: var(--accent); border-color: var(--accent); }

.pb-tt-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}
@media (max-width: 900px) {
    .pb-tt-layout { grid-template-columns: 1fr; }
}

.pb-tt-tree {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem 0.6rem 0.7rem 0.6rem;
    max-height: 56vh;
    overflow-y: auto;
}
.pb-tt-row {
    display: grid;
    grid-template-columns: var(--indent, 0) 16px minmax(0, 1.4fr) 110px minmax(0, 1.6fr) 28px 28px;
    gap: 0.45rem;
    align-items: center;
    padding: 0.28rem 0;
}
.pb-tt-bullet {
    color: var(--text-muted);
    font-size: 0.78rem;
    text-align: center;
    flex-shrink: 0;
    user-select: none;
}
.pb-tt-row input,
.pb-tt-row select {
    padding: 0.42rem 0.55rem;
    font-size: 0.82rem;
    background: var(--bg-card);
    border: 1px solid var(--border-hover);
    border-radius: 5px;
    color: var(--text);
    box-sizing: border-box;
    min-width: 0;
    width: 100%;
}
.pb-tt-row input:focus,
.pb-tt-row select:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--bg-hover);
}
.pb-tt-row input.pb-tt-name { font-weight: 600; }
.pb-tt-row input.pb-tt-hint {
    font-family: ui-monospace, monospace;
    font-size: 0.78rem;
    color: var(--text);
}
.pb-tt-row input.pb-tt-hint:disabled {
    color: var(--text-dim);
    background: var(--bg);
    border-style: dashed;
}
.pb-tt-row .pb-tt-btn {
    background: transparent;
    border: 1px solid var(--border-hover);
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 5px;
    padding: 0;
    width: 28px; height: 28px;
    font-size: 0.95rem;
    line-height: 1;
}
.pb-tt-row .pb-tt-btn:hover { color: var(--accent); border-color: var(--accent); }
.pb-tt-row .pb-tt-btn.rm:hover { color: var(--red); border-color: var(--red); }
.pb-tt-row .pb-tt-stub {
    grid-column: 3;
    font-size: 0.76rem;
    color: var(--text-muted);
    font-style: italic;
}

.pb-tt-add-root {
    margin-top: 0.6rem;
    width: 100%;
    background: transparent;
    border: 1px dashed var(--border-hover);
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 5px;
    padding: 0.55rem;
    font-size: 0.82rem;
}
.pb-tt-add-root:hover { color: var(--accent); border-color: var(--accent); }

.pb-tt-preview {
    font-family: ui-monospace, monospace;
    font-size: 0.78rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.8rem 0.9rem;
    color: var(--text);
    white-space: pre;
    max-height: 56vh;
    overflow: auto;
    line-height: 1.5;
}
.pb-tt-preview-label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 0.4rem;
}

/* ============================================================
   Generate-from-intent panel
   ============================================================ */
.pb-gen-card {
    border: 1px solid var(--border-hover);
    border-radius: 8px;
    background: linear-gradient(135deg, rgba(96,165,250,0.06), rgba(96,165,250,0.02));
    padding: 1rem;
    margin-bottom: 1.1rem;
}
.pb-gen-open-btn {
    width: 100%;
    background: transparent;
    border: 1px dashed var(--accent);
    color: var(--accent);
    padding: 0.7rem 1rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.88rem;
    font-weight: 500;
}
.pb-gen-open-btn:hover {
    background: rgba(96, 165, 250, 0.08);
}
.pb-gen-title {
    font-size: 0.8rem;
    color: var(--text);
    margin: 0 0 0.3rem 0;
    font-weight: 600;
}
.pb-gen-hint {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-bottom: 0.7rem;
    line-height: 1.45;
}
.pb-gen-model-row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.7rem;
    margin-bottom: 0.7rem;
}
.pb-gen-model-row span {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.pb-gen-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.6rem;
}
.pb-gen-actions button {
    padding: 0.55rem 0.9rem;
    border-radius: 5px;
    font-size: 0.82rem;
    cursor: pointer;
    border: 1px solid var(--border-hover);
    background: var(--bg);
    color: var(--text);
}
.pb-gen-actions button.primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #0a0e17;
    font-weight: 600;
    flex: 1;
}
.pb-gen-actions button.primary:hover { filter: brightness(1.1); }
.pb-gen-actions button.primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
.pb-gen-error {
    margin-top: 0.7rem;
    padding: 0.6rem 0.8rem;
    background: rgba(248, 113, 113, 0.08);
    border: 1px solid rgba(248, 113, 113, 0.4);
    border-radius: 5px;
    color: var(--red);
    font-size: 0.76rem;
}
.pb-gen-spinner {
    display: inline-block;
    width: 12px; height: 12px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: pb-spin 0.7s linear infinite;
    vertical-align: -2px;
    margin-right: 0.4rem;
}
@keyframes pb-spin { to { transform: rotate(360deg); } }

/* ============================================================
   Test-run view
   ============================================================ */
.pb-test-wrap {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.pb-test-picker {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.8rem;
}
.pb-test-run-btn {
    width: 100%;
    background: var(--accent);
    border: none;
    color: #0a0e17;
    padding: 0.75rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 600;
}
.pb-test-run-btn:hover { filter: brightness(1.1); }
.pb-test-run-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.pb-test-result {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    background: var(--bg);
}
.pb-test-status {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding-bottom: 0.8rem;
    margin-bottom: 0.8rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.76rem;
    color: var(--text-muted);
    flex-wrap: wrap;
}
.pb-test-badge {
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.pb-test-badge.pass { background: rgba(52,211,153,0.15); color: var(--green); border: 1px solid var(--green); }
.pb-test-badge.fail { background: rgba(248,113,113,0.12); color: var(--red); border: 1px solid var(--red); }
.pb-test-badge.none { background: var(--bg-hover); color: var(--text-muted); border: 1px solid var(--border); }

.pb-test-section {
    margin-top: 1rem;
}
.pb-test-section h5 {
    margin: 0 0 0.5rem 0;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    font-weight: 600;
}
.pb-test-json {
    font-family: ui-monospace, monospace;
    font-size: 0.76rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.7rem 0.8rem;
    color: var(--text);
    white-space: pre;
    max-height: 320px;
    overflow: auto;
    line-height: 1.5;
}
.pb-criterion-eval {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 5px;
    margin-bottom: 0.4rem;
    font-size: 0.76rem;
}
.pb-criterion-eval.pass { border-left: 3px solid var(--green); }
.pb-criterion-eval.fail { border-left: 3px solid var(--red); }
.pb-criterion-eval-cond {
    font-family: ui-monospace, monospace;
    color: var(--text);
}
.pb-criterion-eval-cond small { color: var(--text-muted); }
.pb-criterion-eval-mark {
    font-weight: 600;
    font-size: 0.82rem;
}
.pb-criterion-eval.pass .pb-criterion-eval-mark { color: var(--green); }
.pb-criterion-eval.fail .pb-criterion-eval-mark { color: var(--red); }

.pb-test-raw {
    margin-top: 1rem;
}
.pb-test-raw summary {
    cursor: pointer;
    font-size: 0.74rem;
    color: var(--text-muted);
    padding: 0.3rem 0;
}
.pb-test-raw summary:hover { color: var(--accent); }
.pb-test-raw pre {
    margin: 0.5rem 0 0 0;
    font-family: ui-monospace, monospace;
    font-size: 0.72rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.7rem;
    color: var(--text-muted);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 260px;
    overflow: auto;
}

/* ════════════════════════════════════════════════════════════════
   ARTICLE-BOOKMARK — merged from shared/article_bookmark.css 2026-05-27
   ════════════════════════════════════════════════════════════════ */
/* article_bookmark.css — styles for the shared "Save for later" popover.
 *
 * Loaded globally from base.html so any page that mounts a bookmark
 * trigger (`data-bookmark-trigger`) or pulls in
 * ArticleBookmark.renderPopover() gets the same look.
 *
 * Lifted from streams.css 1353-1538 (DD-032 Phase 3). The dd025-*
 * palette vars are defined locally inside the bookmark + popover
 * elements with fallbacks to the user.css product palette, so this
 * file is self-contained — pages don't need to load streams.css to
 * get the styling.
 */

/* ── Palette fallback for non-streams pages ──────────────────────
   When this CSS loads on a page that doesn't include streams.css,
   the dd025-* vars don't exist at :root. Scope them locally to the
   popover so it picks up the user.css product palette via
   intermediate vars. On streams.html the :root dd025-* definitions
   in streams.css win (later cascade, same specificity), preserving
   the GitHub-Primer palette there. */
.dd025-card-bookmark,
.dd025-bookmark-pop,
.dd025-bookmark-pop-host {
    --dd025-bg:              var(--bg, #0d1117);
    --dd025-surface-hover:   var(--bg-hover, #21262d);
    --dd025-surface-elev:    var(--bg-card, #11161d);
    --dd025-text:            var(--text, #c9d1d9);
    --dd025-text-bright:     var(--white, #f0f6fc);
    --dd025-text-dim:        var(--text-muted, #6e7681);
    --dd025-accent:          var(--accent, #58a6ff);
}

/* ── Body-mounted popover host (used by data-bookmark-trigger flow)─ */
.dd025-bookmark-pop-host {
    position: absolute;
    z-index: 900;
}

/* ── Bookmark icon button (lives in card / action row) ──────────── */
.dd025-card-bookmark {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 2px;
    background: transparent;
    border: none;
    color: var(--dd025-text-dim);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: color 120ms ease, background 120ms ease;
}

/* ── Popover panel ───────────────────────────────────────────── */
.dd025-bookmark-pop {
    /* Streams page positions this absolutely relative to its card
       container (`top: 38px; right: 10px`). The body-mounted variant
       (used by Incoming etc.) is wrapped in `.dd025-bookmark-pop-host`
       which is absolutely-positioned by article_bookmark.js — the
       popover itself uses `static` then so the host's coordinates
       win. */
    position: absolute;
    top: 38px;
    right: 10px;
    z-index: 50;
    width: 320px;
    background: var(--dd025-surface-elev);
    border: 1px solid var(--dd025-accent);
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    cursor: default;
}
.dd025-bookmark-pop-host .dd025-bookmark-pop {
    position: static;
    top: auto;
    right: auto;
}

/* ── Note section ────────────────────────────────────────────── */

/* ── Work-product list ─────────────────────────────────────────── */

/* ── "+ Create new Work Product" inline row ────────────────────── */

/* ════════════════════════════════════════════════════════════════
   INLINE BLOCKS — extracted from templates 2026-05-27
   ════════════════════════════════════════════════════════════════ */

/* ── from public/pricing.html ──────────────────────────────────── */
              .lp-pricing-trust { margin-top: -0.5rem; margin-bottom: 2.5rem; }
              .lp-trust-line {
                display: flex;
                align-items: center;
                justify-content: center;
                flex-wrap: wrap;
                gap: 0.4rem 0.9rem;
                font-size: 0.9rem;
                opacity: 0.7;
                line-height: 1.5;
              }
              .lp-trust-flag {
                font-size: 1.4rem;
                line-height: 1;
                margin-right: 0.2rem;
                opacity: 1;
                font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "EmojiOne Color", sans-serif;
              }
              .lp-trust-sep { opacity: 0.4; }
              @media (max-width: 640px) {
                .lp-trust-sep { display: none; }
              }
            
              .lp-pricing-addons { margin-top: -1rem; }
              .lp-addons-row {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 1.5rem;
              }
              .lp-addon-card {
                padding: 1.75rem;
                border-radius: 16px;
                border: 1px solid rgba(79,140,255,0.32);
                background: linear-gradient(135deg, rgba(79,140,255,0.12), rgba(79,140,255,0.02));
                display: flex;
                flex-direction: column;
                position: relative;
                cursor: pointer;
                transition: outline-color 140ms, transform 140ms, background 140ms;
              }
              .lp-addon-card:hover { transform: translateY(-2px); }
              .lp-addon-card.is-included {
                outline: 2px solid rgba(79,140,255,0.85);
                outline-offset: 4px;
                background: linear-gradient(135deg, rgba(79,140,255,0.22), rgba(79,140,255,0.05));
              }
              .lp-addon-card__toggle {
                position: absolute;
                top: 1rem;
                right: 1rem;
                font-size: 0.75rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.06em;
                padding: 0.3rem 0.7rem;
                border-radius: 999px;
                border: 1px solid rgba(79,140,255,0.45);
                background: transparent;
                color: inherit;
                pointer-events: none;
              }
              .lp-addon-card.is-included .lp-addon-card__toggle {
                background: rgba(79,140,255,0.85);
                border-color: rgba(79,140,255,0.85);
                color: #fff;
              }
              .lp-addon-card__eyebrow {
                font-size: 0.8rem;
                text-transform: uppercase;
                letter-spacing: 0.08em;
                opacity: 0.75;
                margin-bottom: 0.4rem;
                padding-right: 5rem; /* avoid collision with toggle pill */
              }
              .lp-addon-card__title { margin: 0 0 0.5rem; font-size: 1.2rem; font-weight: 600; line-height: 1.35; }
              .lp-addon-card__note { margin: 0 0 1rem; opacity: 0.85; font-size: 0.95rem; }
              .lp-addon-card__price { display: flex; align-items: baseline; gap: 0.4rem; margin-bottom: 0.3rem; }
              .lp-addon-card__amount { font-size: 1.75rem; font-weight: 700; }
              .lp-addon-card__period { opacity: 0.7; }
              .lp-addon-card__base { margin: 0 0 1rem; font-size: 0.85rem; opacity: 0.75; }
              .lp-addon-card .lp-cta { align-self: flex-start; margin-top: auto; }
              /* At Enterprise tier the commercial-use card has no concrete
                 price — suppress the price block + base note for a clean
                 card with just title, description, and CTA. */
              .lp-addon-card--commercial.is-tier-custom .lp-addon-card__price,
              .lp-addon-card--commercial.is-tier-custom .lp-addon-card__base { display: none; }

              /* Tier cards become click-targets */
              .lp-pricing-card { cursor: pointer; transition: transform 140ms, box-shadow 140ms, outline-color 140ms; }
              .lp-pricing-card:hover { transform: translateY(-2px); }
              .lp-pricing-card.is-selected {
                outline: 2px solid rgba(79,140,255,0.85);
                outline-offset: 4px;
              }
              /* Once the visitor has actively picked a tier, the marketing
                 nudge — both badge and featured "blue ribbon" — is noise. */
              .lp-pricing-grid.is-user-selected .lp-pricing-card__badge { display: none; }
              .lp-pricing-grid.is-user-selected .lp-pricing-card--featured {
                border-color: var(--border);
                box-shadow: none;
              }

              /* Bundle total panel */
              .lp-bundle {
                margin-top: 1.75rem;
                padding: 1.5rem 2rem;
                border-radius: 16px;
                background: var(--surface, rgba(255,255,255,0.04));
                border: 1px solid var(--border, rgba(255,255,255,0.12));
                display: grid;
                grid-template-columns: 1fr auto;
                gap: 2rem;
                align-items: center;
              }
              .lp-bundle__items { display: flex; flex-direction: column; gap: 0.35rem; }
              .lp-bundle__eyebrow {
                font-size: 0.75rem;
                text-transform: uppercase;
                letter-spacing: 0.08em;
                opacity: 0.65;
                margin-bottom: 0.4rem;
              }
              .lp-bundle__line {
                display: flex;
                justify-content: space-between;
                gap: 1.5rem;
                font-size: 0.95rem;
              }
              .lp-bundle__line--addon { opacity: 0.9; }
              .lp-bundle__line.is-hidden { display: none; }
              .lp-bundle__label { opacity: 0.85; }
              .lp-bundle__amount { font-variant-numeric: tabular-nums; opacity: 0.95; }
              .lp-bundle__total-block { text-align: right; min-width: 200px; }
              .lp-bundle__total-label {
                font-size: 0.75rem;
                text-transform: uppercase;
                letter-spacing: 0.08em;
                opacity: 0.65;
                margin-bottom: 0.2rem;
              }
              .lp-bundle__total-amount {
                font-size: 2rem;
                font-weight: 700;
                line-height: 1;
                margin-bottom: 0.2rem;
              }
              .lp-bundle__total-period { font-size: 0.9rem; font-weight: 400; opacity: 0.7; margin-left: 0.2rem; }
              .lp-bundle__total-note { margin: 0 0 0.8rem; font-size: 0.8rem; opacity: 0.65; }

              @media (max-width: 720px) {
                .lp-addons-row { grid-template-columns: 1fr; }
                .lp-bundle { grid-template-columns: 1fr; }
                .lp-bundle__total-block { text-align: left; }
              }
            

/* ── from user/_report_wizard_steps.html ───────────────────────── */
.wizard-steps {
    display: flex; align-items: center;
    gap: 0.5rem; margin: 0.4rem 0 1.2rem;
    padding: 0.6rem 0.8rem; background: rgba(255,255,255,0.02);
    border: 1px solid var(--border); border-radius: 6px;
}
.wizard-step { display: flex; align-items: center; gap: 0.45rem; color: var(--text-dim); font-size: 0.78rem; text-decoration: none; }
a.wizard-step:hover { color: var(--accent); }
a.wizard-step:hover .wizard-step-num { border-color: var(--accent); }
.wizard-step-num {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.4rem; height: 1.4rem; border-radius: 50%;
    border: 1px solid currentColor; font-weight: 600; font-size: 0.7rem;
}
.wizard-step.is-active { color: var(--accent); }
.wizard-step.is-active .wizard-step-num { background: var(--accent); color: #fff; border-color: var(--accent); }
.wizard-step.is-done { color: #86efac; }
.wizard-step.is-done .wizard-step-num { background: rgba(34,197,94,0.18); color: #86efac; border-color: rgba(34,197,94,0.55); }
.wizard-step-sep {
    flex: 1 0 1.5rem; max-width: 3rem;
    height: 1px; background: var(--border);
}

/* Light-theme overrides — the dark-theme defaults above use pale
   greens and a near-transparent strip background that disappear or
   wash out on a white surface. Switch to the theme's deeper green
   token (var(--green) = #047857 in light mode) and a real tinted
   pill background for the done state. */
body.light .wizard-steps { background: var(--bg-hover); }
body.light .wizard-step.is-done { color: var(--green); }
body.light .wizard-step.is-done .wizard-step-num {
    background: rgba(4, 120, 87, 0.12);
    color: var(--green);
    border-color: rgba(4, 120, 87, 0.5);
}
body.light .wizard-step.is-active .wizard-step-num { color: #fff; }

/* ── from user/admin_ai_cost.html ──────────────────────────────── */
.cost-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap;
}
.cost-window { display: inline-flex; gap: 0.3rem; }
.cost-window-btn {
    padding: 0.3rem 0.7rem; border-radius: 4px;
    background: rgba(0,0,0,0.2); border: 1px solid var(--border);
    color: var(--text-muted); font-size: 0.78rem; text-decoration: none;
}
.cost-window-btn.active { background: rgba(167,139,250,0.18); color: #c4b5fd; border-color: rgba(167,139,250,0.35); }

.cost-kpi-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.8rem; margin-bottom: 1.4rem; }
.cost-kpi {
    background: rgba(0,0,0,0.22); border: 1px solid var(--border);
    border-radius: 8px; padding: 0.9rem 1rem;
}
.cost-kpi-label { font-size: 0.72rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.3rem; }
.cost-kpi-value { font-size: 1.6rem; font-weight: 600; color: var(--white); font-variant-numeric: tabular-nums; }
.cost-kpi-hint { font-size: 0.72rem; color: var(--text-dim); margin-top: 0.25rem; }
.cost-uncounted-badge {
    display: inline-block; padding: 0.1rem 0.45rem; border-radius: 10px;
    background: rgba(220,38,38,0.15); color: #fca5a5;
    font-size: 0.68rem; font-weight: 600;
}

.cost-chart-wrap { margin-bottom: 1.6rem; }
.cost-chart-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 0.6rem;
}
.cost-section-title { font-size: 0.92rem; font-weight: 600; margin: 0; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
.cost-group-toggle { display: inline-flex; gap: 0.3rem; align-items: center; font-size: 0.75rem; color: var(--text-dim); }
.cost-toggle-btn {
    padding: 0.2rem 0.55rem; border-radius: 4px; text-decoration: none;
    color: var(--text-muted); border: 1px solid var(--border);
    background: rgba(0,0,0,0.2); font-size: 0.74rem;
}
.cost-toggle-btn.active { background: rgba(167,139,250,0.18); color: #c4b5fd; border-color: rgba(167,139,250,0.35); }

.cost-chart {
    width: 100%; height: 220px;
    background: rgba(0,0,0,0.22); border: 1px solid var(--border);
    border-radius: 6px; display: block;
}
.cost-chart-xaxis {
    display: flex; justify-content: space-between;
    font-size: 0.7rem; color: var(--text-dim); margin-top: 0.3rem;
}
.cost-chart-yaxis { font-size: 0.7rem; color: var(--text-dim); margin-top: 0.1rem; }

.cost-legend {
    display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.7rem;
    font-size: 0.74rem; color: var(--text-muted);
}
.cost-legend-item { display: inline-flex; align-items: center; gap: 0.3rem; }
.cost-swatch {
    display: inline-block; width: 10px; height: 10px; border-radius: 2px;
}
.cost-legend-more { color: var(--text-dim); font-style: italic; }

.cost-breakdowns {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1.4rem;
}
.cost-table-section {
    background: rgba(0,0,0,0.22); border: 1px solid var(--border);
    border-radius: 8px; padding: 0.9rem 1rem;
}
.cost-table-section .cost-section-title { margin-bottom: 0.6rem; }

.cost-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.cost-table th, .cost-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); text-align: left; }
.cost-table th { color: var(--text-dim); font-weight: 500; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; }
.cost-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.cost-table code { font-size: 0.78rem; color: var(--white); }

.cost-owner-pill {
    display: inline-block; padding: 0.1rem 0.45rem; border-radius: 10px;
    font-size: 0.68rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
}
.cost-owner-organization { background: rgba(96,165,250,0.14); color: #93c5fd; }
.cost-owner-account      { background: rgba(52,211,153,0.14); color: #6ee7b7; }
.cost-owner-system       { background: rgba(148,163,184,0.14); color: #cbd5e1; }
.cost-owner-unknown      { background: rgba(220,38,38,0.10); color: #fca5a5; }

.cost-filter-form {
    display: flex; gap: 0.7rem; align-items: end; margin-bottom: 0.8rem; flex-wrap: wrap;
}
.cost-filter-form label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.72rem; color: var(--text-dim); }
.cost-filter-form input {
    width: 220px; background: rgba(0,0,0,0.25); color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 4px; padding: 0.3rem 0.5rem; font-size: 0.82rem;
}
.cost-filter-form .btn-reset { background: rgba(220,38,38,0.1); color: #fca5a5; border-color: rgba(220,38,38,0.35); }

.cost-recent-table td:first-child { color: var(--text-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }

.cost-pagination {
    display: flex; gap: 0.5rem; align-items: center; margin-top: 0.6rem;
    font-size: 0.78rem; color: var(--text-dim);
}
.cost-pagination .btn-disabled { opacity: 0.3; cursor: not-allowed; }

.cost-empty {
    padding: 1rem; text-align: center; color: var(--text-dim);
    font-size: 0.82rem; font-style: italic;
    background: rgba(0,0,0,0.15); border-radius: 6px;
}

/* ── from user/admin_ai_pricing.html ───────────────────────────── */
.pricing-flash {
    padding: 0.5rem 0.8rem; margin: 0.6rem 0; border-radius: 6px; font-size: 0.85rem;
}
.pricing-flash-ok  { background: rgba(34,197,94,0.12);  color: #86efac; border: 1px solid rgba(34,197,94,0.35); }
.pricing-flash-err { background: rgba(220,38,38,0.10); color: #fca5a5; border: 1px solid rgba(220,38,38,0.35); }

.pricing-table { width: 100%; border-collapse: collapse; margin-top: 0.8rem; font-size: 0.85rem; }
.pricing-table th, .pricing-table td { padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--border); text-align: left; }
.pricing-table th { color: var(--text-dim); font-weight: 500; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }
.pricing-table input[type=number] {
    width: 100%; background: rgba(0,0,0,0.25); color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 4px; padding: 0.3rem 0.5rem; font-size: 0.82rem;
}

/* Highlight override rows so they stand out from the defaults */
.pricing-row-override { background: rgba(167,139,250,0.05); }

.pricing-model code { font-size: 0.82rem; color: var(--white); }
.pricing-badge { display: inline-block; padding: 0.1rem 0.5rem; border-radius: 10px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.pricing-badge-default  { background: rgba(148,163,184,0.14); color: #cbd5e1; }
.pricing-badge-override { background: rgba(167,139,250,0.18); color: #c4b5fd; }
.pricing-actions { white-space: nowrap; }
.pricing-actions .btn-reset { background: rgba(220,38,38,0.1); color: #fca5a5; border-color: rgba(220,38,38,0.35); }

/* ── from user/admin_pipeline_builder.html ─────────────────────── */
.config-label {
    display: block; font-size: 0.7rem; color: var(--text-dim);
    text-transform: uppercase; font-weight: 700; margin-bottom: 0.2rem;
}
.config-input {
    width: 100%; background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 4px;
    padding: 0.4rem 0.6rem; font-size: 0.85rem;
}
.config-input:focus { outline: none; border-color: var(--accent); }
.stage-card {
    border: 1px solid var(--border); border-radius: 6px;
    margin-bottom: 0.6rem; overflow: hidden;
}
.stage-header {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.5rem 0.7rem; background: var(--bg-card);
}
.stage-body { padding: 0.5rem 0.7rem; }
.task-row {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.3rem 0; border-bottom: 1px solid var(--border);
    font-size: 0.8rem;
}
.task-row:last-child { border-bottom: none; }
.stage-remove, .task-remove {
    background: none; border: none; color: var(--text-dim);
    cursor: pointer; font-size: 0.9rem; padding: 0.2rem;
}
.stage-remove:hover, .task-remove:hover { color: var(--red); }

/* ── from user/admin_pipeline_edit.html ────────────────────────── */
.config-editor {
    width: 100%; background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 6px;
    padding: 0.8rem; font-family: monospace; font-size: 0.8rem;
    line-height: 1.5; resize: vertical; tab-size: 2;
}
.config-editor:focus { outline: none; border-color: var(--accent); }

/* ── from user/admin_pipelines.html ────────────────────────────── */
/* `.pb-storage-pill` and `.pb-pill-*` moved to user.css so the
   tasks page and any future list views get them for free. */
.pb-pipeline-delete:hover {
    background: #991b1b !important;
    color: #fecaca !important;
}

/* ── from user/admin_task_edit.html ────────────────────────────── */
@keyframes intent-spin { to { transform: rotate(360deg); } }
.config-toggle {
    font-size: 0.8rem; color: var(--text-muted);
    display: flex; align-items: center; gap: 0.3rem; cursor: pointer;
}

/* ── from user/article_detail.html ─────────────────────────────── */
.ac-chip {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.25rem 0.6rem; border-radius: 14px;
    background: var(--bg-hover); border: 1px solid var(--border);
    font-size: 0.75rem;
}
.ac-chip a { color: var(--text); text-decoration: none; }
.ac-chip a:hover { color: var(--accent); }
.ac-chip-remove {
    background: transparent; border: 0; color: var(--text-muted);
    cursor: pointer; padding: 0; font-size: 0.95rem; line-height: 1;
}
.ac-chip-remove:hover { color: #ef4444; }
.ac-picker-dropdown {
    position: absolute; top: 100%; left: 0; right: 0;
    background-color: var(--bg-card); border: 1px solid var(--border);
    border-radius: 6px; max-height: 220px; overflow-y: auto;
    z-index: 1000; box-shadow: 0 6px 20px rgba(0,0,0,0.7);
    isolation: isolate;
}
.ac-picker-row {
    padding: 0.5rem 0.7rem; cursor: pointer;
    border-bottom: 1px solid var(--border); font-size: 0.8rem;
    background-color: var(--bg-card); color: var(--text);
}
.ac-picker-row:hover { background-color: var(--bg-hover); }
.ac-picker-row--create { color: var(--accent); font-weight: 500; }
.ac-picker-empty {
    padding: 0.6rem 0.8rem; color: var(--text-muted);
    font-size: 0.8rem; background-color: var(--bg-card);
}
body.light .ac-picker-dropdown {
    background-color: #ffffff;
    box-shadow: 0 6px 20px rgba(15, 23, 42, 0.16);
}
body.light .ac-picker-row,
body.light .ac-picker-empty { background-color: #ffffff; color: #0f172a; }
body.light .ac-picker-row:hover { background-color: #f1f5f9; }
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.3; } }

/* ── from user/articles_themes.html ────────────────────────────── */
  /* ============================================================
     Article Themes — master/detail
     Left: list of themes (tags with ≥N articles).
     Right: articles for the currently-selected theme.
     ============================================================ */

  body:has(.at-shell) .main-content {
      max-width: none;
      padding: 1rem 1.2rem 0 1.2rem;
      display: flex;
      flex-direction: column;
      min-height: 100vh;
      box-sizing: border-box;
  }
  body:has(.at-shell) .page-header { margin-bottom: 0.6rem; }
  body:has(.at-shell) .page-header h1 { font-size: 1.2rem; margin: 0; }

  .at-controls {
      display: flex;
      gap: 0.6rem;
      align-items: center;
      margin-bottom: 0.8rem;
      font-size: 0.78rem;
      color: var(--text-muted);
      flex-wrap: wrap;
  }
  .at-controls label {
      display: flex;
      align-items: center;
      gap: 0.4rem;
  }
  .at-controls select,
  .at-controls input[type="number"] {
      background: var(--bg-card);
      border: 1px solid var(--border);
      color: var(--text);
      padding: 0.3rem 0.5rem;
      border-radius: 4px;
      font-size: 0.78rem;
      font-family: inherit;
  }
  .at-controls input[type="number"] { width: 60px; }
  .at-controls .at-stat { color: var(--text-muted); font-size: 0.74rem; }

  .at-load-more {
      background: var(--bg-card);
      border: 1px dashed var(--border-hover);
      color: var(--text-muted);
      padding: 0.32rem 0.7rem;
      border-radius: 4px;
      cursor: pointer;
      font-size: 0.74rem;
      font-family: inherit;
  }
  .at-load-more:hover:not(:disabled) {
      color: var(--accent);
      border-color: var(--accent);
      border-style: solid;
  }
  .at-load-more:disabled {
      opacity: 0.4;
      cursor: not-allowed;
  }

  .at-shell {
      flex: 1;
      display: grid;
      grid-template-columns: 280px 1fr;
      gap: 0;
      border: 1px solid var(--border);
      border-radius: 8px;
      background: var(--bg-card);
      overflow: hidden;
      min-height: 600px;
  }

  /* Left column — themes list */
  .at-themes {
      border-right: 1px solid var(--border);
      background: var(--bg);
      overflow-y: auto;
      padding: 0.6rem 0.6rem 1rem 0.6rem;
  }
  .at-themes-header {
      font-size: 0.66rem;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      color: var(--text-muted);
      padding: 0.6rem 0.5rem 0.4rem 0.5rem;
      font-weight: 600;
  }
  .at-theme-search {
      width: 100%;
      box-sizing: border-box;
      padding: 0.45rem 0.6rem;
      background: var(--bg-card);
      border: 1px solid var(--border);
      color: var(--text);
      border-radius: 5px;
      font-size: 0.78rem;
      font-family: inherit;
      margin: 0 0 0.6rem 0;
  }
  .at-theme-search:focus {
      outline: none;
      border-color: var(--accent);
  }
  .at-theme-search::placeholder { color: var(--text-dim); }

  .at-theme {
      display: grid;
      grid-template-columns: minmax(0, 1fr) 70px 28px;
      align-items: center;
      gap: 0.5rem;
      padding: 0.55rem 0.75rem;
      border-radius: 6px;
      cursor: pointer;
      user-select: none;
      transition: all 0.12s;
      border: 1px solid transparent;
      margin-bottom: 0.2rem;
  }
  .at-theme-spark {
      width: 70px;
      height: 16px;
      display: block;
      opacity: 0.55;
  }
  .at-theme.at-selected .at-theme-spark { opacity: 1; }
  .at-theme-spark .at-spark-line {
      fill: none;
      stroke: var(--text-muted);
      stroke-width: 1.4;
  }
  .at-theme.at-selected .at-theme-spark .at-spark-line { stroke: var(--accent); }
  .at-theme-spark .at-spark-area {
      fill: var(--text-muted);
      opacity: 0.18;
  }
  .at-theme.at-selected .at-theme-spark .at-spark-area {
      fill: var(--accent);
      opacity: 0.22;
  }
  .at-theme-spark .at-spark-dot {
      fill: var(--text-muted);
  }
  .at-theme.at-selected .at-theme-spark .at-spark-dot { fill: var(--accent); }
  .at-theme:hover {
      background: var(--bg-hover);
      border-color: var(--border);
  }
  .at-theme.at-selected {
      background: rgba(96, 165, 250, 0.10);
      border-color: var(--accent);
  }
  .at-theme-name {
      font-size: 0.82rem;
      color: var(--text);
      font-weight: 500;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
  }
  .at-theme.at-selected .at-theme-name { color: var(--accent); }
  .at-theme:not(.at-virtual) .at-theme-name::before {
      content: '#';
      color: var(--text-muted);
      margin-right: 0.15rem;
  }
  .at-theme.at-selected:not(.at-virtual) .at-theme-name::before { color: var(--accent); }
  .at-theme-count {
      font-size: 0.7rem;
      color: var(--text-muted);
      background: var(--bg-hover);
      padding: 0.1rem 0.5rem;
      border-radius: 8px;
      min-width: 28px;
      text-align: center;
  }
  .at-theme.at-selected .at-theme-count {
      background: rgba(96, 165, 250, 0.18);
      color: var(--accent);
  }

  /* Right column — selected theme's articles */
  .at-detail {
      overflow-y: auto;
      padding: 1.2rem 1.5rem 2rem 1.5rem;
  }
  .at-detail-header {
      display: flex;
      align-items: baseline;
      gap: 0.7rem;
      padding-bottom: 0.85rem;
      margin-bottom: 1rem;
      border-bottom: 1px solid var(--border);
  }
  .at-detail-tag {
      font-size: 1.1rem;
      font-weight: 600;
      color: var(--accent);
  }
  .at-detail-meta {
      font-size: 0.74rem;
      color: var(--text-muted);
  }

  .at-bucket {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      margin: 1.2rem 0 0.5rem 0;
      font-size: 0.66rem;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      color: var(--text-muted);
      font-weight: 600;
  }
  .at-bucket:first-child { margin-top: 0; }
  .at-bucket-line {
      flex: 1;
      height: 1px;
      background: var(--border);
  }
  .at-bucket-count {
      color: var(--text-dim);
      font-weight: 500;
  }

  .at-article-list {
      list-style: none;
      padding: 0;
      margin: 0;
      display: flex;
      flex-direction: column;
      gap: 0.6rem;
  }
  .at-article {
      padding: 0.85rem 1rem;
      border: 1px solid var(--border);
      border-radius: 6px;
      background: var(--bg);
      transition: all 0.12s;
  }
  .at-article:hover {
      border-color: var(--accent);
  }
  .at-article-title {
      font-size: 0.92rem;
      color: var(--text);
      font-weight: 500;
      text-decoration: none;
      display: block;
      line-height: 1.4;
  }
  .at-article-title:hover { color: var(--accent); }
  .at-article-meta {
      display: flex;
      gap: 0.6rem;
      align-items: center;
      margin-top: 0.4rem;
      font-size: 0.7rem;
      flex-wrap: wrap;
  }
  .at-article-date {
      color: var(--text);
      opacity: 0.65;
      font-variant-numeric: tabular-nums;
      letter-spacing: 0.02em;
  }
  .at-article-cat {
      padding: 0.15rem 0.55rem;
      background: rgba(245, 158, 11, 0.12);
      border: 1px solid rgba(245, 158, 11, 0.35);
      border-radius: 4px;
      color: var(--amber);
      font-weight: 500;
      text-transform: uppercase;
      font-size: 0.64rem;
      letter-spacing: 0.04em;
  }
  .at-article-summary {
      margin-top: 0.5rem;
      font-size: 0.78rem;
      color: var(--text-muted);
      line-height: 1.5;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
  }
  .at-article-tags {
      margin-top: 0.5rem;
      display: flex;
      gap: 0.3rem;
      flex-wrap: wrap;
  }
  .at-article-tag {
      font-size: 0.66rem;
      color: var(--text-muted);
      background: var(--bg-hover);
      padding: 0.1rem 0.45rem;
      border-radius: 3px;
      border: 1px solid var(--border);
      cursor: pointer;
      transition: all 0.1s;
  }
  .at-article-tag:hover {
      color: var(--accent);
      border-color: var(--accent);
  }
  .at-article-tag.at-current {
      color: var(--accent);
      border-color: var(--accent);
      background: rgba(96, 165, 250, 0.1);
  }
  .at-article-tag.at-more {
      border-style: dashed;
      font-style: italic;
  }
  .at-article-tag.at-more:hover {
      color: var(--text);
      border-color: var(--accent);
  }

  /* Novelty badge on article rows */
  .at-novelty-badge {
      display: inline-block;
      padding: 0.1rem 0.45rem;
      border-radius: 3px;
      font-size: 0.64rem;
      font-weight: 600;
      letter-spacing: 0.03em;
      font-variant-numeric: tabular-nums;
  }
  .at-novelty-high {
      background: rgba(52, 211, 153, 0.15);
      color: var(--green);
      border: 1px solid rgba(52, 211, 153, 0.4);
  }
  .at-novelty-mid {
      background: rgba(245, 158, 11, 0.12);
      color: var(--amber);
      border: 1px solid rgba(245, 158, 11, 0.3);
  }
  .at-novelty-low {
      background: var(--bg-hover);
      color: var(--text-dim);
      border: 1px solid var(--border);
  }

  /* Virtual theme styling */
  .at-theme.at-virtual .at-theme-name {
      font-style: italic;
  }
  .at-theme.at-virtual .at-theme-name::before {
      content: '✦ ';
      color: var(--green);
      margin-right: 0;
  }

  .at-empty {
      text-align: center;
      color: var(--text-muted);
      padding: 4rem 1rem;
      font-size: 0.85rem;
      font-style: italic;
  }

/* ── from user/base.html ───────────────────────────────────────── */
.app-footer {
    margin-top: 2rem;
    padding: 0.5rem 0;
    text-align: center;
    font-size: 0.7rem;
    color: var(--text-dim);
    opacity: 0.6;
    font-family: monospace;
}
.app-footer:hover { opacity: 1; }

/* Global flash toast — drop-down from the top of the viewport with
   icon + message, auto-dismisses after ~3.5s. Type-aware (success /
   error / warn / info) with appropriate colour theming. Pages set
   `flash_toast` and optionally `flash_toast_type`; JS spawner uses
   the same component for AJAX-triggered toasts.

   Positioned fixed (centred above the main content) so it overlays
   without pushing content. Pointer events disabled so a quick click
   on the page below isn't swallowed. */
/* Layout: dark slate surface, slim coloured bar on the left, ringed
   icon badge, message, dismissable. Inspired by the user-supplied
   reference card. Each "type" only re-tints the bar + icon — the
   surface stays neutral so the text contrast is consistent across
   success / info / warn / error. Light-theme overrides at the bottom
   swap the slate for a paper surface with darker text. */
.flash-toast {
    position: fixed;
    top: 1rem;
    left: 50%;
    transform: translate(-50%, -140%);
    z-index: 1400;
    display: flex;
    align-items: center;
    gap: 0.95rem;
    min-width: 340px;
    max-width: min(92vw, 560px);
    padding: 0.95rem 1.1rem 0.95rem 1.4rem;
    border-radius: 12px;
    background: #1e293b;
    border: 1px solid #334155;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5),
                0 2px 6px rgba(0, 0, 0, 0.35);
    font-size: 0.95rem;
    font-weight: 600;
    color: #f1f5f9;
    letter-spacing: 0.005em;
    overflow: hidden;
    pointer-events: auto;
    animation: flash-toast-in 0.34s cubic-bezier(0.18, 0.89, 0.32, 1.18) forwards,
               flash-toast-out 0.4s ease 3.1s forwards;
}
.flash-toast-bar {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
    border-radius: 12px 0 0 12px;
}
.flash-toast-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem; height: 2rem;
    border-radius: 50%;
    border: 2px solid currentColor;
    flex-shrink: 0;
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1;
}
.flash-toast-msg {
    flex: 1;
    line-height: 1.35;
    color: #f8fafc;
}
.flash-toast-close {
    background: transparent;
    border: 0;
    color: #94a3b8;
    font-size: 1.25rem;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    border-radius: 6px;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s, color 0.15s;
}
.flash-toast-close:hover { background: rgba(255,255,255,0.08); color: #f8fafc; }

/* Type tints — only the bar + icon ring change; the surface and
   text stay neutral so colour-blind users still parse the icon
   shape. */
.flash-toast--success .flash-toast-bar { background: #10b981; }
.flash-toast--success .flash-toast-icon { color: var(--green); background: rgba(16,185,129,0.12); }

.flash-toast--info .flash-toast-bar { background: var(--accent-hover); }
.flash-toast--info .flash-toast-icon { color: var(--accent); background: rgba(59,130,246,0.14); font-style: italic; font-family: Georgia, serif; }

.flash-toast--warn .flash-toast-bar { background: var(--amber); }
.flash-toast--warn .flash-toast-icon { color: #fbbf24; background: rgba(251,191,36,0.14); }

.flash-toast--error .flash-toast-bar { background: #ef4444; }
.flash-toast--error .flash-toast-icon { color: var(--red); background: rgba(248,113,113,0.14); }

/* Light theme — paper surface, darker text, the bar + icon stay
   colour-tinted but with deeper hues so they read on a light bg. */
body.light .flash-toast {
    background: #ffffff;
    border-color: #e2e8f0;
    color: #0f172a;
    box-shadow: 0 14px 32px rgba(15, 23, 42, 0.16),
                0 1px 3px rgba(15, 23, 42, 0.08);
}
body.light .flash-toast-msg { color: #0f172a; }
body.light .flash-toast-close { color: #64748b; }
body.light .flash-toast-close:hover { background: rgba(15,23,42,0.06); color: #0f172a; }
body.light .flash-toast--success .flash-toast-icon { color: #047857; background: rgba(16,185,129,0.12); }
body.light .flash-toast--info .flash-toast-icon { color: #1d4ed8; background: rgba(59,130,246,0.12); }
body.light .flash-toast--warn .flash-toast-icon { color: #b45309; background: rgba(251,191,36,0.16); }
body.light .flash-toast--error .flash-toast-icon { color: #b91c1c; background: rgba(248,113,113,0.14); }
@keyframes flash-toast-in {
    0% { transform: translate(-50%, -120%); opacity: 0; }
    100% { transform: translate(-50%, 0%); opacity: 1; }
}
@keyframes flash-toast-out {
    0% { transform: translate(-50%, 0%); opacity: 1; }
    100% { transform: translate(-50%, -120%); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .flash-toast {
        animation: flash-toast-fade-out 0.2s ease 3.3s forwards;
        transform: translate(-50%, 0%);
    }
    @keyframes flash-toast-fade-out {
        to { opacity: 0; }
    }
}
/* Light theme — the toast surface uses the same tokens but its
   coloured tick still pops since --green is mapped per-theme. */
body.light .flash-toast {
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
}

/* DD-021 — Activity stream pane.
   Layout-side rules (`.app-layout` padding-right reservation,
   `.activity-collapsed` toggle, mobile reset) now live in `user.css`
   alongside the rest of the .app-layout flex setup, so the
   gutter-reserving logic isn't split across two files. */

/* Sidebar collapse — chevron in the top-left corner toggles the
   primary nav. Persisted to localStorage so the choice survives
   reloads. The streams page benefits most: collapse the main sidebar
   to give the streams nav + content more horizontal room. */
.sidebar-toggle {
    position: fixed;
    top: 8px;
    /* Default (sidebar open): sit INSIDE the sidebar at its top-right
       corner. Sidebar is 220px wide, button is 32px, leave 8px gutter:
       220 - 32 - 8 = 180px from the viewport-left.
       Collapsed state slides the button to the body so it's still
       reachable to re-open the sidebar. */
    left: 180px;
    z-index: 60;
    width: 28px; height: 28px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 1rem; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    transition: background 120ms ease, color 120ms ease, left 0.18s ease, border-color 120ms ease;
}
.sidebar-toggle:hover {
    background: var(--bg-hover, #1a2332);
    color: var(--text);
    border-color: var(--border-hover, #374151);
}
.app-layout.sidebar-collapsed .sidebar-toggle { left: 8px; }
.sidebar-toggle-icon { font-weight: 700; }

.sidebar { transition: width 0.18s ease, padding 0.18s ease, opacity 0.12s ease; }
.app-layout.sidebar-collapsed .sidebar {
    width: 0 !important;
    padding-left: 0; padding-right: 0;
    overflow: hidden;
    border-right-width: 0;
    opacity: 0;
    pointer-events: none;
}
/* Reserve room at the left edge of the main content for the
   floating sidebar-toggle (hamburger) button — otherwise the
   topbar's greeting / email runs underneath it. The button itself
   is `position: fixed; left: 8px; width: 28px`, so 50px of
   padding-left keeps the topbar text clear with a small gap. */
.app-layout.sidebar-collapsed .main-content {
    padding-left: 50px;
}

/* Activity-stream pane — a real flex sibling of the sidebar + main.
   Sticky-positioned so it stays pinned to the viewport top while the
   main content scrolls; flex-shrink: 0 protects its width when the
   main has a lot of content; the collapsed state shrinks width to 0
   so the layout reclaims the space and the main-content reflows. */
.activity-stream {
    position: sticky; top: 0;
    align-self: flex-start;
    flex: 0 0 var(--activity-stream-width, 320px);
    width: var(--activity-stream-width, 320px);
    height: 100vh;
    /* On wide viewports the .main-content caps at 1100px (its
       reading-line max-width), which leaves slack between main and
       this pane. `margin-left: auto` consumes that slack so the pane
       stays flush against the right edge. */
    margin-left: auto;
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    display: flex; flex-direction: column;
    z-index: 50;
    overflow: hidden;
    transition: flex-basis 0.18s ease, width 0.18s ease,
                border-left-width 0.18s ease;
}
.app-layout.activity-collapsed .activity-stream {
    flex-basis: 0;
    width: 0;
    border-left-width: 0;
}

.activity-stream-header {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.55rem 0.7rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-hover);
}
.activity-stream-title {
    flex: 1;
    font-size: 0.78rem; font-weight: 600;
    color: var(--text);
    text-transform: uppercase; letter-spacing: 0.06em;
}
.activity-stream-status {
    font-size: 0.7rem; color: #6ee7b7;
    width: 8px; height: 8px; border-radius: 50%;
    background: #475569;
}
.activity-stream-status.connected { background: #10b981; }
.activity-stream-status.error     { background: #ef4444; }
.activity-stream-toggle {
    background: none; border: none; cursor: pointer;
    color: var(--text-muted);
    font-size: 1.05rem; line-height: 1; padding: 0.1rem 0.3rem;
}
.activity-stream-toggle:hover { color: var(--text); }

.activity-stream-body {
    flex: 1; overflow-y: auto; overflow-x: hidden;
    padding: 0.4rem 0;
}
.activity-stream-empty {
    padding: 1rem 0.8rem;
    color: var(--text-muted); font-size: 0.78rem;
    font-style: italic; text-align: center;
}
.activity-stream-hint {
    margin-top: 0.4rem; font-style: normal;
    color: var(--text-dim); font-size: 0.7rem;
}

/* DD-021 v2 — sectioned roll-up rendering. Each section is a <details>
   so expand/collapse is native + accessible. Header carries title +
   unseen counter; body holds the per-event rows when expanded. */
.activity-section { border-bottom: 1px solid var(--border); }
.activity-section:last-child { border-bottom: none; }
.activity-section-header {
    list-style: none;
    cursor: pointer;
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.45rem 0.7rem;
    background: var(--bg-hover);
    user-select: none;
}
.activity-section-header::-webkit-details-marker { display: none; }
.activity-section-header::before {
    content: "›";
    color: var(--text-dim);
    font-size: 0.9rem; line-height: 1;
    transition: transform 0.12s ease;
    transform: rotate(0deg);
}
.activity-section[open] > .activity-section-header::before {
    transform: rotate(90deg);
}
.activity-section-title {
    flex: 1;
    font-size: 0.7rem; font-weight: 700;
    color: var(--text);
    text-transform: uppercase; letter-spacing: 0.06em;
}
.activity-section-count {
    font-size: 0.68rem;
    color: var(--text-dim);
    font-family: monospace;
}
.activity-section-count.has-unseen {
    color: var(--accent);
    font-weight: 600;
}
.activity-section-body {
    /* The <details> body wraps to fit its rows; per-row borders come
       from .activity-row's existing border-bottom rule. */
}
/* ARTICLES is the highest-cadence section — on a busy stack it can
   accumulate dozens of new rows in minutes, which would otherwise
   push everything else off-viewport. Cap the visible rows to ~5 with
   an inner scroll bar; the buffer still holds 50 so older rows are
   reachable by scrolling. Other sections keep natural height because
   they're lower-cadence and their rows tend to be more contextual. */
.activity-section[data-section="articles"] > .activity-section-body {
    max-height: 32rem;
    overflow-y: auto;
}
.activity-section-empty {
    padding: 0.5rem 0.7rem;
    font-size: 0.72rem; color: var(--text-dim);
    font-style: italic;
}

.activity-row {
    display: block;
    padding: 0.4rem 0.7rem;
    border-left: 3px solid transparent;
    text-decoration: none; color: var(--text);
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    transition: background 0.1s, border-left-color 0.1s;
}
.activity-row:hover { background: var(--bg-hover); }
.activity-row.collected { border-left-color: var(--accent-hover); }
/* Newly arrived row — short background flash AND a 7-second pulsing
   border so the user can spot WHAT just landed even if they were
   reading lower in the rail. The .fresh class is removed by JS after
   the animation budget so static rows don't keep pulsing. */
.activity-row.fresh {
    animation:
        activity-flash 0.6s ease,
        activity-pulse 1.4s ease-in-out 0s 5;
}
@keyframes activity-flash {
    0%   { background: rgba(59, 130, 246, 0.18); }
    100% { background: transparent; }
}
@keyframes activity-pulse {
    0%   { border-left-color: var(--accent-hover);
           box-shadow: inset 3px 0 0 rgba(59, 130, 246, 0.0); }
    50%  { border-left-color: #93c5fd;
           box-shadow: inset 3px 0 0 rgba(147, 197, 253, 0.55); }
    100% { border-left-color: var(--accent-hover);
           box-shadow: inset 3px 0 0 rgba(59, 130, 246, 0.0); }
}

.activity-row-source {
    font-size: 0.7rem; font-weight: 600;
    color: var(--accent, #60a5fa);
    text-transform: uppercase; letter-spacing: 0.04em;
}
.activity-row-title {
    font-size: 0.82rem; line-height: 1.3;
    margin-top: 0.15rem;
    overflow: hidden; text-overflow: ellipsis;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.activity-row-meta {
    font-size: 0.68rem; color: var(--text-dim);
    margin-top: 0.25rem;
}

.activity-stream-strip {
    position: fixed; right: 0; top: 50%;
    transform: translateY(-50%);
    width: 38px; min-height: 130px;
    background: var(--accent, #3b82f6);
    border: none; border-right: none;
    border-radius: 8px 0 0 8px;
    cursor: pointer;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 0.5rem; padding: 0.6rem 0;
    color: white;
    box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.25);
    z-index: 50;
    transition: width 0.12s, background 0.12s;
}
.activity-stream-strip:hover {
    width: 44px;
    background: #2563eb;
}
.activity-stream-strip-icon { font-size: 1.1rem; }
.activity-stream-strip-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 0.65rem; font-weight: 700; letter-spacing: 0.15em;
    color: white;
}
.activity-stream-strip-badge {
    background: white; color: #ef4444;
    font-size: 0.6rem; font-weight: 700;
    border-radius: 999px; padding: 0.05rem 0.35rem;
    min-width: 14px; text-align: center;
    display: none;
    border: 1px solid white;
}
.activity-stream-strip-badge.visible { display: inline-block; }

@media (max-width: 768px) {
    /* `.app-layout` padding reset on mobile lives in user.css */
    .activity-stream, .activity-stream-strip { display: none !important; }
}

/* DD-029 § Hide-vs-show — "More — Complete Onboarding" affordance.
   Native <details> for accessible expand/collapse. The locked-row
   names + per-row "complete X to unlock" hints come from Jinja, so
   no JS state to maintain. */
.sidebar-locked-groups {
    margin: 0.4rem 0;
    border-top: 1px dashed var(--border);
    padding-top: 0.5rem;
}
.sidebar-locked-summary {
    list-style: none;
    cursor: pointer;
    padding: 0.4rem 1.2rem;
    color: var(--text-dim);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    display: flex; align-items: center; gap: 0.4rem;
    user-select: none;
    transition: color 0.12s;
}
.sidebar-locked-summary::-webkit-details-marker { display: none; }
.sidebar-locked-summary:hover { color: var(--text-muted); }
.sidebar-locked-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1rem; height: 1rem; border-radius: 50%;
    border: 1px solid currentColor;
    font-size: 0.6rem; font-weight: 700;
    transition: transform 0.12s ease;
}
.sidebar-locked-groups[open] > .sidebar-locked-summary > .sidebar-locked-icon {
    transform: rotate(45deg);
}
.sidebar-locked-body {
    padding: 0.2rem 1.2rem 0.6rem;
}
.sidebar-locked-row {
    padding: 0.25rem 0;
    font-size: 0.7rem;
    color: var(--text-dim);
}
.sidebar-locked-row-name {
    display: block;
    color: var(--text-muted);
    font-weight: 600;
    text-transform: capitalize;
}
.sidebar-locked-row-hint {
    display: block;
    color: var(--text-dim);
    font-size: 0.65rem;
    margin-top: 0.05rem;
}

/* DD-029 — sidebar onboarding indicator + drawer. */
.sidebar-onboarding-indicator {
    flex: 1 1 auto;
    margin-right: 0.4rem;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    border: 1px solid var(--amber, #f59e0b);
    background: rgba(245, 158, 11, 0.10);
    color: var(--amber, #f59e0b);
    font-size: 0.6rem; font-weight: 700;
    letter-spacing: 0.12em;
    cursor: pointer;
    text-transform: uppercase;
    animation: sidebar-onboarding-pulse 2.4s ease-in-out infinite;
    transition: background 0.12s, transform 0.12s;
}
.sidebar-onboarding-indicator:hover {
    background: rgba(245, 158, 11, 0.20);
}
.sidebar-onboarding-indicator:active {
    transform: translateY(1px);
}
@keyframes sidebar-onboarding-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.0); }
    50%      { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.18); }
}

{# z-index 1300 — above page-level widgets that go up to ~1000
   (source-collection picker dropdown, modals, etc.) but below the
   global flash toast at 1400, which is intentionally always on top.
   Without this the picker dropdown could overlay the drawer when
   open behind it. #}
.onboarding-drawer { position: fixed; inset: 0; z-index: 1300; display: none; }
.onboarding-drawer[aria-hidden="false"] { display: block; }
.onboarding-drawer-backdrop {
    position: absolute; inset: 0;
    background: rgba(0, 0, 0, 0.5);
}
.onboarding-drawer-panel {
    position: absolute;
    left: 240px;            /* clear of the sidebar */
    bottom: 1rem;
    width: 380px;
    max-width: calc(100vw - 280px);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
    display: flex; flex-direction: column;
    overflow: hidden;
}
.onboarding-drawer-header {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-hover);
}
.onboarding-drawer-stage-num {
    flex: 0 0 auto;
    width: 1.7rem; height: 1.7rem; border-radius: 50%;
    background: var(--amber, #f59e0b);
    color: #fff;
    font-size: 0.78rem; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
}
.onboarding-drawer-title {
    flex: 1; margin: 0;
    font-size: 0.92rem; color: var(--text);
}
.onboarding-drawer-close {
    background: none; border: none;
    color: var(--text-muted); cursor: pointer;
    font-size: 1.2rem; line-height: 1;
    padding: 0.1rem 0.4rem;
}
.onboarding-drawer-close:hover { color: var(--text); }
.onboarding-drawer-body {
    padding: 0.9rem; flex: 1;
    color: var(--text);
}
.onboarding-drawer-copy {
    margin: 0; font-size: 0.85rem; line-height: 1.5;
    color: var(--text-muted);
}
.onboarding-drawer-signals {
    margin: 0.6rem 0 0;
    padding: 0.45rem 0.7rem;
    font-size: 0.78rem;
    color: var(--accent);
    background: rgba(96, 165, 250, 0.08);
    border-radius: 4px;
    font-family: monospace;
}
.onboarding-drawer-actions {
    display: flex; flex-direction: column; gap: 0.4rem;
    padding: 0.6rem 0.9rem 0.9rem;
    border-top: 1px solid var(--border);
}
.onboarding-action-advance { width: 100%; }
.onboarding-action-row { display: flex; gap: 0.4rem; }
.onboarding-action-back, .onboarding-action-skip { flex: 1 1 0; }
.onboarding-action-dismiss {
    background: none; border: none;
    color: var(--text-dim);
    font-size: 0.7rem; cursor: pointer;
    text-align: center;
    padding: 0.2rem 0;
    text-decoration: underline;
}
.onboarding-action-dismiss:hover { color: var(--text-muted); }

/* DD-029 — guided-tour spotlight. Briefly outlines an element after
   the drawer advances the user to a new page, so they see where to
   click next without the drawer staying in the way. Three pulses
   at ~1.6s = ~5s total animation budget; JS removes the class at
   5.4s so the static look settles in. */
.onboarding-spotlight {
    position: relative;
    z-index: 5;
    animation: onboarding-spotlight-pulse 1.6s ease-in-out 3;
    border-radius: 6px;
}
@keyframes onboarding-spotlight-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
    50%      { box-shadow: 0 0 0 6px rgba(245, 158, 11, 0.55); }
}
body.light .onboarding-spotlight {
    animation-name: onboarding-spotlight-pulse-light;
}
@keyframes onboarding-spotlight-pulse-light {
    0%, 100% { box-shadow: 0 0 0 0 rgba(180, 83, 9, 0); }
    50%      { box-shadow: 0 0 0 6px rgba(180, 83, 9, 0.65); }
}
@media (prefers-reduced-motion: reduce) {
    .onboarding-spotlight { animation: none; }
}

/* ── from user/direct.html ─────────────────────────────────────── */
/* The global .btn is intentionally small for inline list actions
   (0.3rem padding, 0.8rem font). The Direction page CTAs and modal
   actions need more weight without breaking the rest of the
   .btn ecosystem — scope the bump to where it belongs. */
.page-header .btn,
.dir-form-actions .btn,
.dir-preview-header .btn {
  padding: 0.55rem 1.2rem;
  font-size: 0.9rem;
  font-weight: 500;
  border-radius: 6px;
}
.dir-form-actions .btn-primary,
.page-header .btn-primary,
.dir-preview-header .btn-primary {
  /* Primary buttons inherit colors from the global .btn-primary;
     the size bump above gives them the proper weight. */
}

.dir-lede { color: var(--text-muted); max-width: 720px; margin: 0.5rem 0 1.5rem; }
.dir-list { display: flex; flex-direction: column; gap: 0.5rem; }
.dir-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color 0.15s;
}
.dir-card:hover { border-color: var(--border-hover); }
.dir-card summary {
  padding: 0.75rem 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--text);
}
.dir-card-title { flex: 1; font-weight: 500; }
.dir-card-aud { color: var(--text-muted); font-size: 0.85rem; }
.dir-pill { padding: 2px 8px; border-radius: 999px; font-size: 0.75rem; font-weight: 500; }
.dir-pill-thin { background: rgba(251, 191, 36, 0.15); color: #fbbf24; border: 1px solid rgba(251, 191, 36, 0.3); }
.dir-card-body {
  padding: 0.5rem 1rem 1rem;
  border-top: 1px solid var(--border);
  color: var(--text);
}
.dir-row { margin: 0.4rem 0; }
.dir-row strong { color: var(--text); font-weight: 600; }
.dir-meta { color: var(--text-dim); font-size: 0.75rem; font-family: monospace; }

.dir-tag {
  display: inline-block;
  padding: 2px 8px;
  margin: 2px;
  background: rgba(96, 165, 250, 0.12);
  color: var(--accent);
  border: 1px solid rgba(96, 165, 250, 0.25);
  border-radius: 4px;
  font-size: 0.8rem;
}
.dir-tag-topical {
  background: rgba(168, 85, 247, 0.12);
  color: #c084fc;
  border-color: rgba(168, 85, 247, 0.25);
}

.dir-overlay {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 4rem; z-index: 100;
}
.dir-form-card, .dir-preview-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2rem;
  width: 90%;
  max-width: 720px;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  color: var(--text);
}
.dir-preview-card { max-width: 900px; }
.dir-form-card h2, .dir-preview-card h2 { color: var(--text); margin-top: 0; }
.dir-form-card label { display: block; margin: 1rem 0; }
.dir-form-card label span {
  display: block; font-weight: 600;
  margin-bottom: 0.25rem;
  color: var(--text);
}
.dir-form-card input, .dir-form-card textarea {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-hover);
  background: var(--bg);
  color: var(--text);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
}
.dir-form-card input:focus, .dir-form-card textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.dir-form-card input::placeholder, .dir-form-card textarea::placeholder {
  color: var(--text-dim);
}
.dir-form-card textarea { resize: vertical; }
.dir-form-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1.5rem; }

.dir-status {
  margin-top: 1rem; padding: 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.dir-status.error {
  background: rgba(239, 68, 68, 0.1);
  color: var(--red);
  border-color: rgba(239, 68, 68, 0.3);
}
.dir-status.busy {
  background: rgba(96, 165, 250, 0.1);
  color: var(--accent);
  border-color: rgba(96, 165, 250, 0.3);
}

.dir-preview-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}
.dir-preview-note {
  padding: 0.75rem;
  background: rgba(251, 191, 36, 0.1);
  color: #fbbf24;
  border: 1px solid rgba(251, 191, 36, 0.3);
  border-radius: 6px;
  margin-bottom: 1rem;
}
.dir-preview-section { margin: 1.5rem 0; }
.dir-preview-section h3 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  color: var(--text);
  font-weight: 600;
}
.dir-preview-row {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}
.dir-preview-row:last-child { border-bottom: none; }
.dir-preview-row a {
  color: var(--accent);
  text-decoration: none;
}
.dir-preview-row a:hover { text-decoration: underline; }
.dir-preview-meta { color: var(--text-muted); font-size: 0.8rem; }
.dir-empty { color: var(--text-dim); font-style: italic; }

/* Inline code chip in the matcher meta line */
.dir-row code {
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.75rem;
  color: var(--text);
}

/* Editable tag chips: × removes the tag from the matcher; the row
   ends with a small "+ add" input for analyst-curated additions. */
.dir-tag-edit-row {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
}
.dir-tag-list { display: flex; flex-wrap: wrap; gap: 4px; }
.dir-tag .dir-tag-x {
    background: transparent; border: none; cursor: pointer;
    color: inherit; opacity: 0.5;
    margin-left: 0.35rem; padding: 0;
    font-size: 0.95rem; line-height: 1;
    vertical-align: baseline;
}
.dir-tag .dir-tag-x:hover { opacity: 1; color: var(--red); }
.dir-tag-add-input {
    background: var(--bg);
    color: var(--text);
    border: 1px dashed var(--border-hover);
    border-radius: 4px;
    padding: 1px 8px;
    font-size: 0.8rem;
    width: 8rem;
    transition: border-color 0.15s;
}
.dir-tag-add-input:focus {
    outline: none;
    border-color: var(--accent);
    border-style: solid;
}
.dir-tag-add-input::placeholder { color: var(--text-dim); }
.dir-tag-saving { opacity: 0.5; pointer-events: none; }

/* Per-card actions row + in-card live panels */
.dir-card-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
.dir-card-live { margin-top: 1rem; padding-top: 1rem; border-top: 1px dashed var(--border); }
.dir-card-live-status { color: var(--text-muted); font-size: 0.85rem; font-style: italic; }
.dir-card-live h4 {
  margin: 1rem 0 0.4rem;
  font-size: 0.9rem;
  color: var(--text);
  font-weight: 600;
}

/* ── Article cards (reuse from report-wizard curate page) ─────── */
.candidates-list { display:flex; flex-direction:column; gap:0.4rem; }
.candidate { border:1px solid var(--border); border-radius:6px; background:rgba(255,255,255,0.02); }
.candidate[open] { border-color:rgba(96,165,250,0.4); }
.candidate-summary {
    list-style: none; cursor: pointer;
    display:flex; align-items:center; gap:0.6rem;
    padding:0.55rem 0.8rem; font-size:0.82rem;
}
.candidate-summary::-webkit-details-marker { display: none; }
.candidate-title { flex: 1; color: var(--text); font-weight: 500; }
.candidate-score {
    flex: 0 0 auto; font-size:0.7rem; padding:0.1rem 0.45rem;
    border-radius:8px; font-family:monospace;
    background:rgba(34,197,94,0.14); color:#86efac; border:1px solid rgba(34,197,94,0.35);
}
.candidate-date { flex: 0 0 auto; font-size:0.72rem; color:var(--text-dim); font-family:monospace; }
.candidate-detail { padding:0.5rem 1rem 0.7rem; border-top:1px solid var(--border); }
.candidate-section { margin-bottom:0.5rem; }
.candidate-section-label { color:var(--text-dim); font-size:0.68rem; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:0.2rem; }
.candidate-section-body { color:var(--text-muted); font-size:0.8rem; line-height:1.5; }
.candidate-meta-grid { display:grid; grid-template-columns: 7rem 1fr; gap:0.35rem 0.6rem; font-size:0.78rem; margin:0; align-items:start; }
.candidate-meta-grid dt { color:var(--text-dim); margin:0; padding-top:0.15rem; }
.candidate-meta-grid dd { color:var(--text-muted); margin:0; word-break:break-word; min-width:0; }
.candidate-url-link { color:var(--accent); text-decoration:none; word-break:break-all; }
.candidate-url-link:hover { text-decoration:underline; }
.chip-row { display:flex; flex-wrap:wrap; gap:0.3rem; }
.chip {
    display:inline-block; padding:0.1rem 0.5rem; border-radius:10px;
    font-size:0.72rem; line-height:1.3; border:1px solid transparent;
}
.chip-tag      { background:rgba(96,165,250,0.12);  color:#93c5fd; border-color:rgba(96,165,250,0.30); }
.chip-topical  { background:rgba(168,85,247,0.12);  color:#c084fc; border-color:rgba(168,85,247,0.25); }
/* Gap-finder signals — green to visually mark "the customer's
   enricher tasks already cover this". Distinct from the blue
   baseline-tag chips so the analyst sees the source-of-truth axis. */
.chip-gap      { background:rgba(34,197,94,0.12);   color:#86efac; border-color:rgba(34,197,94,0.30); font-family:monospace; font-size:0.68rem; }
.candidate-actions { margin-top:0.7rem; display:flex; gap:0.4rem; }
.btn-detail { background:rgba(96,165,250,0.10); color:#93c5fd; border-color:rgba(96,165,250,0.35); }
.btn-detail:hover { background:rgba(96,165,250,0.18); }

/* Pagination control */
.dir-pager {
    display:flex; gap:0.4rem; align-items:center;
    margin: 0.6rem 0 0.4rem; font-size:0.78rem;
}
.dir-pager .pager-info { color:var(--text-muted); margin-right:auto; }

/* ── Gap suggestions table — shape mirrors the sources table ──── */
.gap-table {
    display: grid;
    grid-template-columns:
        minmax(8rem, 1fr)    /* task name */
        minmax(10rem, 2fr)   /* field path */
        minmax(8rem, 2fr)    /* matched value */
        minmax(3.5rem, auto) /* coverage count */
        minmax(4rem, auto)   /* layer */
        minmax(8rem, 2fr);   /* signals that hit */
    gap: 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
}
.gap-table > div {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border);
    align-self: center;
}
.gap-table > div:nth-last-child(-n+6) {
    border-bottom: none;
}
.gap-table .gap-head {
    background: rgba(255,255,255,0.04);
    color: var(--text-dim);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    padding: 0.4rem 0.75rem;
}
.gap-table .gap-task    { color: var(--text); font-weight: 500; }
.gap-table .gap-path    { color: var(--text-muted); font-family: monospace; font-size: 0.75rem; }
.gap-table .gap-value   { color: #86efac; font-family: monospace; font-size: 0.78rem; }
.gap-table .gap-count   { color: var(--text); font-family: monospace; text-align: right; font-weight: 600; }
.gap-table .gap-layer   { color: var(--text-dim); font-family: monospace; font-size: 0.72rem; text-transform: uppercase; }

.dir-section-hint {
    color: var(--text-muted);
    font-size: 0.78rem;
    margin: 0.3rem 0 0.6rem;
    line-height: 1.5;
}

/* ── Suggested-sources table ──────────────────────────────────────
   Five-column grid so name/country/cadence/overlap/topics all align
   across rows. Columns picked for the v1 source-coverage shape; if
   we add more (last-published, cost, etc.) they get their own col. */
.sources-table {
    display: grid;
    grid-template-columns:
        minmax(12rem, 2fr)   /* name */
        minmax(4rem, auto)   /* country */
        minmax(5rem, auto)   /* cadence */
        minmax(3.5rem, auto) /* overlap count */
        minmax(8rem, 3fr);   /* matched topical */
    gap: 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
}
.sources-table > div {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border);
    align-self: center;
}
/* Drop the bottom border on the last row's cells (5 columns). */
.sources-table > div:nth-last-child(-n+5) {
    border-bottom: none;
}
.sources-table .src-head {
    background: rgba(255,255,255,0.04);
    color: var(--text-dim);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    padding: 0.4rem 0.75rem;
}
.sources-table .src-name a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
}
.sources-table .src-name a:hover { text-decoration: underline; }
.sources-table .src-country,
.sources-table .src-cadence {
    color: var(--text-muted);
    font-family: monospace;
    font-size: 0.75rem;
}
.sources-table .src-overlap {
    color: var(--text);
    font-family: monospace;
    text-align: right;
    font-weight: 600;
}
.sources-table .src-topical { line-height: 1.6; }

/* Hide a row's worth of cells together when paginated out. We tag
   each cell with data-page="N" and toggle via display:none. */
.sources-table > div[data-paged-out="1"] { display: none; }

/* ── Article-detail modal (reuse from report-wizard curate page) ── */
.article-modal { position:fixed; inset:0; z-index:1000; display:none; }
.article-modal[aria-hidden="false"] { display:block; }
.article-modal-backdrop {
    position:absolute; inset:0; background:rgba(0,0,0,0.65);
    backdrop-filter:blur(2px);
}
.article-modal-panel {
    position:relative; margin:3vh auto; max-width:1080px; width:92vw;
    max-height:94vh; display:flex; flex-direction:column;
    background:#0f172a; border:1px solid var(--border); border-radius:8px;
    box-shadow:0 30px 80px rgba(0,0,0,0.55);
}
.article-modal-header {
    display:flex; align-items:flex-start; gap:0.6rem;
    padding:0.8rem 1rem; border-bottom:1px solid var(--border);
}
.article-modal-header h2 { margin:0; font-size:0.95rem; color:var(--text); flex:1; line-height:1.3; }
.article-modal-body { padding:0.9rem 1.1rem; overflow:auto; font-size:0.83rem; color:var(--text-muted); line-height:1.5; }
.article-modal-body h3 { color:var(--text); font-size:0.85rem; margin:1rem 0 0.4rem; text-transform:uppercase; letter-spacing:0.04em; }
.article-modal-body h3:first-child { margin-top:0; }
.article-modal-body .meta-grid { display:grid; grid-template-columns:9rem 1fr; gap:0.3rem 0.7rem; font-size:0.8rem; }
.article-modal-body .meta-grid dt { color:var(--text-dim); }
.article-modal-body .meta-grid dd { margin:0; word-break:break-word; }
.article-modal-body .exec-summary {
    background:rgba(255,255,255,0.03); border-left:3px solid rgba(96,165,250,0.5);
    padding:0.6rem 0.8rem; border-radius:0 4px 4px 0; margin-top:0.4rem;
}
.article-modal-body .task-card {
    border:1px solid var(--border); border-radius:6px;
    margin-bottom:0.5rem; background:rgba(255,255,255,0.02);
}
.article-modal-body .task-card > summary {
    list-style:none; cursor:pointer; padding:0.5rem 0.8rem;
    display:flex; gap:0.6rem; align-items:center;
    font-size:0.78rem; color:var(--text-muted);
}
.article-modal-body .task-card > summary::-webkit-details-marker { display:none; }
.article-modal-body .task-name { color:var(--text); font-weight:600; flex:1; }
.article-modal-body .task-model { font-family:monospace; font-size:0.7rem; color:var(--text-dim); background:rgba(255,255,255,0.04); padding:0.05rem 0.35rem; border-radius:3px; }
.article-modal-body .task-result { padding:0.5rem 0.8rem; border-top:1px solid var(--border); background:rgba(0,0,0,0.2); }
.article-modal-body .task-result pre { margin:0; white-space:pre-wrap; word-break:break-word; font-size:0.74rem; color:#cbd5e1; font-family:monospace; line-height:1.45; max-height:42rem; overflow:auto; }
.article-modal-body .modal-error { color:#fca5a5; background:rgba(220,38,38,0.08); border:1px solid rgba(220,38,38,0.25); padding:0.6rem 0.8rem; border-radius:4px; }

/* Multi-stage loader on the create form */
.dir-loader {
  margin-top: 1.5rem;
  padding: 1.25rem;
  background: rgba(96, 165, 250, 0.06);
  border: 1px solid rgba(96, 165, 250, 0.2);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.dir-loader-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(96, 165, 250, 0.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: dir-spin 0.9s linear infinite;
}
@keyframes dir-spin { to { transform: rotate(360deg); } }
.dir-loader-stages {
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
}
.dir-loader-stages li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0;
  color: var(--text-dim);
  font-size: 0.9rem;
  transition: color 0.3s;
}
.dir-loader-stages li.active {
  color: var(--accent);
  font-weight: 500;
}
.dir-loader-stages li.done {
  color: var(--text-muted);
}
.dir-loader-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--text-dim);
  flex-shrink: 0;
  transition: background 0.3s;
}
.dir-loader-stages li.active .dir-loader-dot {
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.2);
}
.dir-loader-stages li.done .dir-loader-dot {
  background: #10b981;  /* emerald — completion */
}
.dir-loader-hint {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin: 0;
  text-align: center;
  max-width: 480px;
}

/* ── from user/home.html ───────────────────────────────────────── */
.home-page-header { margin-bottom: 1rem; }
.home-greeting { font-size: 1.4rem; font-weight: 500; margin: 0; }
.home-greeting-suffix {
    color: var(--text-muted); font-weight: 400;
    margin-left: 0.4rem;
}

/* Hero wrap centres the onboarding card vertically on the viewport.
   Previously depended on `main-content--full`'s 100vh flex column;
   now self-sizes so the rest of Home doesn't need that wrapper. */
.home-onboarding-hero-wrap {
    min-height: 70vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}

/* ───── "What's happening" card grid ─────────────────────────────
   Auto-fit packing: cards size to the available width with a 320px
   minimum, equal columns, no gaps when one card is missing (e.g.
   the WP card is hidden for members — the layout reflows to two
   columns instead of leaving a hole). Stacks vertically below
   ~640px (a single 320px column + gutter). */
.home-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1rem;
    margin-top: 0.5rem;
    align-items: start;
}

.home-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.9rem 1rem 0.6rem;
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.home-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.4rem;
}
.home-card__title {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text);
}
.home-card__more {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-decoration: none;
}
.home-card__more:hover { color: var(--accent); }
.home-card__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.home-card__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.45rem 0;
    border-bottom: 1px solid var(--border);
    min-width: 0;
}
.home-card__row:last-child { border-bottom: none; }
.home-card__row-title {
    color: var(--text);
    font-size: 0.86rem;
    font-weight: 500;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}
.home-card__row-title:hover { color: var(--accent); }
.home-card__row-meta {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    flex-shrink: 0;
    font-size: 0.72rem;
}
.home-card__row-meta .muted { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.home-card__empty {
    color: var(--text-muted);
    font-size: 0.82rem;
    padding: 1rem 0.2rem;
}
.home-card__new-badge {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 0.05rem 0.35rem;
    border-radius: 4px;
    background: var(--accent);
    color: var(--bg);
    text-transform: uppercase;
}

/* Insight cards — share the home-card chrome but add a lede line
   under the title to explain the window/threshold the card was
   computed against (e.g. "Volume change last 7d vs prior 7d"). */
.home-card__lede {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin: -0.2rem 0 0.5rem;
    line-height: 1.4;
}

.insight-pill {
    display: inline-flex;
    align-items: center;
    height: 18px;
    padding: 0 0.45rem;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
}
.insight-pill--up   { background: rgba(16, 185, 129, 0.18); color: var(--green); }
.insight-pill--down { background: rgba(239, 68, 68, 0.18);  color: var(--red); }
.insight-pill--flat { background: rgba(148, 163, 184, 0.18); color: var(--text-muted); }
.insight-pill--new  { background: rgba(96, 165, 250, 0.18); color: #93c5fd; text-transform: uppercase; }
body.light .insight-pill--up   { background: #ecfdf5; color: #047857; }
body.light .insight-pill--down { background: #fef2f2; color: #b91c1c; }
body.light .insight-pill--flat { background: #f1f5f9; color: #475569; }
body.light .insight-pill--new  { background: #eff6ff; color: #1e40af; }
/* `@property` lets us animate the conic-gradient's `from` angle as
   a real CSS property (Chrome/Safari current; Firefox 128+). The
   sparkle "orbits" the card by rotating the gradient, not the
   pseudo-element — a transform-rotate on a non-square pseudo would
   clip awkwardly. */
@property --hero-sparkle-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

.home-onboarding-hero {
    position: relative;
    width: 100%;
    max-width: 640px;
    padding: 2.6rem 2.8rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-card);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    text-align: center;
    isolation: isolate;
}
/* Sparkle ring — a thin amber arc traveling around the card's
   perimeter. Two-mask trick clips the conic-gradient to the
   padding ring only, so it never bleeds onto card content. */
.home-onboarding-hero::before {
    content: '';
    position: absolute;
    inset: -1px;
    padding: 2px;
    border-radius: 13px;
    background: conic-gradient(
        from var(--hero-sparkle-angle),
        transparent 0deg,
        transparent 270deg,
        rgba(245, 158, 11, 0.0) 285deg,
        rgba(245, 158, 11, 0.85) 330deg,
        rgba(245, 158, 11, 0.0) 355deg,
        transparent 360deg
    );
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: home-onboarding-sparkle 4.5s linear infinite;
    pointer-events: none;
    z-index: -1;
}
/* Soft amber glow that pulses with the sparkle's pass — keeps the
   card feeling "alive" between the sparkle's visible arcs. */
.home-onboarding-hero::after {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: 14px;
    box-shadow: 0 0 24px 2px rgba(245, 158, 11, 0.0);
    animation: home-onboarding-glow 4.5s ease-in-out infinite;
    pointer-events: none;
    z-index: -2;
}
@keyframes home-onboarding-sparkle {
    to { --hero-sparkle-angle: 360deg; }
}
@keyframes home-onboarding-glow {
    0%, 60%, 100% { box-shadow: 0 0 12px 1px rgba(245, 158, 11, 0.0); }
    20%           { box-shadow: 0 0 28px 2px rgba(245, 158, 11, 0.20); }
}
@media (prefers-reduced-motion: reduce) {
    .home-onboarding-hero::before,
    .home-onboarding-hero::after {
        animation: none;
    }
}

/* Light-theme overrides — the dark-theme amber #f59e0b at 0.85 alpha
   is bright on a near-black background but too washed-out on a
   white surface. Swap to the theme's deeper amber (#b45309) and
   bump alphas; same shape, more contrast. */
body.light .home-onboarding-hero::before {
    background: conic-gradient(
        from var(--hero-sparkle-angle),
        transparent 0deg,
        transparent 270deg,
        rgba(180, 83, 9, 0.0) 285deg,
        rgba(180, 83, 9, 1.0) 330deg,
        rgba(180, 83, 9, 0.0) 355deg,
        transparent 360deg
    );
}
body.light .home-onboarding-hero {
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.10);
}
@keyframes home-onboarding-glow-light {
    0%, 60%, 100% { box-shadow: 0 0 12px 1px rgba(180, 83, 9, 0.0); }
    20%           { box-shadow: 0 0 28px 3px rgba(180, 83, 9, 0.32); }
}
body.light .home-onboarding-hero::after {
    animation-name: home-onboarding-glow-light;
}
.home-onboarding-hero h1 {
    font-size: 2.2rem;
    line-height: 1.15;
    margin: 0 0 0.9rem;
    color: var(--text);
    letter-spacing: -0.01em;
}
.home-onboarding-tagline {
    margin: 0 auto 1.6rem;
    color: var(--text-muted);
    font-size: 1.05rem; line-height: 1.55;
    max-width: 52ch;
}
.btn-large { padding: 0.7rem 1.6rem; font-size: 1rem; }
.home-onboarding-cta { font-weight: 600; }

/* ── from user/login.html ──────────────────────────────────────── */
      /* Light-theme cleanup for the passkey button — its hard-coded
         #334155 hover landed as a dark slate on a light surface,
         which read like a borrowed widget. The accent border + bg
         gradient matches the rest of the app's light treatments. */
      body.light .btn-passkey { background: var(--bg-hover); color: var(--text); }
      body.light .btn-passkey:hover { background: var(--surface-alt); border-color: var(--accent); }
    

/* ── from user/organization.html ───────────────────────────────── */
.org-overview { display: flex; flex-direction: column; gap: 1.6rem; }
.org-overview__header { padding-bottom: 0.4rem; border-bottom: 1px solid var(--border); }
.org-overview__name { font-size: 1.6rem; margin: 0 0 0.2rem; }
.org-overview__desc { color: var(--text-muted); margin: 0 0 0.5rem; line-height: 1.5; max-width: 70ch; }
.org-overview__meta { color: var(--text-muted); font-size: 0.78rem; display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.org-overview__meta-sep { opacity: 0.5; }
.org-overview__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1rem;
}
.org-overview__card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.1rem 1.2rem;
}
.org-overview__section-title {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    margin: 0 0 0.7rem;
}
.org-overview__sub-section-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    opacity: 0.75;
    margin: 0.8rem 0 0.4rem;
    font-weight: 600;
}
.org-overview__sub-section-title:first-of-type { margin-top: 0; }
.org-overview__hint { font-size: 0.8rem; color: var(--text-muted); margin: 0 0 0.7rem; line-height: 1.4; }
.org-overview__empty { color: var(--text-muted); font-size: 0.85rem; font-style: italic; margin: 0; }
.org-overview__members,
.org-overview__packages {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.org-overview__member,
.org-overview__package {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.4rem 0;
    border-bottom: 1px dashed var(--border);
}
.org-overview__member:last-child,
.org-overview__package:last-child { border-bottom: 0; }
.org-overview__member-name { font-weight: 500; }
.org-overview__member-email { color: var(--text-muted); font-size: 0.78rem; }
.org-overview__member-role {
    margin-left: auto;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}
.org-overview__package-name { font-weight: 500; }
.org-overview__package-desc {
    flex-basis: 100%;
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.4;
}
.org-overview__package--archived { opacity: 0.6; }
.org-overview__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.8rem;
    margin: 0;
}
.org-overview__stat { display: flex; flex-direction: column; gap: 0.15rem; }
.org-overview__stat dt {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.org-overview__stat dd { font-size: 1.4rem; font-weight: 600; margin: 0; color: var(--text); }
.org-overview__uncapped { font-size: 0.85rem; font-weight: 400; color: var(--text-muted); font-style: italic; }

/* ── from user/pipeline_builder.html ───────────────────────────── */
  /* ============================================================
     Pipeline Builder — self-contained vanilla JS PoV
     ============================================================ */

  /* Break the builder out of the standard 1100px / 2rem-padding
     content area so the canvas can use the whole viewport.
     Scoped to this page only via :has(). */
  /* The whole page content is wrapped in a `.view-mode-readonly` (or
     plain) div for the read-only banner overlay. Without this rule
     that wrapper would be a single flex item under `.main-content--full`
     and the .pb-shell flex:1 inside it wouldn't have a flex parent
     to flex against — collapsing the canvas to its 320px floor.
     `display: contents` makes the children behave as if they were
     direct children of `.main-content--full`, restoring the flex
     pipeline (header takes natural height, .pb-shell fills the rest). */
  body:has(.pb-shell) .main-content > div:not(.pb-shell):not(.page-header) {
      display: contents;
  }

  /* Page header trim — `.main-content--full` already handles the
     viewport-fit + flex-column part. The remaining tweaks shrink the
     header so the canvas claims more of the visible area. */
  body:has(.pb-shell) .page-header {
      margin-bottom: 0.6rem;
      flex: 0 0 auto;
  }
  body:has(.pb-shell) .page-header h1 {
      font-size: 1.1rem;
      margin: 0;
  }
  body:has(.pb-shell) .page-subtitle {
      font-size: 0.72rem;
      color: var(--text-muted);
      margin-top: 0.2rem;
  }

  .pb-shell {
      display: grid;
      grid-template-columns: 220px 1fr;
      gap: 0;
      flex: 1;            /* fill all remaining space below the header */
      min-height: 320px;  /* protective floor on tiny windows */
      margin-bottom: 1rem;
      border: 1px solid var(--border);
      border-radius: 8px;
      overflow: hidden;
      background: var(--bg-card);
  }

  .pb-palette {
      border-right: 1px solid var(--border);
      background: var(--bg-hover);
      padding: 1rem 0.8rem;
      display: flex;
      flex-direction: column;
      gap: 0.6rem;
  }
  .pb-palette h3 {
      margin: 0 0 0.4rem 0;
      font-size: 0.75rem;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      color: var(--text-muted);
  }
  .pb-chip {
      display: flex;
      align-items: center;
      gap: 0.6rem;
      padding: 0.6rem 0.8rem;
      background: var(--bg-card);
      border: 1px solid var(--border);
      border-radius: 6px;
      cursor: grab;
      user-select: none;
      font-size: 0.85rem;
      color: var(--text);
      transition: all 0.15s;
  }
  .pb-chip:hover {
      border-color: var(--accent);
      transform: translateX(2px);
  }
  .pb-chip:active { cursor: grabbing; }
  .pb-chip-dot {
      width: 10px; height: 10px; border-radius: 50%;
      flex-shrink: 0;
  }
  .pb-chip[data-type="task"]   .pb-chip-dot { background: var(--accent-hover); }
  .pb-chip[data-type="output"] .pb-chip-dot { background: var(--amber); }

  .pb-help {
      margin-top: auto;
      font-size: 0.72rem;
      color: var(--text-muted);
      line-height: 1.5;
  }
  .pb-help kbd {
      display: inline-block;
      padding: 0 0.3rem;
      background: var(--bg-card);
      border: 1px solid var(--border);
      border-radius: 3px;
      font-family: ui-monospace, monospace;
      font-size: 0.68rem;
  }

  /* ---- Canvas ---- */
  .pb-main {
      display: flex;
      flex-direction: column;
      min-width: 0;
  }
  .pb-toolbar {
      display: flex;
      gap: 0.5rem;
      align-items: center;
      padding: 0.55rem 0.8rem;
      border-bottom: 1px solid var(--border);
      background: var(--bg-hover);
      font-size: 0.8rem;
  }
  .pb-toolbar .pb-spacer { flex: 1; }
  .pb-toolbar button {
      padding: 0.35rem 0.7rem;
      background: var(--bg-card);
      border: 1px solid var(--border);
      border-radius: 4px;
      color: var(--text);
      cursor: pointer;
      font-size: 0.78rem;
  }
  .pb-toolbar button:hover { border-color: var(--accent); }
  .pb-toolbar .pb-status { color: var(--text-muted); font-size: 0.72rem; }

  .pb-canvas {
      flex: 1;
      position: relative;
      overflow: hidden;
      background-color: var(--bg-card);
      background-image: radial-gradient(circle, rgba(127,127,127,0.28) 1px, transparent 1px);
      background-size: 20px 20px;
      background-position: 0 0;
      cursor: default;
  }
  .pb-canvas.pb-panning { cursor: grabbing; }

  /* Floating metadata/status panel — pinned to the top-left corner
     of the canvas viewport (outside .pb-world so it doesn't pan or
     zoom with the graph). Holds the pipeline name, version, save
     status, and the Save Permanently button. */
  .pb-meta-panel {
      position: absolute;
      top: 0.8rem;
      left: 0.8rem;
      z-index: 5;
      background: rgba(10, 14, 23, 0.88);
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
      border: 1px solid var(--border-hover);
      border-radius: 8px;
      padding: 0.55rem 0.75rem;
      min-width: 240px;
      max-width: 320px;
      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
      font-size: 0.75rem;
      color: var(--text);
      user-select: none;
      /* Non-interactive by default so nodes underneath remain
         clickable. Only the name field re-enables pointer events
         for its inline rename. The actual Save action lives in the
         toolbar, not the panel, so there are no other interactive
         children to worry about. */
      pointer-events: none;
  }
  .pb-meta-panel .pb-meta-name,
  .pb-meta-panel .pb-meta-name-input {
      pointer-events: auto;
  }
  .pb-meta-name-row {
      display: flex;
      align-items: center;
      gap: 0.4rem;
      margin-bottom: 0.45rem;
  }
  .pb-meta-name {
      flex: 1;
      font-size: 0.95rem;
      font-weight: 600;
      color: var(--text);
      cursor: text;
      padding: 0.2rem 0.35rem;
      border-radius: 4px;
      border: 1px solid transparent;
      transition: background 120ms, border-color 120ms;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
  }
  .pb-meta-name:hover {
      background: rgba(255, 255, 255, 0.04);
      border-color: var(--border);
  }
  .pb-meta-name-input {
      flex: 1;
      font-size: 0.95rem !important;
      font-weight: 600 !important;
      padding: 0.2rem 0.35rem !important;
      background: var(--bg) !important;
      border: 1px solid var(--accent) !important;
      border-radius: 4px;
      color: var(--text);
      outline: none;
  }
  .pb-meta-version {
      font-size: 0.68rem;
      color: var(--text-muted);
      font-family: ui-monospace, monospace;
      white-space: nowrap;
  }
  .pb-meta-status-row {
      display: flex;
      align-items: center;
      gap: 0.4rem;
      margin-bottom: 0.55rem;
      flex-wrap: wrap;
  }
  .pb-meta-chip {
      display: inline-flex;
      align-items: center;
      gap: 0.3rem;
      padding: 0.2rem 0.5rem;
      border-radius: 12px;
      font-size: 0.64rem;
      font-weight: 600;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      white-space: nowrap;
  }
  .pb-meta-chip.synced {
      background: rgba(52, 211, 153, 0.14);
      border: 1px solid rgba(52, 211, 153, 0.5);
      color: var(--green);
  }
  .pb-meta-chip.draft {
      background: rgba(245, 158, 11, 0.14);
      border: 1px solid rgba(245, 158, 11, 0.5);
      color: var(--amber);
  }
  .pb-meta-chip.unsaved {
      background: rgba(239, 68, 68, 0.14);
      border: 1px solid rgba(239, 68, 68, 0.5);
      color: var(--red);
  }
  .pb-meta-timestamp {
      font-size: 0.66rem;
      color: var(--text-muted);
      flex: 1;
      text-align: right;
      white-space: nowrap;
  }
  .pb-meta-save-btn {
      width: 100%;
      padding: 0.45rem 0.6rem;
      background: var(--accent);
      color: #0a0e17;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-size: 0.78rem;
      font-weight: 600;
      transition: opacity 120ms;
  }
  .pb-meta-save-btn:disabled {
      opacity: 0.4;
      cursor: not-allowed;
  }

  /* Draft-restore toast — top-right corner of the canvas, slides in
     when a session draft is detected on boot. Dismissed manually or
     after the user picks Restore / Discard. */
  .pb-draft-toast {
      position: absolute;
      top: 0.8rem;
      right: 0.8rem;
      z-index: 6;
      background: rgba(10, 14, 23, 0.92);
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
      border: 1px solid rgba(245, 158, 11, 0.6);
      border-radius: 8px;
      padding: 0.7rem 0.9rem;
      max-width: 320px;
      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
      font-size: 0.76rem;
      color: var(--text);
      display: none;
  }
  .pb-draft-toast.pb-open { display: block; }
  .pb-draft-toast-title {
      font-weight: 700;
      color: var(--amber);
      margin-bottom: 0.3rem;
      font-size: 0.76rem;
      text-transform: uppercase;
      letter-spacing: 0.04em;
  }
  .pb-draft-toast-body {
      color: var(--text-muted);
      margin-bottom: 0.55rem;
      font-size: 0.74rem;
      line-height: 1.4;
  }
  .pb-draft-toast-actions {
      display: flex;
      gap: 0.4rem;
  }
  .pb-draft-toast-btn {
      flex: 1;
      padding: 0.35rem 0.5rem;
      background: var(--bg);
      border: 1px solid var(--border);
      color: var(--text);
      border-radius: 4px;
      cursor: pointer;
      font-size: 0.72rem;
      font-weight: 600;
  }
  .pb-draft-toast-btn.primary {
      background: var(--accent);
      color: #0a0e17;
      border-color: var(--accent);
  }
  .pb-draft-toast-btn:hover { opacity: 0.85; }

  .pb-world {
      position: absolute;
      top: 0; left: 0;
      width: 0; height: 0;
      transform-origin: 0 0;
      will-change: transform;
  }

  .pb-edges {
      position: absolute;
      top: -5000px;
      left: -5000px;
      width: 10000px;
      height: 10000px;
      pointer-events: none;
      overflow: visible;
  }
  .pb-edges path {
      fill: none;
      stroke: var(--text-muted);
      stroke-width: 2;
      pointer-events: visibleStroke;
      cursor: pointer;
  }
  .pb-edges path:hover { stroke: #ef4444; stroke-width: 3; }
  .pb-edges path.pb-edge-pending {
      stroke: var(--accent);
      stroke-dasharray: 6 4;
      pointer-events: none;
  }

  /* ---- Nodes ---- */
  .pb-node {
      position: absolute;
      width: 180px;
      background: var(--bg-card);
      border: 2px solid var(--border);
      border-radius: 8px;
      box-shadow: 0 2px 6px rgba(0,0,0,0.15);
      user-select: none;
      font-size: 0.82rem;
  }
  .pb-node.pb-selected {
      border-color: var(--accent);
      box-shadow: 0 0 0 3px rgba(59,130,246,0.25);
  }
  .pb-node-header {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.5rem 0.7rem;
      border-bottom: 1px solid var(--border);
      cursor: grab;
      font-weight: 600;
      font-size: 0.72rem;
      text-transform: uppercase;
      letter-spacing: 0.06em;
  }
  .pb-node-header:active { cursor: grabbing; }
  .pb-node.task     .pb-node-header { background: rgba(59,130,246,0.12); color: var(--accent-hover); }
  .pb-node.decision .pb-node-header { background: rgba(168,85,247,0.15); color: #c084fc; }
  .pb-node.output   .pb-node-header { background: rgba(245,158,11,0.12); color: var(--amber); }
  .pb-node.decision {
      border-color: rgba(168,85,247,0.45);
  }
  .pb-branch-row {
      display: flex;
      align-items: center;
      gap: 0.3rem;
      padding: 0.25rem 0.4rem;
      font-size: 0.7rem;
      border-radius: 4px;
      background: rgba(168,85,247,0.06);
      margin-bottom: 2px;
  }
  .pb-branch-row .pb-branch-kind {
      color: #c084fc;
      font-weight: 600;
      text-transform: uppercase;
      font-size: 0.58rem;
      letter-spacing: 0.05em;
  }
  .pb-branch-row .pb-branch-route {
      color: var(--text-muted);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
  }
  .pb-node-header .pb-node-title { flex: 1; }
  .pb-node-close {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 18px;
      height: 18px;
      padding: 0;
      margin: 0;
      background: transparent;
      border: 0;
      border-radius: 4px;
      color: inherit;
      opacity: 0.55;
      cursor: pointer;
      font-size: 14px;
      line-height: 1;
  }
  .pb-node-close:hover { opacity: 1; background: rgba(239,68,68,0.22); color: #ef4444; }

  /* Live execution indicators for test runs. `.pb-running` pulses
     the node border so the user can see which task the executor is
     working on right now; `.pb-done` / `.pb-failed` / `.pb-skipped`
     are terminal states applied on task.completed. */
  @keyframes pbPulseAmber {
      0%, 100% {
          border-color: var(--amber);
          box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.55);
      }
      50% {
          border-color: #fbbf24;
          box-shadow: 0 0 0 8px rgba(245, 158, 11, 0.08);
      }
  }
  .pb-node.pb-running {
      border-color: var(--amber) !important;
      animation: pbPulseAmber 1.1s ease-in-out infinite;
  }
  .pb-node.pb-done {
      border-color: var(--green) !important;
      box-shadow: 0 0 0 2px rgba(52, 211, 153, 0.25);
  }
  .pb-node.pb-failed {
      border-color: var(--red) !important;
      box-shadow: 0 0 0 2px rgba(248, 113, 113, 0.3);
  }
  .pb-node.pb-skipped {
      opacity: 0.55;
  }
  /* Conditional task: a dashed border signals to the author that
     execution is gated on a prior task's result. Takes precedence
     over the normal solid border but yields to the live run-state
     highlights above (which use !important). */
  .pb-node.pb-conditional {
      border-style: dashed;
      border-color: var(--amber);
  }

  .pb-node-body {
      padding: 0.6rem 0.7rem 0.7rem 0.7rem;
      display: flex;
      flex-direction: column;
      gap: 0.4rem;
  }
  .pb-node-body input {
      width: 100%;
      padding: 0.3rem 0.45rem;
      background: var(--bg-hover);
      border: 1px solid var(--border);
      border-radius: 4px;
      color: var(--text);
      font-size: 0.78rem;
      box-sizing: border-box;
  }
  .pb-node-body input:focus { outline: none; border-color: var(--accent); }
  .pb-node-body label {
      font-size: 0.66rem;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 0.05em;
  }

  /* ---- Ports ---- */
  .pb-port {
      position: absolute;
      width: 14px;
      height: 14px;
      background: var(--bg-card);
      border: 2px solid var(--text-muted);
      border-radius: 50%;
      cursor: crosshair;
      top: 50%;
      transform: translate(-50%, -50%);
      z-index: 2;
      transition: all 0.12s;
  }
  .pb-port:hover { background: var(--accent); border-color: var(--accent); transform: translate(-50%, -50%) scale(1.25); }
  .pb-port.in  { left: 0; }
  .pb-port.out { left: 100%; }
  .pb-port.active { background: var(--accent); border-color: var(--accent); }

  /* ============================================================
     Inspector — modal popup over the canvas
     ============================================================ */
  @keyframes pb-fade-in { from { opacity: 0; } to { opacity: 1; } }




  .pb-inspector-body input,
  .pb-inspector-body select,
  .pb-inspector-body textarea {
      width: 100%;
      padding: 0.5rem 0.65rem;
      background: var(--bg);
      border: 1px solid var(--border-hover);
      border-radius: 5px;
      color: var(--text);
      font-size: 0.85rem;
      box-sizing: border-box;
      font-family: inherit;
  }
  .pb-inspector-body textarea {
      font-family: ui-monospace, monospace;
      font-size: 0.78rem;
      min-height: 140px;
      resize: vertical;
      line-height: 1.5;
  }
  .pb-inspector-body input:focus,
  .pb-inspector-body select:focus,
  .pb-inspector-body textarea:focus {
      outline: none;
      border-color: var(--accent);
      background: var(--bg-card);
  }





  /* Themed selection list — replaces native <select> for source
     filter and output type. Each item is a row; the selected one
     gets an accent left-border and tinted background. */
  .pb-sel-list {
      display: flex;
      flex-direction: column;
      gap: 0;
      margin-top: 0.3rem;
      border: 1px solid var(--border);
      border-radius: 5px;
      overflow: hidden;
      max-height: 180px;
      overflow-y: auto;
  }
  .pb-sel-item {
      padding: 0.38rem 0.55rem;
      font-size: 0.72rem;
      color: var(--text-muted);
      cursor: pointer;
      border-left: 3px solid transparent;
      transition: all 0.1s;
      background: var(--bg);
      user-select: none;
  }
  .pb-sel-item:not(:last-child) {
      border-bottom: 1px solid var(--border);
  }
  .pb-sel-item:hover {
      color: var(--text);
      background: var(--bg-hover);
  }
  .pb-sel-item.pb-sel-active {
      color: var(--accent);
      background: rgba(96, 165, 250, 0.08);
      border-left-color: var(--accent);
      font-weight: 600;
  }

  /* Task node "Edit" affordance — small chevron in the body */
  .pb-task-edit {
      align-self: flex-end;
      background: transparent;
      border: 1px solid var(--border);
      color: var(--text-muted);
      cursor: pointer;
      border-radius: 4px;
      padding: 0.2rem 0.5rem;
      font-size: 0.68rem;
  }
  .pb-task-edit:hover { color: var(--accent); border-color: var(--accent); }

  /* Task inspector — sticky header with the task name, stepper,
     dirty indicator and Save button. The header takes the place of
     the old bottom-of-form Save button: it's always visible while
     scrolling through the Design form, the Save button reflects
     whether anything has changed since the inspector was opened, and
     the task name is editable right at the top instead of buried. */
  .pb-task-header {
      position: sticky;
      top: 0;
      /* High z-index so form controls below the header (datalist
         dropdowns, output template tree handles, etc.) can't render
         on top of the header when the body scrolls. Sticky elements
         share the stacking context of their nearest ancestor, so the
         value only needs to outrank other pb-inspector-body children,
         but we leave headroom for future overlays. */
      z-index: 50;
      /* Fully opaque background so scrolling content behind the
         header doesn't bleed through — var(--bg-card) already has
         an alpha of 1 but we set it explicitly for clarity. */
      background: var(--bg-card);
      /* Negate the inspector body's padding so the header spans
         edge-to-edge; re-add matching padding inside. The bottom
         margin is generous so the first control below the header
         (the Model task picker) can't visually touch the header's
         shadow when the user scrolls. */
      margin: -1.2rem -1.4rem 1.2rem -1.4rem;
      padding: 0.9rem 1.4rem 0.75rem 1.4rem;
      border-bottom: 1px solid var(--border);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
      /* New stacking context so nothing inside the header can be
         pulled above it by accident, and so we're not relying on the
         inspector-body's stacking. */
      isolation: isolate;
  }
  /* Test run button — sits next to Save in the action bar. Styled
     as a secondary action (outline) so the primary Save still
     carries the accent colour. Swaps text to "← Back to editor"
     when the inspector is in test mode. */

  /* Task inspector — sub-tab row (Prompt / Output Template / Gating).
     Sits just below the task picker (above the first tab's content)
     and lets the user jump between the three distinct concerns of
     task authoring without scrolling through one long form. */

  /* Task node — bound-task name display. Read-only, prominent so it
     reads as an identity rather than an editable field. Taking the
     place of the free-text label input that used to confuse users
     into thinking they were binding a task by typing. */
  .pb-task-bound-name {
      font-size: 0.8rem;
      font-weight: 600;
      color: var(--text);
      padding: 0.35rem 0.5rem;
      background: rgba(59,130,246,0.08);
      border: 1px solid rgba(59,130,246,0.25);
      border-radius: 4px;
      margin-bottom: 0.35rem;
      word-break: break-word;
      user-select: none;
  }

  /* Task node — pass-criteria indicator. Purely informational:
     shows whether the bound task has pass criteria defined and, if
     so, how many. Colour encodes presence so the card's gating
     posture is scannable at a glance. Editing happens on the
     Gating sub-tab of the inspector. */
  .pb-task-pass-indicator {
      font-size: 0.68rem;
      font-weight: 600;
      padding: 0.25rem 0.5rem;
      border-radius: 10px;
      margin: 0.25rem 0 0.35rem 0;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      user-select: none;
      align-self: flex-start;
  }
  .pb-task-pass-indicator.pb-pass-on {
      background: rgba(52, 211, 153, 0.12);
      border: 1px solid rgba(52, 211, 153, 0.4);
      color: var(--green);
  }
  .pb-task-pass-indicator.pb-pass-off {
      background: rgba(127, 127, 127, 0.08);
      border: 1px solid rgba(127, 127, 127, 0.25);
      color: var(--text-muted);
  }

  /* Task node — inline task picker (only shown while unbound). */
  .pb-task-card-picker {
      width: 100%;
      font-size: 0.72rem;
      padding: 0.3rem 0.4rem;
      background: var(--bg);
      border: 1px solid var(--border);
      color: var(--text);
      border-radius: 4px;
      margin-bottom: 0.35rem;
  }
  .pb-task-card-picker:focus { outline: none; border-color: var(--accent); }

  /* Output-card template button row — keeps "Edit" and "+ New" side
     by side under the template picker, with a hint of accent on the
     "+ New" affordance so it stands out when no templates exist. */
  .pb-tpl-btn-row {
      display: flex;
      gap: 0.3rem;
      align-items: center;
      flex-wrap: wrap;
      margin-top: 0.25rem;
  }
  .pb-tpl-new {
      color: var(--accent);
      border-color: rgba(52, 211, 153, 0.35);
      background: rgba(52, 211, 153, 0.08);
  }
  .pb-tpl-new:hover {
      background: rgba(52, 211, 153, 0.14);
      border-color: var(--accent);
  }

  /* Searchable source picker — combobox pattern. The input sits
     inline with the node body; the filtered list floats below,
     styled to match the rest of the dark UI. */
  .pb-source-combobox {
      position: relative;
      display: flex;
      flex-direction: column;
      gap: 0.2rem;
  }
  .pb-source-combobox input.pb-source-search {
      background: var(--bg-card);
      border: 1px solid var(--border);
      color: var(--text);
      padding: 0.35rem 0.5rem;
      border-radius: 4px;
      font-size: 0.74rem;
      width: 100%;
  }
  .pb-source-combobox input.pb-source-search:focus {
      outline: none;
      border-color: var(--accent);
  }
  .pb-source-combobox .pb-source-clear {
      position: absolute;
      right: 6px;
      top: 6px;
      background: transparent;
      border: none;
      color: var(--text-muted);
      cursor: pointer;
      font-size: 0.72rem;
      line-height: 1;
      padding: 2px 4px;
  }
  .pb-source-combobox .pb-source-clear:hover { color: var(--accent); }
  .pb-source-combobox .pb-source-list {
      /* Break out of the node's width when the picker is open: the
         source node is ~220px wide but source names and collection
         labels routinely exceed that. Anchor the dropdown at the
         input's left edge and let it grow to a comfortable fixed
         width. z-index has to sit above sibling nodes on the canvas
         and above any node-body content that renders underneath. */
      position: absolute;
      top: 100%;
      left: 0;
      right: auto;
      width: 420px;
      max-width: calc(100vw - 40px);
      z-index: 1000;
      max-height: 360px;
      overflow-y: auto;
      background: var(--bg-card);
      border: 1px solid var(--border);
      border-radius: 4px;
      margin-top: 2px;
      box-shadow: 0 8px 28px rgba(0, 0, 0, 0.6);
      display: none;
      isolation: isolate;
  }
  .pb-source-combobox.pb-open .pb-source-list { display: block; }
  .pb-source-combobox .pb-source-item {
      padding: 0.5rem 0.7rem;
      font-size: 0.78rem;
      color: var(--text);
      cursor: pointer;
      border-bottom: 1px solid rgba(255, 255, 255, 0.05);
      display: flex;
      align-items: center;
      gap: 0.4rem;
      flex-wrap: wrap;
      background-color: var(--bg-card);
  }
  .pb-source-combobox .pb-source-item:last-child { border-bottom: none; }
  .pb-source-combobox .pb-source-item:hover,
  .pb-source-combobox .pb-source-item.pb-source-active {
      background: var(--bg-hover);
      color: var(--accent);
  }
  .pb-source-combobox .pb-source-item .pb-source-cat {
      color: var(--text-muted);
      font-size: 0.68rem;
      margin-left: 0.5rem;
  }
  .pb-source-combobox .pb-source-name {
      flex: 1 1 auto;
      min-width: 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
  }
  /* Kind pill appended after the name so it's obvious at a glance
     whether a row is an individual source or a named collection. */
  .pb-source-kind {
      display: inline-block;
      padding: 1px 6px;
      border-radius: 10px;
      font-size: 0.62rem;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      line-height: 1.4;
      flex: 0 0 auto;
  }
  .pb-source-kind.pb-kind-source {
      background: rgba(16, 185, 129, 0.18);
      color: #10b981;
      border: 1px solid rgba(16, 185, 129, 0.35);
  }
  .pb-source-kind.pb-kind-collection {
      background: rgba(59, 130, 246, 0.18);
      color: var(--accent);
      border: 1px solid rgba(59, 130, 246, 0.35);
  }
  .pb-source-meta {
      color: var(--text-muted);
      font-size: 0.68rem;
      flex: 0 0 auto;
  }
  .pb-source-combobox .pb-source-empty {
      padding: 0.5rem;
      color: var(--text-muted);
      font-size: 0.72rem;
      font-style: italic;
      text-align: center;
  }

  /* ============================================================
     Output template tree editor
     ============================================================ */

  @media (max-width: 900px) {
      .pb-tt-layout { grid-template-columns: 1fr; }
  }

  .pb-tt-row {
      display: grid;
      /* indent | bullet | name | type | hint | + | × */
      grid-template-columns: var(--indent, 0) 16px minmax(0, 1.4fr) 110px minmax(0, 1.6fr) 28px 28px;
      gap: 0.45rem;
      align-items: center;
      padding: 0.28rem 0;
  }
  .pb-tt-row input,
  .pb-tt-row select {
      padding: 0.42rem 0.55rem;
      font-size: 0.82rem;
      background: var(--bg-card);
      border: 1px solid var(--border-hover);
      border-radius: 5px;
      color: var(--text);
      box-sizing: border-box;
      min-width: 0;
      width: 100%;
  }
  .pb-tt-row input:focus,
  .pb-tt-row select:focus {
      outline: none;
      border-color: var(--accent);
      background: var(--bg-hover);
  }



  /* ============================================================
     Generate-from-intent panel
     ============================================================ */
  @keyframes pb-spin { to { transform: rotate(360deg); } }

  /* ============================================================
     Step indicator at the top of the inspector
     ============================================================ */
  .pb-stepper {
      display: flex;
      gap: 0.4rem;
      margin-bottom: 1.2rem;
      padding-bottom: 1rem;
      border-bottom: 1px solid var(--border);
  }
  .pb-stepper-btn {
      flex: 1;
      background: var(--bg);
      border: 1px solid var(--border-hover);
      color: var(--text-muted);
      padding: 0.7rem 0.9rem;
      border-radius: 6px;
      cursor: pointer;
      font-size: 0.84rem;
      font-weight: 500;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 0.5rem;
      transition: all 0.15s;
  }
  .pb-stepper-btn:hover:not(:disabled) {
      border-color: var(--accent);
      color: var(--text);
  }
  .pb-stepper-btn.active {
      background: rgba(96, 165, 250, 0.12);
      border-color: var(--accent);
      color: var(--accent);
  }
  .pb-stepper-btn:disabled {
      opacity: 0.4;
      cursor: not-allowed;
  }
  .pb-stepper-num {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 20px; height: 20px;
      border-radius: 50%;
      background: var(--bg-hover);
      color: var(--text-muted);
      font-size: 0.7rem;
      font-weight: 600;
  }
  .pb-stepper-btn.active .pb-stepper-num {
      background: var(--accent);
      color: #0a0e17;
  }

  /* ============================================================
     Test-run view (step 2)
     ============================================================ */




/* ── from user/process_trigger_edit.html ───────────────────────── */
.trigger-edit-form {
    max-width: 760px;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.trigger-form-actions {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    margin-top: 0.5rem;
}
.trigger-form-actions .form-status { margin-left: auto; }

/* Predicate row — one per AND-clause in the trigger's conditions */
.predicate-list { display: flex; flex-direction: column; gap: 0.6rem; }
.predicate-row {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
    display: flex; flex-direction: column; gap: 0.55rem;
}
.predicate-top {
    display: flex; gap: 0.5rem; align-items: center;
}
.predicate-top select {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.35rem 0.55rem;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
}
.predicate-top select:hover { border-color: var(--border-hover); }
.predicate-top select:focus { outline: none; border-color: var(--accent); }
.predicate-dim { min-width: 11rem; }
.predicate-matcher { min-width: 9rem; }
.predicate-remove {
    margin-left: auto;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0.1rem 0.5rem;
}
.btn-ghost {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
}
.btn-ghost:hover {
    background: var(--bg-hover);
    color: var(--text);
}

/* Chip input — Enter/comma to commit; backspace on empty input
   removes the last chip; chips render with an inline remove × */
.chip-input {
    display: flex; flex-wrap: wrap; gap: 0.3rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.35rem 0.4rem;
    min-height: 2rem;
    align-items: center;
}
.chip-input:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent);
}
.chip-input-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
/* Removable chip used inside `.chip-input` only. Distinct geometry
   (inline-flex, filled background, larger radius) from the bordered
   meta-grid `.chip` — renamed off the colliding `.chip` name so the
   two no longer fight by source order. */
.chip-input-chip {
    display: inline-flex; align-items: center; gap: 0.3rem;
    background: var(--bg-hover);
    color: var(--text);
    border-radius: 12px;
    padding: 0.1rem 0.55rem 0.1rem 0.65rem;
    font-size: 0.8rem;
}
.chip-remove {
    background: transparent;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
}
.chip-remove:hover { color: var(--red); }
.chip-input-field {
    flex: 1;
    min-width: 8rem;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    padding: 0.15rem 0.25rem;
}

/* Length predicate — 2×2 grid of numeric inputs */
.predicate-length-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.5rem;
}
.predicate-length-cell {
    display: flex; flex-direction: column; gap: 0.2rem;
}
.predicate-length-label {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.predicate-length-input {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.35rem 0.55rem;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
}
.predicate-length-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent);
}

.predicate-add-row { margin-top: 0.7rem; }

/* ── from user/process_triggers.html ───────────────────────────── */
.trigger-group-list { display: flex; flex-direction: column; gap: 0.75rem; }
.trigger-group {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-card);
    overflow: hidden;
}
.trigger-group-summary {
    cursor: pointer;
    padding: 0.75rem 1rem;
    display: flex; align-items: center; gap: 0.75rem;
    font-weight: 600;
    list-style: none;
}
.trigger-group-summary::-webkit-details-marker { display: none; }
.trigger-group-summary::before {
    content: "▸";
    color: var(--text-muted);
    transition: transform 0.15s ease;
    display: inline-block;
}
.trigger-group[open] > .trigger-group-summary::before { transform: rotate(90deg); }
.trigger-group-task { flex: 1; }
.trigger-group-count {
    font-weight: 400;
    color: var(--text-muted);
    font-size: 0.85rem;
}
.trigger-group-add-rule {
    margin-left: 0.5rem;
    font-size: 0.78rem;
    padding: 0.15rem 0.55rem;
    /* Don't inherit the summary's cursor — the link has its own
       interaction model and the stopPropagation guard means clicking
       it shouldn't toggle the surrounding <details>. */
    cursor: pointer;
}
.trigger-group-body { padding: 0 1rem 0.75rem; }
.trigger-table { width: 100%; border-collapse: collapse; }
.trigger-table th, .trigger-table td {
    text-align: left;
    padding: 0.5rem 0.4rem;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}
.trigger-table th {
    font-size: 0.75rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.trigger-description-preview {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-top: 0.15rem;
}
.trigger-predicate-count { color: var(--text-muted); font-size: 0.85rem; }
.trigger-th-enabled, .trigger-td-enabled { width: 5rem; text-align: center; }
.trigger-th-actions, .trigger-td-actions { width: 9rem; text-align: right; }
.trigger-td-actions .btn { margin-left: 0.25rem; }
.toggle { position: relative; display: inline-block; width: 32px; height: 18px; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
    position: absolute; cursor: pointer;
    top: 0; left: 0; right: 0; bottom: 0;
    background: var(--border);
    border-radius: 18px;
    transition: 0.15s;
}
.toggle-slider::before {
    content: "";
    position: absolute;
    height: 14px; width: 14px;
    left: 2px; bottom: 2px;
    background: white;
    border-radius: 50%;
    transition: 0.15s;
}
.toggle input:checked + .toggle-slider { background: var(--accent); }
.toggle input:checked + .toggle-slider::before { transform: translateX(14px); }

/* ── from user/profile.html ────────────────────────────────────── */
/* Reuse the chip-edit styles from direct.html — duplicated here so
   the profile page works standalone if direct.html's CSS hasn't
   been loaded yet. Same chip semantics. */
#req-filters-section .dir-tag-edit-row {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
}
#req-filters-section .dir-tag-list { display: flex; flex-wrap: wrap; gap: 4px; }
#req-filters-section .dir-tag {
    display: inline-block;
    padding: 2px 8px;
    margin: 2px;
    background: rgba(96, 165, 250, 0.12);
    color: var(--accent);
    border: 1px solid rgba(96, 165, 250, 0.25);
    border-radius: 4px;
    font-size: 0.8rem;
}
#req-filters-section .dir-tag-x {
    background: transparent; border: none; cursor: pointer;
    color: inherit; opacity: 0.5;
    margin-left: 0.35rem; padding: 0;
    font-size: 0.95rem; line-height: 1;
}
#req-filters-section .dir-tag-x:hover { opacity: 1; color: var(--red); }
#req-filters-section .dir-tag-add-input {
    background: var(--bg);
    color: var(--text);
    border: 1px dashed var(--border-hover);
    border-radius: 4px;
    padding: 1px 8px;
    font-size: 0.8rem;
    width: 14rem;
}
#req-filters-section .dir-tag-add-input:focus {
    outline: none;
    border-color: var(--accent);
    border-style: solid;
}
#req-filters-section .dir-tag-saving { opacity: 0.5; pointer-events: none; }

/* ── from user/report_detail.html ──────────────────────────────── */
.generating-status { display:flex; gap:0.6rem; align-items:center;
    font-size:0.78rem; color:var(--text-dim); }
.generating-dot { display:inline-block; width:0.6rem; height:0.6rem;
    border-radius:50%; background:#fcd34d;
    animation: pulse-dot 1.2s ease-in-out infinite; }
@keyframes pulse-dot { 0%,100% { opacity:0.35; } 50% { opacity:1; } }
.sse-status { color:var(--text-dim); font-size:0.72rem; padding:0.05rem 0.4rem;
    border:1px solid var(--border); border-radius:8px; }
.sse-status[data-state="live"]   { color:#86efac; border-color:rgba(34,197,94,0.4); }
.sse-status[data-state="closed"] { color:#fca5a5; border-color:rgba(220,38,38,0.4); }
.status-badge { display:inline-block; padding:0.15rem 0.55rem; border-radius:10px; font-size:0.7rem; font-weight:600; text-transform:uppercase; }
.status-draft      { background:rgba(148,163,184,0.14); color:#cbd5e1; border:1px solid rgba(148,163,184,0.35); }
.status-generating { background:rgba(245,158,11,0.16); color:#fcd34d; border:1px solid rgba(245,158,11,0.4); }
.status-ready      { background:rgba(34,197,94,0.14); color:#86efac; border:1px solid rgba(34,197,94,0.35); }
.status-failed     { background:rgba(220,38,38,0.16); color:#fca5a5; border:1px solid rgba(220,38,38,0.4); }
/* Canonical `.report-content` ruleset lives near line 3094.
 * The per-feature overrides below only set the differing properties. */

/* python-markdown's `footnotes` extension wraps the auto-generated
   references at the bottom in a `<div class="footnote">` with no
   heading element. We inject "References" via ::before and hide the
   default <hr/> separator the extension emits, so the section reads
   as a proper bibliography. */
.report-content .footnote {
    margin-top: 2rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
}
.report-content .footnote::before {
    content: "References";
    display: block;
    color: var(--text);
    font-size: 1.15rem;
    font-weight: 600;
    margin-top: 0.4rem;
    margin-bottom: 0.6rem;
}
.report-content .footnote hr { display: none; }
.report-content .footnote ol {
    padding-left: 2rem;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.5;
}
.report-content .footnote li { margin-bottom: 0.4rem; }
.report-content .footnote li p { margin: 0; }

/* Footnote jump highlight — when the user clicks an inline `[^A1]`
   link (or a back-arrow on a footnote), briefly pulse the target
   element so the eye can find the landing spot in a long report.
   Triggered by JS adding the .pulse-highlight class. */
.report-content .pulse-highlight {
    animation: pulse-fn-bg 1s ease-out;
    border-radius: 4px;
}
@keyframes pulse-fn-bg {
    0%   { background-color: rgba(96, 165, 250, 0.45); box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.45); }
    100% { background-color: transparent;              box-shadow: 0 0 0 4px rgba(96, 165, 250, 0);    }
}

/* ── from user/report_detail_v2.html ───────────────────────────── */
.status-badge { display:inline-block; padding:0.15rem 0.55rem; border-radius:10px; font-size:0.7rem; font-weight:600; text-transform:uppercase; }

@keyframes pulse-dot { 0%,100% { opacity:0.35; } 50% { opacity:1; } }

.dd040-detail-actions { display:flex; gap:0.4rem; flex-wrap:wrap; }

/* Overview card — replaces the older inline meta row. Grid of
 * key/value cells; export buttons sit under a divider at the bottom. */
.dd040-meta-card {
    margin-top: 1rem;
    padding: 0.95rem 1.1rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.dd040-meta-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.7rem;
}
.dd040-meta-title {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.dd040-meta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0.7rem 1.2rem;
}
.dd040-meta-cell {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
.dd040-meta-k {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}
.dd040-meta-v {
    font-size: 0.88rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd040-meta-v code {
    background: var(--bg-hover);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    font-size: 0.85em;
    color: var(--accent);
}
.dd040-meta-v .muted { color: var(--text-muted); }
.dd040-meta-config {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    white-space: normal;
    font-size: 0.78rem;
}
.dd040-meta-config span { color: var(--text-muted); }
.dd040-meta-config code { font-size: 0.85em; }

/* Export group — divider above, then a row of format buttons. */
.dd040-export {
    margin-top: 0.85rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.dd040-export-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    margin-right: 0.4rem;
}
.dd040-export-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    background: var(--bg-hover);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    text-decoration: none;
    font-size: 0.82rem;
    transition: background 100ms ease, border-color 100ms ease;
}
.dd040-export-btn:hover {
    background: var(--bg);
    border-color: var(--accent);
    color: var(--accent);
}
.dd040-export-icon { font-size: 1rem; }

.dd040-report-err {
    background:rgba(220,38,38,0.08);
    border:1px solid rgba(220,38,38,0.3);
    padding:0.7rem;
    border-radius:6px;
    color:#fca5a5;
    font-size:0.78rem;
    white-space:pre-wrap;
    margin: 0.4rem 0;
}

.dd040-detail-sections {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-top: 1.2rem;
}
.dd040-detail-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}
.dd040-detail-section-head {
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap: 0.8rem;
    margin-bottom: 0.7rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.6rem;
}
.dd040-detail-section-title {
    margin:0;
    font-size: 1.05rem;
    color: var(--text);
}
.dd040-detail-section-meta {
    display:flex;
    align-items:center;
    gap: 0.55rem;
}
.dd040-section-status {
    display:inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 8px;
    font-size: 0.68rem;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 0.04em;
}
.dd040-section-status--ready   { background:rgba(34,197,94,0.14); color:#86efac; border:1px solid rgba(34,197,94,0.35); }
.dd040-section-status--error   { background:rgba(220,38,38,0.16); color:#fca5a5; border:1px solid rgba(220,38,38,0.4); }
.dd040-section-status--pending { background:rgba(148,163,184,0.14); color:#cbd5e1; border:1px solid rgba(148,163,184,0.35); }

/* Light-theme overrides — the pastel text colors above are tuned
   for a dark background; on near-white they fail contrast. Swap to
   darker, theme-token colours that read against a light tint while
   keeping the same hue family for status semantics. */
body.light .status-draft,
body.light .dd040-section-status--pending {
    background: rgba(71, 85, 105, 0.10);
    color: #334155;
    border-color: rgba(71, 85, 105, 0.35);
}
body.light .status-generating {
    background: rgba(180, 83, 9, 0.12);
    color: #92400e;
    border-color: rgba(180, 83, 9, 0.4);
}
body.light .status-ready,
body.light .dd040-section-status--ready {
    background: rgba(4, 120, 87, 0.12);
    color: #047857;
    border-color: rgba(4, 120, 87, 0.4);
}
body.light .status-failed,
body.light .dd040-section-status--error,
body.light .dd040-report-err {
    background: rgba(185, 28, 28, 0.10);
    color: #b91c1c;
    border-color: rgba(185, 28, 28, 0.4);
}
body.light .sse-status[data-state="live"]   { color: #047857; }
body.light .sse-status[data-state="closed"] { color: #b91c1c; }
.dd040-detail-section-actions {
    display:flex;
    gap: 0.35rem;
}
.dd040-detail-section-actions .btn[data-busy="1"] {
    opacity: 0.6;
    cursor: progress;
}
.dd040-detail-section-empty {
    padding: 1rem;
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.85rem;
}

/* Canonical `.report-content` ruleset lives near line 3094.
 * The per-feature overrides below only set the differing properties. */

/* Cross-section citation links. Body sections produce [A1]; the Flask
 * view rewrites them into anchored links pointing at the matching
 * entry in the References section. Style them as a quiet inline pill
 * so they read as a citation, not as body link. */
.report-content .dd040-cite {
    color: var(--accent);
    text-decoration: none;
    font-size: 0.82em;
    padding: 0 0.2em;
    border-radius: 3px;
    transition: background 100ms ease;
    /* Citations are independent of the surrounding prose's weight —
     * a bracket inside a `<strong>` should still read as a citation
     * marker, not as part of the emphasised phrase. The `<strong>`
     * neighbours stay bold; only the link itself reverts to normal. */
    font-weight: normal;
}
.report-content .dd040-cite:hover {
    background: rgba(96, 165, 250, 0.12);
    text-decoration: underline;
}
/* The anchor target inside the References section. The id sits on
 * the wrapping `<p>` so the whole row is the highlight surface — a
 * 2-character `[N]` span is too small to catch the eye. */
.report-content p.dd040-ref {
    scroll-margin-top: 4rem;
    padding: 0.35rem 0.6rem;
    margin-left: -0.6rem;
    margin-right: -0.6rem;
    border-radius: 4px;
    border-left: 3px solid transparent;
    transition: background 200ms ease, border-color 200ms ease;
}
.report-content p.dd040-ref:target {
    background: rgba(96, 165, 250, 0.18);
    border-left-color: var(--accent);
    animation: dd040-cite-pulse 1.8s ease-out;
}
@keyframes dd040-cite-pulse {
    0%   { background: rgba(96, 165, 250, 0.45); }
    60%  { background: rgba(96, 165, 250, 0.30); }
    100% { background: rgba(96, 165, 250, 0.18); }
}

/* Source contribution chart — horizontal-bar style, CSS-only.
 * Sorted by descending count; bar width is a % of the max count in
 * the report, so the eye reads relative weight at a glance. */
.dd040-source-contribution {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
    margin-top: 1rem;
}
.dd040-sc-head {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-bottom: 0.8rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--border);
}
.dd040-sc-title {
    margin: 0;
    font-size: 1.05rem;
    color: var(--text);
}
.dd040-sc-sub {
    color: var(--text-muted);
    font-size: 0.78rem;
    line-height: 1.5;
}
.dd040-sc-rows {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.dd040-sc-row {
    /* Three-column grid: [bracket] [bar+title] [count]. The bar+title
     * cell stacks vertically — title above, bar below — so the title
     * carries the meaning and the bar is the visual weight.
     *
     * Count column uses `auto` so multi-word labels ("74 mentions")
     * don't overflow a too-narrow fixed-rem column; previously
     * `3.2rem` cropped the hover background visually short of the
     * text. `min-width` keeps single-digit rows from looking lopsided. */
    display: grid;
    /* Bracket column tightened from 2.6rem so `[1]` doesn't sit
     * with ~20px of dead space to its left under right-alignment.
     * 2rem comfortably fits `[99]` in monospace; `[123]+` edge into
     * the gap, which is acceptable for the rare three-digit case. */
    grid-template-columns: 2rem 1fr auto;
    align-items: center;
    gap: 0.7rem;
    padding: 0.4rem 0.5rem;
    border-radius: 6px;
    cursor: pointer;
    text-decoration: none;
    color: inherit;
    transition: background 100ms ease;
}
.dd040-sc-row:hover {
    background: var(--bg-hover);
}
.dd040-sc-bracket {
    color: var(--accent);
    font-family: monospace;
    font-weight: 600;
    font-size: 0.88rem;
    /* Left-aligned so the bracket reads as a label hugging the row's
     * left edge. Right-align left visually-jarring whitespace between
     * the row padding and the bracket. */
    text-align: left;
}
.dd040-sc-barwrap {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}
.dd040-sc-label {
    color: var(--text);
    font-size: 0.84rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd040-sc-bar {
    height: 6px;
    background: var(--bg-hover);
    border-radius: 3px;
    overflow: hidden;
    position: relative;
}
.dd040-sc-bar-fill {
    /* Width set inline as a percentage by the JS. Accent gradient so
     * the chart sits visually next to the rest of the report chrome
     * without looking like a generic spreadsheet bar. */
    position: absolute;
    inset: 0 auto 0 0;
    background: linear-gradient(90deg, rgba(96, 165, 250, 0.45), rgba(96, 165, 250, 0.85));
    border-radius: 3px;
    transition: width 350ms cubic-bezier(0.4, 0, 0.2, 1);
}
.dd040-sc-count {
    color: var(--text);
    font-size: 0.84rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    font-weight: 500;
}
.dd040-sc-count-unit {
    color: var(--text-muted);
    font-size: 0.7rem;
    font-weight: 400;
    margin-left: 0.18rem;
}

/* ── from user/report_wizard_curate.html ───────────────────────── */
.candidate-check { flex: 0 0 auto; cursor: pointer; }
.candidate-title { flex: 1; color: var(--white); font-weight: 500; }

/* Novelty + quality pills — tinted by score so high-signal articles
   visually pop without being shouty. */
.candidate-novelty, .candidate-quality {
    flex: 0 0 auto; font-size:0.7rem; padding:0.1rem 0.45rem;
    border-radius:8px; font-family:monospace; border:1px solid transparent;
}
.candidate-novelty                    { background:rgba(148,163,184,0.10); color:#cbd5e1; border-color:rgba(148,163,184,0.25); }
.candidate-novelty[data-score="3"]    { background:rgba(96,165,250,0.14); color:#93c5fd; border-color:rgba(96,165,250,0.35); }
.candidate-novelty[data-score="4"]    { background:rgba(34,197,94,0.14);  color:#86efac; border-color:rgba(34,197,94,0.35); }
.candidate-novelty[data-score="5"]    { background:rgba(34,197,94,0.22);  color:#bbf7d0; border-color:rgba(34,197,94,0.55); font-weight:600; }
.candidate-quality                    { background:rgba(148,163,184,0.10); color:#cbd5e1; border-color:rgba(148,163,184,0.25); }
.candidate-quality[data-good="1"]     { background:rgba(34,197,94,0.14);  color:#86efac; border-color:rgba(34,197,94,0.35); }

.candidate-source { flex: 0 0 auto; font-size:0.72rem; color:var(--text-muted); display:flex; align-items:center; gap:0.3rem; }

.owner-pill { display:inline-block; padding:0.05rem 0.4rem; border-radius:8px; font-size:0.62rem; font-weight:600; text-transform:uppercase; letter-spacing:0.03em; }
.owner-system  { background:rgba(34,197,94,0.18);  color:#86efac; }
.owner-org     { background:rgba(124,58,237,0.18); color:#c4b5fd; }
.owner-account { background:rgba(96,165,250,0.18); color:#93c5fd; }

.candidate-detail { padding:0.5rem 1rem 0.7rem 2.4rem; border-top:1px solid var(--border); }


/* Soft-coloured chips for the meta-grid. Each domain gets its own
   muted hue so the eye can scan them at a glance:
     blue   → tags        (informational, neutral)
     red    → actors      (threat actor, hostile)
     amber  → sectors     (industry context)
     gray   → category    (editorial classification)
   The 0.10–0.16 alpha range keeps everything visible without dominating.
   The `.chip` base lives once near `.chip-row` above; only the colour
   modifiers are declared here. */
.chip-actor    { background:rgba(220,38,38,0.13);   color:#fca5a5; border-color:rgba(220,38,38,0.32); }
.chip-sector   { background:rgba(245,158,11,0.13);  color:#fcd34d; border-color:rgba(245,158,11,0.32); }
.chip-category { background:rgba(167,139,250,0.13); color:#c4b5fd; border-color:rgba(167,139,250,0.32); }

/* Match-reason is reasoning text, not a tag — keep it plain so the
   alias-chain narrative ("APT28 (also matched aliases: Fancy Bear, …)")
   reads as a sentence and isn't truncated by a pill background. */
.match-reason {
    color:#86efac; font-size:0.78rem; line-height:1.4;
}


/* ── Light-theme overrides ──────────────────────────────────────────
   Every pill / chip / score above uses a pastel text colour designed
   for a dark background. On the light theme those pastels (#86efac,
   #93c5fd, #fca5a5, #fcd34d, #c4b5fd) wash out against a white
   surface and fail contrast. The overrides below swap to deeper text
   tones drawn from the theme's semantic vars (var(--green/red/amber/
   accent) which themselves shift between themes) and increase the
   tinted-background alpha so the pill silhouette stays legible. */
body.light .candidate-novelty                 { background:rgba(71,85,105,0.10);  color:#475569; border-color:rgba(71,85,105,0.30); }
body.light .candidate-novelty[data-score="3"] { background:rgba(37,99,235,0.10);  color:#1d4ed8; border-color:rgba(37,99,235,0.35); }
body.light .candidate-novelty[data-score="4"] { background:rgba(4,120,87,0.10);   color:#047857; border-color:rgba(4,120,87,0.40); }
body.light .candidate-novelty[data-score="5"] { background:rgba(4,120,87,0.18);   color:#065f46; border-color:rgba(4,120,87,0.55); }
body.light .candidate-quality                 { background:rgba(71,85,105,0.10);  color:#475569; border-color:rgba(71,85,105,0.30); }
body.light .candidate-quality[data-good="1"]  { background:rgba(4,120,87,0.10);   color:#047857; border-color:rgba(4,120,87,0.40); }

body.light .owner-system  { background:rgba(4,120,87,0.14);   color:#065f46; }
body.light .owner-org     { background:rgba(91,33,182,0.14);  color:#5b21b6; }
body.light .owner-account { background:rgba(29,78,216,0.14);  color:#1e40af; }

body.light .chip-tag      { background:rgba(29,78,216,0.10);  color:#1e40af; border-color:rgba(29,78,216,0.35); }
body.light .chip-actor    { background:rgba(185,28,28,0.10);  color:#991b1b; border-color:rgba(185,28,28,0.40); }
body.light .chip-sector   { background:rgba(180,83,9,0.10);   color:#92400e; border-color:rgba(180,83,9,0.40); }
body.light .chip-category { background:rgba(91,33,182,0.10);  color:#5b21b6; border-color:rgba(91,33,182,0.35); }

body.light .candidate-date   { color:var(--text-muted); }
body.light .candidate-source { color:var(--text); }
body.light .match-reason     { color:#065f46; }
body.light .btn-detail       { background:rgba(29,78,216,0.08); color:#1e40af; border-color:rgba(29,78,216,0.35); }
body.light .btn-detail:hover { background:rgba(29,78,216,0.16); }

/* ── Article-detail modal ─────────────────────────────────────────────
   Hidden until JS sets [aria-hidden="false"]. Backdrop is a separate
   element so click-to-close doesn't fight with text-selection inside
   the panel. */
.article-modal-header h2 {
    margin:0; font-size:0.95rem; color:var(--white); flex:1;
    line-height:1.3;
}
.article-modal-body h3 {
    color:var(--white); font-size:0.85rem; margin:1rem 0 0.4rem;
    text-transform:uppercase; letter-spacing:0.04em;
}
.article-modal-body .task-name { color:var(--white); font-weight:600; flex:1; }

/* ── from user/report_wizard_params.html ───────────────────────── */
.form-hint { font-size:0.7rem; color:var(--text-dim); margin-top:0.2rem; }
.form-hint code { background:rgba(255,255,255,0.04); padding:0 0.25rem; border-radius:3px; }

/* ── from user/report_wizard_template.html ─────────────────────── */
.generation-refused {
    margin-top:1rem; padding:0.6rem 0.8rem; border-radius:6px;
    background:rgba(220,38,38,0.10); border:1px solid rgba(220,38,38,0.35);
    color:#fca5a5; font-size:0.82rem; line-height:1.4;
}
.synthesis-preview {
    margin-top:1rem; padding:0.7rem 0.9rem; border-radius:6px;
    background:rgba(96,165,250,0.06); border:1px solid rgba(96,165,250,0.25);
}
.preview-title {
    color:var(--white); font-size:0.78rem; font-weight:600;
    text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.5rem;
}
.preview-grid {
    display:grid; grid-template-columns: 9.5rem 1fr;
    gap:0.3rem 0.7rem; font-size:0.82rem; margin:0;
}
.preview-grid dt { color:var(--text-dim); margin:0; }
.preview-grid dd { color:var(--text-muted); margin:0; }
.preview-grid strong { color:var(--white); }
.preview-warn { color:#fcd34d; font-size:0.78rem; margin-left:0.3rem; }
.preview-hint { color:var(--text-dim); font-size:0.74rem; margin-left:0.3rem; }

.generate-form {
    display:flex; flex-direction:column; gap:0.7rem; margin-top:1.2rem;
}
.model-picker {
    display:flex; flex-direction:column; gap:0.25rem;
    padding:0.6rem 0.8rem;
    background:rgba(167,139,250,0.06); border:1px solid rgba(167,139,250,0.25);
    border-radius:6px;
}
.model-picker-label {
    color:var(--white); font-size:0.78rem; font-weight:600;
    text-transform:uppercase; letter-spacing:0.04em;
}
.model-picker select {
    background:rgba(0,0,0,0.25); color:var(--text-muted);
    border:1px solid var(--border); border-radius:4px;
    padding:0.35rem 0.5rem; font-size:0.85rem; max-width:32rem;
}
.model-picker-hint { color:var(--text-dim); font-size:0.74rem; }
.generate-row { display:flex; gap:0.5rem; align-items:center; }

/* ── from user/report_wizard_topic.html ────────────────────────── */
.topic-card-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.8rem; margin-top: 0.6rem;
}
.topic-card {
    display: block; padding: 1rem; border: 1px solid var(--border);
    border-radius: 8px; background: rgba(255,255,255,0.02);
    text-decoration: none; color: inherit;
    transition: background 120ms ease, border-color 120ms ease;
}
.topic-card:hover {
    background: rgba(96,165,250,0.06);
    border-color: rgba(96,165,250,0.45);
}
.topic-card-title { color: var(--white); font-weight: 600; font-size: 0.95rem; margin-bottom: 0.3rem; }
.topic-card-desc { color: var(--text-muted); font-size: 0.8rem; line-height: 1.4; margin-bottom: 0.6rem; }
.topic-card-meta { display: flex; gap: 0.4rem; color: var(--text-dim); font-size: 0.72rem; }
.topic-card-meta strong { color: var(--white); }
.topic-card-params { color: var(--text-dim); font-size: 0.7rem; margin-top: 0.3rem; font-style: italic; }

/* ── from user/reports_list.html ───────────────────────────────── */
.reports-table th { text-align:left; padding:0.5rem 0.6rem; color:var(--text-muted); font-size:0.75rem; text-transform:uppercase; }
.reports-table td { padding:0.5rem 0.6rem; border-top:1px solid var(--border); }
.reports-table td.num { text-align:right; }
.report-name-link { color:var(--accent); text-decoration:none; font-weight:600; }
.report-name-link:hover { text-decoration:underline; }
.topic-badge { display:inline-block; padding:0.15rem 0.55rem; border-radius:10px; background:rgba(96,165,250,0.14); color:#93c5fd; border:1px solid rgba(96,165,250,0.35); font-size:0.7rem; font-weight:600; text-transform:uppercase; letter-spacing:0.03em; }
.status-badge { display:inline-block; padding:0.15rem 0.55rem; border-radius:10px; font-size:0.7rem; font-weight:600; text-transform:uppercase; }

/* ── from user/source_add.html ─────────────────────────────────── */
.discover-spinner {
    width: 16px; height: 16px;
    border: 2px solid var(--border);
    border-top: 2px solid var(--accent);
    border-radius: 50%;
    animation: discover-spin 0.8s linear infinite;
    flex-shrink: 0;
}
@keyframes discover-spin { to { transform: rotate(360deg); } }

/* Bot-protection block. Shown when the discovery detector classifies
   the origin as WAF-protected (Cloudflare / Akamai / AWS WAF / etc).
   Visually distinct from the generic `.validate-status.invalid` row
   so the user immediately understands this is a different kind of
   failure — the source IS reachable, just not by automation. Uses
   the same amber palette as the trial-banner so it reads as
   "warning, not error". */
.discover-blocked {
    display: flex;
    align-items: flex-start;
    gap: 0.9rem;
    padding: 1rem 1.1rem;
    border: 1px solid rgba(245, 158, 11, 0.45);
    background: rgba(245, 158, 11, 0.08);
    border-left: 4px solid var(--amber, #f59e0b);
    border-radius: 8px;
    margin-top: 0.6rem;
}
.discover-blocked-icon {
    font-size: 1.6rem;
    line-height: 1;
    flex-shrink: 0;
    color: var(--amber, #f59e0b);
}
.discover-blocked-body { flex: 1; min-width: 0; }
.discover-blocked-title {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text);
    margin-bottom: 0.4rem;
}
.discover-blocked-explainer {
    margin: 0 0 0.5rem;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.discover-blocked-hint {
    margin: 0 0 0.5rem;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.discover-blocked-meta {
    font-size: 0.72rem;
    color: var(--text-dim);
    font-family: monospace;
    margin-top: 0.4rem;
}

/* "More details (optional)" disclosure on the source-details form.
   Quiet until clicked; the user shouldn't feel like they're skipping
   a required field by leaving it closed. */
.form-extras { margin: 0.6rem 0; }
.form-extras-summary {
    list-style: none;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.78rem;
    padding: 0.4rem 0;
    user-select: none;
}
.form-extras-summary::-webkit-details-marker { display: none; }
.form-extras-summary::before {
    content: "›";
    display: inline-block;
    width: 0.9em;
    color: var(--text-dim);
    transition: transform 0.12s ease;
}
.form-extras[open] > .form-extras-summary::before {
    transform: rotate(90deg);
}
.form-extras-body {
    padding: 0.4rem 0 0.2rem;
}

/* Result-section explainer — sits below the section label, above the
   list of options. One sentence framing what THIS group is so the
   user can pick between "follow the whole site" and "follow what's
   on the page I pasted". */
.validate-suggestion-explainer {
    color: var(--text-muted);
    font-size: 0.78rem;
    line-height: 1.5;
    margin: 0.2rem 0 0.6rem;
}
.validate-suggestion-explainer strong { color: var(--text); }

/* "Show all N articles" expander on each article-pattern row. */
.selector-samples-toggle {
    margin-top: 0.4rem;
    background: none;
    border: none;
    color: var(--accent);
    cursor: pointer;
    font-size: 0.78rem;
    padding: 0.2rem 0;
    text-decoration: underline;
}
.selector-samples-toggle:hover { color: var(--accent-hover); }

/* ── from user/source_collection_detail.html ───────────────────── */
/* Explicit hex values so there is zero chance of falling back to
   transparent through an undefined CSS variable, and
   `background-color` instead of the shorthand to avoid any
   inherited background-image surprises. Rows get their own opaque
   background too so the parent dropdown can never show through when
   the dropdown is scrolled or partly obscured. */
.source-picker-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background-color: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    max-height: 260px;
    overflow-y: auto;
    z-index: 1000;
    box-shadow: 0 6px 20px rgba(0,0,0,0.7);
    isolation: isolate;
}
.source-picker-row {
    padding: 0.5rem 0.7rem;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    font-size: 0.85rem;
    background-color: var(--bg-card);
    color: var(--text);
}
.source-picker-row:hover { background-color: var(--bg-hover); }
.source-picker-row.disabled { opacity: 0.4; cursor: not-allowed; }
.source-picker-empty {
    padding: 0.6rem 0.8rem;
    color: var(--text-muted);
    font-size: 0.8rem;
    background-color: var(--bg-card);
}

.members-table { width: 100%; margin-top: 0.8rem; }
.members-table th { text-align:left; padding:0.4rem 0.6rem; color:var(--text-muted); font-size:0.7rem; text-transform:uppercase; }
.members-table td { padding:0.5rem 0.6rem; border-top:1px solid var(--border); font-size:0.85rem; }
.members-table .remove-btn {
    background:#7f1d1d; color:#fca5a5; border:1px solid #991b1b;
    padding:0.15rem 0.5rem; border-radius:4px; cursor:pointer; font-size:0.7rem;
}

/* ── from user/source_collections.html ─────────────────────────── */
.scope-badge {
    display:inline-block; padding:0.15rem 0.5rem; border-radius:10px;
    font-size:0.7rem; font-weight:600; text-transform:uppercase;
}
.scope-system { background:#1e3a5f; color:#93c5fd; }
.scope-org    { background:#78350f; color:#fcd34d; }
.definitions-table th { text-align:left; padding:0.5rem 0.6rem; color:var(--text-muted); font-size:0.75rem; text-transform:uppercase; }
.definitions-table td { padding:0.5rem 0.6rem; border-top:1px solid var(--border); }
.source-name-link { color:var(--accent); text-decoration:none; font-weight:600; }
.source-name-link:hover { text-decoration:underline; }

/* ── from user/source_detail.html ──────────────────────────────── */
.source-detail-topbar {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: 1rem;
    padding: 1rem 1.1rem;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 1rem;
}
.source-detail-topbar-left {
    display: flex; align-items: center; gap: 0.85rem;
    flex: 1; min-width: 0;
}
.source-detail-topbar-icon {
    width: 38px; height: 38px; border-radius: 6px;
    background: var(--bg); flex-shrink: 0;
}
.source-detail-topbar-titles { min-width: 0; }
.source-detail-topbar-name {
    margin: 0; font-size: 1.25rem; line-height: 1.2;
    color: var(--text); font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 100%;
}
.source-detail-topbar-url {
    color: var(--text-muted); font-size: 0.78rem;
    text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 100%; display: block;
}
.source-detail-topbar-url:hover { color: var(--accent); text-decoration: underline; }
.source-detail-topbar-pills { display: flex; gap: 0.35rem; flex-wrap: wrap; }
.source-detail-topbar-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }
.state-pill {
    display: inline-flex; align-items: center;
    padding: 0.2rem 0.6rem; border-radius: 12px;
    font-size: 0.72rem; font-weight: 600;
    border: 1px solid var(--border);
    color: var(--text-muted);
    background: var(--surface);
    text-transform: uppercase; letter-spacing: 0.04em;
}
.state-pill.state-active { background: rgba(16,185,129,0.15); color: var(--green); border-color: rgba(16,185,129,0.4); }
.state-pill.state-paused { background: rgba(251,191,36,0.12); color: var(--amber); border-color: rgba(251,191,36,0.35); }
.state-pill.state-archived { background: rgba(248,113,113,0.12); color: var(--red); border-color: rgba(248,113,113,0.35); }
.state-pill.state-type { background: var(--bg); color: var(--text-muted); }
@media (max-width: 640px) {
    .source-detail-topbar { flex-direction: column; align-items: stretch; }
    .source-detail-topbar-actions { justify-content: flex-end; }
}
.profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.6rem 1.2rem; margin: 0.6rem 0; }
.profile-not-profiled-prompt {
    margin: 0.6rem 0;
    padding: 1rem 1.2rem;
    border: 1px dashed var(--border-hover);
    border-radius: 6px;
    background: var(--bg-hover);
    text-align: center;
}
.profile-not-profiled-copy {
    margin: 0 auto 0.9rem;
    color: var(--text-muted);
    font-size: 0.88rem; line-height: 1.55;
    max-width: 56ch;
}
.profile-not-profiled-copy strong { color: var(--text); }
.profile-not-profiled-fineprint {
    margin: 0.7rem 0 0;
    color: var(--text-dim);
    font-size: 0.74rem;
}
.profile-cell { display: flex; flex-direction: column; gap: 0.2rem; }
.profile-cell-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); }
.profile-cell-value { font-size: 0.95rem; font-weight: 500; }
.profile-badge {
    display: inline-block; padding: 0.2rem 0.6rem; border-radius: 4px;
    background: rgba(59, 130, 246, 0.12); color: var(--accent);
    border: 1px solid rgba(59, 130, 246, 0.3);
    font-size: 0.8rem; font-weight: 500;
}
.profile-chip {
    display: inline-block; padding: 0.15rem 0.55rem; margin: 0.1rem 0.2rem 0.1rem 0;
    border-radius: 12px; background: var(--surface-alt); color: var(--text-muted);
    border: 1px solid var(--border); font-size: 0.75rem;
}
.profile-rationale {
    background: var(--surface-alt); border-left: 3px solid var(--accent);
    padding: 0.6rem 0.8rem; border-radius: 0 4px 4px 0;
    font-size: 0.85rem; color: var(--text); line-height: 1.45; margin-top: 0.6rem;
}
.profile-confidence-bar {
    height: 6px; background: var(--surface-alt); border-radius: 3px; overflow: hidden;
    width: 100%; margin-top: 0.2rem;
}
.profile-confidence-fill {
    height: 100%; background: linear-gradient(to right, #ef4444 0%, #f59e0b 50%, #10b981 100%);
}
.profile-empty {
    padding: 1rem; background: var(--surface-alt); border-radius: 4px;
    color: var(--text-muted); font-size: 0.85rem; line-height: 1.5;
}
.profile-error {
    padding: 0.6rem 0.8rem; background: rgba(239, 68, 68, 0.1);
    border-left: 3px solid #ef4444; border-radius: 0 4px 4px 0;
    color: #fca5a5; font-size: 0.8rem; font-family: monospace;
}
.profile-banner {
    padding: 0.6rem 0.8rem; background: rgba(59, 130, 246, 0.1);
    border-left: 3px solid var(--accent); border-radius: 0 4px 4px 0;
    color: var(--accent); font-size: 0.85rem; margin-top: 0.6rem;
    display: flex; align-items: center; gap: 0.5rem;
}
.profile-banner-spinner {
    display: inline-block; width: 14px; height: 14px; border: 2px solid var(--accent);
    border-top-color: transparent; border-radius: 50%;
    animation: profile-spin 0.8s linear infinite;
}
@keyframes profile-spin { to { transform: rotate(360deg); } }

/* Topical-focus chip editor */
.topical-chip-row { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.topical-chip { display: inline-flex; align-items: center; gap: 0.3rem; }
.topical-x {
    background: none; border: none; color: var(--text-dim); cursor: pointer;
    font-size: 1.05rem; line-height: 1; padding: 0 0.1rem; opacity: 0.55;
    transition: color 0.12s, opacity 0.12s;
}
.topical-x:hover { color: var(--red); opacity: 1; }
.topical-add-row { position: relative; margin-top: 0.4rem; max-width: 320px; }
.topical-add-input {
    width: 100%; box-sizing: border-box;
    background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 12px;
    padding: 0.25rem 0.65rem; font-size: 0.78rem;
}
.topical-add-input:focus { outline: none; border-color: var(--accent); }
.topical-suggestions {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0;
    background: var(--surface, var(--bg)); border: 1px solid var(--border);
    border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.35);
    max-height: 240px; overflow-y: auto; z-index: 20;
}
.topical-suggestion {
    display: flex; justify-content: space-between; gap: 0.6rem;
    padding: 0.35rem 0.6rem; cursor: pointer; font-size: 0.78rem;
    border-bottom: 1px solid var(--border);
}
.topical-suggestion:last-child { border-bottom: none; }
.topical-suggestion:hover, .topical-suggestion.active { background: var(--surface-alt); }
.topical-suggestion-meta { color: var(--text-dim); font-size: 0.7rem; }
.topical-saving { opacity: 0.5; pointer-events: none; }

/* State pill — communicates the profiler's progress on this source */
.profile-state-pill {
    display: inline-block; padding: 0.18rem 0.55rem; border-radius: 999px;
    font-size: 0.7rem; font-weight: 600; letter-spacing: 0.03em;
    text-transform: uppercase; margin-bottom: 0.5rem;
}
.profile-state-not-profiled {
    background: rgba(148, 163, 184, 0.15); color: #94a3b8;
    border: 1px solid rgba(148, 163, 184, 0.3);
}
.profile-state-profiled {
    background: rgba(16, 185, 129, 0.12); color: #6ee7b7;
    border: 1px solid rgba(16, 185, 129, 0.3);
}
.profile-state-partial {
    background: rgba(245, 158, 11, 0.12); color: #fbbf24;
    border: 1px solid rgba(245, 158, 11, 0.3);
}
.profile-state-errored {
    background: rgba(239, 68, 68, 0.1); color: #fca5a5;
    border: 1px solid rgba(239, 68, 68, 0.3);
}
.profile-cell-empty { color: var(--text-dim); font-style: italic; font-size: 0.85rem; }
.profile-topical-empty {
    color: var(--text-muted); font-size: 0.78rem; font-style: italic;
    margin: 0.25rem 0;
}
.feed-pill {
    display: inline-flex; align-items: center; gap: 0.3rem;
    padding: 0.3rem 0.8rem; border-radius: 20px;
    background: var(--surface-alt); color: var(--text-muted);
    border: 1px solid var(--border); cursor: pointer;
    font-size: 0.8rem; transition: all 0.2s; user-select: none;
}
.feed-pill:hover { border-color: var(--accent); }
.feed-pill.active {
    background: rgba(59, 130, 246, 0.15); color: var(--accent);
    border-color: var(--accent);
}

.recheck-skipped-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.9rem 1rem;
    margin: 0.8rem 0;
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 6px;
    background: var(--surface-alt);
}
.recheck-skipped-copy {
    flex: 1;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--text);
}
.recheck-skipped-copy strong { color: var(--text); }
.recheck-skipped-fineprint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.78rem;
    color: var(--text-muted);
}
.recheck-skipped-btn { flex-shrink: 0; white-space: nowrap; }
@media (max-width: 640px) {
    .recheck-skipped-card { flex-direction: column; align-items: stretch; }
    .recheck-skipped-btn { align-self: flex-start; }
}

/* View-mode summary cards — collapsible "details" with a header
   row that always shows a one-line gist, and the rest revealed on
   click. Visual goal: less form, more glance. */
.sd-summary-card { padding-bottom: 0; }
.sd-summary-summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.1rem 0;
}
.sd-summary-summary::-webkit-details-marker { display: none; }
.sd-summary-summary::before {
    content: '▸'; color: var(--text-muted);
    font-size: 0.7rem; transition: transform 0.15s;
}
.sd-summary-card[open] .sd-summary-summary::before { transform: rotate(90deg); }
.sd-summary-hint {
    color: var(--text-muted); font-size: 0.82rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    flex: 1;
}
.sd-summary-body {
    margin-top: 0.7rem; display: flex; flex-direction: column; gap: 0.45rem;
}
.sd-summary-row {
    display: flex; gap: 0.8rem; align-items: baseline;
    font-size: 0.85rem;
}
.sd-summary-label {
    color: var(--text-muted); flex: 0 0 110px;
    text-transform: uppercase; font-size: 0.7rem;
    letter-spacing: 0.04em;
}
.sd-summary-value {
    flex: 1; color: var(--text); display: inline-flex;
    flex-wrap: wrap; gap: 0.3rem; align-items: center;
}

/* Collection summary — a row of compact chips, each showing one
   facet (type, polling, JS rendering, min words, etc.). */
.sd-chip-row {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    margin-top: 0.6rem;
}
.sd-chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.35rem 0.7rem; border-radius: 16px;
    background: var(--bg-hover); border: 1px solid var(--border);
    font-size: 0.78rem;
}
.sd-chip-key {
    color: var(--text-muted); font-size: 0.7rem;
    text-transform: uppercase; letter-spacing: 0.03em;
}
.sd-chip-val { color: var(--text); font-weight: 500; }
.sd-chip-val code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    background: rgba(255,255,255,0.04);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
}
.sd-chip--off .sd-chip-val { color: var(--text-muted); }

/* Profile-style data grid — each "row" is actually a label/value
   stack (label on top, value beneath). Stacks flow horizontally
   across whatever width is available, like the field grid on a
   user-profile or settings page. No bounding box or coloured
   cells — just typographic hierarchy. Wraps cleanly on narrow
   viewports thanks to auto-fill + minmax. */
.sd-data-list-card { padding-top: 1rem; padding-bottom: 1rem; }
.sd-data-list {
    margin: 0.7rem 0 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1.1rem 1.6rem;
}
.sd-data-row {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}
.sd-data-key {
    /* Smaller + more muted than the value so the eye reads the
       value as the "data" and the label as a quiet field name.
       Light theme has its own override below since --text-muted
       lands too dark there for this size. */
    color: var(--text-dim);
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 500;
    margin: 0;
    opacity: 0.85;
}
body.light .sd-data-key {
    color: #94a3b8;
    opacity: 1;
}
.sd-data-val {
    margin: 0;
    color: var(--text);
    font-size: 0.95rem;
    line-height: 1.4;
    font-weight: 500;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    align-items: center;
    word-break: break-word;
}
.sd-data-val code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.85rem;
    background: rgba(255,255,255,0.04);
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-weight: 400;
}
body.light .sd-data-val code {
    background: rgba(15, 23, 42, 0.06);
}
.sd-data-val-muted { color: var(--text-muted); font-style: italic; font-weight: 400; }
.sd-data-key code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.78rem;
    color: var(--text);
    font-weight: 500;
    background: rgba(255,255,255,0.04);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
}
body.light .sd-data-key code { background: rgba(15, 23, 42, 0.06); }
/* Some values benefit from spanning two columns (long descriptions,
   feed URLs). Add `data-span="2"` on the row when called for. */
.sd-data-row[data-span="2"] { grid-column: span 2; }
.sd-data-row[data-span="all"] { grid-column: 1 / -1; }

/* Hairline rule that separates the data-list above from a sibling
   subsection (e.g. Collection Log) within the same card. Brings
   enough visual contrast to read as "different zone" without
   needing a full card-section split. */
.sd-section-divider {
    margin: 1.4rem 0 0;
    border-top: 1px solid var(--border);
    /* On light theme the default border is too pale to break the
       eye flow; nudge it a hair darker. */
}
body.light .sd-section-divider {
    border-top-color: #cbd5e1;
}
.sd-subsection-title {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: 0.005em;
}
.sc-chip {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.25rem 0.6rem; border-radius: 14px;
    background: var(--bg-hover); border: 1px solid var(--border);
    font-size: 0.75rem;
}
.sc-chip-remove {
    background: transparent; border: 0; color: var(--text-muted);
    cursor: pointer; padding: 0; font-size: 0.9rem; line-height: 1;
}
.sc-chip-remove:hover { color: var(--danger); }
.source-picker-dropdown {
    /* Opaque background + own stacking context so this dropdown
       floats cleanly above sibling .card-section blocks further
       down the page. Explicit hex values instead of CSS variables
       — a misspelled var() falls back to transparent and lets the
       underlying text bleed through. */
    position: absolute; top: 100%; left: 0; right: 0;
    background-color: var(--bg-card); border: 1px solid var(--border);
    border-radius: 6px; max-height: 220px; overflow-y: auto;
    z-index: 1000; box-shadow: 0 6px 20px rgba(0,0,0,0.7);
    isolation: isolate;
}
.source-picker-row {
    padding: 0.5rem 0.7rem; cursor: pointer;
    border-bottom: 1px solid var(--border); font-size: 0.8rem;
    background-color: var(--bg-card); color: var(--text);
}
.source-picker-empty {
    padding: 0.6rem 0.8rem; color: var(--text-muted);
    font-size: 0.8rem; background-color: var(--bg-card);
}
.source-picker-empty { padding: 0.6rem 0.8rem; color: var(--text-muted); font-size: 0.8rem; }

/* Light-theme overrides — the dark hard-coded hex values above
   leave the dropdown looking like a black slab on a light page.
   The token-mapped colours land properly in light mode. */
body.light .source-picker-dropdown {
    background-color: #ffffff;
    box-shadow: 0 6px 20px rgba(15, 23, 42, 0.16);
}
body.light .source-picker-row,
body.light .source-picker-empty { background-color: #ffffff; color: #0f172a; }
body.light .source-picker-row:hover { background-color: #f1f5f9; }

/* ── from user/sources.html ────────────────────────────────────── */
.sources-first-hero-wrap {
    flex: 1 1 auto;
    min-height: 60vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}
.sources-first-hero {
    width: 100%;
    max-width: 560px;
    text-align: center;
    padding: 2.6rem 2.8rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-card);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
body.light .sources-first-hero {
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08);
}
.sources-first-hero h2 {
    margin: 0 0 0.8rem;
    font-size: 1.7rem; line-height: 1.2;
    color: var(--text);
}
.sources-first-hero-copy {
    margin: 0 auto 1.6rem;
    color: var(--text-muted);
    font-size: 1rem; line-height: 1.55;
    max-width: 50ch;
}
.sources-first-hero-fineprint {
    margin: 1.4rem 0 0;
    font-size: 0.78rem;
    color: var(--text-dim);
}
.sources-first-hero-fineprint a { color: var(--accent); }

/* ── Sources list view ────────────────────────────────────────
   List-of-rows replacing the previous tile grid. Each row is a
   self-contained anchor: status dot · favicon · name+url+desc ·
   last-collected meta. Same data-attrs as the old `.source-card`
   so the search/filter JS keeps working unmodified — both class
   names live on the element to avoid a JS-side rename. */
.source-list {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--border);
}
.source-row {
    /* Override the legacy `.source-card { position: relative }` so
       any leftover absolutely-positioned children from the old
       tile design (e.g. `.source-status-icon`) don't float into
       the row's right edge and overlap the meta block. */
    position: static;
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.6rem 0.5rem;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
    transition: background 100ms ease;
}
.source-row:hover { background: var(--bg-hover); }
.source-row.source-archived { opacity: 0.6; }
.source-row__favicon {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 3px;
    object-fit: contain;
    margin-top: 0.1rem;
}
.source-row__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.source-row__head {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    min-width: 0;
}
.source-row__name {
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--text);
}
.source-row__url {
    color: var(--text-muted);
    font-size: 0.78rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
.source-row__desc {
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.4;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.source-row__meta {
    /* Single-line: "Last Collected: May 24, 14:30 ●"
       inline-flex keeps the timestamp and status dot side-by-side
       on the same baseline. Reserve enough horizontal room that
       a normal timestamp + dot never wraps and never crowds the
       row body. */
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-muted);
    font-size: 0.75rem;
    white-space: nowrap;
    margin-top: 0.2rem;
}
.source-row__last--never {
    color: var(--text-dim);
    font-style: italic;
}

/* ── from user/system.html ─────────────────────────────────────── */
    .sec-events-table .sec-event-row-expandable { cursor: pointer; }
    .sec-events-table .sec-event-row-expandable:hover { background: rgba(255,255,255,0.03); }
    .sec-event-toggle { width: 1.5rem; padding-right: 0; color: var(--text-dim); }
    .sec-toggle-glyph { display: inline-block; transition: transform 120ms ease; }
    .sec-event-row.expanded .sec-toggle-glyph { transform: rotate(90deg); }
    .sec-event-detail td { padding: 0.5rem 0.8rem 0.7rem 0.8rem; background: rgba(255,255,255,0.02); }
    .sec-event-grid { display: grid; grid-template-columns: 8rem 1fr; gap: 0.3rem 0.8rem; }
    .sec-event-k { color: var(--text-dim); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; }
    .sec-event-v { color: var(--white); font-size: 0.78rem; }
    

/* ── from user/tasks.html ──────────────────────────────────────── */
@keyframes run-spin { to { transform: rotate(360deg); } }

/* ════════════════════════════════════════════════════════════════
   TODO: duplicate selector — reconcile (162 groups)
   ════════════════════════════════════════════════════════════════ */
/* The following selectors appear in more than one section above.
   Reconcile by either merging the rule bodies, namespacing one of
   them, or deleting the dead duplicate. Listed by occurrence count
   then alphabetically. Source = the section banner the rule lives
   under in this file. */

/* DUP body.light — appears in: BASELINE — original user.css; STREAMS — merged from streams.css 2026-05-27 (×2); PUBLIC — merged from public.css 2026-05-27 */
/* DUP .pb-inspector-body textarea — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27 (×2); INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .status-badge — appears in: DASHBOARD — merged from dashboard.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 (×3) */
/* DUP .dd025-bookmark-pop — appears in: STREAMS — merged from streams.css 2026-05-27; ARTICLE-BOOKMARK — merged from shared/article_bookmark.css 2026-05-27 (×2) */
/* DUP .dd025-card-bookmark — appears in: STREAMS — merged from streams.css 2026-05-27; ARTICLE-BOOKMARK — merged from shared/article_bookmark.css 2026-05-27 (×2) */
/* DUP .dd032-wb-section-confirm-delete — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×3) */
/* DUP .lp-demo-dash__grid — appears in: DEMO — merged from demo.css 2026-05-27 (×3) */
/* DUP .lp-hero-flow — appears in: PUBLIC — merged from public.css 2026-05-27 (×3) */
/* DUP .lp-pricing-grid — appears in: PUBLIC — merged from public.css 2026-05-27 (×3) */
/* DUP .lp-sp-anatomy-grid — appears in: PUBLIC — merged from public.css 2026-05-27 (×3) */
/* DUP .lp-sp-curation-grid — appears in: PUBLIC — merged from public.css 2026-05-27 (×3) */
/* DUP .lp-topbar — appears in: PUBLIC — merged from public.css 2026-05-27 (×3) */
/* DUP .sidebar — appears in: BASELINE — original user.css (×2); INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .source-picker-empty — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×3) */
/* DUP :root — appears in: BASELINE — original user.css; STREAMS — merged from streams.css 2026-05-27; PUBLIC — merged from public.css 2026-05-27 */
/* DUP .activity-stream — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .activity-stream-strip — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .article-list — appears in: BASELINE — original user.css (×2) */
/* DUP .article-modal-body .task-name — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .article-modal-body h3 — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .article-modal-header h2 — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .at-controls input[type="number"] — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .breaking-banner — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .breaking-summary — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .candidate-detail — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .candidate-novelty — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .candidate-quality — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .candidate-title — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .cards-grid — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .cost-table th — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .cve-grid — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .cycle-layout — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .cycle-step-btn — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .data-table — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .data-table td — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .data-table th — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .dd025-add-tile — appears in: STREAMS — merged from streams.css 2026-05-27 (×2) */
/* DUP .dd025-bookmark-pop-host — appears in: ARTICLE-BOOKMARK — merged from shared/article_bookmark.css 2026-05-27 (×2) */
/* DUP .dd025-card--just-arrived — appears in: STREAMS — merged from streams.css 2026-05-27 (×2) */
/* DUP .dd025-col — appears in: STREAMS — merged from streams.css 2026-05-27 (×2) */
/* DUP .dd025-col-header — appears in: STREAMS — merged from streams.css 2026-05-27 (×2) */
/* DUP .dd025-rail — appears in: STREAMS — merged from streams.css 2026-05-27 (×2) */
/* DUP .dd032-tiles — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-body — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-card — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-card--expanded — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-card-byline — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-card-insight-row — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-querybar-row — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-rail — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-section--folded .dd032-wb-section-header — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-section-save — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-section-title — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd032-wb-titlerow — appears in: COLLECTIONS — merged from collections.css 2026-05-27 (×2) */
/* DUP .dd040-compose-field-row — appears in: REPORT-COMPOSE — merged from report_compose.css 2026-05-27 (×2) */
/* DUP .dd040-preview-content — appears in: REPORT-COMPOSE — merged from report_compose.css 2026-05-27 (×2) */
/* DUP .dir-form-card textarea — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .dir-preview-card — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .empty-state — appears in: BASELINE — original user.css (×2) */
/* DUP .entry-cols — appears in: BASELINE — original user.css (×2) */
/* DUP .entry-list-header — appears in: BASELINE — original user.css (×2) */
/* DUP .flash-toast — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .form-row textarea — appears in: BASELINE — original user.css (×2) */
/* DUP .happening-banner — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .happening-summary — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .home-onboarding-hero::after — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .home-onboarding-hero::before — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .lp-addons-row — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .lp-bundle — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .lp-bundle__total-block — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .lp-compound-arrow — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-compound-row — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-demo-article-card--clickable — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-btn--pulse-hint — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-fade-in — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-launchpad-card — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-launchpad-grid — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__chrome — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__close — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__header — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__main — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__nav — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__nav-item — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__nav-item--pulse-hint — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__nav-row — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__panel — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__sidebar — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-demo-modal__sidebar-footer — appears in: DEMO — merged from demo.css 2026-05-27 (×2) */
/* DUP .lp-flow-arrow — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-flow-stage — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-flow-stage:hover — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-flow-stages — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-footer-inner — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-form-row — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-hero — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-hero-tagline — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-link--active — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-mock-doc-table th — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-body — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-card — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-data — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-header — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-prose-tight — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-modal-row dt — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-pricing-card — appears in: PUBLIC — merged from public.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .lp-products-grid — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-section — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-sp-tile-grid — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-topbar-menu-btn — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-topbar-nav — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-topbar-nav__auth — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-topbar-nav__content — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-topbar-nav__sep — appears in: PUBLIC — merged from public.css 2026-05-27 (×2) */
/* DUP .lp-trust-sep — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .main-content — appears in: BASELINE — original user.css (×2) */
/* DUP .nation-grid — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .onboarding-spotlight — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .overlay-card — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .pb-inspector-body input — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-inspector-body input:focus — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-inspector-body select — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-inspector-body select:focus — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-inspector-body textarea:focus — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-task-header — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-tt-row — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-tt-row input — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-tt-row input:focus — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-tt-row select — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .pb-tt-row select:focus — appears in: TASK-INSPECTOR — merged from css/task_inspector.css 2026-05-27; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .phase-links li — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .phase-panel — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .phase-panel-area — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .phase-panel-empty — appears in: LEARN — merged from learn.css 2026-05-27 (×2) */
/* DUP .pricing-table th — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .recheck-skipped-btn — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .recheck-skipped-card — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .sidebar-brand — appears in: BASELINE — original user.css (×2) */
/* DUP .sidebar-link — appears in: BASELINE — original user.css (×2) */
/* DUP .source-card — appears in: BASELINE — original user.css (×2) */
/* DUP .source-detail-topbar — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .source-detail-topbar-actions — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .source-picker-dropdown — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .source-picker-row — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP .sparse-grid — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .stage-header — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .stat-cards — appears in: BASELINE — original user.css (×2) */
/* DUP .story-headline — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .story-narrative — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .tab-bar — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .theme-toggle — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .timeline-overlay — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .timeline-panel — appears in: DASHBOARD — merged from dashboard.css 2026-05-27 (×2) */
/* DUP .topbar — appears in: BASELINE — original user.css (×2) */
/* DUP .topic-card — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .topic-card-desc — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .topic-card:hover — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP .trigger-table th — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
/* DUP body.light .btn-detail — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP body.light .btn-detail:hover — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP body.light .chip-tag — appears in: BASELINE — original user.css; INLINE BLOCKS — extracted from templates 2026-05-27 */
/* DUP body.light .flash-toast — appears in: INLINE BLOCKS — extracted from templates 2026-05-27 (×2) */
