/* ──────────────────────────────────────────────────────────
   Naveyn SPA — /app
   ────────────────────────────────────────────────────────── */

:root {
    --bg-primary: #0d1a0d;
    --bg-surface: #162016;
    --bg-surface-alt: #1a2a1a;
    --bg-input: #0f170f;
    --border: #1a2e1a;
    --border-hover: #3d5a3d;
    --text-primary: #e0e0e0;
    --text-secondary: #c4d4c4;
    --text-muted: #6e8e6e; /* WCAG AA: ≥4.5:1 on bg-surface (was #5a7a5a = 3.49:1, failed normal-text) */
    --text-dim: #3d5a3d; /* decorative / disabled / divider tier only — below AA, never use for readable body text */
    --text-detail: #7a8a7a;
    --text-body: #8a9a8a;
    --accent-purple: #7c3aed;
    --accent-purple-dim: #9b7dcf;
    --accent-green: #4ade80;
    --accent-red: #ef4444;
    --accent-amber: #fbbf24;
    --font-brand: 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
    --font-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    --app-height: 100vh;
    --tab-bar-height: 56px;
    --safe-bottom-pad: calc(var(--tab-bar-height) + env(safe-area-inset-bottom, 34px) + 12px);

    /* ─── Action → color map (U-2) ───────────────────────────
       ONE source of truth for action-button colors, keyed by semantic action
       (not by color). Same action = same color on every surface (feed + inbox).
       The .inbox-btn / .feed-btn color variants below point here; do NOT hardcode
       these hexes at the variant. 2.94 (button unification) consumes these vars. */
    --action-primary-bg: var(--accent-purple);  --action-primary-fg: #ffffff;
    --action-approve-bg: #16a34a;                --action-approve-fg: #ffffff;
    --action-work-bg: #7c3aed;                   --action-work-fg: #ffffff;
    --action-route-bg: #1a1a0d;                  --action-route-fg: #fbbf24;  --action-route-border: #a38517;
    --action-info-bg: #1e3a5f;                   --action-info-fg: #60a5fa;
    --action-dismiss-bg: #1a0d0d;                --action-dismiss-fg: #ef4444; --action-dismiss-border: #3a1a1a;
    --action-pass-bg: var(--bg-primary);         --action-pass-fg: var(--text-muted); --action-pass-border: var(--border);
}

/* ──────────────────────────────────────────────────────────
   Z-INDEX TIERS — keep stacking values on these semantic levels.
   Don't invent intermediate values; pick the tier that fits.
     1–5    in-flow / content stacking (sticky headers, swipe cards, drawer layers)
     50     navigation chrome (tab bar, projects header)
     100    modal / overlay scrims (bottom-sheet overlay, project-modal overlay)
     101    bottom-sheet panel (sits above its own scrim)
     200    toast / transient notification (above everything, incl. modals)
   ────────────────────────────────────────────────────────── */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
/* max-width:100% (not 100vw) — WKWebView resolves `vw` stale-narrow on resume
   from an external link, clamping content to ~half width while clientWidth
   stays correct (#10, 2026-05-24). 100% tracks the containing block; overflow-x
   does the actual clipping. */
html, body { max-width: 100%; overflow-x: hidden; }
/* 16px minimum on all form inputs — prevents iOS auto-zoom on focus */
input, textarea, select { font-size: 16px; }

body {
    font-family: var(--font-system);
    background: var(--bg-primary);
    color: var(--text-primary);
    height: var(--app-height);
    width: 100%;
    max-width: 100%;  /* not 100vw — see html,body note (#10 vw-staleness) */
    overflow: hidden;
    overflow-x: hidden;
    padding-top: env(safe-area-inset-top, 0px);
    -webkit-user-select: none;
    user-select: none;
    -webkit-font-smoothing: antialiased;
}

/* ─── Base button component (2.94 / U-1) ───────────────────────────
   ONE source of truth for button box-model + interaction. Color stays on the
   family classes via the --action-* map (2.91 / U-2 — do NOT add color here).
   Compose: class="btn [btn--sm] <family> [<family-color>]" — base owns the BOX,
   family owns the COLOR. min-height is an iOS-HIG tap-target floor: it can only
   grow a sub-44px button, never shrink one. */
.btn {
    min-height: 44px;
    padding: 9px;
    border-radius: 8px;
    font-size: 12px;
    text-align: center;
    cursor: pointer;
    border: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
}
.btn:active {
    opacity: 0.6;
    transition: opacity 0.05s;
}
.btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}
.btn:focus-visible {
    outline: 2px solid var(--accent-purple);
    outline-offset: 2px;
}
.btn--sm {
    padding: 6px 10px;
    font-size: 11px;
}

/* ─── Login screen ─── */
#loginScreen {
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: var(--app-height);
    padding: 24px;
}
#loginScreen .login-brand {
    font-family: var(--font-brand);
    color: var(--text-secondary);
    font-size: 28px;
    margin-bottom: 8px;
}
#loginScreen .login-sub {
    color: var(--text-muted);
    font-size: 13px;
    margin-bottom: 24px;
}
#loginScreen .login-dot {
    color: var(--accent-purple);
    margin-right: 6px;
}
#loginScreen .login-error {
    color: var(--accent-red);
    font-size: 12px;
    margin-top: 12px;
}

/* ─── App shell ─── */
#appShell {
    display: none;
    flex-direction: column;
    /* body already consumes safe-area-inset-top via padding-top; the shell is
       laid out INSIDE that padding, so it must be the viewport height MINUS the
       top inset. Without the subtraction the shell overshoots the visible area
       by the inset height (e.g. 59px on a Dynamic-Island iPhone), pushing the
       bottom-anchored chat input bar off-screen behind the fixed tab bar —
       invisible and untappable (no input -> no keyboard). Device-verified:
       overlap 67px -> 0px at innerH=852, inset-top=59. */
    height: calc(var(--app-height) - env(safe-area-inset-top, 0px));
    width: 100%;
    max-width: 100%;  /* not 100vw — see html,body note (#10 vw-staleness) */
    overflow: hidden;
}
#appShell.active {
    display: flex;
    /* Reserve the REAL rendered tab-bar height. --tab-bar-height (56px) under-
       reserves by 8px vs the actual ~64px the fixed tab bar occupies, which
       left the chat input bar 8px behind the tab bar even after the height fix
       above. Device-verified: 64px lands the input bar flush above the tab bar. */
    padding-bottom: 64px;
}

/* Mobile: .ipad-content wraps the main content area and must preserve flex chain */
.ipad-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    width: 100%;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
}

/* ─── Tabs ─── */
.tab-content {
    display: none;
    flex-direction: column;
    flex: 1;
    width: 100%;
    max-width: 100%;  /* not 100vw — see html,body note (#10 vw-staleness) */
    min-height: 0;
    overflow: hidden;
}
.tab-content.active { display: flex; }

.tab-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.tab-body {
    flex: 1;
    width: 100%;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    padding: 10px 12px;
    padding-bottom: var(--safe-bottom-pad);
}

/* ─── Tab bar ─── */
/* Capacitor's WKWebView handles the iPhone home indicator safe area natively.
   Do not add env(safe-area-inset-bottom) here — it double-stacks under native. */
.tab-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-around;
    padding: 8px 0;
    border-top: 1px solid var(--border);
    background: var(--bg-input);
    z-index: 50;
}
.tab-bar-item {
    text-align: center;
    cursor: pointer;
    position: relative;
    -webkit-tap-highlight-color: transparent;
    padding: 4px 12px;
}
.tab-bar-icon {
    width: 24px;
    height: 24px;
    margin: 0 auto 3px;
    border-radius: 6px;
    border: 1.5px solid var(--border-hover);
}
.tab-bar-icon.circle { border-radius: 50%; }
.tab-bar-item.active .tab-bar-icon {
    background: var(--accent-purple);
    border-color: var(--accent-purple);
}
.tab-bar-label {
    font-size: 10px;
    color: var(--text-muted);
}
.tab-bar-item.active .tab-bar-label {
    color: var(--accent-purple-dim);
}
.tab-badge {
    position: absolute;
    top: -2px;
    right: 4px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: none;
}
.tab-badge.feed { background: var(--accent-red); }
.tab-badge.chat { background: var(--accent-green); }

