/* Leon — Sabr Brain Interface */

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

body {
    background: #000;
    color: #fff;
    font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Ubuntu, Arial, sans-serif;
    overflow: hidden;
    width: 100vw;
    height: 100vh;
    -webkit-font-smoothing: antialiased;
    cursor: default;
}

#canvas-container { position: fixed; inset: 0; z-index: 0; }
canvas { display: block; }

.section-label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 9px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.55);
    font-weight: 600;
    margin-bottom: 14px;
}

/* ── Identity (top-left) ─────────────────────────────────── */
#identity { position: fixed; top: 26px; left: 30px; z-index: 11; }
.id-mark  { font-size: 13px; letter-spacing: 0.45em; font-weight: 300; color: #fff; line-height: 1; }
.id-sub   { margin-top: 6px; font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.5); font-weight: 400; }

/* Small pill under the identity wordmark — opens the Brain Info modal so
   the always-on neural/cognition readouts only show up when asked for. */
#brain-info-btn {
    margin-top: 14px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.14);
    color: rgba(255,255,255,0.7);
    border-radius: 6px;
    padding: 6px 12px;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.15s;
}
#brain-info-btn:hover {
    background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.3);
    color: #fff;
}
#brain-info-btn:active { transform: translateY(1px); }

/* Shared readout styles — used inside the Brain Info modal */
.rate-row { display: flex; align-items: baseline; gap: 6px; margin-bottom: 2px; }
.rate-metric {
    font-size: 48px; font-weight: 200; letter-spacing: -0.04em;
    color: #fff; font-variant-numeric: tabular-nums; line-height: 1;
    text-shadow: 0 0 50px rgba(255,255,255,0.18);
}
.rate-unit { font-size: 16px; font-weight: 300; color: rgba(255,255,255,0.7); letter-spacing: 0.04em; }
.rate-caption { font-size: 10px; color: rgba(255,255,255,0.5); letter-spacing: 0.06em; margin-bottom: 18px; }
.metric-grid { display: flex; flex-direction: column; gap: 6px; }
.mg-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.mg-label { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255,255,255,0.55); font-weight: 500; }
.mg-value { font-size: 12px; color: #fff; font-variant-numeric: tabular-nums; font-weight: 400; }

/* Brain Info popover — small side panel anchored to the brain-info button.
   NOT a full-screen modal — no backdrop blur, terminals stay visible behind.
   Lives off-screen via translateX(-12px) + opacity 0 by default; .open class
   slides it in. Hidden via pointer-events:none so clicks pass through when
   it's closed. */
#brain-info-popover {
    position: fixed;
    top: 26px;
    left: 290px;
    width: 280px;
    z-index: 12;
    background: #000;
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 10px;
    box-shadow: 0 12px 40px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.04) inset;
    opacity: 0;
    transform: translateX(-12px);
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
#brain-info-popover.open {
    opacity: 1;
    transform: translateX(0);
    pointer-events: auto;
}
.bip-hd {
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 14px 10px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.bip-title {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #fff;
    font-weight: 600;
}
.bip-close {
    background: none; border: none;
    color: rgba(255,255,255,0.55);
    font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px;
    transition: color 0.15s;
}
.bip-close:hover { color: #fff; }
.bip-body {
    padding: 14px 16px 16px;
    display: flex; flex-direction: column; gap: 14px;
}

/* Active state on the trigger button while popover is open */
#brain-info-btn.active {
    background: rgba(255,255,255,0.1);
    border-color: rgba(255,255,255,0.32);
    color: #fff;
}

/* Brain Info popover sections + divider */
.bi-section { display: flex; flex-direction: column; }
.bi-divider { height: 1px; background: rgba(255,255,255,0.08); margin: 4px 0; }

/* Dopamine bar — was yellow/gold gradient, now pure white to match Claude
   Usage bars. Same vocabulary across the popover so the eye doesn't have to
   re-parse a different color metric. */
#cog-da-fill {
    background: #fff;
    box-shadow: 0 0 6px rgba(255,255,255,0.85), 0 0 14px rgba(255,255,255,0.4);
}

/* ── Claude Usage ────────────────────────────────────────── */
/* Leon's Actions — sits below claude-usage, with room to grow */
#leon-actions {
    position: fixed; top: 380px; left: 30px; z-index: 10; width: 240px;
}
#leon-actions .la-line {
    font-size: 10px; color: rgba(255,255,255,0.55);
    letter-spacing: 0.04em; line-height: 1.5;
    overflow: hidden; text-overflow: ellipsis;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    word-break: break-word;
}
#leon-actions .la-line.la-active {
    color: rgba(255, 255, 255, 0.85);
}
#leon-actions .la-line.la-idle {
    color: rgba(255,255,255,0.35);
    font-style: italic;
}
#leon-actions .la-line.la-thinking {
    color: rgba(255, 255, 255, 0.6);
}
#leon-actions .la-tool {
    font-size: 9px; color: rgba(255,255,255,0.5);
    font-family: 'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
    letter-spacing: 0.02em; margin-top: 2px;
}

