/* ══════════════════════════════════════════════════════════════════════════
   paragraph — widgets.css : THE PARTS THE INSPECTOR IS MADE OF.

   Every control obeys three rules:
     · one row is --row tall and separated from the next by a hairline;
     · the label sits left in .t-label caps, the control sits right and is
       flush to the right edge, so columns of numbers align down the rail;
     · a control that holds a number shows a thin underline telling you where
       that number sits between its min and max. No pills, no glows, no radii.

   Class contract — this mirrors exactly what src/ui/*.js builds:

     .prow [.prow-wide .prow-stat .prow-layer .prow-layerstat .prow-fillhead]
                      > .t-label.prow-label + .prow-ctl
     .scrub           > input.scrub-in + i.scrub-unit + i.scrub-bar
                        states: .is-scrubbing .is-editing .is-mixed
     .vecfield        > .scrub.ax-x | .ax-y | .ax-z
     .tgl             > i.tgl-knob + span.tgl-txt          (.is-on / .is-off)
     .seg             > button.seg-item                    (.is-on)
     .swatch (label)  > input.swatch-in + span.swatch-hex  (.is-empty), in .colorfield
     .txtf            input / textarea (.txtf-multi, .ptsfield, .fontf in .fontfield)
     select.sel       enum + .fill-kind
     .fillfield[data-kind] > .prow.prow-fillhead + .fill-params
     .btn (.btn-primary .mini .is-danger .is-on) > i.btn-icon + span.btn-txt + kbd.btn-key
     .tab (.is-on) · .chip · .btn-row · .layer-swatches > .penpick.pen-N
     .insp-group > .sect + .insp-sect · .insp-head > .insp-icon + .insp-title
     .treerow[--depth] > .tguide .twist .pendot .ticon .tname .tparam .teye
                        states: .is-sel .is-hover .is-highlight .is-disabled
                                .is-dragging .dz-before .dz-after .dz-into
     .libgroup > .sect + .libgrid > button.libitem[data-cat] > .libicon + .liblabel
     .pal-item (.is-on) > .pal-kind + .pal-label + .pal-hint
     .ctxitem > .ctx-label + .ctx-key · .ctx-sep
   ══════════════════════════════════════════════════════════════════════════ */

/* CONTRACT-GAP: index.html and several ui modules use `.t-micro`, but
   tokens.css (which is final) never defines it. Defined here as the smallest
   structural caps step, consistent with the other .t-* primitives. */
.t-micro {
  font-family: var(--f-display);
  font-size: var(--fs-micro);
  font-weight: 700;
  font-stretch: condensed;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--txt-faint);
}

/* CONTRACT-GAP: tokens.css `.is-disabled` kills pointer events, which is right
   for menu items but wrong for a disabled *scene node* — you must still be able
   to click it, select it and switch it back on. Restore interaction for those. */
.treerow.is-disabled,
.libitem.is-disabled { pointer-events: auto; }

/* ══════════════════════════ 1. INSPECTOR GROUPS ═══════════════════════ */

.insp-group { display: block; }
.insp-group + .insp-group { border-top: 1px solid var(--line); }
.insp-sect { display: block; }
.insp-sect:empty { display: none; }

