/* The app maker's shell. Monochrome, after shadcn/ui's neutral theme:
   soft-grey sidebar, an inset white work surface, hairline borders, 6/8/10/12px
   radii, black-on-white primary actions. Colour belongs to the generated apps
   only. Type runs at macOS app scale (13px body). Every text pair holds WCAG
   2.2 AA and control edges hold 3:1, so input borders and the focus ring are a
   step darker than shadcn's defaults. */

@font-face {
  font-family: "Geist";
  src: url("../fonts/geist-latin.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("../fonts/geist-mono-latin.woff2") format("woff2");
  font-weight: 400 600;
  font-display: swap;
}

:root {
  --background: #FFFFFF;
  --foreground: #0A0A0A;
  --primary: #171717;
  --primary-hover: #2E2E2E;
  --primary-foreground: #FAFAFA;
  --secondary: #F5F5F5;
  --muted: #F5F5F5;
  --muted-foreground: #6B6B6B;
  --code-mid: #525252; /* strings and numbers in code, as in the code view */
  --accent: #F5F5F5;
  --destructive: #DC2626;
  --success: #16A34A; /* a data call that worked: the dot in the build log (3.3:1 on white) */
  --destructive-text: #B91C1C;
  --destructive-solid: #DC2626;
  --switch-off: #808080;
  --destructive-tint: rgba(220, 38, 38, 0.08);
  --warning: #B45309; /* amber, for warnings only; every pairing below passes AA on --warning-tint */
  --warning-text: #78350F;
  --warning-muted: #92400E;
  --warning-tint: #FFFBEB;
  --border: #E5E5E5;
  --input: #8A8A8A;
  --ring: #737373;
  --sidebar: #FAFAFA;
  --sidebar-accent: #EFEFEF;
  --overlay: rgba(0, 0, 0, 0.5);
  --preview-ground: #FFFFFF;
  --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B6B6B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.08), 0 1px 2px -1px rgb(0 0 0 / 0.08);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);

  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 12px;

  --sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --fs: 13px;
  --fs-sm: 12px;
  --fs-xs: 11px;

  --sidebar-w: 248px;
  --ai-panel-w: clamp(320px, 25vw, 380px);
  --header-h: 48px;
  --fold: 0.25s var(--ease-out); /* a side panel folding away or coming back */
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --background: #0A0A0A;
    --foreground: #FAFAFA;
    --primary: #E5E5E5;
    --primary-hover: #D4D4D4;
    --primary-foreground: #171717;
    --secondary: #262626;
    --muted: #262626;
    --muted-foreground: #A1A1A1;
    --code-mid: #C4C4C4;
    --accent: #262626;
    --destructive: #FF6467;
    --success: #22C55E;
    --destructive-text: #FF8A8C;
    --destructive-solid: #B91C1C;
    --switch-off: #7A7A7A;
    --destructive-tint: rgba(255, 100, 103, 0.12);
    --warning: #FBBF24;
    --warning-text: #FDE68A;
    --warning-muted: #FCD34D;
    --warning-tint: #2B1D07;
    --border: #262626;
    --input: #6A6A6A;
    --ring: #8A8A8A;
    --sidebar: #171717;
    --sidebar-accent: #262626;
    --overlay: rgba(0, 0, 0, 0.7);
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A1A1A1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.3);
    --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.5);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --background: #0A0A0A;
  --foreground: #FAFAFA;
  --primary: #E5E5E5;
  --primary-hover: #D4D4D4;
  --primary-foreground: #171717;
  --secondary: #262626;
  --muted: #262626;
  --muted-foreground: #A1A1A1;
  --code-mid: #C4C4C4;
  --accent: #262626;
  --destructive: #FF6467;
  --success: #22C55E;
  --destructive-text: #FF8A8C;
  --destructive-solid: #B91C1C;
  --switch-off: #7A7A7A;
  --destructive-tint: rgba(255, 100, 103, 0.12);
  --warning: #FBBF24;
  --warning-text: #FDE68A;
  --warning-muted: #FCD34D;
  --warning-tint: #2B1D07;
  --border: #262626;
  --input: #6A6A6A;
  --ring: #8A8A8A;
  --sidebar: #171717;
  --sidebar-accent: #262626;
  --overlay: rgba(0, 0, 0, 0.7);
  --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A1A1A1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.3);
  --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.5);
  color-scheme: dark;
}

/* ---- Base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
html { overscroll-behavior: none; } /* no rubber band on the page itself; its parts scroll */
body {
  margin: 0;
  font: 400 var(--fs)/1.5 var(--sans);
  color: var(--foreground);
  background: var(--sidebar);
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
}
h1, h2, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
code { font: 0.92em var(--mono); }
[hidden] { display: none !important; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.spin { animation: spin 1s linear infinite; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.spacer { flex: 1; }

::selection { background: color-mix(in srgb, var(--foreground) 16%, transparent); }
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--foreground) 22%, transparent) transparent; }

/* ---- Buttons ----------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; padding: 0 12px;
  font: 500 var(--fs)/1 var(--sans); color: var(--foreground); text-decoration: none; white-space: nowrap;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.btn .icon { width: 14px; height: 14px; }
.btn:disabled { opacity: 0.5; pointer-events: none; }
.btn-sm { height: 28px; padding: 0 10px; font-size: var(--fs-sm); gap: 5px; }
.btn-icon { width: 32px; padding: 0; }
.btn-sm.btn-icon { width: 28px; }
.btn-block { width: 100%; }
.btn-primary { background: var(--primary); color: var(--primary-foreground); box-shadow: var(--shadow-xs); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-outline { background: var(--background); border-color: var(--border); box-shadow: var(--shadow-xs); }
.btn-outline:hover { background: var(--accent); }
.btn-ghost:hover { background: var(--accent); }
.btn-ghost-danger { color: var(--destructive); }
.btn-ghost-danger:hover { background: var(--destructive-tint); }
.btn-outline-danger { color: var(--destructive-text); background: var(--destructive-tint); border-color: color-mix(in srgb, var(--destructive) 40%, transparent); }
.btn-destructive { background: var(--destructive-solid); color: #FFFFFF; box-shadow: var(--shadow-xs); }
.btn-destructive:hover { background: color-mix(in srgb, var(--destructive-solid) 88%, black); }

/* ---- Inputs ------------------------------------------------------------------- */
.input {
  width: 100%; height: 32px; padding: 0 10px;
  font-size: var(--fs); background: var(--background);
  border: 1px solid var(--input); border-radius: var(--radius-sm); box-shadow: var(--shadow-xs);
}
.input::placeholder, .composer-input::placeholder { color: var(--muted-foreground); opacity: 1; }
.input:focus { outline: none; border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring), 0 0 0 4px color-mix(in srgb, var(--ring) 25%, transparent); }
.input-wrap { position: relative; }
.input-wrap > .icon { position: absolute; left: 9px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--muted-foreground); pointer-events: none; }
.input-search { padding-left: 30px; height: 30px; }

.select {
  appearance: none; height: 28px; padding: 0 26px 0 9px; min-width: 0;
  font: 500 var(--fs-sm)/1 var(--sans); color: var(--foreground);
  border: 1px solid var(--input); border-radius: var(--radius-sm); cursor: pointer;
  background: var(--select-chevron) no-repeat right 7px center / 13px 13px, var(--background);
}
.select-ghost { border-color: transparent; background-color: transparent; color: var(--muted-foreground); }
.select-ghost:hover { background-color: var(--accent); color: var(--foreground); }
.select option { background: var(--background); color: var(--foreground); }
.select:disabled { opacity: 0.5; cursor: not-allowed; }

.badge {
  display: inline-flex; align-items: center; height: 18px; padding: 0 6px;
  font: 500 var(--fs-xs)/1 var(--sans); color: var(--foreground);
  background: var(--secondary); border-radius: var(--radius-sm); white-space: nowrap;
}
.badge:empty { display: none; }
.badge-mono { font-family: var(--mono); font-weight: 400; }
.badge-outline { background: transparent; border: 1px solid var(--border); }
.badge-danger { color: var(--destructive-text); background: var(--destructive-tint); }
.badge-live { color: var(--primary-foreground); background: var(--primary); }