/* ── Activity Log Panel (mirrors conv-panel) ─────────────── */
#activity-panel {
    position: fixed;
    right: 30px;
    bottom: 120px;
    width: 380px;
    min-width: 280px; min-height: 200px;
    max-width: 800px; max-height: 420px;
    background: rgba(0, 0, 0, 0.94);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 12px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    z-index: 50;
    display: flex; flex-direction: column;
    font-family: inherit;
    box-shadow: 0 8px 32px rgba(0,0,0,0.55);
}
#activity-panel.dragging { cursor: grabbing; transition: none; }
.act-resize-handle {
    position: absolute;
    right: 0; bottom: 0;
    width: 28px; height: 28px;
    cursor: nwse-resize;
    touch-action: none;
    z-index: 2;
}
.act-resize-handle::before {
    content: "";
    position: absolute;
    right: 0; bottom: 0;
    width: 14px; height: 14px;
    background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.35) 50%);
    border-bottom-right-radius: 12px;
}
#act-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 12px;
    font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase;
    color: rgba(255,255,255,0.55); font-weight: 600;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    cursor: grab;
    user-select: none;
}
#activity-panel.dragging #act-header { cursor: grabbing; }
#act-clear {
    background: none; border: none; padding: 0;
    font: inherit; font-size: 9px; letter-spacing: 0.12em;
    text-transform: uppercase; color: rgba(255,255,255,0.4);
    cursor: pointer; transition: color 0.15s;
}
#act-clear:hover { color: rgba(255,255,255,0.85); }
#act-body {
    flex: 1; overflow-y: auto;
    min-height: 0;
    padding: 10px 12px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.18) transparent;
}
#act-body::-webkit-scrollbar { width: 5px; }
#act-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 3px; }
.act-entry { padding: 4px 0; border-bottom: 1px solid rgba(255,255,255,0.04); font-size: 11px; line-height: 1.5; }
.act-entry:last-child { border-bottom: none; }
.act-ts {
    font-size: 9px; color: rgba(255,255,255,0.3);
    font-family: 'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
    margin-right: 6px;
}
.act-cat {
    font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
    font-weight: 600; margin-right: 6px;
    /* Default for any category with no explicit colour below. Before this
       existed, an unmapped category (hearing, vision, business) inherited
       plain white and read as "broken" next to the coloured ones — which is
       exactly what Dean saw: PERCEPTION blue, HEARING white. Unknown kinds
       now get a muted slate instead of glaring white. */
    color: #8a93a8;
}
.act-cat-perception { color: #6bf; }
.act-cat-thinking   { color: #c9f; }
.act-cat-tool       { color: #fd6; }
.act-cat-goal       { color: #6f9; }
.act-cat-inner      { color: #f9c; }
.act-cat-reading    { color: #9cf; }
.act-cat-agent      { color: #4fe3c1; }
.act-cat-hearing    { color: #ffa94d; }
.act-cat-vision     { color: #7ee787; }
.act-cat-business   { color: #ffd166; }
.act-cat-system     { color: #a0a8bd; }
.act-cat-error      { color: #ff6b6b; }

/* Named sub-agent chip inside an activity line. Clicking it expands that
   agent's full output right here in the log — Dean's call, 2026-08-02: no
   separate agents window, the log already IS the window. */
.act-agent-name {
    color: #4fe3c1;
    font-weight: 600;
    cursor: pointer;
    border-bottom: 1px dotted rgba(79, 227, 193, 0.5);
    margin-right: 5px;
}
.act-agent-name:hover { color: #7ff3d9; border-bottom-color: #7ff3d9; }
.act-entry.act-open .act-agent-name { border-bottom-style: solid; }
.act-agent-detail {
    display: none;
    margin: 6px 0 8px 14px;
    padding: 8px 10px;
    background: rgba(79, 227, 193, 0.06);
    border-left: 2px solid rgba(79, 227, 193, 0.55);
    border-radius: 4px;
    color: #cfe;
    font-size: 12px;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 320px;
    overflow-y: auto;
}
.act-entry.act-open .act-agent-detail { display: block; }
.act-text { color: rgba(255,255,255,0.85); }

#claude-usage { position: fixed; top: 100px; left: 30px; z-index: 10; width: 240px; }
.cu-plan { font-size: 9px; letter-spacing: 0.12em; color: #fff; font-weight: 500; text-transform: none; }
.cu-status-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.status-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; transition: all 0.3s; }
.status-dot.idle { background: rgba(255,255,255,0.5); }
.status-dot.processing {
    background: #fff;
    box-shadow: 0 0 6px rgba(255,255,255,1), 0 0 16px rgba(255,255,255,0.6);
    animation: dot-pulse 0.9s ease-in-out infinite;
}
@keyframes dot-pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.4); opacity: 0.55; } }
.status-text { font-size: 11px; color: rgba(255,255,255,0.85); letter-spacing: 0.04em; font-weight: 400; }
.status-text.processing { color: #fff; }
.status-meta { margin-left: auto; font-size: 9px; color: rgba(255,255,255,0.4); letter-spacing: 0.04em; }
.cu-quotas { display: flex; flex-direction: column; gap: 11px; margin-bottom: 14px; }
.cu-row-empty { font-size: 10px; color: rgba(255,255,255,0.4); letter-spacing: 0.06em; font-style: italic; }
.cu-row { display: flex; flex-direction: column; gap: 4px; }
.cu-row-top { display: flex; align-items: baseline; justify-content: space-between; }
.cu-row-label { font-size: 10px; color: rgba(255,255,255,0.7); letter-spacing: 0.04em; font-weight: 400; }
.cu-row-pct { font-size: 11px; color: #fff; font-variant-numeric: tabular-nums; font-weight: 500; }
.cu-bar-track { width: 100%; height: 2px; background: rgba(255,255,255,0.1); border-radius: 1px; overflow: hidden; }
.cu-bar-fill {
    height: 100%; background: #fff; border-radius: 1px;
    box-shadow: 0 0 6px rgba(255,255,255,0.85), 0 0 14px rgba(255,255,255,0.4);
    transition: width 0.7s ease;
}
.cu-row-reset { font-size: 9px; color: rgba(255,255,255,0.4); letter-spacing: 0.04em; }
.cu-extra { display: flex; justify-content: space-between; align-items: baseline; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.08); }
.cu-extra-label { font-size: 10px; color: rgba(255,255,255,0.55); letter-spacing: 0.04em; }
.cu-extra-value { font-size: 11px; color: #fff; font-variant-numeric: tabular-nums; font-weight: 500; }

/* "synced 12s ago" line under Extra usage. Goes red-ish if Octogent is
   offline and we're serving the on-disk snapshot. */
.cu-sync {
    margin-top: 8px;
    font-size: 9px;
    letter-spacing: 0.04em;
    color: rgba(255,255,255,0.35);
    font-variant-numeric: tabular-nums;
}
.cu-sync-stale { color: rgba(255, 170, 80, 0.8); }

/* Refresh button in the Claude Usage section header. Subtle by default,
   lights up cyan on hover; spins the icon while a request is in flight. */
#cu-refresh {
    background: none;
    border: 1px solid rgba(255,255,255,0.14);
    color: rgba(255,255,255,0.55);
    width: 20px; height: 20px;
    padding: 0;
    border-radius: 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s, transform 0.15s;
    margin-left: auto;
    margin-right: 6px;
}
#cu-refresh:hover { color: #fff; border-color: rgba(255,255,255,0.32); background: rgba(255,255,255,0.07); }
#cu-refresh:active { transform: scale(0.92); }
#cu-refresh svg { display: block; }
#cu-refresh.spinning svg { animation: cu-refresh-spin 0.75s linear infinite; }
#cu-refresh.spinning { color: #fff; border-color: rgba(255,255,255,0.32); }
@keyframes cu-refresh-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ── Cognition (inline child of #claude-usage — flows naturally) ─ */
#cognition-panel {
    /* No positioning! Lives inside #claude-usage and just stacks. */
    width: 100%;
}
.cog-spont-indicator {
    color: #ff66cc;
    font-size: 11px;
    opacity: 0;
    transition: opacity 0.4s;
    text-shadow: 0 0 10px rgba(255,102,204,0.7), 0 0 20px rgba(255,102,204,0.3);
}
.cog-spont-indicator.active { opacity: 1; }
/* Dopamine bar override moved below — see #cog-da-fill near the popover
   styles (white, matching the Claude Usage bars). */

/* ── Workspaces (right, transparent) ─────────────────────── */
#workspaces-panel {
    position: fixed; top: 26px; right: 28px;
    width: 250px; max-height: calc(100vh - 110px);
    z-index: 10; overflow-y: auto; overflow-x: hidden;
}
.ws-header { display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 14px; }
.ws-count { font-size: 9px; color: rgba(255,255,255,0.55); font-variant-numeric: tabular-nums; letter-spacing: 0.06em; text-transform: uppercase; }

/* Workspaces / Agents tab pair (replaced the old "N/M live" counter) */
.ws-tab {
    position: relative;
    font-size: 9px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    font-weight: 600;
    color: rgba(255,255,255,0.32);
    cursor: pointer;
    padding-bottom: 3px;
    border-bottom: 1px solid transparent;
    transition: color 0.18s, border-color 0.18s;
    user-select: none;
}
.ws-tab:hover { color: rgba(255,255,255,0.7); }
.ws-tab.active { color: rgba(255,255,255,0.92); border-bottom-color: rgba(255,255,255,0.45); }
.ws-tab-dot {
    display: inline-block; width: 4px; height: 4px; border-radius: 50%;
    background: #fff; margin-left: 6px; vertical-align: middle;
    box-shadow: 0 0 6px rgba(255,255,255,0.95);
    animation: live-pulse 2.4s ease-in-out infinite;
}

/* Agents list */
.ag-row { margin-bottom: 2px; }
.ag-meta {
    font-size: 9px; color: rgba(255,255,255,0.42);
    font-variant-numeric: tabular-nums; letter-spacing: 0.04em;
    flex-shrink: 0;
}
.ag-fail-dot {
    width: 5px; height: 5px; border-radius: 50%;
    background: rgba(255,120,110,0.75); flex-shrink: 0;
    box-shadow: 0 0 6px rgba(255,120,110,0.45);
}
/* State word. Live agents read bright white and glow; finished ones sit back
   dim so the eye lands on what's actually moving. */
.ag-tag {
    font-size: 8px; letter-spacing: 0.14em; text-transform: uppercase;
    padding: 1px 5px; border-radius: 3px; flex-shrink: 0;
}
.ag-tag-live {
    color: #fff; background: rgba(255,255,255,0.14);
    text-shadow: 0 0 8px rgba(255,255,255,0.75);
    animation: live-pulse 2.4s ease-in-out infinite;
}
.ag-tag-done { color: rgba(255,255,255,0.45); background: rgba(255,255,255,0.05); }
.ag-tag-fail { color: rgba(255,140,130,0.95); background: rgba(255,120,110,0.12); }
/* The moving line — last thing the agent actually did. */
.ag-now {
    font-size: 9px; line-height: 1.35; color: rgba(255,255,255,0.72);
    margin: 1px 0 4px 12px; padding-left: 6px;
    border-left: 1px solid rgba(255,255,255,0.22);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A running agent's own name goes full white, not the 62% grey. */
.ws-item.ws-live .ws-item-name { color: #fff; text-shadow: 0 0 10px rgba(255,255,255,0.35); }
.ag-detail {
    margin: 2px 0 8px 12px; padding: 6px 8px;
    border-left: 1px solid rgba(255,255,255,0.12);
    background: rgba(255,255,255,0.02);
    border-radius: 0 4px 4px 0;
}
.ag-detail-label {
    font-size: 8px; letter-spacing: 0.18em; text-transform: uppercase;
    color: rgba(255,255,255,0.38); margin: 4px 0 2px;
}
.ag-detail-body {
    font-size: 10px; line-height: 1.45; color: rgba(255,255,255,0.66);
    white-space: pre-wrap; word-break: break-word;
    max-height: 220px; overflow-y: auto;
}
.ag-detail-body::-webkit-scrollbar { width: 2px; }
.ag-detail-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); }
.ws-skeleton { font-size: 9px; color: rgba(255,255,255,0.4); letter-spacing: 0.16em; text-transform: uppercase; }

/* Folder (recursive, nested) */
.ws-folder { margin-bottom: 6px; }
.ws-folder-hd {
    display: flex; align-items: center; gap: 7px;
    padding: 5px 0; cursor: pointer; user-select: none;
    transition: opacity 0.15s;
}
.ws-folder-hd:hover { opacity: 0.92; }
.ws-caret {
    font-size: 9px; color: rgba(255,255,255,0.5);
    transition: transform 0.2s ease; line-height: 1; width: 8px;
}
.ws-folder.collapsed .ws-caret { transform: rotate(-90deg); }
.ws-folder-dot {
    width: 6px; height: 6px; border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 5px currentColor;
}
.ws-folder-dot-empty { background: rgba(255,255,255,0.3); box-shadow: none; }
.ws-folder-name {
    flex: 1;
    font-size: 11px; color: #fff;
    font-weight: 500; letter-spacing: 0.04em;
}
.ws-folder-meta {
    font-size: 9px; color: rgba(255,255,255,0.45);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
}
.ws-folder-body {
    overflow: hidden;
    max-height: 2000px;
    transition: max-height 0.3s ease, opacity 0.2s ease;
    opacity: 1;
}
.ws-folder.collapsed > .ws-folder-body { max-height: 0; opacity: 0; }

.ws-item {
    display: flex; align-items: center; gap: 7px;
    padding: 4px 0;
    font-size: 12px; color: rgba(255,255,255,0.62);
    cursor: pointer;
    transition: color 0.18s, background 0.18s;
    font-weight: 300; line-height: 1.3;
    border-radius: 4px;
}
.ws-item:hover { color: #fff; background: rgba(255,255,255,0.04); }
.ws-item.ws-live { color: #fff; font-weight: 400; }

.ws-live-dot {
    width: 5px; height: 5px; border-radius: 50%;
    background: #fff; flex-shrink: 0;
    box-shadow: 0 0 6px rgba(255,255,255,0.95), 0 0 14px rgba(255,255,255,0.45);
    animation: live-pulse 2.4s ease-in-out infinite;
}
.ws-cold-dot {
    width: 5px; height: 5px; border-radius: 50%;
    background: rgba(255,255,255,0.18); flex-shrink: 0;
}
@keyframes live-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }

.ws-item-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

#workspaces-panel::-webkit-scrollbar { width: 2px; }
#workspaces-panel::-webkit-scrollbar-track { background: transparent; }
#workspaces-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 1px; }

/* ── Terminal Stack ──────────────────────────────────────── */
#terminal-stack {
    position: fixed;
    top: 26px;
    right: 290px;
    width: 720px;
    max-width: calc(100vw - 320px);
    /* Bottom 90px reserved for the #input-panel (bottom: 24px, ~38px tall)
       so terminal cards never sit underneath the speak-to-leon bar. */
    max-height: calc(100vh - 116px);
    overflow-y: auto;
    overflow-x: hidden;
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* Stack is interactive (scrollbar + wheel-over-gaps must receive events).
       Empty space outside cards routes pointer-events to brain canvas via
       :empty / no-card visibility detection isn't worth the complexity —
       user can click brain through the rest of the screen. */
    pointer-events: auto;
    scrollbar-gutter: stable;
    /* Firefox */
    scrollbar-width: auto;
    scrollbar-color: rgba(255, 255, 255, 0.35) rgba(255, 255, 255, 0.04);
}
/* When the stack is empty, fall through to brain canvas so a fresh dashboard
   doesn't block all clicks in this region. */
#terminal-stack:empty { pointer-events: none; }

/* WebKit / Chromium / Brave scrollbar — wide grey grab zone */
#terminal-stack::-webkit-scrollbar {
    width: 18px;
}
#terminal-stack::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.04);
    border-radius: 8px;
    margin: 4px 0;
}
#terminal-stack::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.30);
    border-radius: 8px;
    border: 4px solid transparent;
    background-clip: padding-box;
    min-height: 60px;
    transition: background 0.12s;
    pointer-events: auto;
}
#terminal-stack::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.55);
    background-clip: padding-box;
}
#terminal-stack::-webkit-scrollbar-thumb:active {
    background: rgba(255, 255, 255, 0.78);
    background-clip: padding-box;
}

.terminal-card {
    pointer-events: auto;
    background: rgba(6,6,8,0.94);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 10px;
    padding: 12px 10px 10px;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    animation: tc-enter 0.25s ease;
    display: flex; flex-direction: column;
    height: 420px;
    transition: height 0.3s ease;
}
.terminal-card.tc-expanded { height: 580px; }

@keyframes tc-enter { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } }

.tc-cold { opacity: 0.85; }

/* Drag target — file is hovering over the card */
.terminal-card.tc-drag-target {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.45);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.25) inset,
        0 0 24px rgba(255, 255, 255, 0.12);
}
.terminal-card.tc-drag-target::before {
    content: 'drop to attach';
    position: absolute;
    inset: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.85);
    text-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
    background: rgba(255, 255, 255, 0.06);
    border: 1px dashed rgba(255, 255, 255, 0.35);
    border-radius: 8px;
    pointer-events: none;
    z-index: 5;
    backdrop-filter: blur(2px);
}
.terminal-card { position: relative; }

.terminal-card.tc-drag-uploading {
    background: rgba(255, 255, 255, 0.05);
}

/* Brief flash after a successful drop so the user knows it landed */
.terminal-card.tc-drag-confirmed {
    animation: drag-confirmed 0.7s ease;
}
@keyframes drag-confirmed {
    0%   { box-shadow: 0 0 0 0 rgba(74, 217, 255, 0); }
    25%  { box-shadow: 0 0 0 2px rgba(74, 217, 255, 0.55), 0 0 28px rgba(74, 217, 255, 0.45); }
    100% { box-shadow: 0 0 0 0 rgba(74, 217, 255, 0); }
}

.tc-hd {
    display: flex; align-items: center; gap: 6px;
    margin-bottom: 6px;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

/* Whole project name takes folder color. flex 0 1 auto + margin-right:auto
   keeps the badge/id/close pinned right while the hover highlight wraps
   only the text itself (instead of stretching across an empty bar). */
.tc-name {
    flex: 0 1 auto;
    margin-right: auto;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    /* Plain cursor — Dean didn't like the OS context-menu icon. The pill
       highlight + brighter glow on hover is enough to signal interactivity. */
    cursor: default;
    padding: 2px 7px;
    margin-left: -7px;
    border-radius: 5px;
    transition: opacity 0.3s, text-shadow 0.3s, background 0.15s, box-shadow 0.15s;
}
.tc-name:hover {
    background: color-mix(in srgb, var(--c, #fff) 14%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c, #fff) 35%, transparent);
}
.tc-name-live {
    text-shadow:
        0 0 8px var(--c, #fff),
        0 0 18px var(--c, #fff),
        0 0 30px color-mix(in srgb, var(--c, #fff) 50%, transparent);
}
.tc-name-live:hover {
    text-shadow:
        0 0 10px var(--c, #fff),
        0 0 24px var(--c, #fff),
        0 0 40px color-mix(in srgb, var(--c, #fff) 65%, transparent);
}
.tc-name-cold {
    opacity: 0.42;
    text-shadow: none;
}
.tc-name-cold:hover { opacity: 0.7; }
.tc-id { font-size: 9px; color: rgba(255,255,255,0.4); font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace; }

/* Thinking badge: hidden until detectDone() spots a thinking line.
   Plain text + pulsing dot, no pill / border. */
.tc-thinking-badge {
    display: none;
    align-items: center;
    gap: 7px;
    color: #34d399;
    font-size: 9px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-weight: 500;
    margin-right: auto;
}
.tc-is-thinking .tc-thinking-badge { display: inline-flex; }
.tcb-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: #34d399;
    box-shadow: 0 0 6px #34d399, 0 0 14px rgba(52, 211, 153, 0.55);
    animation: tcb-pulse 1.1s ease-in-out infinite;
}
@keyframes tcb-pulse {
    0%,100% { transform: scale(1); opacity: 1; }
    50%     { transform: scale(1.6); opacity: 0.55; }
}
.tc-close {
    background: none; border: none; color: rgba(255,255,255,0.5);
    font-size: 18px; line-height: 1; cursor: pointer; padding: 0 3px;
    transition: color 0.15s;
}
.tc-close:hover { color: #fff; }
.tc-refresh {
    background: none; border: none; color: rgba(255,255,255,0.5);
    font-size: 18px; line-height: 1; cursor: pointer; padding: 0 3px;
    transition: color 0.15s;
    /* Force text rendering — without this the system emoji font paints
       ↻ on a white tile while × renders as plain text, breaking parity. */
    font-variant-emoji: text;
    font-family: "SF Mono","JetBrains Mono",Menlo,Consolas,monospace,sans-serif;
}
.tc-refresh:hover { color: #fff; }
.tc-meta {
    display: flex; gap: 8px; align-items: baseline;
    margin-bottom: 8px;
    font-size: 9px;
}
.tc-meta-label { color: rgba(255,255,255,0.4); letter-spacing: 0.1em; text-transform: uppercase; }
.tc-meta-val { color: rgba(255,255,255,0.65); font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* xterm.js host — let xterm render natively, bidirectional PTY */
.tc-term {
    flex: 1;
    background: #000;
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 6px;
    padding: 6px 8px;
    overflow: hidden;
    position: relative;
}
.tc-term .xterm { height: 100% !important; }
.tc-term .xterm-viewport { background: #000 !important; }
.tc-term .xterm-screen { width: 100% !important; }

/* Cold-session row (replaces input row when session not running) */
.tc-cold-row {
    display: flex;
    justify-content: center;
    margin-top: 8px;
}

/* ── New Session button + Modals ────────────────────────── */
#ws-new-btn {
    width: 100%;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.14);
    color: rgba(255,255,255,0.85);
    border-radius: 6px;
    padding: 8px 10px;
    font-size: 11px;
    letter-spacing: 0.06em;
    cursor: pointer;
    margin-bottom: 10px;
    transition: all 0.15s;
    font-weight: 500;
}
#ws-new-btn:hover {
    background: rgba(255,255,255,0.1);
    border-color: rgba(255,255,255,0.3);
    color: #fff;
}
#ws-new-btn:active { transform: translateY(1px); }

#modal-overlay {
    position: fixed; inset: 0;
    z-index: 20000;
    background: rgba(0,0,0,0.65);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: ov-fade 0.15s ease;
}
@keyframes ov-fade { from { opacity: 0; } to { opacity: 1; } }

.modal {
    width: 460px;
    max-width: calc(100vw - 40px);
    background: rgba(12, 12, 14, 0.98);
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.04) inset;
    flex-direction: column;
    animation: modal-in 0.18s ease;
}
@keyframes modal-in {
    from { opacity: 0; transform: translateY(8px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0)   scale(1); }
}
.modal-hd {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 18px 12px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.modal-title {
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #fff;
    font-weight: 600;
}
.modal-close {
    background: none; border: none; color: rgba(255,255,255,0.55);
    font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
    transition: color 0.15s;
}
.modal-close:hover { color: #fff; }

.modal-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 14px; }
.modal-sub { font-size: 11px; color: rgba(255,255,255,0.6); margin-bottom: 4px; }
.modal-field { display: flex; flex-direction: column; gap: 6px; position: relative; }
.mf-label {
    font-size: 9px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.55);
    font-weight: 500;
}
.mf-optional {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0.04em;
    color: rgba(255,255,255,0.35);
    margin-left: 4px;
}
.mf-hint {
    font-size: 10px;
    color: rgba(255,255,255,0.4);
    line-height: 1.4;
}
.mf-hint code {
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    background: rgba(255,255,255,0.06);
    padding: 1px 5px;
    border-radius: 3px;
    color: rgba(255,255,255,0.6);
}
.modal-field input[type="text"],
.modal-field select {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.12);
    color: #fff;
    border-radius: 6px;
    padding: 8px 11px;
    font-size: 12px;
    font-family: inherit;
    outline: none;
    transition: border-color 0.15s, background 0.15s;
}
.modal-field input[type="text"]:focus,
.modal-field select:focus { border-color: rgba(255,255,255,0.35); }

/* Custom themed dropdown (replacing native <select>) */
.custom-select { position: relative; }
.custom-select-btn {
    width: 100%;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.12);
    color: #fff;
    border-radius: 6px;
    padding: 8px 11px;
    font-size: 12px;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    display: flex; align-items: center; justify-content: space-between;
    transition: border-color 0.15s, background 0.15s;
}
.custom-select-btn:hover { background: rgba(255,255,255,0.07); }
.custom-select.cs-open .custom-select-btn { border-color: rgba(255,255,255,0.35); }
.cs-value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: 'SF Mono', Menlo, Consolas, monospace; }
.cs-caret { color: rgba(255,255,255,0.5); font-size: 9px; margin-left: 8px; transition: transform 0.15s; }
.custom-select.cs-open .cs-caret { transform: rotate(180deg); }

.custom-select-pop {
    display: none;
    position: absolute;
    top: calc(100% + 4px); left: 0; right: 0;
    background: rgba(8, 8, 10, 0.98);
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 6px;
    z-index: 50;
    max-height: 240px;
    overflow-y: auto;
    box-shadow: 0 12px 28px rgba(0,0,0,0.55);
    padding: 4px;
}
.custom-select.cs-open .custom-select-pop { display: block; }
.cs-item {
    padding: 7px 10px;
    font-size: 11px;
    color: rgba(255,255,255,0.85);
    cursor: pointer;
    border-radius: 4px;
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    transition: background 0.1s, color 0.1s;
    user-select: none;
}
.cs-item:hover { background: rgba(255,255,255,0.08); color: #fff; }
.cs-item-action { color: rgba(74, 217, 255, 0.85); font-style: italic; font-family: inherit; }
.cs-item-action:hover { background: rgba(74, 217, 255, 0.12); color: #fff; }
.cs-divider { height: 1px; background: rgba(255,255,255,0.08); margin: 4px 6px; }
.mf-color-row {
    display: flex; gap: 10px; align-items: center;
}
.mf-color-row input[type="color"] {
    width: 44px; height: 30px; padding: 0; border: 1px solid rgba(255,255,255,0.15);
    border-radius: 6px; background: none; cursor: pointer;
}
#ns-color-clear {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.7);
    border-radius: 6px;
    padding: 7px 12px;
    font-size: 11px;
    cursor: pointer;
    transition: all 0.15s;
}
#ns-color-clear:hover { background: rgba(255,255,255,0.1); color: #fff; }

.mf-suggest {
    position: absolute;
    top: 100%; left: 0; right: 0;
    margin-top: 4px;
    background: rgba(8, 8, 10, 0.98);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 6px;
    overflow: hidden;
    z-index: 10;
    max-height: 220px;
    overflow-y: auto;
}
.mf-suggest:empty { display: none; }
.ns-path-sug-item {
    padding: 7px 11px;
    font-size: 11px;
    color: rgba(255,255,255,0.75);
    cursor: pointer;
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    transition: background 0.1s;
}
.ns-path-sug-item:hover { background: rgba(255,255,255,0.06); color: #fff; }

.modal-actions {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 14px 18px;
    border-top: 1px solid rgba(255,255,255,0.06);
}
.modal-btn-ghost,
.modal-btn-danger,
.modal-btn-primary {
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 6px;
    padding: 8px 16px;
    font-size: 11px;
    letter-spacing: 0.06em;
    cursor: pointer;
    transition: all 0.15s;
    font-weight: 500;
}
.modal-btn-ghost {
    background: transparent;
    color: rgba(255,255,255,0.7);
}
.modal-btn-ghost:hover { background: rgba(255,255,255,0.06); color: #fff; }
.modal-btn-primary {
    background: rgba(255,255,255,0.92);
    color: #000;
    border-color: #fff;
}
.modal-btn-primary:hover { background: #fff; }
.modal-btn-danger {
    background: rgba(255, 90, 90, 0.14);
    color: #ff7a7a;
    border-color: rgba(255, 90, 90, 0.35);
}
.modal-btn-danger:hover { background: rgba(255, 90, 90, 0.28); color: #ff9d9d; }

/* Move modal — folder picker list */
.folder-picker {
    display: flex; flex-direction: column;
    gap: 4px;
    max-height: 260px;
    overflow-y: auto;
    background: rgba(255,255,255,0.02);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 6px;
    padding: 6px;
}
.folder-pick-item {
    padding: 8px 10px;
    font-size: 12px;
    color: rgba(255,255,255,0.85);
    cursor: pointer;
    border-radius: 4px;
    transition: background 0.1s, color 0.1s;
    font-family: 'SF Mono', Menlo, Consolas, monospace;
}
.folder-pick-item:hover { background: rgba(74, 217, 255, 0.12); color: #fff; }
.folder-pick-empty {
    padding: 12px 10px;
    font-size: 11px;
    color: rgba(255,255,255,0.45);
    font-style: italic;
}
.folder-new-row {
    display: flex; gap: 6px;
}
.folder-new-row input {
    flex: 1;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.12);
    color: #fff;
    border-radius: 6px;
    padding: 8px 11px;
    font-size: 12px;
    outline: none;
}
.folder-new-row input:focus { border-color: rgba(255,255,255,0.35); }
#move-new-folder-btn {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.14);
    color: #fff;
    border-radius: 6px;
    padding: 8px 14px;
    font-size: 11px;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.15s;
}
#move-new-folder-btn:hover { background: rgba(255,255,255,0.12); }

/* ── Right-click context menu ───────────────────────────── */
#context-menu {
    position: fixed;
    z-index: 10000;
    min-width: 168px;
    background: rgba(8, 8, 10, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    padding: 4px;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 12px 36px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.04) inset;
    animation: ctx-fade 0.12s ease;
}
@keyframes ctx-fade { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: scale(1); } }

.ctx-item {
    padding: 7px 12px;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.82);
    cursor: pointer;
    border-radius: 5px;
    transition: background 0.15s, color 0.15s;
    letter-spacing: 0.01em;
    user-select: none;
}
.ctx-item:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.ctx-item.danger { color: #ff7a7a; }
.ctx-item.danger:hover { background: rgba(255, 90, 90, 0.12); color: #ff9d9d; }

.ctx-divider {
    height: 1px;
    background: rgba(255, 255, 255, 0.08);
    margin: 4px 8px;
}

.tc-input-row {
    display: flex; align-items: flex-start; gap: 6px;
}
.tc-prompt-glyph {
    color: rgba(255,255,255,0.55);
    font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
    font-size: 13px;
    line-height: 30px;
    flex-shrink: 0;
}
.tc-input {
    flex: 1;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 5px;
    padding: 7px 10px;
    color: #4ad9ff;
    text-shadow: 0 0 6px rgba(74, 217, 255, 0.4);
    caret-color: #4ad9ff;
    font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
    font-size: 12px;
    outline: none;
    transition: border-color 0.18s, height 0.1s ease;
    /* multi-line textarea behavior */
    resize: none;
    min-height: 30px;
    max-height: 160px;
    line-height: 1.45;
    overflow-y: auto;
    width: 100%;
    display: block;
}
.tc-input:focus { border-color: rgba(255,255,255,0.3); }
.tc-input:disabled { color: rgba(255,255,255,0.3); text-shadow: none; cursor: not-allowed; }
.tc-input::placeholder { color: rgba(255,255,255,0.3); text-shadow: none; }
.tc-input::-webkit-scrollbar { width: 3px; }
.tc-input::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); }

.tc-key, .tc-launch-btn {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 5px;
    color: rgba(255,255,255,0.7);
    font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
    font-size: 10px;
    padding: 5px 8px;
    cursor: pointer;
    transition: all 0.15s;
    letter-spacing: 0.04em;
}
.tc-key:hover, .tc-launch-btn:hover {
    background: rgba(255,255,255,0.12);
    border-color: rgba(255,255,255,0.22);
    color: #fff;
}
.tc-launch-btn { padding: 6px 12px; font-size: 10px; letter-spacing: 0.06em; }

/* ── Response Panel ───────────────────────────────────────── */
#response-panel {
    display: none !important;
}
#response-user {
    font-size: 13px;
    color: #4ad9ff;
    text-shadow: 0 0 8px rgba(74, 217, 255, 0.45);
    letter-spacing: 0.01em;
    margin-bottom: 14px;
    font-weight: 400;
}
#response-text {
    font-size: 18px; color: #fff;
    line-height: 1.65; font-weight: 300; letter-spacing: -0.01em;
    max-width: 680px; margin: 0 auto;
}

/* Tool-use chip — appears in the response panel when Leon is calling a
   PC-control action (screen capture, mouse click, app launch, etc.).
   Transitions through pending → ok / fail then fades. */
.tool-chip {
    display: inline-block;
    margin-top: 12px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 10px;
    letter-spacing: 0.04em;
    font-family: 'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.18);
    color: rgba(255,255,255,0.85);
    transition: opacity 0.25s, background 0.2s, border-color 0.2s;
    max-width: 90%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tool-chip.tool-pending { animation: tool-pulse 1.1s ease-in-out infinite; }
.tool-chip.tool-ok      { border-color: rgba(160, 255, 160, 0.45); color: rgba(220,255,220,0.95); }
.tool-chip.tool-fail    { border-color: rgba(255, 140, 140, 0.55); color: rgba(255,200,200,0.95); }
@keyframes tool-pulse {
    0%, 100% { opacity: 0.65; }
    50%      { opacity: 1; }
}

/* HIGH-risk action confirmation overlay. Modal style — full-screen
   dim, centered card, clear allow/deny buttons. Auto-denies in 28s on
   the JS side; the server kills the action at 30s as a backstop. */
#confirm-overlay {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.62);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center;
    z-index: 9999;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease;
}
#confirm-overlay.visible { opacity: 1; pointer-events: auto; }
/* While confirm dialog is up, the Three.js canvas can intercept pointer
   events at the click point even though it's z-index:0 — some Chromium
   hit-test paths still find a topmost full-screen element. Disabling its
   pointer-events for the modal's lifetime fixes the interception. */
body:has(#confirm-overlay.visible) #canvas-container { pointer-events: none; }

/* Same hit-test bug used to randomly eat clicks on the input-bar buttons
   (mic / wake / webcam / proactive). Whenever the cursor is over the
   input panel OR the status pill OR an input is focused, kill canvas
   pointer-events so clicks land on the button reliably. The :has(:hover)
   pattern flips this BEFORE the click fires (hover activates on enter),
   so the button hit always wins. */
body:has(#input-panel:hover) #canvas-container,
body:has(#input-panel:focus-within) #canvas-container,
body:has(#status-pill:hover) #canvas-container,
body:has(#response-panel.visible:hover) #canvas-container {
    pointer-events: none;
}

/* Belt + suspenders: stamp the input panel + its buttons into their own
   stacking context with a z-index that nothing else in the app touches,
   and explicitly mark the buttons as clickable so no inherited
   pointer-events: none can ever leak in from a parent. */
#input-panel {
    z-index: 500 !important;       /* was 10 — was getting hit-test-beaten */
    isolation: isolate;
}
#input-panel .control-btn,
#input-panel #btn-send {
    position: relative;
    z-index: 1;
    pointer-events: auto;
}

/* Webcam button — same greyscale base as the others, lights up subtly
   when the camera stream is live. No cyan; matches the rest of the chrome. */
#btn-webcam.active {
    color: rgba(255, 255, 255, 0.95);
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.30);
}
/* Proactive eye button — same chrome as webcam when active. Disabled
   look while the brain is still pre-warming Moondream. */
#btn-proactive.active {
    color: rgba(255, 255, 255, 0.95);
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.30);
}
#btn-proactive[disabled] {
    opacity: 0.35;
    cursor: not-allowed;
}

/* Segments inside the unified status pill. Each is hidden by default
   and the wake/webcam toggle code sets a body class to show its segment. */
#status-pill .status-seg     { display: none; align-items: center; gap: 8px; }
#status-pill .status-sep     { display: none; opacity: 0.35; padding: 0 4px; }
body.wake-on        #status-seg-wake      { display: inline-flex; }
/* Camera + watching segments stay visible whenever the pill is up, so their
   on/off state reads at a glance: GREEN dot = on, RED dot = off (Dean 2026-06-21). */
body.wake-on #status-seg-cam, body.webcam-on #status-seg-cam,
body.proactive-on #status-seg-cam, body.proactive-paused #status-seg-cam,
body.wake-on #status-seg-proactive, body.webcam-on #status-seg-proactive,
body.proactive-on #status-seg-proactive, body.proactive-paused #status-seg-proactive { display: inline-flex; }
/* Separators show whenever the pill is up. */
body.wake-on #status-sep-cam, body.webcam-on #status-sep-cam,
body.proactive-on #status-sep-cam, body.proactive-paused #status-sep-cam,
body.wake-on #status-sep-proactive, body.webcam-on #status-sep-proactive,
body.proactive-on #status-sep-proactive, body.proactive-paused #status-sep-proactive { display: inline; }
/* The pill itself shows whenever at least one segment is on */
body.wake-on        #status-pill,
body.webcam-on      #status-pill,
body.proactive-on   #status-pill,
body.proactive-paused #status-pill { opacity: 1; pointer-events: auto;
                                     transform: translateY(0); }
/* Status dots — RED = off (default), GREEN = on. */
.cam-dot, .proactive-dot {
    background: #ff5a5a !important;
    box-shadow: 0 0 8px rgba(255, 90, 90, 0.55) !important;
}
body.webcam-on .cam-dot {
    background: #3ddc84 !important;
    box-shadow: 0 0 9px rgba(61, 220, 132, 0.6) !important;
}
body.proactive-on .proactive-dot {
    background: #3ddc84 !important;
    box-shadow: 0 0 9px rgba(61, 220, 132, 0.6) !important;
}
/* Paused watching reads as off (red dot) with a struck-through label. */
body.proactive-paused #status-seg-proactive .wake-label {
    opacity: 0.55;
    text-decoration: line-through;
}
.status-seg-clickable {
    cursor: pointer;
    transition: opacity 0.12s ease;
}
.status-seg-clickable:hover { opacity: 0.78; }

