:root {
  /* ═══════════ FORMS CORE THEME — suite-wide foundation (2026-08-29) ═════════
     The Forms Suite Visual System. Every Forms application inherits this
     block unchanged — Forms Graphite neutrals, shared text, shared
     semantics — and supplies ONLY its product-accent ramp below. Forms 2D
     is the reference implementation. Graphite values are TUNABLE until the
     suite freeze; after that no Forms app improvises its own dark gray.
     2026-09-29 (owner, small CAD visual pass): the ramp is a touch cooler —
     machined blue-gray graphite (R −2, B +4, luminance unchanged). */
  --forms-graphite-950: #101316;   /* deepest: console, status bar */
  --forms-graphite-900: #15181B;   /* main application chrome */
  --forms-graphite-850: #1A1D20;   /* ribbon / panel surfaces */
  --forms-graphite-800: #202326;   /* elevated surfaces */
  --forms-graphite-750: #2C2F32;   /* hover / selected-neutral */
  --forms-graphite-700: #303336;   /* strong borders / dividers */
  --forms-graphite-600: #434649;   /* subtle control outlines */
  --forms-text-primary:   #E8E8E5;
  --forms-text-secondary: #B7B8B4;
  --forms-text-muted:     #8A8B88;
  --forms-text-disabled:  #5F615E;
  /* Shared semantics — NEVER themed by a product accent */
  --forms-error:   #F87171;
  --forms-warning: #F59E0B;
  --forms-success: #22C55E;
  --forms-info:    #6AA6FF;
  --forms-cad-aid: #5E97E0;   /* CAD drafting aids (SNAP/OSNAP/GRID/OTRACK…) — blue, never purple */

  /* ═══════════ FORMS 2D PRODUCT THEME — Cobalt Blue ═══════════
     Canonical product accent. (Sister accents live in their own apps:
     Forms Element → Phosphor Gold, etc. Same shell, different identity.) */
  --product-accent:         #326BDF;
  --product-accent-bright:  #749FF6;
  --product-accent-muted:   #355EBA;
  --product-accent-dim:     #26437D;
  --product-accent-surface: rgba(50, 107, 223, 0.14);

  /* ── Legacy aliases — existing consumers, mapped onto the system ── */
  --bg-canvas: #181B1F;   /* Model work surface: very dark cool graphite, off pure black (owner 2026-09-29; was BLACK from 2026-09-27) — a notch darker than the panels; renderer.js CANVAS_DEFAULT; grid display defaults off, X/Y axes stay */
  --bg-chrome: var(--forms-graphite-900);
  --bg-panel: var(--forms-graphite-850);
  --border: #25282B;      /* quiet seam (2026-08-26 chrome-quiet pass; cool graphite 2026-09-29) */
  --border-divider: 0.5px solid rgba(255, 255, 255, 0.055);  /* A5.3: soft structural separators */
  --active: var(--forms-graphite-750);
  --accent: var(--product-accent);
  --accent2: var(--product-accent);   /* application state (active tab, current row) — accent */
  --snap: #FFD700;
  --grip: #4169E1;
  --grip-active: #FF4500;
  --text: var(--forms-text-primary);
  --text-dim: var(--forms-text-muted);
  --cli-bg: var(--forms-graphite-950);
  --cli-text: #C6C7C3;
  --cli-prompt: var(--product-accent);
  --status: var(--forms-graphite-950);
  /* Owner FINAL override (2026-08-29, supersedes suite mandate §6): ALL
     highlighted state reads the product accent — status toggles included. Blue
     survives only as --forms-info semantics. */
  --status-on: var(--product-accent);
  /* The Rev 1.0 specification's tokens (ruling 100, 2026-10-17; renderer/src/ui-palette.js UI_TOKENS and
     the canvas scheme). These defaults are what the surfaces were before the tokens existed, so a palette
     that does not set them looks as it did: the panel header is the chrome, a control that is on is the
     product surface tint, and the canvas aids are the drawing's own (the canvas reads the registry; these
     are for what the page paints in the canvas's colours). */
  --panel-header: var(--bg-chrome);
  --active-control: var(--product-accent-surface);
  --canvas-crosshair: rgba(255, 255, 255, 0.6);
  --canvas-default-line: #FFFFFF;
  --canvas-selection: var(--product-accent);
  --canvas-snap: var(--snap);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg-canvas);
  color: var(--text);
  font-family: Aptos, Calibri, 'Segoe UI', 'IBM Plex Sans', system-ui, sans-serif;
  font-size: 12px;
  user-select: none;
}

#app {
  display: grid;
  /* 2026-06-12: row 3 (auto) is the custom toolbar — it collapses to 0 when
     hidden. Before this, #custom-toolbar was a 7th child in a 6-row grid and
     shoved every row down ("yeeted everything to the bottom").
     BBQ run 2026-09-28 (§33): the ribbon row is 107 px — its groups are
     4 + 78 (two 34 px button rows, A5.2.1) + 20 (label) + 4 (A5.2.3) = 106 px
     plus the 1 px divider. It stayed 100 px when A5.2 grew them, so the strip
     was 3 px taller than its box and showed a vertical scrollbar at the right
     end of the ribbon (100 / 125 / 200 %). */
  grid-template-rows: 38px 107px auto 1fr 64px 22px 24px;
  /* One column exactly the window's width: with the implicit auto column the
     title row's min-content (logo + tabs + the Colour / Layer / LT / LW
     pickers, ~1570 px) widened the whole shell past the window at 125 % and
     up — #app then scrolled itself sideways, hiding the left edge, and the
     right dock went off-screen. Each row now handles its own overflow. */
  grid-template-columns: minmax(0, 1fr);
  height: 100vh;
  overflow: hidden;
}
/* Command console expands upward on demand (2026-08-26: "two bottoms") —
   collapsed it shows the prompt + last couple of history lines. */
#app.cli-expanded { grid-template-rows: 38px 107px auto 1fr 200px 22px 24px; }

/* ── Slim, theme-matched scrollbars (2026-06-12) ── */
::-webkit-scrollbar { width: 7px; height: 7px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }
::-webkit-scrollbar-corner { background: transparent; }

/* ===== Top chrome (logo + tabs + global controls, single row) ===== */
#top-chrome {
  display: flex;
  align-items: flex-end;
  padding: 0 8px;
  gap: 8px;
  background: var(--bg-chrome);
  border-bottom: var(--border-divider);   /* A5.3: title/chrome → ribbon */
  height: 38px;
  position: relative;
}
/* Forms 2D signature rule (2026-08-29, QC-final): 1px solid canonical
   The product accent directly below the native File/Edit/View menu row — a
   machined precision edge, not an object. Gradient dropped at 1px (buys
   nothing). Pseudo-element so the bottom divider stays untouched and
   ribbon geometry never shifts. */
#top-chrome::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--product-accent);
  pointer-events: none;
}
.tb-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px 0 6px;
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  border-radius: 4px 4px 0 0;
  height: 30px;
  align-self: flex-end;
  margin-bottom: 0;
}
.tb-logo:hover { background: var(--active); border-color: var(--accent); }
.tb-logo-img {
  filter: brightness(1.8) drop-shadow(0 0 4px rgba(50, 107, 223, 0.5));
}
.tb-logo-text {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 3px;
  color: #E8E8E5;
}
.tb-spacer { flex: 1; }
.tb-global {
  display: flex;
  gap: 4px;
  align-items: center;
  align-self: center;
  margin-bottom: 4px;
}

/* ===== Ribbon tabs — sit inline with logo ===== */
#ribbon-tabs {
  display: flex;
  gap: 2px;
  align-items: flex-end;
  height: 100%;
}
.ribbon-tab {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid transparent;
  border-bottom: none;
  padding: 6px 18px;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.5px;
  cursor: pointer;
  border-radius: 4px 4px 0 0;
  height: 28px;
}
.ribbon-tab:hover { color: var(--text); background: var(--bg-panel); }
.ribbon-tab.active {
  color: var(--accent2);
  background: var(--bg-panel);
  border-color: var(--border);
  border-bottom-color: var(--bg-panel);
  position: relative;
  top: 1px;
}

/* ===== Ribbon panel ===== */
#ribbon-panel {
  background: var(--bg-panel);
  border-bottom: var(--border-divider);   /* A5.3: ribbon → workspace */
  overflow: hidden;
  position: relative;
}
.ribbon-content {
  display: flex;
  align-items: stretch;
  padding: 0;
  height: 100%;
  overflow-x: auto;
  /* The strip scrolls sideways in a narrow window and never vertically (an
     auto overflow-x makes overflow-y auto too). The row height above is what
     makes the content fit; this only states the intent. */
  overflow-y: hidden;
}
.ribbon-content.hidden { display: none; }

/* Named panel — group of tools with a label footer and side separator */
.ribbon-panel-group {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  border-right: var(--border-divider);   /* A5.3: ribbon group separator */
  padding: 4px 0;   /* A5.2.3: +4px vertical (was 0) */
  min-width: 0;
  /* A group keeps its width (2026-09-29, Home): when a tab is wider than the
     window the strip scrolls sideways (graceful overflow, QC ruling) instead
     of squeezing groups until their buttons overlap. The 7 px scrollbar only
     covers the label's bottom padding. */
  flex-shrink: 0;
}
.ribbon-panel-group:last-child { border-right: none; }

.ribbon-rows {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: 1fr 1fr;
  gap: 2px 2px;
  padding: 6px 6px 2px;   /* 2026-08-26: tighter inter-group dead space */
  flex: 1;
  align-items: center;
  justify-content: start;
}

.ribbon-panel-label {
  font-size: 10px;
  letter-spacing: 1px;
  color: #A2A39F;         /* 2026-08-26: brighter than text-dim — subordinate, not invisible */
  font-weight: 600;
  text-transform: uppercase;
  text-align: center;
  padding: 2px 6px 4px;
  line-height: 13px;   /* fixed, so the ribbon height math is the same at every display scale */
  border-top: 1px solid rgba(42, 42, 53, 0.5);
  margin-top: auto;
}

.ribbon-group { display: flex; gap: 0; align-items: center; }

.tb-row {
  display: flex;
  align-items: center;
  padding: 0 6px;
  gap: 3px;
  height: 36px;
}

.tb-group { display: flex; gap: 2px; align-items: center; }
.tb-sep { width: 1px; height: 24px; background: var(--border); margin: 0 4px; }

.tb-btn {
  background: transparent;
  color: var(--text);
  border: 1px solid transparent;
  padding: 5px 8px;   /* A5.2.1: +3px vertical (was 2px) */
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  /* A5.2.1: +3px vertical padding; height grows naturally (fixed height
     removed per spec so the padding increase is visible). */
  min-height: 32px;
}
.tb-btn .tb-icon svg { width: 24px; height: 24px; }   /* Icon System v1 (2026-09-30): the 24 grid 1:1; was 22 px */
.tb-btn:hover {
  background: rgba(50, 107, 223, 0.18);
  border-color: var(--accent);
  color: #E8E8E5;
}
.tb-btn:active { background: var(--accent); color: white; }