/* ---- Shell ---------------------------------------------------------------------- */
.shell {
  height: 100%;
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
}
/* Either side panel folds away (layout.js): its column closes while the panel slides out,
   so the stage takes the room. The parts keep their width meanwhile, so nothing reflows.
   The movement runs only while a panel folds (is-folding), never on a window resize. */
:root[data-sidebar="closed"] .shell { grid-template-columns: 0 minmax(0, 1fr); }
:root.is-folding .shell, :root.is-folding .inset { transition: grid-template-columns var(--fold), margin-left var(--fold); }
:root.is-folding .sidebar, :root.is-folding .ai-col { transition: transform var(--fold); }
@media (min-width: 901px) {
  .sidebar { min-width: 0; overflow: hidden; }
  .sidebar > * { width: var(--sidebar-w); }
  :root[data-sidebar="closed"] .sidebar { transform: translateX(calc(-1 * var(--sidebar-w))); }
  :root[data-sidebar="closed"] .inset { margin-left: 8px; }
  .ai-col { min-width: 0; overflow: hidden; }
  .ai-col > * { width: var(--ai-panel-w); }
  :root[data-panel="closed"] .inset { grid-template-columns: minmax(0, 1fr) 0 0; }
  /* The divider between the stage and the AI panel (panel-resize.js): a narrow track of its own,
     with a wider hit area over the panel's edge. A line shows on hover, while dragging, and
     (thicker, in the focus colour) when it has keyboard focus. */
  .stage-col { grid-column: 1; grid-row: 1; }
  .ai-col { grid-column: 3; grid-row: 1; }
  .panel-gutter { grid-column: 2; grid-row: 1; position: relative; z-index: 3; width: 12px; margin-inline: -6px; cursor: col-resize; touch-action: none; }
  .panel-gutter::before { content: ""; position: absolute; inset: 0 5px; transition: background-color 0.15s; }
  .panel-gutter:hover::before, :root.is-resizing .panel-gutter::before { background: color-mix(in srgb, var(--foreground) 35%, transparent); }
  .panel-gutter:focus-visible { outline: none; }
  .panel-gutter:focus-visible::before { inset: 0 4px; background: var(--ring); }
  :root[data-panel="closed"] .panel-gutter { display: none; }
  :root.is-resizing { cursor: col-resize; user-select: none; }
  :root[data-panel="closed"] .ai-col { transform: translateX(var(--ai-panel-w)); }
}

/* Sidebar */
.sidebar { display: flex; flex-direction: column; min-height: 0; background: var(--sidebar); }
.sidebar-header { display: flex; flex-direction: column; gap: 14px; padding: 14px 12px 8px; }
.brand { display: flex; flex-direction: column; padding: 2px 6px; }
.brand-row { display: flex; align-items: center; gap: 2px; }
.brand-logo { flex: none; width: 36px; height: 18px; margin-left: 6px; }
.brand-name { font: 650 15px/1.2 var(--sans); letter-spacing: -0.01em; color: var(--foreground); }
.brand-ink { color: var(--foreground); } /* "HSBCnio" is always black on light and white on dark, never grey, even in grey copy */
.brand-sub { font-size: var(--fs-sm); line-height: 1; color: var(--muted-foreground); }
.sidebar-content { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 6px; padding: 4px 12px 0; }
.group { display: flex; flex-direction: column; gap: 2px; flex: none; }
.group-apps { flex: 1 1 auto; min-height: 96px; }
/* The list scrolls at the sidebar's full width, its padding inside, so the scrollbar sits at the edge. */
.group-apps .menu { flex: 1; min-height: 0; overflow-y: auto; margin: 0 -12px; padding: 0 12px 8px; }
.group-label { display: flex; align-items: center; height: 30px; padding: 0 8px; font: 500 var(--fs-sm)/1 var(--sans); color: var(--muted-foreground); }
/* The Apps label with the All apps | My apps control at the end of its row. */
.group-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.apps-filter { flex: none; }
.apps-filter .toggle-text { height: 22px; padding: 0 8px; font-size: var(--fs-xs); }
.menu { display: flex; flex-direction: column; gap: 1px; }
.menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%; height: 32px; padding: 0 8px;
  font: 400 var(--fs)/1 var(--sans); color: var(--foreground); text-align: left;
  background: transparent; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.menu-item .icon { color: var(--muted-foreground); }
.menu-item:hover { background: var(--sidebar-accent); }
.menu-item[aria-current="true"] { background: var(--sidebar-accent); font-weight: 500; }
.menu-item[aria-current="true"] .icon { color: var(--foreground); }
.menu-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-badge { flex: none; justify-content: center; min-width: 60px; height: 16px; margin-left: auto; padding: 0 6px; font-size: 10px; font-weight: 500; border-radius: 4px; } /* wide enough for Snapshot; Live matches */
.list-empty { padding: 6px 8px; font-size: var(--fs-sm); color: var(--muted-foreground); }