/* Clock + date — bottom-left corner. Top of the viewport is owned by
   the OS menu / browser tab strip / Brave URL bar, so the clock kept
   visually merging with the chrome above it. Bottom-left puts it in
   clean canvas space, near the conversation log without crowding it. */
#clock {
    position: fixed;
    bottom: 18px;
    right: 28px;
    text-align: right;
    font-family: 'SF Mono', 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.03em;
    text-shadow: 0 0 14px rgba(0, 0, 0, 0.85);
    user-select: none;
    pointer-events: none;
    z-index: 40;
    line-height: 1.15;
}
#clock .clock-time {
    display: block;
    font-size: 16px;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.96);
}
#clock .clock-date {
    display: block;
    margin-top: 2px;
    font-size: 10px;
    font-weight: 400;
    letter-spacing: 0.10em;
    color: rgba(255, 255, 255, 0.50);
    text-transform: lowercase;
}

/* Live preview tile — passive trust signal that the camera is on AND
   showing what Leon would see. Draggable anywhere, resizable from the
   bottom-right corner. JS persists position+size to localStorage. */
.webcam-preview {
    position: fixed;
    /* Default position/size; JS overrides from localStorage on load. */
    top: 60px; right: 24px;
    width: 200px; height: 150px;
    min-width: 120px; min-height: 90px;
    max-width: 800px; max-height: 600px;
    border-radius: 10px;
    overflow: hidden;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid rgba(255, 255, 255, 0.18);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
    opacity: 0; pointer-events: none;
    transition: opacity 0.18s ease;
    z-index: 60;
    cursor: grab;
}
.webcam-preview.visible { opacity: 1; pointer-events: auto; }
.webcam-preview.dragging { cursor: grabbing; transition: none; }
.webcam-preview-body {
    width: 100%; height: 100%;
    pointer-events: none;   /* clicks should hit the parent for dragging */
}
.webcam-preview-body video {
    width: 100%; height: 100%; object-fit: cover;
    transform: scaleX(-1);   /* mirror like a normal selfie cam */
}
.webcam-resize-handle {
    position: absolute;
    right: 0; bottom: 0;
    /* Bigger hit target so a finger can grab it on touch devices.
       The visible diagonal stripe is rendered via the inner ::before so
       the click area can be 28x28 while still LOOKING like a 14x14 grip. */
    width: 28px; height: 28px;
    cursor: nwse-resize;
    touch-action: none;            /* prevent the page from scrolling while resizing */
    z-index: 2;
}
.webcam-resize-handle::before {
    content: "";
    position: absolute;
    right: 0; bottom: 0;
    width: 14px; height: 14px;
    background: linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.55) 50%);
    border-bottom-right-radius: 10px;
}
.webcam-preview { touch-action: none; }   /* same — drag works on touch */