/* ─── Home tab cards ─── */
.home-card {
    background: var(--bg-surface);
    border-radius: 12px;
    padding: 14px;
    margin-bottom: 10px;
    border-left: 3px solid transparent;
    cursor: pointer;
    transition: background 0.15s;
}
.home-card:active { background: var(--bg-surface-alt); }
.home-card.feed-item { border-left-color: var(--accent-purple); }
.home-card.chat-item { border-left-color: var(--accent-green); }
.home-card-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
}
.home-card-subtitle {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 4px;
}
.home-card-badge {
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 10px;
}
.home-card-badge.feed { background: var(--accent-purple); color: white; }
.home-card-badge.chat { background: #1a3a1a; color: var(--accent-green); }

/* ─── Feed — filter chips ─── */
.filter-chips {
    display: flex;
    gap: 6px;
    padding: 10px 16px;
    flex-shrink: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.filter-chips::-webkit-scrollbar { display: none; }
.chip {
    background: var(--bg-surface);
    color: var(--text-muted);
    font-size: 11px;
    padding: 5px 12px;
    border-radius: 8px;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.chip.active {
    background: var(--accent-purple);
    color: white;
}

/* ─── Feed — list cards ─── */
.feed-card {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    margin-bottom: 10px;
    overflow: hidden;
}
.feed-card-body {
    padding: 14px 14px 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.feed-card-body:active {
    background: var(--bg-surface-alt);
}
.feed-card-tags {
    display: flex;
    gap: 6px;
    margin-bottom: 8px;
}
.feed-tag {
    background: var(--border);
    color: var(--accent-purple-dim);
    font-size: 10px;
    padding: 2px 7px;
    border-radius: 6px;
}
/* Phase 2b: a "resurface" card is a proactive watchlist match, not a fresh
   find — green tint distinguishes it from the neutral grey .feed-tag. */
.feed-tag-watchlist {
    background: rgba(74, 222, 128, 0.16);
    color: var(--accent-green);
}
.feed-card-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-primary);
    margin-bottom: 4px;
}
/* 2.98: event date·venue line — the key triage field for a dated discovery feed,
   so it's surfaced on the card (slightly emphasized) without opening the item. */
.feed-card-meta {
    font-size: 12px;
    font-weight: 500;
    color: var(--accent-purple-dim);
    margin-bottom: 4px;
}
.feed-card-summary {
    font-size: 12px;
    color: var(--text-detail);
    line-height: 1.4;
}
.feed-card-actions {
    display: flex;
    gap: 6px;
    padding: 8px 14px 14px;
}
.feed-btn {
    flex: 1;  /* box-model + :active now on base .btn (2.94) */
}
.feed-btn.primary {
    background: var(--action-primary-bg);
    color: var(--action-primary-fg);
}
.feed-btn.muted {
    background: var(--action-pass-bg);
    border: 1px solid var(--action-pass-border);
    color: var(--action-pass-fg);
}
.feed-btn.danger {
    background: var(--action-dismiss-bg);
    border: 1px solid var(--action-dismiss-border);
    color: var(--action-dismiss-fg);
}
.feed-btn.action {
    background: var(--bg-primary);
    border: 1px solid var(--accent-purple);
    color: var(--accent-purple-dim);
}
/* "Work on it in chat" — a distinct *kind* of action (continue thinking, not
   file/decide). Purple-tinted fill sets it apart from route options and the
   decision buttons. */
.feed-chat-btn {
    background: rgba(124, 58, 237, 0.12);
    border: 1px solid var(--accent-purple);
    color: var(--accent-purple-dim);
    font-weight: 500;
}
.feed-chat-btn:active { background: rgba(124, 58, 237, 0.20); }

/* ─── Feed — batch list ─── */
.batch-area {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0 12px 12px;
}

/* ─── Feed — pull-to-refresh spinner ─── */
#tab-feed { position: relative; }
.feed-refresh-spinner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    transform: translateY(-56px);
    opacity: 0;
    z-index: 5;
    transition: transform 0.18s ease, opacity 0.18s ease;
}
.feed-refresh-spinner.pulling { transition: none; }
.feed-refresh-spinner.refreshing {
    transform: translateY(0) !important;
    opacity: 1 !important;
    transition: transform 0.18s ease, opacity 0.18s ease;
}
.feed-refresh-icon {
    width: 22px;
    height: 22px;
    border: 2px solid var(--border);
    border-top-color: var(--accent-purple);
    border-radius: 50%;
}
.feed-refresh-spinner.refreshing .feed-refresh-icon {
    animation: feed-refresh-spin 0.7s linear infinite;
}
@keyframes feed-refresh-spin {
    to { transform: rotate(360deg); }
}
.batch-card {
    background: var(--bg-surface);
    border-radius: 12px;
    padding: 14px;
    margin-bottom: 8px;
    border: 1px solid var(--border);
}
.batch-card-tags { display: flex; gap: 6px; margin-bottom: 8px; }
.batch-card-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-primary);
    margin-bottom: 4px;
}
.batch-card-summary {
    font-size: 12px;
    color: var(--text-detail);
    line-height: 1.4;
    margin-bottom: 12px;
}
.batch-card-actions { display: flex; gap: 6px; }
.batch-btn {
    flex: 1;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px;
    text-align: center;
    font-size: 11px;
    color: var(--text-secondary);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.batch-btn:active { background: var(--bg-surface); }
.batch-btn.action {
    border-color: var(--accent-purple);
    color: var(--accent-purple-dim);
}

.header-btn {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    color: var(--text-secondary);  /* box-model on .btn .btn--sm; :active on base (2.94) */
}

/* ─── Bottom sheet ─── */
.bottom-sheet-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 100;
}
.bottom-sheet-overlay.show { display: block; }
.bottom-sheet {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--bg-surface-alt);
    border-top: 1px solid var(--border-hover);
    border-radius: 16px 16px 0 0;
    padding: 20px 16px 16px;
    z-index: 101;
    transform: translateY(100%);
    transition: transform 0.3s ease-out;
    /* 2.46: tall-content scroll on iOS — needed by migrated form modals */
    max-height: 80vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
}
.bottom-sheet.show { transform: translateY(0); }
.sheet-handle {
    width: 36px;
    height: 4px;
    background: var(--border-hover);
    border-radius: 2px;
    margin: 0 auto 12px;
}
.sheet-title {
    font-size: 14px;
    color: var(--text-secondary);
    font-weight: 500;
    text-align: center;
}
.sheet-subtitle {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 4px;
    text-align: center;
}
.sheet-reasons {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 16px;
}
.sheet-reason {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    font-size: 13px;
    color: var(--text-secondary);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.sheet-reason:active { background: var(--bg-surface); }
.sheet-reason.dim { color: var(--text-muted); }

/* custom_actions §6.3: full-width 44pt status rows for the feed status sheet.
   <button>, so reset the native chrome to match .sheet-reason's look. */
.sheet-row {
    display: block;
    width: 100%;
    min-height: 44px;
    box-sizing: border-box;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    margin-top: 8px;
    font-size: 14px;
    color: var(--text-secondary);
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.sheet-row:active { background: var(--bg-surface); }

/* ─── Phase 3 cascade sheet (D3) — one sliding sheet, content transitions ───
   The .bottom-sheet slides up ONCE; layer changes only swap .cascade-content and
   replay the push-slide enter animation, so the user never sees two stacked
   modals. Rows reuse .sheet-row; the row override here aligns the drill chevron. */
.cascade-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 24px;
    margin-bottom: 4px;
}
.cascade-back {
    background: none;
    border: none;
    padding: 4px 2px;
    font-size: 14px;
    color: var(--text-secondary);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.cascade-back:active { color: var(--text-muted); }
.cascade-close {
    background: none;
    border: none;
    padding: 4px 6px;
    font-size: 15px;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.cascade-close:active { color: var(--text-secondary); }
.cascade-breadcrumb {
    font-size: 11px;
    color: var(--text-muted);
    text-align: center;
    margin-bottom: 2px;
}
.cascade-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
/* 2.99(c): the "Not this run" transient-suppress leaf — de-emphasized and set
   off from the agent's list-routing options by a top divider (it does NOT write
   to the list; it just hides the card for this run). */
.cascade-row.cascade-row-muted {
    color: var(--text-muted);
    margin-top: 6px;
    border-top: 1px solid var(--border);
}
/* ─── Cascade sheet: flex-anchored, robust-by-construction (2026-06-07) ───────
   ROOT CAUSE of the off-screen-rows bug: the shared .bottom-sheet is position:fixed
   bottom:0 with height:auto — it GROWS UPWARD as content changes. iOS WKWebView does
   not re-anchor a fixed+transform sheet when its content height changes on a layer
   swap, so a taller layer's lower rows render below the fold. Five re-anchor/animation
   patches failed on-device; neither Chromium nor desktop WebKit reproduces it, so the
   fix has to be structural rather than a quirk-patch (design-review: Margaret/Kenzo/
   David/Alina + Sasha Park).
   FIX: make the cascade sheet a FLEX CHILD of the overlay (overlay = flex, align-items
   flex-end) instead of a self-anchoring fixed element. As a flex child it reflows
   normally on an in-place content swap; max-height + overflow-y keep a tall layer
   SCROLLABLE rather than clipped, so rows can never be lost even if iOS mis-sizes.
   Reveal is opacity-only (no transform → no fixed-element compositing trap). Scoped to
   the cascade overlay (shared .bottom-sheet form modals + keyboard handling untouched)
   and to mobile (≥768px already uses the centered position:static modal — no bug). */
@media (max-width: 767px) {
    .bottom-sheet-overlay.cascade-overlay.show {
        display: flex;
        align-items: flex-end;
        justify-content: center;
    }
    .cascade-overlay .bottom-sheet,
    .cascade-overlay .bottom-sheet.show {
        position: relative;
        bottom: auto;
        left: auto;
        right: auto;
        width: 100%;
        transform: none;            /* flex positions it; no transform → no iOS re-anchor */
        transition: none;
        max-height: 85vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: calc(16px + env(safe-area-inset-bottom));
        animation: cascadeFade 0.2s ease-out;
    }
    @keyframes cascadeFade { from { opacity: 0; } to { opacity: 1; } }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
    .cascade-overlay .bottom-sheet,
    .cascade-overlay .bottom-sheet.show { animation: none; }
}


/* ─── 2.46: Form-modal sub-classes for .bottom-sheet ──────────
   Title / submit / cancel / input utilities so dynamic form
   modals (project create, element create, inbox approve-all,
   etc.) can be built with the .bottom-sheet pattern. */
.bottom-sheet-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.6);
    z-index: 100;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}
.bottom-sheet-overlay.show { display: block; }
.bottom-sheet-title {
    font-size: 16px;
    font-weight: 600;
    color: #d4d4d4;
    margin-bottom: 12px;
}
.bottom-sheet input,
.bottom-sheet textarea,
.bottom-sheet select {
    width: 100%;
    background: #111e11;
    border: 1px solid #1a2e1a;
    border-radius: 8px;
    color: #d4d4d4;
    padding: 10px 12px;
    font-size: 16px; /* ≥16px required — iOS auto-zooms on focus if smaller */
    margin-bottom: 10px;
    box-sizing: border-box;
}
.bottom-sheet textarea { min-height: 80px; resize: vertical; }
.bottom-sheet-submit {
    width: 100%;
    background: var(--accent-purple);
    border: none;
    border-radius: 8px;
    color: white;
    padding: 12px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    margin-top: 4px;
}
.bottom-sheet-submit:disabled { opacity: 0.4; }
.bottom-sheet-cancel {
    width: 100%;
    background: none;
    border: 1px solid #1a2e1a;
    border-radius: 8px;
    color: #5a7a5a;
    padding: 10px;
    font-size: 14px;
    cursor: pointer;
    margin-top: 6px;
}

/* ─── 2.46: Generic outline button — small-borderless secondary action
   for inline action bars / batch toolbars. Inline width / padding /
   font-size overrides via style="" remain at call sites. */
.btn-outline-secondary {
    width: 100%;
    background: none;
    border: 1px solid #1a2e1a;
    border-radius: 8px;
    color: #5a7a5a;
    padding: 10px;
    font-size: 14px;
    cursor: pointer;
    margin-top: 6px;
}

/* ─── Route selection ─── */
.route-menu {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
}
.route-option {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.route-option:active { background: var(--bg-surface-alt); }
.route-option-title { font-size: 13px; color: var(--text-secondary); }
.route-option-subtitle { font-size: 11px; color: var(--text-muted); }
.route-option-chevron { color: var(--text-dim); font-size: 14px; }

/* ─── Maybe review-links (slice 7) — gentle, muted, end-of-feed ─── */
.maybe-review-zone {
    margin-top: 28px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    opacity: 0.85;
}
.maybe-review-header {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 8px;
}
.maybe-review-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 4px;
    min-height: 44px;
    box-sizing: border-box;
    text-decoration: none;
    border-bottom: 1px solid var(--border);
}
.maybe-review-row:last-child { border-bottom: none; }
.maybe-review-row:active:not(.maybe-review-static) { background: var(--bg-surface-alt); }
.maybe-review-static { cursor: default; }
.maybe-review-title { font-size: 13px; color: var(--text-secondary); }
.maybe-review-sub { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* ─── 2.96 A5: Weekly report card (in-feed item-type, D-021) ─── */
.report-card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-purple);
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    -webkit-tap-highlight-color: transparent;
}
.report-card.report-unread {
    border-left-color: var(--accent-purple-dim);
    box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25);
}
.report-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 14px 10px;
}
.report-unread-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--accent-purple);
    flex-shrink: 0;
}
.report-title {
    font-size: 15px;
    color: var(--text-primary);
}
.report-card.report-unread .report-title { font-weight: 600; }
.report-range {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 1px;
}

