/* Digits (and +/-/%/currency-ish separators) render in a monospace face everywhere,
   while all other glyphs keep the UI font. Achieved with a unicode-range @font-face
   alias that is placed first in every font stack. */
@font-face{
  font-family:"HubNum";
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url(https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2) format('woff2'),
      local("Menlo"),local("Consolas"),local("DejaVu Sans Mono"),local("Courier New");
  unicode-range:U+0030-0039,U+002B,U+002D,U+0025;
}
@font-face{
  font-family:"HubNum";
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url(https://fonts.gstatic.com/s/spacemono/v17/i7dMIFZifjKcF5UAWdDRaPpZUFWaHg.woff2) format('woff2'),
      local("Menlo Bold"),local("Consolas Bold"),local("Courier New Bold");
  unicode-range:U+0030-0039,U+002B,U+002D,U+0025;
}
:root{
  color-scheme:light;
  --font-num:"HubNum";
  --font-ui:"HubNum","Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --font-title:"HubNum","Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --font-mono:"Space Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --bg:#F5F6F7;
  --surface:#ffffff;
  --surface-2:#EEF0F2;
  --surface-soft:#ffffff;
  --bar-soft:#F5F6F7;
  --term-bg:#18191B;
  --line:#E4E7EA;
  --line-soft:rgba(228,231,234,.7);
  --line-2:#D3D7DC;
  --text:#18191B;
  --text-2:#4A4F55;
  --text-3:#6A7178;
  --text-4:#8A9099;
  --text-5:#B6BCC4;
  --link:#269069;
  --accent:#38C492;
  --accent-hover:#2FAE80;
  /* Solid primary-button fill: deeper green so white labels clear WCAG AA
     (#38C492 white ~1.8:1 fails; #269069 white ~4.9:1). Same in both themes. */
  --btn-primary:#269069;
  --btn-primary-hover:#1E7253;
  --accent-fg:#269069;
  --accent-strong-fg:#1E7253;
  --accent-surface:rgba(56,196,146,.12);
  --accent-surface-2:rgba(56,196,146,.08);
  --accent-border:rgba(56,196,146,.4);
  --chip-bg:#EEF0F2;
  --slate-soft:rgba(138,144,153,.14);
  --slate-soft-2:rgba(138,144,153,.08);
  --shadow-color:rgba(24,25,27,.12);
  --dot-ring:rgba(24,25,27,.14);
  --scrim:rgba(24,25,27,.45);
  --err:#EF4E4C;
  --ok:#2FAE80;
  --warn:#E8912F;
  /* Provider identity & activity (DESIGN.md "Provider & Activity" family).
     One source of truth for the chat/dock/quota/history hues — constant across
     both themes (provider identity does not invert). */
  --claude:#a78bfa;               /* Claude quota-bar violet */
  --codex:#22d3ee;                /* Codex quota-bar cyan */
  --claude-orange:#d97745;        /* Claude agent identity (chat) */
  --claude-orange-hover:#c86d3d;
  --claude-orange-fg:#f0a46f;
  --claude-orange-soft:#e8926a;   /* row/home logo tint */
  --codex-chat:#06b6d4;           /* Codex agent identity (chat) */
  --codex-chat-hover:#0891b2;
  --codex-chat-fg:#67e8f9;
  --gemini:#34d399;               /* Gemini agent fg */
  --gemini-deep:#10b981;          /* Gemini agent solid */
  --gemini-deep-hover:#059669;
  --run:#22c55e;
  --run-fg:#16a34a;
  --done:#3b82f6;
  /* App-wide conversation state palette. */
  --chat-working:#f59e0b;
  --chat-waiting:var(--done);
  --chat-done:var(--run);
  --chat-error:#ef4444;
  --live:#14b8a6;
  --live-fg:#0d9488;
  --scan:#38bdf8;
  /* Chat pane base defaults — overridden per provider below. Without these the
     unthemed pane fell back to stale indigo; brand green is the correct base. */
  --chat-user-bg:color-mix(in srgb,var(--accent) 16%,transparent);
  --chat-accent-hover:color-mix(in srgb,var(--accent) 34%,transparent);
  /* Prodify shell */
  --app-bg:#E6E8EC;
  --nav-bg:#ffffff;
  --card:#ffffff;
  --card-line:#E4E7EA;
  --card-shadow:0 4px 16px rgba(24,25,27,.05);
  --panel-shadow:0 12px 40px rgba(24,25,27,.08);
  --popover-shadow:0 8px 24px rgba(24,25,27,.12);
  --accent-grad:#38C492;
  /* Unified control geometry — shared by action buttons, tabs, tags/badges */
  --radius-control:8px;
  --radius-pill:999px;
  --radius-md:12px;
  --radius-lg:16px;
  --radius-xl:20px;
  --radius-shell:28px;
  --pad-control:9px 17px;
  --pad-control-sm:6px 13px;
}
html.dark{
  color-scheme:dark;
  --bg:#18191B;
  --surface:#202225;
  --surface-2:#26282B;
  --surface-soft:rgba(32,34,37,.6);
  --bar-soft:rgba(24,25,27,.6);
  --term-bg:#0f1012;
  --line:#2C2F34;
  --line-soft:rgba(44,47,52,.7);
  --line-2:#3A3D42;
  --text:#F5F6F7;
  --text-2:#D3D7DC;
  --text-3:#B6BCC4;
  --text-4:#8A9099;
  --text-5:#6A7178;
  --link:#6FDCB0;
  --accent:#4BD0A0;
  --accent-hover:#38C492;
  --accent-fg:#6FDCB0;
  --accent-strong-fg:#A6EACE;
  --accent-surface:rgba(75,208,160,.16);
  --accent-surface-2:rgba(75,208,160,.1);
  --accent-border:rgba(75,208,160,.4);
  --chip-bg:#26282B;
  --slate-soft:rgba(182,188,196,.14);
  --slate-soft-2:rgba(182,188,196,.08);
  --shadow-color:rgba(0,0,0,.5);
  --dot-ring:rgba(255,255,255,.12);
  --scrim:rgba(0,0,0,.6);
  --err:#FD6765;
  --ok:#4BD0A0;
  --warn:#F6B24B;
  --app-bg:#0E0F11;
  --nav-bg:#202225;
  --card:#202225;
  --card-line:#2C2F34;
  --card-shadow:0 4px 16px rgba(0,0,0,.35);
  --panel-shadow:0 12px 40px rgba(0,0,0,.45);
  --popover-shadow:0 8px 24px rgba(0,0,0,.5);
  --accent-grad:#4BD0A0;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-ui);line-height:1.6;letter-spacing:.011em;overflow-wrap:anywhere;word-break:break-word}
h1,h2,h3,h4,h5,h6{font-family:var(--font-title)}
input,textarea,select,button{font-family:inherit}
/* every explicit non-mono stack still gets monospace digits via the HubNum alias */
*{font-feature-settings:"tnum" 1}
:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(56,196,146,.28);border-radius:var(--radius-control)}
/* keep code/mono in a tight, natural rhythm — prose spacing hurts alignment there */
code,pre,kbd,samp,.mono,[class*="mono"]{letter-spacing:0}
/* long content must never break out of card boundaries, site-wide */
.hcard,.sg,.card,.tile,.panel,[class*="card"]{overflow-wrap:anywhere;word-break:break-word;white-space:normal}
/* controls & labels must never inherit the site-wide mid-word breaking above:
   they size to their text+icons and break only between whole words, if at all.
   The [class*=…] selectors catch every badge/chip/pill/tag/kind label app-wide
   (e.g. .auto-kind, .cbadge) so a single word like "Scan" can't split to "Sca"/"n". */
button,[role="button"],.btn,.checknow,.hstat-btn,.side-toggle,.item,.menu-item,.pswitch-item,.pswitch-btn,.ftab,.tasktab,.studio-link,.nav-link,
[class*="badge"],[class*="chip"],[class*="pill"],[class*="-tag"],[class*="kind"],[class*="ftab"],[class*="tasktab"],[class*="-run"]{overflow-wrap:normal;word-break:normal}
/* compact pill/badge/tab/kind labels stay on one line and keep their content width when space is tight */
.checknow,.studio-link,.ftab,.tasktab,.tasktab-n,.fcount,.pi-n,.ps-n,
[class*="badge"],[class*="chip"],[class*="pill"],[class*="-tag"],[class*="kind"]:not(.auto-kindpick),[class*="-run"]{white-space:nowrap;flex-shrink:0}
a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}
.wrap{display:flex;flex-direction:column;min-height:100vh}
.top{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:12px 20px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40;background:var(--bg);font-family:var(--font-ui)}
.top h1{font-size:18px;margin:0;letter-spacing:-.02em}
/* the fix/detail popovers carry prose, so keep them in the readable body font */
.top .tip{font-family:var(--font-ui)}
/* "Check now": force-refresh host stats + Claude usage. Deliberately louder than
   the surrounding stats so it reads as the one actionable control in the header. */