.group-settings { flex: none; margin-top: auto; padding: 6px 0 2px; border-top: 1px solid var(--border); }
.tool-list { display: flex; flex-direction: column; }
.tool-item { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px 10px; padding: 8px 6px; border-radius: var(--radius-sm); }
.tool-item:hover { background: var(--sidebar-accent); }
.tool-name { font: 400 var(--fs-sm)/1.4 var(--mono); overflow-wrap: break-word; min-width: 0; }
.tool-item.is-off .tool-name { color: var(--muted-foreground); }
.tool-name .badge { margin-left: 6px; vertical-align: 1px; height: 16px; font-family: var(--sans); }
.tool-desc { grid-column: 1 / -1; font-size: var(--fs-sm); color: var(--muted-foreground); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tool-item:hover .tool-desc { -webkit-line-clamp: unset; }

.sidebar-footer { padding: 8px 12px 12px; }
.account { display: flex; align-items: center; gap: 8px; padding: 8px 6px 8px 10px; border-radius: var(--radius-md); }
.account:hover { background: var(--sidebar-accent); }
.account-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.account-name { display: flex; align-items: center; gap: 6px; font-weight: 500; min-width: 0; }
.account-name span:last-child, .account-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-sub { font-size: var(--fs-sm); color: var(--muted-foreground); }
#account-tools:not(:empty)::after { content: " · "; }
.dot { display: none; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.is-connected .dot, .is-busy .dot, .is-error .dot { display: block; }
.is-connected .dot { background: var(--foreground); }
.is-busy .dot { background: var(--muted-foreground); animation: blink 1s steps(2) infinite; }
.is-error .dot { background: var(--destructive); }

/* Inset work surface */
.inset {
  display: grid; grid-template-columns: minmax(0, 1fr) 0 var(--ai-panel-w);
  min-width: 0; min-height: 0; margin: 8px 8px 8px 0;
  background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
.col-header {
  height: var(--header-h); flex: none; min-width: 0;
  display: flex; align-items: center; gap: 12px; padding: 0 10px 0 16px;
  border-bottom: 1px solid var(--border);
}
/* The stage header starts and ends with the buttons that fold the panels beside it. It has two
   rows: the title (with the meta line beside it), then the toolbar (.stage-bar). */
.stage-col > .col-header { height: auto; min-height: var(--header-h); flex-wrap: wrap; gap: 6px 12px; padding: 10px 10px 8px; }
.panel-toggle { position: relative; color: var(--muted-foreground); }
.panel-toggle:hover { color: var(--foreground); }
#panel-toggle { margin-left: auto; }
/* The AI panel did something while it was closed (a save, a question, the end of a build). */
.panel-toggle.has-news::after { content: ''; position: absolute; top: 5px; right: 5px; width: 6px; height: 6px; border-radius: 50%; background: var(--foreground); }
.sidebar-close, .panel-close, .sheet-handle, .scrim { display: none; }
.sidebar-close { margin-left: auto; }
.icon-down { transform: rotate(90deg); }
#stage-bar[hidden] + .panel-divider { display: none; }

/* Stage column */
.stage-col { display: flex; flex-direction: column; min-width: 0; min-height: 0; container-type: inline-size; }
.crumbs { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 0 1 auto; color: var(--muted-foreground); }
.crumb { white-space: nowrap; }
.crumb-sep { width: 14px; height: 14px; }
.crumb-page { color: var(--foreground); font-weight: 500; white-space: nowrap; }
.title-input {
  min-width: 6ch; max-width: 340px; field-sizing: content;
  height: 28px; padding: 0 6px; margin-left: -6px;
  font: 500 var(--fs)/1 var(--sans); color: var(--foreground);
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
  text-overflow: ellipsis;
}
.title-input:hover { border-color: var(--border); }
.title-input:focus { outline: none; border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring), 0 0 0 4px color-mix(in srgb, var(--ring) 25%, transparent); }
/* The toolbar takes the header's second row: the view and size controls at the start, the
   actions at the end, and on a phone the actions drop to a row of their own, from the start. */
.stage-bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 6px 12px; flex: 1 1 100%; order: 1; min-width: 0; }
.stage-tools { display: flex; align-items: center; gap: 12px; flex: none; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: none; }
.stage-meta { font-size: var(--fs-sm); color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1 1 0%; }
/* The header gives way by the width of its own column (the AI panel takes some of the window):
   the button labels go first, then the size readout, the meta line and the crumbs. */
@container (max-width: 860px) {
  .btn-label, .toggle-label { display: none; }
  .toggle-text { padding: 0 7px; }
  .actions .btn-sm:not(.btn-outline-danger) { width: 28px; padding: 0; }
}
@container (max-width: 720px) {
  .device-readout { display: none; }
}
@container (max-width: 640px) {
  .stage-meta { display: none; }
}
@container (max-width: 560px) {
  .crumb, .crumb-sep { display: none; } /* the title needs the room more than "Apps ›" does */
}

/* Someone else's snapshot app: a strip under the header saying whose it is, centred, the owner first. */
.stage-notice { padding: 12px 16px; color: var(--warning-text); background: var(--warning-tint); border-bottom: 1px solid var(--border); flex: none; }
.stage-notice-text { display: flex; flex-direction: column; align-items: center; gap: 2px; max-width: 64ch; margin: 0 auto; text-align: center; text-wrap: balance; }
.stage-notice-owner { font-size: var(--fs); font-weight: 600; line-height: 1.4; }
.stage-notice-owner > .icon { width: 16px; height: 16px; margin-right: 8px; vertical-align: -3px; color: var(--warning); } /* in the line, so it wraps with the words */
#stage-notice-detail { font-size: var(--fs-sm); line-height: 1.45; color: var(--warning-muted); }
.stage-body { position: relative; flex: 1; min-height: 0; }
/* Over the preview frame while an app loads into it. */
.preview-loading { position: absolute; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: var(--fs-sm); color: var(--muted-foreground); background: var(--preview-ground); }
.preview-loading[hidden] { display: none; }
.viewport { position: absolute; inset: 0; overflow: hidden; background: var(--preview-ground); }
.preview { display: block; width: 100%; height: 100%; border: 0; background: var(--preview-ground); }
.stage-body.is-device { background: var(--muted); }
.stage-body.is-device .viewport {
  inset: auto; left: 50%; top: 50%; transform-origin: center;
  border: 1px solid var(--border); box-shadow: var(--shadow-lg);
}

.device-controls { display: flex; align-items: center; gap: 8px; flex: none; }
.toggle-group { display: inline-flex; gap: 2px; padding: 2px; background: var(--muted); border-radius: var(--radius-md); }
.toggle {
  display: grid; place-items: center; width: 28px; height: 24px; padding: 0;
  color: var(--muted-foreground); background: transparent; border: 0; border-radius: var(--radius-sm); cursor: pointer;
  transition: background-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.toggle .icon { width: 14px; height: 14px; }
.toggle:hover { color: var(--foreground); }
.toggle[aria-pressed="true"] { color: var(--foreground); background: var(--background); box-shadow: var(--shadow-xs); }
.device-readout { font: 400 var(--fs-xs)/1 var(--mono); color: var(--muted-foreground); white-space: nowrap; }
.device-readout:empty { display: none; }
.divider { width: 1px; height: 18px; background: var(--border); flex: none; }
.preview.is-developing { animation: develop 0.8s var(--ease-out) both; }
.pick-hint {
  position: absolute; top: 12px; left: 50%; z-index: 3; transform: translateX(-50%); margin: 0; padding: 6px 12px; white-space: nowrap;
  font-size: var(--fs-sm); color: var(--background); background: var(--foreground); border-radius: 999px; box-shadow: var(--shadow-lg); pointer-events: none;
}
#pick-btn[aria-pressed="true"] { color: var(--primary-foreground); background: var(--primary); border-color: var(--primary); }
#mic-btn[aria-pressed="true"] { color: var(--primary-foreground); background: var(--primary); animation: listening 1.4s ease-out infinite; }
.preview-overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 24px;
  font-size: var(--fs); color: var(--foreground);
  background: color-mix(in srgb, var(--background) 72%, transparent); backdrop-filter: blur(3px);
}
.overlay-card {
  width: min(460px, 100%); max-height: 100%; display: flex; flex-direction: column;
  background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  animation: pop 0.18s var(--ease-out) both;
}
.overlay-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px; font-weight: 500; }
.overlay-icon { display: flex; flex: none; }
.overlay-head .icon { width: 14px; height: 14px; }
.overlay-count { margin-left: auto; font: 400 var(--fs-xs)/1 var(--mono); color: var(--muted-foreground); }
.overlay-calls { overflow-y: auto; min-height: 0; padding: 4px 14px 12px; border-top: 1px solid var(--border); }
.overlay-calls:empty { display: none; }
.call { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; column-gap: 10px; align-items: start; padding: 7px 0; }
.call-tool, .call-detail { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.call-tool { font: 400 var(--fs-sm)/20px var(--mono); }
.call-detail { font-size: var(--fs-sm); line-height: 18px; color: var(--muted-foreground); }
.call-shape { font-family: var(--mono); font-size: var(--fs-xs); }
.call-ms { min-width: 44px; text-align: right; font: 400 var(--fs-xs)/20px var(--mono); font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
.call + .call { border-top: 1px solid var(--border); }
.call-retry { height: 24px; padding: 0 9px; font-size: var(--fs-xs); }
.overlay-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; font-size: var(--fs-sm); color: var(--muted-foreground); border-top: 1px solid var(--border); }
.call .row-icon .icon { width: 14px; height: 14px; }
.call-queued .row-icon { color: var(--muted-foreground); }
.call-done .row-icon { color: var(--foreground); }
.call-failed .row-icon { color: var(--destructive); }
.call-error { display: block; margin-top: 2px; font-size: var(--fs-sm); line-height: 1.45; color: var(--destructive-text); }

/* Building overlay: while Claude writes the app code, a morphing orb (public/js/stage/orb.js)
   over the blurred app or its code, with the progress label beneath. While it is large it
   takes every click, so nothing underneath can be pressed by accident. */
.build-overlay {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 24px;
  color: var(--foreground);
  background: color-mix(in srgb, var(--background) 80%, transparent); backdrop-filter: blur(4px);
  animation: fade 0.45s var(--ease-out) both; transition: opacity 0.5s var(--ease-out);
}
/* The control under the orb that makes it small. */
.build-size { margin-top: 12px; color: var(--muted-foreground); animation: fade 0.4s 0.3s var(--ease-out) both; }
.build-size:hover { color: var(--foreground); }
/* Made small by the person: a pill at the foot of the stage holding the orb, what the AI is
   doing and the control that makes it large again (pressing the pill does the same). */
.build-overlay.is-compact {
  inset: auto auto 16px 50%; transform: translateX(-50%); flex-direction: row; gap: 0; padding: 0 4px 0 2px;
  cursor: pointer;
  background: var(--background); backdrop-filter: none;
  border: 1px solid var(--border); border-radius: 999px; box-shadow: var(--shadow-lg);
}
.build-overlay.is-compact .build-orb { --orb: 46px; margin: -2px -2px -2px 0; }
.build-overlay.is-compact .build-label { flex-direction: row; align-items: baseline; gap: 8px; font-size: var(--fs-sm); white-space: nowrap; }
.build-overlay.is-compact .build-size { width: 28px; margin: 0 0 0 6px; padding: 0; border-radius: 50%; }
.build-overlay.is-compact .build-size-text { display: none; }
.build-overlay .build-label { animation: fade 0.4s 0.2s var(--ease-out) both; }
.build-overlay.is-leaving { opacity: 0; pointer-events: none; } /* fading out: the app is usable again at once */
/* The orb fills about 65% of its canvas (the rest is halo), so the label is pulled up
   into that space to sit just under the orb. */
.build-orb { --orb: min(450px, 62vmin); display: block; width: var(--orb); height: var(--orb); margin-bottom: calc(var(--orb) * -0.13); }
.build-label { display: flex; flex-direction: column; align-items: center; gap: 6px; font-weight: 500; }
.build-meta { font: 400 var(--fs-xs)/1 var(--mono); color: var(--muted-foreground); }
.build-meta:empty { display: none; }

.empty {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 40px 24px; text-align: center;
}
.empty h2 { font: 600 16px/1.3 var(--sans); letter-spacing: -0.01em; text-wrap: balance; }
.empty p { max-width: 46ch; color: var(--muted-foreground); text-wrap: balance; }
.empty .empty-note { margin-top: 14px; font-size: var(--fs-sm); }

/* Ideas to start from, on the empty screen */
/* Ideas to start from (stage/ideas.js): cards in a grid, each with a drawing of the kind of view
   it is (stage/idea-art.js), a name and the request it sends. */
.ideas { width: min(760px, 100%); margin-top: 18px; animation: fade 0.4s var(--ease-out) both; }
.ideas-label { margin: 0 0 10px; font: 500 var(--fs-sm)/1.3 var(--sans); color: var(--muted-foreground); }
.ideas-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.idea {
  display: flex; align-items: flex-start; gap: 12px; width: 100%; height: 100%; padding: 12px; text-align: left; line-height: 1.4;
  color: var(--foreground); background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-xs);
  cursor: pointer; transition: background-color 0.15s, border-color 0.15s;
}
.idea:hover { background: var(--accent); border-color: var(--input); }
.idea-art { flex: none; width: 56px; height: 40px; margin: -2px 0 0 -2px; color: var(--muted-foreground); transition: color 0.15s; }
.idea-art svg { display: block; width: 100%; height: 100%; }
.idea:hover .idea-art { color: var(--foreground); }
.idea-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.idea-title { font-weight: 500; text-wrap: balance; }
.idea-desc { font-size: var(--fs-sm); color: var(--muted-foreground); text-wrap: balance; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* Versions: the earlier versions of the open app, floating over the top right of the preview */
.history {
  position: absolute; top: 10px; right: 10px; z-index: 4; display: flex; flex-direction: column;
  width: min(340px, calc(100% - 20px)); max-height: calc(100% - 20px);
  background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  animation: pop 0.18s var(--ease-out) both;
}
.history-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 8px 0 14px; }
.history-head h2 { font: 600 var(--fs)/1.3 var(--sans); }
.history-desc { padding: 0 14px 10px; font-size: var(--fs-sm); color: var(--muted-foreground); }
.history-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 1px; padding: 6px; border-top: 1px solid var(--border); }
.history-row { display: flex; align-items: flex-start; gap: 2px; border-radius: var(--radius-sm); }
.history-row:hover, .history-row:has(.history-item[aria-current="true"]) { background: var(--sidebar-accent); }
.history-delete { flex: none; margin: 6px 4px 0 0; opacity: 0.55; }
.history-row:hover .history-delete, .history-delete:focus-visible { opacity: 1; }
.history-item {
  display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; padding: 8px; text-align: left;
  color: var(--foreground); background: transparent; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.history-request { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.4; overflow-wrap: anywhere; }
.history-item[aria-current="true"] .history-request { font-weight: 500; }
.history-when { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--muted-foreground); }
.history-foot { display: flex; flex-direction: column; gap: 8px; padding: 10px; border-top: 1px solid var(--border); }
.history-note { font-size: var(--fs-sm); line-height: 1.45; color: var(--muted-foreground); }
.history-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.history-actions .segmented button { height: 24px; padding: 0 10px; font-size: var(--fs-sm); }
#history-btn[aria-pressed="true"] { color: var(--primary-foreground); background: var(--primary); border-color: var(--primary); }