.tb-icon { display: inline-flex; align-items: center; }
.tb-icon svg { display: block; }
.tb-lbl { font-size: 12px; letter-spacing: 0.3px; color: #DBDBD8; }

.tb-label { color: var(--text-dim); margin: 0 4px 0 2px; font-size: 11px; }
.tb-select {
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 2px 4px;
  font-family: inherit;
  font-size: 11px;
  min-width: 100px;
}

/* ===== Ruler ===== */
.ruler {
  height: 18px;
  background: var(--bg-chrome);
  border-bottom: 1px solid var(--border);
  position: relative;
  overflow: hidden;
}

/* ===== Main area ===== */
#main {
  display: grid;
  /* 2026-09-29: the palette sides carry their own edge resizers, so the old
     4px left-resize track is gone (column 2 stays, empty, for the pins). */
  grid-template-columns: auto 0 minmax(0, 1fr) max-content;
  overflow: hidden;
}
/* Explicit grid placement (fix 2026-06-13): a display:none grid item is removed
   from grid AUTO-PLACEMENT. When the left zone is empty, #panel-left AND the
   hidden #panel-left-resize drop out, so #canvas-area + #panel-right would
   auto-shift left into columns 1 & 2 (the 0px tracks) — collapsing the canvas to
   0px (the black/"missing" canvas). Pinning each child to its column makes a
   display:none sibling leave an EMPTY track instead of shifting the rest. */
#panel-left        { grid-column: 1; }
#panel-left-resize { grid-column: 2; }
#canvas-area       { grid-column: 3; }
#panel-right       { grid-column: 4; }
/* When the dock's left zone is empty (default — all panels dock right), collapse
   its column AND the fixed 4px resize-handle track so no dead col-resize strip
   lingers at the far-left edge of the canvas. */
#main.dock-left-empty { grid-template-columns: 0 0 minmax(0, 1fr) max-content; }

#panel-left { width: 240px; flex-shrink: 0; }
#panel-left-resize { display: none !important; }   /* retired: the left side resizes at its own edge */
.panel-resize-h {
  width: 4px;
  cursor: col-resize;
  background: var(--border);
  flex-shrink: 0;
  transition: background 0.1s;
}
.panel-resize-h:hover, .panel-resize-h.dragging { background: var(--accent); }

/* Left panel: Project Browser v2 */
.pb-proj-header {
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-chrome);
  position: relative;
}
.pb-file-name {
  font-weight: 700;
  font-size: 13px;
  color: #E8E8E5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right: 24px;
}
.pb-proj-name {
  font-weight: 500;
  font-size: 11px;
  color: #A6A7A3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right: 24px;
  margin-top: 2px;
}
.pb-proj-number {
  font-size: 10px;
  color: #8A8B88;
  margin-top: 2px;
  font-family: monospace;
}
.pb-source-btn {
  background: linear-gradient(180deg, #2A2D30, #1A1D20);   /* stop was #1B1B26 (blue-tinted; 08-29 sweep miss) */
  border: 1px solid #434649;
  border-radius: 3px;
  padding: 8px 10px !important;
  margin: 4px 8px 8px;
  cursor: pointer;
  transition: background 0.15s;
  text-align: left;
}
/* Hover edge is the accent (every highlighted state is the product accent; blue
   is informational only) and the lower stop graphite — was #6AA6FF / #232333. */
.pb-source-btn:hover { background: linear-gradient(180deg, #383B3E, #202326); border-color: var(--accent); }
.pb-source-btn.active { background: #2A2D30; border-color: #326BDF; color: #FFFFFF; }

/* Drag-drop: view dragging into sheet */
.pb-tree-node.view-draggable { cursor: grab; }
.pb-tree-node.view-draggable:active { cursor: grabbing; }
.pb-tree-node.drop-target { background: rgba(50, 107, 223, 0.18); outline: 1px dashed #326BDF; }
.pb-proj-menu {
  position: absolute;
  top: 8px;
  right: 8px;
  background: transparent;
  color: #8A8B88;
  border: none;
  cursor: pointer;
  font-size: 14px;
  padding: 2px 6px;
  border-radius: 4px;
}
.pb-proj-menu:hover { color: #E8E8E5; background: var(--active); }
.pb-filter-wrap { padding: 6px 8px; border-bottom: 1px solid var(--border); }
.pb-filter-input {
  width: 100%;
  background: #0F0F13;
  color: #E8E8E5;
  border: 1px solid var(--border);
  padding: 4px 6px;
  font-size: 11px;
  border-radius: 4px;
  box-sizing: border-box;
}
.pb-section { padding: 6px 0 2px; border-bottom: 1px dotted rgba(42,42,53,0.6); }
.pb-section:last-child { border-bottom: none; }
.pb-section-hdr {
  font-size: 9px;
  letter-spacing: 1px;
  color: #8A8B88;
  padding: 2px 10px 4px;
  text-transform: uppercase;
  font-weight: 600;
}
.pb-divider {
  padding: 6px 10px;
  font-size: 9px;
  color: #8A8B88;
  letter-spacing: 1px;
  background: #171A1D;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-transform: uppercase;
  text-align: center;
}
.pb-tree-node {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;   /* A5.2.2: +3px vertical (was 3px) — left panel tree rows */
  font-size: 11px;
  color: #E8E8E5;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pb-tree-node:hover { background: var(--active); }
.pb-tree-node.active {
  background: #2E2A40;
  color: var(--accent2);
  font-weight: 600;
}
.pb-root { font-weight: 500; }
.pb-sub { padding-left: 22px; font-size: 10.5px; color: #C6C7C3; }
.pb-ico { font-size: 10px; opacity: 0.8; width: 14px; text-align: center; }
.pb-count { color: #8A8B88; font-size: 10px; margin-left: auto; padding-left: 6px; }
.pb-tree-children { display: none; }
.pb-tree-children.open { display: block; }
.pb-disc-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px;
  font-size: 11px;
  cursor: pointer;
  color: #C6C7C3;
}
.pb-disc-row:hover { background: var(--active); }
.pb-disc-row.active { color: #E8E8E5; }
.pb-disc-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #8A8B88;
}
.pb-disc-row.active .pb-disc-dot { background: #326BDF; }
.pb-disc-code {
  display: inline-block;
  min-width: 22px;
  text-align: center;
  background: #2A2D30;
  padding: 1px 4px;
  border-radius: 4px;
  font-family: monospace;
  font-size: 10px;
  color: #E8E8E5;
}
.pb-disc-name { flex: 1; }
.pb-disc-count { color: #8A8B88; font-size: 10px; }
.pb-btn-sub {
  width: calc(100% - 24px);
  margin: 4px 12px 2px;
  background: transparent;
  color: #326BDF;
  border: 1px dashed #2A2D30;
  padding: 3px 6px;
  font-size: 10px;
  cursor: pointer;
  border-radius: 4px;
}
.pb-btn-sub:hover { background: var(--active); border-color: #326BDF; }

#panel-left {
  background: var(--bg-panel);
  border-right: var(--border-divider);   /* A5.3: left panel → canvas */
  overflow-y: auto;
  min-width: 0;
}

.pb-toolbar {
  padding: 4px 6px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-chrome);
}
.pb-btn {
  width: 100%;
  background: var(--bg-panel);
  color: var(--accent2);
  border: 1px solid var(--border);
  padding: 3px 6px;
  font-size: 10px;
  letter-spacing: 0.5px;
  cursor: pointer;
  border-radius: 4px;
  font-family: inherit;
}
.pb-btn:hover { background: var(--active); border-color: var(--accent); color: var(--text); }

.tree-node {
  padding: 3px 8px;
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tree-node:hover { background: var(--active); }
.tree-node.active { color: var(--accent2); font-weight: bold; }
.tree-icon { font-size: 10px; margin-right: 4px; }
.tree-children { padding-left: 16px; display: none; }
.tree-children.open { display: block; }

/* Left toolbar */
#toolbar-left {
  background: var(--bg-chrome);
  border-right: var(--border-divider);   /* A5.3: left toolbar → workspace */
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4px 0;
  gap: 2px;
}
.tbl-btn {
  width: 28px;
  height: 28px;
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border);
  cursor: pointer;
  border-radius: 4px;
  font-size: 14px;
  font-family: inherit;
  padding: 0;
}
.tbl-btn:hover { background: var(--active); border-color: var(--accent); }
.tbl-sep { height: 1px; width: 24px; background: var(--border); margin: 4px 0; }

/* Canvas */
#canvas-wrap {
  position: relative;
  overflow: hidden;
  background: var(--bg-canvas);
}
#canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: none;
}

/* ===== Right panels ===== */
/* A palette side (palettes.js sets its width, saved per workstation). */
#panel-right {
  background: var(--bg-panel);
  border-left: var(--border-divider);   /* A5.3: canvas → right panel */
  display: flex;
  flex-direction: column;
  width: 268px;
}
.panel { border-bottom: var(--border-divider); }   /* A5.3: right-panel section dividers */
.panel-header {
  background: var(--panel-header);
  padding: 4px 8px;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--text-dim);
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
}
.panel-body { padding: 6px 8px; }
.prop-row {
  display: flex;
  justify-content: space-between;
  padding: 6px 0;   /* A5.2.2: +3px vertical (was 3px) */
  font-size: 11px;
}
.prop-k { color: var(--text-dim); }
.prop-v { color: var(--text); font-family: 'Consolas', 'JetBrains Mono', monospace; }

.panel-btn {
  width: 100%;
  background: var(--bg-chrome);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px;
  cursor: pointer;
  margin-top: 6px;
  font-family: inherit;
  font-size: 11px;
}
.panel-btn:hover { background: var(--active); }

.panel-input {
  width: 100%;
  background: var(--bg-chrome);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 6px;
  font-family: inherit;
  font-size: 11px;
  outline: none;
  margin: 2px 0;
}
.panel-input:focus { border-color: var(--accent); }

/* Layer rows */
.layer-row {
  display: grid;
  grid-template-columns: 14px 14px minmax(40px, 1fr) 70px 36px 16px;
  gap: 4px;
  align-items: center;
  padding: 3px 0;
  font-size: 10px;
  cursor: pointer;
  overflow: hidden;
}
.layer-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.layer-lt, .layer-lw {
  font-family: 'Consolas', 'JetBrains Mono', monospace;
  color: var(--text-dim);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.layer-lt:hover, .layer-lw:hover { color: var(--accent2); }
.layer-row.current { color: var(--accent2); font-weight: bold; }
.layer-swatch {
  width: 12px; height: 12px;
  border: 1px solid var(--border);
  cursor: pointer;
}
.layer-vis {
  cursor: pointer;
  color: var(--text-dim);
  text-align: center;
  font-size: 11px;
}
.layer-vis.on { color: var(--accent2); }

/* ===== Families panel ===== */
#families-panel { min-height: 150px; }
#families-list {
  max-height: 300px;
  overflow-y: auto;
}
.fam-group-header {
  font-size: 10px;
  color: var(--text-dim);
  padding: 4px 0 2px;
  cursor: pointer;
  letter-spacing: 0.5px;
}
.fam-group-header:hover { color: var(--accent2); }
.fam-item {
  padding: 6px 8px;   /* A5.2.2: +3px vertical (was 3px) — library/list items */
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fam-item:hover { background: var(--active); color: var(--accent2); }
.fam-group-body { padding-left: 4px; }
.fam-group-body.collapsed { display: none; }

/* ===== CLI ===== */
#cli-container {
  background: var(--cli-bg);
  border-top: var(--border-divider);   /* A5.3: above CLI area */
  display: flex;
  flex-direction: column;
  font-family: 'Consolas', 'JetBrains Mono', monospace;
  font-size: 12px;
  overflow: hidden;
}
#cli-history {
  flex: 1;
  overflow-y: auto;
  padding: 4px 8px;
  color: var(--cli-text);
  white-space: pre-wrap;
  line-height: 1.35;
  /* CLI log is reference text (errors, diagnostics, inquiry output) — make it
     selectable/copyable even though the app globally disables text selection
     for canvas drag cleanliness. */
  user-select: text;
  -webkit-user-select: text;
  cursor: text;
}
.cli-line { }
.cli-line.prompt { color: var(--cli-prompt); }
.cli-line.echo { color: var(--text); }
.cli-line.err { color: #ff5555; }
.cli-line.info { color: var(--text-dim); }

#cli-input-row {
  display: flex;
  align-items: center;
  padding: 3px 8px;
  border-top: 1px solid var(--border);
  background: var(--cli-bg);
}
#cli-prompt {
  color: var(--cli-prompt);
  margin-right: 6px;
  white-space: nowrap;
}
#cli-input {
  flex: 1;
  background: transparent;
  color: var(--cli-text);
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 12px;
}

/* ===== Layout tabs ===== */
#frame-tabs {
  display: flex;
  background: var(--status);              /* 2026-08-26: reads as one zone with the status bar */
  border-top: var(--border-divider);      /* A5.3 */
  border-bottom: none;
  padding: 0 4px;
  gap: 2px;
  align-items: center;
  height: 22px;
}
.frame-tab {
  background: var(--bg-panel);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-bottom: none;
  padding: 2px 12px;
  font-family: inherit;
  font-size: 10px;
  cursor: pointer;
  border-radius: 4px 4px 0 0;
}
.frame-tab:hover { color: var(--text); }
.frame-tab.active { background: var(--bg-canvas); color: var(--text); border-color: var(--accent); }
.frame-tab-add { color: var(--text-dim); font-size: 14px; padding: 2px 8px; }
.frame-tab-add:hover { color: var(--accent); }

