:root {
  --frame-topbar: 56px;
  --app-viewport-height: 100svh;
  --left-panel-width: 292px;
  --right-panel-width: 340px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
}

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/* Data-driven simulation surfaces. Domain meaning is supplied by adapters. */
.zc-spatial-surface,.zc-master-detail-page,.zc-plan-review,.zc-activity-report{display:grid;height:100%;min-height:0;grid-template-rows:auto minmax(0,1fr);gap:var(--space-3);padding:var(--space-4);overflow:hidden;background:var(--app-bg);color:var(--app-text)}
.zc-spatial-surface>header,.zc-master-detail-page>header{display:flex;justify-content:space-between;gap:var(--space-4);align-items:end}.zc-spatial-surface h1,.zc-master-detail-page h1,.zc-plan-review h1,.zc-activity-report h1,.zc-title-surface h1{margin:0}.zc-spatial-surface header p,.zc-master-detail-page header p,.zc-plan-review>header p,.zc-activity-report>header p,.zc-title-surface article>p{margin:0;color:var(--app-accent);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase}.zc-spatial-surface header span,.zc-master-detail-page header span,.zc-plan-review>header span,.zc-activity-report>header span{color:var(--app-text-muted);font-size:.82rem}.zc-spatial-surface nav,.zc-master-detail-page nav,.zc-master-detail nav,.zc-plan-review footer,.zc-activity-report footer,.zc-title-surface nav{display:flex;flex-wrap:wrap;gap:var(--space-2)}
.zc-spatial-stage{position:relative;min-height:0;overflow:hidden;border:1px solid var(--app-border);border-radius:var(--app-radius-lg);background:var(--app-surface-muted)}.zc-spatial-background,.zc-spatial-layer{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.zc-spatial-layer{pointer-events:none}.zc-spatial-markers{position:absolute;inset:0}.zc-spatial-marker{position:absolute;left:var(--zc-marker-x);top:var(--zc-marker-y);display:grid;justify-items:center;gap:2px;transform:translate(-50%,-50%);border:0;background:transparent;color:var(--app-text);cursor:pointer}.zc-spatial-marker>span{display:grid;width:28px;height:28px;place-items:center;border:2px solid var(--app-border-strong);border-radius:50%;background:var(--app-surface);box-shadow:var(--app-shadow)}.zc-spatial-marker>strong{max-width:130px;padding:3px 6px;border-radius:4px;background:color-mix(in srgb,var(--app-surface) 88%,transparent);font-size:.7rem;white-space:nowrap}.zc-spatial-marker[aria-current="true"]>span{border-color:var(--app-accent);transform:scale(1.16)}.zc-spatial-marker:disabled{opacity:.42;cursor:not-allowed}.zc-spatial-detail{position:absolute;right:var(--space-3);bottom:var(--space-3);z-index:3;width:min(410px,calc(100% - var(--space-6)));overflow:hidden;border:1px solid var(--app-border);border-radius:var(--app-radius-lg);background:color-mix(in srgb,var(--app-surface) 94%,transparent);box-shadow:var(--app-shadow)}.zc-spatial-detail>img{width:100%;height:140px;object-fit:cover}.zc-spatial-detail>div{padding:var(--space-3)}.zc-spatial-detail h2{margin:0 0 var(--space-2)}.zc-spatial-detail p{margin:0;color:var(--app-accent);font-size:.7rem}.zc-spatial-detail span{color:var(--app-text-muted);font-size:.8rem}.zc-shared-badges,.zc-spatial-legend{display:flex;flex-wrap:wrap;gap:var(--space-2)}.zc-shared-badges{margin:var(--space-2) 0}.zc-shared-badges small,.zc-spatial-legend span{padding:4px 7px;border:1px solid var(--app-border);border-radius:999px}.zc-spatial-legend{position:absolute;left:var(--space-3);bottom:var(--space-3);padding:var(--space-2);background:color-mix(in srgb,var(--app-surface) 90%,transparent)}
.zc-master-detail-layout{display:grid;grid-template-columns:minmax(210px,300px) minmax(0,1fr);gap:var(--space-3);min-height:0}.zc-master-list,.zc-master-detail{min-height:0;overflow:auto;border:1px solid var(--app-border);border-radius:var(--app-radius-lg);background:var(--app-surface)}.zc-master-list{display:flex;flex-direction:column;padding:var(--space-2)}.zc-master-list button{display:grid;grid-template-columns:48px 1fr auto;gap:var(--space-2);align-items:center;padding:var(--space-2);border:1px solid transparent;border-radius:var(--app-radius);background:transparent;color:var(--app-text);text-align:left}.zc-master-list button[aria-current="true"]{border-color:var(--app-accent);background:var(--app-surface-muted)}.zc-master-list img,.zc-master-mark{display:grid;width:46px;height:46px;place-items:center;object-fit:cover;border-radius:var(--app-radius);background:var(--app-surface-muted)}.zc-master-list strong,.zc-master-list small{display:block}.zc-master-list small{color:var(--app-text-muted)}.zc-master-detail{padding:var(--space-4)}.zc-master-hero{width:min(180px,35%);max-height:220px;float:left;margin:0 var(--space-4) var(--space-3) 0;object-fit:cover}.zc-master-detail header p{margin:0;color:var(--app-accent)}.zc-master-detail header h2{margin:var(--space-1) 0}.zc-master-detail header span{color:var(--app-text-muted)}.zc-master-sections{clear:both;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--space-3);padding-top:var(--space-3)}.zc-master-sections section{padding:var(--space-3);border:1px solid var(--app-border);border-radius:var(--app-radius)}.zc-master-sections h3{margin:0 0 var(--space-2)}.zc-master-sections section>div{display:flex;justify-content:space-between;gap:var(--space-3);padding:6px 0;border-top:1px solid var(--app-border)}
.zc-plan-review,.zc-activity-report{grid-template-rows:auto auto minmax(0,1fr) auto}.zc-plan-summary,.zc-report-deltas{display:flex;flex-wrap:wrap;gap:var(--space-2)}.zc-plan-summary span,.zc-report-deltas article{padding:var(--space-2) var(--space-3);border:1px solid var(--app-border);border-radius:var(--app-radius);background:var(--app-surface)}.zc-plan-scroll,.zc-report-scroll{min-height:0;overflow:auto}.zc-plan-warnings{padding:var(--space-3);border:1px solid var(--app-danger);border-radius:var(--app-radius)}.zc-plan-warnings p{margin:0}.zc-plan-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--space-3);margin-top:var(--space-3)}.zc-plan-groups>section{padding:var(--space-3);border:1px solid var(--app-border);border-radius:var(--app-radius-lg);background:var(--app-surface)}.zc-plan-groups h2{margin:0}.zc-plan-groups header span{color:var(--app-text-muted);font-size:.8rem}.zc-plan-groups article{display:grid;grid-template-columns:1fr auto;gap:var(--space-2);padding:var(--space-2) 0;border-top:1px solid var(--app-border)}.zc-plan-groups article div span,.zc-plan-groups article small{display:block;color:var(--app-text-muted);font-size:.75rem}.zc-report-deltas{margin-bottom:var(--space-3)}.zc-report-deltas article span,.zc-report-deltas article strong{display:block}.zc-report-results{display:grid;gap:var(--space-2)}.zc-report-results article{display:grid;grid-template-columns:100px 1fr;gap:var(--space-3);padding:var(--space-3);border:1px solid var(--app-border);border-radius:var(--app-radius);background:var(--app-surface)}.zc-report-results h2,.zc-report-results p{margin:0}.zc-report-results p,.zc-report-results small{color:var(--app-text-muted)}
.zc-title-surface{position:relative;width:100%;height:100%;overflow:hidden;background:var(--app-bg);color:var(--app-text)}.zc-title-surface>img,.zc-title-shade{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.zc-title-shade{background:linear-gradient(90deg,color-mix(in srgb,var(--app-bg) 96%,transparent),color-mix(in srgb,var(--app-bg) 58%,transparent) 52%,transparent),linear-gradient(0deg,color-mix(in srgb,var(--app-bg) 75%,transparent),transparent 60%)}.zc-title-surface article{position:absolute;left:clamp(24px,7vw,100px);top:50%;display:grid;width:min(620px,calc(100% - 48px));gap:var(--space-2);transform:translateY(-50%)}.zc-title-surface h1{font-size:clamp(2.8rem,8vw,6rem)}.zc-title-surface article>span{color:var(--app-text-muted);line-height:1.6}.zc-shared-primary{border-color:var(--app-accent)!important;background:var(--app-accent)!important;color:var(--app-accent-contrast,#fff)!important}.zc-shared-empty{margin:auto;color:var(--app-text-muted)}
@media(max-width:700px){.zc-spatial-surface,.zc-master-detail-page,.zc-plan-review,.zc-activity-report{padding:var(--space-2)}.zc-spatial-surface>header,.zc-master-detail-page>header{align-items:stretch;flex-direction:column}.zc-spatial-detail{position:absolute;right:var(--space-2);bottom:var(--space-2);left:var(--space-2);width:auto;max-height:48%;overflow:auto}.zc-spatial-detail>img{height:90px}.zc-spatial-legend{display:none}.zc-master-detail-layout{grid-template-columns:1fr;grid-template-rows:minmax(120px,34%) minmax(0,1fr)}.zc-master-list{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(180px,70%);overflow:auto}.zc-master-hero{width:100px}.zc-plan-groups{grid-template-columns:1fr}.zc-report-results article{grid-template-columns:1fr}.zc-title-surface article{left:24px}.zc-title-surface h1{font-size:clamp(2.5rem,16vw,4.5rem)}}
.zc-spatial-marker>span>img{width:100%;height:100%;object-fit:contain}.zc-spatial-detail-section{display:grid;gap:3px;margin-top:var(--space-2);padding-top:var(--space-2);border-top:1px solid var(--app-border)}.zc-spatial-detail-section small{display:block;color:var(--app-text-muted)}

body {
  margin: 0;
  min-width: 320px;
  min-height: 0;
  background: var(--app-bg);
  color: var(--app-text);
  font: 14px/1.45 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  color: inherit;
}

.loading-spinner {
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--app-border);
  border-top-color: var(--app-accent);
  border-radius: 50%;
  animation: agentbridge-spin 0.8s linear infinite;
}

.session-working-spinner { animation: agentbridge-spin 0.9s linear infinite; transform-origin: center; }
.session-error-icon { color: var(--app-danger); }
.session-approval-icon { color: var(--app-warning); }

/* Agent quota panel. The meter is only shown when the provider reported a real
   remaining percentage; otherwise the row says so in words rather than drawing a
   bar that would imply a measurement we do not have. */
.zc-agent-usage { display: grid; gap: var(--space-2); padding: var(--space-3); border-top: 1px solid var(--app-border); }
.zc-agent-usage:empty { display: none; }
.zc-usage-head { display: flex; align-items: center; justify-content: space-between; }
.zc-usage-head strong { font-size: .9rem; }
.zc-usage-row { display: grid; gap: 6px; padding: var(--space-2); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface); min-width: 0; }
.zc-usage-row header { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); min-width: 0; }
.zc-usage-row header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zc-usage-row header span { flex: 0 0 auto; font-size: .75rem; color: var(--app-text-muted); }
.zc-usage-note { margin: 0; font-size: .78rem; color: var(--app-text-muted); overflow-wrap: anywhere; }
.zc-usage-note strong { color: var(--app-text); }
.zc-usage-meter { block-size: 6px; border-radius: 999px; background: var(--app-surface-muted); overflow: hidden; }
.zc-usage-meter > span { display: block; block-size: 100%; background: var(--app-success, var(--app-accent)); }
.zc-usage-meter[data-level="low"] > span { background: var(--app-warning); }
.zc-usage-meter[data-level="critical"] > span { background: var(--app-danger); }
/* A limiter stop is temporary and self-clearing, so it reads as a warning with a
   retry time rather than as a failure. */
.zc-usage-limit { margin: 0; padding: 6px 8px; border-radius: 6px; font-size: .78rem;
  border: 1px solid color-mix(in srgb, var(--app-warning) 55%, var(--app-border));
  background: color-mix(in srgb, var(--app-warning) 12%, var(--app-surface));
  color: color-mix(in srgb, var(--app-warning) 75%, var(--app-text)); overflow-wrap: anywhere; }
.zc-usage-row[data-limited="true"] { border-color: color-mix(in srgb, var(--app-warning) 50%, var(--app-border)); }
.session-sending-icon { color: var(--app-accent); }
.session-waiting-icon { color: var(--app-warning, #d69b39); }
@keyframes agentbridge-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .loading-spinner,.session-working-spinner { animation: none; } }

.app-shell {
  height: var(--app-viewport-height);
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-rows: var(--frame-topbar) 1fr;
  grid-template-areas:
    "topbar"
    "primary";
}

.topbar {
  grid-area: topbar;
  position: sticky;
  top: 0;
  z-index: 70;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--frame-topbar);
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--app-border);
  background: color-mix(in srgb, var(--app-surface) var(--zc-topbar-opacity, 78%), transparent);
  backdrop-filter: blur(14px) saturate(112%);
}

.title-block,
.panel-head div,
.page-bar-section {
  min-width: 0;
  display: grid;
}

.title-block strong,
.title-block span,
.nav-item strong,
.nav-item small,
.metric-card strong,
.metric-card span,
.template-list-item strong,
.template-list-item span:not(.item-mark, .item-icon, .status-pill),
.template-grid-card strong,
.template-grid-card span,
.template-thumbnail-card strong,
.template-thumbnail-card span,
.template-tree-item strong,
.template-tree-item span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.title-block span,
.panel-head span,
.eyebrow,
.muted,
.nav-item small,
.agent-meta,
.activity-list span {
  color: var(--app-text-muted);
}

.topbar-actions,
.panel-head,
.sheet-head,
.dialog-head,
.local-actions,
.card-head,
.agent-actions,
.play-controls,
.page-bar,
.page-toolbar,
.page-bar-actions,
.view-actions,
.view-switch {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.topbar-actions,
.local-actions,
.panel-head,
.dialog-head,
.card-head,
.page-bar,
.page-toolbar {
  justify-content: space-between;
}

.page-bar-actions,
.view-actions,
.view-switch,
.agent-actions {
  flex-wrap: wrap;
}

.icon-button,
.text-button,
.nav-item,
.context-tabs button,
.side-tabs button,
.view-switch button,
.command-list button {
  border: 1px solid var(--app-border);
  background: var(--app-surface);
  color: var(--app-text);
}

.icon-button {
  inline-size: 36px;
  block-size: 36px;
  display: inline-grid;
  place-items: center;
  border-radius: var(--app-radius);
}

.icon-button svg,
.button-icon svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.text-button,
.context-tabs button,
.side-tabs button,
.view-switch button,
.command-list button {
  min-height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--app-radius);
}

.primary-action {
  border-color: var(--app-accent);
  background: var(--app-accent);
  color: var(--app-bg);
}

/* The attachment source picker ("+" button in the composer) is mounted as a
   direct child of <body>, outside the app shell's own layout, so without an
   explicit overlay position it rendered in-flow (effectively invisible). */
.attachment-source-layer {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: var(--space-4);
}

.attachment-source-backdrop {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgb(0 0 0 / 45%);
  cursor: pointer;
}

