/* 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;
    /* Sleep-mode gray-out transitions both ways (drain + wake). */
    transition: filter 2s ease;
}

/* ── SI sleep mode — gray-out ─────────────────────────────────────────
   While the SI sleeps, the whole dashboard drains to grayscale over ~2s
   and returns to full color the same way on wake. Driven by the
   /api/sleep/state poller in index.html toggling body.leon-sleeping.
   Fail-safe by design: the default body has NO filter, so if the state
   feed is missing or erroring the UI stays in normal full color. */
body.leon-sleeping {
    filter: grayscale(1) saturate(0.6) brightness(0.85);
}

#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: 260px;
    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; transform-origin: center center; will-change: transform; }
#conv-panel.conv-jello-settle {
    animation: conv-jello 0.62s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
    transform-origin: center center;
}
@keyframes conv-jello {
    0%   { transform: skewX(var(--jello-skew, 0deg)) scale(var(--jello-scale, 1)); }
    30%  { transform: skewX(calc(var(--jello-skew, 0deg) * -0.55)) scale(1.015); }
    50%  { transform: skewX(calc(var(--jello-skew, 0deg) * 0.28)) scale(0.99); }
    70%  { transform: skewX(calc(var(--jello-skew, 0deg) * -0.12)) scale(1.005); }
    100% { transform: skewX(0deg) scale(1); }
}
.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;
    /* Click-to-replay (Dean, 2026-08-18). The speaker glyph is drawn as a
       ::after on the label rather than added to the four HTML paint sites,
       for one hard reason: server/__init__.py rebrands this element with a
       LITERAL string replace on `conv-name-leon">Leon:` so every SI shows
       its own name. Any markup inserted between the class and the name
       would break that replace and every non-Leon SI would be stuck reading
       "Leon:". CSS can't break it. */
    cursor: pointer;
    position: relative;
    padding-right: 15px;
    transition: color 0.15s, text-shadow 0.15s;
}
.conv-name-leon::after {
    content: '';
    position: absolute; right: 1px; top: 50%;
    width: 11px; height: 11px; margin-top: -5px;
    /* Speaker glyph, currentColor via mask so it always matches the label. */
    background-color: currentColor;
    -webkit-mask: var(--spk) center/contain no-repeat;
            mask: var(--spk) center/contain no-repeat;
    --spk: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M11 5L6 9H2v6h4l5 4V5z'/><path d='M15.5 8.5a5 5 0 0 1 0 7'/><path d='M18.5 5.5a9 9 0 0 1 0 13'/></svg>");
    opacity: 0.45;
    transition: opacity 0.15s;
}
.conv-name-leon:hover { color: #7fe6ff; text-shadow: 0 0 8px rgba(74,217,255,0.35); }
.conv-name-leon:hover::after { opacity: 1; }
/* While that message is being re-read, the glyph pulses so it's obvious
   WHICH line is talking when several are on screen. */
.conv-name-leon.replaying::after { opacity: 1; animation: spk-pulse 0.9s ease-in-out infinite; }
@keyframes spk-pulse { 50% { opacity: 0.25; } }
.conv-name-leon.replay-wait { opacity: 0.6; }
.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); }

/* ── Leon voice volume (Dean, 2026-08-18) ────────────────────────────
   Sits right of the proactive eye button. Windows has no per-app volume
   mixer reachable from a browser tab, so this scales Leon's own audio
   element only — other tabs, music, and everyone else's voice are
   untouched. Matches .control-btn exactly (same 38px height, same
   border, same fill) so it reads as part of the same row, not a widget
   bolted on. */
.volume-control {
    display: flex; align-items: center; gap: 7px;
    height: 38px; padding: 0 9px 0 9px;
    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);
    transition: all 0.18s;
    cursor: pointer;
    user-select: none;
}
.volume-control:hover { background: rgba(255,255,255,0.12); color: #fff; border-color: rgba(255,255,255,0.22); }
.volume-control.muted { color: rgba(255,255,255,0.4); border-color: rgba(255, 95, 95, 0.45); }
.volume-control svg { flex: 0 0 auto; }
/* The speaker glyph is the mute toggle — separate hit area from the rail. */
#volume-icon { cursor: pointer; display: flex; }

#volume-slider {
    -webkit-appearance: none; appearance: none;
    width: 74px; height: 4px; margin: 0;
    border-radius: 3px;
    background: rgba(255,255,255,0.14);
    outline: none; cursor: pointer;
}
/* Filled portion left of the knob — driven by a JS-set custom property so
   the fill tracks the value in both engines (no ::-moz-range-progress in
   webkit, no gradient trick in gecko without it). */