/* Always-listening (wake-word) toggle. Greyscale by default; lights up
   subtly when active — matches the rest of the input-bar control buttons. */
#btn-wake { /* shares .control-btn styles */ }
#btn-wake.active {
    color: rgba(255, 255, 255, 0.95);
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.30);
    animation: wake-btn-pulse 2.4s ease-in-out infinite;
}
@keyframes wake-btn-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.10); }
    50%      { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.04); }
}

/* Wake-word status pill — sits above the input bar when always-listening
   is on. Tells the user what phrase to say + the current phase
   (listening / heard / transcribing). */
.wake-pill {
    position: fixed;
    bottom: 75px;           /* sits just above the input bar */
    left: 36px;             /* aligned with the input bar's left edge */
    display: flex; align-items: center; gap: 8px;
    padding: 4px 10px;
    background: transparent;  /* no chrome — just floats over the canvas */
    border: none;
    border-radius: 999px;
    font-size: 11px; letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.55);
    opacity: 0; pointer-events: none;
    transform: translateY(6px);
    transition: opacity 0.18s ease, transform 0.18s ease;
    z-index: 50;
}
.wake-pill.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
.wake-pill .wake-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: rgba(180, 255, 200, 0.85);
    box-shadow: 0 0 8px rgba(120, 220, 160, 0.55);
    animation: wake-pulse 1.6s ease-in-out infinite;
}
@keyframes wake-pulse {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}
/* Phase tints on the pill (no border — chrome stays minimal) */
.wake-pill.phase-wake .wake-dot {
    background: #00ffc8;
    box-shadow: 0 0 12px rgba(0, 255, 200, 0.85);
    animation: wake-flash 0.6s ease-in-out 2;
}
.wake-pill.phase-wake { color: #c8fff0; }
.wake-pill.phase-transcribing .wake-dot {
    background: rgba(255, 255, 255, 0.95);
    box-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
}
.wake-pill.phase-transcribing { color: rgba(255, 255, 255, 0.9); }
@keyframes wake-flash {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.6); opacity: 0.7; }
}
#confirm-modal {
    width: 460px; max-width: calc(100vw - 32px);
    background: rgba(20, 20, 22, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 14px;
    padding: 22px 22px 18px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.5);
    color: rgba(255,255,255,0.92);
    font-family: 'SF Pro Display', -apple-system, system-ui, sans-serif;
}
#confirm-modal h3 {
    margin: 4px 0 12px; font-size: 15px; font-weight: 500;
    color: rgba(255,255,255,0.9);
}
.confirm-risk-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.confirm-risk-label {
    font-size: 9px; letter-spacing: 0.14em;
    color: rgba(255,255,255,0.4);
}
#confirm-risk {
    font-size: 10px; letter-spacing: 0.12em; font-weight: 600;
    padding: 2px 8px; border-radius: 999px;
    color: rgba(255, 200, 200, 0.95);
    border: 1px solid rgba(255, 140, 140, 0.45);
    background: rgba(255, 80, 80, 0.10);
}
.confirm-tool-line {
    font-family: 'SF Mono', ui-monospace, monospace;
    font-size: 13px; color: rgba(255,255,255,0.95);
    margin-bottom: 6px;
}
.confirm-tool-name {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.10);
    padding: 2px 8px; border-radius: 6px;
}
.confirm-input {
    font-family: 'SF Mono', ui-monospace, monospace;
    font-size: 11px; color: rgba(255,255,255,0.62);
    background: rgba(0,0,0,0.32);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
    padding: 8px 10px;
    margin: 6px 0 14px;
    word-break: break-word;
    max-height: 140px; overflow-y: auto;
}
.confirm-buttons { display: flex; gap: 10px; }
.confirm-buttons button {
    flex: 1; padding: 10px 14px;
    border-radius: 9px; border: 1px solid rgba(255,255,255,0.16);
    background: rgba(255,255,255,0.04);
    color: rgba(255,255,255,0.92);
    font-size: 13px; font-weight: 500;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.confirm-buttons button:hover { background: rgba(255,255,255,0.10); }
.confirm-btn-allow {
    border-color: rgba(160, 255, 160, 0.40) !important;
    color: rgba(220,255,220,0.95) !important;
}
.confirm-btn-allow:hover { background: rgba(80, 200, 80, 0.16) !important; }
.confirm-btn-deny:hover  { background: rgba(255, 80, 80, 0.14) !important; }
.confirm-hint {
    margin-top: 10px;
    text-align: center;
    font-size: 10px; letter-spacing: 0.06em;
    color: rgba(255,255,255,0.32);
}

/* Tier badge in response panel — shows which model answered (haiku/sonnet/opus).
   Subtle by default, brighter as the tier escalates so heavier replies stand out. */
.tier-badge {
    display: inline-block;
    margin-bottom: 10px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 9px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.55);
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.12);
    font-variant-numeric: tabular-nums;
    transition: opacity 0.2s, color 0.2s;
}
.tier-badge:empty { display: none; }
.tier-badge.tier-fast  { color: rgba(255,255,255,0.5); }
.tier-badge.tier-smart { color: rgba(255,255,255,0.85); border-color: rgba(255,255,255,0.28); }
.tier-badge.tier-max   { color: #fff; border-color: rgba(255,255,255,0.45); background: rgba(255,255,255,0.08); }

/* Optional small "thinking deeply…" label that appears above the dots when
   tier=max (Opus). Hidden by default. */
.thinking-label {
    display: none;
    text-align: center;
    margin-top: 4px;
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.55);
    font-style: italic;
}
.thinking-label:empty { display: none; }
#response-panel.thinking .thinking-label:not(:empty) { display: block; }