.attachment-source-dialog {
  position: relative;
  z-index: 1;
  width: min(360px, 100%);
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius-lg);
  background: var(--app-surface, #17212b);
  color: var(--app-text, #f4f7fb);
  box-shadow: var(--app-shadow);
}

.attachment-source-list {
  display: grid;
  gap: var(--space-2);
}

.attachment-source-button {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface, #17212b);
  color: var(--app-text, #f4f7fb);
  text-align: start;
  cursor: pointer;
}

.attachment-source-button:hover,
.attachment-source-button:focus-visible {
  background: var(--app-accent-soft);
  border-color: var(--app-accent);
}

.attachment-source-button svg {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.attachment-source-button span {
  display: grid;
  gap: 2px;
}

.attachment-source-button small {
  color: var(--app-text-muted, #c8d1dc);
}

.primary {
  grid-area: primary;
  min-width: 0;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  padding: var(--space-4);
}

.session-actions { display:flex; align-items:center; gap:var(--space-2); }
.session-actions .session-new-button { min-height:34px; padding:5px 14px; line-height:1.2; }
.session-actions .session-search-button { inline-size:34px; block-size:34px; flex:0 0 34px; }
.session-actions .session-search-button svg { width:22px; height:22px; stroke-width:2.2; }

.workspace-heading,
.page-host {
  width: min(1180px, 100%);
  margin: 0 auto;
}

.page-host {
  min-height: 100%;
  height: 100%;
}

/* AgentBridge still mounts its product regions as direct children of the
   shared primary slot.  Give the timeline the remaining row explicitly so
   percentage-height narrative pages have a real containing block. */
.app-shell[data-app-id="agentbridge"] .primary {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  align-content: stretch;
}

.app-shell[data-app-id="agentbridge"] .session-header { grid-row: 1; }

.app-shell[data-app-id="agentbridge"] .timeline {
  grid-row: 2;
  min-width: 0;
  min-height: 0;
  height: 100%;
  overflow: auto;
}

.workspace-heading {
  display: grid;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.workspace-heading h1,
.work-card h2,
.work-card h3 {
  margin: 0;
  letter-spacing: 0;
}

.workspace-heading p {
  max-width: 760px;
  margin: var(--space-2) 0 0;
  color: var(--app-text-muted);
}

.eyebrow {
  margin: 0 0 var(--space-1);
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
}

.content-grid,
.metric-grid,
.document-grid,
.game-grid,
.page-frame,
.view-shell,
.view-toolbar,
.template-list,
.template-tree,
.right-body,
.sheet-side,
.command-list,
.activity-list,
.task-stack {
  display: grid;
  gap: var(--space-3);
}

.content-grid,
.document-grid,
.game-grid,
.page-frame {
  gap: var(--space-4);
}

.work-card,
.agent-card,
.page-bar {
  min-width: 0;
  padding: var(--space-4);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius-lg);
  background: var(--app-surface);
  box-shadow: var(--app-shadow);
}

.work-card {
  display: grid;
  gap: var(--space-4);
}

.context-panel,
.right-panel {
  position: fixed;
  inset: var(--frame-topbar) 0 0 0;
  z-index: 50;
  display: none;
  padding: var(--space-4);
  border-bottom: 1px solid var(--app-border);
  background: color-mix(in srgb, var(--app-surface) var(--sidebar-opacity, 82%), transparent);
  backdrop-filter: blur(16px) saturate(108%);
  box-shadow: var(--app-shadow);
  overflow: auto;
}

.app-shell[data-context-open="true"] .context-panel,
.app-shell[data-right-open="true"] .right-panel {
  display: block;
}

.panel-head {
  margin-bottom: var(--space-3);
}

.nav-list {
  display: grid;
  gap: var(--space-3);
}

.context-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  overflow: visible;
}

.page-frame {
  height: 100%;
  min-height: 0;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "page-toolbar-top"
    "page-title"
    "page-body"
    "page-toolbar-bottom";
  align-content: stretch;
  padding-bottom: 0;
  overflow: hidden;
}

.zc-page-body {
  grid-area: page-body;
  min-width: 0;
  min-height: 0;
  overflow: auto;
}

/* The inspector is where a full filesystem path lands, and a path offers no
   space for a line to break at. Left to the browser's defaults it pushed the
   panel it sits in -- a panel narrow by definition -- into a horizontal scroll
   and clipped the value it exists to show. The key sits above its value rather
   than beside it for the same reason: there is no width to spare. */
.zc-inspector {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.zc-inspector > p { margin: 0; color: var(--app-text-muted); overflow-wrap: anywhere; }
.zc-inspector dl { display: grid; gap: var(--space-2); margin: 0; }
.zc-inspector dl > div { display: grid; gap: 2px; min-width: 0; }
.zc-inspector dt { color: var(--app-text-muted); font-size: 0.78rem; }
.zc-inspector dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }

/* A scene supplies one shared base colour. The whole app keeps the same
   component language while its frame becomes a translucent extension of it.

   Readability rule: the wallpaper may be dark or bright and changes per
   character, so text colour is chosen from the measured scene tone rather than
   assumed. `--zc-on-scene` is the colour that is guaranteed to read against the
   scene; every text token derives from it. The user's theme still supplies the
   accent and the component language, so switching theme remains meaningful.

   `--zc-scene-veil` is the minimum opacity of the base colour mixed into any
   text-bearing surface. It is what keeps contrast stable no matter how busy the
   wallpaper is; without it a photo showed straight through a message bubble. */
.app-shell[data-zc-scene-theme="true"] {
  --zc-on-scene: #f4f7fb;
  --zc-on-scene-soft: rgb(235 241 248 / 72%);
  --zc-scene-veil: 86%;
  --app-bg: var(--zc-page-base, #101820);
  --app-surface: color-mix(in srgb, var(--zc-page-base, #101820) var(--zc-scene-veil) , white 14%);
  --app-surface-muted: color-mix(in srgb, var(--zc-page-base, #101820) 90%, white 10%);
  --app-surface-raised: color-mix(in srgb, var(--zc-page-base, #101820) 76%, white 24%);
  --app-border: rgb(255 255 255 / 16%);
  --app-border-strong: rgb(255 255 255 / 26%);
  --app-text: var(--zc-on-scene);
  --app-text-muted: var(--zc-on-scene-soft);
  --app-accent-soft: color-mix(in srgb, var(--app-accent) 24%, var(--zc-page-base, #101820));
  --app-shadow: 0 10px 32px rgb(0 0 0 / 22%);
  background-color: var(--zc-page-base, #101820);
  background-image: linear-gradient(color-mix(in srgb, var(--zc-page-base, #101820) 38%, transparent), color-mix(in srgb, var(--zc-page-base, #101820) 58%, transparent)), var(--zc-page-wallpaper, none);
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
}

/* Scene chrome uses one light text family everywhere. Bright wallpapers are
   handled by darkening text-bearing surfaces, never by flipping individual
   labels to a competing dark palette. */
.app-shell[data-zc-scene-theme="true"][data-zc-scene-tone="light"] {
  --zc-on-scene: #f4f7fb;
  --zc-on-scene-soft: rgb(235 241 248 / 76%);
  --zc-scene-veil: 86%;
  --app-surface: color-mix(in srgb, var(--zc-page-base, #d6c4aa) 34%, #111820 66%);
  --app-surface-muted: color-mix(in srgb, var(--zc-page-base, #d6c4aa) 24%, #111820 76%);
  --app-surface-raised: color-mix(in srgb, var(--zc-page-base, #d6c4aa) 40%, #111820 60%);
  --app-border: rgb(255 255 255 / 18%);
  --app-border-strong: rgb(255 255 255 / 30%);
  --app-shadow: 0 10px 32px rgb(0 0 0 / 24%);
}

/* Text sitting directly on the wallpaper (character name, dialogue) has no
   surface behind it. A text shadow was tried first and read as smearing, so the
   text stays crisp and legibility comes from a scrim behind the block instead. */
.app-shell[data-zc-scene-theme="true"] :is(.zc-scene-caption, .zc-dialogue-box, .zc-character-name) {
  color: var(--zc-on-scene);
  text-shadow: none;
}
.app-shell[data-zc-scene-theme="true"] :is(.zc-dialogue-box, .zc-character-name) {
  background: color-mix(in srgb, var(--zc-page-base, #101820) 62%, transparent);
  backdrop-filter: blur(10px) saturate(108%);
  border-radius: var(--app-radius);
}
.app-shell[data-zc-scene-theme="true"][data-zc-scene-tone="light"] :is(.zc-dialogue-box, .zc-character-name) {
  background: color-mix(in srgb, var(--zc-page-base, #d6c4aa) 30%, #111820 70%);
}

@media (display-mode: standalone) {
  :root { --app-viewport-height: 100dvh; }
}

.app-shell[data-zc-scene-theme="true"][data-zc-scene-tone="light"] :is(.topbar, .context-panel, .right-panel) {
  background-color: color-mix(in srgb, var(--zc-page-base, #d6c4aa) 32%, #111820 68%);
}

/* Character chat lets the scene through the chrome: the topbar sits at 50% and
   the side panels at 70%, so the panels stay readable while the wallpaper is
   still visible behind the frame. */
.app-shell[data-zc-scene-theme="true"] {
  --zc-topbar-opacity: 50%;
  --sidebar-opacity: 70%;
}

.app-shell[data-zc-scene-theme="true"] .topbar {
  border-color: rgb(255 255 255 / 13%);
  background: color-mix(in srgb, var(--zc-page-base, #101820) var(--zc-topbar-opacity), transparent);
  color: var(--app-text);
  box-shadow: 0 8px 28px rgb(0 0 0 / 14%);
  backdrop-filter: blur(16px) saturate(112%);
}

.app-shell[data-zc-scene-theme="true"] .context-panel,
.app-shell[data-zc-scene-theme="true"] .right-panel {
  border-color: rgb(255 255 255 / 12%);
  background: color-mix(in srgb, var(--zc-page-base, #101820) var(--sidebar-opacity, 50%), transparent);
  color: var(--app-text);
  box-shadow: 8px 0 28px rgb(0 0 0 / 16%);
  backdrop-filter: blur(18px) saturate(108%);
}

.context-tabs button {
  flex: 0 0 auto;
  min-inline-size: max-content;
  width: auto;
  white-space: nowrap;
}

.context-tabs button[aria-pressed="true"] {
  border-color: var(--app-accent);
  background: var(--app-accent-soft);
  color: var(--app-accent-hover);
}
.character-add-menu { position:relative; flex:0 0 auto; }
.character-add-menu > summary { display:grid; place-items:center; min-width:34px; min-height:34px; padding:0 10px; list-style:none; cursor:pointer; border:1px solid var(--app-border); border-radius:10px; background:var(--app-surface); color:var(--app-text); font-size:20px; line-height:1; }
.character-add-menu > summary::-webkit-details-marker { display:none; }
.character-add-menu > div { position:absolute; z-index:40; top:calc(100% + 6px); left:0; width:min(290px,calc(100vw - 32px)); display:grid; gap:4px; padding:6px; border:1px solid var(--app-border); border-radius:12px; background:var(--app-surface); color:var(--app-text); box-shadow:var(--app-shadow); }
.character-add-menu > div button { width:100%; display:grid; gap:2px; padding:9px 10px; border:0; border-radius:8px; background:transparent; color:inherit; text-align:left; cursor:pointer; }
.character-add-menu > div button:hover { background:var(--app-accent-soft); }
.character-add-menu > div small { color:var(--app-text-muted); }

.nav-item {
  width: 100%;
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  min-height: 58px;
  padding: var(--space-2);
  border-radius: var(--app-radius);
  text-align: left;
}

.nav-item span:not(.item-mark) {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.nav-item.selected {
  border-color: var(--app-accent);
  background: var(--app-accent-soft);
}

.item-mark {
  display: inline-grid;
  place-items: center;
  inline-size: 36px;
  block-size: 32px;
  border-radius: var(--app-radius-sm);
  background: var(--app-code-bg);
  color: var(--app-code-text);
  font-size: 11px;
  font-weight: 900;
}

.item-icon {
  display: inline-grid;
  place-items: center;
  inline-size: 36px;
  block-size: 32px;
  border-radius: var(--app-radius-sm);
  background: var(--app-surface);
  color: var(--app-accent-hover);
}

.item-icon svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.side-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.side-tabs button[aria-pressed="true"],
.view-switch button[aria-pressed="true"] {
  border-color: var(--app-accent);
  background: var(--app-accent-soft);
  color: var(--app-accent-hover);
}

.agent-card {
  display: grid;
  gap: var(--space-3);
  box-shadow: none;
}

.agent-status {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
}

.status-pill {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--app-radius);
  background: var(--app-accent-soft);
  color: var(--app-accent-hover);
  font-weight: 800;
}

.agent-input,
.editor-area {
  width: 100%;
  min-height: 96px;
  resize: vertical;
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface-muted);
  color: var(--app-text);
  padding: var(--space-3);
}

.metric-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.metric-card {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface-muted);
}

.metric-card strong {
  font-size: 24px;
}

.document-preview,
.queue-row,
.activity-list div,
.task-stack div,
.check-row,
.toolbar-demo,
.template-list-item,
.template-grid-card,
.template-thumbnail-card,
.template-object-card,
.template-tree-item,
.text-surface,
.image-surface,
.playfield,
.control-strip {
  padding: var(--space-3);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface-muted);
}

.page-bar {
  box-shadow: none;
}

.page-frame {
  min-height: 0;
  width: min(100%, 1120px);
  margin-inline: auto;
  padding-inline: var(--space-4);
  padding-bottom: 0;
  box-sizing: border-box;
}

.zc-page-title,.zc-page-title :is(h1,p),.zc-form-section,.zc-form-section :is(legend,label),.zc-settings-toggle,.zc-settings-toggle legend { color: var(--app-text); }

.page-toolbar {
  position: relative;
  z-index: 25;
  min-width: 0;
  min-height: 48px;
  padding: var(--space-2);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  box-shadow: none;
  background: color-mix(in srgb, var(--app-surface) 96%, transparent);
  backdrop-filter: blur(10px);
}

.page-toolbar-top {
  grid-area: page-toolbar-top;
}

.page-toolbar-bottom {
  grid-area: page-toolbar-bottom;
}

.page-toolbar-bottom .page-bar-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(44px, 1fr));
  width: 100%;
  gap: var(--space-2);
}

.page-toolbar-bottom .page-bar-actions > button {
  justify-self: center;
}

.zc-page-title { grid-area: page-title; }

.page-title {
  display: grid;
  gap: var(--space-1);
}

.page-title h2,
.page-title p {
  margin: 0;
}

.page-title p:not(.eyebrow) {
  max-width: 72ch;
  color: var(--app-text-muted);
}

.toolbar-demo {
  display: grid;
  gap: var(--space-3);
}

.toolbar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface);
}

.toolbar-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.check-row {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
}

.view-toolbar {
  grid-template-columns: minmax(0, 1fr);
}

.view-toolbar input {
  min-width: 0;
}

.template-list-item {
  display: grid;
  grid-template-columns: 32px minmax(180px, 1fr) minmax(calc(var(--zc-list-detail-count) * 100px), .8fr) auto;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
  width: 100%;
  color: inherit;
  text-align: left;
}

.template-grid,
.template-thumbnail-grid,
.template-card-list {
  display: grid;
  gap: var(--space-3);
}

.template-grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.template-thumbnail-grid {
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
}

.template-card-list {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.template-grid-card,
.template-thumbnail-card,
.template-object-card {
  display: grid;
  gap: var(--space-2);
  color: inherit;
  text-align: left;
}

.template-list-item,
.template-grid-card,
.template-thumbnail-card,
.template-object-card,
.template-tree-item {
  cursor: pointer;
}

.template-list-item.selected,
.template-grid-card.selected,
.template-thumbnail-card.selected,
.template-object-card.selected,
.template-tree-item.selected {
  border-color: var(--app-accent);
  background: var(--app-accent-soft);
}

.template-state {
  padding: var(--space-4);
  border: 1px dashed var(--app-border-strong);
  border-radius: var(--app-radius);
  color: var(--app-text-muted);
  background: var(--app-surface-muted);
}

.template-state[data-state="loading"],
.loading-state {
  border-style: solid;
  animation: zc-loading-pulse 1.4s ease-in-out infinite;
}

@keyframes zc-loading-pulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

.template-thumb {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  border-radius: var(--app-radius-sm);
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--app-accent) 22%, transparent), transparent 46%),
    var(--app-code-bg);
  color: var(--app-code-text);
  font-weight: 900;
}

.template-tree-item[data-depth="1"] {
  margin-left: var(--space-5);
}

.template-tree-item[data-depth="2"] {
  margin-left: calc(var(--space-5) * 2);
}
.page-title p:empty { display: none; }
.zc-folder-breadcrumbs { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.zc-folder-breadcrumbs > div { display: flex; align-items: center; gap: 4px; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
.zc-folder-breadcrumbs > div > button { flex: 0 0 auto; min-height: 30px; padding: 0 8px; border: 1px solid var(--app-border); border-radius: var(--app-radius-sm); background: var(--app-surface); color: var(--app-text); }
.zc-folder-breadcrumbs > div > span { color: var(--app-text-muted); }
.zc-folder-breadcrumbs > .icon-button { flex: 0 0 auto; }

.template-list-item[data-detail-count="0"],
.zc-list-header[data-detail-count="0"] {
  grid-template-columns: 32px minmax(0, 1fr) auto;
}

.template-list.has-leading-actions .template-list-item[data-detail-count="0"],
.template-list.has-leading-actions .zc-list-header[data-detail-count="0"] {
  grid-template-columns: 36px 32px minmax(0, 1fr) auto;
}

.template-list-item[data-detail-count="0"] .zc-list-fields,
.zc-list-header[data-detail-count="0"] .zc-list-fields {
  display: none;
}

.zc-list-view { overflow-x: auto; }
.template-list { min-width: 620px; gap: 0; }
.zc-list-header {
  display: grid;
  grid-template-columns: 32px minmax(180px, 1fr) minmax(calc(var(--zc-list-detail-count) * 100px), .8fr) auto;
  align-items: center;
  gap: var(--space-2);
  min-height: 36px;
  padding-inline: var(--space-3);
  border-bottom: 1px solid var(--app-border);
  color: var(--app-text-muted);
  font-size: 12px;
}
.template-list.has-leading-actions .template-list-item,
.template-list.has-leading-actions .zc-list-header { grid-template-columns: 36px 32px minmax(180px, 1fr) minmax(calc(var(--zc-list-detail-count) * 100px), .8fr) auto; }
.zc-list-fields { display: grid; grid-template-columns: repeat(var(--zc-list-detail-count), minmax(100px, 1fr)); align-items: center; gap: var(--space-2); min-width: 0; }
.zc-list-fields > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zc-list-end { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); }
.zc-list-leading { display: flex; align-items: center; justify-content: center; min-width: 0; }
.zc-list-leading .zc-item-actions { display: contents; }
.zc-list-leading .zc-item-action { width: 32px; height: 32px; }
.zc-list-item .zc-item-copy { display: block; min-width: 0; }
.zc-list-item .zc-item-copy strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zc-list-view[data-surface="sidebar"] .template-list { min-width: 0; }
.zc-list-view[data-surface="sidebar"] .zc-list-header,
.zc-list-view[data-surface="sidebar"] .zc-list-fields { display: none; }
.zc-list-view[data-surface="sidebar"] .zc-list-leading { display: none; }
.zc-list-view[data-surface="sidebar"] .template-list-item { grid-template-columns: 28px minmax(0, 1fr) auto; min-height: 40px; }
@media (max-width: 699px) {
  .zc-list-view { overflow-x: hidden; }
  .template-list { min-width: 0; }
  .template-list-item,
  .zc-list-header { grid-template-columns: 32px minmax(0, 1fr) minmax(84px, 35%) auto; }
  .template-list.has-leading-actions .template-list-item,
  .template-list.has-leading-actions .zc-list-header { grid-template-columns: 36px 32px minmax(0, 1fr) minmax(84px, 35%) auto; }
  .template-list-item[data-detail-count="0"],
  .zc-list-header[data-detail-count="0"] { grid-template-columns: 32px minmax(0, 1fr) auto; }
  .template-list.has-leading-actions .template-list-item[data-detail-count="0"],
  .template-list.has-leading-actions .zc-list-header[data-detail-count="0"] { grid-template-columns: 36px 32px minmax(0, 1fr) auto; }
}
.zc-folder-item { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }
.template-list-item.zc-folder-item {
  min-height: 36px;
  padding: 4px 10px;
  border-radius: var(--app-radius-sm);
}
.template-list-item.zc-folder-item > .item-icon {
  inline-size: 28px;
  block-size: 28px;
}
.template-list-item.zc-folder-item > .item-icon svg { width: 17px; height: 17px; }
@media (max-width: 999px) {
  .zc-list-view:not([data-surface="sidebar"]) .zc-list-fields { grid-template-columns: minmax(84px, 1fr); }
  .zc-list-view:not([data-surface="sidebar"]) [data-column-id="modified"] { display: none; }
}
.template-grid-card.zc-folder-item,
.template-thumbnail-card.zc-folder-item,
.template-object-card.zc-folder-item { position: relative; padding-inline-end: 52px; }
.template-grid-card.zc-folder-item > .zc-item-actions,
.template-thumbnail-card.zc-folder-item > .zc-item-actions,
.template-object-card.zc-folder-item > .zc-item-actions { position: absolute; inset: var(--space-2) var(--space-2) auto auto; }
.zc-popup-menu { inset: auto var(--space-4) calc(54px + var(--space-2)) auto; inline-size: min(360px, calc(100vw - 32px)); transform: none; }
.zc-popup-menu .zc-page-frame { height: auto; min-height: 0; padding: var(--space-3); }
.zc-popup-menu .zc-page-title { padding-inline-end: 36px; }
.zc-popup-menu .zc-page-body:empty { display: none; }
.zc-popup-menu .page-toolbar-bottom { border: 0; padding: 0; }

.zc-anchored-menu {
  position: fixed;
  z-index: 110;
  min-width: 190px;
  max-width: min(320px, calc(100vw - 16px));
  padding: var(--space-1);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface-raised, var(--app-surface));
  box-shadow: var(--app-shadow);
}
.zc-anchored-menu-actions { display: grid; gap: 2px; }
.zc-anchored-menu-actions > button { width: 100%; min-height: 38px; justify-content: flex-start; text-align: left; }
.app-shell:not([data-surface-mode="mobile"]) .zc-anchored-menu { padding: 3px; }
.app-shell:not([data-surface-mode="mobile"]) .zc-anchored-menu-actions { gap: 1px; }
.app-shell:not([data-surface-mode="mobile"]) .zc-anchored-menu-actions > button { min-height: 32px; padding-block: 4px; }
.app-shell:not([data-surface-mode="mobile"]) .zc-folder-item [data-action="item.more"] { display: none; }

.zc-item-copy {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.zc-sidebar-page {
  min-height: 0;
  display: grid;
  align-content: start;
  gap: var(--space-3);
  padding: var(--space-3);
}

.zc-sidebar-page-title {
  font-size: 0.9rem;
}

.zc-mode-toggle { white-space: nowrap; }
.zc-mode-menu { position: relative; }
.zc-mode-menu > summary { display: inline-flex; align-items: center; list-style: none; cursor: pointer; white-space: nowrap; }
.zc-mode-menu > summary::-webkit-details-marker { display: none; }
.zc-mode-options { position: absolute; z-index: 30; inset-block-start: calc(100% + var(--space-2)); inset-inline-end: 0; display: grid; min-width: 150px; padding: var(--space-1); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface); box-shadow: var(--app-shadow); }
.zc-mode-options button { min-height: 36px; padding: 0 var(--space-3); border: 0; border-radius: calc(var(--app-radius) * .7); background: transparent; color: var(--app-text); text-align: start; }
.zc-mode-options button[aria-checked="true"] { background: var(--app-accent-soft); color: var(--app-accent); font-weight: 700; }
.zc-mode-options button:hover, .zc-mode-options button:focus-visible { background: var(--app-surface-muted); }

.zc-task-page { display: grid; gap: var(--space-3, 12px); min-height: 0; }
.zc-task-workspace { display: grid; grid-template-columns: minmax(0,1fr) minmax(220px,30%); gap: var(--space-3); min-height: 0; }
.zc-task-events { display: grid; gap: var(--space-3, 12px); min-height: 0; overflow: auto; }
.zc-task-event { padding: var(--space-3, 12px); }
.zc-task-event header, .zc-task-queue-item { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3, 12px); }
.zc-task-event pre { overflow: auto; max-height: 280px; padding: 10px; background: var(--app-code-bg); color: var(--app-code-text); }
.zc-task-queue-panel { align-self: start; display: grid; gap: var(--space-2); padding: var(--space-3); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface); }
.zc-task-queue-panel header > div { display: flex; justify-content: space-between; gap: var(--space-2); }
.zc-task-queue { display: grid; gap: var(--space-2, 8px); }
.zc-task-queue-empty { margin: 0; color: var(--app-text-muted); }
.zc-task-queue-item { padding: var(--space-2, 8px); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface-muted); }
.zc-task-status { display: grid; gap: 6px; padding: var(--space-3); border-left: 4px solid var(--app-border-strong); background: var(--app-surface-muted); }
.zc-task-status[data-phase="transmitting"] { border-left-color: var(--app-accent); }.zc-task-status[data-phase="working"] { border-left-color: var(--app-success); }.zc-task-status[data-phase="error"] { border-left-color: var(--app-danger); }
/* Waiting on the user is not a failure. It reads as an actionable pause so the
   approval controls below it look like the next step rather than damage. */
.zc-task-status[data-phase="awaiting-approval"] { border-left-color: var(--app-warning); background: color-mix(in srgb, var(--app-warning) 10%, var(--app-surface)); }
.zc-task-status p { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2); margin: 0; }
.zc-task-branches,.zc-task-history { display: grid; gap: var(--space-2); }.zc-task-branches button,.zc-task-history article { display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface); text-align: left; }.zc-task-history p { margin: 4px 0 0; white-space: pre-wrap; }
.zc-task-input { position: sticky; bottom: 0; }
@media (max-width: 699px) { .zc-task-workspace { grid-template-columns: 1fr; }.zc-task-queue-panel { order: -1; } }
.zc-conversation-page { display: grid; grid-template-rows: auto minmax(0,1fr) auto auto; gap: var(--space-3); width: 100%; height: 100%; min-height: 0; }
.zc-conversation-page[data-chat-mode="plain"] { max-width: none; }
.zc-conversation-head, .zc-conversation-identity, .zc-conversation-message header, .zc-conversation-queue header, .zc-conversation-queue > div { display: flex; align-items: center; gap: var(--space-2); }
.zc-conversation-head { justify-content: space-between; }
.zc-conversation-identity { min-width: 0; }.zc-conversation-identity h1 { margin: 0; }.zc-conversation-identity span { color: var(--app-text-muted); }
.zc-conversation-avatar { display: grid; place-items: center; width: 42px; height: 42px; overflow: hidden; border-radius: 50%; background: var(--app-accent-soft); }.zc-conversation-avatar img { width: 100%; height: 100%; object-fit: cover; }
.zc-conversation-stream { min-height: 0; overflow: auto; display: grid; align-content: start; gap: var(--space-3); }
.zc-conversation-page[data-chat-mode="plain"] .zc-conversation-stream,
.zc-conversation-page[data-chat-mode="plain"] .zc-conversation-message { width: 100%; max-width: none; }
.zc-conversation-page[data-chat-mode="plain"] .zc-chat-composer textarea {
  border-color: var(--app-border);
  background: var(--app-surface);
  color: var(--app-text);
  box-shadow: var(--app-shadow-sm);
}
.zc-conversation-page[data-chat-mode="plain"] .zc-chat-composer textarea::placeholder { color: var(--app-text-muted); }
.zc-conversation-message { padding: var(--space-3); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface); }.zc-conversation-message[data-role="user"] { margin-inline-start: min(12%, 90px); background: var(--app-accent-soft); }.zc-conversation-message header { justify-content: space-between; }
.zc-conversation-message[data-role="error"],.zc-conversation-message[data-variant="error"] { border-color:color-mix(in srgb,var(--app-danger) 58%,var(--app-border)); background:color-mix(in srgb,var(--app-danger) 10%,var(--app-surface)); color:var(--app-danger); }
.zc-conversation-queue { display: grid; gap: var(--space-2); padding: var(--space-3); border: 1px solid var(--app-border); border-radius: var(--app-radius); }.zc-conversation-queue header, .zc-conversation-queue > div { justify-content: space-between; }
.zc-conversation-input:empty { display: none; }

/* Conversation content must never widen the page. Long paths, URLs, and code
   blocks previously pushed the whole surface wide and produced a horizontal
   scrollbar on the mobile surface in every conversation product. */
.zc-conversation-page, .zc-conversation-stream, .zc-conversation-message { min-width: 0; max-width: 100%; }
.zc-conversation-message > * { min-width: 0; max-width: 100%; }
.zc-conversation-message .markdown { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.zc-conversation-message .markdown :is(p, li, h1, h2, h3, h4, h5, h6) { overflow-wrap: anywhere; }
.zc-conversation-message .markdown pre { max-width: 100%; overflow-x: auto; }
.zc-conversation-message .markdown pre { white-space: pre; }
.zc-conversation-message .markdown code { overflow-wrap: anywhere; }
.zc-conversation-message .markdown :is(img, video, canvas, svg) { max-width: 100%; height: auto; }
.zc-conversation-message header time { flex: 0 0 auto; white-space: nowrap; color: var(--app-text-muted); }
.zc-conversation-message header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zc-log-message { min-width: 0; max-width: 100%; }
.zc-log-message > * { min-width: 0; max-width: 100%; }
.zc-log-message header { display: flex; align-items: center; gap: var(--space-2); }
.zc-log-message header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zc-log-message header time { flex: 0 0 auto; margin-inline-start: auto; white-space: nowrap; color: var(--app-text-muted); font-size: 0.85em; }
.zc-log-message .markdown { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.zc-log-message .markdown pre { max-width: 100%; overflow-x: auto; }
.zc-log-message .markdown :is(img, video, canvas, svg) { max-width: 100%; height: auto; }
/* A dead artifact link must not look like a working one. */
.zc-conversation-message a[data-artifact-unavailable="true"] { color: var(--app-text-muted); text-decoration: line-through; cursor: not-allowed; }

.tree-kind-icon.tree-portrait,
.zc-persona-avatar {
  overflow: hidden;
  border-radius: 50%;
}

.tree-kind-icon.tree-portrait img,
.zc-persona-avatar img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: 50% 16%;
}

.app-shell.resizing {
  cursor: col-resize;
  user-select: none;
}

.resize-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 3;
  width: 10px;
  cursor: col-resize;
  touch-action: none;
}
.resize-handle-right { right: -5px; }
.resize-handle-left { left: -5px; }
.resize-handle::after {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 4px;
  width: 1px;
  background: transparent;
}
.resize-handle:hover::after,
.app-shell.resizing .resize-handle::after { background: var(--app-accent); }

.item-icon[data-icon="working"] svg {
  animation: zc-status-spin 1.1s linear infinite;
}

@keyframes zc-status-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .item-icon[data-icon="working"] svg { animation: none; }
}

.template-tree-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0;
  padding-left: calc(var(--space-5) * var(--tree-depth, 0));
  border-radius: var(--app-radius);
}
.template-tree[data-row-border="subtle"] .template-tree-row {
  border: 1px solid var(--tree-row-border-color, color-mix(in srgb, var(--app-border) 58%, transparent));
  border-radius: var(--tree-row-border-radius, 8px);
  margin-block: var(--tree-row-border-gap, 3px);
}

.template-tree-row[data-depth="1"] { --tree-depth: 1; }
.template-tree-row[data-depth="2"] { --tree-depth: 2; }
.template-tree-row[data-depth="3"] { --tree-depth: 3; }
.template-tree { gap: 0; }
.template-tree-row:hover,
.template-tree-row:focus-within,
.template-tree-row.selected { background: var(--app-accent-soft); }
.template-tree-row .template-tree-item {
  min-width: 0;
  min-height: 38px;
  margin-left: 0;
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--app-radius);
  background: transparent;
  box-shadow: none;
}
.tree-action.is-labeled,
.tree-action.is-button {
  width: auto;
  min-width: 34px;
  padding-inline: 7px;
  border-color: var(--app-border);
  border-radius: 7px;
  background: var(--app-surface);
  opacity: 1;
}

.template-tree-row .tree-item-actions:has(.tree-action.is-labeled, .tree-action.is-button) {
  opacity: 1 !important;
}
.tree-item-actions { display: flex; gap: var(--space-1); }
.zc-item-actions { display: inline-flex; align-items: center; gap: var(--space-1); margin-inline-start: auto; }
.zc-item-action { inline-size: 30px; block-size: 30px; display: inline-grid; place-items: center; border: 0; border-radius: var(--radius-sm); background: transparent; color: inherit; cursor: pointer; }
.zc-item-action:hover, .zc-item-action:focus-visible { background: var(--surface-hover); }
.zc-item-action.danger { color: var(--danger, #b42318); }
.zc-item-action svg { inline-size: 17px; block-size: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.zc-action-error { position: fixed; inset: auto var(--space-4) var(--space-4) auto; z-index: 100; display: flex; align-items: center; gap: var(--space-3); max-inline-size: min(420px, calc(100vw - 32px)); padding: var(--space-3) var(--space-4); border: 1px solid var(--danger, #b42318); border-radius: var(--radius-md); background: var(--surface-raised, #fff); color: var(--danger, #b42318); box-shadow: var(--shadow-lg); }
.zc-action-error button { border: 0; background: transparent; color: inherit; font-size: 1.25rem; cursor: pointer; }
.zc-popup-surface { position: fixed; inset: 50% auto auto 50%; z-index: 90; inline-size: min(640px, calc(100vw - 32px)); max-block-size: calc(var(--app-viewport-height) - 48px); overflow: auto; transform: translate(-50%, -50%); border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised, #fff); box-shadow: var(--shadow-lg); }
.zc-popup-close { position: absolute; inset: var(--space-2) var(--space-2) auto auto; z-index: 2; inline-size: 32px; block-size: 32px; border: 0; border-radius: 50%; background: var(--surface-hover); cursor: pointer; }
.zc-image-sequence { display: grid; grid-template-rows: minmax(0, 1fr) auto; min-block-size: 0; block-size: 100%; background: #111; outline: none; }
.zc-sequence-stage { display: grid; place-items: center; min-inline-size: 0; min-block-size: 0; overflow: hidden; }
.zc-sequence-stage img { display: block; inline-size: 100%; block-size: 100%; min-inline-size: 0; min-block-size: 0; object-fit: contain; }
.zc-image-sequence:not([data-fit="contain"]) .zc-sequence-stage { overflow: auto; place-items: start center; }
.zc-image-sequence[data-fit="width"] .zc-sequence-stage img { inline-size: 100%; max-block-size: none; }
.zc-image-sequence[data-fit="width"] .zc-sequence-stage img,
.zc-image-sequence[data-fit="actual"] .zc-sequence-stage img { block-size: auto; object-fit: fill; }
.zc-image-sequence[data-fit="actual"] .zc-sequence-stage img { inline-size: auto; max-inline-size: none; max-block-size: none; }
.zc-sequence-controls { display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-2); background: rgb(0 0 0 / 72%); color: white; }
.zc-sequence-action { min-inline-size: 38px; block-size: 34px; border: 1px solid rgb(255 255 255 / 24%); border-radius: var(--radius-sm); background: rgb(255 255 255 / 10%); color: white; cursor: pointer; }
.zc-sequence-action:disabled { opacity: .35; cursor: default; }
.zc-sequence-fit { font-size: 12px; font-weight: 800; }
.zc-sequence-controls output { min-inline-size: 72px; text-align: center; font-variant-numeric: tabular-nums; }
.tree-action { inline-size: 32px; block-size: 32px; border-color: transparent; background: transparent; font-size: 17px; font-weight:800; }
.app-shell[data-app-id="agentbridge"] #contextList .tree-item-actions { opacity:1; }
.tree-disclosure { width: 12px; color: var(--app-text-muted); font-size: 11px; text-align: center; }
.tree-kind-icon { display: inline-grid; width: 18px; place-items: center; color: var(--app-text-muted); }
.template-tree-item:has(.agent-character-icon) { grid-template-columns: 12px 30px minmax(0, 1fr) auto; }
.tree-kind-icon:has(.agent-character-icon) { width: 30px; height: 30px; overflow: visible; }
.tree-kind-icon .agent-character-icon { display: block; width: 30px; height: 30px; padding: 2px; }
.tree-kind-icon svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }

.template-tree-item {
  width: 100%;
  display: grid;
  grid-template-columns: 12px 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-2);
  color: inherit;
  text-align: left;
}

.template-tree-item span:not(.item-mark, .item-icon, .status-pill) {
  min-width: 0;
  display: grid;
}

.text-surface,
.image-surface {
  display: grid;
  gap: var(--space-3);
}

.text-viewer-body {
  min-width: 0;
  min-height: 280px;
  padding: var(--space-4);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-bg);
  color: var(--app-text, #f4f7fb);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Markdown mode emits real block elements, so the pre-wrap that keeps plain
   text intact instead doubles every gap: the newline the renderer writes
   between two blocks would render as a blank line of its own. */
.text-viewer-body.markdown {
  white-space: normal;
  line-height: 1.75;
}

.text-viewer-body.markdown > :first-child { margin-top: 0; }
.text-viewer-body.markdown > :last-child { margin-bottom: 0; }
.text-viewer-body.markdown :is(h1, h2, h3, h4, h5, h6) { margin: var(--space-5) 0 var(--space-2); line-height: 1.35; }
.text-viewer-body.markdown h1 { font-size: 1.65rem; }
.text-viewer-body.markdown h2 { font-size: 1.4rem; }
.text-viewer-body.markdown h3 { font-size: 1.2rem; }
.text-viewer-body.markdown h4 { font-size: 1.05rem; }
.text-viewer-body.markdown :is(h5, h6) { font-size: 1rem; color: var(--app-text-muted); }
.text-viewer-body.markdown p { margin: 0 0 var(--space-3); }
.text-viewer-body.markdown :is(ul, ol) { margin: 0 0 var(--space-3); padding-inline-start: var(--space-5); }
.text-viewer-body.markdown :is(ul, ol) :is(ul, ol) { margin: var(--space-1) 0 0; }
.text-viewer-body.markdown li { margin: var(--space-1) 0; }
.text-viewer-body.markdown blockquote { margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3); border-inline-start: 3px solid var(--app-border-strong); color: var(--app-text-muted); }
.text-viewer-body.markdown blockquote > :last-child { margin-bottom: 0; }
.text-viewer-body.markdown hr { margin: var(--space-5) 0; border: 0; border-top: 1px solid var(--app-border); }
.text-viewer-body.markdown code { padding: 1px 5px; border-radius: 4px; background: var(--app-surface-muted); font-size: 0.92em; }
/* Every block except a table stays inside the reading column. A document that
   has to be dragged sideways to be read is unreadable, so code wraps here even
   though a chat transcript keeps its own horizontal scroller. */
.text-viewer-body.markdown pre { margin: 0 0 var(--space-3); padding: var(--space-3); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface-muted); white-space: pre-wrap; overflow-wrap: anywhere; }
.text-viewer-body.markdown pre code { padding: 0; background: transparent; }
.text-viewer-body.markdown :is(img, video, svg) { max-width: 100%; height: auto; }

/* A table is the one block that cannot be reflowed without destroying what it
   says, so it carries its own horizontal scroller instead of widening the
   document around it. `tabindex` is what lets a keyboard reach that scroller.

   `overflow-x: auto` alone did not deliver that. A scroll container's
   *min-content* contribution is zero, but its *max-content* contribution is
   still the full table, so any ancestor sized to max-content -- an `auto` grid
   track, a float, `fit-content` -- grew to the table's width and dragged every
   surrounding paragraph out with it. The user then got a page that scrolled
   sideways as a whole, which also swallowed the drag the table's own scroller
   was supposed to receive. `contain: inline-size` makes the wrapper's inline
   size independent of its contents, so the table can never be measured through
   again no matter which surface it lands on. */
.zc-markdown-table { max-width: 100%; margin: 0 0 var(--space-3); overflow-x: auto; overscroll-behavior-x: contain; contain: inline-size; scrollbar-width: thin; border: 1px solid var(--app-border); border-radius: var(--app-radius); }
.zc-markdown-table:focus-visible { outline: 2px solid var(--app-accent); outline-offset: 2px; }
/* The same bargain for the other block that cannot be reflowed. A code fence
   with one unbreakable path in it is just as capable of stretching the
   paragraphs around it, so it too scrolls on its own and is sealed against
   being measured through. Surfaces that would rather wrap code than scroll it
   -- the text viewer, and every conversation surface on a phone -- override
   `white-space` and `overflow-x` above this and keep doing so. */
.markdown pre { max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; contain: inline-size; }
/* `max-content` is what makes the scroller worth having: a percentage width
   lets the layout squeeze every column into the container instead, which
   shreds each cell into a four-line stack and still overflows. */
.zc-markdown-table > table { width: max-content; min-width: 100%; border-collapse: collapse; white-space: normal; }
.zc-markdown-table :is(th, td) { min-width: 7ch; max-width: 34ch; padding: var(--space-2) var(--space-3); border-block-end: 1px solid var(--app-border); text-align: start; vertical-align: top; overflow-wrap: anywhere; }
.zc-markdown-table th { background: var(--app-surface-muted); font-weight: 600; }
.zc-markdown-table tr:last-child :is(th, td) { border-block-end: 0; }

.document-preview p {
  max-width: 72ch;
  margin: 0 0 var(--space-3);
}

.document-preview p:last-child {
  margin-bottom: 0;
}

.queue-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
}

.image-stage,
.playfield {
  min-height: 360px;
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
}

.image-stage {
  display: grid;
  place-items: center;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--app-accent) 24%, transparent), transparent 42%),
    linear-gradient(45deg, color-mix(in srgb, var(--app-surface-muted) 65%, transparent) 25%, transparent 25%),
    var(--app-code-bg);
  background-size: auto, 24px 24px, auto;
  color: var(--app-code-text);
  font-weight: 900;
}

.playfield {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(6, 1fr);
  gap: 6px;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--app-accent) 22%, transparent), transparent 44%),
    var(--app-code-bg);
}

.tile {
  border: 1px solid color-mix(in srgb, var(--app-border) 70%, transparent);
  border-radius: var(--app-radius-sm);
  background: color-mix(in srgb, var(--app-surface) 78%, transparent);
}

.tile.hero {
  background: var(--app-accent);
}

.tile.goal {
  background: var(--app-warning);
}

.control-strip {
  display: grid;
  gap: var(--space-3);
}

label {
  display: grid;
  gap: var(--space-2);
  font-weight: 700;
}

input,
select {
  width: 100%;
  min-height: 38px;
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-surface-muted);
  color: var(--app-text);
  padding: 0 var(--space-3);
}

.scrim {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: none;
  background: transparent;
}

.sheet-side {
  gap: var(--space-4);
}

.app-shell[data-context-open="true"] .scrim,
.app-shell[data-right-open="true"] .scrim,
.app-shell[data-context-open="true"] .sheet,
.app-shell[data-right-open="true"] .sheet {
  display: block;
}

.app-shell > .sheet {
  position: fixed;
  /* Compact context surfaces are bottom sheets, not narrow desktop drawers.
     Use the full inline viewport and a stable block size. max-height alone
     makes the sheet shrink and grow with its current tab contents. */
  inset: auto 0 0;
  width: 100%;
  height: calc(var(--app-viewport-height) - var(--frame-topbar) - var(--space-2));
  max-height: calc(var(--app-viewport-height) - var(--frame-topbar) - var(--space-2));
  z-index: 70;
  display: none;
  padding: var(--space-2) var(--space-3) var(--space-3);
  border: 1px solid var(--app-border);
  border-bottom: 0;
  border-radius: var(--app-radius-lg) var(--app-radius-lg) 0 0;
  background: var(--app-surface, #fff);
  box-shadow: var(--app-shadow);
  isolation: isolate;
  overflow: auto;
}

.sheet-grip {
  width: 44px;
  height: 4px;
  margin: 0 auto var(--space-3);
  border-radius: 999px;
  background: var(--app-border-strong);
}

dialog {
  width: min(520px, calc(100vw - 32px));
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius-lg);
  background: var(--app-surface);
  color: var(--app-text);
  box-shadow: var(--app-shadow);
}

dialog::backdrop {
  background: rgb(0 0 0 / 34%);
}

.dialog-head,
.command-input {
  margin-bottom: var(--space-4);
}

.command-list button {
  text-align: left;
}

[hidden] {
  display: none !important;
}

@media (min-width: 700px) {
  .workspace-heading {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }

  .context-panel {
    inset: var(--frame-topbar) auto 0 0;
    width: min(var(--left-panel-width), calc(100vw - 56px));
    border-right: 1px solid var(--app-border);
    border-bottom: 0;
  }

  .right-panel {
    inset: var(--frame-topbar) 0 0 auto;
    width: min(var(--right-panel-width), calc(100vw - 56px));
    border-left: 1px solid var(--app-border);
    border-bottom: 0;
  }

  .content-grid,
  .document-grid,
  .game-grid {
    grid-template-columns: minmax(0, 1.35fr) minmax(260px, 0.65fr);
  }

  .view-toolbar {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }
}

@media (min-width: 1040px) {
  .app-shell {
    grid-template-columns: var(--left-panel-width) minmax(0, 1fr) var(--right-panel-width);
    grid-template-rows: var(--frame-topbar) 1fr;
    grid-template-areas:
      "topbar topbar topbar"
      "context primary right";
  }

  .scrim,
  .sheet,
  .app-shell[data-context-open="true"] .scrim,
  .app-shell[data-right-open="true"] .scrim,
  .app-shell[data-context-open="true"] .sheet,
  .app-shell[data-right-open="true"] .sheet {
    display: none;
  }

  .context-panel,
  .right-panel {
    position: sticky;
    inset: auto;
    top: var(--frame-topbar);
    display: block;
    width: auto;
    height: 100%;
    max-height: none;
    border-bottom: 0;
    box-shadow: none;
  }

  .context-panel {
    grid-area: context;
    border-right: 1px solid var(--app-border);
  }

  .right-panel {
    grid-area: right;
    border-left: 1px solid var(--app-border);
  }

  .app-shell[data-context-pinned="false"][data-right-pinned="true"] {
    grid-template-columns: minmax(0, 1fr) var(--right-panel-width);
    grid-template-areas:
      "topbar topbar"
      "primary right";
  }

  .app-shell[data-context-pinned="true"][data-right-pinned="false"] {
    grid-template-columns: var(--left-panel-width) minmax(0, 1fr);
    grid-template-areas:
      "topbar topbar"
      "context primary";
  }

  .app-shell[data-context-pinned="false"][data-right-pinned="false"] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "topbar"
      "primary";
  }

  .app-shell[data-context-pinned="false"] .context-panel,
  .app-shell[data-right-pinned="false"] .right-panel {
    display: none;
  }

  .primary {
    padding: var(--space-5);
  }
}

.app-shell[data-surface-mode="desktop"] {
  grid-template-columns: var(--left-panel-width) minmax(0, 1fr) var(--right-panel-width);
  grid-template-rows: var(--frame-topbar) 1fr;
  grid-template-areas:
    "topbar topbar topbar"
    "context primary right";
}

.app-shell[data-surface-mode="desktop"] .scrim,
.app-shell[data-surface-mode="desktop"] .sheet,
.app-shell[data-surface-mode="desktop"][data-context-open="true"] .scrim,
.app-shell[data-surface-mode="desktop"][data-right-open="true"] .scrim,
.app-shell[data-surface-mode="desktop"][data-context-open="true"] .sheet,
.app-shell[data-surface-mode="desktop"][data-right-open="true"] .sheet {
  display: none;
}

.app-shell[data-surface-mode="desktop"] .context-panel,
.app-shell[data-surface-mode="desktop"] .right-panel {
  position: sticky;
  inset: auto;
  top: var(--frame-topbar);
  display: block;
  width: auto;
  height: 100%;
  max-height: none;
  border-bottom: 0;
  box-shadow: none;
}

.app-shell[data-surface-mode="desktop"] .context-panel {
  grid-area: context;
  border-right: 1px solid var(--app-border);
}

.app-shell[data-surface-mode="desktop"] .right-panel {
  grid-area: right;
  border-left: 1px solid var(--app-border);
}

.app-shell[data-surface-mode="desktop"][data-context-pinned="false"][data-right-pinned="true"] {
  grid-template-columns: minmax(0, 1fr) var(--right-panel-width);
  grid-template-areas:
    "topbar topbar"
    "primary right";
}

.app-shell[data-surface-mode="desktop"][data-context-pinned="true"][data-right-pinned="false"] {
  grid-template-columns: var(--left-panel-width) minmax(0, 1fr);
  grid-template-areas:
    "topbar topbar"
    "context primary";
}

.app-shell[data-surface-mode="desktop"][data-context-pinned="false"][data-right-pinned="false"] {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "topbar"
    "primary";
}

.app-shell[data-surface-mode="desktop"][data-context-pinned="false"] .context-panel,
.app-shell[data-surface-mode="desktop"][data-right-pinned="false"] .right-panel {
  display: none;
}

.app-shell[data-surface-mode="mobile"] {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: var(--frame-topbar) 1fr;
  grid-template-areas:
    "topbar"
    "primary";
}

.app-shell[data-surface-mode="mobile"] .context-panel,
.app-shell[data-surface-mode="mobile"] .right-panel {
  display: none;
}

.app-shell[data-surface-mode="mobile"][data-context-open="true"] .scrim,
.app-shell[data-surface-mode="mobile"][data-right-open="true"] .scrim,
.app-shell[data-surface-mode="mobile"][data-context-open="true"] .sheet,
.app-shell[data-surface-mode="mobile"][data-right-open="true"] .sheet {
  display: block;
}

@media (max-width: 860px) {
  .metric-grid {
    grid-template-columns: 1fr;
  }

  .page-bar {
    align-items: stretch;
    flex-direction: column;
  }
}

.template-tree-item.tree-state-icon {
  grid-template-columns: 18px minmax(0, 1fr) auto;
  column-gap: var(--space-1);
}

.template-tree-item strong { font-weight: 600; }
.template-tree-item .muted { font-size: 12px; }

@media (hover: hover) and (pointer: fine) {
  .template-tree-row:not(:hover):not(:focus-within) .tree-item-actions { opacity: 0; }
  .template-tree-row .tree-item-actions:has(.tree-action.is-labeled, .tree-action.is-button) { opacity: 1; }
}

@media (max-width: 699px) {
  .primary { padding: var(--space-2); }
  .workspace-heading { margin-bottom: var(--space-2); }
  .work-card,
  .zc-console-page,
  .zc-console-output,
  .zc-console-inputbar { border-radius: 0; }
  .zc-console-page { border: 0; padding: 0; box-shadow: none; }
  .zc-console-output { border-inline: 0; }
}

.object-card-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: start;
}

.object-card-copy {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.object-card-copy strong {
  overflow-wrap: anywhere;
}

.object-card-badge {
  grid-column: 2;
  min-width: 0;
  justify-self: start;
}

.object-card-details {
  display: grid;
  gap: var(--space-2);
  margin: 0;
}

.object-card-details div {
  display: grid;
  grid-template-columns: minmax(70px, auto) minmax(0, 1fr);
  gap: var(--space-2);
}

.object-card-details dt,
.object-card-details dd {
  margin: 0;
}

.object-card-details dt,
.object-card-meta {
  color: var(--app-text-muted);
  font-size: 12px;
}

.object-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.zc-sidebar-tabs,
.zc-console-page {
  min-width: 0;
  min-height: 0;
  display: grid;
  gap: var(--space-3);
}

.zc-console-page {
  block-size: min(620px, calc(var(--app-viewport-height) - var(--frame-topbar) - 190px));
  grid-template-rows: minmax(0, 1fr) auto;
}

.zc-console-output {
  min-width: 0;
  min-height: 0;
  overflow: auto;
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--app-border);
  border-radius: var(--app-radius);
  background: var(--app-code-bg);
  color: var(--app-code-text);
  white-space: pre-wrap;
}

.zc-console-inputbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2);
  align-items: center;
  padding-top: var(--space-2);
  border-top: 1px solid var(--app-border);
}

.zc-terminal-status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 24px;
  color: var(--app-text-muted);
  font-size: 12px;
}

.zc-terminal-page {
  grid-template-rows: auto minmax(0, 1fr) auto;
}

.zc-terminal-state-dot {
  inline-size: 8px;
  block-size: 8px;
  border-radius: 999px;
  background: var(--app-border-strong);
}

.zc-terminal-page[data-running="true"] .zc-terminal-state-dot {
  background: var(--app-success, var(--app-accent));
}

.zc-terminal-page[data-connection-state="disconnected"] .zc-terminal-state-dot,
.zc-terminal-page[data-connection-state="error"] .zc-terminal-state-dot {
  background: var(--app-danger, #a32929);
}

@media (max-width: 699px) {
  .zc-terminal-page {
    block-size: max(360px, calc(var(--app-viewport-height) - var(--frame-topbar) - 150px));
    max-block-size: 100%;
    gap: var(--space-2);
  }

  .zc-terminal-page .zc-console-output {
    padding: var(--space-2);
    font-size: 12px;
    line-height: 1.45;
    overscroll-behavior: contain;
  }

  .zc-terminal-page .zc-console-inputbar {
    position: sticky;
    inset-block-end: 0;
    padding: var(--space-2);
    padding-block-end: max(var(--space-2), env(safe-area-inset-bottom));
    background: var(--app-surface);
  }
}

.zc-narrative-chat { width: 100%; height: 100%; min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr); overflow: hidden; border: 0; border-radius: 0; background: var(--app-code-bg); box-shadow: none; }
.zc-narrative-scene { position: relative; min-block-size: 100%; display: grid; place-items: end center; overflow: hidden; background-image: var(--zc-scene-bg, none); background-color: var(--zc-scene-fallback, var(--app-code-bg, #111827)); background-size: cover; background-position: center; }
.zc-character-stage { position:absolute; inset:0; overflow:hidden; pointer-events:none; }
.zc-character-portrait { position:absolute; z-index:var(--zc-character-z,1); left:calc(50% + var(--zc-character-x,0%)); bottom:clamp(70px,12dvh,150px); width:min(38vw,460px); height:min(76dvh,calc(100% - clamp(70px,12dvh,150px))); display:grid; place-items:center; color:var(--app-accent); font-size:0; opacity:var(--zc-character-opacity,1); transform:translateX(-50%) scale(var(--zc-character-scale,1)); transform-origin:center bottom; filter:drop-shadow(0 22px 30px rgb(0 0 0 / 24%)); transition:left 180ms ease,height 180ms ease,opacity 180ms ease,transform 180ms ease,filter 180ms ease; }
.zc-character-image { width: 100%; height: 100%; display: block; background-repeat: no-repeat; background-position: bottom center; background-size: contain; }
.zc-character-initial { font-size: clamp(100px, 22vw, 260px); }
.zc-character-stage[data-response-mode="primary"] .zc-character-portrait:not([data-featured="true"]) { filter:drop-shadow(0 16px 24px rgb(0 0 0 / 18%)) saturate(.78) brightness(.84); }
.zc-character-stage[data-response-mode="primary"] .zc-character-portrait[data-featured="true"] { filter:drop-shadow(0 24px 34px rgb(0 0 0 / 28%)); }
.zc-character-stage[data-character-count="1"] .zc-character-portrait { width:min(58vw,620px); }
.zc-character-stage[data-character-count="2"] .zc-character-portrait { width:min(46vw,520px); }
.zc-character-stage[data-character-count]:not([data-character-count="1"]):not([data-character-count="2"]) .zc-character-portrait { width:min(34vw,430px); }
.zc-character-stage[data-response-mode="parallel"] .zc-character-portrait,.zc-character-stage[data-response-mode="sequential"] .zc-character-portrait { opacity:1; filter:drop-shadow(0 22px 30px rgb(0 0 0 / 24%)); }
.zc-character-stage[data-response-mode="sequential"][data-character-count="2"] .zc-character-portrait { width:min(38%,420px); }
.zc-character-stage[data-response-mode="sequential"][data-character-count="3"] .zc-character-portrait { width:min(30%,380px); }
.zc-character-stage[data-response-mode="sequential"][data-character-count="4"] .zc-character-portrait { width:min(25%,330px); }
.zc-scene-caption { position: absolute; inset: 6px auto auto 6px; z-index: 4; display: flex; align-items: center; gap: 4px; padding: 3px; border: 1px solid color-mix(in srgb, var(--app-border) 34%, transparent); border-radius: 9px; background: color-mix(in srgb, var(--app-surface) 34%, transparent); box-shadow: 0 4px 14px rgb(0 0 0 / 8%); backdrop-filter: blur(7px) saturate(88%); }
.zc-scene-caption > strong { padding: 0 7px; color: var(--app-text); font-size: 13px; white-space: nowrap; }
.zc-participant-bar { position: absolute; z-index: 5; inset: 6px 6px auto auto; display: flex; align-items: center; gap: var(--space-2); max-width: min(58%, 620px); }
.zc-participant-list { display: flex; flex-wrap: wrap; justify-content: end; gap: 6px; }
.zc-participant-chip { display: inline-flex; align-items: center; gap: 4px; min-height: 30px; padding: 3px 8px; border: 1px solid rgb(255 255 255 / 20%); border-radius: 999px; background: rgb(10 14 22 / 55%); color: #fff; font-size: 12px; backdrop-filter: blur(8px); }
.zc-participant-chip button { width: 20px; height: 20px; padding: 0; border: 0; background: transparent; color: inherit; }
.zc-participant-invite select { min-height: 30px; border: 1px solid rgb(255 255 255 / 20%); border-radius: 999px; background: rgb(10 14 22 / 70%); color: #fff; padding: 0 10px; }
.zc-roster-controls,.zc-roster-avatars,.zc-discussion-mode { display: flex; align-items: center; gap: 7px; }
.zc-roster-controls,.zc-roster-avatars { flex-direction: column; }
.zc-roster-controls { padding: 7px 5px; border: 1px solid rgb(255 255 255 / 18%); border-radius: 999px; background: rgb(10 14 22 / 55%); backdrop-filter: blur(10px); }
.zc-roster-avatar { width: 34px; height: 34px; padding: 0; overflow: hidden; border: 2px solid rgb(255 255 255 / 34%); border-radius: 50%; background: var(--app-surface); color: var(--app-text); cursor: grab; }
.zc-roster-avatar img { width: 100%; height: 100%; object-fit: cover; }
.zc-roster-avatar[data-featured="true"] { border-color: #fff; box-shadow: 0 0 0 3px var(--app-accent), 0 4px 12px rgb(0 0 0 / 24%); }
.zc-roster-avatar[data-swap-selected="true"] { outline: 3px solid var(--app-warning); outline-offset: 2px; }
.zc-discussion-mode { display: flex; flex-direction: column; align-items: stretch; gap: 6px; color: #fff; font-size: 11px; }
/* `.view-switch button` (widgets.js `collectionSwitcher`) defaults to
   `var(--app-surface)`/`var(--app-text)` sized for a page toolbar sitting on
   the app background. Here it sits on the character-stage image, inside the
   same dark glass pill language as `.zc-roster-controls`/`.zc-roster-avatar`
   -- needs its own contrast and size, not the toolbar default. */
.zc-discussion-mode .view-switch { flex-wrap: nowrap; gap: 2px; padding: 2px; border: 1px solid rgb(255 255 255 / 18%); border-radius: 999px; background: rgb(10 14 22 / 55%); backdrop-filter: blur(8px); }
.zc-discussion-mode .view-switch button { min-height: 24px; padding: 0 8px; border: 0; border-radius: 999px; background: transparent; color: rgb(255 255 255 / 78%); font-size: 11px; }
.zc-discussion-mode .view-switch button[aria-pressed="true"] { background: rgb(255 255 255 / 92%); color: #0d0f16; font-weight: 700; }
.zc-page-tabs { display: flex; flex-wrap: nowrap; gap: 1px; }
.zc-page-tabs button { min-height: 27px; padding: 0 9px; border: 0; border-radius: 6px; background: transparent; color: var(--app-text-muted); font-size: 12px; backdrop-filter: none; }
.zc-page-tabs button[aria-pressed="true"] { background: color-mix(in srgb, var(--app-surface) 76%, transparent); color: var(--app-accent-hover); font-weight: 800; box-shadow: inset 0 -2px 0 var(--app-accent); }
.zc-roster-disclosure { position:relative; }
.zc-roster-disclosure > summary { display:grid; place-items:center; width:30px; height:30px; list-style:none; border:1px solid rgb(255 255 255 / 20%); border-radius:9px; background:rgb(10 14 22 / 58%); color:#fff; cursor:pointer; backdrop-filter:blur(8px); }
.zc-roster-disclosure > summary::-webkit-details-marker { display:none; }
.zc-roster-disclosure > summary span { display:grid; place-items:center; min-width:18px; height:18px; border-radius:999px; background:var(--app-accent); color:#fff; font-size:10px; font-weight:800; }
.zc-roster-disclosure[open] > summary { margin-left:auto; margin-bottom:5px; }
.zc-roster-add { position:relative; }
.zc-roster-add > summary { display:grid; place-items:center; width:34px; height:34px; list-style:none; cursor:pointer; border:1px solid rgb(255 255 255 / 20%); border-radius:50%; background:rgb(10 14 22 / 58%); color:#fff; font-size:20px; }
.zc-roster-add > summary::-webkit-details-marker { display:none; }
.zc-roster-add > div { position:absolute; z-index:45; top:calc(100% + 6px); right:0; display:grid; gap:4px; width:min(260px,calc(100vw - 32px)); padding:6px; border:1px solid var(--app-border); border-radius:12px; background:var(--app-surface); color:var(--app-text); box-shadow:var(--app-shadow); }
.zc-roster-add > div button { display:grid; gap:2px; width:100%; padding:9px 10px; border:0; border-radius:8px; background:transparent; color:inherit; text-align:left; cursor:pointer; }
.zc-roster-add > div button:hover { background:var(--app-accent-soft); }
.zc-roster-add > div small { color:var(--app-text-muted); }
.zc-narrative-log-mode .zc-participant-bar { inset:6px 6px auto auto; }
/* `grid-template-columns` is explicit because the implicit `auto` column sizes
   to its items' max-content: one wide answer (a table, a long `pre`) stretched
   the whole dialogue box past the scene it is positioned inside. */
.zc-dialogue-box { position: absolute; inset: auto 0 0; z-index: 3; min-height: 250px; max-height: min(64%, 620px); display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(92px, auto) auto; align-content: end; gap: var(--space-3); padding: 54px clamp(20px, 5vw, 64px) 22px; border-top: 0; background: linear-gradient(180deg, transparent, rgb(12 14 20 / 58%) 24%, rgb(12 14 20 / 84%)); color: #fff; }
.zc-dialogue-box p { min-height: 2.8em; max-width: 76ch; margin: 0; font-size: clamp(16px, 1.5vw, 20px); line-height: 1.65; text-shadow: 0 1px 3px rgb(0 0 0 / 55%); }
.zc-speaker { position: static; display: block; margin:0; padding: 0; color: #fff; font-size: 18px; font-weight: 800; white-space:nowrap; text-shadow: 0 1px 3px rgb(0 0 0 / 70%); }
.zc-dialogue-answer { position: relative; width: min(100%, 1100px); min-width: 0; min-height: 96px; margin: 0 auto; padding-top: 4px; }
.zc-dialogue-scroll { width: 100%; min-width: 0; max-height: 8.2em; overflow-y: auto; padding-right: var(--space-2); white-space: pre-wrap; font-size: clamp(16px, 1.5vw, 20px); line-height: 1.65; text-shadow: 0 1px 3px rgb(0 0 0 / 55%); scrollbar-color: rgb(255 255 255 / 42%) transparent; }
[data-zc-text-scale="small"] { --zc-text-factor:.88; }
[data-zc-text-scale="default"] { --zc-text-factor:1; }
[data-zc-text-scale="large"] { --zc-text-factor:1.18; }
[data-zc-text-scale="xlarge"] { --zc-text-factor:1.36; }
[data-zc-text-scale] .zc-dialogue-box p,[data-zc-text-scale] .zc-dialogue-scroll { font-size:clamp(calc(16px * var(--zc-text-factor)),calc(1.5vw * var(--zc-text-factor)),calc(20px * var(--zc-text-factor))); }
[data-zc-text-scale] .zc-speaker { font-size:calc(18px * var(--zc-text-factor)); }
[data-zc-text-scale] :is(.zc-message-card,.zc-log-entry,.zc-form-section,.zc-settings-toggle,.zc-context-section) { font-size:calc(1rem * var(--zc-text-factor)); }
.zc-dialogue-prompt { display: none; min-height: 96px; overflow-y: auto; }
.zc-dialogue-prompt p { font-size: 16px; }
.zc-message-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.zc-inline-action { min-height: 28px; padding: 3px 10px; border: 1px solid rgb(255 255 255 / 18%); border-radius: 999px; background: rgb(255 255 255 / 10%); color: inherit; font-size: 12px; }
.zc-dialogue-box[data-scripted="true"] { min-height:220px; grid-template-rows:auto minmax(72px,auto); cursor:pointer; }
.zc-dialogue-box[data-scripted="true"] .zc-message-actions { justify-content:flex-end; }
.zc-scripted-action { min-width:120px; cursor:pointer; }
.zc-mobile-dialogue-tabs { display: none; }
.zc-chat-composer { width: min(100%, 1100px); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
.zc-chat-composer textarea,.zc-persona-designer textarea { width: 100%; min-height: 68px; max-height: 50vh; resize: vertical; overflow-y: auto; border: 1px solid rgb(255 255 255 / 20%); border-radius: var(--app-radius); background: rgb(255 255 255 / 12%); color: inherit; padding: var(--space-3); backdrop-filter: blur(8px); }
/* `.zc-backlog-input` floats over the scene at a fixed bottom offset rather
   than pushing `.zc-backlog-panel`'s edge as it grows, so its own max-height
   has to stay within what that panel reserves for it -- see the comment on
   `.zc-backlog-panel` above. The base 50vh cap is fine in the log/plain
   composer, which does not sit on top of scrollable content this way. */
.zc-narrative-chat .zc-chat-composer textarea { border:0; border-radius:0; box-shadow:none; outline-offset:2px; max-height:160px; }
.zc-chat-composer textarea::placeholder { color: rgb(255 255 255 / 62%); }
.zc-composer-attachments { display:flex; flex-wrap:wrap; gap:6px; min-width:0; }
.zc-composer-attachment { display:inline-flex; align-items:center; gap:6px; max-width:100%; min-height:28px; padding:3px 5px 3px 9px; border:1px solid rgb(255 255 255 / 20%); border-radius:999px; background:rgb(10 14 22 / 58%); color:#fff; }
.zc-composer-attachment > img { width:32px; height:32px; flex:0 0 auto; object-fit:cover; border-radius:8px; }
.zc-composer-attachment[data-uploading="true"] { opacity:.78; }
.zc-composer-attachment > span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.zc-composer-attachment button { width:22px; height:22px; padding:3px; border:0; background:transparent; color:inherit; }
.zc-composer-attachment svg { width:14px; height:14px; fill:none; stroke:currentColor; }
.zc-composer-actions { display: flex; align-items: center; justify-content: flex-end; gap: 6px; min-height: 34px; }
.zc-composer-icon,.zc-composer-picker { position: relative; display: inline-grid; place-items: center; width: 34px; height: 34px; flex: 0 0 34px; padding: 0; overflow: hidden; border: 1px solid rgb(255 255 255 / 20%); border-radius: 10px; background: rgb(10 14 22 / 58%); color: #fff; backdrop-filter: blur(8px); }
.zc-composer-icon svg,.zc-composer-picker svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.zc-composer-picker select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.zc-composer-send { width: 30px; height: 30px; flex-basis: 30px; border-radius: 9px; }
.zc-composer-send svg { width: 15px; height: 15px; }
.zc-composer-icon:focus-visible,.zc-composer-picker:focus-within { outline: 2px solid var(--app-focus); outline-offset: 2px; }
.zc-session-add-menu { position:relative; }
.zc-session-add-menu > summary { list-style:none; cursor:pointer; }
.zc-session-add-menu > summary::-webkit-details-marker,.zc-session-invite-menu > summary::-webkit-details-marker { display:none; }
.zc-session-add-popover { position:absolute; z-index:20; inset:auto auto calc(100% + 8px) 0; width:min(300px,calc(100vw - 32px)); display:grid; gap:4px; padding:6px; border:1px solid rgb(255 255 255 / 20%); border-radius:12px; background:rgb(12 16 25 / 96%); color:#fff; box-shadow:0 14px 38px rgb(0 0 0 / 35%); backdrop-filter:blur(16px); }
.zc-session-add-popover button,.zc-session-invite-menu > summary { width:100%; min-height:44px; display:grid; gap:2px; padding:8px 10px; border:0; border-radius:8px; background:transparent; color:inherit; text-align:left; cursor:pointer; }
.zc-session-add-popover button:hover,.zc-session-invite-menu > summary:hover { background:rgb(255 255 255 / 10%); }
.zc-session-add-popover small,.zc-session-add-empty { color:rgb(255 255 255 / 62%); font-size:11px; }
.zc-session-invite-menu > div { max-height:min(280px,40dvh); overflow:auto; padding:2px 0 2px 12px; }
.zc-session-add-empty { display:block; padding:10px; }
.sr-only { position:absolute!important; width:1px!important; height:1px!important; padding:0!important; margin:-1px!important; overflow:hidden!important; clip:rect(0,0,0,0)!important; white-space:nowrap!important; border:0!important; }
.zc-dialogue-control-row { width:min(100%,1100px); margin:0 auto; display:flex; align-items:center; gap:8px; min-width:0; }
.zc-dialogue-tools { margin-left:auto; min-width:0; display:flex; align-items:center; justify-content:flex-end; gap:6px; }
/* Scrollable so a long queue does not widen this row, but the visible
   scrollbar strip itself was the actual complaint -- one or two icons do not
   need a permanent scroll affordance sitting under them. Still scrollable by
   drag/wheel/keyboard, the bar itself is just not painted. */
.zc-dialogue-tools .zc-composer-activity { min-width:0; overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none; }
.zc-dialogue-tools .zc-composer-activity::-webkit-scrollbar { display:none; }
/* Only the `.zc-dialogue-tools` variant above got wrap/overflow handling.
   This one sits inside `.zc-backlog-input`, which is bounded on both sides
   (`inset` sets a fixed left AND right offset there) -- with neither wrap nor
   scroll, a queued item plus the active one pushed this row past that bound
   instead of onto a second line, and the page picked up a horizontal
   scrollbar for it. */
.zc-composer-activity { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; margin:0; }
.zc-context-memo-button { position:relative; display:inline-grid; place-items:center; width:34px; height:34px; flex:0 0 34px; padding:0; border:1px solid rgb(255 255 255 / 20%); border-radius:10px; background:rgb(10 14 22 / 58%); color:#fff; backdrop-filter:blur(8px); }
.zc-context-memo-button svg { width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.zc-context-memo-button:disabled { opacity:.42; }
.zc-agent-work-status { display:flex; align-items:center; gap:8px; width:min(100%,1100px); margin:0 auto 6px; padding:7px 10px; border-radius:10px; background:rgb(10 14 22 / 72%); color:#fff; font-size:13px; backdrop-filter:blur(8px); }
.zc-agent-work-status svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.8; animation:zc-activity-pulse 1.2s ease-in-out infinite; }

.zc-settings-page { display:grid; gap:var(--space-3); }
.zc-settings-page :is(label, fieldset, section, div) { min-width:0; }
.zc-settings-page :is(input:not([type="radio"]), select, textarea) { width:100%; min-width:0; max-width:100%; }
.zc-settings-quick { display:grid; gap:var(--space-3); order:-1; }
.zc-settings-toggle { min-width:0; margin:0; padding:var(--space-3); border:1px solid var(--app-border); border-radius:var(--app-radius); background:var(--app-surface); }
.zc-settings-toggle legend { padding:0 6px; font-weight:750; color:var(--app-text); }
.zc-segmented-toggle { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:4px; padding:4px; border-radius:12px; background:var(--app-surface-muted); }
.zc-segmented-toggle label { min-width:0; cursor:pointer; }
.zc-segmented-toggle input { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); opacity:0; pointer-events:none; }
.zc-segmented-toggle span { display:flex; min-height:38px; align-items:center; justify-content:center; padding:7px 10px; border-radius:9px; color:var(--app-text-muted); font-weight:700; text-align:center; }
.zc-segmented-toggle input:checked + span { background:var(--app-surface); color:var(--app-accent); box-shadow:var(--app-shadow); }
.zc-segmented-toggle input:focus-visible + span { outline:2px solid var(--app-focus); outline-offset:2px; }
.zc-settings-back svg { width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.zc-activity-button,.zc-modal-icon { position:relative; display:inline-grid; place-items:center; width:34px; height:34px; padding:0; border:1px solid var(--app-border); border-radius:10px; background:var(--app-surface); color:var(--app-text); }
.zc-activity-button svg,.zc-modal-icon svg,.zc-activity-dialog header>span svg { width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.zc-activity-button.is-working svg { animation:zc-activity-pulse 1.2s ease-in-out infinite; }
.zc-activity-order { position:absolute; right:-4px; top:-5px; min-width:16px; height:16px; padding:0 3px; border-radius:999px; background:var(--app-accent); color:#fff; font-size:9px; line-height:16px; }
.zc-activity-count { position:absolute; right:-5px; top:-6px; min-width:17px; height:17px; padding:0 4px; border-radius:999px; background:var(--app-accent); color:#fff; font-size:10px; line-height:17px; }
@keyframes zc-activity-pulse { 50% { opacity:.42; transform:scale(.9); } }
.zc-activity-dialog { width:min(92vw,520px); padding:0; border:1px solid var(--app-border); border-radius:14px; background:var(--app-surface); color:var(--app-text); box-shadow:0 24px 80px rgb(0 0 0 / 35%); }
.zc-activity-dialog::backdrop { background:rgb(0 0 0 / 48%); backdrop-filter:blur(3px); }
.zc-activity-dialog-shell { display:grid; gap:12px; padding:14px; }
.zc-activity-dialog header,.zc-activity-dialog footer { display:flex; align-items:center; gap:8px; }
.zc-activity-dialog header strong { flex:1; }
.zc-activity-dialog footer { justify-content:flex-end; }
.zc-activity-dialog textarea { width:100%; min-height:150px; resize:vertical; padding:12px; border:1px solid var(--app-border); border-radius:10px; background:var(--app-surface-muted); color:inherit; }
.zc-modal-icon.danger { color:var(--app-danger,#d94a4a); }
/* The bottom inset here and the composer textarea's max-height (below) are
   two independent numbers that both have to fit inside the same space --
   this reserved 112px for a textarea that could resize (`resize: vertical`)
   up to 50vh. Typing or pasting a few lines grew the composer past its
   reserved gap and it covered the last message instead of the panel
   shrinking for it. 200px/160px actually fit each other. */
.zc-backlog-panel { position: absolute; inset: 72px clamp(8px, 1.5vw, 20px) 200px; z-index: 3; overflow-y: auto; padding: clamp(10px, 1.4vw, 18px); border: 0; border-radius: var(--app-radius-lg); background: rgb(13 15 22 / 52%); color: #fff; box-shadow: none; backdrop-filter: blur(10px) saturate(80%); }
.zc-narrative-log-mode[data-scripted="true"] .zc-backlog-panel { bottom:20px; }
.zc-chat-log-messages { display: grid; gap: var(--space-3); }
.zc-log-message { max-width: 82%; padding: 12px 16px; border: 1px solid rgb(255 255 255 / 14%); border-radius: var(--app-radius-lg); background: rgb(255 255 255 / 10%); text-shadow: 0 1px 2px rgb(0 0 0 / 60%); }
.zc-log-message[data-role="assistant"] { justify-self: stretch; max-width: 100%; padding: 8px 0 10px 12px; border: 0; border-left: 1px solid rgb(255 255 255 / 10%); border-radius: 0; background: transparent; box-shadow: none; }
.zc-log-message[data-role="user"] { justify-self: end; background: color-mix(in srgb, var(--app-accent) 24%, transparent); }
/* Error text was a fixed pale pink chosen for a dark scene, so on a light theme
   it became pale pink on a pale pink tint and the message could not be read.
   Both the tint and the text now derive from the active text colour, which keeps
   the red signal while following the theme and the scene tone. */
.zc-log-message[data-role="error"],.zc-log-message[data-variant="error"] { justify-self:stretch; max-width:100%; border-color:color-mix(in srgb,var(--app-danger) 55%,var(--app-border)); background:color-mix(in srgb,var(--app-danger) 12%,var(--app-surface)); color:color-mix(in srgb,var(--app-danger) 70%,var(--app-text)); }
.zc-log-message[data-role="error"] :is(strong,.zc-message-title),.zc-log-message[data-variant="error"] :is(strong,.zc-message-title) { color:color-mix(in srgb,var(--app-danger) 85%,var(--app-text)); }
.zc-log-message[data-role="error"] time,.zc-log-message[data-variant="error"] time { color:color-mix(in srgb,var(--app-danger) 45%,var(--app-text)); }
.zc-log-message[data-state="queued"] { border-style:dashed; opacity:.88; }
.zc-log-message[data-state="running"] { border-color:color-mix(in srgb,var(--app-accent) 55%,transparent); }
.zc-message-state { margin-inline-start:auto; color:var(--app-text-muted); font-size:12px; font-weight:800; }
/* Directly visible action icons on a message (stop/steer/edit/cancel) --
   replaced a "⋮" menu that hid them behind an extra click. */
.zc-message-icon-button { display:grid; place-items:center; width:28px; height:28px; padding:0; border:1px solid var(--app-border); border-radius:8px; background:var(--app-surface); color:var(--app-text); cursor:pointer; }
.zc-message-icon-button svg { width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.zc-message-icon-button:hover { background:var(--app-surface-muted); }
.zc-message-icon-button:disabled { opacity:.4; cursor:not-allowed; }
.zc-message-icon-button.danger { color:var(--app-danger,#e5484d); border-color:color-mix(in srgb,var(--app-danger,#e5484d) 40%,var(--app-border)); }
/* Transcript text is meant to be selected and copied -- stated outright so an
   ancestor's `user-select:none` (the tree rows carry one) cannot reach it, and
   so a long-press on a phone offers the selection handles rather than being
   swallowed as a tap. The controls in the header stay unselectable so dragging
   across a message does not pick up "복사" and the timestamp. */
.zc-log-message [data-message-body],
.zc-log-message [data-message-body] * { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
.zc-log-message header { -webkit-user-select: none; user-select: none; }
.zc-plain-chat { display:grid; grid-template-rows:auto minmax(0,1fr) auto; gap:var(--space-3); width:100%; height:100%; min-height:0; }
.zc-plain-chat-head { display:flex; align-items:end; justify-content:space-between; gap:var(--space-3); }
.zc-plain-chat-head h1 { margin:2px 0 0; }
.zc-plain-chat-head span { color:var(--app-text-muted); }
/* Same top placement as narrativeChatPage's `zc-dialogue-tools` -- the
   composerActivity icons belong up here on both chat views, not down by the
   composer, which is where log view's own (differently laid out) controls are. */
.zc-plain-chat-head-tools { display:flex; align-items:center; gap:var(--space-2); margin-inline-start:auto; }
.zc-plain-answer { min-height:0; overflow:auto; padding:clamp(18px,3vw,42px); border:1px solid var(--app-border); border-radius:var(--app-radius-lg); background:var(--app-surface); box-shadow:var(--app-shadow-sm); }
.zc-plain-answer[data-role="error"] { border-color:color-mix(in srgb,var(--app-danger) 60%,var(--app-border)); background:color-mix(in srgb,var(--app-danger) 9%,var(--app-surface)); }
.zc-plain-input { min-height:0; }
.zc-plain-input .zc-chat-composer textarea { min-height:clamp(96px,18vh,190px); background:var(--app-surface); color:var(--app-text); }
/* Plain presentation is theme UI, never a character scene. Keep this
   explicit instead of depending on asynchronous scene-image cleanup. */
/* Plain presentation restores the user's own theme. Falling back to --app-bg was
   not enough on its own: while the scene theme was still applied it had already
   redefined --app-bg to the sampled wallpaper colour, so "returning to the base
   theme" returned to the scene. These rules revert the scene's token overrides so
   the plain surface is the plain theme even if the scene attribute lingers. */
.app-shell:has([data-conversation-presentation="plain"]) {
  /* Custom properties inherit, and the active theme declares these on :root, so
     `inherit` restores the theme value the scene had shadowed on .app-shell. */
  --app-bg: inherit;
  --app-surface: inherit;
  --app-surface-muted: inherit;
  --app-surface-raised: inherit;
  --app-border: inherit;
  --app-border-strong: inherit;
  --app-text: inherit;
  --app-text-muted: inherit;
  --app-accent-soft: inherit;
  --app-shadow: inherit;
  background-color: var(--app-bg);
  background-image: none;
}
.app-shell:has([data-conversation-presentation="plain"]) .primary { background-color:var(--app-bg); background-image:none; }
.app-shell:has([data-conversation-presentation="plain"]) :is(.topbar, .context-panel, .right-panel) {
  background: var(--app-surface);
  color: var(--app-text);
  backdrop-filter: none;
}
.app-shell:has([data-conversation-presentation="plain"]) :is(.zc-scene-caption, .zc-dialogue-box, .zc-character-name) { text-shadow: none; }
[data-conversation-presentation="plain"] .zc-narrative-scene { background-color:transparent; background-image:none; }
[data-conversation-presentation="plain"] :is(.zc-character-stage,.zc-character-portrait,.zc-character-image) { display:none; }
.zc-inline-task-controls { display:flex; align-items:center; justify-content:flex-end; gap:8px; margin-bottom:var(--space-2); color:var(--app-text-muted); }
/* Plain mode has no scene image to float over, so it does not need the
   absolute-positioned overlay layout character mode uses (a fixed 200px
   bottom inset reserved for the composer regardless of actual content,
   which left a large dead gap under a short message list, plus a muted
   panel background that read as barely-there against the flat page
   background). Real flex flow instead: the panel takes the space it
   actually needs and the composer sits directly under it. */
.zc-narrative-log-mode[data-chat-mode="plain"] .zc-narrative-scene { display:flex; flex-direction:column; align-items:stretch; justify-content:flex-start; min-height:0; background:var(--app-bg); color:var(--app-text); }
.zc-narrative-log-mode[data-chat-mode="plain"] .zc-scene-caption { flex:0 0 auto; }
/* `--app-border` is a near-invisible hairline by design (it is tuned for
   splitting surfaces that already contrast, like a card on a page) --
   against this panel's own `--app-surface` sitting on the near-identical
   `--app-bg`, that hairline all but disappeared. `--app-border-strong`
   plus a real shadow gives the panel an edge that reads without needing
   anything inside it focused first. */
.zc-narrative-log-mode[data-chat-mode="plain"] .zc-backlog-panel { position:static; inset:auto; flex:1 1 auto; min-height:0; border:1px solid var(--app-border-strong); box-shadow:var(--app-shadow); background:var(--app-surface); color:var(--app-text); text-shadow:none; }
.zc-narrative-log-mode[data-chat-mode="plain"] .zc-backlog-input { position:static; inset:auto; flex:0 0 auto; margin-top:var(--space-2); color:var(--app-text); }
/* `.zc-narrative-chat .zc-chat-composer textarea` strips the textarea's own
   border to 0 everywhere (it normally relies on the scene's floating card
   look for an edge) -- plain mode has no such card, so without this the
   composer had no visible boundary at all until the browser's own :focus
   outline appeared, which read as "no border unless focused". */
.zc-narrative-log-mode[data-chat-mode="plain"] .zc-chat-composer textarea { border:1px solid var(--app-border-strong); border-radius:var(--app-radius); background:var(--app-surface); }
.zc-log-message header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.zc-log-message p { margin: var(--space-1) 0 0; white-space: pre-wrap; line-height: 1.55; }
.zc-message-details { display: grid; }
.zc-message-details summary,.zc-node-reports summary { cursor: pointer; list-style: none; }
.zc-message-details summary::-webkit-details-marker,.zc-node-reports summary::-webkit-details-marker { display: none; }
.zc-message-details[open] .zc-message-preview { display: none; }
.zc-message-details summary { order: 2; display: grid; justify-items: end; gap: var(--space-1); margin-top: var(--space-2); }
.zc-message-details > p { order: 1; }
.zc-more-label { display: inline-block; color: #9fe2d7; font-size: 12px; font-weight: 800; }
.zc-message-details[open] .zc-more-label::after { content: " 접기"; }
.zc-message-details[open] .zc-more-label { font-size: 0; }
.zc-message-details[open] .zc-more-label::after { font-size: 12px; }
.zc-node-reports { margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px solid rgb(255 255 255 / 14%); }
.zc-node-reports > summary { color: #9fe2d7; font-weight: 800; }
.zc-node-reports > div { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.zc-node-reports article { padding: var(--space-2); border-radius: var(--app-radius); background: rgb(0 0 0 / 18%); }
.zc-node-reports article span { float: right; color: #9fe2d7; font-size: 12px; }
.zc-node-reports .zc-report-preview { margin: var(--space-1) 0 0; font-size: 13px; opacity: .82; overflow-wrap: anywhere; }
.zc-node-reports .zc-report-body > summary { margin-top: var(--space-1); color: #9fe2d7; font-size: 12px; cursor: pointer; list-style: none; }
.zc-node-reports .zc-report-body > summary::-webkit-details-marker { display: none; }
.zc-node-reports .zc-report-body[open] > summary { margin-bottom: var(--space-1); }
.zc-node-reports > div > .text-button { justify-self: start; }
.zc-backlog-input { position: absolute; inset: auto clamp(14px, 5vw, 60px) 22px; z-index: 4; color: #fff; }
.zc-compact-viewer-page { height: 100%; min-height: 0; display: grid; grid-template-rows: auto minmax(0,1fr); gap: var(--space-3); }
.zc-compact-viewer-page.has-navigation { grid-template-rows: auto auto minmax(0,1fr); }
.zc-compact-viewer-page.without-header { grid-template-rows: minmax(0,1fr); gap: 0; }
.zc-compact-viewer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; }
.zc-compact-viewer-head > div { display: flex; align-items: baseline; gap: var(--space-2); }
.zc-compact-viewer-head h2 { margin: 0; font-size: clamp(20px,2vw,28px); }
.zc-compact-viewer-head span { color: var(--app-text-muted); font-size: 11px; font-weight: 800; }
.zc-compact-viewer-head .page-bar-actions { display: flex; gap: var(--space-2); }
.zc-compact-viewer-head button { min-height: 32px; padding: 0 var(--space-3); }
.zc-viewer-navigation { padding: 0 var(--space-1); }
.zc-viewer-navigation input { display: block; width: 100%; margin: 0; accent-color: var(--app-accent); }
.zc-compact-viewer-body { min-height: 0; overflow: auto; }
.zc-compact-viewer-body .text-surface,.zc-compact-viewer-body .image-surface { min-height: 0; height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; }
.zc-compact-viewer-body .text-viewer-body { padding: var(--space-3) 0; }
.zc-compact-viewer-body .zc-text-editor textarea { width: 100%; height: 100%; min-height: 0; resize: none; box-sizing: border-box; }
.zc-compact-viewer-body .image-stage { height: 100%; min-height: 0; padding: 0; border: 0; background: transparent; }
.zc-compact-viewer-body .image-stage img { max-width: 100%; max-height: 100%; object-fit: contain; }
.zc-context-rail,.zc-context-section { display: grid; gap: var(--space-3); }
.zc-context-section { padding-bottom: var(--space-4); border-bottom: 1px solid var(--app-border); }
.zc-context-section-head { display: flex; justify-content: space-between; }
.zc-context-section button { display: grid; gap: 2px; width: 100%; padding: var(--space-3); border: 1px solid var(--app-border); border-radius: var(--app-radius); background: var(--app-surface-muted); color: var(--app-text); text-align: left; }
.zc-context-section small { color: var(--app-text-muted); }
.zc-settings-page,.zc-form-section,.zc-persona-fields { display: grid; gap: var(--space-4); }
.agent-character-view { display:grid; gap:var(--space-4); }
.agent-settings-head { display:flex; align-items:center; gap:var(--space-4); }
.agent-settings-head img { width:min(220px,38vw); max-height:280px; object-fit:contain; object-position:center bottom; }
.agent-settings-head h2,.agent-settings-head p { margin:0; }
.agent-settings-facts { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:var(--space-2); margin:0; }
.agent-settings-facts > div { min-width:0; padding:var(--space-3); border:1px solid var(--app-border); border-radius:var(--app-radius); background:var(--app-surface-muted); }
.agent-settings-facts dt { color:var(--app-text-muted); font-size:12px; font-weight:800; }
.agent-settings-facts dd { margin:4px 0 0; overflow-wrap:anywhere; }
.zc-form-section { border: 1px solid var(--app-border); border-radius: var(--app-radius-lg); padding: var(--space-4); }
.zc-persona-designer { display: grid; gap: var(--space-5); }
.zc-persona-preview { display: grid; place-items: center; gap: var(--space-2); min-height: 240px; padding: var(--space-5); border: 1px solid var(--app-border); border-radius: var(--app-radius-lg); background: var(--app-surface-muted); text-align: center; }
.zc-persona-avatar { display: grid; place-items: center; width: 112px; height: 112px; border-radius: 50%; background: var(--app-accent-soft); color: var(--app-accent); font-size: 54px; }
@media (min-width: 760px) { .zc-persona-designer { grid-template-columns: minmax(240px,.7fr) minmax(0,1.3fr); } }

@media (min-width: 700px) {
  /* Plain chat uses the full width of its primary region while preserving
     the same available side rails as character chat. */
  .primary:has(.zc-conversation-page[data-chat-mode="plain"]) > :is(.timeline,.page-host) { width:100%; max-width:none; margin:0; }
  .primary:has(.zc-narrative-chat) { padding:0; border:0; outline:0; box-shadow:none; }
  .primary:has(.zc-narrative-chat) > :is(.timeline,.page-host) { width:100%; max-width:none; margin:0; border:0; border-radius:0; outline:0; box-shadow:none; }
  .app-shell:has(.zc-narrative-chat) .right-panel { border-left:0; }
}
@media (min-width: 700px) and (max-height: 700px) {
  .zc-dialogue-box {
    min-height: 0;
    max-height: calc(var(--app-viewport-height) - var(--frame-topbar));
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: var(--space-2);
    padding: 24px clamp(20px, 3vw, 48px) 12px;
  }
  .zc-dialogue-answer { min-height: 0; overflow-y: auto; }
  .zc-dialogue-scroll { max-height: min(5.4em, 18dvh); }
  .zc-chat-composer { min-height: 0; }
  .zc-narrative-chat .zc-chat-composer textarea {
    min-height: 52px;
    max-height: min(18dvh, 92px);
    resize: none;
  }
}
@media (max-width: 699px) { .app-shell[data-surface-mode="mobile"] .zc-narrative-chat { min-height:0; border-radius:0; }.app-shell[data-surface-mode="mobile"] .zc-character-stage .zc-character-portrait { display:grid; bottom:clamp(150px,24dvh,230px); width:min(58vw,330px); height:min(72dvh,82%); }.app-shell[data-surface-mode="mobile"] .zc-character-stage[data-character-count]:not([data-character-count="1"]):not([data-character-count="2"]) .zc-character-portrait { width:min(46vw,270px); }.app-shell[data-surface-mode="mobile"] .zc-chat-composer { grid-template-columns:1fr; }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box { height:46dvh; min-height:300px; max-height:50dvh; grid-template-rows:auto minmax(0,1fr); padding:12px var(--space-3) var(--space-3); }.app-shell[data-surface-mode="mobile"] .zc-mobile-dialogue-tabs { display:flex; gap:var(--space-2); }.app-shell[data-surface-mode="mobile"] .zc-mobile-dialogue-tabs button { min-height:30px; padding:0 12px; border:1px solid rgb(255 255 255 / 18%); border-radius:999px; background:rgb(255 255 255 / 8%); color:#fff; }.app-shell[data-surface-mode="mobile"] .zc-mobile-dialogue-tabs button[aria-pressed="true"] { background:rgb(255 255 255 / 20%); font-weight:800; }.app-shell[data-surface-mode="mobile"] .zc-dialogue-answer { min-height:0; overflow-y:auto; }.app-shell[data-surface-mode="mobile"] .zc-speaker { position:static; display:block; margin-bottom:var(--space-1); }.app-shell[data-surface-mode="mobile"] .zc-backlog-panel { inset:70px var(--space-2) 150px; }.app-shell[data-surface-mode="mobile"] .zc-backlog-input { right:var(--space-2); bottom:var(--space-2); left:var(--space-2); } }
@media (max-width: 699px) { .app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="answer"] { grid-template-rows:auto auto minmax(0,1fr); }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="answer"] .zc-chat-composer { display:none; }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] { grid-template-rows:auto minmax(0,1fr); }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-dialogue-control-row,.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-dialogue-answer { display:none; }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-chat-composer { width:100%; height:100%; min-height:0; align-self:stretch; display:grid; grid-template-rows:minmax(0,1fr) auto; }.app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-chat-composer textarea { width:100%; height:100%!important; min-height:0; max-height:none; resize:none; } }
@media (max-width: 699px) { .app-shell[data-surface-mode="mobile"] .zc-narrative-scene { background-image: var(--zc-scene-bg-mobile,var(--zc-scene-bg)); } }

@media (max-width: 699px) {
  /* The composer form has three children -- textarea, the attachment chips,
     and the action row -- but the prompt pane declared only two rows, so the
     moment an attachment existed the third child landed in an implicit row
     that the fixed-height dialogue box had no space for, and the chips drew
     on top of the controls. The textarea's `height:100%` made it worse by
     claiming the whole first row regardless. Attachments get their own row,
     and the textarea yields to them instead of overlapping. */
  .app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-chat-composer {
    grid-template-rows: minmax(0, 1fr) auto auto;
  }
  .app-shell[data-surface-mode="mobile"] .zc-dialogue-box[data-mobile-pane="prompt"] .zc-chat-composer textarea {
    min-height: 0;
  }
  /* A long file name must not push the action row off the box. */
  .zc-composer-attachments { max-height: 30dvh; overflow-y: auto; }

  /* The attachment menu opens upward out of the action row, which sits at the
     bottom of an absolutely positioned dialogue box (`z-index:3`). Without its
     own stacking context above that, and with the row free to clip it, the
     menu opened behind the composer and read as "the picker does nothing". */
  .zc-composer-actions { overflow: visible; }
  .zc-session-add-menu[open] { z-index: 90; }
  .zc-session-add-popover { z-index: 90; max-height: min(60dvh, 420px); overflow-y: auto; }
}

/* Explicit surface preferences remain authoritative, including on a phone. */
@media (max-width: 699px) {
  body { min-width: 0; overflow-x: hidden; }
  /* Surface mode is a user choice; viewport width is a fact. A desktop surface
     kept its fixed left/right panel columns on a narrow viewport, making the grid
     wider than the screen and pushing topbar actions out of reach. Below this
     breakpoint every surface collapses to a single column. */
  .app-shell,
  .app-shell[data-surface-mode="desktop"],
  .app-shell[data-surface-mode="auto"] {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--frame-topbar) minmax(0, 1fr);
    grid-template-areas: "topbar" "primary";
  }
  /* Side panels become overlays at this width instead of stealing grid columns. */
  .app-shell[data-surface-mode="desktop"] .context-panel,
  .app-shell[data-surface-mode="desktop"] .right-panel { position: fixed; z-index: 80; max-width: min(88vw, 320px); }
  .app-shell[data-surface-mode="desktop"]:not([data-context-open="true"]) .context-panel,
  .app-shell[data-surface-mode="desktop"]:not([data-right-open="true"]) .right-panel { display: none; }
  .topbar { min-width: 0; max-width: 100%; }
  .topbar-actions { min-width: 0; flex-wrap: wrap; justify-content: flex-end; }
  .primary, .page-host { min-width: 0; max-width: 100%; }
  /* The trigger is inside a narrow action cell. Anchoring a 300px popover to
     that cell puts its left edge off-screen (observed at x=-118px on 390px),
     leaving only a blank-looking slice visible. Compact popovers belong to the
     viewport, not to the trigger's tiny containing block. */
  .zc-session-add-popover {
    position: fixed;
    inset: auto 12px 68px 12px;
    width: auto;
    max-height: min(60dvh, 420px);
    z-index: 140;
  }
  .app-shell[data-surface-mode="mobile"] {
    width: 100%;
    min-width: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--frame-topbar) minmax(0, 1fr);
    grid-template-areas: "topbar" "primary";
  }
  .app-shell[data-surface-mode="mobile"] .topbar { width: 100%; min-width: 0; }
  .app-shell[data-surface-mode="mobile"] .topbar-actions { min-width: 0; overflow: hidden; }
  .app-shell[data-surface-mode="mobile"] .primary { width: 100%; min-width: 0; padding: 0; overflow-x: hidden; }
  .app-shell[data-surface-mode="mobile"] .page-host,
  .app-shell[data-surface-mode="mobile"] .zc-narrative-chat,
  .app-shell[data-surface-mode="mobile"] .zc-narrative-scene { width: 100%; min-width: 0; }
  /* A phone cannot afford a code block whose preserved whitespace is wider
     than the answer. Keep semantic tables locally scrollable, but wrap prose
     and code-like markdown inside the message width. */
  .zc-conversation-message .markdown pre,
  .zc-log-message .markdown pre,
  .zc-dialogue-scroll.markdown pre,
  .zc-plain-answer .markdown pre {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
    overflow-x: hidden;
  }
}
@media (max-width: 699px) {
  .zc-participant-bar { inset: 6px 6px auto auto; flex-direction: column; align-items: end; max-width: calc(100% - 12px); }
  .zc-narrative-log-mode .zc-participant-bar { inset: 6px 6px auto auto; }
  .zc-scene-caption { inset: 6px auto auto 6px; max-width: calc(100% - 50px); }
  .zc-scene-caption > strong { max-width: 112px; overflow: hidden; text-overflow: ellipsis; }
  .zc-participant-list { width: 100%; justify-content: flex-end; }
  .zc-participant-invite { margin-left: auto; }
  .zc-discussion-mode { align-self: flex-end; flex-direction: row; flex-wrap: wrap; gap: 6px; padding: 0; background: none; backdrop-filter: none; }
}
/* Approval requests previously styled themselves with --zc-surface/--zc-border,
   which are not tokens in this system, so they always fell back to a hard-coded
   white card with unstyled buttons. On a dark scene that produced a white box
   with near-invisible controls. These use the real tokens, so the card follows
   the theme and the scene tone, and each action states its own weight. */
.zc-approval-inbox{display:grid;gap:.5rem;margin:.5rem 0}
.zc-approval-request{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem .875rem;
  border:1px solid color-mix(in srgb,var(--app-warning) 55%,var(--app-border));
  border-left:3px solid var(--app-warning);
  border-radius:.75rem;
  background:color-mix(in srgb,var(--app-warning) 10%,var(--app-surface));
  color:var(--app-text);
}
.zc-approval-request strong{color:var(--app-text);font-size:.95rem}
.zc-approval-request p{margin:.2rem 0 0;color:var(--app-text-muted);font-size:.875rem;overflow-wrap:anywhere}
.zc-approval-request > div:first-child{min-width:0}
.zc-approval-actions{display:flex;flex-wrap:wrap;gap:.4rem;flex:0 0 auto}
.zc-approval-actions button{
  min-height:2.25rem;padding:0 .875rem;border-radius:.5rem;cursor:pointer;
  font-size:.875rem;font-weight:600;white-space:nowrap;
  border:1px solid var(--app-border-strong);
  background:var(--app-surface-raised);
  color:var(--app-text);
}
.zc-approval-actions button:hover{border-color:var(--app-accent);background:var(--app-accent-soft)}
.zc-approval-actions button:focus-visible{outline:2px solid var(--app-focus);outline-offset:2px}
.zc-approval-actions button[data-zc-approval-decision="approve_once"]{
  border-color:transparent;background:var(--app-accent);color:#fff;
}
.zc-approval-actions button[data-zc-approval-decision="approve_once"]:hover{background:var(--app-accent-hover)}
.zc-approval-actions button[data-zc-approval-decision="deny"]{
  border-color:color-mix(in srgb,var(--app-danger) 55%,var(--app-border));
  color:color-mix(in srgb,var(--app-danger) 80%,var(--app-text));
}
.zc-approval-actions button[data-zc-approval-decision="deny"]:hover{
  background:color-mix(in srgb,var(--app-danger) 14%,var(--app-surface));border-color:var(--app-danger);
}
@media(max-width:720px){.zc-approval-request{align-items:stretch;flex-direction:column}.zc-approval-actions button{flex:1}}

/* Reveal controls for an incrementally shown list or tree branch. They sit
   together on one short row under the items they govern: rendering them as two
   separate list rows doubled the height of the thing they exist to shorten and
   made them read as entries in the list. */
.zc-incremental-controls { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.zc-incremental-controls button {
  padding: 2px 8px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--app-border); background: transparent;
  color: var(--app-text-muted); font-size: .75rem; line-height: 1.6;
}
.zc-incremental-controls button:hover { border-color: var(--app-accent); color: var(--app-text); background: var(--app-accent-soft); }
.zc-incremental-controls button:focus-visible { outline: 2px solid var(--app-focus); outline-offset: 2px; }
.zc-incremental-controls button span { opacity: .7; }
.zc-tree-incremental {
  display: flex; align-items: center; min-height: 0;
  padding: 2px 6px 6px calc(var(--space-3) + (var(--tree-depth, 0) * 14px));
  background: none; border: 0;
}

/* Provider mark used where the product speaks plainly. Sized to match the
   character portrait it replaces so the sidebar does not shift between modes. */
.agent-provider-icon { display: inline-grid; place-items: center; inline-size: 22px; block-size: 22px; color: var(--app-text-muted); }
.agent-provider-icon svg { inline-size: 18px; block-size: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tree-item[aria-selected="true"] .agent-provider-icon,
.zc-tree-item[aria-selected="true"] .agent-provider-icon { color: var(--app-text); }

/* Item count for the selected tab. It belongs to the tab, so it sits under the
   tab row and its actions, immediately above the items it counts, rather than in
   a panel header that also had to carry a redundant "탐색" title. */
.context-count { margin: 0; padding: 2px var(--space-3) 4px; font-size: .75rem; color: var(--app-text-muted); }
.context-count:empty { display: none; }

/* Search is a toggle on the actions row, revealed under it. Every tab uses it,
   not sessions alone, and both products present it the same way. */
.context-filter { padding: 0 var(--space-3) var(--space-2); }
.context-filter[hidden] { display: none; }
.session-search-button[aria-expanded="true"] { color: var(--app-accent); border-color: var(--app-accent); }

/* A scrollbar that belongs to the theme instead of the platform default. */
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--app-text-muted) 45%, transparent) transparent; }
*::-webkit-scrollbar { inline-size: 10px; block-size: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  border: 3px solid transparent; border-radius: 999px; background-clip: content-box;
  background-color: color-mix(in srgb, var(--app-text-muted) 42%, transparent);
}
*::-webkit-scrollbar-thumb:hover { background-color: color-mix(in srgb, var(--app-text-muted) 68%, transparent); }
*::-webkit-scrollbar-corner { background: transparent; }

/* Artifact rows are cards in every product. Both products already emit this
   markup; neither had a rule for it, so the list read as undifferentiated text. */
.artifact-list { display: grid; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
.artifact-list-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: var(--space-2); padding: var(--space-2); border: 1px solid var(--app-border);
  border-radius: var(--app-radius-md); background: var(--app-surface-muted);
}
.artifact-list-item + .artifact-list-item { margin-block-start: var(--space-2); }
.artifact-list-item:hover { border-color: color-mix(in srgb, var(--app-accent) 45%, var(--app-border)); }
.artifact-list-item[data-selected="true"] {
  border-color: var(--app-accent);
  background: color-mix(in srgb, var(--app-accent) 12%, var(--app-surface-muted));
}
.artifact-type-mark {
  display: grid; place-items: center; inline-size: 34px; block-size: 34px;
  border-radius: var(--app-radius-sm); background: color-mix(in srgb, var(--app-accent) 16%, transparent);
  color: var(--app-accent); font-size: .62rem; font-weight: 700; letter-spacing: .02em;
}
.artifact-main { display: grid; gap: 2px; min-inline-size: 0; }
.artifact-main strong { overflow: hidden; font-size: .84rem; text-overflow: ellipsis; white-space: nowrap; }
/* Constellation's second line is a short timestamp/status pair and never
   needed to break. AgentBridge's is a full filesystem path -- long, and with
   no spaces to wrap on -- so it must be allowed to break anywhere rather than
   push the card wide or run under the action buttons. */
.artifact-main span { display: block; overflow: hidden; color: var(--app-text-muted); font-size: .72rem; overflow-wrap: anywhere; }
.artifact-actions { display: flex; gap: 4px; }
.artifact-path { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: var(--space-2) var(--space-3) 0; color: var(--app-text-muted); font-size: .74rem; }
.artifact-path button { border: 0; background: none; color: inherit; cursor: pointer; font: inherit; }
.artifact-path button[aria-current="true"] { color: var(--app-text); font-weight: 700; }
/* `object-fit` only affects replaced elements (the `img` inside), not the
   `button` it was set on -- an unconstrained generated image (easily
   1024x1024) had nothing here actually clipping it to this box. */
.artifact-thumb { display: grid; place-items: center; overflow: hidden; inline-size: 34px; block-size: 34px; border: 0; padding: 0; border-radius: var(--app-radius-sm); background: var(--app-surface-muted); cursor: pointer; }
.artifact-thumb img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
/* Never styled -- rows sat as plain unboxed text next to the new fixed-size
   image thumbnails, uneven with them. Matches `.artifact-thumb`'s footprint
   so a mixed image/file list stays one row height. */
.file-kind { display: grid; place-items: center; inline-size: 34px; block-size: 34px; border-radius: var(--app-radius-sm); background: color-mix(in srgb, var(--app-text-muted) 14%, transparent); color: var(--app-text-muted); font-size: .62rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; }

/* An agent whose CLI is missing is greyed rather than labelled: the row itself
   carries the state, and "설치필요" only appears where action is needed. */
.agent-unavailable :is(img, svg, .agent-provider-icon) { filter: grayscale(1); opacity: .45; }
.agent-unavailable { color: var(--app-text-muted); }
.agent-install-warning { margin: 0; color: var(--app-warning, #d08700); font-size: .78rem; font-weight: 600; }

/* The sheet covers the page, so it always offers a way back out. */
.sheet-head { display: flex; justify-content: flex-end; align-items: center; }
.sheet-close svg { inline-size: 18px; block-size: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* Tasks that have gone quiet. Approval and silence are different problems with
   different answers, so they do not look the same. */
.stalled-notice { display: grid; gap: var(--space-2); margin: 0; padding: var(--space-2) var(--space-3); list-style: none; }
.stalled-notice li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px var(--space-2);
  align-items: center; padding: var(--space-2); border: 1px solid var(--app-border);
  border-radius: var(--app-radius-md); background: var(--app-surface-muted);
}
.stalled-notice strong { grid-column: 1; overflow: hidden; font-size: .8rem; text-overflow: ellipsis; white-space: nowrap; }
.stalled-notice span { grid-column: 1; color: var(--app-text-muted); font-size: .72rem; }
.stalled-notice button { grid-column: 2; grid-row: 1 / span 2; }
.stalled-notice li[data-stalled-reason="approval"] {
  border-color: color-mix(in srgb, var(--app-accent) 50%, var(--app-border));
  background: color-mix(in srgb, var(--app-accent) 10%, var(--app-surface-muted));
}
.stalled-notice li[data-stalled-reason="silent"] {
  border-color: color-mix(in srgb, var(--app-danger) 45%, var(--app-border));
  background: color-mix(in srgb, var(--app-danger) 8%, var(--app-surface-muted));
}

/* Portrait-led combat surface. Domain rules stay in the engine; this page only
   renders display models and emits semantic action identifiers. */
.zc-combat-surface { display:grid; grid-template-rows:auto auto minmax(0,1fr) minmax(112px,.36fr) auto; width:100%; height:100%; min-height:0; overflow:hidden; background:radial-gradient(circle at 72% 30%,color-mix(in srgb,var(--app-danger) 12%,transparent),transparent 35%),var(--app-bg); color:var(--app-text); }
.zc-combat-head { display:flex; justify-content:space-between; gap:var(--space-3); align-items:center; padding:var(--space-3) var(--space-4); border-bottom:1px solid var(--app-border); background:color-mix(in srgb,var(--app-surface) 90%,transparent); }
.zc-combat-head p,.zc-combat-head h1,.zc-combat-head span { margin:0; }
.zc-combat-head p { color:var(--app-accent); font-size:.7rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase; }
.zc-combat-head h1 { margin-block:2px; font-size:clamp(1.25rem,3vw,2rem); }
.zc-combat-head span { color:var(--app-text-muted); font-size:.78rem; }
.zc-combat-head>strong { flex:0 0 auto; padding:6px 10px; border:1px solid var(--app-border-strong); border-radius:999px; background:var(--app-surface-muted); font-size:.75rem; }
.zc-combat-progress { display:grid; grid-template-columns:minmax(150px,auto) minmax(120px,1fr); gap:var(--space-3); align-items:center; padding:8px var(--space-4); border-bottom:1px solid var(--app-border); background:var(--app-surface-muted); }
.zc-combat-progress>div { display:flex; gap:8px; justify-content:space-between; font-size:.75rem; }
.zc-combat-progress>div span { color:var(--app-text-muted); }
.zc-combat-progress>span,.zc-combat-meter-track { display:block; overflow:hidden; height:7px; border-radius:999px; background:color-mix(in srgb,var(--app-text) 10%,transparent); }
.zc-combat-progress i { display:block; height:100%; background:linear-gradient(90deg,var(--app-accent),var(--app-warning)); }
.zc-combat-stage { position:relative; display:grid; grid-template-columns:minmax(280px,.9fr) minmax(300px,1.1fr); gap:clamp(12px,3vw,36px); min-height:0; padding:clamp(10px,2.2vw,24px); overflow:auto; }
.zc-combat-party { display:grid; grid-template-columns:repeat(3,minmax(90px,1fr)); gap:10px; align-content:center; min-width:0; }
.zc-combat-unit-card,.zc-combat-enemy-card { position:relative; min-width:0; padding:10px; border:1px solid var(--app-border); border-radius:var(--app-radius); background:color-mix(in srgb,var(--app-surface) 92%,transparent); box-shadow:var(--app-shadow); }
.zc-combat-unit-card[data-active="true"] { border-color:var(--app-accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--app-accent) 25%,transparent),var(--app-shadow); }
.zc-combat-unit-card[data-defeated="true"],.zc-combat-enemy-card[data-defeated="true"] { filter:grayscale(1); opacity:.52; }
.zc-combat-portrait { display:grid; place-items:center; aspect-ratio:4/5; overflow:hidden; margin-bottom:8px; border:1px dashed color-mix(in srgb,var(--app-text-muted) 45%,transparent); border-radius:calc(var(--app-radius) - 2px); background:linear-gradient(145deg,color-mix(in srgb,var(--app-surface-muted) 85%,transparent),color-mix(in srgb,var(--app-bg) 80%,transparent)); }
.zc-combat-portrait>img { width:100%; height:100%; object-fit:cover; }
.zc-combat-portrait-empty { width:46%; aspect-ratio:3/4; border:1px solid color-mix(in srgb,var(--app-text-muted) 16%,transparent); border-radius:45% 45% 18% 18%; background:color-mix(in srgb,var(--app-text-muted) 7%,transparent); }
.zc-combat-unit-card>header { display:flex; justify-content:space-between; gap:5px; align-items:start; }
.zc-combat-unit-card>header strong,.zc-combat-unit-card>header span { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.zc-combat-unit-card>header strong { font-size:.84rem; }
.zc-combat-unit-card>header span,.zc-combat-unit-card>header small { color:var(--app-text-muted); font-size:.66rem; }
.zc-combat-meter { margin-top:8px; }
.zc-combat-meter>div { display:flex; justify-content:space-between; gap:6px; margin-bottom:3px; color:var(--app-text-muted); font-size:.62rem; }
.zc-combat-meter-track i { display:block; height:100%; background:var(--app-danger); transition:width 180ms ease; }
.zc-combat-meter[data-tone="resource"] .zc-combat-meter-track i { background:var(--app-accent); }
.zc-combat-meter[data-tone="break"] .zc-combat-meter-track i { background:var(--app-warning); }
.zc-combat-enemies { display:grid; place-items:center; min-width:0; }
.zc-combat-enemy-card { width:min(100%,430px); }
.zc-combat-enemy-card>header { margin-bottom:8px; text-align:center; }
.zc-combat-enemy-card>header span,.zc-combat-enemy-card>header strong { display:block; }
.zc-combat-enemy-card>header span { color:var(--app-danger); font-size:.68rem; letter-spacing:.08em; }
.zc-combat-enemy-card>header strong { margin-top:2px; font-size:1.05rem; }
.zc-combat-enemy-art,.zc-combat-sprite-window { display:block; overflow:hidden; aspect-ratio:1; }
.zc-combat-enemy-art { width:min(100%,290px); margin-inline:auto; }
.zc-combat-sprite-window img { display:block; width:auto; max-width:none; height:100%; }
.zc-combat-effect { position:absolute; z-index:4; inset:8% 8%; display:grid; place-items:center; pointer-events:none; }
.zc-combat-effect[data-target="party"] { justify-items:start; }
.zc-combat-effect[data-target="enemy"] { justify-items:end; }
.zc-combat-effect>span { display:block; overflow:hidden; width:min(42vw,360px); aspect-ratio:1; }
.zc-combat-effect img { display:block; width:calc(var(--zc-effect-columns) * 100%); max-width:none; height:calc(var(--zc-effect-rows) * 100%); transform:translateY(calc(var(--zc-effect-row) * -100% / var(--zc-effect-rows))); transform-origin:left top; animation:zc-combat-effect-strip .48s steps(5,end) both; }
@keyframes zc-combat-effect-strip { from { margin-left:0; opacity:0; } 12% { opacity:1; } to { margin-left:calc(-1 * (var(--zc-effect-columns) - 1) * 100%); opacity:0; } }
.zc-combat-feed { display:grid; grid-template-rows:auto minmax(0,1fr); min-height:0; border-top:1px solid var(--app-border); background:color-mix(in srgb,var(--app-surface) 94%,transparent); }
.zc-combat-feed>header { display:flex; justify-content:space-between; padding:7px var(--space-4); color:var(--app-text-muted); font-size:.68rem; }
.zc-combat-feed ol { min-height:0; margin:0; padding:0 var(--space-4) 8px; overflow:auto; list-style:none; }
.zc-combat-feed li { display:grid; grid-template-columns:28px 1fr; gap:8px; padding:3px 0; border-top:1px solid color-mix(in srgb,var(--app-border) 55%,transparent); font-size:.72rem; }
.zc-combat-feed li>span { color:var(--app-text-muted); font-variant-numeric:tabular-nums; }
.zc-combat-feed li>p { margin:0; }
.zc-combat-feed li[data-kind="damage"] p,.zc-combat-feed li[data-kind="warning"] p,.zc-combat-feed li[data-kind="defeat"] p { color:var(--app-danger); }
.zc-combat-feed li[data-kind="heal"] p,.zc-combat-feed li[data-kind="victory"] p { color:var(--app-accent); }
.zc-combat-controls { display:flex; justify-content:space-between; gap:var(--space-3); align-items:end; padding:9px var(--space-4); border-top:1px solid var(--app-border); background:var(--app-surface); }
.zc-combat-controls fieldset { display:flex; gap:5px; min-width:0; margin:0; padding:0; border:0; }
.zc-combat-controls legend { position:absolute; overflow:hidden; width:1px; height:1px; clip-path:inset(50%); }
.zc-combat-controls button { min-height:34px; padding:6px 10px; border:1px solid var(--app-border); border-radius:var(--app-radius-sm); background:var(--app-surface-muted); color:var(--app-text); cursor:pointer; }
.zc-combat-controls button[aria-pressed="true"],.zc-combat-controls .zc-combat-primary { border-color:var(--app-accent); background:color-mix(in srgb,var(--app-accent) 18%,var(--app-surface)); }
.zc-combat-controls>div { display:flex; flex-wrap:wrap; gap:6px; justify-content:flex-end; }
@media (max-width:900px) { .zc-combat-stage { grid-template-columns:1fr; } .zc-combat-party { align-content:start; } .zc-combat-enemy-card { width:min(100%,360px); } .zc-combat-enemy-art { width:min(58vw,220px); } }
@media (max-width:699px) { .zc-combat-surface { grid-template-rows:auto auto minmax(0,1fr) minmax(96px,.3fr) auto; } .zc-combat-head { padding:10px 12px; } .zc-combat-head span { display:none; } .zc-combat-progress { grid-template-columns:1fr; gap:5px; padding:7px 12px; } .zc-combat-stage { display:flex; flex-direction:column-reverse; gap:8px; padding:8px; } .zc-combat-party { grid-template-columns:repeat(3,minmax(84px,1fr)); } .zc-combat-portrait { aspect-ratio:1; } .zc-combat-enemy-card { display:grid; grid-template-columns:92px minmax(0,1fr); gap:4px 10px; align-items:center; width:100%; } .zc-combat-enemy-art { grid-row:1/4; width:92px; } .zc-combat-enemy-card>header { text-align:left; } .zc-combat-feed>header,.zc-combat-feed ol { padding-inline:10px; } .zc-combat-controls { align-items:stretch; flex-direction:column; padding:7px 9px calc(7px + env(safe-area-inset-bottom)); } .zc-combat-controls fieldset,.zc-combat-controls>div { display:grid; grid-template-columns:repeat(3,1fr); } .zc-combat-controls>div { grid-template-columns:repeat(2,1fr); } .zc-combat-controls button { padding-inline:6px; } .zc-combat-effect>span { width:min(72vw,300px); } }

.zc-combat-formation { display:grid; grid-template-columns:repeat(var(--zc-formation-columns),minmax(0,1fr)); grid-template-rows:repeat(var(--zc-formation-rows),minmax(0,1fr)); width:min(100%,58vh); max-height:100%; margin:auto; aspect-ratio:var(--zc-formation-columns)/var(--zc-formation-rows); border:1px solid var(--app-border); border-radius:var(--app-radius); background:linear-gradient(color-mix(in srgb,var(--app-accent) 6%,transparent),transparent 45%,color-mix(in srgb,var(--app-danger) 7%,transparent)),var(--app-surface-muted); box-shadow:var(--app-shadow); overflow:hidden; }
.zc-combat-stage:has(.zc-combat-formation) { grid-template-columns:1fr; place-items:center; }
.zc-combat-cell { position:relative; display:grid; place-items:center; min-width:0; min-height:0; border-right:1px solid color-mix(in srgb,var(--app-border) 58%,transparent); border-bottom:1px solid color-mix(in srgb,var(--app-border) 58%,transparent); background:color-mix(in srgb,var(--app-surface) 28%,transparent); }
.zc-combat-cell:nth-child(odd) { background:color-mix(in srgb,var(--app-surface-raised) 18%,transparent); }
.zc-combat-token { isolation:isolate; overflow:visible; padding:2px; }
.zc-combat-token::before { content:""; position:absolute; z-index:-1; inset:7%; border:1px solid color-mix(in srgb,var(--app-accent) 58%,transparent); border-radius:50%; background:color-mix(in srgb,var(--app-accent) 16%,var(--app-bg)); box-shadow:0 0 12px color-mix(in srgb,var(--app-accent) 24%,transparent); }
.zc-combat-token[data-side="enemy"]::before { border-color:color-mix(in srgb,var(--app-danger) 62%,transparent); background:color-mix(in srgb,var(--app-danger) 15%,var(--app-bg)); box-shadow:0 0 12px color-mix(in srgb,var(--app-danger) 24%,transparent); }
.zc-combat-token>img,.zc-combat-token-sprite { display:block; width:82%; height:82%; overflow:hidden; border-radius:50%; object-fit:cover; object-position:50% 22%; }
.zc-combat-token-empty { display:block; width:54%; height:64%; border:1px solid color-mix(in srgb,var(--app-text-muted) 22%,transparent); border-radius:45% 45% 24% 24%; background:color-mix(in srgb,var(--app-text-muted) 8%,transparent); }
.zc-combat-token-sprite img { display:block; width:auto; max-width:none; height:100%; }
.zc-combat-token>strong { position:absolute; z-index:2; left:50%; bottom:7%; max-width:135%; transform:translateX(-50%); padding:1px 3px; border-radius:3px; background:rgb(4 9 10 / 82%); color:var(--app-text); font-size:clamp(5px,.58vw,9px); line-height:1.1; white-space:nowrap; }
.zc-combat-token-hp { position:absolute; z-index:3; right:8%; bottom:2%; left:8%; height:3px; overflow:hidden; border-radius:3px; background:rgb(0 0 0 / 58%); }
.zc-combat-token-hp i { display:block; height:100%; background:var(--app-danger); transition:width 180ms ease; }
.zc-combat-token[data-side="party"] .zc-combat-token-hp i { background:var(--app-accent); }
.zc-combat-token[data-active="true"] { z-index:2; filter:brightness(1.18); }
.zc-combat-token[data-active="true"]::before { outline:2px solid var(--app-text); outline-offset:1px; }
.zc-combat-token[data-defeated="true"] { opacity:.3; filter:grayscale(1); }
@media (max-width:699px) { .zc-combat-formation { width:min(100%,48vh); } .zc-combat-token>strong { display:none; } }

/* Board-first combat layout: the battlefield owns the primary surface while
   compact translucent panels stay in the surrounding gutters. */
.zc-combat-surface { position:relative; display:block; }
.zc-combat-stage,
.zc-combat-stage:has(.zc-combat-formation) {
  display:grid;
  grid-template-columns:clamp(54px,14vw,180px) minmax(0,1fr) clamp(76px,20vw,260px);
  grid-template-rows:auto minmax(0,1fr) auto;
  gap:clamp(4px,1vw,14px);
  width:100%;
  height:100%;
  min-height:0;
  padding:clamp(4px,1vw,14px);
  overflow:hidden;
  background:radial-gradient(circle at 50% 46%,color-mix(in srgb,var(--app-accent) 8%,transparent),transparent 44%),var(--app-bg);
}
.zc-combat-float { border:1px solid var(--app-border); border-radius:var(--app-radius); background:color-mix(in srgb,var(--app-surface) 76%,transparent); box-shadow:0 12px 32px rgb(0 0 0 / 28%); backdrop-filter:blur(12px) saturate(112%); }
.zc-combat-location { grid-column:2; grid-row:1; justify-self:start; display:flex; gap:10px; align-items:center; max-width:min(100%,560px); padding:7px 10px; }
.zc-combat-location>div { min-width:0; }
.zc-combat-location p,.zc-combat-location h1 { margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.zc-combat-location p { color:var(--app-accent); font-size:.57rem; font-weight:800; letter-spacing:.11em; }
.zc-combat-location h1 { font-size:.9rem; line-height:1.15; }
.zc-combat-location>span { color:var(--app-text-muted); font-size:.62rem; white-space:nowrap; }
.zc-combat-location>strong { padding:3px 6px; border:1px solid var(--app-border-strong); border-radius:999px; font-size:.58rem; white-space:nowrap; }
.zc-combat-initiative { grid-column:1; grid-row:2; display:grid; grid-template-rows:auto minmax(0,1fr); min-height:0; align-self:center; max-height:100%; overflow:hidden; }
.zc-combat-initiative>header,.zc-combat-feed>header { display:flex; justify-content:space-between; gap:8px; padding:8px 9px; border-bottom:1px solid var(--app-border); color:var(--app-text-muted); font-size:.64rem; }
.zc-combat-initiative ol { min-height:0; margin:0; padding:5px; overflow:auto; list-style:none; }
.zc-combat-initiative li { display:grid; grid-template-columns:16px 30px minmax(0,1fr); gap:5px; align-items:center; min-width:0; padding:4px; border-radius:5px; opacity:.78; }
.zc-combat-initiative li[data-active="true"] { background:color-mix(in srgb,var(--app-accent) 16%,transparent); opacity:1; }
.zc-combat-initiative li[data-defeated="true"] { filter:grayscale(1); opacity:.3; }
.zc-combat-initiative li>span { color:var(--app-text-muted); font-size:.55rem; text-align:center; }
.zc-combat-initiative li>i { display:block; width:30px; height:30px; overflow:hidden; border:1px solid var(--app-border); border-radius:50%; background:var(--app-surface-muted); }
.zc-combat-initiative li>i>img { width:100%; height:100%; object-fit:cover; object-position:50% 20%; }
.zc-combat-initiative .zc-combat-sprite-window { width:100%; height:100%; aspect-ratio:auto; }
.zc-combat-initiative .zc-combat-sprite-window img { width:auto; max-width:none; height:100%; }
.zc-combat-initiative li strong,.zc-combat-initiative li small { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.zc-combat-initiative li strong { font-size:.62rem; }
.zc-combat-initiative li small { margin-top:1px; color:var(--app-text-muted); font-size:.5rem; }
.zc-combat-board-shell { grid-column:2; grid-row:2; container-type:size; display:grid; place-items:center; align-self:stretch; justify-self:stretch; width:100%; height:100%; min-width:0; min-height:0; overflow:hidden; }
.zc-combat-formation { width:min(100%,100cqh); height:auto; max-width:none; max-height:none; margin:0; aspect-ratio:1/1; border-color:var(--app-border-strong); background:radial-gradient(circle at 50% 50%,color-mix(in srgb,var(--app-surface-raised) 36%,transparent),transparent 62%),linear-gradient(180deg,color-mix(in srgb,var(--app-danger) 5%,transparent),transparent 38%,transparent 62%,color-mix(in srgb,var(--app-accent) 6%,transparent)),var(--app-surface-muted); }
.zc-combat-cell { background:color-mix(in srgb,var(--app-surface) 15%,transparent); }
.zc-combat-cell:nth-child(odd) { background:color-mix(in srgb,var(--app-surface-raised) 10%,transparent); }
.zc-combat-cell[data-zone="enemy"] { background:color-mix(in srgb,var(--app-danger) 9%,var(--app-surface)); }
.zc-combat-cell[data-zone="party"] { background:color-mix(in srgb,var(--app-accent) 9%,var(--app-surface)); }
.zc-combat-feed { grid-column:3; grid-row:2; align-self:center; display:grid; grid-template-rows:auto minmax(0,1fr); min-height:0; max-height:100%; border-top:1px solid var(--app-border); overflow:hidden; }
.zc-combat-feed ol { min-height:0; margin:0; padding:4px 9px 8px; overflow:auto; }
.zc-combat-feed li { grid-template-columns:24px 1fr; gap:5px; padding:5px 0; font-size:.64rem; line-height:1.35; }
.zc-combat-controls { grid-column:2; grid-row:3; justify-self:center; display:flex; align-items:center; width:max-content; max-width:100%; padding:6px; border-top:1px solid var(--app-border); }
.zc-combat-controls button { min-height:30px; padding:4px 9px; font-size:.67rem; }
.zc-combat-effect { position:absolute; z-index:5; inset:-35%; display:grid; place-items:center; pointer-events:none; }
.zc-combat-effect>i { display:block; width:100%; aspect-ratio:1; overflow:hidden; }
.zc-combat-effect img { display:block; width:calc(var(--zc-effect-columns) * 100%); max-width:none; height:calc(var(--zc-effect-rows) * 100%); transform:translateY(calc(var(--zc-effect-row) * -100% / var(--zc-effect-rows))); transform-origin:left top; animation:zc-combat-effect-strip .48s steps(5,end) both; }
@media (max-width:900px) {
  .zc-combat-initiative li { grid-template-columns:14px 25px minmax(0,1fr); padding:3px; }
  .zc-combat-initiative li>i { width:25px; height:25px; }
  .zc-combat-feed li { font-size:.58rem; }
}
@media (max-width:699px) {
  .zc-combat-location { gap:4px; padding:4px 5px; }
  .zc-combat-location h1 { font-size:.7rem; }
  .zc-combat-location p,.zc-combat-location>strong { font-size:.48rem; }
  .zc-combat-location>span { display:none; }
  .zc-combat-initiative li { grid-template-columns:10px minmax(18px,1fr); padding:2px; }
  .zc-combat-initiative li>div { display:none; }
  .zc-combat-initiative li>i { width:clamp(18px,6vw,24px); height:clamp(18px,6vw,24px); }
  .zc-combat-initiative>header,.zc-combat-feed>header { padding:4px; font-size:.5rem; }
  .zc-combat-feed ol { padding:2px 4px 5px; }
  .zc-combat-feed li { display:block; padding:3px 0; font-size:.48rem; line-height:1.2; }
  .zc-combat-feed li>span { display:none; }
  .zc-combat-controls { gap:3px; padding:3px; }
  .zc-combat-controls fieldset,.zc-combat-controls>div { gap:2px; flex-wrap:nowrap; }
  .zc-combat-controls button { min-height:24px; padding:2px clamp(3px,1vw,6px); font-size:clamp(.46rem,1.7vw,.6rem); }
}