#volume-slider { background: linear-gradient(to right,
    rgba(255,255,255,0.55) 0%,
    rgba(255,255,255,0.55) var(--vol-pct, 100%),
    rgba(255,255,255,0.14) var(--vol-pct, 100%),
    rgba(255,255,255,0.14) 100%); }
#volume-slider::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 11px; height: 11px; border-radius: 50%;
    background: #fff;
    border: 0;
    box-shadow: 0 0 6px rgba(255,255,255,0.35);
    transition: transform 0.12s;
}
#volume-slider::-moz-range-thumb {
    width: 11px; height: 11px; border-radius: 50%;
    background: #fff; border: 0;
    box-shadow: 0 0 6px rgba(255,255,255,0.35);
}
.volume-control:hover #volume-slider::-webkit-slider-thumb { transform: scale(1.18); }
#volume-slider::-moz-range-track { background: transparent; }
.volume-control.muted #volume-slider { filter: grayscale(1) opacity(0.55); }

/* Numeric readout — only while the user is actually adjusting, so the row
   stays quiet at rest instead of carrying a permanent number. */
#volume-readout {
    font-size: 10px; letter-spacing: 0.04em;
    color: rgba(255,255,255,0.75);
    /* Dean, 2026-08-18: was min-width 26px + text-align right, which left
       dead slack between the rail and the number at every value (a 3-digit
       tabular string at 10px is ~19px wide, so 26px always over-reserved,
       and right-alignment dumped the leftover as a gap on the rail side).
       Reserve exactly the widest string instead so the number sits tight
       to the rail while the control's own width still never jitters. */
    min-width: 19px; text-align: right;
    margin-left: -2px;
    opacity: 0; transition: opacity 0.15s;
    font-variant-numeric: tabular-nums;
}
.volume-control:hover #volume-readout, .volume-control.adjusting #volume-readout { opacity: 1; }
/* Narrow screens: the rail is the first thing to go, glyph stays as a mute. */
@media (max-width: 620px) { #volume-slider, #volume-readout { display: none; } .volume-control { padding: 0 10px; } }
/* 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; }

/* ── Input bar attached to the conversation box (Dean, 2026-08-23) ──────
   #input-panel and #ip-attachments now live INSIDE #conv-panel's DOM (right
   after #conv-body, before the resize handle) so the whole thing reads as
   one box: header, scrolling history, input row — and dragging/resizing
   the conversation panel carries the input + all its buttons with it.
   Only override on desktop widths; the >900px mobile rules further down
   re-declare position:fixed for #input-panel/#ip-attachments regardless of
   where they sit in the DOM, so the phone layout is untouched. */
@media (min-width: 901px) {
    #conv-panel { overflow: hidden; }
    #conv-panel #input-panel {
        position: static;
        left: auto; right: auto; bottom: auto; top: auto;
        width: auto;
        flex: 0 0 auto;
        flex-wrap: wrap;
        z-index: auto; isolation: auto;
        padding: 8px 10px 10px;
        margin: 0;
        border-top: 1px solid rgba(255, 255, 255, 0.08);
    }
    #conv-panel #ip-attachments {
        position: static;
        left: auto; right: auto; bottom: auto;
        width: auto;
        z-index: auto;
        padding: 6px 10px 0;
    }
}
.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; }
    /* Labels live in #region-labels. v1 emitted .sector-label-3d (7 lobe
       pills); v2 emits .region-label-3d (18 region labels) plus #lobe-legend
       and #graph-view-btn. Kill all of them — none belong on a phone. */
    #region-labels,
    #lobe-legend,
    #graph-view-btn,
    .sector-label-3d,
    .region-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 */