/* Section — collapsible (D-022 reverse-pyramid). Header taps toggle. */
.report-section { border-top: 1px solid var(--border); }
.report-section-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    min-height: 44px;
    box-sizing: border-box;
    cursor: pointer;
}
.report-section-header:active { background: var(--bg-surface-alt); }
.report-section-caret {
    font-size: 11px;
    color: var(--text-muted);
    width: 12px;
}
.report-section-title {
    flex: 1;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
}
.report-section-count {
    font-size: 11px;
    color: var(--text-muted);
    background: var(--border);
    border-radius: 8px;
    padding: 1px 7px;
}
.report-section-body { padding: 0 14px 10px; }
.report-section.collapsed .report-section-body { display: none; }

/* roll-up + health lines — read-only navigable rows (D-023/D-024) */
.report-line {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 0;
    min-height: 40px;
    box-sizing: border-box;
    border-bottom: 1px solid var(--border);
}
.report-line:last-child { border-bottom: none; }
.report-line--tappable { cursor: pointer; }
.report-line--tappable:active { background: var(--bg-surface-alt); }
.report-line-text { flex: 1; font-size: 13px; color: var(--text-secondary); }
.report-line-count {
    font-size: 11px;
    color: var(--text-muted);
    background: var(--border);
    border-radius: 8px;
    padding: 1px 7px;
}

/* new_discoveries accordion (D-103/D-105/D-127/D-129) — the count line expands to a
   tappable roster. The shared collapse caret marks expandability; the count chip
   carries the green accent so it reads as the tappable expand affordance, visually
   distinct from the neutral section caret/count (T-017). */
.report-collapse-caret {
    font-size: 11px;
    color: var(--text-muted);
    width: 12px;
    flex-shrink: 0;
}
.report-disc-header { min-height: 44px; }                 /* ≥44pt tap target (D-129) */
.report-disc-chip {
    color: var(--accent-green);
    background: #1a3a1a;
}
.report-disc-body { padding-left: 22px; }                 /* indent the roster under its line */
.report-disc.collapsed .report-disc-body { display: none; }

/* roster child row — indented, distinct surface, ≥44pt, three transient states
   (normal / loading / dead, D-128/D-129) */
.report-roster-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px;
    min-height: 44px;
    box-sizing: border-box;
    background: var(--bg-surface-alt);
    border-radius: 8px;
    margin: 4px 0;
    cursor: pointer;
}
.report-roster-item:active { background: var(--border); }
.report-roster-title { flex: 1; font-size: 13px; color: var(--text-primary); }
.report-roster-type {
    font-size: 10px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    flex-shrink: 0;
}
.report-roster-item--loading { opacity: 0.5; pointer-events: none; }
.report-roster-item--loading .report-roster-title::after { content: ' …'; color: var(--text-muted); }
.report-roster-item--dead { opacity: 0.6; cursor: default; pointer-events: none; }
.report-roster-item--dead .report-roster-title { color: var(--text-muted); font-style: italic; }
.report-roster-item--dead .route-option-chevron,
.report-roster-item--dead .report-roster-type { display: none; }

/* digests section (Unit C, D-104/D-111/D-112/D-138) — one collapsible accordion per
   consolidated contributor. Header mirrors .report-disc-header (shared caret, ≥44pt);
   body hidden when collapsed (T-036). */
.report-digest-header { min-height: 44px; }                 /* ≥44pt tap target */
.report-digest-body { padding-left: 22px; }                 /* indent prose+sources under header */
.report-digest.collapsed .report-digest-body { display: none; }

/* prose container — internal scroll cap so a long digest can't unbound the card
   (D-111/T-016). Canonical WKWebView inner-scroll set (iOS pitfall #2). */
.report-digest-prose {
    max-height: 320px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-secondary);
    padding: 4px 10px 4px 0;
}
.report-digest-prose p { margin: 0 0 8px; }
.report-digest-prose p:last-child { margin-bottom: 0; }
.report-digest-prose a { color: var(--accent-green); }
.report-digest-prose ul,
.report-digest-prose ol { margin: 0 0 8px; padding-left: 18px; }

/* source attribution rows — under the prose, inside the expanded body (D-138). Each is
   a label-link + Copy button; the link is visually distinct from prose and ≥44pt. */
.report-digest-sources {
    margin-top: 10px;
    border-top: 1px solid var(--border);
    padding-top: 8px;
}
.report-source-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 4px 0;
}
.report-source-link {
    flex: 1;
    font-size: 13px;
    color: var(--accent-green);
    text-decoration: none;
    cursor: pointer;
    word-break: break-word;
}
.report-source-link--plain { color: var(--text-muted); cursor: default; }
.report-source-link:active { opacity: 0.6; }
.report-source-copy {
    flex-shrink: 0;
    font-size: 11px;
    color: #9b7dcf;
    background: none;
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 6px 12px;
    min-height: 32px;
    cursor: pointer;
}

/* D-131/F-007: "Work in chat" action row under a digest's prose+sources, inside the
   expanded body (D-138). Visually distinct from the source rows — an accent-bordered
   button, ≥44pt — so it reads as an action, not another attribution link. */
.report-digest-actions {
    margin-top: 10px;
    border-top: 1px solid var(--border);
    padding-top: 10px;
    display: flex;
}
.report-digest-chat {
    min-height: 44px;
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 500;
    color: var(--accent-green);
    background: var(--bg-surface-alt);
    border: 1px solid var(--accent-green);
    border-radius: 8px;
    cursor: pointer;
}
.report-digest-chat:active { opacity: 0.6; }

.report-health-detail { font-size: 12px; color: var(--text-muted); }
.report-health-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--text-muted);
}
.report-health-dot--ok        { background: var(--accent-green); }
.report-health-dot--attention { background: var(--accent-amber); }
.report-health-dot--error     { background: var(--accent-red); }

/* "N source(s) unavailable" — graceful degradation line (D-015) */
.report-unavailable {
    font-size: 11px;
    color: var(--text-muted);
    padding: 8px 14px 12px;
    border-top: 1px solid var(--border);
}

/* empty/suppressed micro-state (D-026) */
.report-empty { border-left-color: var(--border); }
.report-empty-text {
    font-size: 13px;
    color: var(--text-muted);
    padding: 14px;
}

/* loading skeleton (T-032b) */
.report-skeleton { padding: 14px; border-left-color: var(--border); }
.report-skel-line {
    height: 12px;
    border-radius: 6px;
    background: var(--bg-surface-alt);
    margin-bottom: 10px;
    animation: report-skel-pulse 1.2s ease-in-out infinite;
}
.report-skel-line--head { width: 45%; height: 16px; }
.report-skel-line--short { width: 70%; margin-bottom: 0; }
@keyframes report-skel-pulse {
    0%, 100% { opacity: 0.5; }
    50%      { opacity: 0.9; }
}

.detail-title {
    font-size: 18px;
    font-weight: 500;
    color: var(--text-primary);
    margin-bottom: 8px;
}
.detail-meta {
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 12px;
}
.detail-body {
    font-size: 13px;
    color: var(--text-body);
    line-height: 1.5;
    margin-bottom: 12px;
}
.detail-take {
    background: var(--bg-surface);
    border-left: 3px solid var(--accent-purple);
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.5;
    margin-bottom: 16px;
}
.detail-take-label {
    font-size: 10px;
    color: var(--accent-purple-dim);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 4px;
}

/* ─── Toast ─── */
.toast {
    position: fixed;
    bottom: calc(var(--tab-bar-height) + 20px + env(safe-area-inset-bottom, 0px));
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 16px;
    font-size: 13px;
    color: var(--text-secondary);
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 200;
    pointer-events: none;
}
.toast.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
    pointer-events: auto;
}
.toast-note-link {
    color: var(--accent-purple-dim);
    margin-left: 8px;
    cursor: pointer;
}

/* ─── More tab ─── */
.more-section-label {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 8px;
    padding-left: 4px;
}
.more-group {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    margin-bottom: 16px;
    overflow: hidden;
}
.more-item {
    padding: 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    overflow: hidden;
}
.more-item:not(:last-child) { border-bottom: 1px solid var(--border); }
.more-item:active { background: var(--bg-surface-alt); }
.more-item-title { font-size: 14px; color: var(--text-secondary); flex-shrink: 0; }
.more-item-hint {
    font-size: 12px;
    color: var(--text-dim);
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
    flex-shrink: 1;
    min-width: 0;
}