/* the identity block at the top of a tab: icon, name, id, one line of doc */
.insp-head {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  gap: var(--u) var(--u2);
  padding: var(--u2) var(--u2) var(--u3);
  border-bottom: 1px solid var(--line);
  background: var(--ink-050);
}
.insp-icon {
  grid-row: 1;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  color: var(--accent);
  font-size: var(--fs-head);
  font-style: normal;
  line-height: 1;
}
.insp-icon[data-cat='shape3d']  { color: var(--pen-1); }
.insp-icon[data-cat='shape2d']  { color: var(--pen-3); }
.insp-icon[data-cat='boolean']  { color: var(--pen-2); }
.insp-icon[data-cat='modifier'] { color: var(--pen-4); }
.insp-icon[data-cat='transform'] { color: var(--txt-mid); }
.insp-icon[data-cat='style']    { color: var(--pen-5); }
.insp-icon[data-cat='setting']  { color: var(--txt-dim); }
.insp-title {
  grid-row: 1;
  display: flex;
  align-items: baseline;
  gap: var(--u2);
  min-width: 0;
}
.insp-title .t-head { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-id {
  font-size: var(--fs-micro);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.insp-doc {
  grid-column: 2;
  margin: 0;
  font-size: var(--fs-micro);
  line-height: 1.5;
  color: var(--txt-faint);
}
.insp-doc:empty { display: none; }

.insp-note {
  margin: 0;
  padding: var(--u3) var(--u2);
  font-size: var(--fs-micro);
  line-height: 1.7;
  color: var(--txt-faint);
  text-align: center;
}
.insp-note.warn { color: var(--pen-4); }
.insp-note.error { color: var(--pen-2); }

/* ══════════════════════════ 2. PARAMETER ROWS ═════════════════════════ */

.prow {
  display: grid;
  grid-template-columns: minmax(56px, 40%) minmax(0, 1fr);
  align-items: center;
  gap: var(--u2);
  min-height: var(--row);
  padding: 0 var(--u2);
  border-bottom: 1px solid var(--line-soft);
}
.prow:last-child { border-bottom: 0; }
.prow:hover { background: var(--ink-200); }
.prow-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: default;
  user-select: none;
}
.prow:hover > .prow-label { color: var(--txt-mid); }
/* a param the author never wrote is still at its default — say so quietly */
.prow.is-default > .prow-label { color: var(--txt-faint); }
.prow.is-mixed > .prow-ctl { opacity: 0.72; }

.prow-ctl {
  display: flex;
  align-items: center;
  gap: var(--u);
  min-width: 0;
  justify-content: flex-end;
}
.prow-ctl > * { min-width: 0; }

/* full-width rows: the label sits above its control */
.prow-wide {
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  padding-top: 3px;
  padding-bottom: var(--u);
}
.prow-wide > .prow-label { grid-column: 1; }

/* read-only key/value lines */
.prow-stat, .prow-layerstat { cursor: default; }
.prow-stat > .prow-ctl, .prow-layerstat > .prow-ctl {
  display: block;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.prow-layerstat { grid-template-columns: 9px minmax(40px, 1fr) minmax(0, 1fr); }
.prow-layer { gap: var(--u); }
.prow-layer .txtf { width: 6ch; flex: 0 1 6ch; text-align: center; }

/* an empty-state / summary block */
.pempty {
  padding: var(--u4) var(--u3);
  color: var(--txt-faint);
  font-size: var(--fs-ui);
  line-height: 1.7;
  text-align: center;
}

/* ══════════════════════════ 3. SCRUB NUMBER ═══════════════════════════ */

.scrub {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  height: calc(var(--row) - 4px);
  padding: 0 var(--u) 0 5px;
  background: var(--ink-300);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  cursor: ew-resize;
  overflow: hidden;
  touch-action: none;
}
.scrub:hover { background: var(--ink-400); border-color: var(--line-hi); }
.scrub.is-scrubbing { background: var(--ink-500); border-color: var(--accent); }
.scrub.is-editing { cursor: text; background: var(--ink-500); border-color: var(--line-hot); }
.scrub:focus-within { border-color: var(--accent); }
.scrub:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.scrub.is-mixed .scrub-in { color: var(--txt-dim); }

.scrub-in {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--txt);
  font-family: var(--f-mono);
  font-size: var(--fs-val);
  font-variant-numeric: tabular-nums;
  text-align: right;
  cursor: inherit;
}
.scrub-in:focus-visible { outline: none; }
.scrub-in::-webkit-outer-spin-button,
.scrub-in::-webkit-inner-spin-button { appearance: none; margin: 0; }

.scrub-unit {
  flex: none;
  margin-left: 2px;
  color: var(--txt-faint);
  font-size: var(--fs-micro);
  font-style: normal;
  user-select: none;
}
.scrub-unit:empty { display: none; }

/* the value's position inside [min,max] — 1px, bottom, never a filled track.
   ui/widgets.js sets .scrub-bar's width directly, so the bar *is* the fill and
   the track is drawn by the field itself. */
.scrub::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--line-hi);
  pointer-events: none;
}
.scrub-bar {
  position: absolute;
  left: 0; bottom: 0;
  width: 0;
  max-width: 100%;
  height: 1px;
  background: var(--accent);
  pointer-events: none;
}
.scrub.is-mixed .scrub-bar { background: var(--txt-faint); }