/* ═══════════════════════════════════════════════════════════════════════
   LIQUID GLASS  —  Apple iOS 26 / macOS Tahoe material, ported to the SI
   dashboard. (Dean, 2026-08-23)

   Apple's Liquid Glass is four stacked effects, not a blur:
     1. a real-time backdrop blur WITH saturation boost (the lens)
     2. a translucent tint that lightens/darkens with content behind it
     3. a specular highlight — a bright hairline along the top edge and an
        inner rim light, so the element reads as a solid piece of glass
     4. dynamic response — a lensing highlight that tracks the pointer, and
        a soft compress on press, so it behaves like liquid, not a sticker
   Motion uses Apple's spring curve, not linear ease.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
    --lg-tint:        rgba(255, 255, 255, 0.07);
    --lg-tint-hover:  rgba(255, 255, 255, 0.13);
    --lg-tint-active: rgba(255, 255, 255, 0.18);
    --lg-rim:         rgba(255, 255, 255, 0.20);
    --lg-rim-hover:   rgba(255, 255, 255, 0.34);
    --lg-blur:        saturate(185%) blur(28px);
    --lg-blur-heavy:  saturate(200%) blur(42px);
    --lg-spring:      cubic-bezier(0.32, 0.72, 0, 1);
    --lg-shadow:      0 8px 26px rgba(0, 0, 0, 0.42), 0 1px 2px rgba(0, 0, 0, 0.30);
}

/* ── The base material ───────────────────────────────────────────── */
.lg-btn,
.lg-field,
.lg-surface {
    position: relative;
    isolation: isolate;
    background: var(--lg-tint);
    backdrop-filter: var(--lg-blur);
    -webkit-backdrop-filter: var(--lg-blur);
    border: 0.5px solid var(--lg-rim);
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.42),   /* top specular hairline */
        inset 0 -0.5px 0 0 rgba(255, 255, 255, 0.07),  /* bottom bounce light  */
        var(--lg-shadow);
    transition:
        background 0.32s var(--lg-spring),
        border-color 0.32s var(--lg-spring),
        box-shadow 0.32s var(--lg-spring),
        transform 0.28s var(--lg-spring),
        backdrop-filter 0.32s var(--lg-spring);
}

/* Specular sheen — the glossy curve across the top third of the glass. */
.lg-btn::before,
.lg-surface::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(
        to bottom,
        rgba(255, 255, 255, 0.16) 0%,
        rgba(255, 255, 255, 0.05) 38%,
        rgba(255, 255, 255, 0.00) 62%,
        rgba(255, 255, 255, 0.04) 100%);
    opacity: 0.9;
}

/* Lensing highlight that follows the cursor — the "liquid" part.
   --mx/--my are written by the pointer handler in index.html. */
.lg-btn::after,
.lg-surface::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: -1;
    opacity: 0;
    transition: opacity 0.35s var(--lg-spring);
    background: radial-gradient(
        120px circle at var(--mx, 50%) var(--my, 50%),
        rgba(255, 255, 255, 0.30) 0%,
        rgba(255, 255, 255, 0.10) 34%,
        rgba(255, 255, 255, 0.00) 70%);
}
.lg-btn:hover::after,
.lg-surface:hover::after { opacity: 1; }

.lg-btn:hover {
    background: var(--lg-tint-hover);
    border-color: var(--lg-rim-hover);
    backdrop-filter: var(--lg-blur-heavy);
    -webkit-backdrop-filter: var(--lg-blur-heavy);
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.60),
        inset 0 -0.5px 0 0 rgba(255, 255, 255, 0.10),
        0 10px 30px rgba(0, 0, 0, 0.48);
}
/* Press = the glass compresses and the liquid pools. Apple scales DOWN. */
.lg-btn:active {
    background: var(--lg-tint-active);
    transform: scale(0.955);
    transition-duration: 0.12s;
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.30),
        inset 0 2px 8px rgba(0, 0, 0, 0.30);
}
.lg-btn:focus-visible {
    outline: none;
    border-color: rgba(255, 255, 255, 0.55);
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.60),
        0 0 0 3px rgba(255, 255, 255, 0.14),
        var(--lg-shadow);
}

/* ── Pill / icon button geometry ─────────────────────────────────── */
.lg-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    color: rgba(255, 255, 255, 0.92);
    font: 500 11px/1 inherit;
    letter-spacing: 0.04em;
    cursor: pointer;
    border-radius: 999px;
    padding: 7px 13px;
    -webkit-user-select: none; user-select: none;
}
.lg-icon-btn {
    width: 30px; height: 30px;
    padding: 0;
    border-radius: 50%;
}
.lg-icon-btn svg { display: block; opacity: 0.92; transition: transform 0.5s var(--lg-spring); }
.lg-icon-btn:hover svg { transform: rotate(45deg); }

