/* Colours and type come only from bitwise-ui tokens.css (ADR-002). The bitwise brand is strictly
   black/white (Quote #37509): no hex, no rgba, no hue anywhere in this file. */
@layer reset {
  * { box-sizing: border-box; margin: 0; padding: 0; }
}

/* ── Bitwise UI: two components in one grid — chat 40 left, tool 60 right (Quote #37505) ──
   html overflow:hidden keeps body's overflow on body itself (not propagated to the viewport),
   so on touch body is the swipe track. */
html, body { margin: 0; height: 100%; }
html { overflow: hidden; }
body {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  grid-template-rows: 100%;
  height: 100dvh;
  overflow: hidden;
  scrollbar-width: none;
  /* ONE background layer for the whole studio (operator: "the background can be one layer outside of the dust").
     It is NOT ours: bitwise-ui surface.css paints the depth ground (a radial falloff of brand tokens) on body —
     html has none, so it propagates to the root canvas behind both components on every size — and its animated
     film grain on body::after. Every section above stays transparent so the ground and grain read everywhere. */
  color: var(--text);
  font-family: var(--font-body);
}
/* Dust: the studio's only own layer (bitwise-ui's animated grain sits on body::after). ~21 motes of 1–2px at varied alpha in two coprime SVG mask tiles
   (397px / 563px, so the repeat never reads as a grid), coloured by the ink token. One slow compositor-only
   transform drift; static under reduced motion. No JS, no canvas. */
body::before {
  content: '';
  position: fixed;
  inset: -32px;
  z-index: -1;
  pointer-events: none;
  opacity: 0.8;
  mix-blend-mode: normal;
  background: var(--text-strong);
  --dust-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='397' height='397'%3E%3Ccircle cx='23' cy='41' r='.6' fill-opacity='.7'/%3E%3Ccircle cx='88' cy='190' r='.5' fill-opacity='.4'/%3E%3Ccircle cx='141' cy='72' r='.8' fill-opacity='.55'/%3E%3Ccircle cx='203' cy='311' r='.5' fill-opacity='.3'/%3E%3Ccircle cx='256' cy='128' r='1' fill-opacity='.6'/%3E%3Ccircle cx='310' cy='37' r='.6' fill-opacity='.35'/%3E%3Ccircle cx='352' cy='240' r='.7' fill-opacity='.5'/%3E%3Ccircle cx='61' cy='349' r='.9' fill-opacity='.45'/%3E%3Ccircle cx='174' cy='262' r='.5' fill-opacity='.25'/%3E%3Ccircle cx='289' cy='377' r='.7' fill-opacity='.6'/%3E%3Ccircle cx='377' cy='151' r='.5' fill-opacity='.3'/%3E%3Ccircle cx='118' cy='5' r='.6' fill-opacity='.4'/%3E%3C/svg%3E");
  --dust-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='563' height='563'%3E%3Ccircle cx='47' cy='512' r='1' fill-opacity='.5'/%3E%3Ccircle cx='133' cy='288' r='.6' fill-opacity='.35'/%3E%3Ccircle cx='219' cy='61' r='.8' fill-opacity='.6'/%3E%3Ccircle cx='305' cy='433' r='.5' fill-opacity='.3'/%3E%3Ccircle cx='391' cy='197' r='.9' fill-opacity='.45'/%3E%3Ccircle cx='477' cy='349' r='.6' fill-opacity='.55'/%3E%3Ccircle cx='533' cy='94' r='.5' fill-opacity='.25'/%3E%3Ccircle cx='262' cy='541' r='.7' fill-opacity='.4'/%3E%3Ccircle cx='12' cy='163' r='.6' fill-opacity='.3'/%3E%3C/svg%3E");
  -webkit-mask: var(--dust-a) 0 0 / 397px 397px, var(--dust-b) 0 0 / 563px 563px;
  mask: var(--dust-a) 0 0 / 397px 397px, var(--dust-b) 0 0 / 563px 563px;
  will-change: transform;
  animation: studio-dust 90s ease-in-out infinite alternate;
}
@keyframes studio-dust { to { transform: translate3d(24px, -18px, 0); } }
@media (prefers-reduced-motion: reduce) { body::before { animation: none; } }
/* Both components fill the 100dvh row (Quote #37506): stretch, never content height. */
#chat, #tool { height: 100%; min-width: 0; min-height: 0; padding: 0; margin: 0; border: 0; align-self: stretch; }
#chat { position: relative; overflow: hidden; }
/* The slate's material (bitwise-ui slate data-presence="liquid"): untinted, separated only by blurring what is
   behind it. No studio override. */
/* Breathing room inside the slate (bitwise spacing tokens). The inset lives on the slate's children, not on
   #chat, so the two grid components stay edge-to-edge (no padding/margin/border on #chat itself). */
/* The log box starts below the top-left mark overlay (margin, not padding, so scrolled bubbles never pass under
   it); the input keeps a foot of air (the legal overlay sits in the tool column on desktop). */
#chat > .tbw-slate-log { margin-top: var(--space-12, 3rem); padding: var(--space-4) var(--space-8) 0; }
#chat > .tbw-slate-input { margin-inline: var(--space-8); margin-bottom: var(--space-6); }
#chat[data-mode="dev"] > .tbw-slate-log, #chat[data-mode="dev"] > .tbw-slate-input { display: none; }

/* ── Tool: ONE stage, natively full width × height (Quotes #37510/#37511) ──
   A 1×1 grid; every child shares the single cell and stretches to it. Morpho comes first in source,
   so #tool-stage paints over it without z-index. No viewBox maths, no JS sizing.
   container-type: size makes #tool the container Morpho's portrait query reads (svg/morpho.svg). */