/* ══════════════════════════ 4. VECTOR FIELD ═══════════════════════════ */

.vecfield {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.vecfield > .scrub { padding-left: 3px; }

/* x cyan, y acid, z orange — the same three axes the viewport gizmo uses.
   The axis letter is a pseudo-element: the field itself carries only aria. */
.vecfield > .scrub::before {
  flex: none;
  margin-right: var(--u);
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-label);
  color: color-mix(in srgb, var(--accent) 62%, var(--txt-faint));
  user-select: none;
}
.vecfield > .ax-x { --accent: var(--pen-1); }
.vecfield > .ax-y { --accent: var(--pen-3); }
.vecfield > .ax-z { --accent: var(--pen-4); }
.vecfield > .ax-x::before { content: 'X'; }
.vecfield > .ax-y::before { content: 'Y'; }
.vecfield > .ax-z::before { content: 'Z'; }

/* ══════════════════════════ 5. TOGGLE ═════════════════════════════════ */

/* A hard-edged switch: a 24×12 rectangle with a square knob. No pill.
   The button holds the switch (.tgl-knob) and its ON/OFF word (.tgl-txt). */
.tgl {
  display: inline-flex;
  align-items: center;
  gap: var(--u2);
  flex: none;
  height: calc(var(--row) - 4px);
  cursor: pointer;
  user-select: none;
}
.tgl-knob {
  position: relative;
  display: block;
  flex: none;
  width: 24px; height: 12px;
  background: var(--ink-300);
  border: 1px solid var(--line-hi);
  border-radius: var(--r-sm);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.tgl-knob::after {
  content: '';
  position: absolute;
  top: 1px; left: 1px;
  width: 8px; height: 8px;
  background: var(--txt-faint);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.tgl:hover .tgl-knob { border-color: var(--line-hot); }
.tgl:hover .tgl-knob::after { background: var(--txt-dim); }
.tgl.is-on .tgl-knob { background: var(--ink-500); border-color: var(--accent); }
.tgl.is-on .tgl-knob::after { transform: translateX(12px); background: var(--accent); }
.tgl.is-mixed .tgl-knob::after { transform: translateX(6px); background: var(--txt-dim); }
.tgl:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.tgl[disabled] { opacity: 0.35; pointer-events: none; }

.tgl-txt {
  min-width: 3ch;
  text-align: left;
  color: var(--txt-faint);
  transition: color var(--dur) var(--ease);
}
.tgl.is-on .tgl-txt { color: var(--txt-mid); }

/* ══════════════════════════ 6. SEGMENTED / ENUM ═══════════════════════ */

.seg {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  height: calc(var(--row) - 4px);
  background: var(--ink-300);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  overflow: hidden;
  user-select: none;
}
.seg-item {
  flex: 1 1 0;
  min-width: 0;
  padding: 0 var(--u);
  border-right: 1px solid var(--line);
  color: var(--txt-dim);
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.seg-item:last-child { border-right: 0; }
.seg-item:hover { background: var(--ink-400); color: var(--txt-mid); }
.seg-item.is-on {
  background: var(--ink-500);
  color: var(--accent);
  box-shadow: inset 0 -2px 0 var(--accent);
}
.seg-item:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.seg.is-mixed .seg-item.is-on { box-shadow: none; color: var(--txt-dim); }

/* ══════════════════════════ 7. TOP-BAR MODES ══════════════════════════ */

/* ui/toolbar.js: .mode-group > .t-label.mode-label + (.seg.mode-seg | .btn) */
.mode-group {
  display: flex;
  align-items: center;
  gap: var(--u);
  flex: none;
  min-width: 0;
}
.mode-label { flex: none; color: var(--txt-faint); }
.mode-seg { flex: none; width: auto; background: var(--ink-050); }
.mode-seg .seg-item { flex: 0 0 auto; min-width: 38px; padding: 0 5px; }
.mode-flags { display: flex; align-items: center; gap: 2px; flex: none; }
.mode-flags .flagbtn { min-width: 34px; justify-content: center; }

/* ══════════════════════════ 8. COLOUR SWATCH ══════════════════════════ */

.colorfield { display: flex; align-items: center; gap: var(--u); min-width: 0; }
.swatch {
  position: relative;
  display: block;
  flex: none;
  width: 26px;
  height: calc(var(--row) - 4px);
  cursor: pointer;
}
/* the chip itself, so the hex can sit outside it */
.swatch::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 26px;
  background:
    linear-gradient(var(--c, var(--txt-dim)), var(--c, var(--txt-dim))),
    repeating-conic-gradient(var(--ink-300) 0 25%, var(--ink-100) 0 50%) 0 0 / 6px 6px;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-sm);
}
.swatch:hover::before { border-color: var(--line-hot); }
.swatch.is-empty::after {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 26px;
  background: linear-gradient(to bottom right,
    transparent calc(50% - 1px), var(--pen-2) 50%, transparent calc(50% + 1px));
  pointer-events: none;
}
.swatch-in {
  position: absolute;
  left: 0; top: 0;
  width: 26px; height: 100%;
  padding: 0; border: 0;
  opacity: 0;
  cursor: pointer;
}
.swatch:focus-within::before { border-color: var(--accent); }

/* type or paste a hex straight in */
.swatch-hex {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: calc(var(--row) - 4px);
  padding: 0 var(--u);
  background: var(--ink-300);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--txt);
  font-family: var(--f-mono);
  font-size: var(--fs-val);
  text-transform: lowercase;
}
.swatch-hex::placeholder { color: var(--txt-faint); text-transform: none; }
.swatch-hex:hover { border-color: var(--line-hi); background: var(--ink-400); }
.swatch-hex:focus { border-color: var(--accent); background: var(--ink-400); outline: none; }
.swatch-hex.is-bad { border-color: var(--pen-2); color: var(--pen-2); }