/* ─── Utilities ─── */
.hidden { display: none !important; }
/* JS-toggled hidden state; !important wins over ID-selector rules (e.g. #projects-detail) */
.is-hidden { display: none !important; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.text-center { text-align: center; }
.empty-state {
    text-align: center;
    padding: 40px 20px;
    color: var(--text-muted);
    font-size: 13px;
}

/* ─── iPad responsive ─── */
@media (min-width: 768px) {
    .tab-bar { display: none; }

    #appShell {
        flex-direction: row;
    }
    #appShell.active {
        padding-bottom: 0;
    }

    .ipad-sidebar {
        display: flex;
        flex-direction: column;
        /* DS-5/T-022: narrowed 280→200 to give the projects detail more room.
           Just fits the "naveyn" brand + "Good evening, Shawn" greeting. */
        width: 200px;
        min-width: 200px;
        border-right: 1px solid var(--border);
        background: var(--bg-input);
        height: var(--app-height);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        flex-shrink: 0;
    }

    .ipad-sidebar-header {
        padding: 20px 16px 12px;
        border-bottom: 1px solid var(--border);
        flex-shrink: 0;
    }

    .ipad-sidebar-nav {
        padding: 8px;
        flex-shrink: 0;
    }

    .ipad-nav-item {
        padding: 10px 12px;
        border-radius: 10px;
        margin-bottom: 2px;
        font-size: 14px;
        color: var(--text-secondary);
        cursor: pointer;
        display: flex;
        justify-content: space-between;
        align-items: center;
        -webkit-tap-highlight-color: transparent;
    }
    .ipad-nav-item:active { background: var(--bg-surface); }
    .ipad-nav-item.active {
        background: var(--bg-surface);
        color: var(--accent-purple-dim);
    }

    .ipad-nav-label {
        font-size: 14px;
    }

    .ipad-nav-badge {
        display: none;
        min-width: 20px;
        height: 20px;
        padding: 0 6px;
        border-radius: 10px;
        background: var(--accent-purple);
        color: white;
        font-size: 11px;
        align-items: center;
        justify-content: center;
        font-weight: 500;
    }

    .ipad-sidebar-context {
        flex: 1;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .ipad-context-section {
        padding: 4px 0;
    }

    .ipad-context-label {
        font-size: 11px;
        color: var(--text-muted);
        text-transform: uppercase;
        letter-spacing: 1px;
        padding: 8px 16px 6px;
    }

    .ipad-context-item {
        padding: 10px 16px;
        cursor: pointer;
        border-bottom: 1px solid var(--border);
        -webkit-tap-highlight-color: transparent;
    }
    .ipad-context-item:active {
        background: var(--bg-surface);
    }
    .ipad-context-item:last-child {
        border-bottom: none;
    }
    .ipad-context-item-title {
        font-size: 13px;
        color: var(--text-secondary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .ipad-context-item-sub {
        font-size: 11px;
        color: var(--text-muted);
        margin-top: 2px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .ipad-content {
        flex: 1;
        display: flex;
        flex-direction: column;
        height: var(--app-height);
        overflow: hidden;
        min-width: 0;
    }
    .tab-content { flex: 1; }

    /* Give content more room on iPad but constrain for readability */
    .feed-card,
    .inbox-card,
    .list-item-card {
        max-width: 640px;
    }
    .batch-area,
    .tab-body {
        max-width: 700px;
    }
}

@media (max-width: 767px) {
    .ipad-sidebar { display: none !important; }
}

/* ─── Inbox — segmented control ─── */
.segment-control {
    display: flex;
    background: var(--bg-surface);
    margin: 10px 12px;
    border-radius: 8px;
    flex-shrink: 0;
}
.segment {
    flex: 1;
    text-align: center;
    padding: 8px;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 8px;
    -webkit-tap-highlight-color: transparent;
}
.segment.active {
    background: var(--accent-purple);
    color: white;
}
.segment-count {
    font-size: 10px;
    opacity: 0.8;
}

/* ─── Inbox segments ─── */
.inbox-segment {
    display: none;
}
.inbox-segment.active {
    display: block;
}
.inbox-segment-header {
    display: flex;
    justify-content: flex-end;
    padding: 6px 4px;
}

/* ─── Inbox detail view ─── */
/* Inherits flex/scroll from .tab-body; the extra padding-bottom keeps the
   last row of buttons visible above the fixed tab bar. */
#inbox-detail {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    min-height: 0;
    padding-bottom: 70px;
}

/* ─── Inbox cards ─── */
.inbox-card {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    margin-bottom: 10px;
    overflow: hidden;
}
.inbox-card-body {
    padding: 14px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.inbox-card-body:active {
    background: var(--bg-surface-alt);
}
.inbox-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}
.inbox-card-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    flex: 1;
    margin-right: 8px;
}
.inbox-card-meta {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 3px;
}
.inbox-card-inference {
    font-size: 12px;
    color: var(--accent-purple-dim);
    margin-top: 8px;
    font-style: italic;
}
.inbox-card-actions {
    display: flex;
    gap: 6px;
    padding: 8px 14px 14px;
}
.inbox-btn {
    flex: 1;  /* box-model + :active now on base .btn (2.94) */
}
.inbox-btn.primary {
    background: var(--action-primary-bg);
    color: var(--action-primary-fg);
}
.inbox-btn.blue {
    background: var(--action-info-bg);
    color: var(--action-info-fg);
}
.inbox-btn.purple {
    background: var(--action-work-bg);
    color: var(--action-work-fg);
}
.inbox-btn.green {
    background: var(--action-approve-bg);
    color: var(--action-approve-fg);
}
.inbox-btn.yellow {
    background: var(--action-route-bg);
    border: 1px solid var(--action-route-border);
    color: var(--action-route-fg);
}
.inbox-btn.danger {
    background: var(--action-dismiss-bg);
    border: 1px solid var(--action-dismiss-border);
    color: var(--action-dismiss-fg);
}
.inbox-btn.muted {
    background: var(--action-pass-bg);
    border: 1px solid var(--action-pass-border);
    color: var(--action-pass-fg);
}

/* Stacked action buttons in detail view should be full-width. */
.detail-actions .inbox-btn {
    flex: none;
    width: 100%;
    padding: 12px;
    font-size: 13px;
}

/* ─── Inbox detail action grid (flattened — 6 actions uniform smaller height) ─── */
.inbox-detail-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 16px;
}

/* ─── Category badge ─── */
.category-badge {
    background: var(--border);
    font-size: 10px;
    padding: 2px 7px;
    border-radius: 6px;
    color: var(--accent-purple-dim);
    white-space: nowrap;
}

/* ─── Processed items ─── */
.processed-card {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    padding: 14px;
    margin-bottom: 8px;
}
.processed-status {
    font-size: 10px;
    padding: 2px 7px;
    border-radius: 6px;
}
.processed-status.approved {
    background: #1a3a1a;
    color: var(--accent-green);
}
.processed-status.dismissed {
    background: var(--border);
    color: var(--text-muted);
}

/* ─── Detail view action list ─── */
.detail-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 16px;
}
.detail-action-btn {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
}
.detail-action-btn:active {
    background: var(--bg-surface-alt);
}
.detail-action-title {
    font-size: 13px;
    color: var(--text-secondary);
}
.detail-action-subtitle {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ─── Summary box ─── */
.summary-box {
    background: var(--bg-surface);
    border-radius: 10px;
    border: 1px solid var(--border);
    padding: 12px;
    margin-top: 12px;
    font-size: 13px;
    color: var(--text-body);
    line-height: 1.5;
}

/* ─── Lists ─── */
.list-type-card {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    margin-bottom: 8px;
    padding: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.list-type-card:active {
    background: var(--bg-surface-alt);
}
.list-type-name {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-secondary);
}
.list-type-count {
    font-size: 13px;
    color: var(--text-muted);
}

.list-item-card {
    background: var(--bg-surface);
    border-radius: 12px;
    border: 1px solid var(--border);
    margin-bottom: 8px;
    overflow: hidden;
}
.list-item-body {
    padding: 14px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.list-item-body:active {
    background: var(--bg-surface-alt);
}
.list-item-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
}
.list-item-fields {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 4px;
}
.list-item-status {
    font-size: 10px;
    padding: 2px 7px;
    border-radius: 6px;
    white-space: nowrap;
}
.list-item-status.to-try,
.list-item-status.to-read,
.list-item-status.new {
    background: #1a3a1a;
    color: var(--accent-green);
}
.list-item-status.visited,
.list-item-status.read,
.list-item-status.watched,
.list-item-status.done {
    background: var(--border);
    color: var(--text-muted);
}
.list-item-status.reading,
.list-item-status.in-progress,
.list-item-status.watching {
    background: #1a1a3a;
    color: #60a5fa;
}

.list-detail-field {
    display: flex;
    justify-content: space-between;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}
.list-detail-field-label {
    color: var(--text-muted);
}
.list-detail-field-value {
    color: var(--text-secondary);
    text-align: right;
    max-width: 60%;
}

.status-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 12px;
}
.status-option {
    padding: 8px 14px;
    border-radius: 8px;
    font-size: 12px;
    border: 1px solid var(--border);
    background: var(--bg-primary);
    color: var(--text-muted);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.status-option:active {
    background: var(--bg-surface);
}
.status-option.active {
    background: var(--accent-purple);
    border-color: var(--accent-purple);
    color: white;
}

/* ─── Chat tab ─── */
/* Chat uses a simple flex column. Keyboard is handled by Capacitor
   native Keyboard events which set --keyboard-height on :root; the
   .chat-keyboard-spacer at the bottom of .chat-main grows by that
   amount to push the input above the soft keyboard. */
.chat-main {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* Pin the chat header so it doesn't scroll with messages when the
   keyboard spacer grows. flex-shrink: 0 is defensive in case the
   parent gets squeezed. */
.chat-main > .tab-header {
    flex-shrink: 0;
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--bg-primary);
}

.chat-messages {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.chat-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: 1;
    color: var(--text-muted);
}
.chat-empty-dot {
    font-size: 24px;
    color: var(--accent-purple);
    margin-bottom: 8px;
}
.chat-empty-text {
    font-size: 14px;
}

/* ─── Chat messages ─── */
.chat-msg {
    max-width: 88%;
    font-size: 14px;
    line-height: 1.55;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
.chat-msg.user {
    align-self: flex-end;
    background: var(--accent-purple);
    color: white;
    padding: 10px 14px;
    border-radius: 16px 16px 4px 16px;
    white-space: pre-wrap;
}
.chat-msg.assistant {
    align-self: flex-start;
    background: var(--bg-surface);
    color: var(--text-primary);
    padding: 10px 14px;
    border-radius: 16px 16px 16px 4px;
    border: 1px solid var(--border);
}
.chat-msg.assistant p { margin: 0 0 8px 0; }
.chat-msg.assistant p:last-child { margin-bottom: 0; }
.chat-msg.assistant h3 {
    font-size: 14px;
    font-weight: 600;
    margin: 12px 0 4px 0;
    color: var(--text-secondary);
}
.chat-msg.assistant h4 {
    font-size: 13px;
    font-weight: 600;
    margin: 10px 0 4px 0;
    color: var(--text-secondary);
}
.chat-msg.assistant ul,
.chat-msg.assistant ol {
    margin: 4px 0 8px 0;
    padding-left: 20px;
}
.chat-msg.assistant li { margin-bottom: 4px; }
.chat-msg.assistant pre {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    overflow-x: auto;
    font-size: 12px;
    margin: 8px 0;
}
.chat-msg.assistant code {
    font-family: 'SF Mono', 'Menlo', monospace;
    font-size: 12px;
}
.chat-msg.assistant code:not(pre code) {
    background: var(--bg-input);
    padding: 2px 5px;
    border-radius: 4px;
    border: 1px solid var(--border);
}
.chat-msg.assistant blockquote {
    border-left: 3px solid var(--accent-purple);
    padding-left: 10px;
    margin: 8px 0;
    color: var(--text-muted);
}
.chat-msg.assistant strong { color: var(--text-secondary); }
.chat-msg.assistant hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: 12px 0;
}
.chat-msg.assistant .naveyn-sig {
    color: var(--accent-purple);
    font-style: italic;
}
.chat-msg.assistant table,
.proj-chat-msg.assistant table,
.element-chat-msg.assistant table {
    border-collapse: collapse;
    margin: 10px 0;
    font-size: 13px;
    width: 100%;
    display: block;
    overflow-x: auto;
}
.chat-msg.assistant th,
.chat-msg.assistant td,
.proj-chat-msg.assistant th,
.proj-chat-msg.assistant td,
.element-chat-msg.assistant th,
.element-chat-msg.assistant td {
    border: 1px solid var(--border);
    padding: 6px 10px;
    text-align: left;
}
.chat-msg.assistant th,
.proj-chat-msg.assistant th,
.element-chat-msg.assistant th {
    background: var(--bg-surface-alt);
    color: var(--text-secondary);
    font-weight: 600;
}
.chat-msg.assistant tbody tr:nth-child(even),
.proj-chat-msg.assistant tbody tr:nth-child(even),
.element-chat-msg.assistant tbody tr:nth-child(even) {
    background: var(--bg-surface-alt);
}
.chat-msg.error {
    align-self: center;
    color: var(--accent-red);
    font-size: 12px;
    padding: 6px 12px;
    background: rgba(239, 68, 68, 0.1);
    border-radius: 8px;
}

/* ─── Chat feedback buttons ─── */
.chat-feedback-row {
    display: flex;
    gap: 4px;
    margin-top: 8px;
    opacity: 0.4;
    transition: opacity 0.15s;
}
.chat-msg.assistant:hover .chat-feedback-row,
.chat-msg.assistant:active .chat-feedback-row,
.chat-feedback-row.voted {
    opacity: 1;
}
.chat-fb-btn {
    background: none;
    border: 1px solid transparent;
    border-radius: 4px;
    padding: 2px 6px;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 14px;
    color: var(--text-muted);
    transition: all 0.15s;
    line-height: 1;
    -webkit-tap-highlight-color: transparent;
}
.chat-fb-btn:active {
    opacity: 0.7;
}
.chat-fb-btn.voted {
    color: var(--accent-purple);
    border-color: var(--accent-purple);
}
.chat-fb-btn.voted-other {
    opacity: 0.3;
}

/* ─── Chat input area ─── */
/* Keyboard closed: 10px normal padding.
   Keyboard open: the keyboardWillShow handler sets --keyboard-offset to
   (e.keyboardHeight + 60px) — the +60 covers the iOS predictive-text
   bar plus a small cushion that Capacitor's reported height omits.
   Growing padding-bottom makes the input element itself taller, which
   shrinks the flex:1 .chat-messages above and keeps the textarea and
   send button visible above the keyboard. */
/* ─── Inbox context pill (Sprint 1.36 Phase 1) ─── */
/* Sits above .chat-input-area; toggled by chat.js setPendingInboxContext /
   clearPendingInboxContext. Inline display:none in the HTML keeps it
   collapsed on first paint; JS swaps to display:flex when an inbox link
   is attached to the next message. */
.inbox-context-pill {
    flex-shrink: 0;
    display: none;
    align-items: center;
    gap: 8px;
    margin: 0 12px 4px;
    padding: 6px 6px 6px 12px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--bg-surface);
    font-size: 12px;
    color: var(--text-body);
    line-height: 1.3;
}
.inbox-context-pill-label {
    flex-shrink: 0;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 10px;
    font-weight: 600;
}
.inbox-context-pill-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--accent-purple-dim);
    font-weight: 500;
}
.inbox-context-pill-dismiss {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    min-width: 32px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    border-radius: 50%;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-tap-highlight-color: transparent;
}
.inbox-context-pill-dismiss:hover,
.inbox-context-pill-dismiss:active {
    background: var(--bg-primary);
    color: var(--text-primary);
}