#tool {
  display: grid;
  grid-template: 100% / 100%;
  overflow: hidden;
  position: relative;
  isolation: isolate;
  container-type: size;
}
#tool > * { grid-area: 1 / 1; width: 100%; height: 100%; min-width: 0; min-height: 0; }
#tool-stage { display: grid; grid-template: 100% / 100%; overflow: hidden; }
#tool-stage > .tool-view { grid-area: 1 / 1; display: grid; grid-template: 100% / 100%; width: 100%; height: 100%; min-height: 0; }

/* ── Morpho (bitwise-ui svg/morpho.svg, read and inlined server-side per request), meet-fitted and centred.
   Everything about Morpho — display, animation, fills, shadow, opacity transition, portrait scale, reduced
   motion — lives in its own scoped <style> in bitwise-ui. The studio only states host state: */
/* While a Tool morph holds the stage, Morpho recedes behind it. */
#tool:has(.tool-view[data-view="sync"]) #morpho { opacity: 0; }

/* ── Idle Tool (Quote #37529): the renderer at rest — Morpho alone, plus a quiet non-interactive readout
   centred in its core. Control lives in the slate; nothing here is pressable. ── */
.tool-idle {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  pointer-events: none;
  user-select: none;
}
.tool-readout { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-5); list-style: none; color: var(--text-muted); font-size: var(--text-sm); }
.tool-readout strong { color: var(--text-strong); font-weight: 600; }

/* ── Tool morph (sync): header / body / footer rows filling the whole stage ── */
.tool-morph {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: 100%;
  height: 100%;
  min-height: 0;
  background: transparent;
  color: var(--text);
}
.tool-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-block: 1px solid var(--border); }
/* Keep the bar's last button clear of the fixed account avatar (top-right of the viewport) on desktop. */
@media not ((pointer: coarse) or (max-width: 1024px)) {
  body > #tool .tool-bar { padding-inline-end: 5.5rem; }
  /* …the foot bar clear of the bottom-right legal overlay, and an expanded Tool's top bar clear of the mark. */
  body > #tool .tool-bar:last-child:not(:first-child) { padding-inline-end: 15rem; }
  body:has(.tool-view[data-expanded]) > #tool .tool-bar:first-child { padding-inline-start: 12rem; }
}
.tool-title { flex: 1; min-width: 10rem; color: var(--text-strong); font-size: var(--text-lg); font-weight: 600; }
.tool-title small { display: block; color: var(--text-muted); font-size: var(--text-sm); font-weight: 400; }
/* Controls are bitwise-ui .btn-primary / .btn-ghost; only the toggle's pressed state is studio-specific. */
.tool-bar .btn-ghost[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.tool-meta { color: var(--text-muted); font-size: var(--text-sm); }
.tool-body { display: grid; grid-template: 100% / 100%; min-height: 0; overflow: hidden; }
.tool-body > * { grid-area: 1 / 1; width: 100%; height: 100%; min-height: 0; }
.tool-body > [hidden] { display: none; }
#tool-sync-script {
  overflow: auto;
  padding: var(--space-4);
  color: var(--text);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-sm);
  line-height: 1.5;
  white-space: pre;
  user-select: text;
}
#tool-sync-diagram:not([hidden]) { display: block; }
.tool-body > [hidden] { display: none !important; }
/* PlantUML output is monochrome; force its strokes/text onto the brand's ink tokens. */
#tool-sync-diagram :is(path, line, polygon, rect, ellipse) { stroke: var(--text) !important; }
#tool-sync-diagram text { fill: var(--text-strong) !important; }
#tool-sync-diagram :is(rect, polygon, ellipse, path):not([fill="none"]) { fill: var(--surface) !important; }

/* An expanded Tool takes the whole width; chat steps aside until it collapses (server-rendered state). */
body:has(.tool-view[data-expanded]) { grid-template-columns: 100%; }
body:has(.tool-view[data-expanded]) #chat { display: none; }

/* Touch / small: swipe left-right between chat (first) and tool. Tool is one stage — no vertical pages. */
@media (pointer: coarse), (max-width: 1024px) {
  body {
    grid-auto-flow: column;
    grid-template-columns: 100vw 100vw;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
  }
  #chat, #tool { scroll-snap-align: start; }
  /* Account chrome belongs to the slate page: it scrolls away with it instead of
     sitting over the tool bar once the tool page is snapped in. */
  body { position: relative; }
  /* Mark and legal overlays too: absolute in the body scroll track = pinned to the chat page's corners. */
  body > :is(.studio-account, .studio-mark, .studio-legal) { position: absolute; }
  body > .studio-mark { left: var(--space-4); }
  body > .studio-legal { right: var(--space-4); bottom: var(--space-3); }
  #chat > .tbw-slate-log { padding: var(--space-4) var(--space-4) 0; }
  /* The input sits above the legal line (which takes the chat page's bottom-right corner). */
  #chat > .tbw-slate-input { margin-inline: var(--space-4); margin-bottom: 4rem; }
}

/* ── Overlays — out of the grid flow: mark top-left, account top-right, legal bottom-right ───────── */
.studio-account { position: fixed; z-index: 20; top: 20px; right: 24px; font-family: var(--font-body); }
.studio-mark { position: fixed; z-index: 20; top: 20px; left: 24px; font-family: var(--font-body); }
.studio-mark > a { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 2.25rem; color: var(--text-strong); font-family: var(--font-ui, inherit); font-size: var(--text-sm); font-weight: 600; text-decoration: none; }
.studio-legal { position: fixed; z-index: 20; right: 24px; bottom: var(--space-4); padding: 0; border: 0; background: none; font-family: var(--font-body); line-height: 1.25; }