/* opacity, as a percentage beside the hex */
.swatch-alpha {
  flex: 0 0 42px;
  width: 42px;
  height: calc(var(--row) - 4px);
  padding: 0 3px;
  background: var(--ink-300);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--txt-mid);
  font-family: var(--f-mono);
  font-size: var(--fs-val);
  text-align: right;
}
.swatch-alpha:hover { border-color: var(--line-hi); background: var(--ink-400); }
.swatch-alpha:focus { border-color: var(--accent); background: var(--ink-400); color: var(--txt); outline: none; }
.swatch-alpha.is-bad { border-color: var(--pen-2); color: var(--pen-2); }

/* a row of pen-layer swatches (the carousel itself) */
.layer-swatches { display: flex; gap: 2px; flex: none; }
.pendot {
  display: block;
  width: 7px; height: 7px;
  flex: none;
  background: var(--accent);
  border-radius: var(--r-sm);
}
.penpick {
  width: 13px;
  height: calc(var(--row) - 6px);
  flex: none;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  opacity: 0.55;
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.penpick:hover { opacity: 1; border-color: var(--line-hi); }
.penpick:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; opacity: 1; }

/* ══════════════════════════ 9. TEXT / SELECT ══════════════════════════ */

.txtf, select.sel {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: calc(var(--row) - 4px);
  padding: 0 var(--u);
  background: var(--ink-300);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--txt);
  font-family: var(--f-mono);
  font-size: var(--fs-val);
}
.txtf::placeholder { color: var(--txt-faint); }
.txtf:hover, select.sel:hover { background: var(--ink-400); border-color: var(--line-hi); }
.txtf:focus, select.sel:focus { background: var(--ink-500); border-color: var(--line-hot); }
.txtf:focus-visible, select.sel:focus-visible { outline: 1px solid var(--accent); outline-offset: 0; }

textarea.txtf, .txtf-multi, .ptsfield {
  height: auto;
  min-height: 46px;
  padding: var(--u);
  line-height: 1.45;
  resize: vertical;
  white-space: pre-wrap;
  overflow: auto;
}
.ptsfield { font-variant-numeric: tabular-nums; white-space: pre; }