/* Kill the old white dot + inline text styling on the settings button. */
#integrations-btn::before { content: none !important; }
#integrations-btn {
    display: inline-flex !important;
    align-items: center; justify-content: center;
    gap: 0 !important;
    font-size: 0;                 /* no stray text node */
}
#integrations-btn svg { font-size: 15px; }

/* ── Glass text field (integrations search) ──────────────────────── */
.lg-field {
    display: block;
    box-sizing: border-box;
    width: calc(100% - 40px);
    margin: 12px 20px 8px;
    padding: 10px 14px;
    border-radius: 12px;
    color: #eef2f7;
    font: 13px/1.3 inherit;
    letter-spacing: 0.01em;
}
.lg-field::placeholder { color: rgba(255, 255, 255, 0.40); }
.lg-field:focus {
    outline: none;
    background: var(--lg-tint-hover);
    border-color: rgba(255, 255, 255, 0.45);
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.55),
        0 0 0 3px rgba(255, 255, 255, 0.10),
        var(--lg-shadow);
}

/* ── The two log boxes become real glass instead of flat black ───── */
#conv-panel,
#activity-panel {
    background: rgba(18, 19, 23, 0.42) !important;
    backdrop-filter: saturate(190%) blur(38px) !important;
    -webkit-backdrop-filter: saturate(190%) blur(38px) !important;
    border: 0.5px solid rgba(255, 255, 255, 0.18) !important;
    border-radius: 18px !important;
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.40),
        inset 0 -0.5px 0 0 rgba(255, 255, 255, 0.06),
        0 18px 48px rgba(0, 0, 0, 0.50) !important;
}
#conv-header, #act-header {
    border-bottom: 0.5px solid rgba(255, 255, 255, 0.10);
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.00));
    border-radius: 18px 18px 0 0;
}

/* ── RESIZE FIX ──────────────────────────────────────────────────────
   #input-panel carries `z-index: 500 !important` from its base rule, and
   it now lives INSIDE #conv-panel — so it painted on top of the corner
   grip and ate every pointerdown there. That is why the box could still
   be dragged but no longer resized. Demote the nested copy and lift the
   grip above everything in the panel. */
@media (min-width: 901px) {
    #conv-panel #input-panel {
        z-index: 1 !important;
        isolation: auto !important;
    }
    #conv-panel #ip-attachments { z-index: 1 !important; }
    /* Keep the send button clear of the corner grip. */
    #conv-panel #input-panel { padding-right: 26px; }
}
.conv-resize-handle,
.act-resize-handle,
.webcam-resize-handle {
    z-index: 999 !important;
    pointer-events: auto !important;
}
.conv-resize-handle::before,
.act-resize-handle::before {
    width: 15px; height: 15px;
    background: linear-gradient(135deg, transparent 48%, rgba(255,255,255,0.55) 48%);
    border-bottom-right-radius: 18px;
    opacity: 0.55;
    transition: opacity 0.25s var(--lg-spring);
}
#conv-panel:hover .conv-resize-handle::before,
#activity-panel:hover .act-resize-handle::before { opacity: 1; }

/* ── Status pill, re-homed under Claude Usage ────────────────────── */
#claude-usage #status-pill.wake-pill,
#status-pill.wake-pill.in-usage {
    position: static !important;
    left: auto !important; bottom: auto !important;
    display: flex; flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 12px 0 0;
    padding: 7px 11px;
    width: 100%;
    box-sizing: border-box;
    border-radius: 13px;
    transform: none !important;
    font-size: 10px;
    background: var(--lg-tint);
    backdrop-filter: var(--lg-blur);
    -webkit-backdrop-filter: var(--lg-blur);
    border: 0.5px solid rgba(255, 255, 255, 0.16);
    box-shadow: inset 0 0.5px 0 0 rgba(255, 255, 255, 0.35);
}