/* Three-dot pulse shown while waiting for Leon's reply. Hidden by default;
   #response-panel.thinking flips it visible and dims the (empty) text row. */
.thinking-dots { display: none; justify-content: center; gap: 6px; margin-top: 8px; }
.thinking-dots span {
    width: 7px; height: 7px; border-radius: 50%;
    background: rgba(255,255,255,0.7);
    animation: think-pulse 1s ease-in-out infinite;
}
.thinking-dots span:nth-child(2) { animation-delay: 0.18s; }
.thinking-dots span:nth-child(3) { animation-delay: 0.36s; }
@keyframes think-pulse {
    0%, 100% { opacity: 0.25; transform: scale(0.85); }
    50%      { opacity: 1.0;  transform: scale(1.1); }
}
#response-panel.thinking .thinking-dots { display: flex; }
#response-panel.thinking #response-text { min-height: 8px; }

/* ── Conversation log (translucent scrollback panel) ─────
   Sits bottom-left under Claude Usage. Stays out of the brain canvas
   center and out of the workspaces tree on the right. */
#conv-panel {
    position: fixed;
    left: 30px;
    bottom: 120px;
    width: 380px;
    min-width: 280px; min-height: 200px;
    max-width: 800px; max-height: 420px;
    background: rgba(0, 0, 0, 0.94);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 12px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    z-index: 50;
    display: flex; flex-direction: column;
    font-family: inherit;
    box-shadow: 0 8px 32px rgba(0,0,0,0.55);
}
#conv-panel.dragging { cursor: grabbing; transition: none; }
.conv-resize-handle {
    position: absolute;
    right: 0; bottom: 0;
    width: 28px; height: 28px;
    cursor: nwse-resize;
    touch-action: none;
    z-index: 2;
}
.conv-resize-handle::before {
    content: "";
    position: absolute;
    right: 0; bottom: 0;
    width: 14px; height: 14px;
    background: linear-gradient(135deg, transparent 50%, rgba(255, 255, 255, 0.35) 50%);
    border-bottom-right-radius: 12px;
}
#conv-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 12px;
    font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase;
    color: rgba(255,255,255,0.55); font-weight: 600;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    cursor: grab;
    user-select: none;
}
#conv-panel.dragging #conv-header { cursor: grabbing; }
#conv-clear {
    background: none; border: none; padding: 0;
    font: inherit; font-size: 9px; letter-spacing: 0.12em;
    text-transform: uppercase; color: rgba(255,255,255,0.4);
    cursor: pointer; transition: color 0.15s;
}
#conv-clear:hover { color: rgba(255,255,255,0.85); }
.conv-header-actions { display: flex; align-items: center; gap: 12px; }
/* Stop — borderless square glyph + label. ALWAYS visible (findable at the top
   by Clear), muted when idle, brighter + pulsing while Leon is responding. */
#conv-stop {
    background: none; border: none; padding: 0;
    font: inherit; font-size: 9px; letter-spacing: 0.12em;
    text-transform: uppercase; color: rgba(255,255,255,0.5);
    cursor: pointer; transition: color 0.15s;
    display: inline-flex; align-items: center; gap: 6px;
}
#conv-stop::before {
    content: ""; width: 6px; height: 6px; border-radius: 1px;
    background: rgba(255,255,255,0.5); transition: background 0.15s;
}
#conv-stop:hover { color: #fff; }
#conv-stop:hover::before { background: #fff; }
#conv-stop.active { color: rgba(255,255,255,0.92); animation: convStopPulse 1.4s ease-in-out infinite; }
#conv-stop.active::before { background: #fff; }
@keyframes convStopPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
#conv-body {
    flex: 1; overflow-y: auto;
    min-height: 0;
    padding: 10px 12px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.18) transparent;
}
#conv-body::-webkit-scrollbar { width: 5px; }
#conv-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 3px; }
.conv-turn { padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
.conv-turn:last-child { border-bottom: none; }
.conv-user {
    font-size: 12px; color: rgba(255,255,255,0.92);
    margin-bottom: 4px; line-height: 1.5;
}
.conv-name-dean {
    color: rgba(255,255,255,0.75); font-weight: 600; margin-right: 4px;
    user-select: text;
}
.conv-brain {
    font-size: 12px; color: rgba(255, 255, 255, 0.92);
    line-height: 1.55;
}
.conv-name-leon {
    color: #4ad9ff; font-weight: 600; margin-right: 4px;
    user-select: text;
}
.conv-brain-text { color: inherit; }
.conv-streaming .conv-brain { opacity: 0.85; }
.conv-streaming .conv-brain::after {
    content: '▌'; animation: blink 0.8s step-end infinite; opacity: 0.6;
}
@keyframes blink { 50% { opacity: 0; } }
.conv-thinking {
    padding: 6px 0; color: rgba(255, 255, 255, 0.4);
    font-size: 11px; font-style: italic;
}
.conv-thinking::before { content: ''; }
.conv-thinking .thinking-dots-inline {
    display: inline;
}
.conv-thinking .thinking-dots-inline span {
    animation: dot-pulse 1.2s ease-in-out infinite;
    opacity: 0.4;
}
.conv-thinking .thinking-dots-inline span:nth-child(2) { animation-delay: 0.2s; }
.conv-thinking .thinking-dots-inline span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot-pulse { 0%, 80%, 100% { opacity: 0.3; } 40% { opacity: 1; } }

/* Fenced code block inside the conversation log — small mono box,
   horizontal scroll, dim background. */
.conv-code {
    margin: 6px 0 4px;
    padding: 7px 9px;
    background: rgba(0,0,0,0.45);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 5px;
    font-family: 'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
    font-size: 9.5px;
    line-height: 1.45;
    color: rgba(255,255,255,0.82);
    overflow-x: auto;
    white-space: pre;
    max-height: 160px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.18) transparent;
}
.conv-code code { color: inherit; }