/* ---- Accessibility panel: the audit of the app in the preview (stage/audit.js) ---------- */
.audit { width: min(400px, calc(100% - 20px)); }
.audit-stats { padding: 0 14px 10px; font-size: var(--fs-sm); line-height: 1.45; color: var(--muted-foreground); }
.audit-stats:empty { display: none; }
.audit-body { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 10px 10px; border-top: 1px solid var(--border); }
.audit-section h3 { display: flex; align-items: baseline; gap: 8px; margin: 10px 4px 6px; font: 600 var(--fs-sm)/1.3 var(--sans); }
.audit-sub { font-weight: 400; color: var(--muted-foreground); }
.audit-list { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.audit-item { padding: 8px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.audit-item-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.audit-criteria { margin-left: auto; font: 400 var(--fs-xs)/1 var(--mono); color: var(--muted-foreground); }
.audit-criteria a, .audit-manual a, .audit-foot-note a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.audit-help { margin: 4px 0 6px; font-size: var(--fs-sm); line-height: 1.45; color: var(--muted-foreground); }
.audit-nodes { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.audit-node { display: flex; flex-direction: column; gap: 2px; padding: 4px 6px; border-radius: var(--radius-sm); }
.audit-node:hover, .audit-node:focus-within { background: var(--sidebar-accent); }
.audit-target {
  align-self: flex-start; max-width: 100%; padding: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 400 var(--fs-xs)/1.6 var(--mono); color: var(--foreground); text-align: left; background: none; border: 0; cursor: pointer;
}
.audit-why, .audit-fix { font-size: var(--fs-sm); line-height: 1.45; color: var(--muted-foreground); overflow-wrap: anywhere; }
.audit-fix { color: var(--foreground); }
.audit-more { padding: 2px 6px; font-size: var(--fs-sm); color: var(--muted-foreground); }
.audit-manual { margin: 10px 4px 0; font-size: var(--fs-sm); color: var(--muted-foreground); }
.audit-manual summary { cursor: pointer; font-weight: 600; }
.audit-manual ul { display: flex; flex-direction: column; gap: 3px; margin: 6px 0 0; padding: 0; list-style: none; }
.audit-foot-note { font-size: var(--fs-sm); color: var(--muted-foreground); }
/* Pour's mark beside its name: on the panel's title and in the credit (the toolbar button has it too). */
.audit-title { display: inline-flex; align-items: center; gap: 7px; }
.audit-title .icon { width: 13px; height: 13px; }
.audit-pour { display: inline-flex; align-items: center; gap: 4px; vertical-align: -1px; }
.audit-pour .icon { width: 11px; height: 11px; }
#audit-btn[aria-pressed="true"] { color: var(--primary-foreground); background: var(--primary); border-color: var(--primary); }

/* Preview | Code (code.js): the switch sits between the meta line and the preview sizes.
   In the code view the editor takes the stage under a file bar, and the preview-only
   controls (sizes, pointing) step aside. */
.toggle-text { display: inline-flex; align-items: center; width: auto; padding: 0 9px 0 7px; gap: 5px; font: 500 var(--fs-sm)/1 var(--sans); }
#stage[data-view="code"] .device-controls, #stage[data-view="code"] .viewport, #stage[data-view="code"] .pick-hint { display: none; }
#stage[data-view="code"] .stage-body.is-device { background: var(--background); }
.code-view { position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--background); } /* no z-index: the overlays after it in the markup paint above it */
.code-bar { display: flex; align-items: center; gap: 10px; height: 36px; padding-right: 8px; border-bottom: 1px solid var(--border); flex: none; }
.code-files { display: flex; align-self: stretch; }
.code-file {
  display: inline-flex; align-items: center; padding: 0 14px;
  font: 400 var(--fs-sm)/1 var(--mono); color: var(--muted-foreground);
  background: transparent; border: 0; border-right: 1px solid var(--border); cursor: pointer;
}
.code-file:hover { color: var(--foreground); }
.code-file[aria-selected="true"] { color: var(--foreground); box-shadow: inset 0 -2px 0 var(--foreground); }
/* A file with unsaved changes: a dot after its name. */
.code-file.is-dirty::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 6px; border-radius: 50%; background: currentColor; vertical-align: middle; }
.code-status { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); color: var(--muted-foreground); }
.code-view.is-dirty .code-status::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 7px 1px 0; border-radius: 50%; background: var(--foreground); vertical-align: middle; }
.code-actions { display: flex; align-items: center; gap: 6px; flex: none; }
.code-notice { display: flex; align-items: flex-start; gap: 10px; padding: 8px 8px 8px 14px; font-size: var(--fs-sm); line-height: 1.45; background: var(--muted); border-bottom: 1px solid var(--border); flex: none; }
.code-notice > .icon { flex: none; width: 14px; height: 14px; margin-top: 2px; }
.code-notice-body { flex: 1; min-width: 0; }
.code-notice-list { margin: 2px 0 0; padding-left: 16px; }
.code-editor { flex: 1; min-height: 0; }
.code-loading { position: absolute; inset: 37px 0 0; display: grid; place-items: center; margin: 0; padding: 24px; text-align: center; font-size: var(--fs-sm); color: var(--muted-foreground); background: var(--background); }