/* ── Even sizing across the header controls ──────────────────────── */
#status-row { gap: 14px !important; align-items: center; }
#cu-refresh {
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    border: 0.5px solid rgba(255, 255, 255, 0.14);
    backdrop-filter: saturate(180%) blur(18px);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    transition: background 0.3s var(--lg-spring), transform 0.3s var(--lg-spring);
}
#cu-refresh:hover { background: rgba(255, 255, 255, 0.14); transform: rotate(-90deg); }

/* ── Input-bar controls pick up the same material ────────────────── */
#conv-panel #input-panel .control-btn,
#conv-panel #input-panel #btn-send {
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    border: 0.5px solid rgba(255, 255, 255, 0.15);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    box-shadow: inset 0 0.5px 0 0 rgba(255, 255, 255, 0.30);
    transition: background 0.3s var(--lg-spring), transform 0.2s var(--lg-spring),
                border-color 0.3s var(--lg-spring);
}
#conv-panel #input-panel .control-btn:hover,
#conv-panel #input-panel #btn-send:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.30);
}
#conv-panel #input-panel .control-btn:active,
#conv-panel #input-panel #btn-send:active { transform: scale(0.94); }

/* ── The integrations sheet itself ───────────────────────────────── */
#integrations-overlay > div {
    background: rgba(16, 17, 21, 0.55) !important;
    backdrop-filter: saturate(200%) blur(46px);
    -webkit-backdrop-filter: saturate(200%) blur(46px);
    border: 0.5px solid rgba(255, 255, 255, 0.18) !important;
    border-radius: 24px !important;
    box-shadow:
        inset 0 0.5px 0 0 rgba(255, 255, 255, 0.42),
        0 30px 80px rgba(0, 0, 0, 0.62) !important;
}
.integ-tile { border-radius: 16px; transition: background 0.3s var(--lg-spring), transform 0.25s var(--lg-spring); }
.integ-tile:hover { background: rgba(255, 255, 255, 0.10) !important; transform: translateY(-1px); }
.integ-tile:active { transform: scale(0.96); }

/* Reduced-motion users get the material without the springs. */
@media (prefers-reduced-motion: reduce) {
    .lg-btn, .lg-field, .lg-surface, .integ-tile { transition: none !important; }
    .lg-btn:active { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   LIQUID GLASS — pass 2 (Dean, 2026-08-23)
   Feedback: too translucent, not CLEAR. Apple's material is mostly the
   backdrop showing through — the tint is nearly nothing and the read comes
   from the lens (blur + saturation) plus the specular rim, not from a grey
   fill. So: cut the fill way down, push the saturation up, keep the rim.
   Also: no borders around icons, even spacing, gear docked bottom-left.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── The two log boxes: actually clear now ───────────────────────────── */
#conv-panel,
#activity-panel {
    background: rgba(255, 255, 255, 0.045) !important;   /* was a 42% black fill */
    backdrop-filter: saturate(210%) brightness(1.06) blur(26px) !important;
    -webkit-backdrop-filter: saturate(210%) brightness(1.06) blur(26px) !important;
    border: 0.5px solid rgba(255, 255, 255, 0.22) !important;
    border-radius: 20px !important;
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.45),
        inset 0 -1px 0 0 rgba(255, 255, 255, 0.08),
        inset 1px 0 0 0 rgba(255, 255, 255, 0.10),
        inset -1px 0 0 0 rgba(255, 255, 255, 0.10),
        0 16px 44px rgba(0, 0, 0, 0.38) !important;
    /* Drag physics writes transform; keep the origin at the grabbed edge so
       the lean reads as a hinge, not a spin about the middle. */
    transform-origin: 50% 0%;
    will-change: transform;
}
/* Springy settle after a throw. Suppressed mid-drag so the lean is 1:1. */
#conv-panel, #activity-panel {
    transition: transform 0.42s cubic-bezier(0.18, 1.42, 0.36, 1);
}
#conv-panel.dragging, #activity-panel.dragging { transition: none !important; }

#conv-header, #act-header {
    border-bottom: 0.5px solid rgba(255, 255, 255, 0.09);
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.00));
    border-radius: 20px 20px 0 0;
}
/* Text needs its own contrast now that there's no black plate behind it. */
#conv-body, #act-body { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75); }