/* ── Input Bar ────────────────────────────────────────────── */
/* Pinned to the bottom-LEFT, not centered — the terminal stack lives on
   the right and the bar used to bleed under the bottom of the cards.
   Width caps at 580px on wide screens but shrinks before reaching the
   terminal column's left edge (terminal-stack: right:290 + width:720 ⇒
   its left edge sits at 100vw - 1010px). */
#input-panel {
    position: fixed; bottom: 24px; left: 28px;
    width: min(580px, max(360px, calc(100vw - 1040px)));
    display: flex; align-items: center; gap: 8px; z-index: 10;
}
#text-input {
    flex: 1;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.16);
    border-radius: 8px;
    padding: 11px 16px;
    color: rgba(255, 255, 255, 0.92);
    text-shadow: none;
    caret-color: #fff;
    font-family: inherit; font-size: 14px; font-weight: 400;
    outline: none; transition: border-color 0.25s, background 0.25s;
    letter-spacing: 0.01em;
}
#text-input:focus { border-color: rgba(255,255,255,0.35); background: rgba(255,255,255,0.09); }
#text-input::placeholder { color: rgba(255,255,255,0.4); text-shadow: none; }

#btn-send {
    width: 38px; height: 38px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.18);
    background: rgba(255,255,255,0.08);
    color: #fff; cursor: pointer;
    transition: all 0.18s;
    display: flex; align-items: center; justify-content: center;
}
#btn-send:hover { background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.35); box-shadow: 0 0 12px rgba(255,255,255,0.18); }

.control-btn {
    width: 38px; height: 38px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.12);
    background: rgba(255,255,255,0.05);
    color: rgba(255,255,255,0.65);
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: all 0.18s;
}
.control-btn:hover { background: rgba(255,255,255,0.12); color: #fff; border-color: rgba(255,255,255,0.22); }
.control-btn.active { background: rgba(255,255,255,0.16); border-color: rgba(255,255,255,0.35); color: #fff; box-shadow: 0 0 10px rgba(255,255,255,0.18); }
/* Muted speaker: dimmer fill + subtle red outline so the off state reads. */
.control-btn.muted { color: rgba(255,255,255,0.4); border-color: rgba(255, 95, 95, 0.45); }
.control-btn.muted:hover { color: rgba(255,255,255,0.7); border-color: rgba(255, 95, 95, 0.7); }
/* Abort/stop button — red so it stands out when active */
#btn-abort { color: #ff5f5f; border-color: rgba(255, 95, 95, 0.5); }
#btn-abort:hover { background: rgba(255, 50, 50, 0.25); color: #ff3333; border-color: rgba(255, 50, 50, 0.8); }

/* ── Attachments staged above the input bar ─────────────────
   Renders one chip per dropped/pasted file. Sits in flow above
   #input-panel; #input-panel itself is fixed: bottom 24px, so we
   pin this just above that. */
#ip-attachments {
    position: fixed;
    bottom: 75px;
    left: 28px;
    width: min(580px, max(360px, calc(100vw - 1040px)));
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    z-index: 11;
    pointer-events: auto;
}
#ip-attachments[hidden] { display: none; }
.ip-att-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    padding: 5px 4px 5px 9px;
    background: rgba(20, 20, 24, 0.88);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 999px;
    font-size: 11px;
    color: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
    animation: ip-att-in 0.18s ease;
}
@keyframes ip-att-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.ip-att-icon {
    color: rgba(255, 255, 255, 0.65);
    font-size: 11px;
    line-height: 1;
}
.ip-att-name {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    letter-spacing: 0.01em;
}
.ip-att-size {
    color: rgba(255, 255, 255, 0.45);
    font-size: 10px;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.ip-att-x {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.55);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    padding: 0 5px;
    border-radius: 50%;
    transition: color 0.15s, background 0.15s;
}
.ip-att-x:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.12);
}

/* Mobile: stack chips full-width above the bottom input bar */
@media (max-width: 900px) {
    #ip-attachments {
        left: 8px;
        right: 8px;
        width: auto;
        bottom: calc(70px + env(safe-area-inset-bottom, 0px));
    }
    .ip-att-name { max-width: 140px; }
}
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 560px) {
    #ip-attachments {
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        width: auto;
        bottom: calc(var(--sb) + var(--input-h) + 4px);
    }
}

/* Drag-and-drop file onto the Leon input bar. Same visual vocabulary as
   the terminal card drag styles (tc-drag-*) so the two feel like the same
   feature in two places. The "drop to attach" label lives in a ::before
   so we don't have to inject DOM. */
#input-panel.ip-drag-target {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.45);
    border-radius: 10px;
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.22) inset,
        0 0 26px rgba(255, 255, 255, 0.12);
    padding: 8px;
    transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
}
#input-panel.ip-drag-target::before {
    content: 'drop file to attach';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
    background: rgba(0, 0, 0, 0.5);
    border-radius: 10px;
    border: 1px dashed rgba(255, 255, 255, 0.35);
    pointer-events: none;
    z-index: 5;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
#input-panel.ip-drag-uploading {
    background: rgba(255, 255, 255, 0.04);
}
#input-panel.ip-drag-confirmed {
    animation: ip-drag-confirmed 0.7s ease;
}
@keyframes ip-drag-confirmed {
    0%   { box-shadow: 0 0 0 0 rgba(74, 217, 255, 0); }
    25%  { box-shadow: 0 0 0 2px rgba(74, 217, 255, 0.55), 0 0 28px rgba(74, 217, 255, 0.45); }
    100% { box-shadow: 0 0 0 0 rgba(74, 217, 255, 0); }
}

/* ── Loading ─────────────────────────────────────────────── */
#loading {
    position: fixed; inset: 0; background: #000;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    z-index: 1000; transition: opacity 1s ease;
}
#loading.hidden { opacity: 0; pointer-events: none; }
.loading-wordmark { font-size: 38px; letter-spacing: 0.4em; font-weight: 200; color: #fff; margin-bottom: 5px; }
.loading-company  { font-size: 10px; letter-spacing: 0.3em; color: rgba(255,255,255,0.5); text-transform: uppercase; margin-bottom: 38px; }
.loading-bar      { width: 120px; height: 2px; background: rgba(255,255,255,0.12); border-radius: 1px; margin-bottom: 18px; overflow: hidden; }
.loading-fill     { width: 0%; height: 100%; background: #fff; box-shadow: 0 0 10px rgba(255,255,255,0.85), 0 0 24px rgba(255,255,255,0.4); border-radius: 1px; transition: width 0.3s ease; }
.loading-status   { font-size: 9px; color: rgba(255,255,255,0.5); letter-spacing: 0.25em; text-transform: uppercase; }

/* ── Voice indicator (push-to-talk hold space) ─────────── */
#voice-indicator {
    position: fixed;
    bottom: 120px;
    left: 36px;
    display: flex; align-items: center; gap: 8px;
    padding: 6px 14px;
    background: rgba(8, 8, 10, 0.85);
    border: none;
    border-radius: 999px;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease;
    z-index: 1500;
}
#voice-indicator.active {
    opacity: 1;
    transform: translateY(-4px);
}
.vi-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 0 10px rgba(255, 255, 255, 0.9), 0 0 22px rgba(255, 255, 255, 0.45);
    animation: voice-pulse 1.1s ease-in-out infinite;
}
.vi-label {
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: #ffffff;
    text-shadow: 0 0 6px rgba(255, 255, 255, 0.4);
    font-weight: 500;
}
@keyframes voice-pulse {
    0%, 100% { transform: scale(1);   opacity: 1;   }
    50%       { transform: scale(1.5); opacity: 0.55; }
}

/* ── Hide graph view button injected by brain3d.js ─────── */
#graph-view-btn { display: none !important; }

::-webkit-scrollbar { width: 2px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); }

.region-label-3d { font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif; -webkit-font-smoothing: antialiased; }
.rl-name { font-size: 9px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255,255,255,0.7); }
.rl-stats { font-size: 8px; color: rgba(255,255,255,0.45); letter-spacing: 0.05em; margin-top: 2px; }

/* ── Insecure-context banner ───────────────────────────────────────
   Shown when the page is served over plain http from a non-localhost
   host. iOS/Chrome silently refuse mic + camera in this case; this
   banner surfaces the one-line fix (run `tailscale serve --bg 8000`). */
#insecure-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10000;
    padding: 10px 16px;
    padding-top: calc(10px + env(safe-area-inset-top, 0px));
    background: rgba(40, 18, 18, 0.94);
    border-bottom: 1px solid rgba(255, 120, 120, 0.45);
    color: rgba(255, 220, 220, 0.92);
    font-size: 12px;
    letter-spacing: 0.02em;
    line-height: 1.45;
    display: flex;
    align-items: center;
    gap: 10px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
#insecure-banner[hidden] { display: none; }
#insecure-banner .ib-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #ff7878;
    box-shadow: 0 0 8px rgba(255, 120, 120, 0.7);
    flex-shrink: 0;
}
#insecure-banner .ib-text { flex: 1; }
#insecure-banner code {
    font-family: 'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
    font-size: 11px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    padding: 1px 5px;
    border-radius: 3px;
    color: #ffe9c8;
}
#insecure-banner .ib-close {
    background: none; border: none;
    color: rgba(255, 220, 220, 0.6);
    font-size: 22px; line-height: 1; cursor: pointer;
    padding: 0 4px;
    flex-shrink: 0;
    transition: color 0.15s;
}
#insecure-banner .ib-close:hover { color: #fff; }