/* Claude column */
.ai-col { display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--border); }
.panel-title { display: flex; align-items: center; gap: 8px; }
.panel-title .icon { color: var(--muted-foreground); }
.panel-title h2 { font: 600 var(--fs)/1 var(--sans); }
.panel-sub { margin-left: auto; padding-right: 6px; font-size: var(--fs-sm); color: var(--muted-foreground); }

.log { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px 18px; }
.log-empty { color: var(--muted-foreground); }
.turn + .turn { margin-top: 22px; }
.row { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; gap: 10px; align-items: start; padding: 5px 0; }
.row-icon { display: flex; align-items: center; justify-content: center; height: 20px; color: var(--muted-foreground); }
.row-icon .icon { width: 14px; height: 14px; }
.row-body { min-width: 0; line-height: 20px; overflow-wrap: break-word; }
.row-time { font: 400 var(--fs-xs)/20px var(--mono); color: var(--muted-foreground); }
.row-new { animation: land 0.3s var(--ease-out) both; }

/* The build log is laid out like Claude's own panel. The person's words sit in a box with the
   time above it; the steps that follow are dots on a line down the left, each with a bold name
   and a grey line of what it was; the reply ends the line. Dots are ink when done, blink while
   running, red when failed and grey for thinking and notices. */
.row-user, .row-steer { display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 0; }
.row-user .row-time, .row-steer .row-time { align-self: flex-end; }
.row-user .row-body, .row-steer .row-body { padding: 9px 12px; line-height: 1.5; background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.user-text { white-space: pre-wrap; }
.user-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 6px; }
.user-meta .badge { font-weight: 500; }
.row-steer { margin: 6px 0 6px 26px; }
.row-steer .row-body { padding: 7px 10px; }
.steer-state { display: block; margin-top: 4px; font-size: var(--fs-sm); color: var(--muted-foreground); }

.steps { position: relative; margin-top: 8px; }
.steps::before { content: ""; position: absolute; left: 7.5px; top: 15px; bottom: 10px; width: 1px; background: color-mix(in srgb, var(--foreground) 22%, transparent); }
.step-dot { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--muted-foreground); box-shadow: 0 0 0 3px var(--background); }
.row-ok .step-dot, .row-warn .step-dot { background: var(--foreground); }
.row-fail .step-dot { background: var(--destructive); }
.row-ok:has(.step-io) .step-dot { background: var(--success); } /* a call for data that worked */
.row-pending .step-dot, .row-status .step-dot { background: var(--foreground); animation: blink 1.1s ease-in-out infinite; }
.row-notice .step-dot, .row-thinking .step-dot { background: var(--muted-foreground); }
.row-notice .row-body, .row-thinking .row-body { color: var(--muted-foreground); }
/* A step's time shows over its right edge on hover, so it takes no width from the step. */
.steps .row { position: relative; grid-template-columns: 16px minmax(0, 1fr); }
.steps .row-time { position: absolute; top: 5px; right: 0; padding-left: 8px; background: var(--background); opacity: 0; transition: opacity 0.15s; pointer-events: none; }
.steps .row-steer .row-time { top: 6px; right: 8px; }
.steps .row:hover .row-time { opacity: 1; }
.steps .row:has(.step-io):hover .row-time { opacity: 0; } /* a call's time is in its line's tooltip, clear of its chevron */
.step-head { display: block; }
.step-name { font-weight: 600; overflow-wrap: anywhere; }
.step-desc { margin-left: 2px; color: var(--muted-foreground); }
.step-file { margin-left: 2px; }
.step-sub { display: block; font-size: var(--fs-sm); color: var(--muted-foreground); }
.step-text { display: block; }

/* A call for data folds its IN / OUT box away until its line is clicked. The line looks like any
   other step's; a chevron shows on hover, on focus and while it's open. */
.step-summary { display: flex; align-items: flex-start; gap: 4px; list-style: none; cursor: pointer; border-radius: var(--radius-sm); }
.step-summary .step-head { min-width: 0; }
.step-summary::-webkit-details-marker { display: none; }
.step-summary:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.step-chevron { flex: none; width: 12px; height: 12px; margin-top: 4px; color: var(--muted-foreground); opacity: 0; transition: opacity 0.15s, transform 0.15s; }
.step-summary:hover .step-chevron, .step-summary:focus-visible .step-chevron, .step-io[open] .step-chevron { opacity: 1; }
.step-io[open] .step-chevron { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .step-chevron { transition: none; } }

/* What a call for data sent and what came back, as in Claude's IN / OUT boxes. */
.io { display: block; margin: 6px 0 2px; overflow: hidden; font: 400 var(--fs-sm)/1.55 var(--mono); border: 1px solid var(--border); border-radius: var(--radius-md); }
.io-row { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 8px; padding: 6px 10px; }
.io-row + .io-row { border-top: 1px solid var(--border); }
.io-label { color: var(--muted-foreground); }
.io-text { min-width: 0; font: inherit; }
.io-in { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.io-out { background: var(--muted); }
/* Three lines at most, the last fading out when there's more (the fade sits below a shorter text, out of sight). */
.io-out .io-text { position: relative; display: block; max-height: 4.65em; overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere; }
.io-out .io-text::after { content: ""; position: absolute; left: 0; right: 0; top: 3.4em; height: 1.3em; background: linear-gradient(transparent, var(--muted)); }
.io-out.is-error .io-text { color: var(--destructive-text); }
.io-out { grid-template-columns: 30px minmax(0, 1fr) auto; }
.io-open { width: 24px; height: 24px; margin: -3px -6px -3px 0; color: var(--muted-foreground); }
.io-open .icon { width: 13px; height: 13px; }

/* A call's full output (call-output.js): what was sent, then what came back, each scrolling on its own. */
.dialog-output { width: min(1100px, calc(100vw - 48px)); max-height: min(860px, calc(100vh - 48px)); }
.output { display: flex; flex-direction: column; max-height: inherit; }
.output-head h2, .output .settings-head h2 { font: 600 15px/1.2 var(--mono); overflow-wrap: anywhere; }
.output-body { display: flex; flex-direction: column; gap: 6px; min-height: 0; overflow-y: auto; padding: 12px 20px 16px; }
.output-label { margin-top: 8px; font: 600 var(--fs-sm)/1.3 var(--sans); color: var(--muted-foreground); }
.output-meta { font-size: var(--fs-sm); color: var(--muted-foreground); }
.output-meta:empty { display: none; }
.output-pre {
  margin: 0; padding: 10px 12px; max-height: 220px; overflow: auto; white-space: pre; tab-size: 2;
  font: 400 var(--fs-sm)/1.55 var(--mono); background: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-md);
}
.output-pre:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.output-pre { flex: none; }
.output-out { flex: 1 0 auto; max-height: none; min-height: 160px; }
.output-out.is-error { color: var(--destructive-text); }
.output-out.is-error { white-space: pre-wrap; overflow-wrap: anywhere; }
/* JSON, highlighted in the code view's shades of ink (json.js). */
.json-key { color: var(--foreground); }
.json-string, .json-number { color: var(--code-mid); }
.json-literal { color: var(--foreground); font-weight: 600; }
.json-punct { color: var(--muted-foreground); }
.output-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px 16px; border-top: 1px solid var(--border); }