/* ── Settings gear, docked bottom-left ───────────────────────────────── */
#gear-dock {
    position: fixed;
    left: 24px; bottom: 22px;
    z-index: 120;
    display: flex; align-items: center;
}
#gear-dock #integrations-btn {
    width: 34px; height: 34px;
    padding: 0; margin: 0;
    border: none !important;
    background: none !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    color: rgba(255, 255, 255, 0.50);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: color 0.3s var(--lg-spring), transform 0.5s var(--lg-spring);
}
#gear-dock #integrations-btn::before,
#gear-dock #integrations-btn::after { content: none !important; }
#gear-dock #integrations-btn:hover { color: #fff; transform: rotate(60deg); }
#gear-dock #integrations-btn:active { transform: rotate(60deg) scale(0.9); }
#gear-dock #integrations-btn svg { width: 17px; height: 17px; }

/* ── Status pill: no plate, no border, just the dots + labels ────────── */
#claude-usage #status-pill.wake-pill,
#status-pill.wake-pill.in-usage {
    background: none !important;
    border: none !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    padding: 0 !important;
    margin: 13px 0 0 !important;
    gap: 7px;
}

/* ── Input bar: bare icons, even rhythm, no rings ────────────────────── */
#conv-panel #input-panel {
    align-items: flex-end;          /* icons stay bottom-aligned as the box grows */
    gap: 2px;
    padding: 8px 10px 9px !important;
}
#conv-panel #input-panel .control-btn,
#conv-panel #input-panel #btn-send,
#conv-panel #input-panel #btn-abort {
    width: 30px !important; height: 30px !important;
    min-width: 30px; flex: 0 0 30px;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
    background: none !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border-radius: 8px !important;
    color: rgba(255, 255, 255, 0.55);
    display: inline-flex; align-items: center; justify-content: center;
    transition: color 0.22s var(--lg-spring), transform 0.2s var(--lg-spring);
}
#conv-panel #input-panel .control-btn svg,
#conv-panel #input-panel #btn-send svg,
#conv-panel #input-panel #btn-abort svg { width: 16px; height: 16px; }
#conv-panel #input-panel .control-btn:hover,
#conv-panel #input-panel #btn-send:hover { color: #fff; background: none !important; }
#conv-panel #input-panel .control-btn:active,
#conv-panel #input-panel #btn-send:active { transform: scale(0.88); }
#conv-panel #input-panel .control-btn.active { color: #fff; }
#conv-panel #input-panel #btn-send { color: rgba(255, 255, 255, 0.85); }

/* Volume: same 30px rhythm, and the gap Dean likes kept on its left only. */
#conv-panel #input-panel #volume-control,
#conv-panel #input-panel .volume-control {
    margin-left: 10px !important;
    margin-right: 0 !important;
    gap: 6px;
    height: 30px;
    display: inline-flex; align-items: center;
    background: none !important;
    border: none !important;
    box-shadow: none !important;
}
#conv-panel #input-panel #volume-icon { color: rgba(255, 255, 255, 0.55); display: inline-flex; }
#conv-panel #input-panel #volume-readout {
    font-size: 9px; color: rgba(255, 255, 255, 0.40);
    min-width: 20px; text-align: right;
}

/* ── The typing field grows DOWN instead of running off to the right ─── */
#conv-panel #text-input,
#text-input {
    flex: 1 1 100%;
    min-width: 0;
    display: block;
    resize: none;
    overflow-y: auto;
    max-height: 190px;
    min-height: 34px;
    line-height: 1.42;
    padding: 8px 12px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.05);
    border: 0.5px solid rgba(255, 255, 255, 0.16);
    font-family: inherit; font-size: 14px;
    scrollbar-width: thin;
}
/* The field takes the full first row; the icon strip wraps onto row two, so
   growing text pushes the icons down instead of squeezing them sideways. */
@media (min-width: 901px) {
    #conv-panel #input-panel { flex-wrap: wrap; }
    #conv-panel #text-input  { order: -1; margin-bottom: 6px; }
}
#text-input:focus {
    border-color: rgba(255, 255, 255, 0.34);
    background: rgba(255, 255, 255, 0.08);
}