select.sel {
  appearance: none;
  padding-right: 16px;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--txt-dim) 50%),
                    linear-gradient(135deg, var(--txt-dim) 50%, transparent 50%);
  background-position: calc(100% - 9px) 50%, calc(100% - 5px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}
select.sel option { background: var(--ink-200); color: var(--txt); }
.is-mixed.txtf, select.sel.is-mixed { color: var(--txt-dim); }

/* font picker shows the family in its own face (ui/widgets.js sets it inline) */
.fontfield { display: flex; flex: 1 1 auto; min-width: 0; }
.fontf { font-size: var(--fs-ui); }

/* ══════════════════════════ 10. FILL FIELD ════════════════════════════ */

.fillfield {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--ink-050);
}
.fillfield .prow-fillhead {
  padding-left: var(--u);
  padding-right: var(--u);
  border-bottom: 1px solid var(--line);
}
.fillfield .prow-fillhead .prow-label { color: var(--pen-3); }
.fillfield[data-kind='none'] .prow-fillhead .prow-label { color: var(--txt-faint); }
.fillfield[data-kind='rmhatch'] .prow-fillhead .prow-label { color: var(--pen-5); }
.fill-params { display: block; }
.fill-params:empty { display: none; }
.fillfield .prow { padding-left: var(--u); padding-right: var(--u); }
.fillfield .prow:last-child { border-bottom: 0; }
.fillfield.is-mixed { opacity: 0.72; }

/* ══════════════════════════ 11. BUTTONS ═══════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--u);
  height: calc(var(--row) + 2px);
  padding: 0 var(--u2);
  background: var(--ink-300);
  border: 1px solid var(--line-hi);
  border-radius: var(--r-sm);
  color: var(--txt-mid);
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.btn:hover { background: var(--ink-400); border-color: var(--line-hot); color: var(--txt); }
.btn:active { background: var(--ink-500); }
.btn.is-on { color: var(--accent); border-color: var(--accent); }
.btn[disabled], .btn.is-disabled { opacity: 0.35; pointer-events: none; }
.btn:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.btn.is-danger { color: var(--pen-2); border-color: var(--pen-2-dim); }
.btn.is-danger:hover { color: var(--pen-2); border-color: var(--pen-2); background: var(--ink-400); }
.btn.wide { width: 100%; }

.btn-icon { font-style: normal; font-family: var(--f-mono); line-height: 1; }
.btn-txt { overflow: hidden; text-overflow: ellipsis; }
.btn-key {
  margin-left: 2px;
  color: var(--txt-faint);
  font-family: var(--f-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0;
  text-transform: none;
}
.btn:hover .btn-key { color: var(--txt-dim); }

.btn-primary {
  background: var(--ink-500);
  border-color: var(--accent);
  color: var(--accent);
}
.btn-primary:hover { background: var(--accent); color: var(--ink-000); border-color: var(--accent); }
.btn-primary:hover .btn-key { color: var(--ink-000); }
.btn-primary:active { background: var(--pen-1-dim); color: var(--ink-000); }

/* the compact variant used in the top bar, panel headers and the tool rack */
.mini {
  height: 17px;
  gap: 3px;
  padding: 0 5px;
  background: transparent;
  border-color: var(--line);
  color: var(--txt-dim);
  font-size: var(--fs-micro);
}
.mini:hover { background: var(--ink-300); border-color: var(--line-hi); color: var(--txt); }
.mini.btn-primary { background: var(--ink-500); border-color: var(--accent); color: var(--accent); }

/* a row of actions inside an inspector section */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--u);
  padding: var(--u2);
  border-bottom: 1px solid var(--line-soft);
}
.btn-row:last-child { border-bottom: 0; }
.btn-row .btn { flex: 1 1 auto; }

/* ══════════════════════════ 12. VIEWPORT TOOL RACK ════════════════════ */