.status-label { font-weight: 500; }
/* How far a model has got loading in LM Studio. */
.status-progress { display: block; width: 100%; max-width: 240px; height: 4px; margin: 6px 0 3px; appearance: none; border: 0; border-radius: 2px; background: var(--muted); overflow: hidden; }
.status-progress::-webkit-progress-bar { background: var(--muted); border-radius: 2px; }
.status-progress::-webkit-progress-value { background: var(--foreground); border-radius: 2px; transition: width 0.2s; }
.status-progress::-moz-progress-bar { background: var(--foreground); border-radius: 2px; }
.status-meta { display: block; color: var(--muted-foreground); font-size: var(--fs-sm); }
.status-note { display: block; margin-top: 6px; padding: 8px 10px; font-size: var(--fs-sm); line-height: 1.5; color: var(--foreground); background: var(--muted); border-radius: var(--radius-sm); }

/* What the AI writes sits on the line where it wrote it, with a dot of its own. The last thing on the
   line (the status line while the AI works, then the reply) covers the line below its dot, so the
   line stops just above it. */
.reply { position: relative; margin-top: 8px; padding-left: 26px; line-height: 1.6; color: var(--foreground); overflow-wrap: anywhere; }
.reply::before { content: ""; position: absolute; left: 4.5px; top: 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--foreground); box-shadow: 0 0 0 3px var(--background); }
.steps > .reply:not(:has(~ .row, ~ .reply:not([hidden]))), .steps > .row-status, .steps > .turn-end { z-index: 1; background: var(--background); }
.steps > .row-status { position: relative; }
.reply p + p, .reply ul { margin-top: 6px; }
.reply ul { padding-left: 18px; list-style: disc; }
.reply strong { font-weight: 600; }
.turn-error .reply { color: var(--destructive-text); }
.turn-error .reply::before { background: var(--destructive); }
.reply-error { color: var(--destructive-text); }
.reply-error::before { background: var(--destructive); }
.turn-end { position: relative; display: flex; align-items: center; gap: 4px; min-height: 28px; padding: 4px 0 0 26px; }
.turn-foot { font-size: var(--fs-xs); color: var(--muted-foreground); }
.turn-copy { width: 24px; height: 24px; color: var(--muted-foreground); }
.turn-copy .icon { width: 13px; height: 13px; }
.turn-end:not(:has(.turn-foot:not([hidden]), .turn-copy, .turn-retry)) { display: none; } /* nothing to show under this reply */
.turn-retry { margin-left: 4px; }
.turn-end:has(.turn-retry) { flex-wrap: wrap; gap: 8px; padding-top: 8px; }
.turn-end:has(.turn-retry) .turn-retry { margin-left: 0; }

.composer-wrap { flex: none; padding: 0 12px 12px; }
.composer {
  display: flex; flex-direction: column;
  background: var(--background); border: 1px solid var(--input); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs); transition: border-color 0.15s, box-shadow 0.15s;
}
.composer.is-dropping { border-color: var(--ring); border-style: dashed; }
.selection { display: flex; padding: 8px 8px 0; }
.selection-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; height: 26px; padding: 0 3px 0 8px;
  font-size: var(--fs-sm); background: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.selection-chip > .icon { flex: none; width: 13px; height: 13px; color: var(--muted-foreground); }
.selection-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.selection-chip button { display: grid; place-items: center; flex: none; width: 20px; height: 20px; padding: 0; color: var(--muted-foreground); background: none; border: 0; border-radius: 4px; cursor: pointer; }
.selection-chip button:hover { color: var(--foreground); background: var(--accent); }
.selection-chip button:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
.selection-chip button .icon { width: 12px; height: 12px; }
.attachments { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 8px 0; }
.attachment { position: relative; width: 56px; height: 56px; overflow: hidden; background: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.attachment img { display: block; width: 100%; height: 100%; object-fit: cover; }
.attachment-remove {
  position: absolute; top: 3px; right: 3px; display: grid; place-items: center; width: 18px; height: 18px; padding: 0;
  color: var(--background); background: color-mix(in srgb, var(--foreground) 82%, transparent); border: 0; border-radius: 50%; cursor: pointer;
}
.attachment-remove .icon { width: 10px; height: 10px; }
.attachment-remove:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
.row-pick { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; font-weight: 500; }
.row-pick .icon { width: 11px; height: 11px; }
.row-images { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.row-images img { display: block; width: 72px; height: 54px; object-fit: cover; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.composer:focus-within { border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring), 0 0 0 4px color-mix(in srgb, var(--ring) 25%, transparent); }
.composer-input {
  min-height: 44px; max-height: 200px; padding: 10px 12px 4px; resize: none;
  font: 400 var(--fs)/1.5 var(--sans); background: transparent; border: 0;
}
.composer-input:focus { outline: none; }
.composer-input:disabled { cursor: not-allowed; }
.composer-bar { display: flex; align-items: center; gap: 2px; padding: 4px 6px 6px 6px; }
/* The buttons keep their size (Send and Stop stay round); when the bar is short of room the
   model and effort menus give way instead. */
.composer-bar .btn-icon { flex: none; width: 28px; height: 28px; border-radius: var(--radius-sm); }
.composer-bar .select { flex: 0 1 auto; min-width: 0; text-overflow: ellipsis; }
#send-btn, #stop-btn { border-radius: 50%; }
.composer-bar .btn-outline.btn-icon .icon { width: 12px; height: 12px; }


/* ---- Settings ------------------------------------------------------------------ */
.dialog-settings { width: min(560px, calc(100vw - 32px)); max-height: min(760px, calc(100vh - 48px)); }
.settings { display: flex; flex-direction: column; max-height: inherit; }
.settings-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 16px 12px 20px; border-bottom: 1px solid var(--border); }
.settings-head h2 { font: 600 15px/1.2 var(--sans); }
.settings-body { overflow-y: auto; padding: 4px 20px 20px; }
.settings-section { padding: 16px 0; }
.settings-section + .settings-section { border-top: 1px solid var(--border); }
.settings-section h3 { display: flex; align-items: center; gap: 8px; font: 600 var(--fs)/1.3 var(--sans); }
.settings-desc { margin: 2px 0 12px; font-size: var(--fs-sm); color: var(--muted-foreground); }
.settings-section .tool-list { margin: 8px -6px 0; }

.segmented { display: inline-flex; gap: 2px; padding: 3px; background: var(--muted); border-radius: var(--radius-md); }
.segmented button {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px;
  font: 500 var(--fs)/1 var(--sans); color: var(--muted-foreground);
  background: transparent; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.segmented button .icon { width: 14px; height: 14px; }
.segmented button:hover { color: var(--foreground); }
.segmented button[aria-checked="true"] { color: var(--foreground); background: var(--background); box-shadow: var(--shadow-xs); }

.radio-list { display: flex; flex-direction: column; gap: 8px; }
.radio-card {
  display: flex; align-items: flex-start; gap: 10px; padding: 12px;
  border: 1px solid var(--border); border-radius: var(--radius-md); cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}
.radio-card:hover { background: var(--accent); }
.radio-card:has(input:checked) { border-color: var(--foreground); }
.radio-card.is-disabled { cursor: not-allowed; }
.radio-card.is-disabled:hover { background: transparent; }
.radio-card.is-disabled .radio-text { opacity: 0.6; }
.radio-card input {
  appearance: none; flex: none; width: 16px; height: 16px; margin: 1px 0 0;
  border: 1px solid var(--switch-off); border-radius: 50%; background: var(--background); cursor: inherit;
}
.radio-card input:checked { border-color: var(--primary); background: radial-gradient(circle, var(--primary) 0 4px, var(--background) 4.5px); }
.radio-card input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.radio-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.radio-title { display: flex; align-items: center; gap: 6px; font-weight: 500; }
.radio-desc { font-size: var(--fs-sm); color: var(--muted-foreground); line-height: 1.45; }
.radio-desc a { color: var(--foreground); text-decoration: underline; text-underline-offset: 2px; }
.radio-desc a:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* Design check rows in the build log */
.check-findings { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; font-size: var(--fs-sm); color: var(--muted-foreground); }
.check-findings span { overflow-wrap: anywhere; }

/* ---- Claude not connected -------------------------------------------------------- */
.ai-alert {
  margin-bottom: 8px; padding: 12px;
  background: var(--background); border: 1px solid color-mix(in srgb, var(--destructive) 45%, var(--border)); border-radius: var(--radius-lg);
}
.ai-alert-head { display: flex; align-items: center; gap: 8px; color: var(--destructive-text); }
.ai-alert-head .icon { width: 15px; height: 15px; }
.ai-alert-head h3 { font: 600 var(--fs)/1.3 var(--sans); }
.ai-alert-why { margin: 6px 0 10px; font-size: var(--fs-sm); line-height: 1.5; color: var(--muted-foreground); }
.ai-alert-steps { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; padding-left: 18px; list-style: decimal; font-size: var(--fs-sm); line-height: 1.5; }
.ai-alert-steps li::marker { color: var(--muted-foreground); }
.cmd {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%; margin-top: 4px;
  padding: 2px 2px 2px 8px; font: 400 var(--fs-sm)/1.6 var(--mono);
  background: var(--muted); border-radius: var(--radius-sm);
}
.cmd code { font-size: inherit; overflow-wrap: anywhere; }
.cmd .btn { width: 22px; height: 22px; }
.cmd .btn .icon { width: 12px; height: 12px; }
.ai-alert-actions { display: flex; align-items: center; gap: 10px; }
.ai-alert-status { font-size: var(--fs-sm); color: var(--muted-foreground); }
.ai-off { color: var(--destructive-text); }

/* ---- The dock (ask-dock.js): what needs an answer, in the prompt box's place ---------------
   A card with a stronger edge and shadow than the log, a kicker with a blinking dot saying who
   asks, a step count, the question, and its answers as numbered rows: the number is the key that
   picks it, filled once chosen. The radio buttons behind the rows are hidden; the row shows
   their focus. */
.ask-dock { animation: land 0.2s var(--ease-out) both; }
.ask {
  display: flex; flex-direction: column; gap: 10px; max-height: min(72vh, 680px); overflow-y: auto;
  padding: 14px 14px 12px; background: var(--background);
  border: 1px solid var(--foreground); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
}
.ask-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font: 600 var(--fs-xs)/1.2 var(--sans); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-foreground); }
.ask-kicker::before { content: ""; display: inline-block; width: 6px; height: 6px; margin-right: 7px; border-radius: 50%; background: var(--foreground); vertical-align: 1px; animation: blink 1.1s ease-in-out infinite; }
.ask-count { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; letter-spacing: 0; text-transform: none; }
.ask-dots { display: inline-flex; gap: 3px; }
.ask-dots span { width: 6px; height: 6px; border-radius: 50%; background: var(--border); }
.ask-dots .is-done { background: var(--foreground); }
.ask-title { font: 600 15px/1.35 var(--sans); outline: none; overflow-wrap: anywhere; }
.ask-text { line-height: 1.55; overflow-wrap: anywhere; }
.ask-text p + p, .ask-text ul { margin-top: 6px; }
.ask-text ul { padding-left: 18px; list-style: disc; }
.ask-text strong { font-weight: 600; }
.ask .radio-list { gap: 6px; }
.ask .radio-card { align-items: flex-start; padding: 9px 10px; }
.ask .radio-title { flex-wrap: wrap; }
.ask-option > input[type="radio"] { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.ask-option:has(> input[type="radio"]:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }
.ask-key {
  display: inline-grid; place-items: center; flex: none; min-width: 20px; height: 20px; margin-top: -1px;
  font: 500 var(--fs-xs)/1 var(--mono); color: var(--muted-foreground); border: 1px solid var(--border); border-radius: 5px;
}
.ask-option:has(> input:checked) .ask-key { color: var(--background); background: var(--foreground); border-color: var(--foreground); }
.ask-other { align-items: center; }
.ask-hint { font-size: var(--fs-sm); line-height: 1.45; color: var(--muted-foreground); }
.ask-remember { display: flex; align-items: center; gap: 7px; font-size: var(--fs-sm); color: var(--muted-foreground); cursor: pointer; }
.ask-remember input { margin: 0; accent-color: var(--primary); }
.ask-review { display: flex; flex-direction: column; gap: 6px; padding-left: 18px; list-style: decimal; line-height: 1.5; }
.ask-review strong { margin-right: 6px; font-weight: 600; }
.ask-review span { color: var(--muted-foreground); }
.ask-extra { margin: -4px 0 -2px -10px; }
.ask-extra .btn { color: var(--muted-foreground); }
.ask-extra .btn:hover { color: var(--foreground); }
.ask-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding-top: 2px; }