/* ────────────────────────────────────────────────────────────────────
   MOBILE LAYOUT
   The whole desktop UI is absolute-positioned for a wide viewport.
   Below ~900px we flip the body to a scrollable single-column flow:
   panels become static blocks stacked vertically, the brain canvas
   stays as a dim background, the input bar pins to the bottom with
   safe-area insets, and tap targets bump up to 42px.
   ──────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
    html, body {
        overflow-y: auto;
        overflow-x: hidden;
        height: auto;
        min-height: 100vh;
        min-height: 100dvh;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
    body {
        padding-bottom: calc(90px + env(safe-area-inset-bottom, 0px));
        padding-top: env(safe-area-inset-top, 0px);
    }

    /* Brain 3D — stays as a fixed background, dimmed so text panels read */
    #canvas-container {
        position: fixed;
        inset: 0;
        opacity: 0.35;
        z-index: 0;
        pointer-events: none !important;
    }

    /* Identity bar (top, sticky) — combines wordmark + brain info trigger */
    #identity {
        position: sticky;
        top: 0;
        left: 0;
        right: 0;
        z-index: 60;
        margin: 0;
        padding: 14px 16px 10px;
        padding-top: calc(14px + env(safe-area-inset-top, 0px));
        background: rgba(0, 0, 0, 0.88);
        backdrop-filter: blur(14px);
        -webkit-backdrop-filter: blur(14px);
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
        display: flex;
        align-items: center;
        gap: 14px;
    }
    .id-mark { font-size: 14px; }
    .id-sub  { display: none; } /* hide subtitle to save space */
    #brain-info-btn { margin-top: 0; margin-left: auto; padding: 8px 14px; }

    /* Claude Usage — block under header */
    #claude-usage {
        position: static;
        width: auto;
        margin: 14px 16px;
        z-index: 1;
    }

    /* Workspaces — block, no internal scroll cap */
    #workspaces-panel {
        position: static;
        width: auto;
        max-height: none;
        margin: 14px 16px;
        overflow: visible;
    }
    #ws-new-btn { padding: 12px 14px; font-size: 13px; }
    .ws-item, .ws-folder-hd { padding-top: 8px; padding-bottom: 8px; }
    .ws-item { font-size: 14px; }
    .ws-folder-name { font-size: 13px; }

    /* Terminal stack — full-width block, height driven by cards */
    #terminal-stack {
        position: static;
        width: auto;
        max-width: 100%;
        max-height: none;
        right: auto;
        top: auto;
        margin: 0 12px 24px;
        padding: 0;
        overflow: visible;
        gap: 14px;
    }
    .terminal-card {
        height: 65vh;
        min-height: 320px;
    }
    .terminal-card.tc-expanded { height: 75vh; }
    /* Slim wide desktop scrollbar isn't useful in mobile flow */
    #terminal-stack::-webkit-scrollbar { width: 0; height: 0; }

    /* Conversation log — block */
    #conv-panel {
        position: static;
        width: auto;
        max-height: 220px;
        margin: 0 16px 14px;
        bottom: auto;
        left: auto;
    }

    /* Response panel — full-width float above input */
    #response-panel {
        left: 12px;
        right: 12px;
        bottom: calc(90px + env(safe-area-inset-bottom, 0px));
        padding: 0 4px;
    }
    #response-text { font-size: 16px; max-width: 100%; }

    /* Brain Info popover — full-width drawer under header */
    #brain-info-popover {
        top: 64px;
        top: calc(64px + env(safe-area-inset-top, 0px));
        left: 12px;
        right: 12px;
        width: auto;
        transform: translateY(-8px);
    }
    #brain-info-popover.open { transform: translateY(0); }

    /* Modals — leave a bit of edge breathing room on phones */
    .modal {
        width: calc(100vw - 24px);
        max-width: calc(100vw - 24px);
        max-height: calc(100vh - 80px);
        overflow-y: auto;
    }
    .modal-body { padding: 14px 14px; }
    .modal-field input[type="text"],
    .modal-field select,
    .custom-select-btn {
        font-size: 16px; /* prevent iOS zoom-on-focus */
        padding: 10px 12px;
    }

    /* Input bar — pinned full-width across the bottom */
    #input-panel {
        position: fixed;
        left: 8px;
        right: 8px;
        bottom: calc(8px + env(safe-area-inset-bottom, 0px));
        width: auto;
        gap: 6px;
        padding: 8px;
        background: rgba(0, 0, 0, 0.82);
        backdrop-filter: blur(14px);
        -webkit-backdrop-filter: blur(14px);
        border-radius: 14px;
        border: 1px solid rgba(255, 255, 255, 0.08);
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
    }
    #text-input {
        font-size: 16px; /* prevent iOS zoom-on-focus */
        padding: 11px 14px;
    }
    #btn-send,
    .control-btn {
        width: 42px;
        height: 42px;
        flex-shrink: 0;
    }

    /* Clock — small badge top-right of viewport, won't fight content */
    #clock {
        position: fixed;
        top: calc(14px + env(safe-area-inset-top, 0px));
        right: 16px;
        bottom: auto;
        left: auto;
        text-align: right;
        z-index: 61;
    }
    #clock .clock-time { font-size: 12px; }
    #clock .clock-date { font-size: 9px; }

    /* Status pill — sits above the input bar, full-width-aware */
    .wake-pill {
        left: 16px;
        right: 16px;
        bottom: calc(70px + env(safe-area-inset-bottom, 0px));
        justify-content: center;
    }

    /* Voice indicator — same anchor as status pill */
    #voice-indicator {
        left: 16px;
        right: 16px;
        bottom: calc(70px + env(safe-area-inset-bottom, 0px));
        justify-content: center;
    }

    /* Loading screen — keep the wordmark legible without overflow */
    .loading-wordmark { font-size: 32px; }

    /* Webcam preview tile is a free-floating draggable box. On a phone
       it covers actual content — hide it; the camera still uploads frames
       to the server in the background when enabled. */
    #webcam-preview,
    .webcam-preview { display: none !important; }
}

/* Narrow phones — drop secondary toggles so the input + send stay roomy */
@media (max-width: 480px) {
    #btn-webcam,
    #btn-proactive { display: none; }

    #identity { padding: 12px 14px 8px; }
    #claude-usage,
    #workspaces-panel,
    #conv-panel { margin-left: 12px; margin-right: 12px; }

    .terminal-card { height: 60vh; min-height: 280px; padding: 10px 8px 8px; }
    .tc-name { font-size: 12px; }
    .tc-id   { display: none; } /* internal id chip is noise on small screens */
}

/* Landscape phone (≤1024w, ≤560h, landscape orientation) — restore the
   desktop multi-panel layout, just scaled down so it fits an iPhone in
   landscape. Three columns: Claude Usage (left rail), terminal stack
   (center, fills available space), Workspaces (right rail). Input bar
   sits at the bottom of the center column. Conv panel + secondary
   control toggles are hidden — they don't fit and aren't needed to drive
   the system on a phone. */
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 560px) {
    /* Undo the portrait stacked-flow rules from the (max-width: 900px) block */
    html, body {
        overflow: hidden;
        height: 100vh;
        height: 100dvh;
    }
    body {
        padding-bottom: 0;
        padding-top: 0;
    }

    /* Brain canvas — slightly brighter as a real backdrop, not a faded hint */
    #canvas-container { opacity: 0.5; }

    /* CSS variables for the rail widths so the center column math
       only lives in one place. SL/SR include the safe-area inset. */
    body {
        --rail-l: 150px;
        --rail-r: 160px;
        --input-h: 56px;
        --header-h: 36px;
        --sl: calc(env(safe-area-inset-left, 0px) + 12px);
        --sr: calc(env(safe-area-inset-right, 0px) + 12px);
        --st: calc(env(safe-area-inset-top, 0px) + 6px);
        --sb: calc(env(safe-area-inset-bottom, 0px) + 8px);
    }

    /* Top strip — identity wordmark + brain-info toggle, transparent */
    #identity {
        position: fixed;
        top: var(--st);
        left: var(--sl);
        right: auto;
        margin: 0;
        padding: 0;
        background: transparent;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border: none;
        display: flex;
        align-items: center;
        gap: 10px;
        z-index: 60;
    }
    .id-mark { font-size: 11px; letter-spacing: 0.4em; }
    .id-sub  { display: none; }
    #brain-info-btn {
        margin-top: 0;
        margin-left: 0;
        padding: 5px 10px;
        font-size: 9px;
    }

    /* Left rail — Claude Usage, compact + scrollable */
    #claude-usage {
        position: fixed;
        top: calc(var(--st) + var(--header-h));
        left: var(--sl);
        width: var(--rail-l);
        max-height: calc(100dvh - var(--st) - var(--sb) - var(--header-h) - var(--input-h) - 12px);
        margin: 0;
        overflow-y: auto;
        overflow-x: hidden;
        z-index: 10;
        scrollbar-width: thin;
    }
    #claude-usage .section-label { font-size: 8px; margin-bottom: 8px; letter-spacing: 0.16em; }
    #claude-usage .cu-row-label,
    #claude-usage .cu-row-pct,
    #claude-usage .cu-row-reset,
    #claude-usage .cu-extra-label,
    #claude-usage .cu-extra-value,
    #claude-usage .status-text,
    #claude-usage .cu-plan { font-size: 9px; }
    #claude-usage .cu-quotas { gap: 7px; }
    #claude-usage .cu-status-row { margin-bottom: 10px; }
    #claude-usage .cu-extra { padding-top: 8px; }
    .rate-metric { font-size: 30px; }

    /* Right rail — Workspaces, compact + scrollable */
    #workspaces-panel {
        position: fixed;
        top: calc(var(--st) + var(--header-h));
        right: var(--sr);
        left: auto;
        width: var(--rail-r);
        max-height: calc(100dvh - var(--st) - var(--sb) - var(--header-h) - var(--input-h) - 12px);
        margin: 0;
        overflow-y: auto;
        overflow-x: hidden;
        z-index: 10;
    }
    #ws-new-btn { padding: 7px 10px; font-size: 10px; margin-bottom: 8px; }
    .ws-header { margin-bottom: 10px; }
    .ws-item, .ws-folder-hd { padding: 4px 0; }
    .ws-item { font-size: 11px; }
    .ws-folder-name { font-size: 11px; }
    .ws-folder-meta { font-size: 8px; }

    /* Center column — terminal stack fills the gap between the rails */
    #terminal-stack {
        position: fixed;
        top: calc(var(--st) + var(--header-h));
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        bottom: calc(var(--sb) + var(--input-h) + 8px);
        width: auto;
        max-width: none;
        max-height: none;
        margin: 0;
        padding: 0;
        gap: 10px;
        overflow-y: auto;
    }
    .terminal-card {
        height: 100%;
        min-height: 0;
        padding: 8px 8px 6px;
    }
    .terminal-card.tc-expanded { height: 100%; }

    /* Hide conv panel — center column has higher priority than scrollback */
    #conv-panel { display: none; }

    /* Response panel — floats above input, within the center column */
    #response-panel {
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        bottom: calc(var(--sb) + var(--input-h) + 12px);
    }
    #response-text { font-size: 13px; }

    /* Input bar — pinned at the bottom of the center column */
    #input-panel {
        position: fixed;
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        bottom: var(--sb);
        width: auto;
        padding: 6px;
        gap: 5px;
        background: rgba(0, 0, 0, 0.82);
        backdrop-filter: blur(14px);
        -webkit-backdrop-filter: blur(14px);
        border-radius: 12px;
        border: 1px solid rgba(255, 255, 255, 0.08);
    }
    #text-input { padding: 9px 12px; font-size: 16px; }
    #btn-send,
    .control-btn { width: 38px; height: 38px; }
    /* On the iPhone width-budget there's room for send + mic + speaker + wake.
       Webcam + proactive eye are nice-to-haves — drop them here. */
    #input-panel #btn-webcam,
    #input-panel #btn-proactive { display: none; }

    /* Clock — top right corner, single line */
    #clock {
        position: fixed;
        top: var(--st);
        right: var(--sr);
        bottom: auto;
        left: auto;
        z-index: 61;
        text-align: right;
    }
    #clock .clock-time { font-size: 11px; }
    #clock .clock-date { display: none; }

    /* Brain Info popover — drop into the center column instead of left rail */
    #brain-info-popover {
        top: calc(var(--st) + var(--header-h));
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        width: auto;
        max-height: calc(100dvh - var(--st) - var(--sb) - var(--header-h) - var(--input-h) - 20px);
        overflow-y: auto;
        transform: translateY(-6px);
    }
    #brain-info-popover.open { transform: translateY(0); }

    /* Status pill + voice indicator — float just above the input bar */
    .wake-pill,
    #voice-indicator {
        left: calc(var(--sl) + var(--rail-l) + 12px);
        right: calc(var(--sr) + var(--rail-r) + 12px);
        bottom: calc(var(--sb) + var(--input-h) + 4px);
        justify-content: center;
    }
}