.tool {
  width: 24px; height: 24px;
  padding: 0;
  gap: 0;
  border-color: transparent;
  background: transparent;
  color: var(--txt-dim);
}
.tool:hover { background: var(--ink-300); border-color: var(--line); color: var(--txt); }
.tool.is-on { background: var(--ink-500); color: var(--accent); border-color: var(--accent); }
.tool-icon { font-style: normal; font-family: var(--f-mono); font-size: 12px; line-height: 1; }
.tool-sep { display: block; height: 1px; margin: 2px 0; background: var(--line); }

/* ══════════════════════════ 13. TABS ══════════════════════════════════ */

.tab {
  display: flex;
  align-items: center;
  gap: var(--u);
  height: 100%;
  padding: 0 var(--u2);
  border-right: 1px solid var(--line);
  color: var(--txt-faint);
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
  flex: none;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.tab:hover { color: var(--txt-mid); background: var(--ink-100); }
.tab.is-on {
  color: var(--txt);
  background: var(--ink-100);
  box-shadow: inset 0 -2px 0 var(--accent);
}
.tab:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.tab .dot { width: 5px; height: 5px; background: var(--accent); flex: none; }

/* ══════════════════════════ 14. TREE ROWS ═════════════════════════════ */

/* ui/tree.js sets `--depth` and an inline padding-left of 4 + depth*11 px. */
.treerow {
  --depth: 0;
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--u);
  height: var(--row);
  padding-right: var(--u2);
  color: var(--txt-mid);
  white-space: nowrap;
  user-select: none;
  cursor: default;
}
.treerow:hover, .treerow.is-hover { background: var(--ink-200); color: var(--txt); }
.treerow.is-sel { background: var(--ink-400); color: var(--txt); box-shadow: inset 2px 0 0 var(--accent); }
.treerow.is-sel .tname { color: var(--accent); }
.treerow.is-disabled { opacity: 0.4; }
.treerow.is-disabled .tname { text-decoration: line-through; }
.treerow.is-highlight .tname { color: var(--pen-2); }
.treerow:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.treerow.is-dragging { opacity: 0.5; }
.treerow.dz-into { box-shadow: inset 0 0 0 1px var(--accent); }
.treerow.dz-before { box-shadow: inset 0 2px 0 var(--accent); }
.treerow.dz-after { box-shadow: inset 0 -2px 0 var(--accent); }

/* indent guides — one hairline per level, drawn inside the inline padding */
.tguide {
  position: absolute;
  left: 8px;
  top: 0; bottom: 0;
  width: calc(var(--depth) * 11px);
  background: repeating-linear-gradient(90deg, var(--line-soft) 0 1px, transparent 1px 11px);
  pointer-events: none;
}

.twist {
  flex: none;
  width: 10px;
  align-self: stretch;
  display: grid; place-items: center;
  color: var(--txt-faint);
  font-size: 8px;
}
.twist:hover { color: var(--txt-mid); }
.twist:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.twist.is-empty { visibility: hidden; }

.ticon {
  flex: none;
  width: 12px;
  text-align: center;
  color: var(--txt-dim);
  font-style: normal;
  font-size: var(--fs-micro);
}
.treerow[data-cat='boolean']  .ticon { color: var(--pen-2); }
.treerow[data-cat='modifier'] .ticon { color: var(--pen-4); }
.treerow[data-cat='shape3d']  .ticon { color: var(--pen-1); }
.treerow[data-cat='shape2d']  .ticon { color: var(--pen-3); }
.treerow[data-cat='transform'] .ticon { color: var(--txt-mid); }
.treerow[data-cat='style']    .ticon { color: var(--pen-5); }

.tname {
  flex: none;
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: inherit;
}
.tparam {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--txt-faint);
  font-size: var(--fs-micro);
  font-variant-numeric: tabular-nums;
}
.teye {
  flex: none;
  width: 14px;
  text-align: center;
  color: var(--txt-faint);
  opacity: 0;
  font-size: var(--fs-micro);
}
.treerow:hover .teye, .treerow.is-disabled .teye { opacity: 1; }
.teye:hover { color: var(--txt); }
.teye:focus-visible { outline: 1px solid var(--accent); outline-offset: 0; opacity: 1; }