/* ---- The AI's questions, as rows in the build log once answered (log-rows.js) ---------- */
.answer { display: block; margin-top: 2px; font-weight: 400; color: var(--muted-foreground); font-size: var(--fs-sm); }
/* An answer of one's own in the dock: a row that takes typed words. */
.round-own-row { align-items: center; }
.round-own-row:focus-within { border-color: var(--foreground); box-shadow: 0 0 0 1px var(--foreground); }
.round-own-row .round-own {
  appearance: none; flex: 1; min-width: 0; width: auto; height: 20px; margin: 0; padding: 0;
  font: inherit; color: var(--foreground); background: transparent; border: 0; border-radius: 0; outline: none; cursor: text;
}
.round-own-row .round-own::placeholder { color: var(--muted-foreground); }
.round-asked { margin-top: 2px; font-weight: 400; font-size: var(--fs-sm); color: var(--muted-foreground); }
.round-asked summary { width: fit-content; cursor: pointer; }
.round-asked summary:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.round-asked ol { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 4px; padding-left: 18px; list-style: decimal; line-height: 1.5; }
.round-asked strong { font-weight: 600; color: var(--foreground); }
.round-asked-rec { display: block; }
.round-answer { white-space: pre-line; }

/* ---- Dialog & toasts --------------------------------------------------------------- */
.dialog {
  width: min(420px, calc(100vw - 32px)); padding: 0;
  color: var(--foreground); background: var(--background);
  border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.dialog::backdrop { background: var(--overlay); }
.dialog form { display: flex; flex-direction: column; gap: 20px; padding: 20px; }
.dialog-message { font: 500 14px/1.5 var(--sans); }
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }
.dialog[open] { animation: pop 0.18s var(--ease-out) both; }

.toasts { position: fixed; right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 8px; z-index: 10; pointer-events: none; }
/* Toasts are solid blocks of colour: the interface's colours inverted (Charcoal on the light
   theme, Pale Grey on the dark), so they stand off every surface they land on, or Solid Red
   for an error. */