/* ── Integrations sheet inherits the clearer material too ────────────── */
#integrations-overlay { background: rgba(0, 0, 0, 0.42) !important; }
#integrations-overlay > div {
    background: rgba(255, 255, 255, 0.05) !important;
    backdrop-filter: saturate(210%) brightness(1.05) blur(40px) !important;
    -webkit-backdrop-filter: saturate(210%) brightness(1.05) blur(40px) !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   LIQUID GLASS — pass 3 (Dean, 2026-08-23)
   Feedback: icons too small, too much dead gap in the input row, glass
   still not clear enough, and the top search field needs the material.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Clearer still. Almost no fill; the lens does all the work. ──────── */
#conv-panel,
#activity-panel {
    background: rgba(255, 255, 255, 0.018) !important;
    backdrop-filter: saturate(240%) brightness(1.10) contrast(1.04) blur(20px) !important;
    -webkit-backdrop-filter: saturate(240%) brightness(1.10) contrast(1.04) blur(20px) !important;
    border: 0.5px solid rgba(255, 255, 255, 0.26) !important;
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.55),
        inset 0 -1px 0 0 rgba(255, 255, 255, 0.10),
        inset 1px 0 0 0 rgba(255, 255, 255, 0.13),
        inset -1px 0 0 0 rgba(255, 255, 255, 0.13),
        0 14px 40px rgba(0, 0, 0, 0.32) !important;
    /* The jello integrator drives transform + border-radius every frame, so
       CSS must not fight it with a transition of its own. */
    transition: none !important;
    transform-origin: 50% 0%;
    will-change: transform, border-radius;
}
#conv-header, #act-header {
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.00));
    border-bottom: 0.5px solid rgba(255, 255, 255, 0.11);
}
/* No plate behind the text now, so the text carries its own legibility. */
#conv-body, #act-body,
#conv-header, #act-header { text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9); }

/* ── Input row: bigger icons, folded together, no dead space ─────────── */
#conv-panel #input-panel {
    gap: 0 !important;
    padding: 6px 8px 8px !important;
    justify-content: flex-start;
    align-items: center;
}
#conv-panel #input-panel .control-btn,
#conv-panel #input-panel #btn-send,
#conv-panel #input-panel #btn-abort {
    width: 36px !important; height: 36px !important;
    min-width: 36px !important; flex: 0 0 36px !important;
    margin: 0 !important; padding: 0 !important;
}
#conv-panel #input-panel .control-btn svg,
#conv-panel #input-panel #btn-send svg,
#conv-panel #input-panel #btn-abort svg {
    width: 21px !important; height: 21px !important;
}
/* Volume: same 36px rhythm, one deliberate gap on its left, none after. */
#conv-panel #input-panel #volume-control,
#conv-panel #input-panel .volume-control {
    height: 36px;
    margin-left: 12px !important;
    margin-right: 0 !important;
    gap: 5px !important;
    flex: 0 1 auto;
}
#conv-panel #input-panel #volume-icon svg { width: 19px !important; height: 19px !important; }
#conv-panel #input-panel #volume-slider {
    width: 62px !important; max-width: 62px; flex: 0 0 62px;
}
#conv-panel #input-panel #volume-readout { min-width: 18px; font-size: 9px; }

/* ── Glass on every search / text field, not just the modal ──────────── */
.lg-field,
#integrations-search,
#ws-search,
input[type="search"],
input[type="text"][placeholder*="earch"] {
    background: rgba(255, 255, 255, 0.05) !important;
    backdrop-filter: saturate(220%) brightness(1.08) blur(24px) !important;
    -webkit-backdrop-filter: saturate(220%) brightness(1.08) blur(24px) !important;
    border: 0.5px solid rgba(255, 255, 255, 0.24) !important;
    border-radius: 12px !important;
    box-shadow:
        inset 0 1px 0 0 rgba(255, 255, 255, 0.42),
        0 6px 18px rgba(0, 0, 0, 0.28) !important;
    color: #eef2f7;
}
.lg-field:focus,
#integrations-search:focus,
input[type="search"]:focus {
    background: rgba(255, 255, 255, 0.10) !important;
    border-color: rgba(255, 255, 255, 0.48) !important;
    outline: none;
}

/* The typing field matches the taller icon row. */
#conv-panel #text-input {
    min-height: 38px;
    padding: 9px 13px;
    background: rgba(255, 255, 255, 0.04);
    border: 0.5px solid rgba(255, 255, 255, 0.20);
    backdrop-filter: saturate(200%) blur(18px);
    -webkit-backdrop-filter: saturate(200%) blur(18px);
}