/* ══════════════════════════ 15. INSERT LIBRARY ════════════════════════ */

.libgroup { display: block; }
.libgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(66px, 1fr));
  gap: 1px;
  padding: var(--u2) var(--u2) var(--u3);
}
.libitem {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: 46px;
  padding: var(--u) 2px;
  background: var(--ink-200);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  color: var(--txt-dim);
  cursor: pointer;
  user-select: none;
  overflow: hidden;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.libitem:hover { background: var(--ink-400); border-color: var(--line-hot); color: var(--txt); }
.libitem:active { background: var(--ink-500); }
.libitem:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.libicon {
  display: block;
  color: var(--accent);
  font-style: normal;
  font-size: 15px;
  line-height: 1.1;
  opacity: 0.9;
}
.liblabel {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  color: inherit;
}
.libitem[data-cat='shape3d']   { --accent: var(--pen-1); }
.libitem[data-cat='shape2d']   { --accent: var(--pen-3); }
.libitem[data-cat='boolean']   { --accent: var(--pen-2); }
.libitem[data-cat='modifier']  { --accent: var(--pen-4); }
.libitem[data-cat='transform'] { --accent: var(--txt-mid); }
.libitem[data-cat='style']     { --accent: var(--pen-5); }
.libitem[data-cat='setting']   { --accent: var(--txt-dim); }
.libitem[data-cat='fill']      { --accent: var(--pen-3); }
.libitem.is-fill { border-style: dashed; }

/* ══════════════════════════ 16. CHIPS ═════════════════════════════════ */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--u);
  height: 15px;
  padding: 0 5px;
  background: color-mix(in srgb, var(--accent) 12%, var(--ink-200));
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: var(--r-sm);
  color: var(--accent);
  font-family: var(--f-display);
  font-stretch: condensed;
  font-weight: 700;
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
  flex: none;
}
.chip.quiet {
  background: var(--ink-200);
  border-color: var(--line);
  color: var(--txt-dim);
}
.chip.warn { --accent: var(--pen-4); }
.chip.error { --accent: var(--pen-2); }
.chip.ok { --accent: var(--pen-3); }
button.chip { cursor: pointer; }
button.chip:hover { background: color-mix(in srgb, var(--accent) 22%, var(--ink-200)); }
button.chip:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }

/* ══════════════════════════ 17. DIAGNOSTIC ROWS (rail) ════════════════ */

/* ui/inspector.js builds .diag.is-error|is-warn|is-info > .diag-loc + .diag-msg
   (the code-pane console in app.css uses .diag.error > .loc/.sev/.msg). */
.diag {
  display: flex;
  align-items: baseline;
  gap: var(--u2);
  width: 100%;
  padding: 2px var(--u2);
  border-bottom: 1px solid var(--line-soft);
  color: var(--txt-mid);
  text-align: left;
  cursor: pointer;
}
.diag:last-child { border-bottom: 0; }
.diag:hover { background: var(--ink-200); color: var(--txt); }
.diag:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.diag-loc {
  flex: none;
  min-width: 3ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.diag-msg {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-micro);
}
.diag.is-error .diag-loc { color: var(--pen-2); }
.diag.is-warn .diag-loc { color: var(--pen-4); }

/* per-layer stats table in the document summary */
.layertab { width: 100%; border-collapse: collapse; font-size: var(--fs-ui); }
.layertab td, .layertab th {
  padding: 2px var(--u2);
  border-bottom: 1px solid var(--line-soft);
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--txt-mid);
  font-weight: 400;
}
.layertab th { color: var(--txt-faint); font-size: var(--fs-micro); letter-spacing: var(--ls-label); text-transform: uppercase; }
.layertab td:first-child, .layertab th:first-child { text-align: left; }
.layertab tr:hover td { background: var(--ink-200); color: var(--txt); }

/* ══════════════════════════ 18. COMMAND PALETTE ═══════════════════════ */