.checknow{font:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:6px;border:1px solid var(--accent-border);background:var(--accent-surface);color:var(--accent-fg);border-radius:var(--radius-control);padding:var(--pad-control-sm);font-size:13px;font-weight:600;white-space:nowrap;transition:background .12s,border-color .12s}
.checknow:hover:not(:disabled){background:var(--btn-primary);border-color:var(--btn-primary);color:#fff}
.checknow:disabled{cursor:default;opacity:.85}
.checknow .cn-ic{display:inline-block;font-size:16px;line-height:1}
.checknow.busy .cn-ic{animation:cn-spin .8s linear infinite}
@keyframes cn-spin{to{transform:rotate(360deg)}}
/* Claude and Codex have separate quota bars; provider colour keeps them
   distinguishable while the shared shape makes their values easy to compare. */
.hstat.usage-stat{border-radius:20px;padding:3px 10px}
.hstat.usage-stat.claude{--usage:var(--claude);background:rgba(139,92,246,.12);border:1px solid color-mix(in srgb,var(--claude) 38%,transparent)}
.hstat.usage-stat.codex{--usage:var(--codex);background:color-mix(in srgb,var(--codex-chat) 11%,transparent);border:1px solid color-mix(in srgb,var(--codex) 35%,transparent)}
.hstat.usage-stat .hstat-btn{border-bottom:none;font-weight:600;color:var(--text-2);display:flex;align-items:center;gap:5px}
.usage-value{display:inline-flex;align-items:center;gap:7px}
.usage-num{font-variant-numeric:tabular-nums}
.usage-pie{display:none;width:16px;height:16px;border-radius:50%;flex:0 0 auto}
.usage-track{display:inline-block;width:44px;height:5px;overflow:hidden;border-radius:99px;background:var(--line-2)}
.usage-fill{display:block;height:100%;border-radius:inherit;background:var(--usage);transition:width .25s cubic-bezier(.16,1,.3,1),background .25s ease}
.hstat.usage-stat .hstat-btn:hover,.hstat.usage-stat.open .hstat-btn{color:var(--text)}
/* Quota popover: each period gets a health-tinted meter (green <70 / amber 70–90 /
   red 90+). --um carries that health colour to both the percent text and the fill. */
.hstat .tip .usage-tiptitle{display:block;font-size:11px;font-weight:700;letter-spacing:.02em;color:var(--text-4);text-transform:uppercase;margin-bottom:10px}
.usage-meter{display:block}
.usage-meter+.usage-meter{margin-top:14px}
.usage-meter-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:6px}
.usage-meter-label{font-size:12px;font-weight:600;color:var(--text-2)}
.usage-meter-pct{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--um)}
.usage-meter-bar{height:6px;border-radius:99px;background:var(--line);overflow:hidden}
.usage-meter-fill{display:block;height:100%;border-radius:inherit;background:var(--um);box-shadow:0 0 8px -1px color-mix(in srgb,var(--um) 55%,transparent);transition:width .3s cubic-bezier(.16,1,.3,1),background .25s ease}
.usage-meter-sub{display:block;margin-top:6px;font-size:11px;color:var(--text-4)}
@media (prefers-reduced-motion:reduce){.usage-fill,.usage-meter-fill{transition:none}}
/* header project switcher — always shows the active project; click to jump to any */
.pswitch{position:relative;flex-shrink:0}
.pswitch-btn{display:flex;align-items:center;gap:8px;max-width:min(52vw,280px);font:inherit;cursor:pointer;background:var(--surface-2);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:6px 10px;color:var(--text)}
.pswitch-btn:hover{border-color:var(--accent-fg);background:var(--surface)}
.pswitch-btn .ps-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.pswitch-btn .ps-nm{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.pswitch-btn .ps-cv{font-size:10px;color:var(--text-4);flex-shrink:0;transition:transform .12s}
.pswitch-btn[aria-expanded="true"] .ps-cv{transform:rotate(180deg)}
.pswitch-menu{position:absolute;top:calc(100% + 6px);inset-inline-start:0;z-index:60;width:300px;max-width:92vw;background:var(--surface);border:1px solid var(--line-2);border-radius:10px;box-shadow:0 12px 32px var(--shadow-color);padding:8px}
/* 16px (not smaller) so iOS Safari doesn't auto-zoom the whole page when this
   autoFocus'd search field takes focus as the dropdown opens */
.pswitch-search{width:100%;box-sizing:border-box;margin-bottom:6px;padding:7px 9px;font:inherit;font-size:16px;background:var(--surface-2);border:1px solid var(--line-2);border-radius:7px;color:var(--text)}
.pswitch-list{max-height:min(60vh,380px);overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.pswitch-item{display:flex;align-items:center;gap:9px;width:100%;text-align:start;font:inherit;font-size:13px;padding:8px 9px;border:none;border-radius:7px;background:none;color:var(--text-2);cursor:pointer}
.pswitch-item:hover{background:var(--surface-2)}
.pswitch-item.active{background:var(--accent-surface);color:var(--accent-fg)}
.pswitch-item .pi-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.pswitch-item .pi-nm{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start}
.pswitch-item .pi-n{flex-shrink:0;font-size:11px;color:var(--text-4);background:var(--line);border-radius:8px;padding:0 6px;line-height:16px}
.pswitch-item.active .pi-n{color:var(--accent-fg)}
.pswitch-item .pi-chat{flex-shrink:0;font-size:11px;font-weight:600;border-radius:8px;padding:0 6px;line-height:16px;letter-spacing:-.3px}
.pswitch-item .pi-chat.new{color:var(--accent-fg);background:color-mix(in srgb,var(--accent) 18%,transparent)}
.pswitch-item .pi-chat.run{color:#fff;background:#b3612f} /* working now → chat orange, readable behind white */
.pswitch-item .pi-cur{flex-shrink:0;color:var(--accent-fg);font-size:12px}
.pswitch-item.pi-hidden{opacity:.6}
.pswitch-item .pi-hidden-ic{flex-shrink:0;width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;opacity:.7}
.pswitch-filters{display:flex;padding:0 0 6px}
.pswitch-empty{padding:10px 9px;color:var(--text-4);font-size:12px}
/* Upward-opening variant (menu sits above the button) for the mobile bottom bar */
.pswitch-up .pswitch-menu{top:auto;bottom:calc(100% + 6px)}
/* Mobile-only bottom project bar; hidden on desktop, shown just above .mnav */
.mprojbar{display:none}
.metrics{display:flex;align-items:center;gap:14px;font-size:12px;color:var(--text-3)}
/* Scan button now lives inline in the metrics row, on the same line as CPU/RAM/disk. */
.metrics>.cn-col{display:flex;flex-direction:column;align-items:stretch;gap:3px;flex:0 0 auto}
.metrics>.cn-col>.checknow{padding-top:2px;padding-bottom:2px;min-width:100px;justify-content:center}
.metrics>.cn-col>.ah-fresh{flex:0 0 auto;align-self:center;font-size:9.5px;line-height:1.1;text-align:center}
@keyframes menu-in{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
.menu-item{display:flex;align-items:center;gap:9px;width:100%;text-align:start;font:inherit;font-size:13px;padding:8px 10px;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--text-2);cursor:pointer;transition:background .13s,color .13s}
.ic{width:18px;height:18px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.btn .ic,.iconbtn .ic{width:18px;height:18px}
.menu-item .ic{width:18px;height:18px;text-align:center;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.menu-item:hover{background:var(--surface-2);color:var(--text)}
.menu-item.on{background:var(--accent-surface);color:var(--accent-fg)}
.menu-item.danger{color:var(--err)}
.menu-item.danger:hover{background:color-mix(in srgb,var(--err) 14%,transparent);color:var(--err)}
/* sidebar project row right-click menu — fixed so it lands at the cursor
   regardless of the rail's own scroll/overflow, and clamped in JS to stay
   fully on-screen near the edges. */
.ctx-menu{position:fixed;z-index:70;width:200px;max-width:calc(100vw - 16px);display:flex;flex-direction:column;gap:2px;background:color-mix(in srgb,var(--surface) 92%,transparent);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 18px 44px var(--shadow-color);padding:6px;transform-origin:top left;animation:menu-in .14s cubic-bezier(.16,1,.3,1)}
.ctx-menu-title{padding:6px 10px 8px;margin-bottom:2px;border-bottom:1px solid var(--card-line);font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--text-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hard-refresh{display:inline-flex;align-items:center;gap:6px;flex-shrink:0}
.hard-refresh>span:first-child{font-size:16px;line-height:1}
.metrics b{color:var(--text)}
/* header health stat with click-to-open explanation popover */
.hstat{position:relative;white-space:nowrap;font-size:12px}
.hstat-btn{font:inherit;color:inherit;background:none;border:none;padding:0;cursor:pointer;display:inline-flex;align-items:center;gap:4px;border-bottom:1px dotted var(--text-5)}
.hstat-btn:hover,.hstat.open .hstat-btn{color:var(--text);border-bottom-color:var(--text-4)}
.hstat .tip{position:absolute;top:calc(100% + 8px);inset-inline-start:0;z-index:60;width:300px;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;padding:12px 20px 12px 12px;font-size:12px;line-height:1.55;color:var(--text-2);box-shadow:0 10px 30px var(--shadow-color);white-space:normal;font-weight:400;text-align:start}
.hstat.r .tip{inset-inline-start:auto;inset-inline-end:0}
.hstat .tip b{color:var(--text)}
.hstat .tip-x{position:absolute;top:6px;inset-inline-end:7px;background:none;border:none;color:var(--text-4);cursor:pointer;font-size:12px;line-height:1;padding:2px}
.hstat .tip-x:hover{color:var(--text)}
.hstat .tip .lvl{display:block;margin-top:6px;color:var(--text-3)}
.hstat .tip code,.hstat .tip .cmd{font-family:ui-monospace,Menlo,monospace;background:var(--line);border-radius:4px;padding:1px 5px;font-size:11px;color:var(--accent-fg);white-space:nowrap}
.hstat .tip .cmd{cursor:pointer;border:1px solid var(--line-2)}
.hstat .tip .cmd:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.hstat .tip .cmd::before{content:"▸ ";color:var(--accent)}
.hstat .tip .ask{display:inline-block;margin-top:9px;font:inherit;font-size:11px;cursor:pointer;background:var(--accent-surface);border:1px solid var(--accent);color:var(--accent-strong-fg);border-radius:6px;padding:4px 9px}
.hstat .tip .ask:hover{background:var(--accent);color:#fff}
.hstat .tip .spark-wrap{display:block;margin:2px 0 12px;padding:8px 10px;background:var(--line);border:1px solid var(--line-2);border-radius:8px}
.hstat .tip .spark-head{display:flex;align-items:baseline;justify-content:space-between;font-size:11px;color:var(--text-4);margin-bottom:4px}
.hstat .tip .spark-head b{font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--text-4)}
.hstat .tip .spark-cur{font-size:15px;font-weight:700}
.hstat .tip .spark{display:block;width:100%;height:36px}
.body{display:flex;flex:1;min-height:0}
.sidecol{width:270px;flex-shrink:0;border-inline-end:1px solid var(--line);display:flex;flex-direction:column;min-height:0}
.sidecol.collapsed{width:32px}
.side{flex:1;overflow-y:auto;min-height:0}
/* collapse/expand the whole sidebar to the side; header carries the toggle */
.sidehead{flex-shrink:0;border-bottom:1px solid var(--line)}
.sidecol.collapsed .sidehead{border-bottom:none;height:100%}
.side-toggle{width:100%;height:100%;font:inherit;cursor:pointer;border:none;background:transparent;color:var(--text-2);display:flex;align-items:center;gap:7px;padding:9px 10px;font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase}
.side-toggle:hover{color:var(--text)}
.side-toggle .chev{font-size:11px;width:12px;color:var(--text-3)}
.side-toggle .side-title{flex:1;text-align:start}
.sidecol.collapsed .side-toggle{flex-direction:column;gap:10px;padding:10px 0;align-items:center;justify-content:flex-start}
.side-title-v{writing-mode:vertical-rl;text-orientation:mixed;display:flex;align-items:center;gap:8px;white-space:nowrap}
/* status / hidden filter tabs above the project list */
.sidefilter{display:flex;flex-wrap:wrap;gap:4px;padding:8px;border-bottom:1px solid var(--line);flex-shrink:0}
.side-add{flex-shrink:0;margin:8px;width:calc(100% - 16px)}
.ftab{font:inherit;cursor:pointer;border:1px solid var(--line-2);background:transparent;color:var(--text-3);border-radius:var(--radius-control);padding:var(--pad-control-sm);font-size:11.5px;display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.ftab:hover{border-color:var(--accent-border);color:var(--text-2)}
.ftab.on{background:var(--surface);color:var(--text);border-color:transparent;box-shadow:0 1px 3px rgba(24,25,27,.06)}
.ftab .ftab-ic{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.ftab .fcount{font-size:10px;background:var(--line);border-radius:999px;padding:0 6px;line-height:15px;color:var(--text-4)}
.ftab.on .fcount{background:var(--accent-border);color:#fff}
.rail-filters{display:flex;flex-wrap:wrap;gap:5px;padding:2px 6px 8px}
.rail-filters .ftab{font-size:11px;padding:3px 8px}
.rail-empty{padding:6px 10px;font-size:12px;color:var(--text-4)}
.item{display:flex;align-items:center;gap:8px;width:100%;text-align:start;padding:10px 12px;background:none;border:none;border-bottom:1px solid var(--line-soft);color:inherit;cursor:pointer;font:inherit}
.item:hover,.item.sel{background:var(--surface-2)}
/* drag-to-reorder on each sidebar item; row-level actions (edit/hide/delete)
   live in the right-click .ctx-menu instead of inline icons */
.item .drag-h{color:var(--text-5);cursor:grab;font-size:12px;flex-shrink:0;opacity:0;transition:opacity .12s}
.item:hover .drag-h{opacity:.7}
.item.dragging{opacity:.4}
.item.dragover{box-shadow:inset 0 2px 0 var(--accent)}
.item.hidden-proj{opacity:.55}
.item .nm{flex:1;min-width:0}
.item .nm .t{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.item .nm .s{display:block;font-size:11px;color:var(--text-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;box-shadow:0 0 0 1px var(--dot-ring)}
.dot.sq{border-radius:2px}
.inds{display:flex;align-items:center;gap:7px;flex-shrink:0}
.inds .ind-ic{font-size:13px;line-height:1;filter:grayscale(.1)}
.inds .cbadge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:600;line-height:15px;padding:0 5px;border-radius:8px;flex-shrink:0}
.inds .cbadge.run{background:color-mix(in srgb,var(--run) 16%,transparent);color:var(--run-fg)}
.inds .cbadge.done{background:color-mix(in srgb,var(--done) 16%,transparent);color:var(--done)}
.inds .cbadge.stuck{background:rgba(245,158,11,.18);color:#d97706}
.main{flex:1;min-width:0;overflow-y:auto;padding:24px}
/* Center the readable detail column in the pane. Without margin-inline:auto the
   880px cap start-aligns and dumps all leftover width into one lopsided band next
   to the chat dock, which reads as a wide blank gap between the two split panes. */
.main>*{max-width:880px;margin-inline:auto}
/* project title bar pinned to the top of the scrolling detail pane. Negative
   margins let it bleed to the full content width while top:0 sticks it under
   the global header as you scroll the project down. */
.proj-sticky{position:sticky;top:-24px;z-index:20;background:var(--bg);margin:0 -24px 0;padding:8px 24px 12px;border-bottom:1px solid var(--line)}
/* Project detail: pin the whole header (project name + tab strip) as one unit so
   the name stays fixed at the top of the scrolling pane instead of being covered
   by the sticky tab strip. Negative top cancels the .main 24px top padding so it
   pins flush under the global header. Inner bars go static — the wrapper sticks. */
.detail-head{position:sticky;top:-24px;z-index:22;background:var(--bg)}
.detail-head .proj-sticky{position:static;margin:0 -24px;z-index:auto}
.detail-head .ptabs{position:static;margin:16px -24px 20px}
.project-head-link{font-size:14px;font-weight:600;letter-spacing:0;color:var(--text-3);text-decoration:none;white-space:nowrap}
a.project-head-link:hover{color:var(--accent-fg);text-decoration:underline}
/* Main project tabs (Info · Plan · Tasks · Automations): a full-bleed, underlined
   strip that swaps the section below it. Horizontally scrollable so the labels never
   wrap or clip on a narrow / touch screen (scrollbar hidden, momentum scroll on). */
.ptabs{position:sticky;top:0;z-index:21;display:flex;gap:2px;overflow-x:auto;margin:16px -24px 20px;padding:0 24px;border-bottom:1px solid var(--line-2);background:var(--bg);scrollbar-width:none;-webkit-overflow-scrolling:touch}
.ptabs::-webkit-scrollbar{display:none}
.ptab{flex:0 0 auto;font:inherit;font-size:14px;font-weight:600;cursor:pointer;background:none;border:none;color:var(--text-3);padding:10px 4px;margin:0 12px;white-space:nowrap;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}
.ptab:first-child{margin-inline-start:0}
.ptab:hover{color:var(--text)}
.ptab.on{color:var(--accent-fg);border-bottom-color:var(--accent)}
.ptab-n{display:inline-block;margin-inline-start:6px;min-width:18px;padding:1px 5px;border-radius:9px;background:var(--line-2);color:var(--text-3);font-size:11px;font-weight:700;line-height:15px;text-align:center;vertical-align:1px}
.ptab.on .ptab-n{background:var(--accent);color:#08120d}
.badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;background:var(--accent-surface);color:var(--accent-fg);border-radius:var(--radius-pill,999px);padding:2px 10px}
.chip{display:inline-block;font-size:12px;background:var(--chip-bg);border:1px solid var(--line-2);border-radius:var(--radius-pill,999px);padding:1px 10px;margin:2px;white-space:nowrap}
.ichip{display:inline-block;font-size:12px;background:var(--accent-surface);border:1px solid var(--accent-border);color:var(--accent-fg);border-radius:6px;padding:2px 8px;margin:2px;white-space:nowrap}
.mono{font-family:ui-monospace,Menlo,monospace;font-size:12px;word-break:break-all}
.sec{margin-bottom:20px}
.plinks>div{line-height:1.3}
.plinks a{color:#2563eb;text-decoration:underline}
.sec h3{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3);margin:0 0 8px}
.tipgrid{display:grid;grid-template-columns:1fr;gap:8px;align-items:start}
.scanbox{border:1px solid var(--line-2);border-radius:10px;background:var(--surface-soft);padding:12px;margin-bottom:12px}
.scanbox textarea{font-size:13px}
.tasktabs{display:flex;flex-wrap:wrap;gap:10px 14px;justify-content:space-between;align-items:center;margin-bottom:12px;border-bottom:1px solid var(--line-2);padding-bottom:10px}
.tf-group{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;padding:5px 6px;border-radius:11px;background:var(--line-soft)}
.tasktab{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;background:transparent;color:var(--text-3);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:var(--pad-control-sm);cursor:pointer;transition:all .15s;white-space:nowrap}
.tasktab:hover{color:var(--text-1);border-color:var(--text-4)}
.tasktab.on{background:var(--surface);color:var(--text);border-color:transparent;box-shadow:0 1px 3px rgba(24,25,27,.06)}
.tasktab-n{font-size:11px;font-weight:600;background:var(--line);border-radius:999px;padding:0 6px;min-width:16px;text-align:center}
.tasktab.on .tasktab-n{background:var(--slate-soft)}
.row{display:flex;gap:8px;font-size:14px;margin-bottom:4px}
.row .lb{color:var(--text-4);width:90px;flex-shrink:0}
.live{border:1px solid var(--line);border-radius:10px;padding:12px;background:var(--surface-soft)}
/* Task-card headline row: title (with priority dot) plus the category/status chips.
   On desktop they sit inline; the chips wrap to their own line below the title on
   narrow (phone) widths — see the ≤1000px block. */
.tip-head{display:flex;align-items:center;gap:8px;margin-bottom:4px;flex-wrap:wrap}
.tip-headline{display:inline-flex;align-items:center;gap:8px;min-width:0}
.tip-headline b{overflow-wrap:anywhere}
.tip-chips{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.muted{color:var(--text-4)}
/* unified status + infrastructure card */
.infra{display:grid;grid-template-columns:1fr 1fr}
.infra-col{padding:0 22px;min-width:0}
.infra-col:first-child{padding-inline-start:0}
.infra-col:last-child{padding-inline-end:0}
.infra-col+.infra-col{border-inline-start:1px solid var(--line)}
.infra-h{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3);font-weight:600;margin:0 0 10px;display:flex;align-items:center;gap:7px;flex-wrap:wrap;row-gap:6px;min-width:0}
.infra-h .btn{white-space:nowrap;flex:0 0 auto}
.irow{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:13.5px;padding:6px 0;border-bottom:1px solid var(--line-soft)}
.irow:last-child{border-bottom:none}
.irow .ik{color:var(--text-4);flex-shrink:0}
.irow .iv{color:var(--text-2);text-align:end;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;word-break:normal}
.irow .iv a{color:var(--accent-fg)}
.irow .iv.one-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;word-break:normal}
.studio-link{display:inline-flex;align-items:center;gap:4px;font-size:11px;background:var(--accent-surface);border:1px solid var(--accent-border);color:var(--accent-fg)!important;border-radius:var(--radius-control);padding:2px 7px;text-decoration:none;white-space:nowrap}
.studio-link:hover{color:var(--accent-strong-fg)!important;border-color:var(--accent-fg)}
/* claude chat */
.chat{border:1px solid var(--line);border-radius:10px;background:var(--surface-soft);overflow:hidden;position:relative}
.chat.file-drag{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.chat-file-drop{position:absolute;inset:8px;z-index:40;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:2px dashed var(--accent);border-radius:10px;background:color-mix(in srgb,var(--surface) 90%,var(--accent) 10%);color:var(--text);text-align:center;pointer-events:none;box-shadow:0 8px 28px var(--shadow-color)}
.chat-file-drop-icon{font-size:28px;line-height:1}
.chat-file-drop strong{font-size:15px}
.chat-file-drop span:last-child{font-size:12px;color:var(--text-3)}
.chat .log{max-height:440px;overflow-y:auto;padding:12px 12px 5px;display:flex;flex-direction:column;align-items:center;gap:10px}
/* Center the conversation in a readable column instead of stretching edge-to-edge. */
.chat .log>.cmsg,.chat .log>.empty{width:100%;max-width:none}
.chat .empty{color:var(--text-4);font-size:13px;padding:6px 2px}
.chat .cinterrupt{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:12px;color:var(--err);background:rgba(220,38,38,.08);border:1px solid var(--err);border-radius:8px;padding:6px 10px;margin-top:2px}
.cmsg{display:flex;flex-direction:column;gap:6px;position:relative}
/* right padding reserves the lane the floating copy button occupies, so it never
   sits on top of the hover-revealed timestamp or the ✎ Edit button. */
.cmsg-head{display:flex;align-items:baseline;gap:8px;padding-inline-end:64px}
.cmsg .who{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4)}
/* per-message timestamp: hidden until its message is hovered. Uses opacity (not display) and lives on the existing header row, so revealing it never reflows or shifts the bubble below. */
.cmsg .ctime{font-size:10px;color:var(--text-5);opacity:0;transition:opacity .12s ease;white-space:nowrap;font-variant-numeric:tabular-nums;cursor:default}
.cmsg:hover .ctime{opacity:1}
.cmsg-edit-btn{font-size:10px;color:var(--text-4);background:none;border:none;cursor:pointer;opacity:0;transition:opacity .12s ease;padding:0;margin-inline-start:auto}
.cmsg:hover .cmsg-edit-btn{opacity:1}
.cmsg-edit-btn:hover{color:var(--accent-fg)}
/* The single per-message copy button. Floats over the message's top-right corner and
   is revealed on hover (same pattern as the timestamp/edit button). It sits on the
   .cmsg wrapper rather than inside a text part, so a multi-part assistant answer
   still shows exactly one. */
.cmsg-copy-btn{position:absolute;top:0;inset-inline-end:0;z-index:2;font:inherit;font-size:11px;line-height:1;padding:3px 6px;border:1px solid var(--line-2);border-radius:6px;background:var(--surface);color:var(--text-3);cursor:pointer;opacity:0;transition:opacity .12s ease}
.cmsg:hover .cmsg-copy-btn,.cmsg-copy-btn:focus-visible{opacity:.85}
.cmsg-copy-btn:hover{opacity:1;color:var(--text);border-color:var(--accent)}
/* "+" — saves this assistant message's text as a note in Plan > Notes. Same
   hover-revealed floating treatment as the copy button, parked just inline-start
   of it so the two never overlap. */
.cmsg-note-btn{position:absolute;top:0;inset-inline-end:32px;z-index:2;font:inherit;font-size:12px;line-height:1;padding:3px 7px;border:1px solid var(--line-2);border-radius:6px;background:var(--surface);color:var(--text-3);cursor:pointer;opacity:0;transition:opacity .12s ease}
.cmsg:hover .cmsg-note-btn,.cmsg-note-btn:focus-visible{opacity:.85}
.cmsg-note-btn:hover{opacity:1;color:var(--text);border-color:var(--accent)}
.msg-edit-container{display:flex;flex-direction:column;gap:8px;width:100%}
.msg-edit-textarea{width:100%;min-height:80px;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:8px;font-size:13px;line-height:1.55;color:var(--text);font-family:inherit;resize:vertical}
.msg-edit-actions{display:flex;gap:8px;justify-content:flex-end}
.cmsg.user .bubble{background:var(--chat-user-bg);border:1px solid var(--accent-border)}
.cmsg .bubble{background:var(--chat-user-bg);border:1px solid var(--accent-border);border-radius:8px;padding:8px 10px;font-size:13px;line-height:1.55;color:var(--text-2);white-space:pre-wrap;word-break:break-word}
/* assistant (CLAUDE) bubble: distinct light/white surface to separate it from user messages */
.cmsg.assistant .bubble{background:var(--surface);border:1px solid var(--line)}
/* markdown-rendered assistant bubble */
.cmsg .bubble.md{white-space:normal}
.bubble.md>:first-child{margin-top:0}
.bubble.md>:last-child{margin-bottom:0}
.bubble.md p{margin:0 0 8px}
.bubble.md h1,.bubble.md h2,.bubble.md h3,.bubble.md h4{margin:12px 0 6px;line-height:1.3;font-weight:600;color:var(--text)}
.bubble.md h1{font-size:18px}.bubble.md h2{font-size:16px}.bubble.md h3{font-size:15px}.bubble.md h4{font-size:14px}
.bubble.md ul,.bubble.md ol{margin:0 0 8px;padding-inline-start:20px}
.bubble.md li{margin:2px 0}
.bubble.md li>p{margin:0}
.bubble.md a{color:var(--link)}
.bubble.md code{font-family:ui-monospace,Menlo,monospace;font-size:12px;background:var(--slate-soft);padding:1px 5px;border-radius:4px}
.bubble.md pre{background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:8px 10px;margin:0 0 8px;overflow-x:auto}
.bubble.md pre code{background:none;padding:0;font-size:12px;line-height:1.45;white-space:pre}
.bubble.md blockquote{margin:0 0 8px;padding:2px 10px;border-inline-start:3px solid var(--line-2);color:var(--text-3)}
.bubble.md table{border-collapse:collapse;margin:0 0 8px;font-size:13px;display:block;overflow-x:auto}
.bubble.md th,.bubble.md td{border:1px solid var(--line);padding:4px 8px;text-align:start}
.bubble.md th{background:var(--slate-soft-2);font-weight:600;color:var(--text-4);font-size:12px}
.bubble.md hr{border:none;border-top:1px solid var(--line);margin:10px 0}
.bubble.md img{max-width:100%;border-radius:6px}
/* README preview: render project documentation as a readable document instead
   of exposing the Markdown source in a plain preformatted box. */
.readme-preview{max-height:520px;overflow:auto;padding:24px clamp(18px,4vw,42px);border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--text-2);font-size:14px;line-height:1.7;white-space:normal;overflow-wrap:anywhere;word-break:normal}
.readme-preview>:first-child{margin-top:0}
.readme-preview>:last-child{margin-bottom:0}
.readme-preview h1,.readme-preview h2,.readme-preview h3,.readme-preview h4,.readme-preview h5,.readme-preview h6{color:var(--text);line-height:1.28;font-weight:700;letter-spacing:-.015em;scroll-margin-top:12px}
.readme-preview h1{font-size:28px;margin:0 0 20px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.readme-preview h2{font-size:21px;margin:30px 0 12px;padding-bottom:7px;border-bottom:1px solid var(--line)}
.readme-preview h3{font-size:17px;margin:24px 0 9px;text-transform:none;letter-spacing:-.01em}
.readme-preview h4,.readme-preview h5,.readme-preview h6{font-size:15px;margin:20px 0 8px}
.readme-preview p{margin:0 0 14px}
.readme-preview ul,.readme-preview ol{margin:0 0 16px;padding-inline-start:26px}
.readme-preview li{margin:4px 0;padding-inline-start:2px}
.readme-preview li>p{margin:0}
.readme-preview a{color:var(--link);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}
.readme-preview strong{color:var(--text);font-weight:650}
.readme-preview code{direction:ltr;display:inline;font-family:ui-monospace,Menlo,monospace;font-size:.88em;background:var(--slate-soft);padding:2px 5px;border-radius:4px;word-break:break-word}
.readme-preview pre{direction:ltr;text-align:start;overflow-x:auto;margin:0 0 16px;padding:13px 15px;border:1px solid var(--line);border-radius:8px;background:var(--bg)}
.readme-preview pre code{display:block;background:none;padding:0;white-space:pre;word-break:normal;line-height:1.55}
.readme-preview blockquote{margin:0 0 16px;padding:7px 14px;border-inline-start:4px solid var(--accent);background:var(--accent-surface-2);color:var(--text-3);border-radius:0 6px 6px 0}
.readme-preview blockquote>:last-child{margin-bottom:0}
.readme-preview table{display:block;width:max-content;max-width:100%;overflow-x:auto;border-collapse:collapse;margin:0 0 18px;font-size:13px}
.readme-preview th,.readme-preview td{border:1px solid var(--line);padding:7px 10px;text-align:start}
.readme-preview th{background:var(--slate-soft-2);color:var(--text);font-weight:650}
.readme-preview tr:nth-child(even) td{background:var(--slate-soft-2)}
.readme-preview hr{border:0;border-top:1px solid var(--line);margin:24px 0}
.readme-preview img{display:block;max-width:100%;height:auto;margin:18px auto;border-radius:8px}
.readme-preview input[type="checkbox"]{margin-inline-end:7px}
@media(max-width:600px){
  .readme-preview{max-height:65vh;padding:18px 15px;font-size:13.5px}
  .readme-preview h1{font-size:24px}
  .readme-preview h2{font-size:19px}
}
.ctool{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--live-fg);background:color-mix(in srgb,var(--live) 14%,transparent);border:1px solid color-mix(in srgb,var(--live) 35%,transparent);border-radius:6px;padding:3px 8px}
.ctool .nm{font-weight:600;white-space:nowrap;flex:0 0 auto}
.ctool .dsc{min-width:0;flex:1 1 auto;color:var(--text-3);font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* A skill Claude invoked. Deliberately NOT the teal of the tool rows above — teal
   is the "a tool ran" signal, so skills take the same accent they already have in
   the "/" picker (.slash-n). Hovering the name explains the skill (.slash-pop). */
.ctool.skill{color:var(--accent-fg);background:var(--accent-surface-2);border-color:var(--accent-border)}
.ctool.skill .skill-n{font-family:ui-monospace,Menlo,monospace;cursor:help;border-radius:3px}
.ctool.skill .skill-n:focus-visible{outline:1px solid var(--accent);outline-offset:1px}
/* collapsed run of tool calls — a compact pill that expands to the green rows */
.ctools{display:flex;flex-direction:column;gap:4px;align-items:flex-start}
.ctools-tog{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:9px;line-height:1;color:var(--live-fg);background:color-mix(in srgb,var(--live) 10%,transparent);border:1px solid color-mix(in srgb,var(--live) 30%,transparent);border-radius:4px;padding:0;cursor:pointer;opacity:.55}
.ctools-tog:hover{opacity:1;background:color-mix(in srgb,var(--live) 18%,transparent)}
.ctools-list{display:flex;flex-direction:column;gap:6px;width:100%}
.cfoot{font-size:11px;color:var(--text-5);display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.cfoot .tok{font-family:ui-monospace,Menlo,monospace}
.cfoot .cfoot-time{font-variant-numeric:tabular-nums;color:var(--text-4);white-space:nowrap;cursor:default}
/* quick-action buttons under a finished response — one tap re-prompts Claude */
.cquick{display:flex;gap:6px;flex-wrap:wrap;margin-top:2px}
.cquick button{font:inherit;cursor:pointer;font-size:11px;line-height:1;padding:5px 10px;border-radius:999px;border:1px solid var(--accent-border);background:var(--accent-surface-2);color:var(--accent-strong-fg);white-space:nowrap}
.cquick button:hover:not(:disabled){background:var(--chat-accent-hover);border-color:var(--accent)}
.cquick button:disabled{opacity:.45;cursor:default}
.cquick button.cquick-edit{padding:5px 8px;opacity:.6;color:var(--muted);background:transparent;border-color:var(--line)}
.cquick button.cquick-edit:hover{opacity:1;color:var(--text)}
/* Quick-prompts editor popover */
.qp-overlay{position:fixed;inset:0;background:var(--scrim);z-index:220;display:grid;place-items:center;padding:20px}
.qp-modal{width:min(560px,100%);max-height:85vh;display:flex;flex-direction:column;background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:14px;box-shadow:var(--panel-shadow);overflow:hidden}
.qp-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;border-bottom:1px solid var(--line)}
.qp-head b{font-size:15px}
.qp-hint{padding:10px 16px 0;font-size:12px;line-height:1.5}
.qp-rows{padding:10px 16px;overflow-y:auto;display:flex;flex-direction:column;gap:8px}
.qp-row{display:flex;gap:8px;align-items:center}
.qp-row input{font:inherit;font-size:13px;padding:7px 10px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);color:var(--text)}
.qp-row input:focus{outline:none;border-color:var(--accent)}
.qp-label{flex:0 0 130px;min-width:0}
.qp-prompt{flex:1 1 auto;min-width:0}
.qp-del{flex:0 0 auto;cursor:pointer;font-size:13px;line-height:1;padding:7px 9px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--muted)}
.qp-del:hover{color:var(--err);border-color:var(--err)}
.qp-empty{padding:8px 0;font-size:13px}
.qp-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-top:1px solid var(--line)}
.qp-foot-right{display:flex;gap:8px}
/* assistant text. The copy button that used to live here was removed: one message can
   render several .atext parts, so it duplicated. See .cmsg-copy-btn. */
.atext{position:relative}
/* fenced code block with a Copy / Run-in-terminal toolbar */
.cblock{border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--bg);margin:0 0 2px}
.cblock-bar{display:flex;align-items:center;gap:8px;padding:4px 6px 4px 10px;background:var(--surface);border-bottom:1px solid var(--line)}
.cblock-bar .sp{flex:1}
.cblock-lang{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4);font-family:ui-monospace,Menlo,monospace}
.cblock-btn{font:inherit;font-size:11px;line-height:1;padding:4px 8px;border:1px solid var(--line-2);border-radius:6px;background:var(--surface-2);color:var(--text-2);cursor:pointer;white-space:nowrap;box-sizing:border-box;min-height:24px;display:inline-flex;align-items:center;justify-content:center}
.cblock-btn:hover{color:var(--text);border-color:var(--accent)}
/* "Run in terminal" stays one consistent look everywhere — never tinted by the provider (claude/codex/gemini) accent */
.cblock-btn.run{background:var(--accent-surface);border-color:var(--accent-border);color:var(--accent-fg)}
.cblock-btn.run:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.cblock-pre{margin:0;padding:8px 10px;overflow-x:auto;background:var(--bg)}
.cblock-pre code{font-family:ui-monospace,Menlo,monospace;font-size:12px;line-height:1.5;white-space:pre;color:var(--text-2)}
/* each usage stat carries a hover tooltip (rendered in a document-level portal so
   it's never clipped by the chat log / dock overflow) — hint it with a help cursor */
.cstat{cursor:help;position:relative}
.cstat:hover{color:var(--text-3);text-decoration:underline dotted;text-underline-offset:2px}
.cstat-pop{position:fixed;z-index:200;width:240px;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;padding:9px 11px;font-size:11.5px;line-height:1.5;color:var(--text-2);box-shadow:0 12px 32px var(--shadow-color);white-space:normal;pointer-events:none}
/* Composer: the textarea takes the full first line (wide, flush-left); the +,
   the agent-mode/effort control and the send actions wrap onto a row below it. */
.chat .inp{display:flex;flex-wrap:wrap;gap:8px;padding:10px;border-top:1px solid var(--line);align-items:center;position:relative;order:33}
/* Composer spans the full chat width (no fixed column cap), matching the log. */
.chat .inp-wrap,.chat .inp,.chat .chatdir,.chat .ask-overlay,.chat .chat-state{width:100%;max-width:none;margin-inline:auto;box-sizing:border-box}
.chat .inp textarea{order:1;flex:1 1 100%;width:100%;min-height:40px;height:40px;max-height:160px;font-size:13px;line-height:20px;padding:9px 10px;box-sizing:border-box;overflow-y:hidden}
.chat .inp .attach-menu{order:2}
.chat .inp .agent-controls{order:3}
.chat .inp .inp-actions{order:5;margin-inline-start:auto;display:flex;align-items:center;gap:8px;min-width:0}
/* The top pill bar (.modelbar) and the standalone model dropdown are both
   retired: provider + model now live in the unified selector popover below,
   alongside agent mode & effort. Rules kept as no-ops for any stale markup. */
.chat-model-selector{display:none!important}
.model-picker-mobile{display:none!important}
/* Unified selector — one compact trigger pinned left in the input toolbar that
   opens a single popover for the AI provider, model, execution mode
   (Manual / Edit / Plan / Auto) and reasoning effort (Low / Medium / High). */
.agent-controls{position:relative;flex:0 0 auto}
.agent-controls-trigger{display:inline-flex;align-items:center;gap:6px;height:40px;box-sizing:border-box;padding:0 10px;border:1px solid var(--line-2);border-radius:10px;background:var(--surface);color:var(--text-2);font:inherit;font-size:11.5px;cursor:pointer;white-space:nowrap;transition:border-color .12s,background .12s}
.agent-controls-trigger:hover,.agent-controls-trigger.open{border-color:var(--accent);background:var(--accent-surface-2)}
.agent-controls-trigger .acx-ic{font-size:13px;line-height:1}
.agent-controls-trigger .acx-mode{font-weight:700;color:var(--text-1)}
.agent-controls-trigger .acx-sep{width:1px;height:14px;background:var(--line-2)}
.agent-controls-trigger .acx-eff{display:inline-flex;align-items:center;gap:5px;color:var(--text-3)}
.acx-eff-dots{display:inline-flex;gap:2px;align-items:center}
.acx-eff-dots i{width:4px;height:4px;border-radius:50%;background:var(--line-2)}
.acx-eff-dots[data-eff="low"] i:nth-child(1){background:var(--accent)}
.acx-eff-dots[data-eff="medium"] i:nth-child(1),.acx-eff-dots[data-eff="medium"] i:nth-child(2){background:var(--accent)}
.acx-eff-dots[data-eff="high"] i{background:var(--accent)}
.agent-controls-trigger .acx-caret{color:var(--text-4);font-size:9px;transition:transform .15s}
.agent-controls-trigger.open .acx-caret{transform:rotate(180deg)}
.agent-controls-pop{position:absolute;inset-inline-start:0;bottom:calc(100% + 8px);z-index:60;width:340px;max-width:82vw;max-height:min(70vh,560px);overflow-y:auto;background:var(--surface);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 16px 44px var(--shadow-color);padding:10px;display:flex;flex-direction:column;gap:12px}
.acp-section{display:flex;flex-direction:column;gap:7px}
.acp-h{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-4);padding:0 2px}
.acp-modes{display:flex;flex-direction:column;gap:3px}
.acp-mode{display:flex;align-items:flex-start;gap:10px;text-align:start;width:100%;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--text-2);font:inherit;padding:8px 9px;cursor:pointer;transition:background .1s,border-color .1s}
.acp-mode:hover{background:var(--surface-2)}
.acp-mode.active{background:var(--accent-surface);border-color:var(--accent-border)}
.acp-mode-ic{flex:0 0 auto;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border-radius:7px;background:var(--surface-2);font-size:13px;line-height:1;margin-top:1px}
.acp-mode.active .acp-mode-ic{background:var(--accent);color:#fff}
.acp-mode-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.acp-mode-t{font-size:12.5px;font-weight:700;color:var(--text-1)}
.acp-mode-d{font-size:11px;line-height:1.45;color:var(--text-3)}
.acp-check{flex:0 0 auto;color:var(--accent-fg);font-weight:800;font-size:13px;margin-top:2px}
.acp-efforts{display:flex;gap:4px;background:var(--surface-2);border-radius:9px;padding:3px}
.acp-eff-opt{flex:1;border:none;border-radius:7px;background:transparent;color:var(--text-3);font:inherit;font-size:12px;font-weight:600;padding:6px 4px;cursor:pointer;transition:background .1s,color .1s}
.acp-eff-opt:hover{color:var(--text-1)}
.acp-eff-opt.active{background:var(--accent);color:#fff;box-shadow:0 1px 4px var(--shadow-color)}
.acp-eff-note{font-size:11px;line-height:1.45;color:var(--text-3);padding:0 2px}
/* Agent mode segmented control: reuses .acp-efforts, stacks icon over a short label */
.acp-modeseg .acp-eff-opt{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px 3px}
.acp-modeseg-ic{font-size:14px;line-height:1}
.acp-modeseg-t{font-size:11px;font-weight:600}
/* Unified selector extras: provider row in the trigger + provider/model sections
   inside the same popover as agent mode & effort. */
.agent-controls-trigger .acx-ic{display:inline-flex;align-items:center;color:var(--text-2)}
.agent-controls-trigger .acx-submode{display:inline-flex;align-items:center;font-size:12px;line-height:1;color:var(--text-3)}
.acp-providers .acp-eff-opt{display:inline-flex;align-items:center;justify-content:center;gap:5px}
.acp-providers .acp-eff-opt .provider-logo{opacity:.85}
.acp-providers .acp-eff-opt.active .provider-logo{opacity:1}
.acp-models .acp-mode{align-items:center}
.acp-model-hint{margin-inline-start:7px;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-4);border:1px solid var(--line-2);border-radius:999px;padding:1px 6px;vertical-align:middle}
.acp-mode.active .acp-model-hint{color:var(--accent-fg);border-color:var(--accent-border)}
/* Hub2 per-project quick fixes. The compact checklist button sits immediately
   to the right of the unified model control; its popover stays in the viewport. */
.hub-todo-control{position:relative;order:4;flex:0 0 auto}
.hub-todo-trigger{display:grid;place-items:center;width:40px;height:40px;padding:0;border:1px solid var(--line-2);border-radius:10px;background:var(--surface);color:var(--text-2);font:inherit;font-size:16px;cursor:pointer;transition:border-color .12s,background .12s,color .12s}
.hub-todo-trigger:hover,.hub-todo-trigger.open{border-color:var(--accent);background:var(--accent-surface-2);color:var(--accent-fg)}
.hub-todo-pop{position:absolute;inset-inline-start:0;bottom:calc(100% + 8px);z-index:65;width:min(390px,calc(100vw - 28px));max-height:min(72vh,620px);display:flex;flex-direction:column;gap:9px;padding:12px;background:var(--surface);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 16px 44px var(--shadow-color)}
.hub-todo-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.hub-todo-head>div{display:flex;flex-direction:column;gap:3px;min-width:0}
.hub-todo-head small{font-size:11px;line-height:1.4;color:var(--text-3)}
.hub-todo-pop>textarea{width:100%;min-height:72px!important;height:auto!important;max-height:130px;resize:vertical;order:initial!important;flex:none!important}
.hub-todo-addrow{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:10.5px}
.hub-todo-list{display:flex;flex-direction:column;gap:7px;overflow-y:auto;min-height:0;padding-inline-end:2px}
.hub-todo-empty{padding:14px 4px;text-align:center;font-size:12px}
.hub-todo-item{padding:9px;border:1px solid var(--line-soft);border-radius:9px;background:var(--surface-2)}
.hub-todo-item.status-running{border-color:var(--accent-border)}
.hub-todo-item.status-completed{opacity:.72}
.hub-todo-meta{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:5px;font-size:10.5px;color:var(--text-3)}
.hub-todo-meta>span{font-weight:700;color:var(--accent-fg)}
.hub-todo-note{font-size:12.5px;line-height:1.45;color:var(--text-1);white-space:pre-wrap;overflow-wrap:anywhere}
.hub-todo-item details{margin-top:6px;font-size:11px;color:var(--text-3)}
.hub-todo-item details summary{cursor:pointer}
.hub-todo-item details div{margin-top:5px;padding:6px;border-radius:6px;background:var(--bg);white-space:pre-wrap;overflow-wrap:anywhere}
.hub-todo-item-actions{display:flex;align-items:center;justify-content:flex-end;gap:7px;margin-top:7px}
.hub-todo-dismiss{border:0;background:none;color:var(--text-4);font:inherit;font-size:10.5px;padding:2px 3px;cursor:pointer}
.hub-todo-dismiss:hover{color:var(--err)}
.hub-todo-error{margin-top:5px;font-size:10.5px;white-space:pre-wrap;overflow-wrap:anywhere}
.hub-telegram-connect{display:grid;grid-template-columns:1fr 1fr;gap:7px;padding:9px;border:1px solid var(--line-soft);border-radius:9px;background:var(--surface-2)}
.hub-telegram-connect>b,.hub-telegram-connect>small{grid-column:1/-1}
.hub-telegram-connect>small{font-size:10.5px;line-height:1.4;color:var(--text-3)}
.hub-telegram-connect>input{min-width:0;width:100%;font:inherit;font-size:11.5px;padding:7px 8px}
.hub-telegram-connect>button{grid-column:2;justify-self:end}
.hub-telegram-connected{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:8px;background:var(--accent-surface-2);color:var(--accent-fg);font-size:11px}
/* "/" skills autocomplete that floats above the chat input */
.slashmenu{position:absolute;inset-inline-start:10px;inset-inline-end:10px;bottom:calc(100% + 6px);z-index:50;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;box-shadow:0 10px 30px var(--shadow-color);padding:4px;max-height:280px;overflow-y:auto}
.slash-h{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-5);padding:5px 8px 4px}
.slash-it{display:flex;align-items:baseline;gap:8px;width:100%;text-align:start;background:none;border:none;border-radius:6px;padding:6px 8px;cursor:pointer;color:var(--text-2);font:inherit}
.slash-it:hover,.slash-it.on{background:var(--surface-2)}
.slash-n{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--accent-fg);font-weight:600;flex-shrink:0}
.slash-d{font-size:11px;color:var(--text-4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* full-text explanation shown when hovering a skill row (portal, position:fixed
   so it's never clipped by the dock/menu overflow) */
.slash-pop{position:fixed;z-index:200;width:260px;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;padding:9px 11px;font-size:11.5px;line-height:1.5;color:var(--text-2);box-shadow:0 12px 32px var(--shadow-color);white-space:normal;pointer-events:none}
.slash-pop b{display:block;font-family:ui-monospace,Menlo,monospace;color:var(--accent-fg);margin-bottom:3px}
/* context-window indicator in the chat header */
.ctxchip{display:inline-flex;align-items:center;gap:6px;font-size:10px;color:var(--text-3);white-space:nowrap;cursor:default}
.ctxpie-btn{border:0;background:transparent;padding:2px 4px;border-radius:6px;cursor:pointer;transition:background .15s,transform .15s}
.ctxpie-btn:hover{background:var(--line);transform:scale(1.04)}
.ctxpie-btn:active{transform:scale(.96)}
.ctxpie{width:14px;height:14px;border-radius:50%;flex:0 0 auto;transition:background .3s;box-shadow:inset 0 0 0 1px var(--line-2)}
/* chat attachments: chips above the input + on the user bubble */
.cattach-row{display:flex;flex-wrap:wrap;gap:6px;padding:8px 10px 0}
.catt{display:inline-flex;align-items:center;gap:5px;font-size:11px;background:var(--accent-surface-2);border:1px solid var(--accent-border);color:var(--accent-fg);border-radius:6px;padding:3px 7px;max-width:220px}
.catt .catt-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.catt.up{opacity:.65}
.catt .catt-x{background:none;border:none;color:var(--text-4);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:0 1px;flex-shrink:0}
.catt-thumb{width:28px;height:28px;object-fit:cover;border-radius:4px;flex-shrink:0;display:block}
a.catt,.catt .catt-open{text-decoration:none;color:inherit;display:inline-flex;align-items:center;gap:5px;overflow:hidden;cursor:pointer}
a.catt:hover,.catt .catt-open:hover{text-decoration:underline}
.catts{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}
.iconbtn{background:none;border:1px solid var(--line-2);border-radius:var(--radius-control);color:var(--text-3);cursor:pointer;font-size:16px;line-height:1;padding:0;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;box-sizing:border-box}
.iconbtn:hover:not(:disabled){border-color:var(--accent);color:var(--accent-fg)}
.iconbtn:disabled{opacity:.5;cursor:default}
.attach-menu{position:relative;flex:0 0 auto;display:inline-flex}
.attach-pop{position:absolute;inset-inline-start:0;bottom:calc(100% + 6px);z-index:60;min-width:150px;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;box-shadow:0 10px 30px var(--shadow-color);padding:4px}
.attach-pop button{display:flex;align-items:center;gap:8px;width:100%;border:0;background:none;color:var(--text);font:inherit;font-size:13px;line-height:1.2;text-align:start;cursor:pointer;border-radius:6px;padding:8px 10px;box-sizing:border-box}
.attach-pop button:hover{background:var(--surface-2)}
.thinking{display:inline-flex;align-items:center;gap:7px;color:var(--link);font-size:13px}
.thinking .lbl{font-style:italic}
.thinking .dots{display:inline-flex;gap:3px}
.thinking .dots i{width:4px;height:4px;border-radius:50%;background:currentColor;opacity:.3;animation:thinkpulse 1.2s infinite ease-in-out}
.thinking .dots i:nth-child(2){animation-delay:.2s}
.thinking .dots i:nth-child(3){animation-delay:.4s}
@keyframes thinkpulse{0%,80%,100%{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}
/* terminal modal */
.modal{position:fixed;inset:0;background:var(--scrim);display:flex;flex-direction:column;z-index:50}

/* Ask / question modal — a darker scrim for stronger focus, and a stepped
   questionnaire with clean single- and multi-select option rows. */
.ask-progress{display:flex;align-items:center;gap:6px;margin:2px 0 14px}
.ask-progress .dot{height:4px;flex:1;border-radius:99px;background:var(--line-2);transition:background .2s}
.ask-progress .dot.done{background:var(--accent-fg)}
.ask-progress .dot.cur{background:var(--accent-fg);opacity:.55}
.ask-opt{display:flex;align-items:flex-start;gap:10px;text-align:start;padding:11px 12px;border:1px solid var(--line-2);border-radius:10px;background:var(--surface);cursor:pointer;transition:border-color .12s,background .12s,box-shadow .12s}
.ask-opt:hover{border-color:var(--accent-border,#c7d2fe);background:var(--surface-2)}
.ask-opt.active{border-color:var(--accent-fg);background:var(--accent-surface);box-shadow:0 0 0 1px var(--accent-fg) inset}
.ask-mark{flex:none;width:18px;height:18px;margin-top:1px;border:1.5px solid var(--line-2);display:grid;place-items:center;color:#fff;font-size:12px;line-height:1;transition:background .12s,border-color .12s}
.ask-opt-radio .ask-mark{border-radius:50%}
.ask-opt-check .ask-mark{border-radius:5px}
.ask-opt.active .ask-mark{background:var(--accent-fg);border-color:var(--accent-fg)}
.ask-opt-body{min-width:0}

/* Command palette (⌘K) — a global action index. Reuses the app's scrim/surface
   tokens so it reads as part of the mission-control system, not a bolt-on. */
.cmdk-back{position:fixed;inset:0;z-index:220;background:var(--scrim);display:flex;align-items:flex-start;justify-content:center;padding:12vh 16px 16px;overflow-y:auto}
.cmdk{width:100%;max-width:560px;background:var(--surface);border:1px solid var(--line-2);border-radius:14px;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 24px 60px var(--shadow-color);display:flex;flex-direction:column;max-height:76vh;overflow:hidden;animation:menu-in .16s cubic-bezier(.16,1,.3,1)}
.cmdk-search{display:flex;align-items:center;gap:9px;padding:12px 14px;border-bottom:1px solid var(--line)}
.cmdk-search-ic{color:var(--text-3);flex:none}
.cmdk-input{flex:1;min-width:0;border:none;background:none;outline:none;color:var(--text);font:inherit;font-size:15px;padding:2px 0}
.cmdk-input::placeholder{color:var(--text-3)}
.cmdk-esc{flex:none;font:inherit;font-size:10px;color:var(--text-3);border:1px solid var(--line-2);border-radius:5px;padding:2px 6px;line-height:1.4}
.cmdk-list{overflow-y:auto;padding:6px;flex:1;overscroll-behavior:contain}
.cmdk-sec{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);padding:10px 10px 4px}
.cmdk-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:start;border:none;background:none;color:var(--text-2);font:inherit;font-size:13.5px;padding:8px 10px;border-radius:8px;cursor:pointer}
.cmdk-opt.on{background:var(--surface-2);color:var(--text)}
.cmdk-opt-ic{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;color:var(--text-3)}
.cmdk-opt.on .cmdk-opt-ic{color:var(--accent)}
.cmdk-opt-main{flex:1;min-width:0;display:flex;align-items:baseline;gap:8px;overflow:hidden}
.cmdk-opt-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-opt-sub{flex:none;font-size:11px;color:var(--text-3);font-family:ui-monospace,Menlo,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40%}
.cmdk-opt-hint{flex:none;font:inherit;font-size:10px;color:var(--text-3);border:1px solid var(--line-2);border-radius:5px;padding:1px 5px}
.cmdk-empty{padding:26px 14px;text-align:center;color:var(--text-3);font-size:13px}
.cmdk-foot{display:flex;gap:16px;align-items:center;padding:8px 14px;border-top:1px solid var(--line);font-size:11px;color:var(--text-3);flex-wrap:wrap}
.cmdk-foot kbd{font:inherit;font-size:10px;border:1px solid var(--line-2);border-radius:5px;padding:1px 5px;margin-inline-end:2px}
.nav-cmdk{position:relative}
.nav-cmdk .nav-kbd{margin-inline-start:auto;font-size:10px;color:var(--text-3);border:1px solid var(--line-2);border-radius:5px;padding:1px 5px;line-height:1.5}
@media (prefers-reduced-motion: reduce){.cmdk{animation:none}}
@media (max-width:1000px){.cmdk-back{padding:8vh 12px 12px}.nav-cmdk .nav-kbd{display:none}.cmdk-opt{padding:11px 12px}}
.modal .bar{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--bg);flex-wrap:wrap}
.modal .bar select{width:auto;min-width:160px}
.modal .bar .sp{flex:1}
.modal .term{flex:1;min-height:0;padding:8px 10px;background:var(--term-bg)}
.modal .term .xterm{height:100%}
/* Sounds settings modal — pick a cue per finished-event type */
.sset{max-width:520px;width:calc(100% - 32px);margin:auto;background:var(--surface);border:1px solid var(--line-2);border-radius:14px;box-shadow:0 24px 64px var(--shadow-color);max-height:calc(100% - 48px);display:flex;flex-direction:column;overflow:hidden}
.sset-head{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--line)}
.sset-head h3{margin:0;font-size:15px;flex:1}
.sset-body{padding:4px 18px 10px;overflow-y:auto}
.sset input,.sset select,.sset button{box-sizing:border-box}
.sset-mute{display:flex;align-items:center;gap:11px;padding:15px 0 13px;font-size:13px;color:var(--text-1);cursor:pointer;border-bottom:1px solid var(--line)}
.sset-mute input[type=checkbox]{width:17px;height:17px;flex:0 0 auto;margin:0;padding:0;accent-color:var(--accent-fg)}
.sset-vol{display:flex;align-items:center;gap:12px;padding:14px 0;border-bottom:1px solid var(--line)}
.sset-vol.dim{opacity:.45}
.sset-vol .vlab{font-size:12px;color:var(--text-2);flex:0 0 auto}
.sset-vol input[type=range]{flex:1;width:auto;min-width:0;padding:0;background:none;border:none;accent-color:var(--accent-fg)}
.sset-vol .vpct{font-size:12px;color:var(--text-3);width:38px;text-align:end;flex:0 0 auto}
.sset-row{display:flex;flex-direction:column;gap:9px;padding:12px 0;border-bottom:1px solid var(--line)}
.sset-row:last-child{border-bottom:none}
.sset-rowmain{display:flex;align-items:center;gap:12px}
.sset-row.off .lbl,.sset-row.off select{opacity:.45}
.sset-toggle{flex:0 0 auto;display:flex;align-items:center;cursor:pointer}
.sset-toggle input[type=checkbox]{width:17px;height:17px;margin:0;padding:0;cursor:pointer;accent-color:var(--accent-fg)}
.sset-sub{display:flex;align-items:center;gap:8px;margin-inline-start:29px;font-size:12px;color:var(--text-2);cursor:pointer}
.sset-sub input[type=checkbox]{width:15px;height:15px;margin:0;padding:0;cursor:pointer;accent-color:var(--accent-fg)}
.sset-row.off .sset-sub{opacity:.45}
.sset-row .lbl{flex:1;min-width:0}
.sset-row .lbl .t{display:block;font-size:13px;font-weight:600;color:var(--text-1)}
.sset-row .lbl .d{display:block;font-size:11.5px;color:var(--text-3);margin-top:2px}
.sset-row select{flex:0 0 auto;width:150px;font-size:12.5px;padding:7px 9px;cursor:pointer}
.sset-play{flex:0 0 auto;width:38px;font-size:13px;padding:7px 0;text-align:center;border:1px solid var(--line-2);border-radius:8px;background:var(--surface-2);color:var(--text-2);cursor:pointer}
.sset-play:hover:not(:disabled){background:var(--accent-surface);border-color:var(--accent-fg);color:var(--accent-fg)}
.sset-play:disabled{opacity:.4;cursor:default}
/* Redesigned AI settings: one card per AI touchpoint */
.aiset{max-width:600px}
.aiset-intro{font-size:12.5px;line-height:1.55;color:var(--text-2);margin:12px 0 4px}
.aiset-card{padding:14px;margin:10px 0;background:var(--card);border:1px solid var(--card-line);border-radius:var(--radius-xl);box-shadow:var(--card-shadow)}
.aiset-cardhead{display:flex;align-items:flex-start;gap:12px}
.aiset-titles{flex:1;min-width:0}
.aiset-title{display:block;font-size:13.5px;font-weight:700;color:var(--text-1)}
.aiset-desc{display:block;font-size:11.5px;color:var(--text-3);margin-top:2px;line-height:1.45}
.aiset-controls{display:flex;gap:8px;flex-wrap:wrap;margin-top:11px}
.aiset-controls select{flex:1 1 140px;min-width:0;font-size:12.5px;padding:7px 9px;cursor:pointer}
.sset-foot{display:flex;align-items:center;gap:10px;padding:12px 18px;border-top:1px solid var(--line)}
.sset-foot .sp{flex:1}
/* GitHub connection panel + repo picker */
.gh-acct{display:flex;align-items:center;gap:10px;padding:13px 0;border-bottom:1px solid var(--line)}
.gh-acct img{width:34px;height:34px;border-radius:50%;flex:0 0 auto}
.gh-acct .who{flex:1;min-width:0}
.gh-acct .who .l{display:block;font-size:13px;font-weight:600;color:var(--text-1)}
.gh-acct .who .s{display:block;font-size:11.5px;color:var(--text-3);margin-top:1px}
.gh-search{width:100%;margin:12px 0 8px}
.gh-list{max-height:46vh;overflow-y:auto;border:1px solid var(--line);border-radius:10px}
.gh-row{display:flex;align-items:center;gap:10px;padding:9px 11px;border-bottom:1px solid var(--line);cursor:pointer}
.gh-row:last-child{border-bottom:none}
.gh-row:hover{background:var(--surface-2)}
.gh-row.sel{background:var(--accent-surface)}
.gh-row input{width:16px;height:16px;flex:0 0 auto;margin:0;accent-color:var(--accent-fg)}
.gh-row .nm{flex:1;min-width:0}
.gh-row .nm .t{display:block;font-size:13px;color:var(--text-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gh-row .nm .d{display:block;font-size:11px;color:var(--text-3);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gh-row .tag{flex:0 0 auto;font-size:10.5px;color:var(--text-4);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:0 6px}
.gh-row .lang{flex:0 0 auto;font-size:11px;color:var(--text-3)}
.gh-linked{flex:0 0 auto;font-size:10.5px;color:var(--ok)}
.tstat{font-size:12px}
.tstat.on{color:var(--ok)}.tstat.off{color:var(--err)}
/* file explorer modal (opened from the chat's working-dir link) */
.fbrow-scrim{position:fixed;inset:0;background:var(--scrim);z-index:210;display:grid;place-items:center;padding:20px}
.fbrow{width:min(1000px,96vw);height:min(700px,90vh);display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 24px 60px var(--shadow-color);overflow:hidden}
.fbrow .fhead{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--bg)}
.fbrow .fhead .fpath{flex:1;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--accent-fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:ltr}
.fbrow .fbody{flex:1;min-height:0;display:flex}
.fbrow .flist{width:300px;flex-shrink:0;overflow-y:auto;border-inline-end:1px solid var(--line);padding:4px}
.fbrow .fitem{display:flex;align-items:center;gap:8px;width:100%;text-align:start;padding:6px 8px;border-radius:7px;border:none;background:transparent;color:var(--text-2);font-size:12.5px;cursor:pointer;direction:ltr}
.fbrow .fitem:hover{background:var(--surface-soft)}
.fbrow .fitem.on{background:var(--accent-surface);color:var(--accent-fg)}
.fbrow .fitem .fn{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fbrow .fitem .fsz{flex-shrink:0;font-size:10.5px;color:var(--text-4)}
.fbrow .fitem.up{color:var(--text-3)}
.fbrow .fprev{flex:1;min-width:0;overflow:auto;background:var(--surface-soft)}
.fbrow .fprev pre{margin:0;padding:14px;font-family:ui-monospace,Menlo,monospace;font-size:12px;line-height:1.55;white-space:pre;color:var(--text-2)}
.fbrow .fprev .ftext{display:flex;flex-direction:column;min-height:100%}
.fbrow .fprev-head{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--bg);border-bottom:1px solid var(--line)}
.fbrow .fprev-head .ftitle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--text-2)}
.fbrow .fprev-head .fsavemsg{flex-shrink:0;font-size:11.5px;color:var(--ok)}
.fbrow .fprev-head .fsavemsg.bad{color:var(--err)}
.fbrow .fedit{flex:1;min-height:320px;width:100%;box-sizing:border-box;border:none;resize:none;padding:14px;font-family:ui-monospace,Menlo,monospace;font-size:12px;line-height:1.55;color:var(--text-1);background:var(--surface);outline:none;white-space:pre;overflow:auto}
.fbrow .fprev .fimg{display:block;max-width:100%;margin:0 auto;padding:14px}
.fbrow .fprev iframe{width:100%;height:100%;border:none;background:#fff}
.fbrow .fprev .fmsg{padding:24px;color:var(--text-4);font-size:13px;text-align:center}
.fbrow .fprev .dl{display:inline-block;margin-top:10px}
.fbrow .ferr{padding:10px 14px;color:var(--err);font-size:12px}
.fbrow .dsearch{display:flex;gap:8px;align-items:center;padding:10px 14px;border-bottom:1px solid var(--line);background:var(--bg)}
.fbrow .dsearch input{flex:1;min-width:0;font:inherit;font-size:12.5px;padding:7px 10px;border:1px solid var(--line-2);border-radius:var(--radius-control);background:var(--surface);color:var(--text)}
.fbrow .fitem .dpath{color:var(--text-4);font-size:11px}
/* autonomous AI-run transcript viewer (opened from a task card) */
.airun-body{flex:1;min-height:0;overflow:auto;background:var(--bg);padding:18px 16px}
.airun-inner{max-width:860px;margin:0 auto;display:flex;flex-direction:column;gap:8px}
.airun-foot{display:flex;flex-wrap:wrap;gap:14px;font-size:12px;margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}
/* right-side dock: persistent Claude chat + terminal for the selected project */
.dock{position:relative;width:460px;flex-shrink:0;border-inline-start:1px solid var(--line);display:flex;flex-direction:column;min-height:0;background:var(--bg)}
.dock.collapsed{width:42px;align-items:stretch}
/* drag-to-resize handles: left edge = width, top edge = height, top-left corner = both.
   The dock is anchored to the bottom of the viewport, so the free (resizable) edge is the top. */
.dock-rsz{position:absolute;z-index:30;touch-action:none;background:transparent;transition:background .12s}
.dock-rsz.x{top:0;bottom:0;inset-inline-start:0;width:6px;cursor:ew-resize}
.dock-rsz.y{inset-inline-start:0;inset-inline-end:0;top:0;height:6px;cursor:ns-resize}
.dock-rsz.xy{inset-inline-start:0;top:0;width:16px;height:16px;cursor:nwse-resize;z-index:31}
.dock-rsz.x:hover,.dock-rsz.y:hover,.dock-rsz.x.active,.dock-rsz.y.active{background:var(--accent)}
/* always-visible grip on the top edge so the panel reads as resizable upward */
.dock-rsz.y::after{content:"";position:absolute;inset-inline-start:50%;top:50%;transform:translate(-50%,-50%);width:36px;height:3px;border-radius:3px;background:var(--line-2);transition:background .12s}
.dock-rsz.y:hover::after,.dock-rsz.y.active::after{background:#fff}
/* always-visible corner grip so the panel reads as resizable */
.dock-rsz.xy::before{content:"";position:absolute;inset-inline-start:3px;top:3px;width:8px;height:8px;border-inline-start:2px solid var(--line-2);border-top:2px solid var(--line-2);border-radius:3px 0 0 0;transition:border-color .12s}
.dock-rsz.xy:hover::before,.dock-rsz.xy.active::before{border-color:var(--accent)}
.dock-open{font:inherit;cursor:pointer;flex:1;border:none;border-inline-start:1px solid var(--line);background:var(--surface);color:var(--accent-fg);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;writing-mode:vertical-rl;font-size:13px;letter-spacing:.05em}
.dock-open:hover{background:var(--surface-2)}
/* on tablets/large phones (portrait+landscape) hide the vertical collapsed-dock rail */
@media (max-width:1200px){.dock-open{display:none!important}.dock.collapsed{width:0!important;min-width:0!important;border:none!important;overflow:hidden}}
.dock-open span{transform:rotate(0)}
.dock-head{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--line);flex-shrink:0}
.dock-tabs{display:flex;gap:4px}
.dock-provider-tabs{display:flex;gap:4px}
.dock-provider-tabs button{display:inline-flex;align-items:center;justify-content:center;padding:5px 10px}
.dock-provider-tabs button .provider-logo{display:block}
.dock-tabs button{font:inherit;cursor:pointer;border:1px solid var(--line-2);background:var(--line);color:var(--text-2);border-radius:7px;padding:5px 11px;font-size:13px}
.dock-tabs button:hover{background:var(--line-2)}
.dock-tabs button.active{background:var(--accent);border-color:var(--accent);color:#fff}
.dock-provider-tabs button.provider-claude.active{background:color-mix(in srgb,var(--claude-orange) 12%,transparent);border-color:color-mix(in srgb,var(--claude-orange) 46%,transparent);color:var(--claude-orange-fg)}
.dock-provider-tabs button.provider-codex.active{background:color-mix(in srgb,var(--codex-chat) 13%,transparent);border-color:color-mix(in srgb,var(--codex) 34%,transparent);color:var(--codex-chat-fg)}
.dock-provider-tabs button.provider-gemini.active{background:color-mix(in srgb,var(--gemini-deep) 14%,transparent);border-color:color-mix(in srgb,var(--gemini) 42%,transparent);color:var(--gemini)}
.dock-head .sp{flex:1}
/* panel size controls: big, clear arrow glyphs instead of tiny unicode marks */
.dock-size-btn{display:inline-flex;align-items:center;justify-content:center;padding:0;line-height:0;width:40px;height:40px;min-width:40px;box-sizing:border-box}
.dock-size-btn svg{display:block;width:26px;height:26px}
.dock-size-btn:hover{background:var(--line-2);color:var(--text)}
.dock-size-btn.on{background:var(--accent);border-color:var(--accent);color:#fff}
.dock-head-chat{display:flex;align-items:center;gap:6px;min-width:0;flex-shrink:1}
/* Narrow dock (panel resized small, viewport may still be wide): the header must never
   drop the maximize / collapse / New chat controls. Pin them, let the flexible middle
   (AI options + History) shrink, and collapse History to its clock icon to free space. */
.dock-head{min-width:0;flex-wrap:nowrap;overflow:hidden}
.dock-head>.dock-tabs,.dock-head>.dock-size-btn{flex-shrink:0}
.dock-narrow .dock-head{gap:6px}
.dock-narrow .dock-head>.muted{display:none}
.dock-narrow .dock-head>.sp{flex:0 1 auto;min-width:0}
.dock-narrow .dock-head-chat .btn.sm{padding:4px 8px;font-size:12px}
.dock-narrow .dock-head .chist-lbl{display:none}
.dock-narrow .dock-head .new-chat-btn{flex-shrink:0;white-space:nowrap}
.dock-xnarrow .dock-head{gap:4px}
.dock-xnarrow .dock-provider-tabs button{padding:4px 7px}
.dock-xnarrow .dock-tabs button{padding:4px 8px}
.dock-xnarrow .dock-head-chat .btn.sm{padding:4px 6px}
/* AI-settings gear: an icon-only control next to text buttons reads as tiny, so give it
   a squarer, larger face (and keep it that way in the narrow dock variants above). */
.dock-head-chat .chat-ai-gear.btn.sm,
.dock-narrow .dock-head-chat .chat-ai-gear.btn.sm,
.dock-xnarrow .dock-head-chat .chat-ai-gear.btn.sm{font-size:18px;line-height:1;padding:0;width:34px;height:34px;min-width:34px;flex-shrink:0;box-sizing:border-box}
/* Equal-height header controls: every square/pill button in the chat dock header
   (provider tabs, terminal, gear, history, New chat, wide/minimize) shares one
   34px height so the row reads as a clean, symmetric strip. */
.dock-head .dock-tabs button,
.dock-head-chat>.chat-ai-gear.btn.sm,
.dock-head-chat>.chist>.btn.sm,
.dock-head-chat>.new-chat-btn.btn.sm,
.dock-size-btn{height:34px;min-height:34px;box-sizing:border-box}
.dock-body{flex:1;min-height:0;display:flex;flex-direction:column}
.dock-pane{flex:1;min-height:0;display:flex;flex-direction:column}
.dock-pane.hide{display:none}
/* claude chat fills the dock */
.claudepane{flex:1;min-height:0;display:flex;flex-direction:column;position:relative}
.chat-canvas-layout{flex:1;min-height:0;display:flex;min-width:0}
.chat-canvas-layout>.chat{flex:1;min-width:0}
.artifact-canvas{width:min(48%,720px);min-width:340px;display:flex;flex-direction:column;border-inline-start:1px solid var(--line-2);background:var(--surface);min-height:0}
.artifact-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 11px;border-bottom:1px solid var(--line);background:var(--bar-soft)}
.artifact-head>div:first-child{display:flex;flex-direction:column;min-width:0}.artifact-head b{font-size:13px}.artifact-head span{font-size:11px;color:var(--text-4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.artifact-actions{display:flex;gap:6px;flex-shrink:0}.artifact-actions a{text-decoration:none}
.artifact-body{flex:1;min-height:0;overflow:auto;background:var(--bg)}
.artifact-body pre{box-sizing:border-box;margin:0;padding:18px;min-height:100%;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.55 ui-monospace,Menlo,Consolas,monospace;color:var(--text-2)}
.artifact-body iframe{display:block;width:100%;height:100%;border:0;background:#fff}.artifact-body img{display:block;max-width:100%;margin:auto}.artifact-body>.md{padding:18px}
.artifact-empty{padding:30px;text-align:center;color:var(--text-4)}
@media(max-width:1000px){.chat-canvas-layout{position:relative}.artifact-canvas{position:absolute;inset:0;width:100%;min-width:0;z-index:35;border:0}}
/* AskModal docks directly above the chat composer rather than covering the chat.
   It used to be an absolute scrim over .chat (inset:0), which also blanketed the
   input row — that is what made a run parked for approval feel read-only. Kept in
   normal flow so the composer below stays live: you can answer the buttons, or
   just reply in the box (which resolves the ask as a denial carrying your text).
   order:31 sits it below the working-dir bar (order:30) and above the status
   indicator (.chat-state, order:32) and composer (.inp, order:33). The status is
   ALWAYS last before the composer — folder path (30) → question (31) → status
   (32) → composer (33) — matching the DOM source order used by non-flex .chat. */
/* The overlay caps how tall the ask can get; the modal fills that cap and scrolls
   INSIDE (see .ask-modal-body) rather than pushing its own footer off-screen, so
   Next/Send answer is always reachable without scrolling. */
.ask-overlay{position:relative;z-index:40;order:30;display:flex;justify-content:center;
  padding:8px 12px;border-top:1px solid var(--line);background:var(--bar-soft);
  max-height:82%;overflow:hidden;flex:0 1 auto;min-height:0}
.ask-overlay .ask-modal{display:flex;flex-direction:column;min-height:0;max-height:100%;padding:14px!important}
.ask-modal-inner{display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
/* only the question + options scroll, and only when they truly can't fit —
   header, progress and footer stay put so the buttons never leave the screen */
.ask-modal-body{flex:1 1 auto;min-height:0;overflow-y:auto}
.ask-modal-foot{flex:0 0 auto}
/* Compact metrics so the whole questionnaire fits the viewport without scrolling. */
.ask-modal .ask-q{font-size:14px;line-height:1.3;margin-bottom:1px}
.ask-modal .ask-opt{padding:7px 10px;gap:8px}
.ask-modal .ask-opt .ask-opt-body>span:first-child{font-size:13px}
.ask-modal .ask-opt .ask-opt-body>span:last-child{font-size:11.5px}
.ask-modal .ask-mark{width:16px;height:16px}
.ask-modal .ask-modal-body>div:nth-child(2){margin-bottom:7px}
.ask-modal-body{display:flex;flex-direction:column;gap:0}
.ask-modal-body .ask-opts{gap:6px!important}
.ask-modal .ask-progress{margin:2px 0 8px}
.ask-modal .ask-modal-foot{margin-top:10px!important}
.ask-modal .ask-modal-foot .btn{padding:6px 12px;font-size:13px}
.claudepane.provider-claude{
  --accent:var(--claude-orange);
  --accent-hover:var(--claude-orange-hover);
  --accent-fg:var(--claude-orange-fg);
  --accent-strong-fg:#fdba74;
  --accent-surface:color-mix(in srgb,var(--claude-orange) 18%,transparent);
  --accent-surface-2:color-mix(in srgb,var(--claude-orange) 12%,transparent);
  --accent-border:color-mix(in srgb,var(--claude-orange) 46%,transparent);
  --link:var(--claude-orange-fg);
  --chat-user-bg:color-mix(in srgb,var(--claude-orange) 16%,transparent);
  --chat-accent-hover:color-mix(in srgb,var(--claude-orange) 34%,transparent);
}
.claudepane.provider-codex{
  --accent:var(--codex-chat);
  --accent-hover:var(--codex-chat-hover);
  --accent-fg:var(--codex-chat-fg);
  --accent-strong-fg:#a5f3fc;
  --accent-surface:color-mix(in srgb,var(--codex-chat) 18%,transparent);
  --accent-surface-2:color-mix(in srgb,var(--codex-chat) 12%,transparent);
  --accent-border:color-mix(in srgb,var(--codex) 44%,transparent);
  --link:var(--codex-chat-fg);
  --chat-user-bg:color-mix(in srgb,var(--codex-chat) 16%,transparent);
  --chat-accent-hover:color-mix(in srgb,var(--codex-chat) 34%,transparent);
}
/* Light theme: the pale cyan (#67e8f9) is too faint on white. Darken the
   link/accent foreground in the codex pane so chat text/links stay readable. */
html:not(.dark) .claudepane.provider-codex{
  --accent-fg:var(--codex-chat-hover);
  --link:var(--codex-chat-hover);
}
.claudepane.provider-gemini{
  --accent:var(--gemini-deep);
  --accent-hover:var(--gemini-deep-hover);
  --accent-fg:var(--gemini);
  --accent-strong-fg:#6ee7b7;
  --accent-surface:color-mix(in srgb,var(--gemini-deep) 18%,transparent);
  --accent-surface-2:color-mix(in srgb,var(--gemini-deep) 12%,transparent);
  --accent-border:color-mix(in srgb,var(--gemini) 42%,transparent);
  --link:var(--gemini);
  --chat-user-bg:color-mix(in srgb,var(--gemini-deep) 16%,transparent);
  --chat-accent-hover:color-mix(in srgb,var(--gemini-deep) 34%,transparent);
}
.claudepane-head{display:flex;align-items:center;gap:8px;padding:1px 12px 6px;border-bottom:1px solid var(--line);font-size:11px;color:var(--text-4);flex-shrink:0;position:sticky;top:0;z-index:8;background:var(--bg)}
.claudepane-head .title{flex:1;min-width:0;font-size:14px;font-weight:600;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.25}
.runstatus-bottom{display:flex;align-items:center;gap:7px;min-width:0;margin:0 12px 8px;border:1px solid var(--accent-border);background:var(--accent-surface-2);color:var(--accent-fg);border-radius:8px;padding:7px 10px;font-size:12px;font-weight:700;white-space:nowrap;flex-shrink:0}
.runstatus-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
.runstatus-dot{width:6px;height:6px;border-radius:50%;background:currentColor;box-shadow:0 0 0 0 color-mix(in srgb,var(--codex) 35%,transparent);animation:runpulse 1.2s ease-in-out infinite;flex-shrink:0}
.provider-claude .runstatus-dot{box-shadow:0 0 0 0 color-mix(in srgb,var(--claude-orange) 36%,transparent)}
.provider-gemini .runstatus-dot{box-shadow:0 0 0 0 color-mix(in srgb,var(--gemini) 36%,transparent)}
.chat-state{display:flex;align-items:center;gap:9px;margin:0 12px 8px;border:1px solid var(--line-2);background:var(--bar-soft);color:var(--text-3);border-radius:8px;padding:8px 10px;font-size:12px;flex-shrink:0;order:31}
.chat-state .state-dot{width:8px;height:8px;border-radius:50%;background:var(--text-4);flex-shrink:0}
.chat-state .state-copy{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.chat-state .state-copy b{font-size:12px;line-height:1.2;color:var(--text-2)}
.chat-state .state-copy span{font-size:11.5px;line-height:1.35;color:var(--text-4);overflow:hidden;text-overflow:ellipsis}
/* The active-chat banner uses the same state language as every conversation dot. */
.chat-state.state-idle{border-color:color-mix(in srgb,var(--chat-done) 55%,transparent);background:color-mix(in srgb,var(--chat-done) 10%,transparent)}
.chat-state.state-idle .state-dot{background:var(--chat-done)}
.chat-state.state-idle .state-copy b{color:var(--chat-done)}
/* Blue — the agent is waiting for approval or an answer. */
.chat-state.state-waiting{border-color:color-mix(in srgb,var(--chat-waiting) 55%,transparent);background:color-mix(in srgb,var(--chat-waiting) 10%,transparent)}
.chat-state.state-waiting .state-dot{background:var(--chat-waiting)}
.chat-state.state-waiting .state-copy b{color:var(--chat-waiting)}
/* Orange — agent currently working or processing (processing / loading) */
.chat-state.state-processing,.chat-state.state-loading{border-color:color-mix(in srgb,var(--chat-working) 55%,transparent);background:color-mix(in srgb,var(--chat-working) 12%,transparent)}
.chat-state.state-processing .state-dot,.chat-state.state-loading .state-dot{background:var(--chat-working);animation:runpulse 1.2s ease-in-out infinite}
.chat-state.state-processing .state-copy b,.chat-state.state-loading .state-copy b{color:var(--chat-working)}
/* Red — agent stopped, stuck, or cancelled (stuck / error) */
.chat-state.state-stuck,.chat-state.state-error,.chat-state.state-stopped{border-color:color-mix(in srgb,var(--chat-error) 55%,transparent);background:color-mix(in srgb,var(--chat-error) 10%,transparent)}
.chat-state.state-stuck .state-dot,.chat-state.state-error .state-dot,.chat-state.state-stopped .state-dot{background:var(--chat-error)}
.chat-state.state-stuck .state-copy b,.chat-state.state-error .state-copy b,.chat-state.state-stopped .state-copy b{color:var(--chat-error)}
/* Blue, pulsing — the socket dropped but the run is alive server-side and we are
   re-attaching to the same turn. Deliberately NOT the red error treatment: it is
   a transient transport hiccup, not a lost answer. */
.chat-state.state-reconnecting{border-color:color-mix(in srgb,var(--chat-waiting) 45%,transparent);background:color-mix(in srgb,var(--chat-waiting) 8%,transparent)}
.chat-state.state-reconnecting .state-dot{background:var(--chat-waiting);animation:runpulse 1.2s ease-in-out infinite}
.chat-state.state-reconnecting .state-copy b{color:var(--chat-waiting)}
.chat-state .btn{flex-shrink:0}
@keyframes runpulse{0%,100%{opacity:.55;transform:scale(.9);box-shadow:0 0 0 0 color-mix(in srgb,var(--codex) 25%,transparent)}50%{opacity:1;transform:scale(1.18);box-shadow:0 0 0 5px color-mix(in srgb,var(--codex) 0%,transparent)}}
/* "Copy chat" in the chat header. It previously styled itself with var(--bg-2)/var(--bg-3),
   which are defined nowhere in this sheet — so the background fell back to transparent and
   the button dissolved into the header's own background, reading as "disappeared". Uses the
   real surface/line tokens now so it renders as a visible button in both themes. */
.copychat-btn{flex-shrink:0;white-space:nowrap;font-size:11.5px;font-weight:600;line-height:1.3;color:var(--text-3);background:var(--surface);border:1px solid var(--line-2);border-radius:7px;padding:2px 9px;cursor:pointer;transition:background .15s,border-color .15s,color .15s}
.copychat-btn:hover{background:var(--bar-soft);border-color:var(--accent);color:var(--text)}
/* Chat direction button (header, next to Copy chat). Forces LTR on chat text.
   The forced mode wins over each element's own dir="" attribute, so an author
   `direction`/`text-align` rule applied from the pane overrides every bubble at
   once — no re-render needed. */
.dirmode-btn{flex-shrink:0;white-space:nowrap;font-size:11.5px;font-weight:600;line-height:1.3;color:var(--text-3);background:var(--surface);border:1px solid var(--line-2);border-radius:7px;padding:2px 9px;cursor:pointer;transition:background .15s,border-color .15s,color .15s}
.dirmode-btn:hover{background:var(--bar-soft);border-color:var(--accent);color:var(--text)}
.dirmode-btn.on{color:var(--text);border-color:var(--accent)}
.claudepane[data-dirmode="rtl"] .cmsg .bubble,
.claudepane[data-dirmode="rtl"] .cmsg .atext,
.claudepane[data-dirmode="rtl"] .msg-edit-textarea,
.claudepane[data-dirmode="rtl"] .inp textarea{direction:rtl;text-align:right}
.claudepane[data-dirmode="ltr"] .cmsg .bubble,
.claudepane[data-dirmode="ltr"] .cmsg .atext,
.claudepane[data-dirmode="ltr"] .msg-edit-textarea,
.claudepane[data-dirmode="ltr"] .inp textarea{direction:ltr;text-align:start}
/* Code, terminal output and file paths stay LTR whichever way the prose reads. */
.claudepane[data-dirmode] .cblock,
.claudepane[data-dirmode] .cblock-pre,
.claudepane[data-dirmode] .bubble pre,
.claudepane[data-dirmode] .bubble code{direction:ltr;text-align:start}
/* Browser-style conversation tabs — flip between chats without the history menu */
.chat-tabs-bar{display:flex;align-items:center;gap:3px;padding:1px 6px;border-bottom:1px solid var(--line);background:var(--bg);flex-shrink:0;position:sticky;top:0;z-index:7}
.chat-tabs{display:flex;gap:5px;overflow-x:auto;scroll-behavior:smooth;flex:1;min-width:0;scrollbar-width:none}
.chat-tabs::-webkit-scrollbar{display:none}
.ctab{position:relative;display:flex;align-items:center;gap:5px;flex-shrink:0;height:28px;max-width:170px;padding:1px 9px;border:1px solid var(--line-2);border-top:2px solid transparent;border-radius:7px 7px 4px 4px;background:var(--line);color:var(--text-3);cursor:pointer;font-size:12px;line-height:1.45}
.ctab:hover{background:var(--line-2)}
/* Drag-to-reorder: the lifted tab fades, and a caret marks where it would land. */
.ctab.dragging{opacity:.4}
.ctab.drop-before::before,.ctab.drop-after::after{content:"";position:absolute;top:2px;bottom:2px;width:2px;border-radius:2px;background:var(--accent-fg);box-shadow:0 0 0 1px var(--bg)}
.ctab.drop-before::before{inset-inline-start:-4px}
.ctab.drop-after::after{inset-inline-end:-4px}
.ctab.active{background:var(--surface);color:var(--text)}
.ctab.claude.active{border-top-color:var(--claude-orange)}
.ctab.codex.active{border-top-color:var(--codex)}
.ctab.gemini.active{border-top-color:var(--gemini)}
.ctab-t{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;unicode-bidi:plaintext}
/* Shared conversation-status light across tabs, History, and Recent chats:
   colour = state, .live = blinking (an active run). */
.chat-status-dot{font-size:8px;flex-shrink:0;line-height:1}
.chat-status-dot.dot-working{color:var(--chat-working)}
.chat-status-dot.dot-waiting{color:var(--chat-waiting)}
.chat-status-dot.dot-done{color:var(--chat-done)}
.chat-status-dot.dot-error{color:var(--chat-error)}
.chat-status-dot.live{animation:cipulse 1.2s ease-in-out infinite}
.ctab-x{position:absolute;inset-inline-end:6px;top:50%;transform:translateY(-50%);width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center;background:var(--surface);border:1px solid var(--line-2);color:var(--text-5);cursor:pointer;font-size:11px;line-height:1;padding:0;opacity:0;pointer-events:none;border-radius:5px;box-shadow:0 1px 4px var(--shadow-color);transition:opacity .14s ease,color .14s ease,background .14s ease,border-color .14s ease}
.ctab:hover .ctab-x,.ctab:focus-within .ctab-x{opacity:.88;pointer-events:auto}
/* Touch: :hover is sticky and only lands on the first tap, so a hover-gated ✕ made
   switching tabs feel like a two-tap action. Show ✕ on the active tab only. */
@media (hover:none){.ctab:hover{background:var(--line)}.ctab.active:hover{background:var(--surface)}.ctab:hover .ctab-x{opacity:0;pointer-events:none}.ctab.active .ctab-x{opacity:.88;pointer-events:auto}}
.ctab-x:hover,.ctab-x:focus-visible{color:var(--err);border-color:rgba(252,165,165,.5);opacity:1;outline:none}
/* Chat-tab actions intentionally mirror the project-list context menu. Keep
   these values aligned with .ctx-menu / .ctx-menu-title / .menu-item above. */
.ctab-menu{position:absolute;z-index:30;width:200px;max-width:calc(100vw - 16px);display:flex;flex-direction:column;gap:2px;padding:6px;border:1px solid var(--line-2);border-radius:12px;background:color-mix(in srgb,var(--surface) 92%,transparent);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 18px 44px var(--shadow-color);color:var(--text);transform-origin:top left;animation:menu-in .14s cubic-bezier(.16,1,.3,1)}
.ctab-menu-title{padding:6px 10px 8px;margin-bottom:2px;border-bottom:1px solid var(--card-line);font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--text-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;unicode-bidi:plaintext}
.ctab-menu button{display:flex;align-items:center;gap:9px;width:100%;font:inherit;font-size:13px;text-align:start;padding:8px 10px;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--text-2);cursor:pointer;transition:background .13s,color .13s}
.ctab-menu button:hover,.ctab-menu button:focus-visible{background:var(--surface-2);color:var(--text);outline:none}
.ctab-menu-danger{color:var(--err)!important}
.ctab-menu-danger:hover,.ctab-menu-danger:focus-visible{background:color-mix(in srgb,var(--err) 14%,transparent)!important;color:var(--err)!important}
.ctab-nav{flex-shrink:0;height:28px;background:var(--line);border:1px solid var(--line-2);color:var(--text-3);cursor:pointer;border-radius:var(--radius-control);font-size:13px;line-height:1;padding:2px 7px}
.ctab-nav:hover{background:var(--line-2)}
.modelbar{display:flex;gap:4px;flex:1 1 220px;min-width:0;max-width:100%;margin-inline-start:auto;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:thin;padding-bottom:2px}
.modelbar::-webkit-scrollbar{height:6px}
.modelbar::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:999px}
.modelbar .ppill{font:inherit;font-size:10px;font-weight:700;cursor:pointer;border:1px solid var(--line-2);background:var(--surface-2);color:var(--text-3);border-radius:999px;padding:4px 8px}
.modelbar .ppill.active{border-color:var(--accent);background:var(--accent-surface);color:var(--accent-fg)}
.modelbar .modelsep{width:1px;background:var(--line-2);margin:2px 3px}
.mpill{font:inherit;cursor:pointer;border:1px solid var(--line);background:transparent;color:var(--text-4);border-radius:20px;padding:2px 8px;font-size:10px;line-height:1.5;white-space:nowrap;transition:border-color .12s,color .12s,background .12s}
.mpill:hover:not(:disabled){border-color:var(--line-2);color:var(--text-3)}
.mpill.active{background:var(--accent-surface);border-color:var(--accent-border);color:var(--accent-fg)}
.mpill:disabled{opacity:.45;cursor:default}
.mpill .mhint{margin-inline-start:3px;font-size:9px;opacity:.65;font-style:italic}
/* chat text-size (+/−) controls in the working-dir bar */
.fontbar{display:flex;gap:2px;flex-shrink:0;margin-inline-start:auto}
.claudepane-head .fontbar{margin-inline-start:0}
.fontbar+.modelbar{margin-inline-start:8px}
.fbtn{font:inherit;cursor:pointer;border:1px solid var(--line);background:transparent;color:var(--text-4);border-radius:6px;padding:2px 6px;font-size:10px;line-height:1.5;min-width:22px;white-space:nowrap;font-variant-numeric:tabular-nums;transition:border-color .12s,color .12s}
.fbtn:hover:not(:disabled){border-color:var(--line-2);color:var(--text-3)}
.fbtn.fpct{min-width:34px;color:var(--text-3)}
.fbtn:disabled{opacity:.45;cursor:default}
.dock .chat{flex:1;min-height:0;display:flex;flex-direction:column;border:none;border-radius:0;background:transparent}
.dock .chat .log{flex:1;max-height:none}
.claudepane .btn.primary:hover{background:var(--btn-primary-hover)}
/* chat history dropdown */
.chist{position:relative;flex-shrink:0}
.chist .btn.hasnew{position:relative}
.chist-dot{position:absolute;top:-3px;inset-inline-end:-3px;width:9px;height:9px;border-radius:50%;background:var(--chat-done);border:2px solid var(--surface);box-shadow:0 0 0 1px color-mix(in srgb,var(--chat-done) 40%,transparent)}
.chist-item .chat-status-dot{font-size:9px}
/* Little mark on chats that were created from a task. */
.ci-task{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;font-size:8px;line-height:1;width:13px;height:13px;border-radius:50%;background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent);font-weight:700}
/* Turns orange while the task chat is parked waiting for you to approve/answer. */
.ci-task.act{background:color-mix(in srgb,#F59E0B 22%,transparent);color:#F59E0B;font-size:10px}
.chist-menu{position:absolute;top:calc(100% + 6px);inset-inline-start:0;z-index:40;width:440px;max-width:calc(100vw - 24px);max-height:520px;overflow-y:auto;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;box-shadow:0 12px 32px var(--shadow-color);padding:6px}
.chist-tabs{display:flex;gap:6px;padding:2px 0 8px;margin-bottom:4px;border-bottom:1px solid var(--line-2);position:sticky;top:0}
.chist-tab{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;font:inherit;font-size:12.5px;background:transparent;color:var(--text-3);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:6px 8px;cursor:pointer;transition:all .15s;white-space:nowrap}
.chist-tab:hover{color:var(--text-1);border-color:var(--text-4)}
.chist-tab.on{background:var(--surface-2);color:var(--text);border-color:transparent;box-shadow:0 1px 3px rgba(24,25,27,.06)}
.chist-tab-n{font-size:11px;font-weight:600;background:var(--line);border-radius:999px;padding:0 6px;min-width:16px;text-align:center}
.chist-tab.on .chist-tab-n{background:var(--slate-soft)}
.chist-search{width:100%;box-sizing:border-box;margin:2px 0 6px;padding:6px 8px;font:inherit;font-size:12px;background:var(--surface-2);border:1px solid var(--line-2);border-radius:6px;color:var(--text)}
.chist-group+.chist-group{margin-top:4px}
.chist-glabel{padding:6px 8px 2px;font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4)}
.chist-item{display:flex;align-items:flex-start;gap:6px;padding:8px;border-radius:6px}
.chist-item:hover{background:var(--surface-2)}
.chist-item.active{background:var(--accent-surface)}
.chist-item .ci-t{flex:1;min-width:0;display:flex;align-items:flex-start;gap:6px;text-align:start;background:none;border:none;color:var(--text-2);cursor:pointer;font:inherit;font-size:13px;padding:0}
.chist-item .ci-tt{min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;word-break:break-word;line-height:1.35;padding-top:1px}
.chist-item .ci-bar{flex-shrink:0;align-self:stretch;width:3px;min-height:16px;border-radius:999px;background:var(--text-5)}
.chist-item .ci-bar.claude{background:var(--claude-orange)}
.chist-item .ci-bar.codex{background:var(--codex)}
.chist-item .ci-bar.gemini{background:var(--gemini)}
@keyframes cipulse{0%,100%{opacity:.35}50%{opacity:1}}
.chist-item .ci-n{flex-shrink:0;font-size:10px;color:var(--text-4);background:var(--line);border-radius:8px;padding:0 5px;line-height:15px}
.chist-item .ci-w{font-size:11px;color:var(--text-4);flex-shrink:0}
.chist-item .ci-r,.chist-item .ci-d{background:none;border:none;color:var(--text-5);cursor:pointer;font-size:12px;line-height:1;padding:0 2px;flex-shrink:0;opacity:0}
.chist-item:hover .ci-r,.chist-item:hover .ci-d,.chist-item.active .ci-r,.chist-item.active .ci-d{opacity:1}
.chist-item .ci-r:hover{color:var(--accent-fg)}
.chist-item .ci-d:hover{color:var(--err)}
.chist-empty{padding:10px 8px;color:var(--text-4);font-size:12px}
/* working-directory bar shown above the chat field */
.chatdir{display:flex;align-items:center;gap:7px;padding:3px 12px 5px;border-top:1px solid var(--line);font-size:11px;color:var(--text-3);background:var(--bar-soft);flex-shrink:0;flex-wrap:wrap;order:32}
.chatdir .lbl{flex-shrink:0;color:var(--text-4)}
.chatdir .pth{font-family:ui-monospace,Menlo,monospace;color:var(--accent-fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:ltr;min-width:0;flex-shrink:1}
.chatdir .none{color:var(--text-4)}
.chatdir .agchip{flex-shrink:0;padding:1px 7px;border-radius:999px;font-size:10.5px;white-space:nowrap;border:1px solid var(--line-2)}
.chatdir .agchip.on{color:var(--run);border-color:color-mix(in srgb,var(--run) 40%,transparent);background:color-mix(in srgb,var(--run) 10%,transparent)}
.chatdir .agchip.off{color:var(--err);border-color:color-mix(in srgb,var(--err) 40%,transparent);background:color-mix(in srgb,var(--err) 10%,transparent)}
/* Right-aligned status cluster: session cost, session id, context pie. Quiet
   metadata, but held at --text-3 so 11px labels still clear WCAG AA on the
   soft strip (--text-4 muted would fail ~2.9:1). */
.chatdir .ss-meta{margin-inline-start:auto;display:flex;align-items:center;gap:10px;flex-shrink:0}
.chatdir .ss-cost,.chatdir .ss-sess{font-size:11px;color:var(--text-3);white-space:nowrap}
.chatdir .ss-cost{font-variant-numeric:tabular-nums}
/* Path/status strip spans ~90% of the chat column, centered (overrides the
   width:100% shared rule above). */
.chat .chatdir{width:90%;max-width:none;margin-inline:auto}
/* tip-based prompt suggestions, docked as a sticky strip above the working-dir bar */
.csugg-lbl{margin-top:14px;margin-bottom:6px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4)}
.csugg{display:flex;flex-direction:column;gap:6px}
.csugg .sg,.csugg-dock .sg,.csugg-empty .sg{font:inherit;cursor:pointer;border:1px solid var(--accent-border);background:var(--accent-surface-2);color:var(--accent-strong-fg);border-radius:8px;padding:7px 10px;font-size:12px;line-height:1.4;text-align:start;display:flex;flex-direction:column;gap:2px}
.csugg .sg:hover,.csugg-dock .sg:hover,.csugg-empty .sg:hover{background:var(--chat-accent-hover);border-color:var(--accent)}
.csugg .sg .sg-c,.csugg-dock .sg .sg-c,.csugg-empty .sg .sg-c{color:var(--link);font-size:10px;text-transform:uppercase;letter-spacing:.03em}
.csugg .sg .sg-t,.csugg-dock .sg .sg-t,.csugg-empty .sg .sg-t{color:var(--text);font-weight:500}
/* in-chat suggestion cards: shown in the empty chat area, cleared once a conversation starts */
.csugg-empty{margin-top:22px;width:100%;max-width:640px}
.csugg-empty-lbl{margin-bottom:8px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4)}
.csugg-empty-grid{display:flex;flex-direction:column;gap:8px}
.csugg-empty .sg{padding:9px 12px;width:100%}
/* Recent-chats list shown on the empty new-chat page (last 5 chats) */
.last-chats-list{display:flex;flex-direction:column;gap:4px}
.last-chats-list .lc-row{display:flex;align-items:center;gap:8px;width:100%;text-align:start;font:inherit;cursor:pointer;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:9px 12px}
.last-chats-list .lc-row:hover{background:var(--accent-surface);border-color:var(--accent-border)}
.last-chats-list .lc-row .ci-bar{flex-shrink:0;align-self:stretch;width:3px;min-height:16px;border-radius:999px;background:var(--text-5)}
.last-chats-list .lc-row .ci-bar.claude{background:var(--claude-orange)}
.last-chats-list .lc-row .ci-bar.codex{background:var(--codex)}
.last-chats-list .lc-row .chat-status-dot{font-size:9px}
.last-chats-list .lc-row .lc-t{flex:1;min-width:0;color:var(--text);font-weight:500;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.last-chats-list .lc-row .lc-w{flex-shrink:0;color:var(--text-4);font-size:11px}
/* long text must always wrap cleanly inside card boundaries */
.csugg .sg,.csugg-dock .sg,.csugg-empty .sg,
.csugg .sg .sg-t,.csugg-dock .sg .sg-t,.csugg-empty .sg .sg-t,
.csugg .sg .sg-c,.csugg-dock .sg .sg-c,.csugg-empty .sg .sg-c{overflow-wrap:anywhere;word-break:break-word;white-space:normal;min-width:0}
/* sticky suggestion dock: sits just above the .chatdir path bar in an empty chat */
.csugg-dock{flex-shrink:0;border-top:1px solid var(--line);background:var(--bar-soft);padding:7px 12px}
.csugg-dock-lbl{margin-bottom:6px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-4)}
.csugg-dock-row{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px}
.csugg-dock-row .sg{flex:0 0 auto;max-width:260px}
.csugg-dock-row .sg .sg-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* terminal pane fills the dock */
.termpane{flex:1;min-height:0;display:flex;flex-direction:column}
.termpane-head{display:flex;align-items:center;gap:8px;padding:6px 10px;border-bottom:1px solid var(--line);flex-shrink:0;flex-wrap:wrap}
.termpane-head select{width:auto;min-width:120px}
.termpane-head .sp{flex:1}
.termpane .term{flex:1;min-height:0;padding:6px 8px;background:var(--term-bg)}
.termpane .term .xterm{height:100%}
/* editor */
input,textarea,select{font:inherit;color:var(--text);background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:8px 10px;width:100%}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--accent)}
textarea{resize:vertical;min-height:64px;line-height:1.5}
.fld{display:block;margin-bottom:12px}
.fld>.lbl{display:block;font-size:12px;color:var(--text-3);margin-bottom:4px}
.fld .hint{font-weight:400;color:var(--text-5)}
.fld .hint-i{cursor:help;color:var(--text-4);font-weight:400}
.fld .hint-i:hover{color:var(--text-2)}
button{white-space:nowrap}
.btn{font:inherit;cursor:pointer;border-radius:var(--radius-control);padding:var(--pad-control);border:1px solid var(--line-2);background:var(--surface);color:var(--text);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;vertical-align:middle;box-sizing:border-box}
.btn:hover{background:var(--line-2)}
.btn:disabled{opacity:.5;cursor:default}
.btn.primary{background:var(--btn-primary);border-color:transparent;color:#fff}
.btn.primary:hover:not(:disabled){background:var(--btn-primary-hover)}
.btn.primary:disabled{opacity:.5;cursor:default}
.btn.danger{background:transparent;border-color:#7f1d1d;color:var(--err)}
.btn.danger:hover{background:#7f1d1d;color:#fff}
.btn.sm{padding:var(--pad-control-sm);font-size:13px;min-height:30px}
.btn.xs{padding:3px 9px;font-size:11.5px;min-height:26px}
.chat .inp .iconbtn,.chat .inp .btn.sm{width:40px;height:40px;min-width:40px;min-height:40px;padding:0 12px;box-sizing:border-box}
.chat .inp .btn.sm{width:auto}
.schedule-chat-pop{position:absolute;z-index:30;inset-inline-end:10px;bottom:calc(100% + 8px);width:min(360px,calc(100vw - 28px));padding:12px;background:var(--surface);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 16px 42px #0005;display:grid;gap:9px}
.schedule-chat-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.schedule-chat-pop label{display:grid;gap:4px;font-size:11px;color:var(--text-3)}
.schedule-chat-pop input{font-size:13px;padding:7px 9px}
.schedule-chat-actions{display:flex;justify-content:flex-end;gap:7px}
.schedule-chat-list{border-top:1px solid var(--line);padding-top:8px;display:grid;gap:5px;font-size:11px}
.schedule-chat-list>div{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:7px}
.schedule-chat-list span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
.schedule-chat-list small{color:var(--text-4);white-space:nowrap}
.schedule-chat-list button{border:0;background:none;color:var(--text-4);cursor:pointer;padding:2px}
/* Split "Ask …" button on a task card: main face + caret that opens the AI picker */
.askbtn{position:relative;display:flex;align-items:stretch}
.askbtn-main{flex:1;min-width:0;border-top-right-radius:0;border-bottom-right-radius:0;overflow:hidden;text-overflow:ellipsis}
.askbtn-caret{flex:0 0 auto;padding:3px 6px;margin-inline-start:-1px;border-top-left-radius:0;border-bottom-left-radius:0;font-size:9px;line-height:1}
.askbtn-caret.open{background:var(--accent-surface);border-color:var(--accent-fg);color:var(--accent-fg)}
.askbtn-pop{position:absolute;top:calc(100% + 6px);inset-inline-end:0;z-index:60;width:212px;background:color-mix(in srgb,var(--surface) 92%,transparent);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 18px 44px var(--shadow-color);padding:6px;transform-origin:top right;animation:menu-in .14s cubic-bezier(.16,1,.3,1)}
.askbtn-pop .menu-item{font-size:12.5px}
.askbtn-pop .provider-logo{width:15px;height:15px;flex-shrink:0}
.askbtn-arr{font-size:10px;color:var(--text-4)}
.askbtn-group{position:relative}
/* Claude models fly out to the side of the provider menu, not below it */
.askbtn-sub{position:absolute;top:-6px;inset-inline-end:calc(100% + 8px);z-index:61;width:190px;background:color-mix(in srgb,var(--surface) 92%,transparent);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 18px 44px var(--shadow-color);padding:6px;transform-origin:top right;animation:menu-in .14s cubic-bezier(.16,1,.3,1)}
.askbtn-sub::before{content:"";position:absolute;top:0;bottom:0;inset-inline-end:-8px;width:8px}
.askbtn-sub .menu-item{font-size:12px;padding:6px 8px}
.askbtn-sub .ic{font-size:11px;width:14px;text-align:center;flex-shrink:0;color:var(--text-4)}
.askbtn-hint{font-size:10px;color:var(--text-4)}
.new-chat-btn.claude{background:var(--claude-orange);border-color:var(--claude-orange);color:#fff;font-weight:600}
.new-chat-btn.claude:hover:not(:disabled){background:var(--claude-orange-hover);border-color:var(--claude-orange-hover)}
.new-chat-btn.codex{background:var(--codex-chat);border-color:var(--codex-chat);color:#fff;font-weight:600}
.new-chat-btn.codex:hover:not(:disabled){background:var(--codex-chat-hover);border-color:var(--codex-chat-hover)}
.new-chat-btn.gemini{background:var(--gemini-deep);border-color:var(--gemini-deep);color:#fff;font-weight:600}
.new-chat-btn.gemini:hover:not(:disabled){background:var(--gemini-deep-hover);border-color:var(--gemini-deep-hover)}
.new-chat-btn:disabled{opacity:.45;cursor:default}
.dirbrowse{margin-top:6px;border:1px solid var(--line-2);border-radius:8px;background:var(--surface);box-shadow:0 10px 30px var(--shadow-color);overflow:hidden}
.dirbrowse .db-head{display:flex;align-items:center;gap:8px;padding:6px 8px;border-bottom:1px solid var(--line)}
.dirbrowse .db-path{flex:1;font-size:12px;font-family:ui-monospace,monospace;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start}
.dirbrowse .db-list{max-height:240px;overflow-y:auto;padding:4px}
.dirbrowse .db-item{display:block;width:100%;text-align:start;background:none;border:none;color:var(--text);font:inherit;font-size:13px;padding:5px 8px;border-radius:6px;cursor:pointer}
.dirbrowse .db-item:hover{background:var(--line)}
.dirbrowse .db-foot{padding:6px 8px;border-top:1px solid var(--line);display:flex;justify-content:flex-end}
.seg{display:inline-flex;border:1px solid var(--line-2);border-radius:8px;overflow:hidden}
.seg-b{background:var(--surface);border:none;color:var(--text-3);font:inherit;font-size:13px;padding:7px 12px;cursor:pointer;white-space:nowrap}
.seg-b+.seg-b{border-inline-start:1px solid var(--line-2)}
.seg-b.on{background:var(--accent);color:#fff}
.tip-status{width:auto;padding:3px 7px;font-size:11.5px;background:var(--line);border-color:var(--line-2);border-radius:6px;cursor:pointer}
.tip-nudge{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:8px;padding:6px 8px;font-size:12px;border-radius:7px;background:color-mix(in srgb,var(--run) 12%,transparent);border:1px solid color-mix(in srgb,var(--run) 40%,transparent);color:#bbf7d0}
.tip-nudge-approval>span{flex:1 1 180px;min-width:120px;overflow-wrap:normal;word-break:normal}
.tip-nudge-x{background:none;border:none;color:#86efac;cursor:pointer;font-size:12px;line-height:1;padding:2px 5px;border-radius:4px}
.tip-nudge-x:hover{background:color-mix(in srgb,var(--run) 20%,transparent)}
/* transparent full-screen catcher behind a popover/tooltip — a click on "the back"
   (anywhere outside the popover) closes it, mirroring the modal/iframe overlays */
.pop-back{position:fixed;inset:0;z-index:65;background:transparent}
/* Per-task explainer button + its popover */
.whatis{position:relative}
.whatis>.btn{width:100%}
.whatis-pop{position:absolute;top:calc(100% + 6px);inset-inline-end:0;z-index:70;width:270px;background:var(--surface);border:1px solid var(--line-2);border-radius:8px;padding:11px 12px 12px;font-size:12.5px;line-height:1.65;color:var(--text);box-shadow:0 10px 30px var(--shadow-color);text-align:start}
.whatis-pop .x{position:absolute;top:5px;inset-inline-start:7px;background:none;border:none;color:var(--text-4);cursor:pointer;font-size:12px;line-height:1;padding:2px}
.whatis-pop .x:hover{color:var(--text)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
.grid3{display:grid;grid-template-columns:80px 1fr 1fr;gap:0 14px}
.urlrow{display:flex;gap:8px;margin-bottom:8px}
.urlrow input{flex:1}
.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:18px 0 8px}
.toolbar .sp{flex:1}
.err{color:var(--err);font-size:13px}
.ok{color:var(--ok);font-size:13px}
.project-fields{padding-bottom:16px}
.project-fields-grid input{font-size:12px}
.project-fields-grid .fld>.lbl{font-size:10px}
.project-fields-grid .seg-b,.project-fields-grid .btn.sm{font-size:11px}
.project-fields-grid>h3{font-size:9px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3);margin:20px 0 10px}
.project-fields-status{margin-bottom:0;font-size:11px}
.danger-zone{border-color:color-mix(in srgb,var(--err) 30%,var(--line))}
.danger-zone h3{color:var(--err)}
/* notes & files */
.note{border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--surface-soft);margin-bottom:8px}
.note .meta{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--text-4);margin-bottom:6px}
.note .meta .sp{flex:1}
.note .txt{font-size:14px;line-height:1.55;color:var(--text-2);white-space:pre-wrap;word-break:break-word}
.note .del{background:none;border:none;color:var(--text-4);cursor:pointer;font:inherit;font-size:13px;padding:0 2px}
.note .del:hover{color:var(--err)}
.note .meta .ed{background:none;border:none;color:var(--text-4);cursor:pointer;font:inherit;font-size:12px;padding:0 2px}
.note .meta .ed:hover{color:var(--accent-fg)}
/* inline editing of single fields straight from the project page (status, priority, one-liner, summary) — no full editor */
.badge.editable{cursor:pointer}
.badge.editable:hover{border-color:var(--line-2)}
.badge .inline-sel{width:auto;background:none;border:none;padding:0 2px;color:inherit;font:inherit;cursor:pointer}
.badge .inline-sel:focus{outline:none}
.badge .pk{color:var(--text-4)}
.inline-ed{background:none;border:none;color:var(--text-5);cursor:pointer;font:inherit;font-size:12px;padding:0 2px;opacity:0;transition:opacity .12s}
.inline-wrap:hover .inline-ed{opacity:.85}
.inline-ed:hover{color:var(--accent-fg);opacity:1}
.note img.thumb{max-width:100%;max-height:320px;border-radius:8px;display:block;margin-top:4px}
.note .fileline{display:flex;align-items:center;gap:8px;font-size:14px}
.dropzone{border:1px dashed var(--line-2);border-radius:10px;padding:12px;background:var(--bar-soft);transition:border-color .15s,background .15s}
.dropzone.drag{border-color:var(--accent);background:var(--accent-surface)}
.dropzone .acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.dropzone .acts .sp{flex:1}
/* bottom tab bar — mobile only; hidden on desktop (media query below re-enables it) */
.mnav{display:none}
@media (max-width:760px){
  /* Phone/tablet shell: a fixed-height column (header · swappable view · bottom tab bar).
     Applies through portrait-tablet and landscape-phone widths (≤760px). Below that the
     desktop 3-column (sidebar · detail · dock) can't fit — it crushes the middle detail
     pane to one word per line — so every viewport that can't comfortably hold all three
     columns gets this single-view shell with the bottom icon nav instead.
     Each of the three panels becomes a full-screen "view" toggled by .mnav, so the
     Claude chat is a first-class screen instead of something buried below a long scroll. */
  /* Hard stop for sideways scroll/pan: clamp the outer shell to the viewport
     width and force overflow-x:hidden with !important so no descendant (a
     stray absolute popover, a too-wide inline table) can reopen a horizontal
     scrollbar on the page itself. */
  html,body,.wrap{overflow-x:hidden!important;width:100vw;max-width:100vw;position:relative}
  html,body{overflow:hidden}
  /* reset the desktop base's min-height:100vh — otherwise it beats height:100dvh
     (100vh > 100dvh while the browser toolbar shows), stretching the shell past the
     visible viewport and pushing the bottom .mnav off-screen ("out of border") */
  .wrap{min-height:0;height:100vh;height:100dvh;display:flex;flex-direction:column;overflow:hidden}
  .top{flex-shrink:0;padding:9px 12px;gap:6px 10px}
  .top h1{display:none} /* the project switcher is the identity/context on phones */
  /* icon-only on phones (label hidden below): keep it square but finger-tall */
  .btn.sm.hard-refresh{padding:9px 11px;min-height:40px}
  .hard-refresh-label{display:none}
  /* Every absolutely-positioned popover/switcher/tooltip/dropdown: never wider
     than the viewport (minus a small margin) and never push content past its
     bounds, no matter which corner it's anchored to or how wide its content is. */
  .pswitch-menu,.chist-menu,.hstat .tip,.whatis-pop,.askbtn-pop,.askbtn-sub,.attach-pop,.agent-controls-pop,.hub-todo-pop,.ctx-menu,.ctab-menu,.cstat-pop,.slash-pop,.slashmenu,.schedule-chat-pop,.nav-menu,.nav-menu-down{max-width:calc(100vw - 20px)}
  /* The agent-controls popover is anchored to its trigger, which sits mid-composer
     (order:3). Anchoring to either trigger edge runs it off one side of the phone.
     Drop the wrapper as the offset parent (position:static) so the popover anchors to
     the full-width composer (.inp is position:relative) and pin it to both viewport
     margins — it then spans the screen width and can never overflow either edge. */
  .agent-controls{position:static}
  .agent-controls-pop{inset-inline-start:10px;inset-inline-end:10px;width:auto;max-width:none}
  .hub-todo-control{position:static}
  .hub-todo-pop{inset-inline-start:10px;inset-inline-end:10px;width:auto;max-width:none}
  /* History dropdown: the .chist trigger sits mid-row in the chat header — the
     "New chat" button follows it and the flex spacer is dropped on mobile, so
     the buttons pack left and leave space on the right. Anchoring the near-full-
     width menu to the small trigger ran its far edge off-screen ("out of
     border"). Same fix as agent-controls: drop the trigger + its group as offset
     parents (position:static) so the menu anchors to the full-width .dock-head,
     then pin it to both viewport margins so it can never overflow either edge. */
  .dock-head{position:relative}
  .dock-head-chat{position:static}
  .chist{position:static}
  .chist-menu{inset-inline-start:10px;inset-inline-end:10px;width:auto;max-width:none;box-sizing:border-box}
  .top>div:empty{display:none} /* drop the desktop flex spacers so the header packs tight */
  .pswitch{order:-1} /* current project first, front-and-centre */
  .pswitch-btn{max-width:60vw}
  .metrics{font-size:11px;gap:6px 12px;flex-wrap:wrap}

  /* Task cards: the action column eats ~120px, so on phones the title had almost
     no room and squished to one word per line. Give the title the full first line
     and drop the category/status chips onto their own line below it. */
  .tip-headline{flex:1 1 100%}
  .tip-chips{flex-basis:100%}

  .body{flex:1;min-height:0;flex-direction:column;position:relative}
  /* only the active view is shown; the rest are display:none */
  .body>.sidecol,.body>.main,.body>.dock{display:none}
  .body.mv-projects>.sidecol{display:flex}
  .body.mv-detail>.main{display:block}
  .body.mv-chat>.dock{display:flex}

  /* Projects list: a real vertical, scrollable list (not the desktop rail/strip) */
  .sidecol{width:auto;flex:1;min-height:0;border:none;flex-direction:column}
  .sidecol.collapsed{width:auto}
  .sidehead{display:none} /* the tab bar handles navigation, so the collapse toggle is redundant */
  .side{width:auto;flex:1;min-height:0;flex-direction:column;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}
  .item{width:auto;min-width:0;flex-shrink:0;border-inline-end:none;border-bottom:1px solid var(--line-soft)}
  .item .drag-h{opacity:.7}
  .item .nm .s{display:block}

  /* Detail pane scrolls internally within its view */
  .main{padding:16px;max-width:100%;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
  .main h2{font-size:20px!important}
  .infra{grid-template-columns:1fr}
  .infra-col{padding:0}
  .infra-col+.infra-col{border-inline-start:none;border-top:1px solid var(--line);margin-top:16px;padding-top:16px}
  .grid2,.grid3,.tipgrid{grid-template-columns:1fr}
  .row{flex-wrap:wrap}
  .detail-head{position:static}
  .proj-sticky,.detail-head .proj-sticky{position:static;margin:0 0 4px;padding:0;border:none;background:none;flex-wrap:wrap}
  .detail-head .ptabs{margin:16px -24px 20px}
  /* Give the name + status/health block the full width so the Generate/Edit buttons
     wrap to their own row instead of squeezing the meta into a narrow column — that
     lets the status dropdown and the Live-health badge share ONE line. */
  .proj-head-main{flex:1 1 100%;min-width:0}
  .proj-meta{flex-wrap:nowrap!important;gap:6px!important}
  .proj-meta .badge{white-space:nowrap}
  .ptabs{margin-inline:0;padding-inline:0}
  .ptab{min-height:40px;padding:8px 4px}
  /* Mobile Tasks view: reclaim vertical space so real task cards clear the fold.
     The "Tasks" tab already names the screen, so drop the redundant heading, and
     tighten the category + status filter strip and its buttons. */
  .aitips-h{display:none}
  .aitips-head{margin-bottom:4px!important;gap:6px!important}
  .tasktabs{gap:6px 8px;margin-bottom:8px;padding-bottom:6px}
  .tf-group{padding:3px 4px;gap:4px}
  .tasktab{padding:5px 9px;font-size:12px}
  .tasktab-n{font-size:10.5px;padding:0 5px;min-width:15px}

  /* ── Finger-sized tap targets ──
     Touch screens need a comfortable ~40px hit area on every button and tab.
     The compact desktop sizes (.btn.sm/.xs collapse to 26–30px; the filter/chat
     tab strips sit at ~24px) are too small to hit accurately with a thumb, so
     bump padding + min-height up to a finger-friendly floor here. white-space
     is already nowrap on these, so the extra room never wraps the label. */
  .btn{min-height:44px;padding:10px 16px}
  .btn.sm{min-height:40px;padding:8px 14px;font-size:13.5px}
  .btn.xs{min-height:36px;padding:7px 12px;font-size:12.5px}
  .iconbtn{min-width:44px;min-height:44px;font-size:17px}
  /* project filter chips: taller pill, still single-line */
  .ftab{padding:8px 14px;font-size:12.5px;min-height:38px}
  .ftab .fcount{font-size:11px}
  /* Keep the conversation carousel compact while retaining clear tap targets. */
  .chat-tabs-bar{gap:3px;padding:1px 5px}
  .ctab{padding:1px 8px;font-size:12px;max-width:190px}
  .ctab-nav{padding:2px 9px;font-size:14px}
  /* bottom nav labels stay on one line under their icon; the button itself
     clips so a long label (5 buttons across = less room each) can never
     spill past its flex slot and reopen a horizontal scroll */
  .mnav button{min-height:52px;white-space:nowrap;overflow:hidden}

  /* Chat/terminal dock fills its view; strip the desktop resize + collapse chrome.
     min-width:0 is load-bearing: .dock is a flex item in the column .body, so with the
     default min-width:auto it refuses to shrink below its content's min-content width —
     the chat tab strip + long title balloon it to ~2500px and it's clipped off the right
     edge ("out of border"). min-width:0 lets it size to the viewport so the inner
     overflow-x:auto (tabs) and ellipsis (title) take over. */
  .dock{width:auto!important;height:auto!important;flex:1;min-height:0;min-width:0;border:none;background:var(--bg)}
  .dock.collapsed{width:auto;height:auto}
  .dock-rsz,.dock-open{display:none!important}
  /* never let the collapsed dock leave a vertical-text rail on narrow layouts */
  .dock.collapsed{width:0!important;min-width:0!important;border:none!important;overflow:hidden}
  .dock-head .btn.sm[title="Minimize panel"]{display:none}
  /* let the whole flex chain shrink to the viewport so nothing is forced wider/taller */
  .dock-body,.dock-pane,.claudepane{min-width:0}
  /* dock header (provider tabs · Terminal · History · New chat) — on phones keep it to a
     SINGLE row instead of wrapping to two. Drop the flex spacer + redundant project-name
     label, compact the buttons, and collapse the History button to its clock+count (the
     word "History" is hidden via .chist-lbl) so the AI-model tabs, Terminal, History and
     New chat all pack onto one line. min-width:0 lets the row shrink to the viewport. */
  .dock-head{flex-wrap:nowrap;min-width:0;gap:6px}
  .dock-head>.sp{display:none}
  .dock-head>.muted{display:none}
  .dock-head-chat{flex-wrap:nowrap;gap:6px;flex-shrink:0}
  .dock-tabs{flex-shrink:0}
  .dock-provider-tabs button{padding:4px 8px}
  .dock-tabs button{padding:4px 9px}
  .dock-head-chat .btn.sm{padding:4px 8px;font-size:12px}
  .dock-head .chist-lbl{display:none}
  /* Chat fills the pane as a flex column: the log becomes the sole scroll region while the
     working-dir bar + composer stay pinned. Without this the log keeps its desktop
     max-height:440px cap and the stack (log + suggestions + dir bar + composer) grows taller
     than the pane — and since .dock/.chat clip with overflow:hidden, the composer gets pushed
     past the bottom edge ("out of border"). Edge-to-edge on phones, so drop the card chrome. */
  .claudepane .chat{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column;border:none;border-radius:0}
  .claudepane .chat .log{flex:1;min-height:0;max-height:none;padding:8px 8px 4px;gap:7px}
  .claudepane-head{gap:6px;padding:1px 10px 4px}
  .claudepane-head .title{font-size:14px;line-height:1.25}
  .copychat-btn{padding:2px 8px;font-size:11px;line-height:1.3}
  .cmsg{gap:4px}
  .cmsg .bubble{padding:7px 9px;line-height:1.45}
  .cquick{gap:4px}
  .cquick button{padding:4px 8px}
  .csugg-dock{padding:5px 9px}
  .csugg-dock-lbl{margin-bottom:4px}
  .chat-state{gap:7px;margin:0 9px 5px;padding:6px 8px}
  /* mobile: keep the status alert to a single line */
  .chat-state .state-copy{flex-direction:row;align-items:center;gap:6px}
  .chat-state .state-copy b{flex-shrink:0}
  .chat-state .state-copy span{white-space:nowrap}

  /* bottom tab bar */
  /* flex:1 on every button splits the bar evenly across however many buttons
     are rendered (4 or 5) — no per-count width math needed */
  /* Project selector lives at the bottom on mobile: a bar just above .mnav */
  .mprojbar{display:flex;flex-shrink:0;justify-content:center;padding:8px 12px;border-top:1px solid var(--line);background:var(--bg)}
  .mprojbar .pswitch{width:100%}
  .mprojbar .pswitch-btn{width:100%;max-width:none;justify-content:center}
  .mprojbar .pswitch-menu{inset-inline-start:50%;transform:translateX(-50%)}
  .mnav{display:flex;flex-shrink:0;position:sticky;bottom:0;z-index:20;border-top:1px solid var(--line);background:var(--bg);padding-bottom:env(safe-area-inset-bottom)}
  .mnav button{flex:1;min-width:0;background:none;border:none;color:var(--text-4);font:inherit;font-size:11px;display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 4px 7px;cursor:pointer;position:relative;transition:color .12s}
  .mnav button .mic{width:23px;height:23px;display:block;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
  /* the label itself: min-width:0 lets it shrink below its own text width
     inside the flex column, ellipsis catches anything that still doesn't fit
     a narrow 1-of-6 slot instead of wrapping or overflowing the button */
  .mnav button .mlabel{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}
  .mnav button.on{color:var(--accent-fg)}
  .mnav button.on::before{content:"";position:absolute;top:0;inset-inline-start:22%;inset-inline-end:22%;height:2px;border-radius:0 0 3px 3px;background:var(--accent-fg)}
  .mnav .mcount{position:absolute;top:3px;inset-inline-start:calc(50% + 7px);min-width:18px;height:18px;padding:0 4px;box-sizing:border-box;border-radius:9px;background:color-mix(in srgb,var(--accent) 72%,#000);color:#fff;font-size:10.5px;font-weight:800;line-height:18px;text-align:center;box-shadow:0 0 0 1.5px var(--bg)}
  /* "done" badges (new completed chats / recently finished tasks) read as a
     positive signal rather than an open-work count → green instead of accent.
     Use a solid, saturated green (not the light --ok tint) so white text stays
     legible on top of it. */
  .mnav .mcount.done{background:var(--btn-primary)}

  /* ── Mobile comfort: composer, model picker & touch targets ──
     On a phone the chat footer (working-dir bar + composer) is where you actually
     type, so give it room and finger-sized controls. */
  /* working-dir bar: put the model picker on its own horizontally-scrollable row
     instead of letting the pills wrap mid-line into a cramped block */
  .chat-model-selector{gap:4px!important;padding:5px 8px!important}
  .chatdir{gap:4px 6px;padding:3px 8px 4px}
  /* model picker gets its own horizontal strip so every model remains reachable
     after a chat starts without expanding the footer vertically. */
  .modelbar{width:100%;margin-inline-start:0;order:5;flex:1 0 100%;flex-wrap:nowrap;overflow-x:auto}
  .mpill{font-size:11px;padding:4px 9px;flex-shrink:0}
  .mpill .mhint{font-size:10px}
  /* Phone: keep the whole controls row on ONE line — the picker shrinks first
     and truncates rather than wrapping attach/mode/Stop to a second row. */
  .model-picker-mobile{order:-1;max-width:34vw;height:42px;font-size:11px!important;padding:0 6px}
  .chat .inp .inp-actions,.chat .inp .agent-controls{min-width:0;flex-shrink:1}
  /* Any form control under 16px makes iOS Safari auto-zoom the whole page on
     focus. Enforce a 16px floor for every input/textarea/select on small
     screens; !important beats the class-specificity of per-component overrides
     (.scanbox textarea, .sset-row select, .fbrow .dsearch input, .auto-fld …). */
  input,textarea,select{font-size:16px!important}
  /* composer row: roomier attach / send buttons; 16px textarea stops iOS Safari
     from auto-zooming the whole page when the field takes focus */
  .chat .inp{gap:6px;padding:7px 8px}
  .agent-controls-trigger{height:42px}
  .agent-controls-trigger .acx-mode{max-width:52px;overflow:hidden;text-overflow:ellipsis}
  .agent-controls-pop{width:auto;max-width:none}
  .chat .inp textarea{font-size:16px;min-height:42px;height:42px}
  .chat .inp textarea::placeholder{font-size:14px}
  .chat .inp .iconbtn,.chat .inp .btn.sm{height:42px;min-height:42px;min-width:42px}
  .chat .inp .iconbtn{font-size:17px;padding:0}
  .chat .inp .btn.sm{padding:0 16px;font-size:14px}

  /* ── No sideways pan: clamp every scroll pane's horizontal axis ──
     .main / .log declare overflow-y:auto, and per the CSS overflow spec that
     silently promotes overflow-x from visible to *auto* — so a single too-wide
     child (a long unbroken URL, a wide code block) turns the whole pane into a
     horizontal scroller the finger can drag. Pin overflow-x:hidden so the pane
     can only ever scroll vertically; genuinely wide content (code blocks,
     tables) keeps its OWN inner overflow-x:auto and scrolls within its box. */
  .main,.claudepane .chat .log,.dock-body,.dock-pane,.airun-body{overflow-x:hidden}
  /* long unbreakable tokens (URLs, paths, hashes) wrap instead of widening the
     pane past the screen edge */
  .bubble,.bubble.md,.airun-inner,.note,.main p,.main li{overflow-wrap:anywhere;word-break:break-word}
  /* Absolutely-positioned popovers/tooltips/menus sit outside the normal flow, so
     the wrap rule above doesn't reach them: a long unbroken token in an explainer
     tip or history/menu entry would push the box past its max-width and reintroduce
     a side-scroll. Force wrapping here too. (Menu rows that use white-space:nowrap +
     ellipsis are unaffected — overflow-wrap is ignored under nowrap.) */
  .hstat .tip,.pswitch-menu,.chist-menu,.whatis-pop,.askbtn-pop,.askbtn-sub,.slashmenu,.agent-controls-pop,.ctx-menu,.ctab-menu,.cstat-pop,.slash-pop,.schedule-chat-pop,.nav-menu,.nav-menu-down,.attach-pop{overflow-wrap:anywhere;word-break:break-word}

  /* ── File browser modal: full-screen, single column on phones ──
     Desktop shows a fixed 300px file list beside the preview; at phone width
     that leaves the preview a ~70px sliver and the dialog pokes past the screen
     edge. Fill the viewport and stack the list ABOVE the preview instead. */
  .fbrow-scrim{padding:0}
  .fbrow{width:100vw;max-width:100vw;height:100dvh;border:none;border-radius:0}
  .fbrow .fbody{flex-direction:column}
  .fbrow .flist{width:auto;flex:0 0 auto;max-height:40vh;border-inline-end:none;border-bottom:1px solid var(--line)}
  .fbrow .fprev{min-width:0;min-height:0}
  /* modal dialogs never exceed the viewport width */
  .modal,.sset,.airun-inner{max-width:100vw}
}
/* Phones (portrait): the tightest layout tweaks */
@media (max-width:560px){
  /* ── Metadata: stack label over value in a single column ──
     The infra / status area is a label↔value grid on desktop. At phone width a
     two-up row crushes long values (file paths, RTL hosting strings, URLs)
     against the screen edge, so collapse every label-value pair to a vertical
     stack: the muted label sits on its own line above its left-aligned value. */
  .irow{flex-direction:column;align-items:stretch;gap:2px;padding:8px 0}
  .irow .ik{font-size:12px}
  .irow .iv{text-align:start}
  /* metadata grids drop to one column too, so each cell owns the full width */
  .grid2,.grid3,.tipgrid{display:flex;flex-direction:column;gap:8px}
  /* ── Unified controls scale down together on phones ──
     Tighten the shared padding token so buttons, tabs and badges give back a
     little horizontal room, but keep every *interactive* control at a 36px
     finger-sized tap target. Badges/chips are labels, not tap targets, so they
     stay compact. Radius is intentionally left unchanged — the whole point of
     the unified system is one border-radius at every breakpoint. */
  :root{--pad-control:9px 15px;--pad-control-sm:7px 12px;}
  .btn,.actionpill,.iconbtn,.checknow,.ftab,.tasktab{min-height:36px}
  .btn.sm,.btn.xs{min-height:34px}
  .actionpill{font-size:12.5px}
  /* let tab and badge strips wrap onto multiple rows rather than overflow */
  .badge,.chip{font-size:11.5px}
  /* category/status filter buttons: slightly smaller floor than other controls so the
     filter strip gives back a row of vertical space on phones (still comfortably tappable) */
  .tasktab{min-height:32px;padding:5px 9px}
  /* ── Task/approval card: stack body over actions on phones ──
     Desktop lays each task row as [body flex:1][120px action column] side by
     side. At phone width the fixed 120px column squishes the body, so the
     automation approval box wraps ugly and buttons overlap. Collapse the row to
     a vertical stack: body on top, full-width action column below. Inline
     styles set display/width, so override with !important. */
  .task-row{flex-direction:column!important;align-items:stretch!important}
  .task-row>div{min-width:0}
  .task-actions{width:auto!important}
  /* approval nudge: buttons drop full-width under the message instead of squishing */
  .tip-nudge-approval>span{flex:1 1 100%}
  .tip-nudge-approval>.btn{flex:1 1 auto}
}
@media (min-width:761px) and (max-width:1100px){
  .dock{width:380px}
}
/* keep the Claude/Terminal dock a reasonable card instead of stretching full page height.
   Paired with the ≤1000px shell above: the desktop 3-column layout only engages >1000px. */
@media (min-width:761px){
  /* lock the shell to the viewport so the detail pane (.main) scrolls *internally*
     instead of the whole window — this is what makes the sticky project title /
     chat header actually pin, and lets the dock stay a fixed, resizable panel. */
  .wrap{height:100vh;overflow:hidden}
  .dock:not(.collapsed){align-self:flex-end;height:min(720px,calc(100vh - 96px));border-radius:12px 12px 0 0;overflow:hidden}
  /* "Open wide": the dock takes over the middle detail pane, giving Claude a
     roomy full-width chat while the project list stays visible on the left. */
  .body.dock-maxed>.main{display:none}
  .dock.maxed{flex:1 1 auto;width:auto;min-width:0;box-shadow:-12px 0 32px rgba(0,0,0,.28)}
}

/* ── Automations panel ── */
.auto-form{border:1px solid var(--line);background:var(--card-2,rgba(255,255,255,.02));border-radius:10px;padding:14px;margin:6px 0 12px}
.auto-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
@media (max-width:760px){.auto-grid{grid-template-columns:1fr}}
.auto-fld{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--text-2);margin-top:8px}
.auto-fld>span{font-weight:600}
.auto-fld input,.auto-fld select,.auto-fld textarea{font:inherit;font-size:13px;color:var(--text);background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:7px 9px;width:100%;box-sizing:border-box}
.auto-fld textarea{resize:vertical;line-height:1.5}
.auto-chk{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-2)}
.auto-list{display:flex;flex-direction:column;gap:8px;margin-top:6px}
.auto-row{display:flex;gap:12px;align-items:flex-start;border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--card-2,rgba(255,255,255,.02))}
.auto-row.off{opacity:.6}
/* Site Health tab: the shared check-frequency knob + one live row per project. */
.auto-health-freq{display:flex;align-items:center;gap:12px;flex-wrap:wrap;border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--card-2,rgba(255,255,255,.02))}
.auto-health-freq .lbl{flex:1;min-width:180px}
.auto-health-freq .lbl .t{display:block;font-size:13px;font-weight:600;color:var(--text-1)}
.auto-health-freq .lbl .d{display:block;font-size:11.5px;color:var(--text-3);margin-top:2px}
.auto-health-freq input{font:inherit;font-size:13px;color:var(--text);background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius-control);padding:6px 8px}
.auto-health-row{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:10px;padding:9px 12px;background:var(--card-2,rgba(255,255,255,.02))}
.auto-health-row .hdot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.auto-health-row .hname{font-weight:600;font-size:13.5px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.auto-health-row .hverdict{font-size:12px;font-weight:600;flex-shrink:0}
.auto-health-row .hdet{font-size:11.5px;color:var(--text-3);margin-inline-start:auto;font-variant-numeric:tabular-nums;text-align:end}
.auto-main{flex:1;min-width:0}
.auto-title{font-weight:600;font-size:14px;display:flex;align-items:center;gap:8px}
.auto-run{font-size:11px;color:#facc15;font-weight:500}
.auto-meta{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0}
.auto-goal{font-size:12px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:560px}
.auto-last{font-size:12px;color:var(--text-2);margin-top:4px}
.auto-hist{margin-top:4px}
.auto-hist-toggle{font:inherit;font-size:12px;color:var(--text-2);background:none;border:none;padding:2px 0;cursor:pointer;display:inline-flex;align-items:center;gap:5px}
.auto-hist-toggle:hover{color:var(--text)}
.auto-hist-toggle .tw{font-size:10px;opacity:.7}
.auto-hist-list{list-style:none;margin:4px 0 0;padding:6px 0 2px 14px;border-inline-start:2px solid var(--line);display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--text-2)}
.auto-hist-list li{line-height:1.4}
.auto-actions{display:flex;flex-direction:column;gap:6px;flex-shrink:0}
.auto-toggle{flex-shrink:0;width:38px;height:22px;border-radius:999px;border:1px solid var(--line);background:var(--line-2);position:relative;cursor:pointer;padding:0;transition:background .15s}
.auto-toggle.on{background:var(--accent);border-color:var(--accent)}
.auto-toggle .knob{position:absolute;top:2px;inset-inline-start:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:inset-inline-start .15s}
.auto-toggle.on .knob{inset-inline-start:18px}
.auto-toggle:disabled{cursor:default;opacity:.7}
.auto-kindpick{display:flex;gap:8px;margin-bottom:4px}
.auto-kbtn{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:1px;font:inherit;font-size:14px;font-weight:600;color:var(--text-2);background:var(--bg);border:1px solid var(--line);border-radius:var(--radius-control);padding:8px 12px;cursor:pointer}
.auto-kbtn>span{font-size:11px;font-weight:400;color:var(--muted,#8a94a6)}
.auto-kbtn.on{border-color:var(--accent);color:var(--text);background:var(--chip-bg)}
.auto-cats{display:flex;flex-wrap:wrap;gap:6px}
.catpick{font:inherit;font-size:12px;color:var(--text-2);background:var(--bg);border:1px solid var(--line);border-radius:7px;padding:5px 9px;cursor:pointer}
.catpick.on{border-color:var(--accent);color:var(--text);background:var(--chip-bg);font-weight:600}
.auto-kind{font-size:11px;font-weight:700;border-radius:6px;padding:1px 7px;border:1px solid var(--line-2)}
.auto-kind.scan{color:var(--scan);background:color-mix(in srgb,var(--scan) 12%,transparent)}
.auto-kind.fixer{color:var(--claude);background:color-mix(in srgb,var(--claude) 12%,transparent)}
.chip.tgt{font-weight:600}
/* Per-kind colour theme: every automation row exposes --k (🔍 scan = sky,
   🛠 fix = violet) and the row's tag, edge, toggle and buttons all read it,
   so a row reads as scan-or-fix at a glance — matching its tab button. */
.auto-row.k-scan{--k:var(--scan)}
.auto-row.k-fixer{--k:var(--claude)}
.auto-row.k-scan,.auto-row.k-fixer{border-color:color-mix(in srgb,var(--k) 35%,transparent);box-shadow:inset 3px 0 0 var(--k)}
.auto-row.k-scan .auto-toggle.on,.auto-row.k-fixer .auto-toggle.on{background:var(--k);border-color:var(--k)}
.auto-row.k-scan .auto-actions .btn,.auto-row.k-fixer .auto-actions .btn{border-color:color-mix(in srgb,var(--k) 40%,transparent);color:var(--k)}
.auto-row.k-scan .auto-actions .btn:hover:not(:disabled),.auto-row.k-fixer .auto-actions .btn:hover:not(:disabled){background:color-mix(in srgb,var(--k) 14%,transparent)}
.auto-row.k-scan .auto-run,.auto-row.k-fixer .auto-run{color:var(--k)}
.auto-row.k-scan .auto-hist-list,.auto-row.k-fixer .auto-hist-list{border-inline-start-color:color-mix(in srgb,var(--k) 45%,transparent)}
/* Tab buttons carry the same two themes as the rows they filter to. */
.seg-b.on.seg-scan{background:var(--scan)}
.seg-b.on.seg-fixer{background:var(--claude)}
/* Active cross-project (🌐 global) rule shown inside a per-project panel:
   distinct tinted card so it stands out from local rules (tint follows --k). */
.auto-row.global{background:linear-gradient(90deg,color-mix(in srgb,var(--k,var(--scan)) 10%,transparent),var(--card-2,rgba(255,255,255,.02)) 60%);position:relative}
.auto-global-tag{position:absolute;top:8px;inset-inline-end:12px;font-size:10px;font-weight:700;color:var(--k,var(--scan));background:color-mix(in srgb,var(--k,var(--scan)) 14%,transparent);border:1px solid color-mix(in srgb,var(--k,var(--scan)) 40%,transparent);border-radius:6px;padding:1px 7px;letter-spacing:.02em}

/* ─────────────────── Prodify-style left-sidebar shell ─────────────────── */
.appshell{display:flex;flex:1;min-height:0;background:var(--app-bg)}
/* left navigation rail */
.appnav{width:250px;flex-shrink:0;display:flex;flex-direction:column;min-height:0;gap:14px;padding:14px 12px;background:var(--nav-bg);border-inline-end:1px solid var(--card-line)}
.nav-links{display:flex;flex-direction:column;gap:2px}
.nav-link{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:10px;font:inherit;font-size:13.5px;font-weight:500;color:var(--text-3);background:none;border:none;cursor:pointer;text-align:start;width:100%;transition:background .12s,color .12s}
.nav-link:hover{background:var(--surface-2);color:var(--text)}
.nav-link.on{background:var(--accent-surface);color:var(--accent-fg);font-weight:600}
.nav-link .ic{width:18px;height:18px;text-align:center;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.nav-link .badge-n{margin-inline-start:auto;font-size:10px;font-weight:700;background:var(--accent);color:#fff;border-radius:999px;padding:1px 6px;min-width:18px;text-align:center;line-height:16px}
.nav-sec{display:flex;flex-direction:column;min-height:0;flex:1}
.nav-sec-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 8px 4px;font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-4)}
.nav-add{font:inherit;font-size:11px;font-weight:600;color:var(--accent-fg);background:var(--accent-surface);border:none;border-radius:8px;padding:3px 9px;cursor:pointer;text-transform:none;letter-spacing:0}
.nav-add:hover{background:var(--accent);color:#fff}
.nav-sec-acts{display:flex;align-items:center;gap:6px}
/* "Arrange" is a quiet ghost toggle at rest; when on it reads as the current
   mode (accent surface), matching the filter tabs' active state. */
.nav-arrange{font:inherit;font-size:11px;font-weight:600;color:var(--text-3);background:transparent;border:1px solid var(--line-2);border-radius:8px;padding:3px 9px;cursor:pointer;text-transform:none;letter-spacing:0;transition:background .13s,color .13s,border-color .13s}
.nav-arrange:hover{color:var(--text);border-color:var(--text-5)}
.nav-arrange.on{color:var(--accent-fg);background:var(--accent-surface);border-color:transparent}
/* Rows while arranging: no hover-navigate cue, drag handle always shown, a lead
   checkbox, and a ticked row tints toward the accent so the selection is legible. */
.appnav .item.arranging{cursor:pointer}
.appnav .item.arranging .drag-h{opacity:.7}
.appnav .item.picked{background:var(--accent-surface)}
.appnav .item.picked .nm .t{color:var(--accent-fg)}
.pick-box{flex-shrink:0;width:17px;height:17px;display:grid;place-items:center;border:1.5px solid var(--line-2);border-radius:5px;font-size:11px;line-height:1;color:#fff;transition:background .12s,border-color .12s}
.pick-box.on{background:var(--accent);border-color:var(--accent)}
.pill-hidden{margin-inline-start:6px;font-size:9.5px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--text-4);border:1px solid var(--line-2);border-radius:5px;padding:0 4px;vertical-align:middle}
.row-rm{flex-shrink:0;width:24px;height:24px;display:grid;place-items:center;border:none;background:transparent;color:var(--text-4);border-radius:7px;font-size:13px;cursor:pointer;transition:background .12s,color .12s}
.row-rm:hover{background:color-mix(in srgb,var(--err) 15%,transparent);color:var(--err)}
/* Footer action bar for the current selection — pinned under the list. */
.arr-bar{flex-shrink:0;margin-top:6px;padding:8px;border-top:1px solid var(--line-soft);display:flex;flex-direction:column;gap:8px}
.arr-bar-top{display:flex;align-items:center;gap:8px}
.arr-link{font:inherit;font-size:11.5px;font-weight:600;color:var(--accent-fg);background:none;border:none;padding:0;cursor:pointer}
.arr-link:hover{text-decoration:underline}
.arr-count{font-size:11.5px;color:var(--text-4)}
.arr-why{margin-inline-start:auto}
.arr-bar-acts{display:flex;gap:6px}
.arr-bar-acts .btn{flex:1;justify-content:center}
.arr-why-note{font-size:12px;line-height:1.6;color:var(--text-3);background:var(--surface-2);border:1px solid var(--line-soft);border-radius:9px;padding:9px 11px}
.nav-filter{display:flex;flex-wrap:wrap;gap:4px;padding:0 4px 6px}
.nav-list{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:1px}
.appnav .item{border-radius:9px;border-bottom:none;padding:8px 10px;gap:9px}
.appnav .item.sel .nm .t{color:var(--accent-fg)}
/* Overflow popup opened by the Settings nav item — holds GitHub, AI settings,
   Sounds, the appearance toggle and Sign out (the single account surface). */
.nav-menu{position:absolute;inset-inline-start:0;inset-inline-end:0;bottom:calc(100% + 8px);z-index:70;display:flex;flex-direction:column;gap:8px;padding:9px;background:var(--surface);border:1px solid var(--line-2);border-radius:12px;box-shadow:0 -10px 34px var(--shadow-color);transform-origin:bottom center;animation:menu-in-up .14s cubic-bezier(.16,1,.3,1)}
.nav-menu-sep{height:1px;margin:1px 2px;background:var(--card-line)}
@keyframes menu-in-up{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}
/* Settings nav item lives near the top of the rail, so its popup opens
   downward instead of the footer profile's upward .nav-menu. */
.nav-settings{position:relative}
.nav-menu-down{inset-inline-start:0;inset-inline-end:auto;bottom:auto;top:calc(100% + 6px);min-width:230px;transform-origin:top left;animation:menu-in-down .14s cubic-bezier(.16,1,.3,1)}
@keyframes menu-in-down{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
.nav-util-label{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--text-4);padding:0 8px}
.nav-notif-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.notif-gear{display:inline-flex;align-items:center;justify-content:center;padding:3px;margin:-3px -3px -3px 0;border:none;background:transparent;color:var(--text-4);border-radius:6px;cursor:pointer;transition:background .13s,color .13s}
.notif-gear:hover{background:var(--surface-2);color:var(--text-2)}
.notif-gear .ic{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
/* Notification bell dropdown (see NotificationsBell in src/app.jsx). */
.nav-bell .badge-n{background:var(--err);color:#fff}
.nav-notif{min-width:300px;max-height:min(70vh,440px);overflow-y:auto;gap:2px}
/* ===== Why the notifications popup kept landing "out of border" =====
   The desktop bell's horizontal position is NOT fixed: .ah-end is justify-content
   :flex-end normally (bell far RIGHT), but the `@container appmain (max-width:1480px)`
   header reflow below reverses it to flex-start (bell far LEFT). appmain's width moves
   with sidebar/dock resizing and zoom, so BOTH states happen on a normal desktop.
   A static anchor is therefore correct in one state and off-screen in the other —
   fixing it at one window size breaks the other, which is why this regressed over and
   over. The anchor MUST follow the same container query that moves the bell:
     appmain >1480px  -> bell right -> popup right:0 (here)
     appmain <=1480px -> bell left  -> popup left:0  (in the @container block below)
   The mobile bell is nested under .ah-mctrls, so the direct-child combinator below
   never matches it and it keeps the plain .nav-menu-down left anchor, which is right
   for its far-left position. */
.ah-end>.nav-settings-compact .nav-menu-down{inset-inline-start:auto;inset-inline-end:0;transform-origin:top right}
/* Compact variant: bell sits inline among the dock's provider/terminal tabs
   instead of stacked full-width in the sidebar rail. */
.nav-settings-compact{position:relative;display:inline-flex}
.nav-bell-compact{width:auto;display:inline-flex;align-items:center;justify-content:center;gap:0;padding:5px 10px;font:inherit;font-size:13px;border:1px solid var(--line-2);background:var(--line);color:var(--text-2);border-radius:7px}
.nav-bell-compact:hover{background:var(--line-2)}
.nav-bell-compact.on{background:var(--accent);border-color:var(--accent);color:#fff}
.nav-bell-compact .badge-n{position:absolute;top:-4px;inset-inline-end:-4px;margin-inline-start:0;min-width:16px;padding:0 4px;line-height:15px;font-size:9px}
/* Hamburger variant of SettingsMenu: icon-only chip in the mobile header (the
   sidebar's Settings menu is hidden ≤1000px). Same chip look as the compact bell. */
.nav-settings-ham{position:relative;display:inline-flex}
.nav-ham{width:auto;display:inline-flex;align-items:center;justify-content:center;gap:0;padding:6px 9px;border:1px solid var(--line-2);background:var(--line);color:var(--text-2);border-radius:7px}
.nav-ham:hover{background:var(--line-2)}
.nav-ham.on{background:var(--accent);border-color:var(--accent);color:#fff}
.notif-empty{padding:14px 10px;font-size:12.5px;color:var(--text-4);text-align:center}
.notif-item{display:flex;align-items:flex-start;gap:9px;width:100%;text-align:start;font:inherit;padding:8px 9px;border:1px solid transparent;border-radius:9px;background:transparent;color:var(--text-2);cursor:pointer;transition:background .13s}
.notif-item:hover{background:var(--surface-2)}
.notif-dot{flex-shrink:0;width:7px;height:7px;margin-top:5px;border-radius:999px;background:var(--text-4)}
/* Notifications use the shared conversation-state palette too. */
.notif-item.ev-runFinished .notif-dot,.notif-item.ev-taskDone .notif-dot{background:var(--chat-done)}
.notif-item.ev-needsApproval .notif-dot{background:var(--chat-waiting)}
.notif-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.notif-title{font-size:13px;font-weight:600;color:var(--text)}
.notif-sub{font-size:11.5px;color:var(--text-3);overflow-wrap:anywhere}
.notif-time{flex-shrink:0;font-size:10.5px;color:var(--text-4);margin-top:1px}
/* Header actions cluster (mute + gear) on the panel title row. */
.notif-head-actions{display:inline-flex;align-items:center;gap:2px}
.notif-mute{display:inline-flex;align-items:center;justify-content:center;padding:2px 4px;border:none;background:transparent;font-size:13px;line-height:1;border-radius:6px;cursor:pointer;opacity:.75;transition:background .13s,opacity .13s}
.notif-mute:hover{background:var(--surface-2);opacity:1}
.notif-mute.on{opacity:1}
/* Muted indicator on the bell button + the in-panel banner. */
.notif-muted-dot{margin-inline-start:4px;font-size:11px;line-height:1}
.notif-muted-banner{margin:2px 4px 4px;padding:5px 8px;font-size:11.5px;color:var(--text-3);background:var(--surface-2);border-radius:8px;text-align:center}
/* Action-required rows (an agent parked on your approval): orange accent + tag. */
.notif-item.needs-action{border-color:#d9770633;background:#d977060d}
.notif-item.needs-action:hover{background:#d977061a}
.notif-action-tag{align-self:flex-start;margin-top:3px;font-size:10px;font-weight:700;letter-spacing:.02em;text-transform:uppercase;color:#b45309;background:#d977061f;border-radius:999px;padding:1px 7px}
:root.dark .notif-action-tag{color:#fbbf24;background:#d9770626}
.nav-appearance{display:flex;gap:4px;padding:3px;margin:0 4px;background:var(--surface-2);border-radius:10px}
.nav-appearance button{flex:1;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:5px;font:inherit;font-size:12px;font-weight:600;padding:7px 8px;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--text-3);cursor:pointer;transition:background .14s,color .14s,box-shadow .14s}
.nav-appearance button:hover{color:var(--text-2)}
.nav-appearance button.on{background:var(--surface);border-color:var(--line-2);color:var(--text);box-shadow:0 1px 3px var(--shadow-color)}
.nav-appearance .ic{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
/* Sign out now renders as a .menu-item.danger inside the profile popup, so no
   dedicated .nav-signout styling is needed. */
/* main region */
/* container-type makes .appmain a query container so the header reflow below can
   key on the header's OWN available width (viewport − sidebar) instead of the raw
   viewport. The old viewport breakpoint didn't know the 250px sidebar was eating
   the row, so it reflowed too late and the flex row wrapped raggedly first. Safe:
   .appmain has no position:fixed/absolute descendants that would be rebased — the
   context menu is a sibling rendered before it and the hover popovers are portaled
   to <body>. */
.appmain{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0;container-type:inline-size;container-name:appmain}
/* flex-wrap:nowrap above the 1480px container breakpoint: the row is sized to fit
   there, and a wrap was only ever reached by runtime width jitter (a metric gaining
   a digit, "Scan"→"Scanning…"), which flipped the header between one and two ragged
   lines. Below 1480px the @container block turns .apphead into a grid and the ≤1000px
   media block restores wrapping, so this only governs the wide band. */
.apphead{display:flex;align-items:center;gap:12px 14px;flex-wrap:nowrap;padding:9px 20px;border-bottom:1px solid var(--card-line);background:var(--app-bg);flex-shrink:0;position:sticky;top:0;z-index:30}
.apphead .metrics{font-size:12px}
/* active-project label in the app header (desktop): the header background is
   tinted per project inline; this shows the project name up front so the top bar
   reads as "you are in <project>" at a glance */
.ah-proj{display:inline-flex;align-items:center;gap:9px;min-width:0;max-width:340px}
.ah-proj-dot{flex-shrink:0;width:13px;height:13px;border-radius:4px}
.ah-proj-nm{font-size:19px;font-weight:800;letter-spacing:-.4px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ah-openport{flex-shrink:0;text-decoration:none;font-variant-numeric:tabular-nums}
/* header groups: three sections across the row — .ah-start (project name) on the left,
   .ah-usage (Claude/Codex plan usage) centred, and .ah-end (Scan+freshness, host stats
   and hard refresh) pinned right. Sides use flex-basis:auto (NOT 0) so each section first
   reserves its own content width and only *shares* the leftover space. With flex-basis:0
   the two sides split the row 50/50 regardless of content, so the content-heavy .ah-end
   got squeezed below its natural width and wrapped into a lopsided multi-line mess long
   before the grid kicked in. When the header's own width narrows the apphead becomes a
   grid (the @container appmain block below).
   The groups themselves are nowrap: a group only ever wraps at its own boundary (handled
   by the grid reflow), never mid-group — so a slightly-tight row can never fan a single
   group's controls out onto a ragged extra line. */
.ah-start,.ah-end,.ah-lead,.ah-usage{display:flex;align-items:center;flex-wrap:nowrap;gap:12px 14px;min-width:0}
.ah-start{flex:1 1 auto;justify-content:flex-start}
.ah-end{flex:1 1 auto;justify-content:flex-end}
.ah-usage{flex:0 1 auto;justify-content:center}
.ah-usage>.hard-refresh{margin-inline-start:6px}
/* When the header's own width drops below ~1480px the three-section flex row no longer
   fits on one line (project name + two usage chips + hard-refresh + bell + Scan + four
   host metrics is ~1330px of content before gaps). Reflow to a 2-row grid before that
   happens, so the tidy grid — not a ragged 2–3 line wrap — covers the medium band:
     row 1: project name (.ah-start) | Scan+freshness + host stats (.ah-end, right-aligned)
     row 2: Claude/Codex usage + Hard refresh (.ah-usage, full width)
   Row 1 mirrors the wide band — identity left, controls right — so crossing the breakpoint
   only DROPS the usage group to its own line; nothing teleports across the header. The
   earlier "end end"/"start usage" arrangement did the opposite: it demoted the project name
   under the telemetry and left row 1 crammed against the left edge with a wide empty right
   half, because the rule meant to pin that edge (.ah-end>.hard-refresh) matched nothing —
   Hard refresh is a child of .ah-usage, not .ah-end. This is a @container query on .appmain (not a viewport @media),
   so it measures the space the header ACTUALLY has after the sidebar's 250px, and reflows
   exactly when the row would otherwise overflow — regardless of sidebar width or zoom.
   It sits before the ≤1000px mobile @media, which (later in source order) overrides it. */
@container appmain (max-width:1480px){
  /* Keep the header on ONE line in the medium band: name | usage | controls.
     The usage group stays inline between the project name and the right-hand
     controls instead of dropping to its own row (which left a wide empty gap).
     .ah-end can shrink and its host-metrics strip scrolls horizontally if the
     row runs out of room, so nothing wraps to a second line. */
  .apphead{display:grid;grid-template-columns:auto auto minmax(0,1fr);grid-template-areas:"start usage end";align-items:center;column-gap:12px}
  .apphead>.ah-start{grid-area:start;min-width:0}
  .apphead>.ah-usage{grid-area:usage;min-width:0;justify-content:flex-start;flex:0 0 auto}
  .apphead>.ah-end{grid-area:end;min-width:0;flex:1 1 auto;justify-content:flex-end}
  .ah-start,.ah-end,.ah-usage{column-gap:10px}
  .apphead>.ah-end>.ah-lead{min-width:0}
  .apphead>.ah-end>.ah-lead .metrics{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .apphead>.ah-end>.ah-lead .metrics::-webkit-scrollbar{display:none}
  .apphead>.ah-end>.nav-settings-compact{order:2}
  .apphead>.ah-end>.nav-settings-compact .nav-menu-down{max-width:calc(100cqw - 24px)}
}
/* Data-freshness label sits inline at the end of the metrics row */
.ah-fresh{font-size:10.5px;line-height:1.15}
.ah-fresh .hstat-btn{font-weight:500}
/* ── Header stability ──────────────────────────────────────────────────────
   Every group in .apphead was content-sized: .ah-start/.ah-end flex-grow and
   .ah-usage is centred between them, so ANY text getting wider or narrower at
   runtime re-laid out the whole row — the usage chips visibly slid sideways and,
   near the 1480px breakpoint, the jitter flipped the header between the flex row
   and the grid ("changing structure"). The text that changes on its own:
     · .ah-fresh   "Waiting for data…" ↔ "Updated 7m ago" ↔ "Updated 11m ago (stale)"
     · .checknow   "Scan" ↔ "Scanning…"
     · usage chip  "…" (loading) ↔ "42%" + the 44px track
     · metrics     "5%" ↔ "100%", uptime "4h 20m" ↔ "12d 3h"
   Fix at the source: reserve the widest state for each of them and use tabular
   figures, so a value update repaints in place and never moves a neighbour. */
.apphead .hstat,.apphead .checknow{font-variant-numeric:tabular-nums}
.ah-fresh{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ah-usage>.hstat.usage-stat{min-width:152px}
.ah-usage>.hstat.usage-stat .hstat-btn{width:100%;justify-content:space-between}
.usage-num{min-width:34px;text-align:end}
.apphead .metrics>.hstat{min-width:38px}
.apphead .metrics>.hstat.ah-up{min-width:66px}
.appbody{flex:1;display:flex;min-height:0}
.appbody>.main{background:var(--app-bg)}

/* ===== Floating shell layout (HR design system) — desktop only =====
   Turns the app frame into rounded white panels floating on a gray desk:
   the sidebar and the main area each become a shadowed, hairline-bordered
   panel separated by desk gaps. Mobile (<=1000px) keeps its full-bleed
   layout untouched. Remove this whole block to revert to edge-to-edge. */
@media (min-width:761px){
  .appshell{padding:16px;gap:16px;background:var(--app-bg)}
  .appnav{background:var(--nav-bg);border:1px solid var(--card-line);border-radius:var(--radius-xl);box-shadow:var(--panel-shadow)}
  .appmain{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius-shell);box-shadow:var(--panel-shadow);overflow:hidden}
  .apphead{background:var(--surface)}
  .appbody>.main,.appbody>.home{background:transparent}
  .dock{background:var(--surface)}
  .appnav.apprail{width:70px}
}

/* ===== Icon rail (replaces the wide project sidebar) ===== */
.appnav.apprail{gap:6px;padding:14px 0 0;align-items:center}
.apprail .rbrand{width:40px;height:40px;border-radius:12px;background:#1b1c1f;color:var(--accent);border:none;cursor:pointer;font-size:22px;line-height:1;display:grid;place-items:center;flex-shrink:0;margin-bottom:6px}
.apprail .rail-nav{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1 1 auto;min-height:0;width:100%;overflow:hidden}
.apprail .rail-nav::-webkit-scrollbar{width:0}
.apprail .rit{width:42px;height:42px;border-radius:12px;border:1px solid transparent;background:transparent;color:var(--text-3);cursor:pointer;display:grid;place-items:center;flex-shrink:0;transition:background .14s,color .14s}
.apprail .rit:hover{background:var(--accent-surface);color:var(--accent-fg)}
.apprail .rit.on{background:var(--accent);border-color:var(--accent);color:#fff}
.apprail .rit svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.apprail .rail-sep{width:26px;height:1px;background:var(--line);margin:4px 0;flex-shrink:0}
.apprail .rail-projs{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;flex:1 1 auto;min-height:0;overflow:hidden}
.apprail .rail-proj-list{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}
.apprail .rail-proj-list::-webkit-scrollbar{width:6px}
.apprail .rail-proj-list::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:999px}
.apprail .rproj{position:relative;width:40px;height:40px;border-radius:12px;border:2px solid transparent;background:transparent;padding:0;cursor:pointer;display:grid;place-items:center;flex-shrink:0}
.apprail .rproj:hover{border-color:var(--line-2)}
.apprail .rproj.on{border-color:var(--accent)}
.apprail .rproj[draggable="true"]{cursor:grab}
.apprail .rproj.dragging{opacity:.4;cursor:grabbing}
.apprail .rproj.dragging *{pointer-events:none}
.apprail .rproj-i{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;color:#fff;font-weight:800;font-size:12px}
.apprail .rproj-h{position:absolute;inset-inline-end:-1px;bottom:-1px;width:11px;height:11px;border-radius:999px;border:2px solid var(--nav-bg)}
/* project activity badge. The number is tiny, so the fill must carry enough
   contrast against white — the mint --accent did not (≈2:1) and read as a blur.
   run = a chat is working now → Claude chat orange; done = finished, unopened →
   solid green; stuck = amber. All three are darkened brand tones so #fff clears 4.5:1. */
.apprail .rproj-n{position:absolute;top:-5px;inset-inline-end:-5px;min-width:17px;height:17px;padding:0 4.5px;border-radius:999px;font-size:10.5px;font-weight:800;line-height:16px;letter-spacing:-.2px;color:#fff;background:var(--btn-primary);border:1.5px solid var(--nav-bg);text-align:center}
/* Conversation status indicators (running / completed / failed) on the right of
   a project row. Same darkened brand tones as .rproj-n so #fff clears 4.5:1. */
.cstat{display:inline-flex;align-items:center;gap:3px;flex-shrink:0}
.cstat-n{min-width:17px;height:17px;padding:0 4.5px;border-radius:999px;font-size:10.5px;font-weight:800;line-height:17px;letter-spacing:-.2px;color:#fff;text-align:center}
.cstat-n.run{background:#b3612f}
.cstat-n.done{background:var(--btn-primary)}
.cstat-n.fail{background:#b91c1c}
/* The collapsed 40px rail cannot fit three chips: it keeps the single merged
   .rproj-n badge, and only the expanded rail shows the full breakdown. */
.apprail .rproj-st{display:none}
.apprail.exp .rproj-st{display:inline-flex;margin-inline-start:auto}
.apprail.exp .rproj-n{display:none}
.apprail .rproj-n.run{background:#b3612f}
.apprail .rproj-n.done{background:var(--btn-primary)}
.apprail .rproj-n.stuck{background:#b45309}
.apprail .rit-add{color:var(--text-4)}
.apprail .rail-foot{display:flex;flex-direction:column;align-items:center;gap:6px;width:100%;margin-top:6px;flex:0 0 auto;padding:6px 0 10px;border-top:1px solid var(--line);background:var(--nav-bg)}
.apprail .rail-foot .nav-settings{position:relative}
.apprail .rail-foot .nav-link{width:42px;height:42px;border-radius:12px;padding:0;justify-content:center;color:var(--text-3)}
.apprail .rail-foot .nav-menu-down{top:auto;bottom:calc(100% + 6px);inset-inline-start:0}
/* collapse/expand handle: small square floating on the sidebar's edge, sized
   and rounded like the site's other compact icon controls (row-rm/iconbtn
   family). Hidden until the sidebar or the button itself is hovered/focused;
   stays visible on touch/no-hover input where hover can't reveal it. */
.apprail .rail-toggle{position:absolute;top:auto;bottom:44px;inset-inline-end:6px;z-index:8;width:24px;height:24px;min-height:0;padding:0;gap:0;border-radius:var(--radius-control);background:var(--card);border:1px solid var(--card-line);color:var(--text-3);box-shadow:0 1px 5px rgba(0,0,0,.22);opacity:0;transform:scale(.85);transition:opacity .14s ease,transform .14s ease,background .14s,color .14s,border-color .14s;display:grid;place-items:center}
.apprail:hover .rail-toggle,.apprail .rail-toggle:focus-visible{opacity:1;transform:scale(1)}
.apprail .rail-toggle:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.apprail .rail-toggle svg{width:13px;height:13px;stroke-width:2.2}
/* keep the toggle a fixed square in the expanded rail too - `.apprail.exp .rit`
   below would otherwise stretch it to width:100%; `.rit.rail-toggle` outranks it. */
.apprail.exp .rit.rail-toggle{width:24px;height:24px;inset-inline-end:8px;padding:0;gap:0;display:grid;place-items:center}
@media (hover:none){.apprail .rail-toggle{opacity:1;transform:scale(1)}}

/* ===== Expanded rail — widen to show text labels + full project names ===== */
.rlabel{display:none}
.apprail{transition:width .16s ease;position:relative}
.apprail.resizing{transition:none;user-select:none}
.apprail.exp{width:236px;align-items:stretch;padding:14px 12px 0}
/* drag-to-resize handle on the inline-end edge of the expanded sidebar */
.rail-rsz{position:absolute;top:0;bottom:0;inset-inline-end:-3px;width:8px;z-index:5;cursor:ew-resize;touch-action:none;background:transparent;transition:background .12s}
.rail-rsz::after{content:"";position:absolute;top:50%;inset-inline-end:3px;transform:translateY(-50%);width:3px;height:40px;border-radius:3px;background:var(--line-2);transition:background .12s}
.rail-rsz:hover::after,.rail-rsz.active::after{background:var(--accent)}
.rail-rsz:hover,.rail-rsz.active{background:color-mix(in srgb,var(--accent) 18%,transparent)}
.apprail.exp .rlabel{display:block;font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.1;text-align:start}
.apprail.exp .rbrand{width:100%;justify-content:flex-start;background:transparent;display:flex;align-items:center;gap:10px;padding:0;margin-bottom:8px}
.apprail.exp .rbrand-i{width:40px;height:40px;border-radius:12px;background:#1b1c1f;display:grid;place-items:center;flex-shrink:0}
.apprail .rbrand-t{color:var(--text-1);font-size:15px;font-weight:800}
.apprail.exp .rail-nav,.apprail.exp .rail-projs,.apprail.exp .rail-foot{align-items:stretch}
.apprail.exp .rit{width:100%;justify-content:flex-start;display:flex;align-items:center;gap:11px;padding:0 11px}
.apprail.exp .rit svg{flex-shrink:0}
.apprail.exp .rail-sep{width:auto;margin:6px 11px}
.apprail.exp .rproj{width:100%;justify-content:flex-start;display:flex;align-items:center;gap:11px;padding:0 8px;height:44px;border-radius:11px;border-color:transparent}
.apprail.exp .rproj:hover{border-color:transparent;background:var(--accent-surface)}
.apprail.exp .rproj.on{border-color:transparent;background:var(--accent-surface)}
.apprail.exp .rproj.on .rproj-nm{color:var(--accent-fg)}
.apprail.exp .rproj-i{position:relative;width:30px;height:30px;font-size:11px;flex-shrink:0}
.apprail.exp .rproj-nm{flex:1;min-width:0;color:var(--text-2)}
.apprail.exp .rproj-n{position:static;margin-inline-start:auto;flex-shrink:0}
.apprail.exp .rail-foot .nav-settings-ham{width:100%}
.apprail.exp .rail-foot .nav-link{width:100%;justify-content:flex-start;gap:11px;padding:0 11px}

/* home dashboard */
.home{flex:1;min-width:0;min-height:0;overflow-x:hidden;overflow-y:auto;padding:26px 30px;background:var(--app-bg);box-sizing:border-box}
.home-inner{width:100%;max-width:1140px;min-width:0;margin:0 auto}
.home-greet .date{font-size:12.5px;color:var(--text-4);font-weight:600}
.home-greet h1{margin:6px 0 3px;font-size:30px;letter-spacing:-.02em}
.home-greet .sub{font-size:19px;font-weight:600;color:#a5b4fc}
.home-actions{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0 24px}
.actionpill{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:13px;font-weight:600;padding:var(--pad-control);border-radius:var(--radius-control);border:1px solid var(--card-line);background:var(--card);color:var(--text-2);cursor:pointer;box-shadow:var(--card-shadow);transition:transform .1s,border-color .12s,color .12s}
.actionpill:hover{border-color:var(--accent-border);color:var(--text);transform:translateY(-1px)}
.actionpill.primary{background:var(--btn-primary);color:#fff;border-color:transparent}
.actionpill.primary:hover{background:var(--btn-primary-hover)}
.home-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;align-items:start;width:100%;max-width:100%}
.home-grid>*{width:100%;min-width:0;max-width:100%}
/* Home KPI stat row + projects grid (HR dashboard preview) */
.home-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin:0 0 22px}
.kpi{background:var(--card);border:1px solid var(--card-line);border-radius:var(--radius-lg);box-shadow:var(--card-shadow);padding:16px 18px;display:flex;flex-direction:column;gap:10px;min-width:0}
button.kpi{width:100%;text-align:start;font:inherit;color:inherit;cursor:pointer;transition:transform .12s ease,box-shadow .12s ease,border-color .12s ease}
button.kpi:hover{transform:translateY(-2px);box-shadow:var(--card-shadow-hover,0 8px 22px rgba(0,0,0,.10));border-color:var(--accent)}
button.kpi:active{transform:translateY(0)}
button.kpi:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.kpi-top{display:flex;align-items:center;justify-content:space-between}
.kpi-ic{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;color:#fff;flex-shrink:0}
.kpi-ic svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.kpi-val{font-size:30px;font-weight:800;letter-spacing:-.03em;line-height:1;font-variant-numeric:tabular-nums}
.kpi-lbl{font-size:12px;color:var(--text-3);font-weight:600}
.home-projects{margin-top:24px}
.hp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.hp-head h3{font-size:15px;font-weight:700;margin:0}
.hp-head .see-all{font:inherit;font-size:12px;font-weight:600;cursor:pointer;border:1px solid var(--line-2);background:var(--card);color:var(--text-2);border-radius:var(--radius-control);padding:5px 12px}
.hp-head .see-all:hover{border-color:var(--accent);color:var(--accent-fg)}
.hp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr));gap:14px}
.pcard{text-align:start;font:inherit;cursor:pointer;background:var(--card);border:1px solid var(--card-line);border-radius:var(--radius-md);box-shadow:var(--card-shadow);padding:14px;display:flex;flex-direction:column;gap:12px;transition:transform .1s,border-color .12s}
.pcard:hover{transform:translateY(-1px);border-color:var(--accent-border)}
.pcard-top{display:flex;align-items:center;gap:10px;min-width:0}
.pcard-mark{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;color:#fff;font-weight:800;font-size:12.5px;flex-shrink:0}
.pcard-name{flex:1;font-size:13.5px;font-weight:700;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;text-align:start}
.pcard-foot{display:flex;align-items:center;justify-content:space-between;gap:8px}
.pcard-meta{font-size:11.5px;color:var(--text-4)}
.pcard-badge{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;white-space:nowrap}
.pcard-dot{width:7px;height:7px;border-radius:999px;flex-shrink:0}
/* Skeletons: shape-preserving load placeholders so the dashboard never shows a
   false "empty account" state before /api/projects and recent chats settle.
   Tokens carry the theme, so light/dark both work; motion is off under
   prefers-reduced-motion. */
@keyframes hub-shimmer{0%{background-position:-160px 0}100%{background-position:160px 0}}
.skel{display:inline-block;border-radius:6px;background:linear-gradient(90deg,var(--surface-2) 25%,var(--line-2) 37%,var(--surface-2) 63%);background-size:320px 100%;animation:hub-shimmer 1.2s ease-in-out infinite}
.skel-line{height:12px;flex:1;min-width:0}
.skel-line.sm{height:10px;width:60%}
.skel-dot{width:10px;height:10px;border-radius:999px;flex-shrink:0}
.skel-mark{width:34px;height:34px;border-radius:9px;flex-shrink:0}
.skel-row{display:flex;align-items:center;gap:10px;padding:8px 4px;pointer-events:none}
.pcard.skel-card{pointer-events:none;gap:14px}
.hcard-error{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:14px;border:1px solid var(--card-line);border-radius:var(--radius-md);background:var(--card);color:var(--text-2);font-size:13px}
@media (prefers-reduced-motion:reduce){.skel{animation:none}}
@media (max-width:900px){.home-kpis{grid-template-columns:repeat(2,1fr)}}
.hcard{background:var(--card);border:1px solid var(--card-line);border-radius:var(--radius-xl);box-shadow:var(--card-shadow);padding:18px 18px 8px;min-width:0;max-width:100%;box-sizing:border-box}
.hcard-head{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.hcard-head h3{margin:0;font-size:15px;display:flex;align-items:center;gap:8px}
.hcard-head .cnt{font-size:12px;color:var(--text-4);font-weight:600}
.last-chats-head{align-items:flex-start}
.home-chat-actions{margin-inline-start:auto;display:flex;align-items:center;justify-content:flex-end;gap:7px;flex-wrap:wrap;min-width:0}
.home-chat-btn{display:inline-flex;align-items:center;gap:6px;font:inherit;font-size:11.5px;font-weight:700;line-height:1;padding:6px 9px;border-radius:999px;border:1px solid var(--card-line);background:var(--surface-soft);color:var(--text-2);cursor:pointer;white-space:nowrap;transition:border-color .12s,color .12s,background .12s}
.home-chat-btn:hover{border-color:var(--accent-border);background:var(--accent-surface-2);color:var(--text)}
.home-chat-btn.claude{color:var(--claude-orange-soft);border-color:rgba(217,119,87,.4);background:rgba(217,119,87,.12)}
.home-chat-btn.codex{color:var(--codex-chat-fg);border-color:color-mix(in srgb,var(--codex) 32%,transparent);background:color-mix(in srgb,var(--codex-chat) 10%,transparent)}
.hcard-head .more{margin-inline-start:auto;font:inherit;font-size:12px;font-weight:600;color:var(--accent-fg);background:none;border:none;cursor:pointer;padding:0}
.hcard-head .more:hover{text-decoration:underline}
.hrow{display:flex;align-items:center;gap:10px;width:100%;text-align:start;padding:11px 6px;border:none;border-top:1px solid var(--line-soft);background:none;color:inherit;font:inherit;cursor:pointer;border-radius:8px}
.hrow:first-of-type{border-top:none}
.hrow:hover{background:var(--surface-2)}
.hrow .dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.hrow .dot.pulse{box-shadow:0 0 0 4px color-mix(in srgb,var(--live) 14%,transparent)}
.hrow .nm{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13.5px;font-weight:500;color:var(--text)}
.hrow .meta{font-size:12px;color:var(--text-4);flex-shrink:0}
.hrow .meta.unseen{color:var(--accent-fg);font-weight:700}
.hrow .pill-n{font-size:11px;font-weight:700;color:var(--accent-fg);background:var(--accent-surface);border-radius:999px;padding:1px 8px;flex-shrink:0}
.hrow .pill-n.live{color:var(--live-fg);background:color-mix(in srgb,var(--live) 14%,transparent)}
.hrow .pill-n.zero{color:var(--text-4);background:var(--line)}
.last-chats-list{max-height:340px;overflow-y:auto;margin:0 -6px;padding:0 6px}
.hrow.chat-row{align-items:center}
/* Last Chats — featured latest + condensed list (impeccable live, accepted 2026-07-10) */
.last-chats-feat{display:flex;flex-direction:column}
.lc-feature{display:flex;flex-direction:column;gap:8px;padding:16px;border-radius:11px;background:var(--slate-soft-2);border:none;text-align:start;color:inherit;font:inherit;cursor:pointer;transition:background .12s ease;margin-bottom:10px;width:100%}
.lc-feature:hover{background:var(--slate-soft)}
.lc-feature .lc-ftop{display:flex;align-items:center;gap:7px;font-size:10px;color:var(--text-4)}
.lc-feature.provider-claude .provider-logo{color:var(--claude)}
.lc-feature.provider-codex .provider-logo{color:var(--codex)}
.lc-flabel{font-weight:600;letter-spacing:.02em;color:var(--text-3)}
.lc-ftime{margin-inline-start:auto;font-size:10px;color:var(--text-4);white-space:nowrap}
.lc-ftime.unseen{color:var(--accent-fg);font-weight:700}
.lc-ftime.live{color:var(--live-fg);background:color-mix(in srgb,var(--live) 14%,transparent);font-weight:700;padding:1px 8px;border-radius:999px}
.lc-fname{font-size:16px;font-weight:600;line-height:1.34;color:var(--text)}
.lc-fsub{font-size:12px;color:var(--text-4)}
.lc-side{display:flex;flex-direction:column;margin:0 -6px;padding:0 6px;max-height:340px;overflow-y:auto}
.lc-row{display:grid;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;gap:10px;padding:9px 8px;border:none;background:none;text-align:start;color:inherit;font:inherit;cursor:pointer;border-radius:8px;transition:background .12s ease;width:100%;min-width:0}
.lc-row:hover{background:var(--surface-2)}
.lc-row .provider-logo{flex-shrink:0}
.lc-row.provider-claude .provider-logo{color:var(--claude-orange-soft)}
.lc-row.provider-codex .provider-logo{color:var(--codex-chat-fg)}
.lc-row.provider-gemini .provider-logo{color:var(--gemini)}
.lc-rmain{min-width:0;display:flex;flex-direction:column;gap:1px}
.lc-rname{min-width:0;font-size:12.5px;font-weight:500;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lc-rsub{min-width:0;font-size:11px;color:var(--text-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lc-rtime{font-size:10px;color:var(--text-4);white-space:nowrap;flex-shrink:0}
.lc-rtime.unseen{color:var(--chat-done);font-weight:700}
.lc-rtime.unseen.fail{color:var(--chat-error)}
.lc-rtime.live{color:var(--chat-working);font-weight:700}
.hrow.chat-row .chat-main{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.hrow.chat-row .chat-main .nm{display:block;flex:0;width:100%}
.hrow.chat-row .chat-sub{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11.5px;color:var(--text-4)}
.hrow.chat-row .provider-logo{flex-shrink:0}
.hrow.chat-row.provider-claude .provider-logo{color:var(--claude-orange-soft)}
.hrow.chat-row.provider-claude:hover{background:rgba(217,119,87,.08)}
.hrow.chat-row.provider-codex .provider-logo{color:var(--codex-chat-fg)}
.hrow.chat-row.provider-codex:hover{background:color-mix(in srgb,var(--codex-chat) 8%,transparent)}
.hrow.chat-row.provider-gemini .provider-logo{color:var(--gemini)}
.hrow.chat-row.provider-gemini:hover{background:color-mix(in srgb,var(--gemini-deep) 8%,transparent)}
.hcard-empty{padding:16px 6px 20px;font-size:13px;color:var(--text-4)}
.home-mini{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:18px}
.mstat{background:var(--card);border:1px solid var(--card-line);border-radius:14px;box-shadow:var(--card-shadow);padding:13px 15px}
.mstat .k{font-size:11.5px;color:var(--text-4);font-weight:600;text-transform:uppercase;letter-spacing:.03em}
.mstat .v{font-size:22px;font-weight:700;margin-top:3px;letter-spacing:-.02em}
.mstat .v small{font-size:12px;font-weight:600;color:var(--text-4);margin-inline-start:3px}

/* desktop: nav rail + roomy dock inside appbody */
@media (min-width:761px){
  .appbody>.main{overflow-y:auto}
  .appbody>.dock:not(.collapsed){align-self:stretch;height:auto;border-radius:0}
  /* The dock fills the appbody top-to-bottom so the chat interface attaches flush
     under the apphead instead of floating above the bottom. height:auto!important
     overrides the persisted inline height (which otherwise leaves empty white space
     above a bottom-anchored panel); align-self:stretch fills the full column. */
  .appbody>.dock:not(.collapsed):not(.maxed){align-self:stretch;height:auto!important;border-radius:0}
  .appshell.dock-maxed .appbody>.main{display:none}
  .dock.maxed{flex:1 1 auto;width:auto;min-width:0}
}
/* phone/tablet: nav becomes a full-screen "Projects/Menu" view driven by .mnav */
@media (max-width:760px){
  .appshell{flex:1;min-height:0;flex-direction:column;position:relative}
  .appnav{display:none}
  .appshell.mv-projects>.appnav{display:flex;width:auto!important;flex:1;min-height:0;border-inline-end:none;order:1}
  .rail-rsz{display:none}
  /* Projects tab still shows the sticky stats header (CPU/RAM/disk/uptime +
     Claude/Codex usage): keep .appmain mounted for its header only — collapse it to
     header height, hide its body, and order it above the project list. */
  .appshell.mv-projects>.appmain{display:flex;flex:0 0 auto;min-height:0;order:0}
  .appshell.mv-projects>.appmain>.appbody{display:none}
  /* Projects view owns the persistent rail controls on small screens too, so
     former header-menu actions remain reachable without reintroducing a top menu. */
  .appnav .nav-list{margin:0}
  .appmain{flex:1;min-height:0}
  .apphead{padding:8px 12px}
  /* ── Header reflow (≤1000px): exactly two rows ─────────────────────────────
       row 1 — controls:  [☰ menu · 🔔 bell] ····filler···· [Scan] [↻ refresh]
       row 2 — telemetry: [Claude][Codex]  +  host metrics (CPU/RAM/disk/uptime)
     Both .ah-end and .ah-usage collapse with display:contents so every control
     becomes a direct flex child of .apphead and can be ordered independently.
     A zero-height ::before (order:4, flex-basis:100%) is the single row break, so
     the strip never spills onto a third line. The host-metrics group scrolls
     sideways instead of wrapping, keeping every stat reachable without adding a
     row. Project name isn't shown on mobile (it lives in the .mprojbar switcher),
     so the empty .ah-start just acts as the row-1 spacer. */
  .apphead{display:flex;flex-wrap:wrap;align-items:center;column-gap:7px;row-gap:8px}
  .apphead>.ah-end,.apphead>.ah-usage{display:contents}
  .apphead::before{content:"";order:4;flex:0 0 100%;height:0}
  /* row 1 — controls */
  .ah-end>.ah-mctrls{order:0;display:flex;align-items:center;gap:8px;flex:0 0 auto}
  .apphead>.ah-start{order:1;flex:1 1 auto;min-width:0}
  /* the desktop width reservations are sized for 12px type — re-reserve them at
     the compact phone scale so the row is still jitter-free but not oversized.
     The Scan button + freshness chip now ride inside the metrics strip (row 2). */
  .ah-end>.ah-lead .metrics>.cn-col>.checknow{min-height:0;padding:2px 8px;font-size:10px;gap:4px;border-radius:8px;min-width:70px}
  .ah-end>.ah-lead .metrics>.cn-col>.checknow .cn-ic{font-size:12px}
  .ah-end>.ah-lead .metrics>.cn-col>.ah-fresh{font-size:8.5px}
  .ah-usage>.hard-refresh{order:3;flex:0 0 auto;margin-inline-start:0}
  /* row 2 — telemetry. Usage chips compact to a colour-dot + % (the provider name
     and the session/weekly meters stay one tap away in the popover) so both
     providers AND all four host metrics fit the row without scrolling on a phone.
     Provider identity is carried by the dot colour: purple = Claude, cyan = Codex. */
  /* dot + % only here, so the .usage-num reservation alone keeps it steady.
     These selectors MUST carry the .hstat qualifier: the desktop reservations are
     .ah-usage>.hstat.usage-stat (3 classes) and .ah-usage>.hstat.usage-stat .hstat-btn
     (4 classes). Dropping .hstat here loses on specificity no matter that this block
     comes later, and the chip silently keeps min-width:152px + space-between — which
     is what stranded the colour dot at the far left of the chip with the percentage
     117px away, and spent 304px of a 390px row on two mostly-empty boxes. */
  .ah-usage>.hstat.usage-stat{order:5;flex:0 0 auto;padding:0;min-width:0}
  /* width:auto is load-bearing — the desktop rule sets width:100%, so without it the
     button still fills the chip and flex-start alone would not close the gap. */
  .ah-usage>.hstat.usage-stat .hstat-btn{width:auto;justify-content:flex-start;font-size:0;gap:6px}
  .ah-usage>.usage-stat.claude,.ah-usage>.usage-stat.codex{background:none;border-color:transparent}
  .ah-usage>.hstat.usage-stat .hstat-btn::before{display:none}
  .ah-usage>.hstat.usage-stat .usage-value{font-size:12px;gap:6px}
  .ah-usage>.hstat.usage-stat .usage-pie{display:inline-block}
  .ah-usage>.hstat.usage-stat .usage-track{display:none}
  /* Keep the 34px reservation (1% -> 100% must not move the row) but left-align it
     here. Right-aligned, the slack falls between the dot and its OWN number while the
     next chip's dot butts up against it, so "● 49% ● 1%" visually grouped each dot with
     the number to its left. Left-aligned, the number hugs its dot and the slack becomes
     the separator before the next provider. */
  .ah-usage>.hstat.usage-stat .usage-num{text-align:start}
  /* host metrics fill the remaining width (flex-basis:0 keeps them on the usage
     line rather than wrapping to a third row); they scroll sideways only as a
     fallback on the very narrowest phones, with a soft fade hinting at overflow. */
  .ah-end>.ah-lead{order:6;flex:1 1 0;min-width:0;justify-content:flex-start}
  .ah-end>.ah-lead .metrics{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;gap:9px;
     scrollbar-width:none;-webkit-overflow-scrolling:touch;
     -webkit-mask-image:linear-gradient(90deg,#000 92%,transparent);mask-image:linear-gradient(90deg,#000 92%,transparent)}
  .ah-end>.ah-lead .metrics::-webkit-scrollbar{display:none}
  .ah-end>.ah-lead .metrics>.hstat{flex:0 0 auto}
  .appbody>.home,.appbody>.main,.appbody>.dock{display:none}
  .appshell.mv-home .appbody>.home{display:flex}
  .appshell.mv-detail .appbody>.main{display:block}
  .appshell.mv-chat .appbody>.dock{display:flex}
  .home{padding:16px}
  .home-grid{grid-template-columns:minmax(0,1fr)}
  .home-mini{grid-template-columns:repeat(2,1fr)}
  .home-greet h1{font-size:24px}
  .home-greet .sub{font-size:16px}
}
/* ── Tablet header (iPad, 700–1000px): keep the whole strip on ONE line ──────
   The ≤1000px block above splits the header into two rows (controls · telemetry)
   via a zero-height ::before break — right for narrow phones, but on a tablet the
   row has ample width, so collapse it back to a single line: drop the forced row
   break, stop the strip wrapping, and let the empty .ah-start spacer shrink away
   so controls + usage + host metrics share one line (metrics still scroll if the
   row runs out of room). */
@media (min-width:700px) and (max-width:760px){
  .apphead{flex-wrap:nowrap}
  .apphead::before{display:none}
  .apphead>.ah-start{flex:0 1 auto}
  .ah-usage>.hard-refresh{order:7}
  .ah-end>.ah-lead{flex:1 1 0}
}
/* Light-theme legibility: darken Live-status text and quick-prompt buttons.
   The status values use inline style color:var(--ok/--err/--warn), so we
   re-scope those vars on .live (inline var() resolves to the darker value). */
html:not(.dark) .live{--ok:#167A58;--err:#C2302E;--warn:#B36A12}
html:not(.dark) .infra-h{color:#3B4046}
html:not(.dark) .irow .ik{color:#565C63}
html:not(.dark) .irow .iv{color:#26292D}
html:not(.dark) .cquick button,
html:not(.dark) .csugg .sg,
html:not(.dark) .csugg-dock .sg,
html:not(.dark) .csugg-empty .sg{color:#155C42}
html:not(.dark) .csugg .sg .sg-t,
html:not(.dark) .csugg-dock .sg .sg-t,
html:not(.dark) .csugg-empty .sg .sg-t{color:#18191B}
html:not(.dark) .tip-nudge{color:#155C42}
html:not(.dark) .tip-nudge-x{color:#167A58}
html:not(.dark) .tip-headline,
html:not(.dark) .tip-headline b{color:#18191B}
html:not(.dark) .usage-track{background:#C2C8CF}
html:not(.dark) .usage-meter-bar{background:#C2C8CF}
.cmsg.note .note-bubble{opacity:.85;font-size:12.5px;font-style:italic;border-inline-start:2px solid var(--line);padding-inline-start:8px;white-space:pre-wrap;}
