  #canvasWrap.space-pan.panning{cursor:grabbing;}
  /* #canvasZoomOuter's box is resized in JS to the zoomed pixel size, so canvasWrap's
     native scrollbars/scroll range stay correct at any zoom level; #canvas itself keeps
     its original 3200x2200 layout size and is just visually scaled via transform, so
     every node.x/node.y stays in the same simple "logical" pixel space it always was —
     only canvasPoint() and a couple of "center of viewport" spots need to divide by zoom. */
  #canvasZoomOuter{position:relative;}
  #canvas{position:relative; width:3200px; height:2200px; transform-origin:0 0;}
  #zoomBadge{font-size:11.5px; color:var(--muted); user-select:none;}
  svg#edgeLayer{position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:2;}
  svg#edgeLayer path{fill:none;}
  /* Canvas spec §1.6/§2 — flow wires use --wire (#7D8B9B, 3.18:1 on the canvas; the old
     #97A6B5/#AEBAC6 were 2.28:1/1.81:1). The else/default wire differs by dash only.
     Every stroke/dash/hit width is × --wire-scale (set by applyCanvasZoom) so a wire stays
     ≥1.5px on screen at fit zoom. */
  svg#edgeLayer .edge{stroke:var(--wire); stroke-width:calc(2px * var(--wire-scale, 1)); cursor:pointer;}
  svg#edgeLayer .edge.default{stroke-dasharray:calc(5px * var(--wire-scale, 1)) calc(4px * var(--wire-scale, 1));}
  svg#edgeLayer .edge.selected{stroke:var(--brand-600) !important; stroke-width:calc(2.5px * var(--wire-scale, 1)) !important;}
  svg#edgeLayer .edge.auto-edge{stroke:var(--logic-fg); stroke-dasharray:calc(3px * var(--wire-scale, 1)) calc(3px * var(--wire-scale, 1)); opacity:.85; pointer-events:none; cursor:default;}
  svg#edgeLayer .edge-hit{fill:none; stroke:transparent; stroke-width:calc(14px * var(--wire-scale, 1)); pointer-events:stroke; cursor:pointer;}
  svg#edgeLayer .edge-label{fill:var(--muted); font-size:11.5px;}
  svg#edgeLayer .edge-label.auto-edge-label{fill:var(--logic-fg-strong); font-style:italic;}
  svg#edgeLayer .wiring-temp{stroke:var(--brand-600); stroke-width:calc(2px * var(--wire-scale, 1)); stroke-dasharray:calc(4px * var(--wire-scale, 1)) calc(3px * var(--wire-scale, 1));}
  .edge-action-wrap{position:absolute; transform:translate(-50%,-50%); display:flex; gap:6px; z-index:6;}
  .edge-action-btn{
    font-size:11.5px; padding:5px 12px; border-radius:var(--r-chip); cursor:pointer; white-space:nowrap;
    box-shadow:var(--shadow-2); border:1px solid var(--border-strong); background:var(--surface-default); color:var(--text-secondary);
  }
  .edge-action-btn.del{border-color:var(--border); color:var(--error-fg);}
  .edge-action-btn.del:hover{background:var(--error-bg); border-color:var(--error-fg);}
  .edge-action-btn.page{border-color:var(--border); color:var(--brand-800);}
  .edge-action-btn.page:hover{background:var(--brand-50); border-color:var(--brand-600);}
  svg#edgeLayer .edge.page-break{stroke:var(--brand-500);}
  svg#edgeLayer .edge.drop-target{stroke:var(--brand-600) !important; stroke-width:5px !important;}
  .page-break-marker text{user-select:none;}
  /* Page-break marker (defect 6: was inline #3B82F6) — class-based, action blue. */
  .page-break-marker .pbm-dot{fill:var(--surface-default); stroke:var(--brand-600); stroke-width:1.5;}
  .page-break-marker .pbm-glyph{fill:none; stroke:var(--brand-600); stroke-width:1.3; stroke-linejoin:round;}

  /* Sections — draggable/resizable frames that group nodes; moving the frame moves
     every node currently inside it. Membership is computed live from node position. */
  .section-frame{
    position:absolute; z-index:1; border:1px dashed var(--border-control); border-radius:var(--r-card);
    background:var(--section-fill);
  }
  .section-hd{
    position:absolute; top:-28px; left:0; right:0; display:flex; align-items:center; gap:6px;
    cursor:grab; padding:2px 2px 2px 6px;
  }
  .section-hd:active{cursor:grabbing;}
  .section-hd .section-label{font-size:12px; font-weight:600; color:var(--text-secondary); width:auto; flex:0 1 auto; max-width:220px; padding:2px 5px;}
  .section-hd .section-count{font-size:11.5px; color:var(--muted); white-space:nowrap;}
  .section-hd-icons{display:flex; align-items:center; gap:2px; margin-left:auto;}
  .section-hd button.icon-btn{background:transparent; border:none; color:var(--muted); opacity:.7; padding:2px 5px; font-size:12px; border-radius:var(--r-control); cursor:pointer;}
  .section-hd button.icon-btn:hover{opacity:1; color:var(--error-fg); background:var(--surface-sunken); border:none;}
  .section-resize{
    position:absolute; right:-5px; bottom:-5px; width:14px; height:14px; border-radius:var(--r-chip);
    background:var(--surface-default); border:1.5px solid var(--border-strong); cursor:nwse-resize;
  }

  /* Repeat-gate enclosed region: computed live from flow traversal, not draggable/resizable.
     SOLID plum vs. a section's dashed gray — a different visual language on purpose. */
  .region-frame{
    position:absolute; z-index:1; pointer-events:none;
    border:1.5px solid color-mix(in srgb, var(--repeat-fg) 45%, transparent); border-radius:var(--r-card);
    background:var(--repeat-fill);
  }
  .region-hd{
    position:absolute; top:-22px; left:0; right:0; font-size:12px; font-weight:600; color:var(--repeat-fg);
    padding:2px 6px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }

  /* ============================== COMPACT NODE (canvas spec §2) ==============================
     Read-only summary cards with a fixed size per type (nodeBoxSize() in node-summary.js
     writes width/height inline). No form controls on the canvas — the side panel is the
     only editor. Type scale: header 11/600 uppercase, label 13/600, meta 11.5, pills
     11/600 — nothing under 11px at 100%. */
  /* Drawing Set §5 skin: an ink hairline (--border-control, 3.35:1 on the sheet) instead of
     a shadow; 6px corners, 5px header corners; header 11px narrow (75%) +0.08em. Only a
     dragged node floats (--shadow-2). Sizes, ports and keyboard paths are the canvas spec's. */
  .node{position:absolute; box-sizing:border-box; width:240px; height:108px; background:var(--surface-default);
    border:1px solid var(--border-control); border-radius:var(--r-card); box-shadow:none; cursor:grab; z-index:3; user-select:none;
    transition:border-color var(--dur-1) var(--ease-step);}
  .node:hover{border-color:var(--text-secondary);}
  .node.selected{outline:2px solid var(--brand-600); outline-offset:2px; box-shadow:none; z-index:4;}
  .node:focus-visible{outline:2px solid var(--brand-600); outline-offset:2px;}
  .node.dragging{box-shadow:var(--shadow-2); cursor:grabbing;}
  .node .hd{height:28px; padding:0 8px 0 12px; display:flex; align-items:center; gap:6px; font-size:11px; font-weight:600; font-stretch:var(--stretch-label);
    letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; border-bottom:1px solid var(--border-default); border-radius:calc(var(--r-card) - 1px) calc(var(--r-card) - 1px) 0 0;}
  /* Shape marks (spec §5) — the node kind by shape as well as tint, 12px, header ink. */
  .node .hd .nf-shape{flex:none; vertical-align:0;}
  .lod-overview .node .hd .nf-shape{visibility:visible; width:min(calc(12px / var(--z)), 36px); height:min(calc(12px / var(--z)), 36px);}
  .node .hd .k{flex:1; min-width:0; display:inline-flex; align-items:center; gap:5px; overflow:hidden; text-overflow:ellipsis;}
  .nf-body{padding:8px 12px 10px; display:flex; flex-direction:column; gap:6px;}
  .nf-label{font-size:13px; font-weight:600; line-height:18px; min-height:36px; color:var(--text-primary);
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere;}
  .nf-label.empty{color:var(--text-muted); font-weight:500;}
  .nf-meta{height:20px; display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--text-muted); white-space:nowrap;}
  .nf-meta .sum{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;}
  .nf-meta .sum.err{color:var(--error-fg);}
  .nf-meta .sum.warn{color:var(--warning-fg);} /* file upload on a server without file storage */
  .nf-meta .req{font-size:11.5px; font-weight:500;}
  .nf-meta .ind{display:inline-flex; align-items:center; color:var(--text-muted); flex:none;}
  .nf-glyph{width:28px; height:16px; flex:none;}
  .nf-var{color:var(--repeat-fg); background:var(--repeat-bg); border-radius:var(--r-stamp); padding:0 3px;}
  .node .hd .startTag{font-size:11px; font-weight:600; font-stretch:100%; letter-spacing:0; text-transform:none; padding:1px 7px; border-radius:var(--r-chip); background:var(--brand-800); color:var(--text-on-accent); flex:none;}
  .node .hd .cmt-n{font-size:11.5px;}
  /* repeat_start: block name (1 line) + variant names (1 line) share the 2-line label area */
  .nf-label.nf-1l{-webkit-line-clamp:1; min-height:18px;}
  .node.repeat_start .nf-body{gap:0;}
  .nf-sub{font-size:11.5px; line-height:18px; color:var(--text-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-bottom:6px;}
  /* end screen: message 13/500, clamp 3 lines, no meta */
  .nf-label.nf-msg{font-weight:500; -webkit-line-clamp:3; min-height:54px;}

  /* Header tints — ink is the strong token, all >=4.5:1 (spec §2 table). Acceptance and
     profile setup live in 12-community.css with the other onboarding node rules. */
  .node.question .hd{background:var(--brand-100); color:var(--brand-800);}
  .node.condition .hd, .node.section_loop .hd{background:var(--logic-bg); color:var(--logic-fg-strong);}
  .node.split .hd{background:var(--split-bg); color:var(--split-fg-strong);}
  .node.end .hd{background:var(--success-bg); color:var(--success-fg);}
  .node.repeat_start .hd, .node.repeat_end .hd{background:var(--repeat-bg); color:var(--repeat-fg);}
  .node .hd .gate-warn{color:var(--warning-fg); display:inline-flex; align-items:center; flex:none;}
  .node .hd button.icon-btn{
    background:transparent; border:none; color:inherit; opacity:.65; padding:2px 5px; font-size:12px; border-radius:var(--r-control); cursor:pointer;
  }
  .node .hd button.icon-btn:hover{opacity:1; background:var(--on-tint-hover); color:inherit; border:none;}
  /* A4 — comment button: always in the DOM (layout never reflows), opacity-only
     visibility. No status colour — a comment is not a status, the glyph just takes the
     header's own ink via color:inherit. */
  .node .hd button.icon-btn.cmt{display:inline-flex; align-items:center; opacity:0; gap:4px; padding:2px 6px 2px 5px; flex:none;}
  .node:hover .hd button.icon-btn.cmt, .node.selected .hd button.icon-btn.cmt{opacity:.65;}
  .node .hd button.icon-btn.cmt.done{opacity:.5;}
  .node .hd button.icon-btn.cmt.has{opacity:1;}
  .node .hd button.icon-btn.cmt.active{opacity:1; background:var(--on-tint-hover);}
  .node .hd button.icon-btn.cmt:hover{opacity:1;}
  .node .hd button.icon-btn.cmt:focus-visible{opacity:1;}
  .node .hd .cmt-n{font-weight:700; font-stretch:100%; letter-spacing:0; line-height:1;}

  /* Branch rows (condition / section loop / split). data-branch-id on each row; ELSE uses
     __default. layoutConditionPorts() reads the .nf-br row centres for port positions. */
  .nf-body.nf-rows{padding:4px 0; display:block;}
  .nf-gl{height:26px; padding:4px 12px 0; font-size:13px; font-weight:600; line-height:18px; color:var(--text-primary);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .nf-br{height:44px; display:flex; align-items:center; gap:8px; padding:0 16px 0 12px; border-top:1px solid var(--border-default);}
  .nf-rows > .nf-br:first-child, .nf-rows > .nf-gl + .nf-br{border-top:0;}
  .nf-br.nf-br-else{height:32px; border-top:1px dashed var(--border-strong);}
  .nf-br.nf-br-none{height:32px;}
  .nf-br .pill{flex:none; font-size:11px; font-weight:600; line-height:16px; font-variant-numeric:tabular-nums; color:var(--logic-fg-strong); background:var(--logic-bg); border-radius:var(--r-chip); padding:1px 7px;}
  .nf-br .pill.else{background:var(--surface-sunken); color:var(--text-secondary);}
  .nf-br-sum{flex:1; min-width:0; font-size:11.5px; line-height:16px; color:var(--text-secondary);
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere;}
  .nf-br-sum .q, .nf-br-sum .v{color:var(--text-primary); font-weight:600;}
  /* typed-rules §1a — only the question may ellipse; operator and values never clip. */
  .nf-br-sum .q{display:inline-block; vertical-align:bottom; max-width:60%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .nf-br-sum.muted{color:var(--text-muted);}
  .nf-br-sum.warn{color:var(--warning-fg); display:flex; align-items:center; gap:4px;}
  .nf-br-loop{flex-direction:column; align-items:stretch; justify-content:center; gap:0;}
  .nf-br-loop .l1{display:flex; align-items:baseline; gap:4px; font-size:12px; line-height:16px; white-space:nowrap; min-width:0;}
  .nf-br-loop .l1 .nd{color:var(--text-muted); flex:none;}
  .nf-br-loop .l1 .sec{font-weight:600; color:var(--text-primary); min-width:0; overflow:hidden; text-overflow:ellipsis;}
  .nf-br-loop .l1 .sec.warn{color:var(--warning-fg); font-weight:500;}
  .nf-br-loop .l2{flex:none; display:block; white-space:nowrap; text-overflow:ellipsis;}
  .nf-br-split{height:32px; justify-content:space-between;}
  .nf-br-split .nm{flex:1; min-width:0; font-size:12px; font-weight:600; color:var(--text-primary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .nf-br-split .pct{flex:none; font-size:12px; font-weight:600; color:var(--split-fg-strong);}

  /* Shape glyphs (node meta + palette): 1.25px --border-strong strokes, --surface-sunken
     fills, accents in the node-type colour (currentColor via the g-* class). */
  .nf-glyph .gs{fill:var(--surface-sunken); stroke:var(--border-strong); stroke-width:1.25;}
  .nf-glyph .gl{fill:none; stroke:var(--border-strong); stroke-width:1.25;}
  .nf-glyph .gd{fill:var(--surface-subtle); stroke:var(--border-strong); stroke-width:1.25; stroke-dasharray:2.5 2;}
  .nf-glyph .ga{fill:none; stroke:currentColor; stroke-width:1.25; stroke-linecap:round; stroke-linejoin:round;}
  .nf-glyph .gs.ga{fill:var(--surface-sunken); stroke:currentColor;}
  .nf-glyph .ga.gf{fill:currentColor;}
  .nf-glyph .ga.gdash{stroke-dasharray:2.5 2;}
  .nf-glyph.g-q{color:var(--brand-600);}
  .nf-glyph.g-c{color:var(--logic-fg);}
  .nf-glyph.g-sp{color:var(--split-fg);}
  .nf-glyph.g-rp{color:var(--repeat-fg);}
  .nf-glyph.g-e{color:var(--success-fg);}
  .nf-glyph.g-s{color:var(--text-muted);}

  /* Ports — 20px transparent hit area, 14px visible dot (spec §2). --port-scale grows
     them at overview zoom so they stay grabbable. */
  .port{position:absolute; width:20px; height:20px; background:transparent; border:0; box-shadow:none; cursor:crosshair; z-index:5; transform:scale(var(--port-scale,1));}
  .port::after{content:''; position:absolute; left:3px; top:3px; width:14px; height:14px; box-sizing:border-box; border-radius:50%;
    background:var(--port-c); border:2px solid var(--surface-default); box-shadow:0 0 0 1px var(--border-control); pointer-events:none;}
  .port:hover::after{transform:scale(1.25);}
  .port.in{left:-10px; top:4px; --port-c:var(--wire);}
  .port.out{right:-10px; top:4px; --port-c:var(--brand-600);}
  .port.out.default{--port-c:var(--wire);}
  .port.compare{left:50%; margin-left:-10px; bottom:-10px; top:auto; --port-c:var(--compare-fg);}
  /* Compare port — bottom-center, own accent, own kind of wire (meaning, not flow).
     Hidden until node hover unless the compare layer is toggled on (body.compare-layer-on). */
  .port.compare{opacity:0; transition:opacity var(--dur-2) var(--ease-step); transform-origin:50% 0;} /* scales downward at overview, never over the label */
  .node:hover .port.compare, body.compare-layer-on .port.compare{opacity:1;}
  .node.compare-target-ok{outline:2px solid var(--compare-fg); outline-offset:1px;}
  svg#edgeLayer .compare-wire{fill:none; stroke:var(--compare-fg); stroke-width:calc(2px * var(--wire-scale, 1)); stroke-dasharray:calc(7px * var(--wire-scale, 1)) calc(4px * var(--wire-scale, 1));}
  svg#edgeLayer .compare-wire.selected{stroke-width:calc(2.5px * var(--wire-scale, 1));}
  svg#edgeLayer .compare-wire.broken, svg#edgeLayer .compare-wire.drift{stroke:var(--compare-fg);}
  svg#edgeLayer .compare-wire-hit{fill:none; stroke:transparent; stroke-width:calc(14px * var(--wire-scale, 1)); cursor:pointer;}
  svg#edgeLayer .wiring-temp.compare-temp{stroke:var(--compare-fg); stroke-dasharray:calc(7px * var(--wire-scale, 1)) calc(4px * var(--wire-scale, 1));}

  /* Overview mode (spec §4) — below 70% the cards become label-only; the label is sized
     in screen pixels (10px / zoom) so it stays readable at fit. */
  .lod-overview .node .hd > *{visibility:hidden;}
  .lod-overview .node .nf-meta, .lod-overview .node .nf-br-sum, .lod-overview .node .nf-sub{display:none;} /* .nf-sub = repeat start's line 2, meta-level detail */
  .lod-overview .node .nf-body{padding:4px 10px;}
  .lod-overview .node .nf-label{font-size:min(calc(10px / var(--z)), 36px); line-height:1.1;}
  .lod-overview .node.end .nf-label{-webkit-line-clamp:2;} /* 3 lines at overview size spill below the card */
  .lod-far .node .nf-label, .lod-far .node.end .nf-label{-webkit-line-clamp:1;}
  .lod-overview .node .nf-br .pill{font-size:min(calc(10px / var(--z)), 32px);}
  .lod-overview .section-hd, .lod-overview .region-hd{transform:scale(min(calc(.85 / var(--z)), 3.4)); transform-origin:left bottom;}
  /* the scaled header fits its frame: icons go first, then the name ellipses; the count never overlaps a neighbour */
  .lod-overview .section-hd{right:auto; width:calc(100% / min(calc(.85 / var(--z)), 3.4)); overflow:hidden;}
  .section-hd .section-label{min-width:0; text-overflow:ellipsis;}
  .section-hd .section-count{flex:none;}
  .lod-overview .section-hd-icons{display:none;}
  .lod-overview .section-frame:hover .section-hd-icons{display:flex;}
  .compare-badge circle{fill:var(--surface-default);}
  .drift-chip{display:inline-block; font-size:11px; font-weight:600; padding:2px 7px; border-radius:var(--r-chip); background:var(--warning-bg); color:var(--warning-fg); margin-left:8px; vertical-align:middle;}
  .sig-pill{display:inline-block; font-size:11px; font-weight:600; padding:2px 7px; border-radius:var(--r-chip); background:var(--brand-50); color:var(--brand-700); border:1px solid var(--brand-100); cursor:default; white-space:nowrap;}
  .cmp-label-sig{margin-top:3px;}
  .sig-line{font-size:12px; color:var(--text-secondary); margin-top:10px;}
  .sig-what{color:var(--text-muted); border-bottom:1px dotted var(--text-muted); cursor:help; margin-left:4px;}
  .cmp-val{min-width:86px; width:auto;}
  .compare-pin-ic{color:var(--text-muted); margin-right:6px; display:inline-flex; vertical-align:-2px;}

  /* Inline editable widgets — shared by node cards AND the side panel */
  .inline-edit{
    background:transparent; border:1px solid transparent; color:var(--text); font:inherit;
    padding:3px 5px; border-radius:var(--r-control); width:100%;
  }
  .inline-edit:hover{border-color:var(--border-control);}
  .inline-edit:focus{background:var(--surface-default); border-color:var(--brand-600); outline:2px solid var(--brand-600); outline-offset:1px;}
  .inline-edit.label-edit{font-size:13.5px; font-weight:600; margin-bottom:6px;}
  .inline-edit.tiny{width:56px; padding:2px 4px; font-size:11.5px;}
  .inline-edit.tiny[type=date]{width:110px;}
  .inline-edit.textarea{min-height:56px; resize:vertical; font-size:13px;}
  .type-row{display:flex; align-items:center; gap:8px; margin-bottom:8px; flex-wrap:wrap;}
  .tiny-select{font:inherit; font-size:11.5px; background:var(--surface-default); border:1px solid var(--border-control); color:var(--text); border-radius:var(--r-control); padding:3px 5px;} /* §7.4 identity-scale radius. Canvas spec §1.6: font:inherit FIRST — after font-size it reset the size and selects rendered 16px. */
  .req-chk{display:flex; align-items:center; gap:4px; font-size:11.5px; color:var(--muted); white-space:nowrap;}
  .req-chk input{margin:0;}
  .preview-field{background:var(--panel3); border:1px dashed var(--border); border-radius:var(--r-control); padding:8px 9px; font-size:12px; color:var(--muted); font-style:italic;}
  .preview-field.textarea{min-height:34px;}
  .minmax-row{display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--muted);}
  /* File upload editor (spec file-upload §1) */
  .fu-kinds{border:0; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:6px;}
  .fu-kinds legend{padding:0; margin-bottom:6px; font-size:11.5px; font-weight:600; color:var(--text-secondary);}
  .fu-kind{display:flex; align-items:flex-start; gap:6px; cursor:pointer;}
  .fu-kind input{margin:2px 0 0;}
  .fu-kind.is-disabled{cursor:default;}
  .fu-kind-txt{display:flex; flex-direction:column; gap:1px; min-width:0;}
  .fu-kind-l{font-size:12.5px; color:var(--text-primary);}
  .fu-kind.is-disabled .fu-kind-l{color:var(--text-muted);}
  .fu-kind-s{font-size:11.5px; color:var(--text-muted);}
  .fu-rule{height:0; border-top:1px solid var(--border-default); margin:2px 0;}
  .fu-size{margin-top:10px;}
  .fu-note{display:flex; gap:8px; align-items:flex-start; margin-top:10px; padding:10px 12px; background:var(--surface-subtle); border:1px solid var(--border-default); border-radius:var(--r-control); color:var(--text-secondary);}
  .fu-note .nf-i{flex:none; margin-top:2px;}
  .fu-note p{margin:0; font-size:12.5px; line-height:18px;}
  /* Star rating / NPS node-editor previews (canvas card + side panel, shared markup) */
  .star-count-preview{display:flex; gap:6px; color:var(--text-faint); pointer-events:none; margin-top:4px;}
  .nps-count-preview{display:flex; gap:2px; margin-bottom:8px;}
  .nps-preview-cell{flex:1; height:16px; border:1px solid var(--border-strong); border-radius:var(--r-chip); display:flex; align-items:center; justify-content:center;}
  .nps-preview-cell span{font-size:11.5px; color:var(--text-muted);}
  .nps-label-row{display:flex; gap:6px;}
  .nps-label-row .inline-edit{flex:1;}
  /* An analytics bar row referencing a since-removed shared-list option. */
  .hbar-label-faint{color:var(--text-muted); font-style:italic;}

  .opt-list{display:flex; flex-direction:column; gap:4px; margin-bottom:6px;}
  .opt-row{display:flex; align-items:center; gap:6px;}
  .opt-row input.inline-edit{flex:1; padding:4px 6px; font-size:12.5px;}
  .opt-row[draggable="true"]{cursor:grab;}
  .opt-row.dragging{opacity:.4;}
  .opt-row.drag-over{border-top:2px solid var(--accent2);}
  .rank-drag{cursor:grab; color:var(--text-faint); padding:0 2px; flex:none; display:inline-flex; align-items:center;}
  .rank-drag:active{cursor:grabbing;}
  .cell-ind{width:13px; height:13px; flex:none; border:1.6px solid var(--text-faint); display:inline-block;}
  .cell-ind.radio{border-radius:50%;}
  .cell-ind.checkbox{border-radius:var(--r-chip);}
  .rank-num{width:17px; height:17px; flex:none; border-radius:50%; background:var(--brand-600); color:var(--text-on-accent); font-size:11px; font-weight:700; display:flex; align-items:center; justify-content:center;}
  /* §7.6 — muted at rest, red only on hover/focus: a remove affordance isn't a permanent
     status, so it shouldn't wear status colour until it's actually about to be used.
     Applies everywhere .mini-x is used (option/row/column remove, branch remove, …). */
  .mini-x{background:transparent; border:none; color:var(--text-muted); padding:2px 5px; line-height:1; opacity:.75;}
  .mini-x:hover{opacity:1; border:none; color:var(--error-fg);}
  .mini-x:focus-visible{opacity:1; color:var(--error-fg);}
  .mini-arrow{padding:2px 6px; font-size:11px;}
  .mini-add{background:var(--panel3); border:1px dashed var(--border); color:var(--accent2); width:22px; height:22px; border-radius:var(--r-control); font-size:13px; line-height:1; padding:0;}
  .mini-add-row{width:100%; font-size:11.5px; padding:5px; background:transparent; border:1px dashed var(--border); color:var(--muted); margin-top:2px;}
  .mini-add-row:hover{color:var(--accent2); border-color:var(--accent2);}

  .mini-matrix{border-collapse:collapse; margin-top:2px; max-width:100%;}
  .mini-matrix-wrap{overflow-x:auto; max-width:100%;}
  .mini-matrix th, .mini-matrix td{padding:3px 4px; text-align:center; vertical-align:middle;}
  .mini-matrix th.corner{width:20px;}
  .mini-matrix th.colhead{min-width:64px;}
  .mini-matrix th.colhead .inline-edit{text-align:center;}
  .mini-matrix th.rowhead{text-align:left; white-space:nowrap;}
  .mini-matrix th.rowhead .inline-edit{width:90px; font-weight:400; font-size:12px;}
  .mini-matrix th.colhead .inline-edit{width:64px; font-weight:400; font-size:11.5px;}
  .mini-matrix .cell-ind{margin:0 auto;}
  .mini-matrix .addcell, .mini-matrix .addcell-row{padding:2px;}
  .mode-row{display:flex; gap:10px; margin-bottom:8px; font-size:11.5px; color:var(--muted);}
  .mode-row .seg{display:flex; align-items:center; gap:4px; cursor:pointer;}
  .mode-row .seg input{margin:0;}

  .branch-box-inline{background:var(--panel3); border:1px solid var(--border); border-radius:var(--r-control); padding:9px; margin-bottom:8px;}
  .branch-box-inline.default-note{background:transparent; border-style:dashed; margin-top:8px; padding:7px 9px;}
  .branch-box-inline .bhead{display:flex; justify-content:space-between; align-items:center; margin-bottom:6px; gap:6px;}
  .branch-box-inline .bhead strong{font-size:11.5px; color:var(--logic-fg-strong); white-space:nowrap;}
  .branch-box-inline.default-note .bhead strong{color:var(--muted);}
  /* .rule-row and its selects are gone — the condition rule editor is now
     public/js/builder/rule-editor.js + public/css/18-rule-editor.css's .nf-rule (typed-
     rules spec §1c/§8.6). Its four flex:1;min-width:88px selects were exactly what forced
     .node to 460px and produced 89.3px-wide truncated selects — banned outright by §5.2. */
  .then-wire{font-size:11.5px; color:var(--text-secondary); margin-top:2px;}
  /* Was scoped to .node — the canvas no longer has editors, so it lives in the panel now. */
  .node-explain{font-size:11.5px; color:var(--text-secondary); line-height:1.45; margin-bottom:8px;}
  .loop-target{display:inline-block; max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:-3px;}
  .loop-box .bhead .tiny-select{flex:1; min-width:120px;}

  /* Split node */
  .split-box .bhead strong{color:var(--split-fg);}
  .split-box .bhead{gap:4px;}
  .split-name{flex:1; font-weight:600; font-size:11.5px;}
  .split-pct{font-size:12px; font-weight:700; color:var(--split-fg); white-space:nowrap; padding:0 2px;}
  .split-weight-row{display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--muted);}
  .split-weight-row .inline-edit{width:44px;}

  /* Repeat gate: variant list */
  .mode-row.stacked{flex-direction:column; gap:6px;}
  .mode-row.stacked .seg{align-items:flex-start;}
  .mode-explain{font-size:11.5px; color:var(--muted); margin:-4px 0 8px 18px;}
  .variant-box{background:var(--panel3); border:1px solid var(--border); border-radius:var(--r-control); padding:9px; margin-bottom:8px;}
  .variant-box.drag-over{border-top:2px solid var(--repeat-fg);}
  .variant-box .bhead{display:flex; align-items:center; gap:6px; margin-bottom:6px;}
  .variant-box .split-pct{color:var(--repeat-fg);}
  .variant-name{flex:1; font-weight:600; font-size:11.5px;}
  .variant-label-input{margin-bottom:2px;}
  .variant-hint{font-size:11.5px; color:var(--muted); margin-bottom:6px;}
  .variant-box.err .variant-name{border-color:var(--error-fg) !important;}
  .variant-err-line{font-size:11.5px; color:var(--error-fg); margin-top:4px;}
  .repeat-footnote{font-size:11.5px; color:var(--muted); margin-top:6px;}
  .repeat-end-body{font-size:12.5px; color:var(--text-secondary); line-height:1.5;}
  .repeat-end-broken{font-size:11.5px; color:var(--error-fg); margin-top:6px;}
  .variant-chip-row{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:8px;}
  .variant-chip{display:inline-flex; align-items:center; gap:5px; font-size:11.5px; border:1px solid var(--border); border-radius:var(--r-chip); padding:3px 10px; background:var(--surface-default); cursor:pointer;}
  .variant-chip .lg-swatch{width:10px; height:10px; border-radius:var(--r-stamp); flex:none;}
  .variant-chip.off{background:var(--surface-sunken); color:var(--text-muted);}
  .rp-compare-row{display:flex; align-items:center; gap:8px; margin-bottom:4px;}
  .rp-compare-label{width:150px; flex:none; font-size:11.5px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .rp-compare-bars{flex:1; display:flex; flex-direction:column; gap:2px;}
  .rp-vbar-row{display:flex; align-items:center; gap:6px;}
  .rp-vbar-track{flex:1; height:10px; background:var(--surface-sunken); border-radius:0 var(--r-mark) var(--r-mark) 0; overflow:hidden;}
  .rp-vbar-fill{height:100%; border-radius:0 var(--r-mark) var(--r-mark) 0;}
  .rp-vbar-val{font-size:11.5px; color:var(--text-muted); white-space:nowrap; min-width:70px;}
  .rp-avg-row{display:flex; align-items:center; gap:8px; margin-bottom:6px;}
  .rp-avg-label{width:130px; flex:none; font-size:11.5px; color:var(--text-secondary); display:flex; align-items:center; gap:5px; overflow:hidden;}
  .rp-avg-text{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .rp-nps-row{display:flex; align-items:center; gap:10px; margin-bottom:6px;}
  .rp-nps-name{width:110px; flex:none; font-size:11.5px; color:var(--text-secondary);}
  .rp-nps-score{width:70px; flex:none; text-align:right;}
  .rp-nps-score .n{font-size:16px; font-weight:600; color:var(--text-primary);}
  .rp-nps-score .sub{font-size:11.5px; color:var(--muted);}

  /* Node picture attachment (any node type) */
  .node-image-wrap{margin-bottom:8px;}
  .node-image{width:100%; max-height:140px; object-fit:cover; border-radius:var(--r-control); border:1px solid var(--border); display:block; margin-bottom:4px;}
  .node-image-actions{display:flex; gap:6px; align-items:center;}
  .node-image-actions .node-image-btn{flex:1; margin-top:0;}
  .node-image-btn{cursor:pointer; text-align:center; display:block;}

  /* Image-choice question type — up to 4 clickable picture tiles */
  .img-choice-grid{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-bottom:6px;}
  .img-choice-tile{background:var(--panel3); border:1px solid var(--border); border-radius:var(--r-control); padding:6px; display:flex; flex-direction:column; gap:4px;}
  .img-choice-img{width:100%; height:64px; object-fit:cover; border-radius:var(--r-control); display:block;}
  .img-choice-empty{
    height:64px; border:1px dashed var(--border); border-radius:var(--r-control); display:flex; align-items:center; justify-content:center;
    color:var(--muted); font-size:11.5px; cursor:pointer; text-align:center;
  }
  .img-choice-empty:hover{border-color:var(--accent); color:var(--accent);}
  .img-choice-label{font-size:11.5px;}
  .img-choice-tile-actions{display:flex; align-items:center; justify-content:flex-end; gap:4px;}
  .img-choice-change{font-size:11.5px; color:var(--muted); cursor:pointer; text-decoration:underline;}
  .img-choice-change:hover{color:var(--accent);}

  /* "Please elaborate" follow-up toggle */
  .elab-row{display:flex; align-items:center; gap:8px; margin-top:6px; flex-wrap:wrap;}
  .elab-row .inline-edit{flex:1; min-width:120px; font-size:11.5px;}

  /* Respondent-facing image-choice tile (dev-test modal + Respondent preview view) */
  .resp-img-tile{background:var(--surface-subtle); border:2px solid var(--border-control); border-radius:var(--r-control); padding:6px; display:flex; flex-direction:column; gap:4px; cursor:pointer;}
  .resp-img-tile:hover{border-color:var(--brand-600);}
  .resp-img-tile.selected{border-color:var(--brand-600); background:var(--brand-50);}