.toast {
  pointer-events: auto; width: min(360px, calc(100vw - 32px));
  padding: 12px 14px; font-size: var(--fs);
  color: var(--primary-foreground); background: var(--primary);
  border: 1px solid var(--primary); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  animation: land 0.25s var(--ease-out) both;
}
.toast-error { color: #FFFFFF; background: var(--destructive-solid); border-color: var(--destructive-solid); }
.toast a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.toast a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* ---- Splash ------------------------------------------------------------------------ */
/* Over the page from the first paint until its state, apps and Claude status are in: the
   building orb (public/js/stage/orb.js) above the sidebar's wordmark, at the same size,
   and what the page is waiting for, on a frost that lets the page show through as it
   fills in. The orb fills about 65% of its canvas, so the wordmark is pulled up under
   it, and its halo is faded out before the canvas edge, which would otherwise show. */
/* ---- The gate (core/gate.js): over the page until the browser is signed in ------------------ */
.gate { --orb: min(1100px, 82vw); position: fixed; inset: 0; z-index: 9; display: grid; place-items: center; padding: 24px; background: var(--sidebar); }
.gate[hidden] { display: none; }
/* A card in the inset's style; the orb is pinned to its right edge and clipped by it. */
.gate-card {
  position: relative; overflow: hidden; display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: center; gap: 32px;
  width: min(960px, 100%); min-height: min(600px, 100%); padding: 56px;
  background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-sm);
}
.gate-text { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; max-width: 420px; }
.gate-text .brand-row { margin: 0 0 20px -6px; }
.gate h1 { font: 600 24px/1.2 var(--sans); letter-spacing: -0.02em; text-wrap: balance; }
.gate p { max-width: 44ch; color: var(--muted-foreground); text-wrap: balance; }
.gate-cta { height: 36px; margin-top: 10px; padding: 0 18px; font-size: var(--fs); }
.gate-note { color: var(--destructive-text); font-size: var(--fs-sm); }
.gate-note[hidden] { display: none; }
.gate-status { min-height: 18px; font-size: var(--fs-sm); color: var(--muted-foreground); }
/* Opening: the wordmark and what the page is checking. The welcome rises in once the state is known. */
.gate-copy { display: contents; }
.gate.is-opening .gate-copy { display: none; }
.gate:not(.is-opening) .gate-status { display: none; }
.gate:not(.is-opening) .gate-copy > * { animation: rise 0.4s var(--ease-out) both; }
.gate-orb { position: absolute; right: -46%; top: 50%; transform: translateY(-50%); display: block; width: var(--orb); height: var(--orb); mask-image: radial-gradient(closest-side, #000 80%, transparent 100%); pointer-events: none; }
/* A phone: one centred column, the orb hanging from the top of the screen, the button full width. */
@media (max-width: 900px) {
  .gate { --orb: min(640px, 150vw); padding: 0; }
  .gate-card { grid-template-columns: 1fr; align-content: start; gap: 0; min-height: 100%; padding: calc(var(--orb) * 0.56) 24px calc(24px + env(safe-area-inset-bottom)); border: 0; border-radius: 0; box-shadow: none; }
  .gate-orb { right: auto; top: calc(var(--orb) * -0.3); left: 50%; transform: translateX(-50%); }
  .gate-text { align-items: center; max-width: 420px; margin: 0 auto; text-align: center; }
  .gate-text .brand-row { margin: 0 0 16px; }
  .gate h1 { font-size: 22px; }
  .gate-cta { width: 100%; max-width: 320px; justify-content: center; margin-top: 14px; }
}
/* Through the gate: the card grows into the work surface and the wordmark glides to the sidebar's
   (gate.js names them for the transition). A beat after the surface starts to grow, the app list
   fades in from the left and the AI panel from the right; the rest crossfades. On the way back
   the two fade out first. */
::view-transition-group(*) { animation-duration: 0.6s; animation-timing-function: var(--ease-out); }
::view-transition-old(root) { animation-duration: 0.35s; }
/* The surface: a solid, rounded, clipped box grows from the card into the work surface. Its two
   images keep their own size inside it (nothing stretches), the card's copy fades out fast and
   the surface's content comes in late, so the two never overlap. The box is the group, not the
   image pair: the pair blends its images additively against its own backdrop, and a background
   there would wash the incoming image out to white. */
::view-transition-group(surface) { overflow: clip; border-radius: var(--radius-xl); background: var(--background); outline: 1px solid var(--border); outline-offset: -1px; box-shadow: var(--shadow-sm); }
::view-transition-old(surface), ::view-transition-new(surface) { object-fit: none; object-position: top left; }
::view-transition-old(surface) { animation-duration: 0.2s; }
::view-transition-new(surface) { animation-delay: 0.25s; animation-duration: 0.35s; }
/* The wordmark keeps its size on the way (its box is the sidebar's full width at one end and the
   text's at the other) and stays above the app list, which would otherwise paint over it. */
::view-transition-old(brand), ::view-transition-new(brand) { object-fit: none; object-position: left center; }
/* The wordmark looks the same at both ends, so it moves as one image rather than crossfading. */
::view-transition-old(brand) { animation: none; opacity: 0; }
::view-transition-new(brand) { animation: none; opacity: 1; }
::view-transition-group(brand) { z-index: 1; }
::view-transition-new(sidebar):only-child { animation: 0.5s var(--ease-out) 0.2s both fade, 0.5s var(--ease-out) 0.2s both from-left; }
::view-transition-new(chat):only-child { animation: 0.5s var(--ease-out) 0.3s both fade, 0.5s var(--ease-out) 0.3s both from-right; }
::view-transition-old(sidebar):only-child, ::view-transition-old(chat):only-child { animation: 0.3s var(--ease-out) both fade-out; }

/* ---- Motion ------------------------------------------------------------------------ */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
@keyframes blink { 50% { opacity: 0.25; } }
@keyframes land { from { opacity: 0; transform: translateY(4px); } }
@keyframes pop { from { opacity: 0; transform: scale(0.97); } }
@keyframes fade { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes from-left { from { transform: translateX(-16px); } }
@keyframes from-right { from { transform: translateX(16px); } }
@keyframes listening { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 45%, transparent); } 100% { box-shadow: 0 0 0 8px transparent; } }
@keyframes develop { from { opacity: 0; clip-path: inset(0 0 100% 0); } to { opacity: 1; clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---- Narrow screens ---------------------------------------------------------------- */
/* ---- Phones and small tablets: the stage is the screen, and the panels slide over it ------- */
@media (max-width: 900px) {
  .panel-gutter { display: none; } /* the AI panel is a sheet from the bottom here, not a column */
  .shell { display: block; height: 100%; height: 100dvh; }
  .inset { display: block; height: 100%; margin: 0; border: 0; border-radius: 0; box-shadow: none; }
  .stage-col { height: 100%; }
  .stage-body { flex: 1; min-height: 0; }
  .col-header { height: auto; min-height: var(--header-h); flex-wrap: wrap; padding: 8px 10px; }
  .stage-col > .col-header { padding-top: calc(8px + env(safe-area-inset-top)); }
  .panel-divider, .device-readout { display: none; }
  .sidebar-close, .panel-close { display: inline-flex; }
  .sheet-handle { display: block; flex: none; width: 36px; height: 4px; margin: 8px auto 0; border-radius: 2px; background: var(--border); }
  /* The apps menu: a drawer from the left, over the stage. */
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 8;
    width: min(300px, 85vw); padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom);
    border-right: 1px solid var(--border); box-shadow: var(--shadow-lg);
  }
  :root[data-sidebar="closed"] .sidebar { transform: translateX(calc(-100% - 24px)); box-shadow: none; }
  /* The AI panel: a sheet from the bottom, the composer at its foot. It is sized from the
     visible part of the page (sliding.js keeps --vv-height and --vv-bottom), so when the
     keyboard comes up on iOS and covers the page's foot, the sheet lifts above it. */
  .ai-col {
    position: fixed; right: 0; bottom: var(--vv-bottom, 0px); left: 0; z-index: 8;
    height: min(calc(var(--vv-height, 100dvh) * 0.85), calc(var(--vv-height, 100dvh) - 56px));
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--background); border: 1px solid var(--border); border-bottom: 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0; box-shadow: var(--shadow-lg);
  }
  :root[data-panel="closed"] .ai-col { transform: translateY(calc(100% + 24px)); box-shadow: none; }
  /* A finger pulling a panel moves it directly; let go short of the way and it springs back. */
  .sheet-handle, .ai-col > .col-header { touch-action: none; }
  /* Everything in the drawer, its scrolling list included: a sideways swipe stays a pull. */
  .sidebar, .sidebar * { touch-action: pan-y; }
  .sidebar.is-pulled, .ai-col.is-pulled { transition: none; }
  .sidebar.is-settling, .ai-col.is-settling { transition: transform var(--fold); }
  .log, .sidebar-content { overscroll-behavior: contain; }
  .ai-col > .col-header { height: 40px; min-height: 0; flex-wrap: nowrap; padding: 0 8px 0 16px; }
  .panel-close { margin-left: 4px; }
  .panel-sub { padding-right: 0; }
  .scrim { display: block; position: fixed; inset: 0; z-index: 7; background: var(--overlay); }
  .scrim[hidden] { display: none; }
  /* Over the preview, the side panels take the width they can. */
  .history, .audit { top: 8px; right: 8px; width: min(400px, calc(100% - 16px)); max-height: calc(100% - 16px); }
  .toasts { right: 16px; left: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 10; }
  .toast { width: auto; }
}
@media (max-width: 600px) {
  #device-toggles { display: none; } /* the preview is already the phone */
}
/* Touch: targets a little larger. Text fields keep their size: the viewport's fixed scale
   (index.html) stops iOS zooming the page to focus one, which is what 16px fields were for. */
/* A touch screen in a browser tab, where the page can zoom: iOS zooms into any field under 16px
   when it is tapped, so fields take 16px there. Added to the Home Screen the scale is fixed. */
@media (pointer: coarse) and (display-mode: browser) {
  input, textarea, select { font-size: 16px; }
}
@media (pointer: coarse) {
  .btn-sm { height: 32px; }
  .btn-sm.btn-icon, .actions .btn-sm:not(.btn-outline-danger) { width: 32px; }
  .composer-bar .btn-icon { width: 32px; height: 32px; }
  .menu-item { min-height: 36px; }
}