/* Tighter sub-band for very short landscape (e.g. iPhone mini ~375h) */
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 400px) {
    body {
        --rail-l: 138px;
        --rail-r: 148px;
        --input-h: 50px;
        --header-h: 30px;
    }
    .terminal-card { padding: 6px 6px 4px; }
    #text-input { padding: 7px 10px; }
    #btn-send,
    .control-btn { width: 34px; height: 34px; }
    /* Drop wake too if we're really tight on width-budget */
    #input-panel #btn-wake { display: none; }
}

/* Flip-camera button is mobile-only — hidden everywhere by default; the
   mobile block re-shows it once the cam is on. */
#btn-flip-cam { display: none; }

/* ─────────────────────────────────────────────────────────────────────
   MOBILE CLEAN-UP PASS (2026-06-27) — Dean wants the phone clean in BOTH
   orientations: vertical, borderless, camera button + tile visible, no
   desktop clutter (no terminals/workspaces even when rotated), no
   integrations button crowding the clock, activity log gone. This block is
   LAST so it wins source order. Applies to all phones (portrait + landscape).
   ───────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {

    /* Force the clean stacked scroll layout in BOTH orientations — the
       landscape block tried to restore the desktop 3-column rig; we override
       it back to a simple phone page. */
    html, body {
        overflow-y: auto !important;
        overflow-x: hidden !important;
        height: auto !important;
        min-height: 100dvh;
    }

    /* Make the phone page an explicit ordered column so the stack order is
       guaranteed no matter what inline drag-positions got saved on desktop.
       Header first, then conversation, then activity log, then camera. The
       input bar is position:fixed so it stays out of this flow. */
    body {
        display: flex !important;
        flex-direction: column !important;
    }
    #identity        { order: 0 !important; }
    #activity-panel  { order: 1 !important; }   /* activity log ON TOP */
    #conv-panel      { order: 2 !important; }   /* conversation UNDER it */
    #webcam-preview.webcam-preview { order: 3 !important; }  /* camera below */

    /* THE actual eyesore: the 3D brain + its floating region labels
       (FRONTAL LOBE, PARIETAL LOBE, etc.) render right on top of the
       conversation text and make it unreadable. On a phone the brain is pure
       noise — kill the canvas AND the labels so the page is just clean text. */
    #canvas-container { display: none !important; }
    /* The labels live in #region-labels as .sector-label-3d — NOT
       .region-label-3d (that class never existed; my first pass missed them,
       which is why the FRONTAL/PARIETAL/etc. text survived). Kill both. */
    #region-labels,
    .sector-label-3d  { display: none !important; }

    /* Solid black page so the boxes read cleanly with the brain gone. */
    body { background: #000 !important; }

    /* Borders off — Sabr rule: nothing gets a box drawn around it. */
    #identity      { border-bottom: none !important; }
    #input-panel   { border: none !important;
                     box-shadow: 0 8px 30px rgba(0,0,0,0.6) !important; }

    /* Declutter: desktop power panels + noisy logs + the integrations button.
       The phone is just: header + clock, camera, conversation, input.
       (Reversible — say the word to bring any back.) */
    #claude-usage,
    #workspaces-panel,
    #terminal-stack,
    #integrations-btn { display: none !important; }

    /* Two stacked boxes — conversation on top, activity log under it — each a
       clean static card whose TEXT SCROLLS INSIDE (the #conv-body / #act-body
       children already scroll; we just constrain the card height and put them
       in normal flow, not floating/draggable). Then the camera box sits below.
       Dean: "two boxes on top of each other, then camera below that." */
    #conv-panel,
    #activity-panel {
        display: flex !important;
        position: static !important;
        left: auto !important; right: auto !important;
        top: auto !important; bottom: auto !important;
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        margin: 10px 12px 0 !important;
        height: 30vh !important;          /* fixed card height → body scrolls */
        max-height: 34vh !important;
        min-height: 140px !important;
        border: none !important;          /* borders off */
        border-radius: 16px !important;
        background: rgba(255,255,255,0.035) !important;
        box-shadow: none !important;
        z-index: 1 !important;
        transform: none !important;       /* drop any leftover desktop drag offset */
        touch-action: auto !important;
        cursor: default !important;
    }
    /* Headers shouldn't act like drag handles in the stacked layout. */
    #conv-header, #act-header { cursor: default !important; }
    /* The scroll bodies fill the card and scroll on their own. */
    #conv-body, #act-body { flex: 1 1 auto !important; overflow-y: auto !important; min-height: 0 !important; }
    /* No drag-resize grips on the phone. */
    .conv-resize-handle, .act-resize-handle { display: none !important; }

    /* Camera BUTTON + FLIP button must be tappable on the phone. The camera
       button was hidden on narrow widths/landscape (why Dean couldn't turn the
       cam on); the flip button is mobile-only and appears once the cam is on. */
    #input-panel #btn-webcam { display: inline-flex !important; }
    #input-panel #btn-flip-cam { display: none !important; }
    body.webcam-on #input-panel #btn-flip-cam { display: inline-flex !important; }

    /* Camera TILE — clean borderless vertical, in normal flow under header.
       Only shows when the cam is actually on (.visible). */
    #webcam-preview.webcam-preview {
        position: static !important;
        display: none;                      /* collapsed until camera is on */
        top: auto !important; left: auto !important;
        right: auto !important; bottom: auto !important;
        width: auto !important;
        height: auto !important;
        max-width: none !important; max-height: none !important;
        min-width: 0 !important; min-height: 0 !important;
        margin: 12px 12px 4px !important;
        height: 40vh !important;            /* concrete height — can't collapse */
        min-height: 240px !important;
        aspect-ratio: auto !important;
        border: none !important;
        border-radius: 18px !important;
        box-shadow: 0 10px 34px rgba(0,0,0,0.55) !important;
        background: rgba(255,255,255,0.03) !important;
        cursor: default !important;
        touch-action: auto !important;
        z-index: 1 !important;
    }
    #webcam-preview.webcam-preview.visible {
        display: block !important;
        opacity: 1 !important;
        pointer-events: auto !important;
    }
    .webcam-preview-body { border-radius: 18px; overflow: hidden; }
    /* No dragging/resizing on the phone — it's an in-flow tile now. */
    .webcam-resize-handle { display: none !important; }

    /* Back camera shouldn't be mirrored (selfie flip is front-cam only). */
    body.cam-back .webcam-preview-body video,
    body.cam-back #webcam-video { transform: none !important; }

    /* Input bar — full-width bottom, no rail offsets even in landscape. */
    #input-panel {
        position: fixed !important;
        left: 8px !important; right: 8px !important;
        bottom: calc(8px + env(safe-area-inset-bottom, 0px)) !important;
        width: auto !important;
    }

    /* Leave room at the bottom so the last box isn't hidden behind the input. */
    body { padding-bottom: calc(86px + env(safe-area-inset-bottom, 0px)) !important; }

    /* Clock removed on the phone — Dean doesn't want the time/date up there. */
    #clock { display: none !important; }

    /* THE camera-button fix. In portrait the input row is too narrow to hold
       send + mic + speaker + wake + webcam, so webcam (5th in DOM order) got
       pushed off the right edge — invisible until you rotate and gain width.
       Keep the essentials Dean actually uses on the phone (mic, speaker,
       camera), drop wake + proactive, and lock button sizes so the text field
       shrinks instead of the buttons clipping. Camera now shows in BOTH
       orientations. */
    #input-panel #btn-wake,
    #input-panel #btn-proactive { display: none !important; }
    #input-panel { flex-wrap: nowrap !important; }
    #input-panel #btn-send,
    #input-panel .control-btn { flex: 0 0 auto !important; }
    #text-input { min-width: 0 !important; flex: 1 1 auto !important; }
}

/* ── Agent transcript panel ───────────────────────────────────
   Dean's ask: clicking an agent row should slide out a rectangle the same
   shape as a terminal card, showing that agent's real work in plain English
   while it cooks — not a truncated one-line ticker.
   Geometry deliberately MIRRORS #terminal-stack (top 26 / right 290 / 720w)
   so the two read as the same surface. */
#agent-panel {
    position: fixed;
    top: 26px;
    right: 290px;
    width: 720px;
    max-width: calc(100vw - 320px);
    max-height: calc(100vh - 116px);
    z-index: 101;               /* just above terminal cards */
    display: none;
    flex-direction: column;
    pointer-events: auto;
    background: rgba(6,6,8,0.96);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 10px;
    padding: 12px 10px 10px;
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    animation: tc-enter 0.25s ease;
}
#agent-panel.open { display: flex; }

.ap-hd {
    display: flex; align-items: center; gap: 8px;
    padding-bottom: 8px; margin-bottom: 8px;
    border-bottom: 1px solid rgba(255,255,255,0.10);
    flex: 0 0 auto;
}
.ap-name {
    font-size: 12px; letter-spacing: 0.3px;
    color: rgba(255,255,255,0.92); font-weight: 600;
}
.ap-status { font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px; }
.ap-status.running { color: #eaeaea; }
.ap-status.done    { color: rgba(255,255,255,0.45); }
.ap-status.failed  { color: #ff6b6b; }
/* Pulsing dot while live, so a working agent never looks identical to a
   finished one — same signal language as the agent rows. */
.ap-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: rgba(255,255,255,0.3); flex: 0 0 auto;
}
.ap-dot.live { background: #fff; animation: ap-pulse 1.4s ease-in-out infinite; }
@keyframes ap-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }

.ap-spacer { flex: 1 1 auto; }
.ap-btn {
    background: none; border: 1px solid rgba(255,255,255,0.15);
    color: rgba(255,255,255,0.6); border-radius: 4px;
    font-size: 10px; padding: 2px 7px; cursor: pointer;
    font-family: inherit;
}
.ap-btn:hover { color: #fff; border-color: rgba(255,255,255,0.4); }
.ap-btn.armed { color: #fff; border-color: rgba(255,255,255,0.45); }

.ap-body {
    flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 11px; line-height: 1.55;
    color: rgba(255,255,255,0.78);
    white-space: pre-wrap; word-break: break-word;
    scrollbar-width: thin;
}
.ap-body::-webkit-scrollbar { width: 8px; }
.ap-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 2px; }
.ap-empty { color: rgba(255,255,255,0.35); font-style: italic; }

/* Line kinds, so the log is skimmable instead of a wall */
.ap-l-tool   { color: #9ecbff; }              /* » tool call */
.ap-l-out    { color: rgba(255,255,255,0.45); } /* ← tool result */
.ap-l-think  { color: rgba(255,255,255,0.35); font-style: italic; }
.ap-l-say    { color: rgba(255,255,255,0.88); }
.ap-l-mark   { color: #7ee787; }              /* == finished / === header */