#palette {
  position: fixed;
  z-index: var(--z-modal);
  top: 14vh;
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, 92vw);
  max-height: 62vh;
  display: flex;
  flex-direction: column;
  background: var(--ink-100);
  border: 1px solid var(--line-hot);
  border-radius: var(--r-sm);
  overflow: hidden;
}
#palette-input {
  flex: none;
  height: 34px;
  padding: 0 var(--u3);
  background: var(--ink-050);
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--txt);
  font-family: var(--f-mono);
  font-size: var(--fs-head);
}
#palette-input::placeholder { color: var(--txt-faint); }
#palette-input:focus-visible { outline: none; box-shadow: inset 0 -2px 0 var(--accent); }
#palette-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 0;
}
.pal-item {
  display: flex;
  align-items: center;
  gap: var(--u2);
  width: 100%;
  height: 24px;
  padding: 0 var(--u3);
  color: var(--txt-mid);
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}
.pal-item:hover { background: var(--ink-200); }
.pal-item.is-on { background: var(--ink-400); color: var(--txt); box-shadow: inset 2px 0 0 var(--accent); }
.pal-item:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.pal-kind {
  flex: none;
  width: 52px;
  color: var(--txt-faint);
}
.pal-label { flex: none; color: inherit; }
.pal-label em { font-style: normal; color: var(--accent); }
.pal-hint {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
  font-size: var(--fs-micro);
}
.pal-group {
  height: var(--hdr);
  display: flex;
  align-items: center;
  padding: 0 var(--u3);
  background: var(--ink-050);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  color: var(--txt-faint);
}
.pal-group:first-child { border-top: 0; }
.pal-empty { padding: var(--u4); text-align: center; }

/* ══════════════════════════ 19. TOOLTIP ═══════════════════════════════ */

#tooltip {
  position: fixed;
  z-index: var(--z-float);
  max-width: 280px;
  padding: 3px var(--u2);
  background: var(--ink-000);
  border: 1px solid var(--line-hot);
  border-radius: var(--r-sm);
  color: var(--txt-mid);
  font-size: var(--fs-micro);
  line-height: 1.5;
  pointer-events: none;
  white-space: pre-wrap;
}

/* ══════════════════════════ 20. CONTEXT MENU ══════════════════════════ */

#ctxmenu {
  position: fixed;
  z-index: var(--z-float);
  min-width: 168px;
  max-height: 70vh;
  overflow: auto;
  padding: 2px 0;
  background: var(--ink-200);
  border: 1px solid var(--line-hot);
  border-radius: var(--r-sm);
}
.ctxitem {
  display: flex;
  align-items: center;
  gap: var(--u3);
  width: 100%;
  height: 21px;
  padding: 0 var(--u2);
  color: var(--txt-mid);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.ctxitem:hover { background: var(--ink-400); color: var(--txt); }
.ctxitem:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }
.ctxitem[disabled] { color: var(--txt-faint); pointer-events: none; }
.ctxitem.danger { color: var(--pen-2); }
.ctx-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.ctx-key { flex: none; color: var(--txt-faint); font-family: var(--f-mono); }
.ctx-sep {
  display: flex;
  align-items: center;
  height: 1px;
  margin: 2px 0;
  background: var(--line);
  overflow: hidden;
}
/* a separator that carries a label grows into a small ruled header */
.ctx-sep:not(:empty) {
  height: var(--hdr);
  margin: 0;
  padding: 0 var(--u2);
  background: var(--ink-100);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  color: var(--txt-faint);
}

/* ══════════════════════════ 21. NARROW LAYOUT ═════════════════════════ */

@media (max-width: 1100px) {
  .prow { min-height: 26px; }
  .scrub, .seg, .txtf, select.sel, .swatch { height: 22px; }
  .libgrid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); }
  #palette { top: 6vh; max-height: 78vh; }
}

/* pointer: coarse — fingers need more than 22px */
@media (pointer: coarse) {
  .prow { min-height: 30px; }
  .scrub, .seg, .txtf, select.sel, .swatch { height: 26px; }
  .treerow { height: 28px; }
  .tgl-knob { width: 30px; height: 16px; }
  .tgl-knob::after { width: 12px; height: 12px; }
  .tgl.is-on .tgl-knob::after { transform: translateX(14px); }
  .tool { width: 30px; height: 30px; }
}