/* ===== Status bar ===== */
#status-bar {
  background: var(--status);
  border-top: var(--border-divider);   /* A5.3: above status bar */
  display: flex;
  align-items: center;
  padding: 0 8px;
  gap: 6px;
  font-family: 'Consolas', 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--text-dim);
}
#status-coords { min-width: 180px; color: var(--text); }
.sb-sep { width: 1px; height: 16px; background: var(--border); }
.sb-toggle {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid transparent;
  padding: 2px 8px;
  cursor: pointer;
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.5px;
  border-radius: 4px;
}
.sb-toggle:hover { background: var(--bg-panel); }
.sb-toggle.on {
  color: var(--status-on);
  border-color: var(--status-on);
}
#status-mode { margin-left: auto; color: var(--text); }

.sb-gridmode { display: inline-flex; gap: 1px; margin-left: 2px; }
.sb-gm-btn {
  background: transparent; border: 1px solid transparent;
  color: var(--text-dim); padding: 1px 4px; cursor: pointer;
  font-size: 12px; border-radius: 4px; font-family: inherit;
}
.sb-gm-btn:hover { background: var(--bg-panel); }
.sb-gm-btn.on { color: var(--status-on); border-color: var(--status-on); }

/* Dynamic input field (floats near cursor) */
.dyn-input-wrap {
  position: fixed;
  z-index: 1500;
  display: flex;
  gap: 2px;
  background: var(--bg-chrome);
  border: 1px solid var(--border);
  padding: 2px;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  font-family: 'Consolas', monospace;
  font-size: 11px;
  /* The tooltip rides 18px from the cursor; it must never take the canvas's
     mouse events (a fast move landed on it and a click focused a box). The
     boxes are reached with the keyboard. */
  pointer-events: none;
}
.dyn-input-wrap.hidden { display: none; }
.dyn-input-label {
  padding: 2px 4px;
  color: var(--text-dim);
  white-space: nowrap;
}
.dyn-input {
  background: var(--bg-canvas);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 1px 4px;
  font-family: inherit;
  font-size: 11px;
  width: 70px;
  outline: none;
}
.dyn-input:focus, .dyn-input.active { border-color: var(--accent); background: #2A2D30; }
/* Pass 3 (owner: "dynamic input needs stronger visual separation"): the box
   is a raised chrome surface that stands off the drawing; the field that takes
   the next key wears the accent ring; a typed (locked) value reads bright, a
   live one muted. app.js puts .dyn-raised on the wrap, .typed on a typed box. */
.dyn-input-wrap.dyn-raised {
  background: var(--forms-graphite-750, #2C2F32);
  border: 1px solid var(--forms-graphite-600, #434649);
  border-radius: 6px;
  padding: 3px;
  gap: 3px;
  align-items: center;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.dyn-input-wrap.dyn-raised .dyn-input-label { color: var(--forms-text-secondary, #B7B8B4); }
.dyn-input-wrap.dyn-raised .dyn-input {
  background: var(--forms-graphite-950, #101316);
  border: 1px solid var(--forms-graphite-600, #434649);
  border-radius: 3px;
  color: var(--forms-text-muted, #8A8B88);
  width: 84px;
}
.dyn-input-wrap.dyn-raised .dyn-input.typed {
  color: var(--forms-text-primary, #E8E8E5);
  border-color: var(--product-accent-muted, #355EBA);
}
.dyn-input-wrap.dyn-raised .dyn-input:focus {
  color: var(--forms-text-primary, #E8E8E5);
  background: #0C0E10;
  border-color: var(--product-accent, #326BDF);
  box-shadow: 0 0 0 1px var(--product-accent, #326BDF);
}

/* ===== Context menu ===== */
.ctx-menu {
  position: fixed;
  min-width: 160px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
  z-index: 1000;
  padding: 4px 0;
  font-family: 'Segoe UI', sans-serif;
  font-size: 11px;
  color: var(--text);
}
.ctx-menu.hidden { display: none; }
.ctx-item {
  padding: 5px 14px;
  cursor: pointer;
  white-space: nowrap;
}
.ctx-item:hover { background: var(--active); color: var(--accent2); }
.ctx-item.disabled { color: var(--text-dim); cursor: default; }
.ctx-item.disabled:hover { background: transparent; color: var(--text-dim); }
.ctx-sep { height: 1px; background: var(--border); margin: 4px 0; }
.ctx-hotkey {
  float: right;
  color: var(--text-dim);
  margin-left: 24px;
}

/* ===== Modals ===== */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 4000;
}
.modal.hidden { display: none; }
.cmd-palette-box { display: flex; }
.cmd-palette-box.hidden { display: none !important; }
.modal-content {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.6);
  min-width: 300px;
  max-width: 90vw;
  max-height: 80vh;
  overflow: auto;
}
.modal-sm { min-width: 280px; max-width: 400px; }
.modal-header {
  background: var(--bg-chrome);
  padding: 8px 12px;
  font-size: 12px;
  font-weight: bold;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.modal-close {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 14px;
}
.modal-close:hover { color: #ff5555; }
.modal-body { padding: 8px 12px; }


/* User Preferences tabs */
.prefs-tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.prefs-tab {
  flex: 1; background: transparent; color: var(--text-dim);
  border: none; padding: 7px 10px; cursor: pointer;
  border-bottom: 2px solid transparent;
  font-family: inherit; font-size: 11px; letter-spacing: 0.5px;
}
.prefs-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.prefs-tab:hover { color: var(--text); }
.prefs-panel { display: none; }
.prefs-panel.active { display: block; }

/* Hatch picker */
.hatch-dialog {
  display: grid;
  grid-template-columns: 1fr 310px;
  gap: 12px;
  padding: 12px;
}
.hatch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px;
  max-height: 440px;
  overflow-y: auto;
  padding: 2px;
}
.hatch-tile {
  background: var(--bg-chrome);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: var(--text-dim);
  font-size: 9px;
  letter-spacing: 0.3px;
}
.hatch-tile:hover { border-color: var(--accent); background: var(--active); color: var(--text); }
.hatch-tile.selected {
  border-color: var(--accent);
  background: rgba(50, 107, 223, 0.15);
  color: var(--accent2);
}
.hatch-tile canvas {
  width: 72px;
  height: 72px;
  background: var(--bg-canvas);
  border-radius: 4px;
}
.hatch-preview-pane {
  border-left: 1px solid var(--border);
  padding-left: 12px;
  display: flex;
  flex-direction: column;
}
.hatch-preview-title {
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--text-dim);
  text-transform: uppercase;
  margin-bottom: 6px;
}
#hatch-preview-canvas {
  background: var(--bg-canvas);
  border: 1px solid var(--border);
  border-radius: 4px;
  width: 100%;
  height: 240px;
}
.hatch-selected-name {
  text-align: center;
  font-family: monospace;
  color: var(--accent2);
  font-size: 14px;
  padding: 8px 0;
}

/* Layer Manager modal */
.lm-tabs { display: flex; border-bottom: 1px solid var(--border); background: var(--bg-chrome); }
.lm-tab {
  background: transparent; color: var(--text-dim);
  border: none; padding: 8px 14px; cursor: pointer;
  border-bottom: 2px solid transparent; font-family: inherit; font-size: 11px;
  letter-spacing: 0.5px; text-transform: uppercase;
}
.lm-tab.active { color: var(--accent); border-bottom-color: var(--accent); background: var(--bg-panel); }
.lm-tab:hover { color: var(--text); }

.lm-panel { display: none; padding: 10px; }
.lm-panel.active { display: block; }

.lm-toolbar {
  display: flex; gap: 4px; align-items: center;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
  background: var(--bg-chrome); margin: -10px -10px 8px;
}

.lm-header-row, .lm-layer-row {
  display: grid;
  grid-template-columns: 32px 32px 32px 40px 1.5fr 1fr 0.8fr 0.6fr 1.5fr;
  gap: 4px;
  align-items: center;
  padding: 4px 10px;
  font-size: 11px;
}
.lm-header-row {
  background: var(--bg-chrome);
  color: var(--text-dim);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border-bottom: 1px solid var(--border);
}

.lm-list { max-height: 420px; overflow-y: auto; }
.lm-layer-row { border-bottom: 1px solid rgba(42, 42, 53, 0.4); cursor: pointer; }
.lm-layer-row:hover { background: var(--active); }
.lm-layer-row.current { background: rgba(74, 158, 255, 0.1); color: var(--accent2); }

.lm-swatch { width: 16px; height: 16px; border: 1px solid var(--border); cursor: pointer; border-radius: 4px; }
.lm-toggle { cursor: pointer; text-align: center; color: var(--text-dim); font-size: 13px; }
.lm-toggle.on { color: var(--accent2); }
.lm-toggle.locked { color: #FF8855; }
.lm-toggle.print { color: #88DD88; }
.lm-layer-row input[type="text"],
.lm-layer-row input[type="number"] {
  background: transparent; border: 1px solid transparent; color: inherit;
  font-family: inherit; font-size: 11px; padding: 2px 4px; width: 100%;
}
.lm-layer-row input[type="text"]:focus,
.lm-layer-row input[type="number"]:focus {
  background: var(--bg-chrome); border-color: var(--accent);
}
.lm-layer-row select {
  background: var(--bg-chrome); color: var(--text);
  border: 1px solid var(--border); font-size: 11px; padding: 2px; width: 100%;
}

.lm-state-row {
  display: flex; gap: 8px; align-items: center;
  padding: 6px 10px; border-bottom: 1px solid rgba(42, 42, 53, 0.4);
}
.lm-state-row .lm-state-name { flex: 1; color: var(--text); }
.lm-state-row button { padding: 3px 10px; font-size: 10px; }

.pp-lbl {
  display: block;
  color: var(--text-dim);
  font-size: 11px;
  margin-top: 8px;
  margin-bottom: 2px;
}

.cb-tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 8px; }
.cb-tab {
  flex: 1;
  background: transparent; color: var(--text-dim);
  border: none; padding: 6px 12px; cursor: pointer;
  border-bottom: 2px solid transparent; font-family: inherit; font-size: 12px;
}
.cb-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.cb-tab:hover { color: var(--text); }
.cb-desc {
  color: var(--text-dim); font-size: 11px;
  background: var(--bg-chrome); padding: 6px 8px;
  border-radius: 4px; line-height: 1.4;
}

.osnap-row {
  display: block;
  padding: 4px 0;
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
}
.osnap-row input { margin-right: 8px; }
.osnap-row:hover { color: var(--accent2); }


/* ═════════ WORKSPACE TAB ═════════ */
.ws-layer-row {
  display: flex;
  gap: 4px;
  align-items: center;
  padding: 4px 6px;
}
.ws-icon-btn {
  width: 28px;
  height: 28px;
  background: #2A2D30;
  color: #C6C7C3;
  border: 1px solid #383B3E;
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: background 0.1s;
}
.ws-icon-btn:hover { background: #383B3E; color: #FFFFFF; }
.ws-icon-btn:active { transform: translateY(1px); }
.ws-layer-select {
  flex: 1;
  min-width: 180px;
  height: 28px;
  background: #1E2124;
  color: #E8E8E5;
  border: 1px solid #383B3E;
  border-radius: 3px;
  padding: 0 8px;
  font-size: 12px;
  font-family: 'Segoe UI', Arial, sans-serif;
}

/* ═════════ POPUP DROPDOWN MENUS ═════════ */
.ws-popup {
  position: absolute;
  background: #1E2124;
  border: 1px solid #434649;
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.5);
  padding: 4px;
  z-index: 200;
  min-width: 220px;
  display: none;
}
.ws-popup.open { display: block; }
.ws-popup-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  cursor: pointer;
  color: var(--forms-text-primary);   /* was #E0E0F0 — a blue-tinted neutral the 08-29 sweep missed */
  font-size: 12px;
  font-family: 'Segoe UI', Arial, sans-serif;
  border-radius: 3px;
}
.ws-popup-item:hover { background: #2A2D30; color: #FFFFFF; }
.ws-popup-item.disabled { color: var(--forms-text-disabled); cursor: default; }   /* was #555568 (sweep miss) */
.ws-popup-item.disabled:hover { background: transparent; }
.ws-popup-sep {
  height: 1px;
  background: #383B3E;
  margin: 4px 6px;
}
.ws-popup-label {
  font-size: 10px;
  color: #8A8B88;
  padding: 6px 10px 3px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.ws-popup-icon {
  width: 18px;
  display: flex;
  justify-content: center;
  color: inherit;   /* Icon System v1: row ink (was --forms-info blue on the menu dot) */
}

/* ═════════ PLOT MODE PICKER ═════════ */
.plot-mode-btn {
  background: #1E2124;
  color: #C6C7C3;
  border: 1px solid #383B3E;
  border-radius: 3px;
  padding: 10px 6px;
  cursor: pointer;
  text-align: center;
  transition: background 0.1s, border-color 0.1s;
}
.plot-mode-btn:hover { background: #222528; border-color: #434649; }
.plot-mode-btn.active {
  background: #2A2D30;
  border-color: #326BDF;
  color: #FFFFFF;
}
.pmode-title { font-weight: bold; font-size: 12px; }
.pmode-sub   { font-size: 10px; color: #8A8B88; margin-top: 2px; }
.plot-mode-btn.active .pmode-sub { color: #B7B8B4; }

/* (The retired scientific calculator's rules were removed 2026-09-30: no
   element uses #calc-* / .calc-* / .ck any more.) */

/* ══════════════════════════════════════════════════════
   TOOLBAR LOGO
   ══════════════════════════════════════════════════════ */

.tb-logo {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 6px 0 4px;
  user-select: none;
  cursor: default;
}

.tb-logo-img {
  width: 21px;
  height: 21px;
  object-fit: contain;
  flex-shrink: 0;
  filter: brightness(1.8) drop-shadow(0 0 6px rgba(50, 107, 223, 0.5));
}

.tb-logo-text {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 3px;
  color: #E8E8E5;
  line-height: 1;
}

/* (Splash rules removed 2026-09-30: the splash is its own window,
   renderer/splash.html, with its own inline styles; no element in this page
   uses #forms2d-splash / #splash-bg / .splash-*.) */

/* ══════════════════════════════════════════════════════
   FILE OPEN PROGRESS BAR
   ══════════════════════════════════════════════════════ */

#file-load-bar-wrap {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background: var(--cli-bg);
  border-top: 1px solid var(--border);
}

#file-load-bar-wrap.visible {
  display: flex;
}

#file-load-bar-track {
  flex: 1;
  height: 2px;
  background: var(--forms-graphite-850);   /* was #1A1A28 (blue-tinted; 08-29 sweep miss) */
  border-radius: 99px;
  overflow: visible;
  position: relative;
}

#file-load-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #2462E7, #326BDF, #749FF6);
  border-radius: 99px;
  transition: width 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
}

#file-load-bar-fill::after {
  content: '';
  position: absolute;
  right: -3px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #A4C2FA;
  box-shadow: 0 0 6px 2px rgba(164, 194, 250, 0.6);
}

#file-load-label {
  font-size: 10px;
  font-family: 'Consolas', 'JetBrains Mono', monospace;
  color: var(--forms-graphite-600);   /* was #444458 (blue-tinted; 08-29 sweep miss), same luminance */
  white-space: nowrap;
  min-width: 80px;
  text-align: right;
}

/* ══════════════════════════════════════════════════════
   WORKSPACE MANAGEMENT
   ══════════════════════════════════════════════════════ */

.hidden-panel { display: none !important; }

/* Canvas area with rulers */
#canvas-area {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr;
  overflow: hidden;
}
#ruler-corner { grid-column: 1; grid-row: 1; }
#ruler-h { grid-column: 2; grid-row: 1; }
#ruler-v { grid-column: 1; grid-row: 2; }
#canvas-wrap { grid-column: 2; grid-row: 2; }

#ruler-h, #ruler-v { background: var(--bg-chrome); flex-shrink: 0; }
#ruler-h { height: 20px; width: 100%; border-bottom: 1px solid var(--border); }
#ruler-v { width: 20px; height: 100%; border-right: 1px solid var(--border); }
#ruler-corner {
  width: 20px; height: 20px;
  background: var(--bg-chrome);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Panel title bars */
.panel-title-bar {
  display: flex;
  align-items: center;
  padding: 0 6px;
  height: 22px;
  background: var(--panel-header);
  border-bottom: 1px solid var(--border);
  cursor: grab;
  user-select: none;
  flex-shrink: 0;
}
.panel-title-bar:active { cursor: grabbing; }
.panel-drag-handle { color: #333639; font-size: 12px; margin-right: 6px; cursor: grab; }
.panel-title-label { flex: 1; font-size: 10px; letter-spacing: 1px; color: var(--text-dim); text-transform: uppercase; }
.panel-title-controls { display: flex; gap: 4px; }
.panel-ctrl-btn {
  width: 16px; height: 16px;
  background: transparent; border: none;
  color: #333639; cursor: pointer;
  font-size: 11px; display: flex;
  align-items: center; justify-content: center;
  border-radius: 4px; padding: 0;
}
.panel-ctrl-btn:hover { background: var(--active); color: var(--text); }

/* Panel resize handle */
.panel-resize-handle {
  width: 4px; background: transparent;
  cursor: col-resize; flex-shrink: 0;
}
.panel-resize-handle:hover, .panel-resize-handle.dragging { background: var(--accent); }

/* Workspace toggle mini-panel */
#workspace-toggle-panel {
  position: fixed; bottom: 32px; right: 12px;
  z-index: 2000; background: var(--bg-panel);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 0; min-width: 200px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
}
#workspace-toggle-panel.hidden { display: none; }

.ws-panel-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
  font-size: 10px; letter-spacing: 1px; color: var(--text-dim); text-transform: uppercase;
}
.ws-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 10px; font-size: 11px; color: var(--text); cursor: pointer;
}
.ws-toggle-row:hover { background: var(--active); }

.ws-toggle-switch {
  width: 28px; height: 14px; border-radius: 7px;
  background: var(--border); position: relative; transition: background 0.15s; flex-shrink: 0;
}
.ws-toggle-switch.on { background: var(--accent); }
.ws-toggle-switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 10px; height: 10px; border-radius: 50%;
  background: white; transition: left 0.15s;
}
.ws-toggle-switch.on::after { left: 16px; }

.ws-divider { height: 1px; background: var(--border); margin: 2px 0; }
.ws-footer {
  display: flex; gap: 6px; padding: 6px 10px; border-top: 1px solid var(--border);
}
.ws-btn {
  flex: 1; background: var(--bg-chrome); color: var(--text-dim);
  border: 1px solid var(--border); padding: 3px 8px; font-size: 10px;
  border-radius: 4px; cursor: pointer; font-family: inherit;
}
.ws-btn:hover { background: var(--active); color: var(--text); }

/* Layer panel enhancements */
.layer-filter-wrap {
  padding: 4px 6px; border-bottom: 1px solid var(--border);
  display: flex; gap: 4px; align-items: center;
}
.layer-filter-input {
  flex: 1; background: var(--bg-chrome); border: 1px solid var(--border);
  color: var(--text); font-size: 10px; padding: 2px 5px; font-family: inherit; border-radius: 4px;
}
.layer-filter-input::placeholder { color: #333639; }
.layer-highlight-toggle {
  display: flex; align-items: center; gap: 4px;
  font-size: 10px; color: var(--text-dim); cursor: pointer; user-select: none; white-space: nowrap;
}

/* Tab key full-canvas mode */
body.canvas-focus-mode #panel-left,
body.canvas-focus-mode #panel-right,
body.canvas-focus-mode .pal-float,
body.canvas-focus-mode #cli-container { display: none !important; }

/* ─── ISA Palette (v0.6.0) ─────────────────────────────────────────────── */
/* Each right-side panel needs `flex-shrink: 0` so adjacent panels can't
   collapse into each other when content grows. Without this the Families
   list bleeds into the ISA palette area below it. */
#panel-right > .panel { flex-shrink: 0; }
/* (#isa-panel rules removed 2026-09-30: the ISA panel is gone; its rows live on as .isa-pal-* in the Library.) */
.isa-pal-cat {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px;
  background: var(--bg-chrome);
  border-top: 1px solid var(--border);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  user-select: none;
}
.isa-pal-cat:hover { background: var(--active); }
.isa-pal-chev { width: 10px; color: var(--accent); }
.isa-pal-cat-label { flex: 1; }
.isa-pal-cat-count {
  color: var(--text-dim); font-size: 10px;
  background: rgba(255,255,255,0.04);
  padding: 1px 6px; border-radius: 8px;
}
.isa-pal-list {
  display: block;
  background: rgba(0,0,0,0.12);
}
.isa-pal-subhdr {
  padding: 4px 12px;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
  border-top: 1px solid var(--border);
}

/* ── Dock panel content (the Library rows; the dock chrome itself retired
   2026-09-29 for the palette shell — see the Palettes block) ─────────── */
.dock-form-row {
  display: flex; justify-content: space-between; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text); padding: 3px 4px; cursor: pointer; border-radius: 3px;
}
.dock-form-row:hover { background: var(--border); }

/* ── Custom toolbar (one icon high) ────────────────────────────────────── */
#custom-toolbar {
  display: flex; align-items: center; gap: 2px; padding: 1px 6px;
  height: 30px; flex-shrink: 0;
  background: var(--bg-chrome); border-bottom: 1px solid var(--border);
}
/* Collapse WITHOUT display:none (2026-06-12): a display:none child stops
   being a grid item, every row below shifts one slot, and the CLI lands in
   the wrong band ("we lost some important stuff down there"). */
#custom-toolbar.ctb-off { height: 0; min-height: 0; padding: 0; border: none; overflow: hidden; }
#custom-toolbar.hidden { display: flex; height: 0; min-height: 0; padding: 0; border: none; overflow: hidden; }
.ctb-btn {
  width: 28px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: 4px;
  color: var(--text); font-size: 10px; cursor: pointer; padding: 0;
}
.ctb-btn:hover { background: var(--bg-panel); border-color: var(--border); }
.ctb-btn svg { width: 16px; height: 16px; }
.ctb-widget { display: inline-flex; align-items: center; gap: 3px; height: 26px; }
.ctb-widget select {
  background: var(--bg-panel); border: 1px solid var(--border); color: var(--text);
  font-size: 10px; height: 22px; max-width: 110px;
}
.ctb-sep { width: 1px; height: 18px; background: var(--border); margin: 0 3px; }
.isa-pal-row {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  gap: 6px;
  align-items: center;
  padding: 4px 8px 4px 14px;
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
  border-bottom: 1px solid rgba(42,42,53,0.4);
}
.isa-pal-row:hover { background: var(--active); }
.isa-pal-icon { color: var(--accent); text-align: center; }
.isa-pal-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.isa-pal-tag {
  color: var(--text-dim);
  font-family: Consolas, monospace;
  font-size: 10px;
}
.isa-pal-row-action {
  background: rgba(50, 107, 223, 0.08);
  color: var(--accent);
}
.isa-pal-row-action:hover { background: rgba(50, 107, 223, 0.18); }

/* ─── Inline slot-edit popover (v0.7.0) ──────────────────────────────── */
.bubble-slot-modal {
  position: fixed;
  z-index: 6000;
  min-width: 320px;
  background: var(--bg-panel);
  border: 1px solid var(--accent);
  box-shadow: 0 6px 24px rgba(0,0,0,0.6);
  border-radius: 4px;
  font-family: 'Segoe UI', system-ui, sans-serif;
}
.bubble-slot-modal.hidden { display: none; }
.bsmodal-header {
  padding: 8px 12px;
  background: var(--bg-chrome);
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  letter-spacing: 1px;
  color: var(--text-dim);
  text-transform: uppercase;
  border-radius: 4px 4px 0 0;
}
.bsmodal-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.bsmodal-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 8px;
  align-items: center;
  font-size: 11px;
}
.bsmodal-row.bsmodal-check {
  grid-template-columns: auto auto;
  margin-top: 4px;
  color: var(--text-dim);
}
.bsmodal-lbl { color: var(--text-dim); }
.bsmodal-input {
  background: var(--bg-chrome);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 6px;
  font-family: Consolas, monospace;
  font-size: 11px;
  outline: none;
}
.bsmodal-input:focus { border-color: var(--accent); }
.bsmodal-footer {
  padding: 8px 12px;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  border-top: 1px solid var(--border);
}

/* ═════════ CONTEXTUAL RIBBON TABS ═════════ */
.ribbon-tab-contextual {
  background: #222528 !important;
  color: #749FF6 !important;
  border-color: #434649 !important;
}
.ribbon-tab-contextual.active {
  background: #2E2E40 !important;
}
.ribbon-contextual { background: #222528 !important; }
.ctx-align {
  background: #2A2D30;
  color: #C6C7C3;
  border: 1px solid #434649;
  border-radius: 2px;
  cursor: pointer;
  font-size: 12px;
  padding: 0;
}
.ctx-align:hover { background: #383B3E; color: #FFFFFF; }
.ctx-align.active {
  background: #326BDF;
  color: #FFFFFF;
  border-color: #326BDF;
}
/* Table tab Bold / Italic show the current cell (bedtime run 2026-09-30) —
   the on state is the accent, like the alignment grid. */
.tb-btn[aria-pressed="true"] {
  background: var(--active-control);
  border-color: var(--accent);
  color: #FFFFFF;
}

/* ═══════════════════════════════════════════════════════════════════════════
   X-8 REVIEW-FINISH LAYER (owner directive, 2026-09-27)
   "More Forms-Review-like — minus the purple." Forms Review consumes THIS
   app's Graphite palette; what evolved there is the FINISH: white-alpha
   borders, a radius ramp, layered shadows, a 4px grid, snappy motion, and
   hover as NEUTRAL elevation (accent = application state only). This layer
   ports that finish onto the existing selectors — additive, cascade-wins,
   no geometry changes. The product accent keeps the accent slot (Review's
   vermilion slot). Tokens mirror formsReview/src/tokens.css.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --bg-elevated:    var(--forms-graphite-800);
  --bg-overlay:     var(--forms-graphite-750);
  --bg-input:       #111417;                    /* graphite input well */
  --border-subtle:  #ffffff0f;
  --border-default: #ffffff18;
  --border-strong:  #ffffff28;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 10px;
  --shadow-sm: 0 1px 3px #00000040;
  --shadow-md: 0 4px 12px #00000060;
  --shadow-lg: 0 8px 24px #00000080;
  --accent-dim: var(--product-accent-surface);
  --motion-fast: 100ms ease;
  --motion-base: 150ms ease;
}

/* ── Buttons: neutral-elevation hover, snappy, soft radius, focus ring ── */
.tb-btn, .panel-btn, .ctb-btn, .modal-close, .ctx-item {
  transition: background-color var(--motion-fast), color var(--motion-fast),
              border-color var(--motion-fast);
}
.tb-btn { border-radius: var(--radius-sm); }
.panel-btn, .ctb-btn { border-radius: var(--radius-sm); }
.tb-btn:hover, .ctb-btn:hover { background: var(--bg-overlay); }
.panel-btn:hover:not(:disabled) { background: var(--bg-overlay); }
.tb-btn:focus-visible, .panel-btn:focus-visible, .ctb-btn:focus-visible,
.ribbon-tab:focus-visible, .frame-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--accent-dim), 0 0 0 1px var(--product-accent-muted);
}
.tb-btn:disabled, .panel-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── Tabs: quiet until active; hover elevates, never tints ── */
.ribbon-tab { border-radius: var(--radius-sm) var(--radius-sm) 0 0; transition: background-color var(--motion-fast), color var(--motion-fast); }
.ribbon-tab:hover { background: var(--bg-overlay); }
.frame-tab, .lm-tab, .cb-tab { border-radius: var(--radius-sm) var(--radius-sm) 0 0; transition: background-color var(--motion-fast), color var(--motion-fast); }
.frame-tab:hover:not(.active) { background: var(--bg-overlay); }

/* ── Menus & popups: elevated surface, white-alpha edge, real shadow ── */
.ctx-menu {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 4px;
}
.ctx-item { border-radius: var(--radius-sm); }
.ctx-item:hover { background: var(--bg-overlay); }
.ctx-sep { border-color: var(--border-subtle); }

/* ── Modals: the Review card ── */
.modal-content, .bubble-slot-modal, .bsmodal-body {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.modal-header, .bsmodal-header { border-bottom: 1px solid var(--border-subtle); }
.bsmodal-footer { border-top: 1px solid var(--border-subtle); }

/* ── Inputs: graphite well, alpha border, strong focus edge ── */
#cli-input, .dyn-input, .bsmodal-input, .layer-filter-input, .modal-content input[type="text"],
.pal-body input[type="text"]:not(.pi-in), .pal-body select:not(.pi-sel):not(.pi-type),
.modal-content select, .modal-content textarea {
  background: var(--bg-input);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  transition: border-color var(--motion-fast);
}
#cli-input:focus, .dyn-input:focus, .bsmodal-input:focus, .layer-filter-input:focus,
.pal-body input[type="text"]:not(.pi-in):focus, .pal-body select:not(.pi-sel):not(.pi-type):focus,
.modal-content input[type="text"]:focus, .modal-content select:focus,
.modal-content textarea:focus {
  outline: none;
  border-color: var(--border-strong);
}

/* ── Scrollbars: slim graphite, Review-quiet ── */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--forms-graphite-700); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--forms-graphite-600); border: 2px solid transparent; background-clip: content-box; }

/* ═══ Ribbon labels hidden (owner, 2026-09-27: "remove the tool bar text for
   now"). Icons + the native tooltip carry command identity until the
   QC-owned ribbon/icon redesign lands. ONE switch: remove the
   `ribbon-icons-only` class from #ribbon-panel to restore labels.
   A button with no icon would keep its text; since Icon System v1
   (2026-09-30) every ribbon button has one, the contextual Hatch / Table
   buttons included. Dropdown buttons keep a caret so they still read as
   menus. ═══ */
#ribbon-panel.ribbon-icons-only .tb-btn .tb-icon + .tb-lbl { display: none; }
/* ═══ Hatch editor (owner seat-time 2026-09-28): one non-modal surface for
   every way into an existing hatch — Properties swatch, double-click,
   right-click › Edit Hatch…. Docked right so the drawing previews live. ═══ */
.hatch-editor {
  position: fixed;
  right: 16px;
  top: 96px;
  width: 330px;
  max-height: calc(100vh - 140px);
  overflow-y: auto;
  z-index: 1600;
  padding: 10px;
  font-size: 11px;
  color: var(--text);
  background: var(--bg-elevated, var(--bg-panel));
  border: 1px solid var(--border-default, var(--border));
  border-top: 2px solid var(--accent);
  border-radius: var(--radius-md, 6px);
  box-shadow: var(--shadow-md, 0 8px 24px rgba(0,0,0,0.45));
}
.hatch-editor .he-head { display: flex; justify-content: space-between; font-weight: bold; font-size: 12px; margin-bottom: 8px; }
.hatch-editor .he-x, .hatch-editor .hf-x { cursor: pointer; color: var(--forms-text-muted, #8A8B88); }
.hatch-editor .he-x:hover, .hatch-editor .hf-x:hover { color: var(--text); }
.hatch-editor .he-search { width: 100%; margin-bottom: 6px; }
.hatch-editor .he-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  max-height: 210px;
  overflow-y: auto;
  margin-bottom: 6px;
}
.hatch-editor .he-tile { text-align: center; cursor: pointer; padding: 2px; border: 1px solid transparent; border-radius: 4px; }
.hatch-editor .he-tile:hover { background: var(--bg-overlay, rgba(255,255,255,0.05)); }
.hatch-editor .he-tile.selected { border-color: var(--accent); }
.hatch-editor .he-tile canvas { display: block; margin: 0 auto; background: #111; border-radius: 2px; }
.hatch-editor .he-tile div { font-size: 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hatch-editor .he-row { display: flex; align-items: center; gap: 6px; margin-top: 5px; }
.hatch-editor .he-row label { width: 52px; flex: none; color: var(--forms-text-muted, #8A8B88); }
.hatch-editor .he-row input { flex: 1; min-width: 0; }
.hatch-editor .he-name { font-family: Consolas, monospace; color: var(--accent2, var(--accent)); }
.hatch-editor .he-custom-toggle { margin-top: 8px; width: 100%; }
.hatch-editor .he-custom { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--border-subtle, #282B2E); }
.hatch-editor .he-hidden { display: none; }
.hatch-editor .he-famhead, .hatch-editor .he-fam {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1.6fr 14px;
  gap: 3px;
  margin-top: 4px;
  align-items: center;
}
.hatch-editor .he-famhead span { font-size: 9px; color: var(--forms-text-muted, #8A8B88); }
.hatch-editor .he-fam input { min-width: 0; }
.hatch-editor .he-addfam, .hatch-editor .he-csave { margin-top: 6px; width: 100%; }
.hatch-editor .he-cprev { display: block; width: 100%; height: 80px; margin-top: 6px; background: #111; border-radius: 3px; }
.hatch-editor .he-cmsg { min-height: 14px; margin-top: 4px; color: var(--forms-text-muted, #8A8B88); }
.hatch-editor .he-foot { display: flex; justify-content: flex-end; gap: 6px; margin-top: 10px; }
.hatch-editor .he-ok { background: var(--accent); color: #fff; }
.pp-hatch-swatch { display: block; cursor: pointer; background: #111; border: 1px solid var(--border-default, #383B3E); border-radius: 3px; }
.pp-hatch-swatch:hover { border-color: var(--accent); }

#ribbon-panel.ribbon-icons-only .tb-btn[data-dropdown]::after {
  content: '▾';
  font-size: 9px;
  line-height: 1;
  color: var(--forms-text-muted);
  margin-left: -1px;
}

/* ═══ Palettes (2026-09-29 pinned-workspace pass) — ONE shell for every
   persistent tool (palettes.js). A side (#panel-left / #panel-right) holds
   groups; a group tabs palettes and stacks with the next behind a splitter;
   a palette collapses to its header or floats as a card. Quiet graphite: the
   active tab's underline is the only accent. ═══ */
.pal-zone { position: relative; display: flex; flex-direction: column; min-height: 0; overflow: hidden; background: var(--bg-panel); }
.pal-zone-left { border-right: var(--border-divider); }
.pal-group { display: flex; flex-direction: column; min-height: 0; }
.pal-group.collapsed { flex: 0 0 auto !important; }
.pal-grp-hdr {
  display: flex; align-items: stretch; gap: 1px; height: 26px; flex: 0 0 26px;
  padding: 0 3px 0 2px; background: var(--bg-chrome); border-bottom: 1px solid var(--border-subtle);
  user-select: none;
}
.pal-tabs { flex: 1; min-width: 0; display: flex; align-items: stretch; overflow: hidden; }
.pal-tab {
  flex: 0 1 auto; min-width: 28px; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 0 8px; background: transparent; border: none; border-bottom: 2px solid transparent;
  font-family: inherit; font-size: 11px; color: var(--forms-text-muted); cursor: pointer;
  transition: color var(--motion-fast), border-color var(--motion-fast);
}
.pal-tab:hover { color: var(--text); }
.pal-tab.active { color: var(--text); border-bottom-color: var(--product-accent); }
.pal-tab:focus-visible, .pal-btn:focus-visible { outline: none; box-shadow: 0 0 0 1px var(--product-accent-muted); }
.pal-btn {
  flex: none; align-self: center; width: 20px; height: 20px; padding: 0; line-height: 20px;
  background: transparent; border: none; border-radius: var(--radius-sm);
  font-family: inherit; font-size: 11px; color: var(--forms-text-muted); cursor: pointer;
}
.pal-btn:hover { background: var(--bg-overlay); color: var(--text); }
.pal-grp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pal-group.collapsed .pal-grp-body { display: none; }
.pal-palette { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pal-body { flex: 1; min-height: 0; overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; }
/* The palette's tab names it — the section headings the adopted panels
   brought with them would say it twice. */
.pal-body > .panel { border-bottom: none; }
.pal-body > .panel > .panel-header { display: none; }
.pal-split { flex: 0 0 5px; cursor: row-resize; background: var(--bg-chrome); border-top: 1px solid var(--border-subtle); border-bottom: 1px solid var(--border-subtle); }
.pal-split:hover, .pal-split.dragging { background: var(--bg-overlay); }
.pal-zone-resize { position: absolute; top: 0; bottom: 0; width: 4px; cursor: col-resize; z-index: 5; }
.pal-zone-resize.right { left: 0; }
.pal-zone-resize.left { right: 0; }
.pal-zone-resize:hover, .pal-zone-resize.dragging { background: var(--border-default); }
.pal-float {
  position: fixed; z-index: 720; display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg-panel); border: 1px solid var(--border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
}
.pal-float.collapsed { height: auto !important; }
.pal-float-hdr {
  display: flex; align-items: center; gap: 1px; height: 26px; flex: 0 0 26px; padding: 0 3px 0 10px;
  background: var(--bg-chrome); border-bottom: 1px solid var(--border-subtle); cursor: grab; user-select: none;
}
.pal-float-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; color: var(--text); }
.pal-float-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pal-float.collapsed .pal-float-body, .pal-float.collapsed .pal-float-grip { display: none; }
.pal-float-grip {
  position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; cursor: nwse-resize;
  border-right: 2px solid var(--border-strong); border-bottom: 2px solid var(--border-strong);
}
.pal-menu {
  position: fixed; z-index: 3000; min-width: 150px; padding: 4px;
  background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.pal-menu-item { height: 24px; line-height: 24px; padding: 0 10px; border-radius: var(--radius-sm); font-size: 11px; color: var(--text); cursor: pointer; white-space: nowrap; }
.pal-menu-item:hover { background: var(--bg-overlay); }
.pal-menu-sep { height: 1px; margin: 4px 2px; background: var(--border-subtle); }
.pal-ghost {
  position: fixed; z-index: 3001; pointer-events: none; padding: 3px 8px; font-size: 11px; color: var(--text);
  background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
}
.pal-drop-edge { position: fixed; z-index: 2999; width: 28px; }
.pal-drop-edge.pal-drop-on, .pal-zone.pal-drop-on { background: var(--product-accent-surface); box-shadow: inset 0 0 0 1px var(--product-accent-muted); }
.pal-grp-hdr.pal-drop-on { box-shadow: inset 0 -2px 0 var(--product-accent-muted); }
body.pal-dragging, body.pal-dragging * { cursor: grabbing !important; }
.ws-panel-sub { padding: 4px 10px 2px; font-size: 9px; letter-spacing: 1px; color: var(--text-dim); }

/* ═══ Properties inspector (properties.js) — "Property name   value", one
   row height, one label column, controls that read as text until the row is
   hovered or the field focused; sections, not cards. ═══ */
#props-body.pi-host { padding: 0; display: flex; flex-direction: column; }
.pi-head {
  position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; background: var(--bg-panel); border-bottom: 1px solid var(--border-subtle);
}
.pi-search { box-sizing: border-box; width: calc(100% - 16px); margin: 5px 8px; padding: 5px 7px; border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-input); color: var(--text); font: inherit; font-size: 11px; }
.pi-status { margin: 4px 8px; padding: 6px; font-size: 11px; line-height: 1.4; color: var(--text); border-left: 2px solid var(--border-strong); }
.pi-status.pi-error { color: var(--forms-error); border-color: var(--forms-error); }
.pi-status[hidden], .pi-row[hidden], .pi-sec[hidden] { display: none; }
.pi-sec-h { width: 100%; border: 0; border-radius: 0; background: transparent; font-family: inherit; text-align: left; }
.pi-sec-h:focus-visible { outline: 1px solid var(--product-accent); outline-offset: -2px; }
.pi-unit { margin-left: 5px; font-size: 9px; color: var(--text-muted); font-weight: normal; }
.pi-readonly-mark { margin-left: 5px; color: var(--text-muted); }
.pi-rgb { display: flex; align-items: center; gap: 3px; min-width: 0; }
.pi-rgb-swatch { width: 23px; height: 19px; padding: 0; border: 0; background: transparent; flex: 0 0 23px; }
.pi-in[aria-invalid="true"] { outline: 1px solid var(--forms-error); outline-offset: -1px; }
.pi-type {
  flex: 1; min-width: 0; height: 24px; padding: 0 22px 0 6px; box-sizing: border-box;
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--text);
  background: var(--bg-input) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%238A8B88'/%3E%3C/svg%3E") no-repeat right 8px center;
  border: 1px solid var(--border-default); border-radius: var(--radius-sm); appearance: none; -webkit-appearance: none; outline: none; cursor: pointer;
}
.pi-type:focus { border-color: var(--border-strong); }
.pi-type:disabled { opacity: 1; cursor: default; padding-left: 0; background: transparent; border-color: transparent; }
.pi-type option { background: var(--bg-elevated); color: var(--text); font-weight: normal; }
.pi-count { display: none; }
.pi-banner {
  display: flex; align-items: center; gap: 6px; margin: 6px 8px 2px; padding: 5px 7px;
  font-size: 10.5px; line-height: 1.35; color: var(--forms-text-secondary);
  background: var(--product-accent-surface); border-left: 2px solid var(--product-accent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.pi-banner > span { flex: 1; }
.pi-banner[hidden] { display: none; }
#props-dynamic { padding: 2px 0 10px; }
.pi-sec + .pi-sec, .pi-fold-b > .pi-sec + .pi-sec { border-top: 1px solid var(--border-subtle); }
.pi-sec-h {
  display: flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px;
  font-size: 10px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--forms-text-muted); cursor: pointer; user-select: none;
}
.pi-sec-h:hover { color: var(--text); }
.pi-chev { width: 10px; font-size: 9px; }
.pi-sec.collapsed .pi-sec-b { display: none; }
.pi-sec-b { padding-bottom: 4px; }
.pi-row {
  display: grid; grid-template-columns: minmax(72px, 42%) minmax(0, 1fr); align-items: center;
  column-gap: 6px; min-height: 22px; padding: 0 8px 0 22px;
}
.pi-row:hover { background: rgba(255, 255, 255, 0.025); }
.pi-k { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; color: var(--forms-text-secondary); }
.pi-owned .pi-k { color: var(--forms-text-muted); }
.pi-v { min-width: 0; display: flex; align-items: center; gap: 4px; }
.pi-in, .pi-sel, .pi-pick {
  flex: 1; width: 100%; min-width: 0; height: 20px; box-sizing: border-box; margin: 0; padding: 0 5px;
  font-family: Consolas, 'JetBrains Mono', monospace; font-size: 11px; color: var(--text);
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm); outline: none;
  transition: border-color var(--motion-fast), background-color var(--motion-fast);
}
.pi-row:hover .pi-in:not(.pi-ro), .pi-row:hover .pi-sel, .pi-row:hover .pi-pick:not(:disabled) { border-color: var(--border-default); }
.pi-in:focus, .pi-sel:focus, .pi-pick:focus-visible { background: var(--bg-input); border-color: var(--border-strong); }
.pi-in.pi-ro { color: var(--forms-text-muted); cursor: default; }
.pi-in::placeholder { color: var(--forms-text-muted); font-style: italic; }
.pi-sel { appearance: none; -webkit-appearance: none; padding-right: 16px; cursor: pointer; }
.pi-row:hover .pi-sel, .pi-sel:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%238A8B88'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 5px center;
}
.pi-sel option { background: var(--bg-elevated); color: var(--text); }
.pi-pick { display: flex; align-items: center; gap: 6px; text-align: left; cursor: pointer; }
.pi-pick:disabled { cursor: default; color: var(--forms-text-muted); }
.pi-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pi-sw { flex: none; width: 12px; height: 12px; box-sizing: border-box; border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 2px; }
.pi-sw-by { box-shadow: inset 0 0 0 2px var(--bg-panel); }
.pi-sw-varies { background: transparent !important; border-style: dashed; }
.pi-sample { flex: none; display: inline-flex; align-items: center; width: 40px; height: 10px; color: var(--forms-text-secondary); }
.pi-sample svg { display: block; }
.pi-cb { margin: 0 0 0 5px; width: 13px; height: 13px; accent-color: var(--product-accent); cursor: pointer; }
.pi-cb:disabled { cursor: default; opacity: 0.55; }
.pi-sum, .pi-hatch, .pi-file { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; }
.pi-sum-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-left: 5px; font-size: 11px; color: var(--text); }
.pi-edit {
  flex: none; height: 20px; padding: 0 8px; font-family: inherit; font-size: 10.5px; color: var(--forms-text-secondary);
  background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: var(--radius-sm); cursor: pointer;
}
.pi-edit:hover { color: var(--text); background: var(--bg-overlay); }
.pi-hatch .pp-hatch-swatch { flex: none; width: 44px; height: 18px; box-sizing: border-box; }
.pi-fold { margin: 6px 8px 0; padding: 5px 0 3px; font-size: 10.5px; color: var(--forms-text-muted); border-top: 1px solid var(--border-subtle); cursor: pointer; user-select: none; }
.pi-fold:hover { color: var(--text); }
.pi-empty { padding: 14px 10px; font-size: 11px; color: var(--forms-text-muted); }
.pi-add { color: var(--forms-text-secondary); font-family: inherit; }
.pi-menu {
  position: fixed; z-index: 3000; max-height: 340px; overflow-y: auto; padding: 4px;
  background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-md);
}
.pi-mi { display: flex; align-items: center; gap: 8px; height: 22px; padding: 0 8px; border-radius: var(--radius-sm); font-size: 11px; color: var(--text); cursor: pointer; white-space: nowrap; }
.pi-mi:hover { background: var(--bg-overlay); }
.pi-mi.on { color: var(--product-accent-bright); }
.pi-menu-sep { height: 1px; margin: 4px 2px; background: var(--border-subtle); }
.pi-mgrid { display: grid; grid-template-columns: repeat(10, 16px); gap: 3px; padding: 4px 6px; }
.pi-msw { width: 16px; height: 16px; box-sizing: border-box; border: 1px solid rgba(255, 255, 255, 0.18); border-radius: 2px; cursor: pointer; }
.pi-msw:hover { border-color: var(--text); }
.pi-msw.on { box-shadow: 0 0 0 2px var(--product-accent); }

/* ═══ Draw › Properties group (Home › Properties): the drafting defaults —
   current Layer / Color / Linetype / Lineweight — moved out of the title
   row. Same widgets, two rows, one label column. ═══ */
.ribbon-props {
  flex: 1; display: grid; grid-template-columns: auto auto auto auto; grid-template-rows: 1fr 1fr;
  align-items: center; column-gap: 6px; row-gap: 2px; padding: 6px 8px 2px;
}
.ribbon-props .rp-k { font-size: 10px; color: var(--forms-text-muted); text-align: right; }
.ribbon-props button.panel-input { width: 128px !important; height: 24px !important; overflow: hidden; }
.ribbon-props #linetype-picker-slot button.panel-input { width: 150px !important; }
.ribbon-props button.panel-input > span:first-child { min-width: 0; overflow: hidden; white-space: nowrap; }
.ribbon-props svg { flex: none; }
/* Home › Properties also carries Match Properties (QC 2026-09-29): one
   button in its own column beside the four pickers, centred on both rows. */
.ribbon-props .rp-match { grid-column: 5; grid-row: 1 / span 2; align-self: center; }
/* The picker grid keeps the button grids' 78 px height, so with the strip's
   sideways scrollbar its label stays on the same baseline as its neighbours. */
.ribbon-props { min-height: 78px; }

/* ═══ Home tab (QC rulings 2026-09-29): split buttons + category menus ═══
   A split is a face (the last tool used from its family — a normal .tb-btn
   that runs its data-cmd) and a narrow caret that opens the family. A
   category menu is a .tb-btn[data-dropdown] whose face never changes. An
   open control shows the accent edge: every "on" state is the product accent. */
.tb-split { display: inline-flex; align-items: stretch; }
.tb-split > .tb-split-face { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.tb-split-caret {
  width: 10px; min-height: 32px; padding: 0; margin: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--forms-text-muted);
  border: 1px solid transparent; border-left: none;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-family: inherit; font-size: 9px; line-height: 1; cursor: pointer;
  transition: background-color var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.tb-split:hover > .tb-split-face, .tb-split:hover > .tb-split-caret { border-color: var(--border-default); }
.tb-split > .tb-split-face:hover, .tb-split > .tb-split-caret:hover { border-color: var(--accent); background: var(--bg-overlay); color: var(--text); }
.tb-split-caret:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-dim), 0 0 0 1px var(--product-accent-muted); }
.tb-split > .tb-split-caret[aria-expanded="true"], .tb-menu-btn[aria-expanded="true"] { border-color: var(--accent); background: var(--bg-overlay); color: var(--text); }
.home-flyout .ws-popup-icon svg { width: 16px; height: 16px; display: block; }

/* ═══ Quick Access (QC 2026-09-29): New · Open · Save | Undo · Redo in the
   title row, beside the Forms mark — the only quick-access surface (the
   floating opt-in toolbar was retired). Same routes as Ctrl+N/O/S/Z/Y. ═══ */
#quick-access { display: flex; align-items: center; gap: 2px; align-self: flex-end; height: 30px; margin-right: 6px; }
.qa-btn {
  width: 28px; height: 26px; padding: 0; display: inline-grid; place-items: center;
  background: transparent; color: var(--text); border: 1px solid transparent; border-radius: var(--radius-sm);
  cursor: pointer; transition: background-color var(--motion-fast), border-color var(--motion-fast);
}
.qa-btn .tb-icon svg { width: 18px; height: 18px; display: block; }
.qa-btn:hover { background: var(--bg-overlay); border-color: var(--accent); }
.qa-btn:active { background: var(--accent); }
.qa-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-dim), 0 0 0 1px var(--product-accent-muted); }
.qa-sep { width: 1px; height: 16px; background: var(--border-default); margin: 0 4px; }

/* The ribbon strip's sideways scrollbar (Home in a narrow window) is thin, so
   it covers only the group labels' bottom padding, never their text. */
.ribbon-content::-webkit-scrollbar { height: 6px; }
.ribbon-content::-webkit-scrollbar-thumb { border-width: 1px; border-radius: 3px; }

/* ═════════ ICON SYSTEM v1 (2026-09-30) ═════════
   One registry (renderer/src/icons.js) paints every icon on a 24 × 24 grid.
   Ink is currentColor, so hover / pressed / disabled / menu text all reach the
   glyph; the accent and the markup red are tokens. ICON-SEMANTICS-v1.md holds
   the grammar. */
:root {
  --icon-accent: var(--product-accent);
  /* No revision / markup token existed: the Revision Cloud uses the design
     system's one red rather than a new one (owner ruling 2026-09-30). */
  --icon-markup: var(--forms-error);
}
svg.fi { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
svg.fi .t { stroke-width: 1; }
svg.fi .h { stroke-width: 2.4; }
svg.fi .a { stroke: var(--icon-accent); }
svg.fi .af { fill: var(--icon-accent); stroke: none; }
svg.fi .f { fill: currentColor; stroke: none; }
svg.fi .r { stroke: var(--icon-markup); }
svg.fi .m { opacity: 0.45; }
/* Dashes use butt caps: round caps would add a half stroke-width to each end
   of every dash and close the gaps (a 1.5 stroke on 2.2/2 left 0.5 px gaps,
   which read as solid lines at 24 px). */
svg.fi .d { stroke-dasharray: 2.2 1.8; stroke-linecap: butt; }
svg.fi .dd { stroke-dasharray: 5 1.8 1.4 1.8; stroke-linecap: butt; }
svg.fi .o12 { opacity: 0.12; }
svg.fi .o3 { opacity: 0.3; }
svg.fi .o35 { opacity: 0.35; }
svg.fi .o55 { opacity: 0.55; }
svg.fi .o85 { opacity: 0.85; }
/* On an accent ground (the press flash, the active alignment cell) the
   accent parts — and the Revision Cloud's markup red — turn to ink so
   nothing disappears into the purple. */
.tb-btn:active svg.fi .a, .qa-btn:active svg.fi .a, .ctx-align.active svg.fi .a, .tb-btn:active svg.fi .r { stroke: currentColor; }
.tb-btn:active svg.fi .af, .qa-btn:active svg.fi .af, .ctx-align.active svg.fi .af { fill: currentColor; }
/* A disabled menu row: the whole glyph takes the row's disabled ink. */
.ws-popup-item.disabled svg.fi .a { stroke: currentColor; }
.ws-popup-item.disabled svg.fi .af { fill: currentColor; }
/* Sizes: ribbon 24 px (padding 4 / 7 keeps every button 40 × 34 — the Home
   width is unchanged), menu rows 16 px, alignment cells 16 px, Quick Access 18. */
.tb-btn:has(> .tb-icon) { padding: 4px 7px; }
.ws-popup-icon svg { width: 16px; height: 16px; display: block; }
.ctx-align { display: grid; place-items: center; }
.ctx-align .tb-icon svg { width: 16px; height: 16px; }

/* ═════════ 0.9 DRAFTING CLOSURE RUN — PHASE 1: PROFESSIONAL DENSITY (2026-10-01) ═════════
   Measured at 1920×1080, 2560×1440 and 3840×2160 at 100 / 125 / 150 %, a
   1366×768 laptop, half a 2560 screen and the 1024 × 700 minimum window
   (DRAFTING-CLOSURE-RUN-0.9.md, Phase 1). The vertical chrome already matches
   a CAD ribbon's (title + tabs + panels: 145 px here, about 148 in AutoCAD),
   so the ribbon keeps its height. What changed: the control pitch, what a
   narrow window cuts off, and the short screen. */

/* Ribbon controls: a square 36 × 34 pitch for the 24 px icons (was 40 × 34),
   a CAD ribbon's density; Home now needs about 1140 px, not 1250. */
.tb-btn:has(> .tb-icon) { padding: 4px 5px; }

/* A ribbon strip wider than the window scrolls sideways (QC 2026-09-29); the
   wheel scrolls it too (app.js) and a fade marks the side that has more. */
.ribbon-content.more-right { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); }
.ribbon-content.more-left { -webkit-mask-image: linear-gradient(to right, transparent, #000 40px); mask-image: linear-gradient(to right, transparent, #000 40px); }
.ribbon-content.more-left.more-right { -webkit-mask-image: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent); }

/* The folded ribbon (the CAD / Office convention for a short screen): a
   double-click on a tab, or the ▴ after the tabs, folds the ribbon to its
   tabs and the drawing takes the height. Folded, a tab click drops that
   tab's panel OVER the drawing (it never pushes it) until a tool runs, Esc,
   or a click elsewhere. Remembered per workstation (forms2d.ribbon.min.v1). */
#app { --ribbon-row: 107px; grid-template-rows: 38px var(--ribbon-row) auto 1fr 64px 22px 24px; }
#app.cli-expanded { grid-template-rows: 38px var(--ribbon-row) auto 1fr 200px 22px 24px; }
#app.ribbon-min { --ribbon-row: 0px; }
#app.ribbon-min #ribbon-panel { visibility: hidden; height: 0; border-bottom: none; }
#app.ribbon-min #ribbon-panel.ribbon-flyout {
  visibility: visible; height: 107px; position: relative; z-index: 150;
  border-bottom: 1px solid var(--border-strong); box-shadow: var(--shadow-lg);
}
.ribbon-min-btn {
  align-self: flex-end; flex: none; width: 22px; height: 22px; margin: 0 0 3px 4px; padding: 0;
  display: inline-grid; place-items: center;
  background: transparent; color: var(--forms-text-muted); border: 1px solid transparent; border-radius: var(--radius-sm);
  font-family: inherit; font-size: 10px; line-height: 1; cursor: pointer;
  transition: background-color var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.ribbon-min-btn:hover { background: var(--bg-overlay); color: var(--text); border-color: var(--border-default); }
.ribbon-min-btn[aria-pressed="true"] { color: var(--product-accent-bright); }
.ribbon-min-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-dim), 0 0 0 1px var(--product-accent-muted); }

/* Status bar: every control stays on screen down to the 1024 px window (the
   Layout space tab, Panels and Settings were cut off). The Plato chip, the
   discipline and the coordinates give way, in that order; the toggles keep
   their size. */
#status-bar { gap: 4px; padding: 0 6px; }
#status-bar > * { flex: none; }
#sb-license { flex: 0 4 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
#sb-discipline { flex: 0 2 auto; min-width: 72px; max-width: 132px; }
#status-coords { flex: 0 1 168px; min-width: 132px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.sb-toggle { padding: 2px 6px; }

/* Layout tabs read at the chrome's 11 px (were 10). */
.frame-tab { font-size: 11px; padding: 2px 10px; }

/* ═════════ ICON SYSTEM v1.1 — COLOUR (0.9 run, Phase 2, 2026-10-01) ═════════
   Recolour, not redesign. Neutral at rest: the glyph is ink (the control's
   text colour) and so are the parts v1 painted in Arkhon Purple (a / af);
   where those mark a change, a result or a measurement, the context they act
   on is halftone (s), so they still read first. Colour only where it means
   something: the markup red (r, the Revision Cloud), the destructive red
   (x: erase, delete, duplicates and clean-up removed), lamp amber (y / yf: a
   layer lit or thawed, a lock, a colour swatch), ice blue (ic: a frozen
   layer). The product accent marks state only: an icon's accent parts wear it
   while its control is on (aria-pressed) or its list is open (aria-expanded). */
:root {
  --icon-danger: var(--forms-error);
  --icon-amber: #E3B341;
  --icon-ice: #79B8F2;
}
svg.fi .a { stroke: currentColor; }
svg.fi .af { fill: currentColor; }
svg.fi .s { opacity: 0.5; }
svg.fi .x { stroke: var(--icon-danger); }
svg.fi .xf { fill: var(--icon-danger); stroke: none; }
svg.fi .y { stroke: var(--icon-amber); }
svg.fi .yf { fill: var(--icon-amber); stroke: none; }
svg.fi .ic { stroke: var(--icon-ice); }
.tb-btn[aria-pressed="true"] svg.fi .a, .tb-btn[aria-expanded="true"] svg.fi .a { stroke: var(--icon-accent); }
.tb-btn[aria-pressed="true"] svg.fi .af, .tb-btn[aria-expanded="true"] svg.fi .af { fill: var(--icon-accent); }
/* On an accent ground (the press flash) and in a disabled menu row every
   coloured part turns to ink, as the accent always did. */
.tb-btn:active svg.fi .a, .tb-btn:active svg.fi .x, .tb-btn:active svg.fi .y, .tb-btn:active svg.fi .ic,
.ws-popup-item.disabled svg.fi .x, .ws-popup-item.disabled svg.fi .y, .ws-popup-item.disabled svg.fi .ic { stroke: currentColor; }
.tb-btn:active svg.fi .af, .tb-btn:active svg.fi .xf, .tb-btn:active svg.fi .yf,
.ws-popup-item.disabled svg.fi .xf, .ws-popup-item.disabled svg.fi .yf { fill: currentColor; }

/* Icon System V2: semantic parts retain meaning across every shared surface. */
:root { --icon-blue: #79B8F2; --icon-green: #73CD98; }
svg.fi .b { stroke: var(--icon-blue); }
svg.fi .bf { fill: var(--icon-blue); stroke: none; }
svg.fi .g { stroke: var(--icon-green); }
svg.fi .gf { fill: var(--icon-green); stroke: none; }
svg.fi .p { stroke: var(--icon-accent); }
svg.fi .pf { fill: var(--icon-accent); stroke: none; }
.fb-btn svg.fi { width: 14px; height: 14px; }
.mtext-bar svg.fi { width: 13px; height: 13px; }
:is(button:disabled, [aria-disabled="true"], .ws-popup-item.disabled, .ctx-align.active) svg.fi :is(.a,.r,.x,.y,.ic,.b,.g,.p),
:is(.tb-btn:active,.qa-btn:active,.fb-btn:active) svg.fi :is(.b,.g,.p) { stroke: currentColor; }
:is(button:disabled, [aria-disabled="true"], .ws-popup-item.disabled, .ctx-align.active) svg.fi :is(.af,.xf,.yf,.bf,.gf,.pf),
:is(.tb-btn:active,.qa-btn:active,.fb-btn:active) svg.fi :is(.bf,.gf,.pf) { fill: currentColor; }
button:disabled svg.fi :is(.s,.m) { opacity: 1; }
.pb-ico svg.fi, .lm-toggle svg.fi, [data-fld] svg.fi { width: 16px; height: 16px; vertical-align: middle; pointer-events: none; }
/* Disabled glyphs remain identifiable without retaining semantic color. */
.tb-btn:disabled:has(svg.fi) { opacity: 1; color: #888D91; }
.ws-popup-item.disabled:has(svg.fi) { color: #888D91; }
.lm-tbtn svg.fi, th svg.fi, .xg-icon svg.fi, .ctx-item svg.fi { width: 16px; height: 16px; vertical-align: middle; pointer-events: none; }
#app-menu-btn svg.fi { width: 18px; height: 18px; }
svg.fi { width: 16px; height: 16px; vertical-align: middle; }
.ctx-item > span:has(svg.fi) { display: inline-flex; margin-right: 6px; pointer-events: none; }
.panel-btn svg.fi, .lm-tbtn svg.fi, .sp-cmd svg.fi, #autosave-chip svg.fi { pointer-events: none; }
.setup-palette { padding: 7px; }
.setup-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--border); }
.setup-tabs button { padding: 6px 4px; color: var(--text-dim); background: transparent; border: 0; border-bottom: 2px solid transparent; font: inherit; font-size: 11px; cursor: pointer; }
.setup-tabs button.active { color: var(--text); border-bottom-color: var(--accent); }
.setup-summary { color: var(--text-dim); font-size: 11px; margin: 12px 0; }
.setup-action { display: grid; grid-template-columns: 26px 1fr; align-items: center; gap: 1px 7px; width: 100%; text-align: left; color: var(--text); background: transparent; border: 1px solid var(--border); padding: 8px; margin: 5px 0; cursor: pointer; font: inherit; font-size: 12px; }
.setup-action:hover { background: var(--bg-hover, #2A2B2A); }
.setup-action > span:first-child { grid-row: span 2; }
.setup-action small { grid-column: 2; color: var(--text-dim); font-size: 10px; }