/* Sprint 1.36 follow-up: persistent jump-back banner pinned below the chat
   header. flex-shrink:0 so it never scrolls with messages. Tap → reopen the
   originating inbox item. Carries the FULL item name (the sidebar/history
   title truncates), so long to-do titles stay identifiable. */
.chat-inbox-source {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-surface);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.chat-inbox-source:active {
    background: var(--bg-primary);
}
.chat-inbox-source-icon {
    flex-shrink: 0;
    color: var(--accent-purple-dim);
    font-size: 13px;
}
.chat-inbox-source-label {
    flex-shrink: 0;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 10px;
    font-weight: 600;
}
.chat-inbox-source-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--accent-purple-dim);
    font-size: 13px;
    font-weight: 500;
}
/* F-M4: global-scope variant — non-tappable, muted (no purple accent). */
.chat-inbox-source.chat-scope-global {
    cursor: default;
}
.chat-inbox-source.chat-scope-global:active {
    background: var(--bg-surface);
}
.chat-inbox-source.chat-scope-global .chat-inbox-source-icon,
.chat-inbox-source.chat-scope-global .chat-inbox-source-title {
    color: var(--text-muted);
}
/* F-M4: pending-attach variant — purple (active scope) but non-tappable, since
   the next message will carry this item; mirrors the "Working on:" pill. */
.chat-inbox-source.chat-scope-pending {
    cursor: default;
}
.chat-inbox-source.chat-scope-pending:active {
    background: var(--bg-surface);
}

.chat-input-area {
    flex-shrink: 0;
    padding: 8px 12px 10px;
    padding-bottom: calc(10px + var(--keyboard-offset, 0px));
    border-top: 1px solid var(--border);
    background: var(--bg-primary);
}
.chat-input-wrapper {
    display: flex;
    align-items: flex-end;
    gap: 8px;
}
.chat-input-wrapper textarea {
    flex: 1;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 10px 14px;
    color: var(--text-primary);
    font-size: 16px; /* prevents iOS zoom */
    font-family: inherit;
    resize: none;
    outline: none;
    min-height: 40px;
    max-height: 120px;
    line-height: 1.4;
    transition: border-color 0.15s;
}
.chat-input-wrapper textarea:focus {
    border-color: var(--accent-purple);
}
.chat-input-wrapper textarea::placeholder {
    color: var(--text-muted);
}
.chat-send-btn {
    background: var(--accent-purple);
    border: none;
    border-radius: 50%;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: opacity 0.15s;
    -webkit-tap-highlight-color: transparent;
}
.chat-send-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.chat-send-btn svg { width: 16px; height: 16px; fill: white; }

/* ─── Typing indicator ─── */
.chat-typing {
    flex-shrink: 0;
    display: none;
    align-items: center;
    gap: 4px;
    padding: 4px 14px 8px;
    font-size: 12px;
    color: var(--text-muted);
    background: var(--bg-primary);
}
.chat-typing.active { display: flex; }
.typing-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-purple);
    animation: typingPulse 1.2s ease-in-out infinite;
}
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
.typing-dot:nth-child(3) { animation-delay: 0.4s; }
.typing-label {
    margin-left: 6px;
    font-style: italic;
}
@keyframes typingPulse {
    0%, 100% { opacity: 0.3; transform: scale(0.8); }
    50% { opacity: 1; transform: scale(1); }
}

/* ─── Quick reply buttons ─── */
.chat-quick-replies {
    display: flex;
    gap: 8px;
    padding: 4px 0 0;
    align-self: flex-start;
}
.chat-quick-replies button {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 12px;
    padding: 6px 14px;
    border-radius: 16px;
    cursor: pointer;
    transition: all 0.15s;
    -webkit-tap-highlight-color: transparent;
}
.chat-quick-replies button:active {
    background: var(--accent-purple);
    color: white;
    border-color: var(--accent-purple);
}

/* ─── Header buttons (small) ─── */
.header-btn-sm {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 11px;
    padding: 4px 10px;
    border-radius: 6px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.header-btn-sm:active {
    background: var(--bg-surface-alt);
}

/* ─── Chat history screen (within tab) ─── */
/* Visible state; hidden state via .is-hidden utility on the element. */
#chat-history-screen {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    width: 100%;
}
.chat-session-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 4px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.chat-session-item:active {
    background: var(--bg-surface-alt);
}
.chat-session-item-info { flex: 1; min-width: 0; }
.chat-session-title {
    font-size: 14px;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.chat-session-title.active-session {
    color: var(--accent-purple);
}
/* 1.36 #6: iPad sidebar active-session indicator — mirrors the history
   modal's .chat-session-title.active-session purple cue (F-008). */
.ipad-context-item-title.active-session {
    color: var(--accent-purple);
    font-weight: 600;
}
.ipad-context-item.active-session {
    border-left: 2px solid var(--accent-purple);
}
.chat-session-time {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
}
/* Multi-select action bar — appears at the top of the session list
   once at least one checkbox is ticked. */
.chat-select-bar {
    display: none;
    align-items: center;
    justify-content: space-between;
    padding: 8px 4px;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
    color: var(--text-muted);
    position: sticky;
    top: 0;
    background: var(--bg-primary);
    z-index: 5;
}

.chat-history-search-wrap {
    position: sticky;
    top: 0;
    background: var(--bg-primary);
    z-index: 4;
    padding: 8px 4px;
    display: flex;
    align-items: center;
    gap: 4px;
}
.chat-history-search-input {
    flex: 1;
    padding: 10px 12px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text-primary);
    outline: none;
}
.chat-history-search-input:focus { border-color: var(--border-hover); }
.chat-history-search-clear {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 22px;
    padding: 4px 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
}
.chat-history-search-clear:active { opacity: 0.6; }

.chat-session-check {
    width: 18px;
    height: 18px;
    margin-right: 10px;
    flex-shrink: 0;
    accent-color: var(--accent-purple);
}

.chat-session-delete {
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 14px;
    padding: 8px;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

/* ─── PROJECTS ─────────────────────────────────────── */

/* Project screen containers — flex column so scroll body can flex:1 */
#projects-list,
#projects-detail,
#projects-staging,
#projects-element,
#projects-chat {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* Scrollable body — mirrors .tab-body for iOS momentum scrolling */
.projects-scroll-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    padding-bottom: var(--safe-bottom-pad);
}

/* Reduce tab label font to fit 5 tabs on narrow screens */
@media (max-width: 400px) {
    .tab-bar-label { font-size: 9px; }
}

/* Project list header */
.projects-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px 8px;
}
.projects-header-title {
    font-family: 'Palatino Linotype', 'Palatino', Georgia, serif;
    font-size: 18px;
    font-weight: 600;
    color: var(--text-secondary);
}
.projects-header-btn {
    width: 32px; height: 32px;
    border-radius: 50%;
    border: 1.5px solid var(--accent-purple);
    color: var(--accent-purple);
    background: none;
    font-size: 18px;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

/* Project list cards */
.project-card {
    background: #111e11;
    border: 1px solid #1a2e1a;
    border-radius: 12px;
    padding: 16px;
    margin: 0 16px 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.project-card:active { background: #152015; }
.project-card .project-title {
    font-size: 16px;
    font-weight: 600;
    color: #d4d4d4;
    margin-bottom: 4px;
}
.project-card .project-goal {
    font-size: 13px;
    color: #5a7a5a;
    margin-bottom: 10px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.project-card .project-meta {
    display: flex;
    gap: 12px;
    font-size: 11px;
    color: #3d5a3d;
}
.project-meta-staging {
    color: var(--accent-purple) !important;
    font-weight: 600;
}

/* Project detail header */
.project-detail-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px 6px;
}
.project-back-btn {
    background: none; border: none; color: var(--accent-purple);
    font-size: 18px; cursor: pointer; padding: 4px;
    -webkit-tap-highlight-color: transparent;
}
.project-detail-title {
    flex: 1;
    font-family: 'Palatino Linotype', 'Palatino', Georgia, serif;
    font-size: 17px; font-weight: 600; color: #d4d4d4;
}
.project-detail-goal {
    padding: 0 16px 8px;
    font-size: 12px; color: #5a7a5a;
}

/* Element tree items */
.element-row {
    padding: 12px 16px;
    border-bottom: 1px solid #1a2e1a;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
    -webkit-tap-highlight-color: transparent;
}
.element-row:active { background: #152015; }
.element-row .element-title {
    flex: 1;
    font-size: 14px;
    color: #d4d4d4;
}
.element-row .element-count {
    font-size: 11px;
    color: #3d5a3d;
    min-width: 50px;
    text-align: right;
}
/* Accordion collapse for element children */
.element-children.collapsed { display: none; }
.el-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: -12px -8px -12px -8px; /* expand touch target without affecting layout */
    font-size: 18px;
    color: #5a7a5a;
    flex-shrink: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.el-toggle-spacer {
    width: 24px;
    flex-shrink: 0;
}
.element-row.staging {
    border-bottom: 2px solid #1a2e1a;
    color: #9b7dcf;
}
.element-row.staging .element-title { color: #9b7dcf; }

/* Element status pills */
.el-status {
    font-size: 10px;
    padding: 2px 8px;
    border-radius: 6px;
    display: inline-block;
    font-weight: 600;
}
.el-status-draft { background: #1a2e1a; color: #4ade80; }
.el-status-developing { background: #2a2a1a; color: #fbbf24; }
.el-status-mature { background: #1a1a2a; color: #818cf8; }
.el-status-final { background: #1a2a2a; color: #22d3ee; }

/* Element content / synthesis section */
.el-content-section {
    padding: 8px 16px;
    border-bottom: 1px solid #1a2e1a;
    flex-shrink: 0;
    max-height: 120px;
    overflow-y: auto;
}
.el-content-label {
    font-size: 10px;
    color: #5a7a5a;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 4px;
}
.el-content-text {
    font-size: 13px;
    color: #d4d4d4;
    line-height: 1.5;
    cursor: pointer;
}

/* Element detail — chat-first layout */
.element-chat-container {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: 0;          /* WKWebView flex fallback — min-height:0 alone doesn't collapse */
    overflow: hidden;
}
.element-header-card {
    padding: 12px 16px;
    background: #111e11;
    border-bottom: 1px solid #1a2e1a;
    flex-shrink: 0;
}
.element-header-card .el-title {
    font-size: 16px;
    font-weight: 600;
    color: #d4d4d4;
}

/* Evidence drawer (iPhone: overlay; iPad: persistent panel) */
.evidence-drawer {
    position: fixed;
    bottom: var(--tab-bar-height, 56px);
    left: 0;
    right: 0;
    background: #0f170f;
    border-top: 1px solid #1a2e1a;
    border-radius: 16px 16px 0 0;
    max-height: 60vh;
    transform: translateY(100%);
    transition: transform 0.3s ease;
    z-index: 50;
    display: flex;
    flex-direction: column;
}
.evidence-drawer.open { transform: translateY(0); }
.evidence-drawer-handle {
    width: 36px;
    height: 4px;
    background: #3d5a3d;
    border-radius: 2px;
    margin: 8px auto;
    flex-shrink: 0;
}
.evidence-drawer-header {
    padding: 8px 16px 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}
.evidence-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 0 16px 16px;
    -webkit-overflow-scrolling: touch;
}

/* Evidence cards */
.evidence-card {
    background: #111e11;
    border: 1px solid #1a2e1a;
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 8px;
}
.evidence-card .ev-content {
    font-size: 13px;
    color: #d4d4d4;
    line-height: 1.5;
}
.evidence-card .ev-origin {
    font-size: 11px;
    color: #3d5a3d;
    margin-top: 6px;
}
.evidence-card .ev-rel {
    display: inline-block;
    font-size: 10px;
    padding: 1px 6px;
    border-radius: 4px;
    margin-right: 4px;
    font-weight: 600;
}
.ev-rel-supports { background: #1a2e1a; color: #4ade80; }
.ev-rel-contradicts { background: #2e1a1a; color: #f87171; }
.ev-rel-qualifies { background: #2a2a1a; color: #fbbf24; }
.ev-rel-extends { background: #1a1a2e; color: #818cf8; }
.ev-rel-inspires { background: #2e1a2e; color: #c084fc; }

/* ─── Segmented control (Chat/Evidence toggle) ─── */
.proj-segment-control {
    display: flex;
    background: #111e11;
    border-radius: 8px;
    padding: 2px;
    margin: 8px 12px;
    flex-shrink: 0;
}
.proj-segment-btn {
    flex: 1;
    padding: 8px 0;
    border: none;
    background: transparent;
    font-size: 14px;
    font-weight: 500;
    color: #5a7a5a;
    border-radius: 6px;
    cursor: pointer;
    text-align: center;
    transition: background 0.2s, color 0.2s;
}
.proj-segment-btn.active {
    background: #1a2e1a;
    color: #d4d4d4;
    font-weight: 600;
}
/* iPad: segment control stays visible (same as iPhone, just larger) */

/* ─── Evidence panel (replaces drawer on iPhone) ─── */
.evidence-panel {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* DS-5: keep the 📷 / + / Select group from crowding the "N datapoints" label
   in the evidence-panel header on narrow iPad panels (landscape 340px / ≥1200
   380px). The header is inline-styled display:flex with no flex-wrap, so add it
   here — the button group drops to a second line instead of overflowing. */
.evidence-panel-header {
    flex-wrap: wrap;
    gap: 6px;
}

/* ─── Evidence relationship groups ─── */
.evidence-group-header {
    font-size: 13px;
    font-weight: 600;
    color: #5a7a5a;
    padding: 12px 0 4px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
}
.evidence-group-header .count {
    font-weight: 400;
    color: #3d5a3d;
    font-size: 12px;
}
.evidence-group.collapsed .evidence-group-items {
    display: none;
}

/* ─── Multi-select ─── */
.proj-select-mode .select-checkbox {
    display: flex;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 2px solid #3d5a3d;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 12px;
    color: white;
    cursor: pointer;
}
.proj-select-mode .select-checkbox.checked {
    background: #4a7a4a;
    border-color: #4a7a4a;
}
.proj-action-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: #0f170f;
    border-top: 1px solid #1a2e1a;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    display: flex;
    justify-content: space-between;
    align-items: center;
    z-index: 100;
    font-size: 13px;
    color: #d4d4d4;
}
body.keyboard-open .proj-action-bar { display: none !important; }
/* Managed select-bars (Inbox / To-Dos) live on the #tab-inbox TAB screen, where
   the bottom tab bar stays visible. The shared .proj-action-bar sits at bottom:0
   (z-index 100) and so renders its opaque background OVER the tab bar (z-index 50).
   Raise these two to sit flush ABOVE the tab bar. The tab bar is fixed at bottom:0
   with NO safe-area padding, so its real rendered height (~64px — see #appShell.active
   above: --tab-bar-height(56px) under-reserves by 8px, 64px is device-verified) already
   spans the home-indicator zone; we do NOT add env(safe-area-inset-bottom) on top or
   the bar floats ~26px too high. +10px (= ~66px) matches the REAL rendered tab-bar
   height measured in the browser pre-verify (Chromium 390×844: tab bar = 66px; var
   under-reserves by ~10px). A tiny gap is strictly safer than the overlap this fixes,
   so we round UP to the measured height rather than down to the 64px appShell literal.
   Flat 12px bottom padding (the shared rule's safe-area bottom-padding would now sit
   above the tab bar and just inflate the bar). The EXTERNAL projects bars keep the
   bare .proj-action-bar rule (out of scope this sprint). POLISH #1.
   NOTE for device pass: bar shows only when ≥1 selected; in select mode it now covers
   the bottom ~17px of the last row (scroll pad is 102px, bar bottom is 66px). If that
   reachability gap is noticeable on-device, file the per-segment select-pad as a chip
   (mirror projects' .proj-select-pad) rather than reworking this rule. */
#inbox-select-action-bar,
#todos-select-action-bar {
    bottom: calc(var(--tab-bar-height, 56px) + 10px);
    padding-bottom: 12px;
}
/* Select mode: clear the fixed action bar so the last project card stays
   reachable in both portrait (action bar overlays tab bar) and landscape
   (sidebar nav, --safe-bottom-pad ≈ 12px). */
.projects-scroll-body.proj-select-pad {
    padding-bottom: calc(96px + env(safe-area-inset-bottom, 34px));
}

/* ─── Pushback border (challenge tier) ─── */
.chat-pushback-border {
    border-left: 3px solid #fbbf24 !important;
}

/* ─── Zero-evidence badge ─── */
.el-zero-badge {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #d4a574;
    opacity: 0.7;
    display: inline-block;
    margin-left: 4px;
    vertical-align: middle;
}

/* ─── Notes indicator + editing ─── */
.dp-notes-indicator {
    font-size: 12px;
    margin-left: 4px;
    opacity: 0.6;
}
.ev-notes-section {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #1a2e1a;
}
.ev-notes-input {
    width: 100%;
    background: #0a120a;
    border: 1px solid #1a2e1a;
    border-radius: 6px;
    color: #d4d4d4;
    font-size: 16px; /* prevents iOS zoom */
    padding: 8px;
    resize: vertical;
    min-height: 40px;
    max-height: 120px;
    font-family: inherit;
}
.ev-notes-input:focus {
    outline: none;
    border-color: #3d5a3d;
}

/* Chat area within element detail */
.element-chat-messages {
    flex: 1;
    min-height: 0;
    height: 0;          /* WKWebView flex fallback */
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px 16px;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.element-chat-input-bar {
    padding: 8px 12px;
    border-top: 1px solid #1a2e1a;
    display: flex;
    gap: 8px;
    align-items: flex-end;
    flex-shrink: 0;
    background: #0d1a0d;
    /* Bug 3 (2026-05-17 real-device): the element-chat flex column is
       --app-height (100vh) tall; with only keyboard-offset clearance the
       input bar sat at the very bottom, occluded behind the fixed 56px
       tab bar + ~34px home indicator when the keyboard was closed (user
       saw the "Start a conversation…" placeholder but NO input box).
       Reuse the project's own tab-bar+safe-area constant
       (--safe-bottom-pad ≈ 102px) when the keyboard is closed; when it
       opens the tab bar auto-hides (body.keyboard-open) and the keyboard
       offset (larger) wins via max(). Single declaration, no JS. */
    padding-bottom: calc(8px + max(var(--keyboard-offset, 0px), var(--safe-bottom-pad)));
}
.element-chat-input-bar textarea {
    flex: 1;
    background: #111e11;
    border: 1px solid #1a2e1a;
    border-radius: 8px;
    color: #d4d4d4;
    padding: 8px 12px;
    font-size: 14px;
    resize: none;
    min-height: 36px;
    max-height: 120px;
}
.element-chat-input-bar button {
    background: var(--accent-purple);
    border: none;
    border-radius: 50%;
    width: 36px; height: 36px;
    color: white;
    font-size: 16px;
    cursor: pointer;
    flex-shrink: 0;
}
.element-chat-input-bar button:disabled {
    opacity: 0.4;
    cursor: default;
}

/* Chat bubbles (reuse from main chat, element-scoped) */
.proj-chat-msg {
    margin-bottom: 12px;
    max-width: 90%;
}
.proj-chat-msg.user {
    margin-left: auto;
    background: var(--accent-purple);
    color: white;
    padding: 10px 14px;
    border-radius: 16px 16px 4px 16px;
    font-size: 14px;
    line-height: 1.5;
}
.proj-chat-msg.assistant {
    background: #111e11;
    border: 1px solid #1a2e1a;
    padding: 10px 14px;
    border-radius: 16px 16px 16px 4px;
    font-size: 14px;
    color: #d4d4d4;
    line-height: 1.5;
}

/* Staging suggestion pill */
.suggest-pill {
    display: inline-block;
    padding: 4px 10px;
    font-size: 11px;
    border-radius: 12px;
    background: #1a1a2e;
    color: #818cf8;
    cursor: pointer;
    margin-top: 6px;
    -webkit-tap-highlight-color: transparent;
}
.suggest-pill:active { background: #252542; }

/* Keyboard-open backstop: hide tab bar via CSS class (JS also hides it) */
body.keyboard-open .tab-bar { display: none !important; }
/* Normal-state restore: static rule wins regardless of inline JS adjudication.
   DS-5: scoped to phones — at ≥768px the iPad sidebar is the nav and the bar
   stays hidden (@media min-width:768px .tab-bar{display:none}). This rule's
   higher specificity (0,0,2,1) was unconditionally re-showing the bar on iPad. */
@media (max-width: 767px) {
    body:not(.keyboard-open) .tab-bar { display: flex; }
}

/* Empty states */
.projects-empty {
    text-align: center;
    padding: 60px 20px;
    color: #5a7a5a;
    font-size: 14px;
}

/* iPad: side-by-side layout for project detail */
@media (min-width: 768px) {
    .project-split-layout {
        display: flex;
        height: calc(100vh - 60px);
    }
    .project-split-tree {
        width: 300px;
        flex-shrink: 0;
        border-right: 1px solid #1a2e1a;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
    .project-split-content {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }
    /* Evidence drawer becomes persistent side panel on iPad */
    .evidence-drawer {
        position: relative;
        bottom: auto;
        border-radius: 0;
        max-height: none;
        transform: none;
        border-top: none;
        border-left: 1px solid #1a2e1a;
        width: 320px;
        flex-shrink: 0;
        z-index: auto;
    }
    .evidence-drawer.open { transform: none; }
}

/* ─── Cycle 2: iPad Three-Panel Layout ────────────────────── */

/* Wrapper for chat + evidence panels (flex-row on iPad) */
.el-panels-wrap {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: 0;  /* WKWebView flex child shrink fix */
    overflow: hidden;
}

@media (min-width: 768px) {
    /* DS-5/T-022: project detail is a vertical document (header → goal →
       brief → element tree) in BOTH orientations. Elements open in a SEPARATE
       #projects-element screen, so #projects-detail has NO right-hand content
       panel — the prior flex-direction:row spread goal/brief/tree horizontally
       and clipped the Project Brief, and display:none on the header removed the
       back button plus the add-element / chat / matrix / more actions. Keep it
       a column with a visible header and a full-width scrolling tree. */
    #projects-detail {
        flex-direction: column !important;
    }
    #projects-detail .projects-scroll-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
}

/* DS-5/T-022: element detail (chat + evidence) is side-by-side ONLY in
   LANDSCAPE, where there's room. In PORTRAIT (narrow) the el-panels-wrap falls
   back to the base column layout + the iPhone Chat/Evidence segment toggle
   (#el-segment stays visible, evidence-panel keeps its inline display:none
   until _switchElSegment shows it) — a single active panel, per the approved
   model. This also fixes the LANDSCAPE glitch where the chat panel collapsed
   to height:0 (the base height:0 is a column main-axis fallback; in this row
   cross-axis it defeated align-items:stretch, leaving only the evidence panel
   floating with a large empty area). */
/* 2.95 / D-005: also fire for ANY desktop (pointer:fine) regardless of orientation, so a
   tall/narrow tiled desktop window keeps the row split instead of collapsing to the phone
   single-panel + segment toggle. Touch iPad (pointer:coarse) still keys off physical landscape. */
@media (min-width: 768px) and (orientation: landscape),
       (min-width: 768px) and (pointer: fine) {
    .el-panels-wrap {
        flex-direction: row;
    }
    #el-segment {
        display: none !important;
    }
    .el-panels-wrap .element-chat-container {
        flex: 1;
        min-width: 0;
        height: auto;   /* override base height:0 so the chat fills the row
                           cross-axis instead of collapsing to 0 */
        display: flex !important; /* Override any inline display:none */
        border-right: 1px solid #1a2e1a;
    }
    .el-panels-wrap .evidence-panel {
        display: flex !important; /* Override inline display:none */
        flex-direction: column;
        width: 340px;
        min-width: 280px;
        max-width: 400px;
        flex-shrink: 0;
        overflow: hidden;
    }
    .el-panels-wrap .evidence-panel .projects-scroll-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
    .el-panels-wrap .element-chat-messages {
        flex: 1;
        min-height: 0;
        height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
}

/* Ensure graceful degradation below 768px */
@media (max-width: 767px) {
    .el-panels-wrap {
        flex-direction: column;
    }
    /* Segment toggle controls visibility on phone */
    .el-panels-wrap .evidence-panel {
        /* Controlled by _switchElSegment JS */
    }
}

/* ─── 2.26: Projects List ↔ Detail split layout (iPad+) ───
   At 768px+, #projects-list (left, 320px) and #projects-detail (right, flex:1)
   render side-by-side inside #projects-split-wrap. At ≤767px the wrap is
   display:contents (transparent) so iPhone behavior is unchanged. */
#projects-split-wrap {
    display: contents;
}

@media (min-width: 768px) {
    #projects-split-wrap {
        display: flex;
        flex-direction: row;
        flex: 1;
        min-height: 0;
        height: 100%;
        overflow: hidden;
    }
    #projects-split-wrap #projects-list {
        display: flex !important;
        flex-direction: column;
        /* DS-5/T-022: #projects-list inherits flex:1 from the base
           #projects-list,#projects-detail,… rule (line ~1700); without an
           explicit flex-grow:0 it GREW past 320px and starved the detail
           column in landscape. Pin it to 320px so detail (flex:1) gets the
           rest. Portrait overrides this back to flex:1 (full-width column). */
        flex: 0 0 360px;
        width: 360px;
        min-width: 360px;
        border-right: 1px solid var(--border);
        overflow: hidden;
    }
    #projects-split-wrap #projects-detail {
        display: flex !important;
        flex-direction: column;
        flex: 1;
        min-width: 0;
        overflow: hidden;
    }
    #projects-split-wrap #projects-detail:empty::before {
        content: 'Select a project to view details';
        display: block;
        text-align: center;
        padding: 60px 20px;
        color: var(--text-muted);
        font-size: 14px;
    }
}

/* ─── DS-5/T-022: iPad PORTRAIT single-active-column ──────────────────────────
   At portrait iPad widths the 280px sidebar + 320px list + flex detail left the
   Project Brief only ~168px (clipped). In portrait we collapse the split-wrap to
   ONE active column — the list by default, the project detail once a project is
   open (.detail-active, set by showProjectDetail / cleared by showProjectList).
   Landscape keeps the 2-up split unchanged (rules above). Media queries re-
   evaluate on rotation, so the .detail-active flag stays correct across both
   orientations with no JS resize listener. Below 768px the wrap is
   display:contents (iPhone path) so none of this applies. */
/* 2.95 / D-005: restricted to touch (pointer:coarse) so a tall/narrow tiled DESKTOP window
   does NOT collapse the Projects 2-up split to a single column (that would hide the open
   project detail — a data-loss read). Touch iPad keeps the portrait single-column collapse. */
@media (min-width: 768px) and (orientation: portrait) and (pointer: coarse) {
    /* Default (no project open): list takes the full column, detail hidden. */
    #projects-split-wrap #projects-list {
        width: auto;
        min-width: 0;
        flex: 1;
        border-right: none;
    }
    #projects-split-wrap #projects-detail {
        display: none !important;
    }
    /* Project open: detail takes the full column, list swaps out. */
    #projects-split-wrap.detail-active #projects-list {
        display: none !important;
    }
    #projects-split-wrap.detail-active #projects-detail {
        display: flex !important;
        flex: 1;
    }
    /* The "Select a project" placeholder is a 2-up (landscape) affordance; in
       portrait the list IS the column when nothing is selected, so suppress it. */
    #projects-split-wrap #projects-detail:empty::before {
        content: none;
    }
}

/* ─── Cycle 2: Element Description ────────────────────────── */
.element-desc {
    font-size: 11px;
    color: #5a7a5a;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 200px;
    margin-top: 2px;
}

/* ─── Cycle 2: Scoped Chat Banner ─────────────────────────── */
.scope-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    background: #2a1f3d;
    border-bottom: 1px solid #9b7dcf;
    font-size: 13px;
    color: #9b7dcf;
    flex-shrink: 0;
}
.scope-banner-close {
    background: none;
    border: none;
    color: #9b7dcf;
    font-size: 20px;
    padding: 4px 12px;
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 2.112: tappable single-datapoint scope bar → jump to the source datapoint. */
.scope-banner-jump {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
    min-width: 0;
    min-height: 44px;
    cursor: pointer;
    -webkit-tap-highlight-color: rgba(155, 125, 207, 0.25);
}
.scope-banner-jump-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-decoration: underline;
    text-decoration-color: rgba(155, 125, 207, 0.45);
    text-underline-offset: 2px;
}
.scope-banner-jump .scope-banner-arrow {
    font-size: 15px;
    opacity: 0.75;
    flex-shrink: 0;
}
.scope-banner-jump:active {
    opacity: 0.7;
}

/* ─── Cycle 2: Save As Evidence Button ────────────────────── */
.save-evidence-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 28px;
    height: 28px;
    background: none;
    border: none;
    color: #5a7a5a;
    font-size: 16px;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    -webkit-tap-highlight-color: transparent;
}
.save-evidence-btn:active { color: #9b7dcf; background: rgba(155, 125, 207, 0.1); }

/* ─── Cycle 2: Project Brief ──────────────────────────────── */
.project-brief {
    padding: 8px 16px;
    flex-shrink: 0;
}
.project-brief-textarea {
    width: 100%;
    background: #0f170f;
    border: 1px solid #1a2e1a;
    border-radius: 6px;
    color: #c4d4c4;
    font-size: 16px; /* iOS zoom prevention */
    padding: 10px;
    resize: vertical;
    min-height: 60px;
    font-family: var(--font-system);
}
.project-brief-counter {
    font-size: 11px;
    color: #5a7a5a;
    text-align: right;
    padding-top: 4px;
}
.project-brief-counter.near-limit { color: #f87171; }

/* ─── Cycle 2: Outcome Rating Stars ──────────────────────── */
.rating-star { cursor: pointer; transition: color 0.1s; }
.rating-star.active { color: #9b7dcf !important; }

/* ─── Cycle 2: Evidence Filter Bar ────────────────────────── */
.evidence-filter-bar {
    display: flex;
    gap: 6px;
    padding: 8px 16px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-shrink: 0;
    border-bottom: 1px solid #1a2e1a;
}
.evidence-filter-chip {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 14px;
    font-size: 12px;
    color: #5a7a5a;
    border: 1px solid #1a2e1a;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.evidence-filter-chip.active {
    color: #9b7dcf;
    border-color: #9b7dcf;
    background: rgba(155, 125, 207, 0.1);
}

/* ─── 2.26: Project Chat Split Layout (iPad+) ───────────── */
.project-chat-split {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    height: 0;
    overflow: hidden;
}

@media (min-width: 768px) {
    .project-chat-split {
        flex-direction: row;
    }

    .project-chat-tree {
        width: 300px;
        min-width: 260px;
        flex-shrink: 0;
        border-right: 1px solid var(--border);
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .project-chat-tree-header {
        padding: 12px 16px;
        border-bottom: 1px solid var(--border);
        flex-shrink: 0;
        font-size: 14px;
        color: var(--text-secondary);
        font-weight: 600;
    }

    .project-chat-tree-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }

    .project-chat-panel {
        flex: 1;
        display: flex;
        flex-direction: column;
        min-width: 0;
        overflow: hidden;
    }
}

/* ─── 2.22: Desktop responsive (≥1200px) ─────────────────── */
@media (min-width: 1200px) {
    :root {
        /* No tab bar at this width (sidebar nav), but viewport-fit=cover means
           the home indicator still intrudes in landscape iPad. Keep the
           safe-area inset so the chat input bar / scroll bodies clear it —
           hardcoding 12px dropped it and parked the input under the indicator. */
        --safe-bottom-pad: calc(12px + env(safe-area-inset-bottom, 0px));
    }

    .ipad-sidebar {
        width: 220px;
        min-width: 220px;
    }

    .ipad-content {
        max-width: 1400px;
    }

    .feed-card,
    .inbox-card,
    .list-item-card {
        max-width: 720px;
    }

    .batch-area,
    .tab-body {
        max-width: 860px;
    }

    /* 2.46: .bottom-sheet desktop — flex-overlay centered, opacity-fade in/out */
    .bottom-sheet-overlay.show {
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .bottom-sheet {
        position: static;
        width: 100%;
        max-width: 600px;
        max-height: 85vh;
        border-radius: 16px;
        border-top: none;
        transform: none;
        opacity: 0;
        transition: opacity 0.2s ease-out;
    }
    .bottom-sheet.show {
        transform: none;
        opacity: 1;
    }

    .project-split-tree {
        width: 320px;
    }
    .project-chat-tree {
        width: 320px;
    }
    .el-panels-wrap .evidence-panel {
        width: 380px;
        max-width: 440px;
    }

    .chat-messages,
    .chat-input-area {
        max-width: 860px;
        margin-left: auto;
        margin-right: auto;
        width: 100%;
    }
    /* iPad has no tab bar (#appShell.active padding-bottom:0 ≥768), so the
       chat input sat flush at the screen bottom — clipped behind the home
       indicator on no-home-button iPads. Reserve the bottom safe-area inset;
       max() lets the keyboard offset win when the keyboard is open (the
       indicator is then covered). Mirrors the .element-chat-input-bar fix. */
    .chat-input-area {
        padding-bottom: calc(10px + max(env(safe-area-inset-bottom, 0px), var(--keyboard-offset, 0px)));
    }
}

/* ─── 2.95: Desktop adopts the device-agnostic iPad layout ───
   The 2.22 stopgap that capped desktop at a centered 480px phone column (and hid the
   .ipad-sidebar) for the legacy browser-context body class + hover:hover + pointer:fine was
   removed here. Desktop now falls through to the ≥768 (row + sidebar) and ≥1200 (enhanced
   caps) iPad tiers. The browser-context class machinery was removed entirely (shell.js) — it
   had no other consumers. */

/* ─── 2.95 / D-007: re-enable text selection on detail prose for mouse copy-to-colleague ───
   The global body rule keeps user-select:none for touch-selection jank; pointer:fine mouse
   devices re-enable it on the detail-prose surfaces only. */
@media (pointer: fine) {
    .project-brief,
    .element-desc,
    .evidence-card, .evidence-card .ev-content, .evidence-card .ev-origin, .evidence-card .ev-rel,
    .chat-messages {
        -webkit-user-select: text;
        user-select: text;
    }
}

/* ─── 2.95 / D-008: pointer cursor + visible keyboard focus for mouse/keyboard users ───── */
@media (pointer: fine) {
    .ipad-nav-item,
    .feed-card, .inbox-card, .list-item-card,
    .ipad-context-item { cursor: pointer; }
}
.ipad-nav-item:focus-visible {
    outline: 2px solid var(--accent-purple);
    outline-offset: -2px;
}

/* ─── 2.22: Hover states for cursor users (any width) ───── */
@media (hover: hover) {
    .ipad-nav-item:hover { background: var(--bg-surface); }
    .feed-card:hover,
    .inbox-card:hover,
    .list-item-card:hover { border-color: var(--border-hover); }
    .ipad-context-item:hover { background: var(--bg-surface); }
    .chat-fb-btn:hover { color: var(--accent-purple); }
    .bottom-sheet-cancel:hover { border-color: #3d5a3d; color: #a8bca8; }
    .bottom-sheet-submit:hover { background: #6d28d9; }
    .btn-outline-secondary:hover { border-color: #3d5a3d; color: #a8bca8; }
    .more-item:hover { background: var(--bg-surface-alt); }
}

/* ─── 2.44: Inline-style consolidation (Sprint B-StyleSweep, 2026-05-12) ───── */
.tab-title { font-size: 15px; font-weight: 500; color: var(--text-secondary); }
.tab-header-actions { display: flex; gap: 8px; }
.tab-header-spacer { width: 50px; }

.ipad-brand-title { font-family: var(--font-brand); color: var(--text-secondary); font-size: 22px; letter-spacing: 1px; }
.ipad-brand-dot { color: var(--accent-purple); }
#ipad-greeting { color: var(--text-muted); font-size: 12px; margin-top: 4px; }
.ipad-sidebar-divider { border-bottom: 1px solid var(--border); margin: 8px 16px; }
.ipad-context-placeholder { padding: 12px 16px; color: var(--text-dim); font-size: 12px; }
.ipad-context-more { padding: 8px 16px; font-size: 11px; color: var(--text-dim); }

.chat-sessions-loading { text-align: center; color: var(--text-muted); font-size: 13px; padding: 40px 0; }

#deviceLogin { margin-top: 24px; }
.device-login-label { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
.device-login-input {
    width: 100%;
    max-width: 280px;
    padding: 12px 16px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-surface);
    color: var(--text-primary);
    font-size: 14px;
    outline: none;
    -webkit-appearance: none;
}
.device-login-button {
    display: block;
    width: 100%;
    max-width: 280px;
    margin-top: 10px;
    padding: 12px;
    border-radius: 10px;
    border: none;
    background: var(--accent-purple);
    color: white;
    font-size: 14px;
    cursor: pointer;
    -webkit-appearance: none;
}
#deviceError { color: var(--accent-red); font-size: 12px; margin-top: 8px; }

/* ─── Full-ancestor breadcrumb (BS-1.14 / D-023) ─────────────────────
   Left-truncation: the container is RTL so text-overflow clips the
   START (root side) on overflow; the inner <bdi> keeps the chain
   readable left-to-right. The current element is ALSO always shown
   verbatim via the sibling .el-title, so the deepest segment is never
   lost even under aggressive narrow-viewport overflow (T-019). */
.el-breadcrumb {
    font-size: 11px;
    color: #5a7a5a;
    direction: rtl;
    text-align: left;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.el-breadcrumb bdi { direction: ltr; unicode-bidi: isolate; }

/* ─── Evidence Matrix (BS-1.10/1.11 / D-011/D-012) ───────────────────
   Native horizontal-scroll only — no touch/swipe handler (D-010 /
   BS-1.9). iOS back-edge-swipe and grid scroll both preserved. */
.matrix-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}
.matrix-table {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    min-width: 100%;
}
.matrix-table th,
.matrix-table td {
    border-bottom: 1px solid #1a2e1a;
    border-right: 1px solid #1a2e1a;
    vertical-align: top;
}
.matrix-corner {
    position: sticky;
    left: 0;
    top: 0;
    z-index: 3;
    background: #0d1a0d;
    min-width: 96px;
}
.matrix-col-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: #0d1a0d;
    color: #c4d4c4;
    font-size: 11px;
    font-weight: 600;
    padding: 8px 10px;
    text-align: left;
    white-space: nowrap;
    min-width: 180px;
}
.matrix-col-relationship { color: #9b7dcf; }
.matrix-col-tag { color: #5a7a5a; }
.matrix-row-head {
    position: sticky;
    left: 0;
    z-index: 1;
    background: #0d1a0d;
    color: #c4d4c4;
    font-size: 12px;
    font-weight: 600;
    padding: 8px 10px;
    text-align: left;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.matrix-cell {
    padding: 6px;
    min-width: 180px;
    background: #0f170f;
}
.matrix-cell .evidence-card { margin-bottom: 6px; }
.matrix-cell .evidence-card:last-child { margin-bottom: 0; }
/* Empty intersection: an explicit, intentional empty cell — NOT an
   error glyph, NOT a row-collapse (T-016). */
.matrix-cell-empty {
    background: #0d1a0d;
    min-width: 180px;
}

/* Loading skeleton (T-014): a grid skeleton, never a spinner-on-blank. */
.matrix-skeleton { padding: 16px 0; }
.matrix-skel-row { display: flex; gap: 8px; margin-bottom: 8px; }
.matrix-skel-cell {
    flex: 1;
    height: 56px;
    border-radius: 6px;
    background: #0f170f;
    border: 1px solid #1a2e1a;
    animation: matrix-skel-pulse 1.2s ease-in-out infinite;
}
@keyframes matrix-skel-pulse {
    0%, 100% { opacity: 0.45; }
    50% { opacity: 0.85; }
}

/* ─── 2.85: In-app full-screen image viewer ───────────────────────────
   Reuses the .bottom-sheet slide-up lifecycle (so it inherits the .show
   transition) but overrides the partial-height strip into a full-screen,
   transparent, centered photo viewer. No inputs → no keyboard registration. */
.image-viewer-overlay { background: rgba(0,0,0,0.85); z-index: 200; }
.image-viewer-sheet {
    top: 0;                  /* span full height, not just the bottom strip */
    height: 100vh;
    max-height: 100vh;
    background: transparent;
    border-top: none;
    border-radius: 0;
    padding: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 201;
}
.image-viewer-body {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}
.image-viewer-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;     /* correct aspect ratio in portrait + landscape */
}
.image-viewer-status { color: var(--text-secondary, #c4d4c4); font-size: 14px; }
.image-viewer-close {
    position: fixed;
    top: max(12px, env(safe-area-inset-top));
    right: 16px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: rgba(0,0,0,0.55);
    color: #fff;
    font-size: 20px;
    line-height: 40px;
    text-align: center;
    cursor: pointer;
    z-index: 202;
}
