@weasel-js/ui 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{Callout-BUn0dP_S.js → Callout-DpTO3fkb.js} +10 -10
- package/dist/chunks/Callout-DpTO3fkb.js.map +1 -0
- package/dist/chunks/{Checkbox-DFn-x0JO.js → Checkbox-d4IfhiXh.js} +2 -2
- package/dist/chunks/{Checkbox-DFn-x0JO.js.map → Checkbox-d4IfhiXh.js.map} +1 -1
- package/dist/chunks/{CloseButton-BmNmRVtb.js → CloseButton-wb7Or5Eg.js} +2 -2
- package/dist/chunks/{CloseButton-BmNmRVtb.js.map → CloseButton-wb7Or5Eg.js.map} +1 -1
- package/dist/chunks/{ColorModeControl-DaVJ-SyX.js → ColorModeControl-DET6Itwq.js} +3 -3
- package/dist/chunks/{ColorModeControl-DaVJ-SyX.js.map → ColorModeControl-DET6Itwq.js.map} +1 -1
- package/dist/chunks/{DataGrid-CmHJe57v.js → DataGrid-B6IS9vUk.js} +2 -2
- package/dist/chunks/{DataGrid-CmHJe57v.js.map → DataGrid-B6IS9vUk.js.map} +1 -1
- package/dist/chunks/{DetentSlider-DNTAk8xP.js → DetentSlider-D40V8Oma.js} +2 -2
- package/dist/chunks/{DetentSlider-DNTAk8xP.js.map → DetentSlider-D40V8Oma.js.map} +1 -1
- package/dist/chunks/{Dialog-DKfsk5VN.js → Dialog-h-5MeYpu.js} +9 -9
- package/dist/chunks/{Dialog-DKfsk5VN.js.map → Dialog-h-5MeYpu.js.map} +1 -1
- package/dist/chunks/{Disclosure-Ch2KxYuB.js → Disclosure-CpWt87nO.js} +7 -7
- package/dist/chunks/{Disclosure-Ch2KxYuB.js.map → Disclosure-CpWt87nO.js.map} +1 -1
- package/dist/chunks/FitLabel-BzZGkWfL.js +76 -0
- package/dist/chunks/FitLabel-BzZGkWfL.js.map +1 -0
- package/dist/chunks/{GradientEditor-DD2OjQtn.js → GradientEditor-vz771M-N.js} +4 -4
- package/dist/chunks/{GradientEditor-DD2OjQtn.js.map → GradientEditor-vz771M-N.js.map} +1 -1
- package/dist/chunks/{Icon--B1ME-6c.js → Icon-DPRUIo3G.js} +4 -1
- package/dist/chunks/Icon-DPRUIo3G.js.map +1 -0
- package/dist/chunks/{Jog-BrkzdGV2.js → Jog-TE6QI9i1.js} +3 -3
- package/dist/chunks/{Jog-BrkzdGV2.js.map → Jog-TE6QI9i1.js.map} +1 -1
- package/dist/chunks/{LayerList-Bxj1N6bj.js → LayerList-BXTAjK-4.js} +6 -6
- package/dist/chunks/{LayerList-Bxj1N6bj.js.map → LayerList-BXTAjK-4.js.map} +1 -1
- package/dist/chunks/{ListEditor-OQDzG4A5.js → ListEditor-DGtwj99m.js} +2 -2
- package/dist/chunks/{ListEditor-OQDzG4A5.js.map → ListEditor-DGtwj99m.js.map} +1 -1
- package/dist/chunks/{MeshEditor-DWpvg8H6.js → MeshEditor-8CRsu-Td.js} +2 -2
- package/dist/chunks/{MeshEditor-DWpvg8H6.js.map → MeshEditor-8CRsu-Td.js.map} +1 -1
- package/dist/chunks/{NumberField-DS0WSiin.js → NumberField-BXFrOi5M.js} +8 -5
- package/dist/chunks/{NumberField-DS0WSiin.js.map → NumberField-BXFrOi5M.js.map} +1 -1
- package/dist/chunks/{PaintField-BdmQM53v.js → PaintField-DX4uYlF9.js} +2 -2
- package/dist/chunks/{PaintField-BdmQM53v.js.map → PaintField-DX4uYlF9.js.map} +1 -1
- package/dist/chunks/{PaintInput-DaQMeBsI.js → PaintInput-CWyOJXUM.js} +5 -5
- package/dist/chunks/{PaintInput-DaQMeBsI.js.map → PaintInput-CWyOJXUM.js.map} +1 -1
- package/dist/chunks/{PatternPicker-B3HcMZWg.js → PatternPicker-0j51aDJ3.js} +9 -9
- package/dist/chunks/PatternPicker-0j51aDJ3.js.map +1 -0
- package/dist/chunks/{Prefs-C4MZ28SX.js → Prefs-gbjYqvSD.js} +41 -41
- package/dist/chunks/Prefs-gbjYqvSD.js.map +1 -0
- package/dist/chunks/{Properties-DseN56WI.js → Properties-BbNuMiic.js} +4 -4
- package/dist/chunks/{Properties-DseN56WI.js.map → Properties-BbNuMiic.js.map} +1 -1
- package/dist/chunks/PropertyField-CWUtNK1w.js +751 -0
- package/dist/chunks/PropertyField-CWUtNK1w.js.map +1 -0
- package/dist/chunks/{SelectionPanel-C3WzyaZV.js → SelectionPanel-BpUqP75b.js} +2 -2
- package/dist/chunks/{SelectionPanel-C3WzyaZV.js.map → SelectionPanel-BpUqP75b.js.map} +1 -1
- package/dist/chunks/{SidebarPanel-AXQ0jRDx.js → SidebarPanel--dJ-k9-V.js} +3 -3
- package/dist/chunks/{SidebarPanel-AXQ0jRDx.js.map → SidebarPanel--dJ-k9-V.js.map} +1 -1
- package/dist/chunks/Slider-CHBQ8uUC.js +439 -0
- package/dist/chunks/Slider-CHBQ8uUC.js.map +1 -0
- package/dist/chunks/{SwatchGrid-9ZPiDmxd.js → SwatchGrid-DxK9e_IV.js} +3 -3
- package/dist/chunks/SwatchGrid-DxK9e_IV.js.map +1 -0
- package/dist/chunks/{SwatchStrip-Bi9iPLoh.js → SwatchStrip-BY6A511W.js} +2 -2
- package/dist/chunks/{SwatchStrip-Bi9iPLoh.js.map → SwatchStrip-BY6A511W.js.map} +1 -1
- package/dist/chunks/{ThemeSwitcher-DiBmMh_B.js → ThemeSwitcher-tnATkIo1.js} +2 -2
- package/dist/chunks/{ThemeSwitcher-DiBmMh_B.js.map → ThemeSwitcher-tnATkIo1.js.map} +1 -1
- package/dist/chunks/{Timeline-sMCH2fah.js → Timeline-FlLUm8nd.js} +4 -4
- package/dist/chunks/{Timeline-sMCH2fah.js.map → Timeline-FlLUm8nd.js.map} +1 -1
- package/dist/chunks/{Toast-C3ozq11V.js → Toast-CuHkT0x0.js} +2 -2
- package/dist/chunks/{Toast-C3ozq11V.js.map → Toast-CuHkT0x0.js.map} +1 -1
- package/dist/chunks/ToggleBar-BZ4Gk1IU.js +84 -0
- package/dist/chunks/ToggleBar-BZ4Gk1IU.js.map +1 -0
- package/dist/chunks/{TokenPanel-WtKGY2Db.js → TokenPanel-DongdiZM.js} +23 -23
- package/dist/chunks/{TokenPanel-WtKGY2Db.js.map → TokenPanel-DongdiZM.js.map} +1 -1
- package/dist/chunks/ToolOptionsBar-wTPJFfOn.js +94 -0
- package/dist/chunks/ToolOptionsBar-wTPJFfOn.js.map +1 -0
- package/dist/chunks/{Tree-Cc8lIzgM.js → Tree-hzIbj2q1.js} +2 -2
- package/dist/chunks/{Tree-Cc8lIzgM.js.map → Tree-hzIbj2q1.js.map} +1 -1
- package/dist/chunks/checkbox.module-Dcx8ILgR.js +5 -0
- package/dist/chunks/checkbox.module-Dcx8ILgR.js.map +1 -0
- package/dist/chunks/{icons-Dr2-r30x.js → icons-CofIOTiI.js} +2 -2
- package/dist/chunks/{icons-Dr2-r30x.js.map → icons-CofIOTiI.js.map} +1 -1
- package/dist/chunks/{model-qsAFK7_0.js → model-qQj8Ny9w.js} +134 -133
- package/dist/chunks/model-qQj8Ny9w.js.map +1 -0
- package/dist/chunks/{prefField-BE_Ytr2H.js → prefField-CCm_nzlM.js} +81 -75
- package/dist/chunks/prefField-CCm_nzlM.js.map +1 -0
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/Checkbox/index.js +1 -1
- package/dist/components/CloseButton/index.js +1 -1
- package/dist/components/ColorModeControl/index.js +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/DetentSlider/index.js +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/Disclosure/index.js +1 -1
- package/dist/components/FitLabel/FitLabel.d.ts +41 -0
- package/dist/components/FitLabel/FitLabel.d.ts.map +1 -0
- package/dist/components/FitLabel/index.d.ts +3 -0
- package/dist/components/FitLabel/index.d.ts.map +1 -0
- package/dist/components/FitLabel/index.js +2 -0
- package/dist/components/GradientEditor/index.js +1 -1
- package/dist/components/InlineRange/InlineRange.d.ts +1 -1
- package/dist/components/Jog/index.js +1 -1
- package/dist/components/LayerList/index.js +1 -1
- package/dist/components/ListEditor/index.js +1 -1
- package/dist/components/MeshEditor/index.js +1 -1
- package/dist/components/NumberField/UnitField.d.ts.map +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/PaintField/index.js +1 -1
- package/dist/components/PaintInput/index.js +1 -1
- package/dist/components/PatternPicker/index.js +1 -1
- package/dist/components/Prefs/index.js +2 -2
- package/dist/components/Prefs/prefField.d.ts.map +1 -1
- package/dist/components/Properties/NumberControls.d.ts +16 -0
- package/dist/components/Properties/NumberControls.d.ts.map +1 -0
- package/dist/components/Properties/PropertyField.d.ts +18 -8
- package/dist/components/Properties/PropertyField.d.ts.map +1 -1
- package/dist/components/Properties/index.js +2 -2
- package/dist/components/SelectionPanel/index.js +2 -2
- package/dist/components/SelectionPanel/renderLeaf.d.ts.map +1 -1
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/Slider/Slider.d.ts +6 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/SwatchGrid/index.js +1 -1
- package/dist/components/SwatchStrip/index.js +1 -1
- package/dist/components/ThemeSwitcher/index.js +1 -1
- package/dist/components/Timeline/index.js +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/ToggleBar/ToggleBar.d.ts.map +1 -1
- package/dist/components/ToggleBar/index.js +1 -1
- package/dist/components/TokenPanel/index.js +1 -1
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts +1 -1
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts.map +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/Tree/index.js +1 -1
- package/dist/components/stanceCss.d.ts +6 -0
- package/dist/components/stanceCss.d.ts.map +1 -1
- package/dist/components/stanceSurfaces.d.ts.map +1 -1
- package/dist/endless.d.ts +7 -0
- package/dist/endless.d.ts.map +1 -0
- package/dist/icons/paths.d.ts +2 -0
- package/dist/icons/paths.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -70
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +9 -9
- package/dist/chunks/Callout-BUn0dP_S.js.map +0 -1
- package/dist/chunks/Icon--B1ME-6c.js.map +0 -1
- package/dist/chunks/PatternPicker-B3HcMZWg.js.map +0 -1
- package/dist/chunks/Prefs-C4MZ28SX.js.map +0 -1
- package/dist/chunks/PropertyField-BbNqK8xr.js +0 -743
- package/dist/chunks/PropertyField-BbNqK8xr.js.map +0 -1
- package/dist/chunks/Slider-DSrlMEq8.js +0 -389
- package/dist/chunks/Slider-DSrlMEq8.js.map +0 -1
- package/dist/chunks/SwatchGrid-9ZPiDmxd.js.map +0 -1
- package/dist/chunks/ToggleBar-Z2jZiguF.js +0 -80
- package/dist/chunks/ToggleBar-Z2jZiguF.js.map +0 -1
- package/dist/chunks/ToolOptionsBar-CZTYPoC2.js +0 -88
- package/dist/chunks/ToolOptionsBar-CZTYPoC2.js.map +0 -1
- package/dist/chunks/checkbox.module-DLQV9tMX.js +0 -5
- package/dist/chunks/checkbox.module-DLQV9tMX.js.map +0 -1
- package/dist/chunks/model-qsAFK7_0.js.map +0 -1
- package/dist/chunks/prefField-BE_Ytr2H.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyField-BbNqK8xr.js","names":["s","TooltipTrigger","Tooltip","SliderTrack","_Fragment","s","_exhaustive","Switch","sharedCheckbox","shared","Input","RadioGroup","Radio","Select","dlog","Tooltip$1","TooltipTrigger$1","useStance","range_module_default","ColorField","Select$1","FontFamilySelect","FontWeightSelect","Input$1","spinKey","UnitField","ToggleBar","PaintInput","PaintField","RadioGroup$1","Radio$1","Switch$1","checkbox_module_default","Properties_module_default","DENSITY_CLASS","ALIGN_CLASS","propertyMetricClass","base","density","align","className","PanelNesting","createContext","PropertyPanel","nested","useContext","attrs","heading","title","selectable","stance","actions","PropertyList","forwardRef","pack","PropertySpan","PropertyNote","PropertyRow","variantClass","variant","intrinsic","resolved","layout","layoutClass","cls","span","auto","autoControl","trailing","readout","rowRef","useRef","labelRef","multiline","useMultiline","head","onAutoChange","AutoToggle","label","hint","description","PropertyHelp","tail","multi","group","children","setMultiline","useState","useLayoutEffect","row","enabled","observer","labelStyle","lineHeight","floor","labelWraps","tallChild","child","name","toggle","e","onChange","Focusable","PropertyField","field","props","id","useId","control","nameOf","controlClassName","shape","rowShape","rowClassName","SliderRow","ControlBody","PropertyControl","typed","SliderCell","useSliderDraft","draft","setDraft","p","onInput","next","boxedReadout","SliderReadout","SliderTrack$1","Fragment","BooleanControl","NumberInput","StringControl","EnumControl","ColorControl","PaintControl","Dimmed","mixed","unset","on","box","useEffect","useCommitListener","ref","latest","commit","el","onCommit","unitSuffix","unit","ignore","known","input","sliderBounds","live","range","raw","value","min","max","v","decimals","step","display","decimal","EditableReadout","text","format","n","qty","read","parseAs","displayValue","fit","useTextEdit","drafting","edit","placeholder","drawnGlyph","glyph","glyphTip","o","current","opt","lit","added","onClear","splitAlpha","eight","toHex8","getAlpha01","withAlpha","apart","split","alpha","route","hex","own","write","a","settled","withAlpha01","Editor"],"sources":["../../src/components/Properties/Properties.module.css","../../src/components/Properties/PropertyPanel.tsx","../../src/components/Properties/PropertyField.tsx"],"sourcesContent":["/* One stylesheet for the whole property-panel family. PropertyList, PropertyRow,\n PropertyGroup and Subpanel are styled together because the grid\n rules genuinely cross components — `.listPairs > .subpanel` and\n `.groupBody > :not(.rowColor)` name two components in one selector, and a CSS\n Module can only compose local names within its own file. */\n\n/* Authored against a border-box reset (labkit's `.lk-root *`). weasel-ui has no\n global reset, so the family restates it over its own subtrees. */\n.panel,\n.list,\n.row,\n.group,\n.subpanel,\n.panel *,\n.list *,\n.row *,\n.group *,\n.subpanel * {\n box-sizing: border-box;\n}\n\n/* A panel is chrome: a drag across it should move a slider, not paint a\n selection over its labels. What the family shows as a value stays copyable,\n and a field stays one — Safari carries `none` into an input's caret. */\n.panel,\n.list,\n.row,\n.group,\n.subpanel {\n -webkit-user-select: none;\n user-select: none;\n}\n\n/* Opted in with `selectable` (a debug panel's default): the whole family lets\n text select, reaching past each member's own `none`. */\n.panel[data-selectable='true'],\n.panel[data-selectable='true'] :is(.panel, .list, .row, .group, .subpanel, .card, .cardList) {\n -webkit-user-select: text;\n user-select: text;\n}\n\n.readout,\n.readoutInput,\n.row input:not([type='range']):not([type='checkbox']):not([type='radio']),\n.row textarea,\n.row [contenteditable] {\n -webkit-user-select: text;\n user-select: text;\n}\n\n/* ── Container metrics ──────────────────────────────────────────────\n Every spacing number the family lays out with is read from a `--wzl-prop-*`\n custom property with its own value as the fallback, so a consumer can move\n any of them from an ancestor without selector surgery. The `density` classes\n below set them in preset bundles; nothing in this file declares one, so an\n inherited value always reaches the use site. */\n\n.panel {\n background: var(--_s-fill);\n border: var(--_s-border-width) var(--_s-border-style) var(--_s-border-color);\n border-radius: var(--_s-radius);\n padding: var(--_s-pad);\n backdrop-filter: blur(var(--_s-blur));\n -webkit-backdrop-filter: blur(var(--_s-blur));\n}\n\n.panel[data-stance='preview'] {\n overflow: hidden;\n}\n\n\n.panelTitle {\n font-family: var(--_s-title-font);\n font-weight: var(--_s-title-weight);\n font-size: var(--_s-title-size);\n line-height: var(--wzl-leading-snug);\n letter-spacing: var(--_s-title-tracking);\n text-transform: var(--_s-title-case);\n color: var(--_s-title-color);\n padding: var(--_s-title-inset);\n margin: 0 0 var(--wzl-prop-panel-title-gap, 12px);\n}\n\n.panelHeader {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n margin: 0 0 var(--wzl-prop-panel-title-gap, 12px);\n}\n\n.panelHeader > .panelTitle {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n}\n\n.panelActions {\n display: flex;\n flex: none;\n align-items: center;\n gap: var(--wzl-space-2);\n margin-inline-start: auto;\n}\n\n/* Each panel resolves its slots into local names: the stance's own value,\n then — nested — the stance's nested value, falling back to the panel's base\n slot. The slots are @weasel-js/theme's STANCE_SLOTS. */\n/* BEGIN GENERATED stance rules: panel — `npm run gen:stances`, do not edit. */\n\n.panel {\n --wzl-tone: initial;\n}\n\n.panel {\n --_s-surface: var(--wzl-panel-surface);\n --_s-border-color: var(--wzl-panel-border-color);\n --_s-border-style: var(--wzl-panel-border-style);\n --_s-border-width: var(--wzl-panel-border-width);\n --_s-radius: var(--wzl-panel-radius);\n --_s-pad: var(--wzl-prop-panel-pad, var(--wzl-panel-pad));\n --_s-blur: var(--wzl-panel-blur);\n --_s-tone-mix: var(--wzl-panel-tone-mix);\n --_s-tone: var(--wzl-tone, var(--_s-surface));\n --_s-accent: var(--wzl-tone);\n --_s-title-font: var(--wzl-panel-title-font);\n --_s-title-weight: var(--wzl-panel-title-weight);\n --_s-title-size: var(--wzl-panel-title-size);\n --_s-title-case: var(--wzl-panel-title-case);\n --_s-title-tracking: var(--wzl-panel-title-tracking);\n --_s-title-color: var(--wzl-panel-title-color);\n --_s-title-inset: var(--wzl-panel-title-inset);\n}\n\n.panel[data-stance='scope'] {\n --_s-surface: var(--wzl-stance-scope-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-scope-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-scope-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-scope-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-scope-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-scope-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-scope-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-scope-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-scope-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-scope-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-scope-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-scope-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-scope-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-scope-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-scope-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-scope-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-scope-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='scope'][data-nested] {\n --_s-surface: var(--wzl-stance-scope-nested-surface, var(--wzl-stance-scope-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-scope-nested-border-color, var(--wzl-stance-scope-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-scope-nested-border-style, var(--wzl-stance-scope-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-scope-nested-border-width, var(--wzl-stance-scope-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-scope-nested-radius, var(--wzl-stance-scope-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-scope-nested-pad, var(--wzl-stance-scope-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-scope-nested-blur, var(--wzl-stance-scope-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-scope-nested-tone-mix, var(--wzl-stance-scope-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-scope-nested-tone, var(--wzl-stance-scope-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-scope-nested-accent, var(--wzl-stance-scope-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-scope-nested-title-font, var(--wzl-stance-scope-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-scope-nested-title-weight, var(--wzl-stance-scope-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-scope-nested-title-size, var(--wzl-stance-scope-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-scope-nested-title-case, var(--wzl-stance-scope-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-scope-nested-title-tracking, var(--wzl-stance-scope-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-scope-nested-title-color, var(--wzl-stance-scope-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-scope-nested-title-inset, var(--wzl-stance-scope-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='aside'] {\n --_s-surface: var(--wzl-stance-aside-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-aside-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-aside-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-aside-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-aside-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-aside-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-aside-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-aside-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-aside-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-aside-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-aside-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-aside-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-aside-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-aside-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-aside-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-aside-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-aside-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='aside'][data-nested] {\n --_s-surface: var(--wzl-stance-aside-nested-surface, var(--wzl-stance-aside-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-aside-nested-border-color, var(--wzl-stance-aside-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-aside-nested-border-style, var(--wzl-stance-aside-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-aside-nested-border-width, var(--wzl-stance-aside-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-aside-nested-radius, var(--wzl-stance-aside-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-aside-nested-pad, var(--wzl-stance-aside-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-aside-nested-blur, var(--wzl-stance-aside-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-aside-nested-tone-mix, var(--wzl-stance-aside-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-aside-nested-tone, var(--wzl-stance-aside-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-aside-nested-accent, var(--wzl-stance-aside-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-aside-nested-title-font, var(--wzl-stance-aside-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-aside-nested-title-weight, var(--wzl-stance-aside-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-aside-nested-title-size, var(--wzl-stance-aside-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-aside-nested-title-case, var(--wzl-stance-aside-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-aside-nested-title-tracking, var(--wzl-stance-aside-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-aside-nested-title-color, var(--wzl-stance-aside-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-aside-nested-title-inset, var(--wzl-stance-aside-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='advanced'] {\n --_s-surface: var(--wzl-stance-advanced-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-advanced-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-advanced-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-advanced-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-advanced-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-advanced-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-advanced-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-advanced-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-advanced-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-advanced-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-advanced-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-advanced-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-advanced-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-advanced-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-advanced-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-advanced-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-advanced-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='advanced'][data-nested] {\n --_s-surface: var(--wzl-stance-advanced-nested-surface, var(--wzl-stance-advanced-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-advanced-nested-border-color, var(--wzl-stance-advanced-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-advanced-nested-border-style, var(--wzl-stance-advanced-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-advanced-nested-border-width, var(--wzl-stance-advanced-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-advanced-nested-radius, var(--wzl-stance-advanced-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-advanced-nested-pad, var(--wzl-stance-advanced-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-advanced-nested-blur, var(--wzl-stance-advanced-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-advanced-nested-tone-mix, var(--wzl-stance-advanced-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-advanced-nested-tone, var(--wzl-stance-advanced-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-advanced-nested-accent, var(--wzl-stance-advanced-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-advanced-nested-title-font, var(--wzl-stance-advanced-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-advanced-nested-title-weight, var(--wzl-stance-advanced-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-advanced-nested-title-size, var(--wzl-stance-advanced-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-advanced-nested-title-case, var(--wzl-stance-advanced-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-advanced-nested-title-tracking, var(--wzl-stance-advanced-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-advanced-nested-title-color, var(--wzl-stance-advanced-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-advanced-nested-title-inset, var(--wzl-stance-advanced-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='debug'] {\n --_s-surface: var(--wzl-stance-debug-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-debug-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-debug-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-debug-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-debug-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-debug-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-debug-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-debug-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-debug-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-debug-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-debug-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-debug-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-debug-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-debug-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-debug-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-debug-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-debug-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='debug'][data-nested] {\n --_s-surface: var(--wzl-stance-debug-nested-surface, var(--wzl-stance-debug-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-debug-nested-border-color, var(--wzl-stance-debug-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-debug-nested-border-style, var(--wzl-stance-debug-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-debug-nested-border-width, var(--wzl-stance-debug-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-debug-nested-radius, var(--wzl-stance-debug-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-debug-nested-pad, var(--wzl-stance-debug-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-debug-nested-blur, var(--wzl-stance-debug-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-debug-nested-tone-mix, var(--wzl-stance-debug-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-debug-nested-tone, var(--wzl-stance-debug-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-debug-nested-accent, var(--wzl-stance-debug-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-debug-nested-title-font, var(--wzl-stance-debug-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-debug-nested-title-weight, var(--wzl-stance-debug-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-debug-nested-title-size, var(--wzl-stance-debug-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-debug-nested-title-case, var(--wzl-stance-debug-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-debug-nested-title-tracking, var(--wzl-stance-debug-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-debug-nested-title-color, var(--wzl-stance-debug-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-debug-nested-title-inset, var(--wzl-stance-debug-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='danger'] {\n --_s-surface: var(--wzl-stance-danger-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-danger-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-danger-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-danger-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-danger-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-danger-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-danger-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-danger-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-danger-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-danger-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-danger-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-danger-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-danger-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-danger-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-danger-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-danger-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-danger-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='danger'][data-nested] {\n --_s-surface: var(--wzl-stance-danger-nested-surface, var(--wzl-stance-danger-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-danger-nested-border-color, var(--wzl-stance-danger-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-danger-nested-border-style, var(--wzl-stance-danger-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-danger-nested-border-width, var(--wzl-stance-danger-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-danger-nested-radius, var(--wzl-stance-danger-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-danger-nested-pad, var(--wzl-stance-danger-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-danger-nested-blur, var(--wzl-stance-danger-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-danger-nested-tone-mix, var(--wzl-stance-danger-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-danger-nested-tone, var(--wzl-stance-danger-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-danger-nested-accent, var(--wzl-stance-danger-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-danger-nested-title-font, var(--wzl-stance-danger-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-danger-nested-title-weight, var(--wzl-stance-danger-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-danger-nested-title-size, var(--wzl-stance-danger-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-danger-nested-title-case, var(--wzl-stance-danger-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-danger-nested-title-tracking, var(--wzl-stance-danger-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-danger-nested-title-color, var(--wzl-stance-danger-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-danger-nested-title-inset, var(--wzl-stance-danger-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='notice'] {\n --_s-surface: var(--wzl-stance-notice-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-notice-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-notice-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-notice-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-notice-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-notice-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-notice-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-notice-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-notice-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-notice-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-notice-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-notice-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-notice-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-notice-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-notice-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-notice-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-notice-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='notice'][data-nested] {\n --_s-surface: var(--wzl-stance-notice-nested-surface, var(--wzl-stance-notice-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-notice-nested-border-color, var(--wzl-stance-notice-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-notice-nested-border-style, var(--wzl-stance-notice-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-notice-nested-border-width, var(--wzl-stance-notice-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-notice-nested-radius, var(--wzl-stance-notice-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-notice-nested-pad, var(--wzl-stance-notice-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-notice-nested-blur, var(--wzl-stance-notice-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-notice-nested-tone-mix, var(--wzl-stance-notice-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-notice-nested-tone, var(--wzl-stance-notice-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-notice-nested-accent, var(--wzl-stance-notice-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-notice-nested-title-font, var(--wzl-stance-notice-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-notice-nested-title-weight, var(--wzl-stance-notice-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-notice-nested-title-size, var(--wzl-stance-notice-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-notice-nested-title-case, var(--wzl-stance-notice-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-notice-nested-title-tracking, var(--wzl-stance-notice-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-notice-nested-title-color, var(--wzl-stance-notice-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-notice-nested-title-inset, var(--wzl-stance-notice-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='important'] {\n --_s-surface: var(--wzl-stance-important-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-important-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-important-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-important-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-important-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-important-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-important-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-important-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-important-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-important-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-important-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-important-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-important-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-important-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-important-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-important-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-important-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='important'][data-nested] {\n --_s-surface: var(--wzl-stance-important-nested-surface, var(--wzl-stance-important-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-important-nested-border-color, var(--wzl-stance-important-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-important-nested-border-style, var(--wzl-stance-important-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-important-nested-border-width, var(--wzl-stance-important-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-important-nested-radius, var(--wzl-stance-important-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-important-nested-pad, var(--wzl-stance-important-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-important-nested-blur, var(--wzl-stance-important-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-important-nested-tone-mix, var(--wzl-stance-important-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-important-nested-tone, var(--wzl-stance-important-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-important-nested-accent, var(--wzl-stance-important-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-important-nested-title-font, var(--wzl-stance-important-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-important-nested-title-weight, var(--wzl-stance-important-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-important-nested-title-size, var(--wzl-stance-important-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-important-nested-title-case, var(--wzl-stance-important-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-important-nested-title-tracking, var(--wzl-stance-important-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-important-nested-title-color, var(--wzl-stance-important-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-important-nested-title-inset, var(--wzl-stance-important-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel[data-stance='preview'] {\n --_s-surface: var(--wzl-stance-preview-surface, var(--wzl-panel-surface));\n --_s-border-color: var(--wzl-stance-preview-border-color, var(--wzl-panel-border-color));\n --_s-border-style: var(--wzl-stance-preview-border-style, var(--wzl-panel-border-style));\n --_s-border-width: var(--wzl-stance-preview-border-width, var(--wzl-panel-border-width));\n --_s-radius: var(--wzl-stance-preview-radius, var(--wzl-panel-radius));\n --_s-pad: var(--wzl-stance-preview-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad)));\n --_s-blur: var(--wzl-stance-preview-blur, var(--wzl-panel-blur));\n --_s-tone-mix: var(--wzl-stance-preview-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-preview-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-preview-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-preview-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-preview-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-preview-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-preview-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-preview-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide)));\n --_s-title-color: var(--wzl-stance-preview-title-color, var(--wzl-fg-muted));\n --_s-title-inset: var(--wzl-stance-preview-title-inset, var(--wzl-panel-title-inset));\n}\n\n.panel[data-stance='preview'][data-nested] {\n --_s-surface: var(--wzl-stance-preview-nested-surface, var(--wzl-stance-preview-surface, var(--wzl-panel-surface)));\n --_s-border-color: var(--wzl-stance-preview-nested-border-color, var(--wzl-stance-preview-border-color, var(--wzl-panel-border-color)));\n --_s-border-style: var(--wzl-stance-preview-nested-border-style, var(--wzl-stance-preview-border-style, var(--wzl-panel-border-style)));\n --_s-border-width: var(--wzl-stance-preview-nested-border-width, var(--wzl-stance-preview-border-width, var(--wzl-panel-border-width)));\n --_s-radius: var(--wzl-stance-preview-nested-radius, var(--wzl-stance-preview-radius, var(--wzl-panel-radius)));\n --_s-pad: var(--wzl-stance-preview-nested-pad, var(--wzl-stance-preview-pad, var(--wzl-prop-panel-pad, var(--wzl-panel-pad))));\n --_s-blur: var(--wzl-stance-preview-nested-blur, var(--wzl-stance-preview-blur, var(--wzl-panel-blur)));\n --_s-tone-mix: var(--wzl-stance-preview-nested-tone-mix, var(--wzl-stance-preview-tone-mix, var(--wzl-panel-tone-mix)));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-preview-nested-tone, var(--wzl-stance-preview-tone, var(--_s-surface))));\n --_s-accent: var(--wzl-stance-preview-nested-accent, var(--wzl-stance-preview-accent, var(--wzl-tone)));\n --_s-title-font: var(--wzl-stance-preview-nested-title-font, var(--wzl-stance-preview-title-font, var(--wzl-font-display)));\n --_s-title-weight: var(--wzl-stance-preview-nested-title-weight, var(--wzl-stance-preview-title-weight, var(--wzl-font-weight-light)));\n --_s-title-size: var(--wzl-stance-preview-nested-title-size, var(--wzl-stance-preview-title-size, var(--wzl-font-size-sm)));\n --_s-title-case: var(--wzl-stance-preview-nested-title-case, var(--wzl-stance-preview-title-case, var(--wzl-params-label-case, uppercase)));\n --_s-title-tracking: var(--wzl-stance-preview-nested-title-tracking, var(--wzl-stance-preview-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wide))));\n --_s-title-color: var(--wzl-stance-preview-nested-title-color, var(--wzl-stance-preview-title-color, var(--wzl-fg-muted)));\n --_s-title-inset: var(--wzl-stance-preview-nested-title-inset, var(--wzl-stance-preview-title-inset, var(--wzl-panel-title-inset)));\n}\n\n.panel {\n --_s-fill: var(--_s-surface);\n}\n\n.panel[data-tone],\n.panel[data-stance] {\n --_s-fill: color-mix(in oklab, var(--_s-tone) var(--_s-tone-mix), var(--_s-surface));\n}\n\n.panel[data-tone] {\n --wzl-accent: var(--_s-accent);\n --wzl-accent-base: var(--_s-accent);\n --wzl-accent-strong: color-mix(in oklab, var(--_s-accent) 70%, var(--wzl-fg));\n --wzl-accent-soft: color-mix(in oklab, var(--_s-accent) 45%, var(--wzl-surface));\n --wzl-accent-hover: var(--wzl-accent-strong);\n --wzl-accent-fg: var(--wzl-accent-strong);\n --wzl-focus-ring: var(--wzl-accent-strong);\n}\n\n/* END GENERATED stance rules: panel */\n\n.list {\n display: grid;\n grid-template-columns: 1fr 1fr;\n column-gap: var(--wzl-prop-column-gap, 16px);\n row-gap: var(--wzl-prop-row-gap, 4px);\n align-items: stretch;\n /* A property panel is dense: its fields are shorter and tighter than a\n standalone Input. Mapped here, on the container, so one declaration moves\n every field in the panel — and read from the container-level name so a\n density set further up is not shadowed by this declaration. */\n --wzl-field-h: var(--wzl-prop-field-h, var(--wzl-control-h-sm));\n --wzl-field-pad-x: var(--wzl-prop-field-pad-x, 6px);\n /* A kit `<Select>` in a row is a field like any other, and its trigger reads\n its height from a standalone control's token rather than the panel's. */\n --wzl-select-h: var(--wzl-field-h);\n}\n\n/* Default packing: only color rows pair, everything else spans full width.\n Scoped to NOT apply in pairs mode (otherwise this 0,2,0 selector beats the\n pairs override below, which is only 0,1,0). */\n.list:not(.listPairs) > :not(.rowColor) {\n grid-column: 1 / -1;\n}\n\n/* `pack=\"pairs\"` flips that: every row auto-places into the 2-col grid two\n per row, and explicit full-width children opt in via the span helper class. */\n.listPairs > * {\n min-width: 0;\n}\n\n.listPairs > .span,\n.listPairs > .subpanel,\n.listPairs > h3 {\n grid-column: 1 / -1;\n}\n\n/* `pack=\"one-up\"` gives every row the full width, color rows included — the\n one packing a palette can be built from. */\n.listOneUp > * {\n grid-column: 1 / -1;\n}\n\n/* ── density ────────────────────────────────────────────────────────\n Preset bundles for the container metrics above. Set on whichever container\n the consumer puts `density` on; every metric inherits down from there, so a\n panel sets the whole family and a single group can still differ. `normal`\n states its values rather than omitting them, so a group can go back to the\n default inside a tighter panel. */\n\n.densityTight {\n --wzl-prop-row-gap: 2px;\n --wzl-prop-subpanel-row-gap: 2px;\n --wzl-prop-column-gap: 8px;\n --wzl-prop-panel-pad: 10px 12px;\n --wzl-prop-panel-title-gap: 8px;\n --wzl-prop-group-pad: 4px 8px 6px;\n --wzl-prop-group-title-gap: 2px;\n --wzl-prop-field-h: 18px;\n --wzl-prop-field-pad-x: 5px;\n}\n\n.densityNormal {\n --wzl-prop-row-gap: 4px;\n --wzl-prop-subpanel-row-gap: 3px;\n --wzl-prop-column-gap: 16px;\n --wzl-prop-panel-pad: 14px 16px;\n --wzl-prop-panel-title-gap: 12px;\n --wzl-prop-group-pad: 6px 10px 8px;\n --wzl-prop-group-title-gap: 4px;\n --wzl-prop-field-h: 20px;\n --wzl-prop-field-pad-x: 6px;\n}\n\n.densityRoomy {\n --wzl-prop-row-gap: 8px;\n --wzl-prop-subpanel-row-gap: 7px;\n --wzl-prop-column-gap: 20px;\n --wzl-prop-panel-pad: 18px 20px;\n --wzl-prop-panel-title-gap: 16px;\n --wzl-prop-group-pad: 10px 14px 12px;\n --wzl-prop-group-title-gap: 6px;\n --wzl-prop-field-h: 24px;\n --wzl-prop-field-pad-x: 8px;\n}\n\n/* ── align ──────────────────────────────────────────────────────────\n Where an inline row's label and control sit on the row's cross axis.\n Inherits like density does, so a column of color rows lines its swatches up\n on one edge from a single declaration on the list.\n\n Two names, because a color row aligns twice: its items within their grid row,\n and the whole grid within the row's box. They agree except at `baseline`,\n which `align-content` does not take — there the grid goes to the top and the\n items find the label's baseline inside it.\n\n A row whose label and control are both one line of text reads a third:\n centering two runs of different sizes leaves their baselines apart, so there\n `center` means `baseline`. */\n\n.alignStart {\n --wzl-prop-row-align: start;\n --wzl-prop-row-align-content: start;\n --wzl-prop-row-align-text: start;\n}\n\n.alignCenter {\n --wzl-prop-row-align: center;\n --wzl-prop-row-align-content: center;\n --wzl-prop-row-align-text: baseline;\n}\n\n.alignEnd {\n --wzl-prop-row-align: end;\n --wzl-prop-row-align-content: end;\n --wzl-prop-row-align-text: end;\n}\n\n.alignBaseline {\n --wzl-prop-row-align: baseline;\n --wzl-prop-row-align-content: start;\n --wzl-prop-row-align-text: baseline;\n}\n\n/* ── Row ────────────────────────────────────────────────────────\n Default shape: label on top (with optional right-aligned readout),\n control below. */\n\n.row {\n display: flex;\n flex-direction: column;\n /* Every row stands on the same floor, whatever it holds. A switch is 16px, a\n range track 12 and a field 20, so a column of mixed rows sets its own line\n spacing row by row and reads as ragged — which is what a reader sees first,\n long before any one control's height. Taller content still grows the row;\n this only stops a short one from collapsing under the field it sits beside. */\n min-height: var(--wzl-prop-row-h, var(--wzl-field-h, var(--wzl-control-h)));\n /* No gap by default — controls sit flush under their label, matching\n speech-balloons `.field { gap: 0 }`. Slider rows pull tighter still\n via a negative margin on the label below. */\n gap: 0;\n min-width: 0;\n}\n\n/* Slider rows: pull the track up under the label so the row reads as one\n tight block rather than a label + a separate horizontal strip. Also\n bottom-align the track within the row so paired rows in a 2-col grid\n keep their tracks lined up even when one label wraps to two lines. */\n/* Stacked rows only: `:has()` carries its argument's specificity, so on an inline\n row this outranks `.rowInline`'s space-between and packs label and track to the\n right edge. */\n.row:not(.rowInline):has(> input[type='range']) {\n justify-content: flex-end;\n}\n\n.row:not(.rowInline):has(> input[type='range']) > .rowLabel {\n /* Baseline-align (not center) so the readout input doesn't inflate the\n label-group height past the text baseline. */\n align-items: baseline;\n gap: var(--wzl-space-2);\n margin-bottom: -4px;\n}\n\n.rowLabel {\n font-family: var(--wzl-font-display);\n font-weight: var(--wzl-font-weight-light);\n font-size: var(--wzl-font-size-sm);\n line-height: var(--wzl-leading-snug);\n color: var(--wzl-fg-muted);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n display: flex;\n align-items: center;\n justify-content: var(--wzl-params-label-align, start);\n gap: var(--wzl-space-3);\n}\n\n/* A label track, only where a row runs label-beside-control: a stacked row's\n label already spans the row, and a width there would narrow it instead. */\n.rowInline > .rowLabel,\n.rowColor:not(.rowBlock) > .rowLabel,\n.rowCheckbox:not(.rowBlock) > .rowLabel {\n inline-size: var(--wzl-params-label-width, auto);\n}\n\n.readout {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n font-size: var(--wzl-font-size-sm);\n line-height: var(--wzl-leading-snug);\n font-style: normal;\n font-weight: var(--wzl-font-weight-medium);\n color: var(--wzl-accent-fg);\n margin-left: auto;\n}\n\n/*\n * An inline row's readout, which the row draws after the control rather than\n * beside the label: its width changes with the value, and anything after it on\n * the row would be shoved sideways on every update.\n */\n.readoutAfter {\n flex: 0 0 auto;\n margin-left: 0;\n}\n\n/* Bare readout text — the word a row shows while it is auto — carrying\n `.readoutInput`'s box, inside `.readoutGroup` just as the input is. The label\n is a baseline-aligned flex line, so anything taller above the baseline drags\n the whole line, label included, down with it: an input's border and padding\n did that for 3.5px on every pin toggle. Both states have to be the same box\n *and* the same nesting, because the group's own strut is 5px of the height. */\n.readoutText {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n display: inline-block;\n /* The input's content box, not its line-height: a text input's inner editor\n will not shrink to a line-height below the font's own content area, so it\n renders 16px of content where a span renders 11px. Stating the height on\n both and filling it here is what makes the two boxes agree. */\n height: var(--wzl-field-h, var(--wzl-control-h-sm));\n line-height: calc(var(--wzl-field-h, var(--wzl-control-h-sm)) - 4px);\n border: 1px solid transparent;\n padding: 1px 0;\n}\n\n/* ⓘ help affordance beside a row label. */\n.help {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.15em;\n height: 1.15em;\n padding: 0;\n border: 0;\n background: none;\n color: var(--wzl-fg-subtle);\n font: inherit;\n font-size: var(--wzl-font-size-sm);\n line-height: 1;\n letter-spacing: normal;\n cursor: help;\n border-radius: var(--wzl-radius-sm);\n}\n\n.help:hover {\n color: var(--wzl-fg);\n border-color: transparent;\n}\n\n.help:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 1px;\n color: var(--wzl-fg);\n}\n\n/* The pinned/auto affordance. Invisible at rest so a panel of thirty rows is\n not thirty dots; revealed by the row, and permanent once the row is auto. */\n/* The row's label is also its pin, so it says so when pointed at — the same\n dotted underline a compact `<Select>` puts under its value. */\n.autoToggle {\n cursor: pointer;\n border-radius: var(--wzl-radius-sm);\n}\n\n/* The same dotted line a compact `<Select>` draws under its value. Stated\n longhand: the shorthand's `auto` thickness takes the font's, which at label\n size closes the gaps and reads as a solid rule. The line takes the label's\n own color — a label is already muted, and a subtler line under it is a 1px\n dotted rule nobody can see. */\n.autoToggle:hover {\n text-decoration: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: 1px;\n text-decoration-color: currentColor;\n text-underline-offset: 0.25em;\n}\n\n.autoToggle:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 2px;\n}\n\n/* Single always-rendered <input> styled to read as a text label until focused. */\n.readoutInput {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n font-size: inherit;\n font-style: inherit;\n font-weight: var(--wzl-font-weight-medium);\n /* Force leading-tight — the label parent inherits 1.2, which would make the\n input box ~3px taller than the speech-balloons reference. */\n line-height: var(--wzl-leading-tight);\n color: var(--wzl-accent-fg);\n background: transparent;\n border: 1px solid transparent;\n border-radius: var(--wzl-radius-sm);\n padding: 1px 0;\n margin: 0;\n /* Stated rather than left to the control's intrinsic size, which `.readoutText`\n cannot reproduce — see the note there. */\n height: var(--wzl-field-h, var(--wzl-control-h-sm));\n /* One width for every readout, so a column of sliders ends on one line; a range whose widest\n value (the fit, in digit-wide `ch`) will not fit it widens its own box. The box is\n border-box, so its border comes back on top, with half a `ch` for a glyph wider than a digit. */\n width: max(\n var(--wzl-property-readout-w, calc(4.5ch + 2px)),\n calc(var(--wzl-property-readout-fit, 0px) + 2px + 0.5ch)\n );\n text-align: right;\n cursor: text;\n outline: none;\n transition: background 80ms ease, border-color 80ms ease;\n -moz-appearance: textfield;\n}\n\n.readoutInput:hover {\n background: color-mix(in srgb, currentColor 8%, transparent);\n}\n\n.readoutInput:focus {\n background: var(--wzl-input-surface, var(--wzl-surface-sunken));\n border-color: var(--wzl-focus-ring);\n}\n\n.readoutInput::-webkit-inner-spin-button,\n.readoutInput::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n/* Inline-block (not flex) so the browser's native vertical-align for\n <sub>/<sup> still works inside — flex collapses baseline semantics\n and sinks superscripts onto the baseline. */\n.readoutGroup {\n display: inline-block;\n white-space: nowrap;\n}\n\n/* Word-style units (e.g. \"px\") read as a small dim suffix next to the digits. */\n.readoutUnit {\n color: var(--wzl-fg-muted);\n font-size: var(--wzl-font-size-2xs);\n line-height: var(--wzl-leading-tight);\n pointer-events: none;\n}\n\n/* An inline row's readout sits between the control and the next cell, so a unit\n beside it would take width from the track. It hangs below the digits instead,\n out of flow, so a row with a unit is the same size as one without. */\n.readoutAfter .readoutGroup {\n position: relative;\n}\n\n.readoutAfter .readoutUnit {\n position: absolute;\n top: 100%;\n right: 1px;\n margin-top: -4px;\n line-height: 1;\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n}\n\n/* A number and its unit, on one line, the field taking what the unit leaves. */\n.fieldUnitGroup {\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n white-space: nowrap;\n min-width: 0;\n}\n\n.fieldUnitGroup > .numberField {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n/* Symbol units (e.g. `<sup>°</sup>`) lean on the browser's native super\n positioning in a readout. Just dim them to match — do NOT set\n line-height: 0, that would re-collapse the glyph onto the baseline. A flex\n item ignores `vertical-align`, so beside a field the glyph rides the top of\n the line instead. */\n.readoutGroup sup,\n.fieldUnitGroup sup {\n color: var(--wzl-fg-muted);\n font-size: var(--wzl-font-size-2xs);\n pointer-events: none;\n}\n\n.fieldUnitGroup > sup {\n align-self: flex-start;\n}\n\n/* ── Inline layout: label sits to the left of the control. ────── */\n.rowInline {\n flex-direction: row;\n align-items: var(--wzl-prop-row-align, center);\n /* Label on the left edge, field on the right: fields of different widths\n still line up as one rail down the column. */\n justify-content: space-between;\n gap: var(--wzl-space-3);\n}\n\n.rowInline .rowLabel {\n /* The label never gives: shrinking it breaks a name like `silhouette_width`\n mid-word, since it carries no break opportunity of its own. The field is\n what yields as the column narrows. */\n flex: 0 0 auto;\n}\n\n/* A row past one line — a textarea or list editor beside the label, or a label\n that wrapped — reads from the top: centering puts the label's first line\n halfway down the control, level with nothing. First baseline sets the label's\n first line on the control's first line of text, and a control with no text\n (a switch, a box) sits on that line the way it does in running text. Outranks\n `align` and the select row's text alignment, which place a one-line row.\n `data-multiline` is measured by the row. */\n.row.rowInline:has(textarea, [role='group'] > ul),\n.row.rowInline[data-multiline],\n.row.rowCheckbox:not(.rowBlock)[data-multiline] {\n align-items: first baseline;\n}\n\n.row.rowColor:not(.rowBlock)[data-multiline] > .rowLabel,\n.row.rowColor:not(.rowBlock)[data-multiline] > input[type='color'],\n.row.rowColor:not(.rowBlock)[data-multiline] > .colorField > :first-child {\n align-self: first baseline;\n}\n\n/* A textarea's baseline is its last line in some engines, so beside one the\n label goes to the top and steps down to the textarea's first line instead. */\n.rowInline:has(textarea) > .rowLabel {\n align-self: flex-start;\n padding-block-start: calc(var(--wzl-space-2) + 1px);\n}\n\n.rowInline > input,\n.rowInline > select,\n.rowInline > .toggleBar {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n/* Fields size to their content, not to the row they happen to sit in: a number\n is a handful of digits and a short string is a word. Stated as a width and\n not as a `min(100%, …)`, because an auto-width sidebar sizes to what its\n fields ask for and a percentage asks for an input's 20-character default.\n Only a field set in the row itself: a surface that wraps its control in a\n slot of its own sizes it there. */\n.row > .numberField,\n.row > .fieldUnitGroup > .numberField {\n flex: 0 1 auto;\n width: var(--wzl-prop-number-width, 9ch);\n max-width: 100%;\n}\n\n.row > .textField {\n width: var(--wzl-prop-text-width, 16ch);\n max-width: 100%;\n}\n\n/* The property rows' fields set their text at the weight the readouts use.\n The attribute outranks the field's own `font: inherit`. */\n.numberField input[type='text'],\n.textField input[type='text'] {\n font-weight: var(--wzl-font-weight-medium);\n}\n\n/* A select is as tall as the fields around it. */\n.select {\n --wzl-select-h: var(--wzl-field-h, var(--wzl-control-h));\n}\n\n/* Set directly in a property row, it drops its box and underlines its value:\n a dense row of settings reads its choices as words, and 10px of caret is a\n tenth of a short value's width. A surface that slots the control in a\n wrapper of its own — a prefs form, an inspector cell — keeps the box. */\n.row > .select {\n --wzl-select-bg: transparent;\n --wzl-select-border: 1px solid transparent;\n --wzl-select-pad: 0;\n --wzl-select-chevron: none;\n --wzl-select-underline: underline;\n --wzl-select-focus-border: transparent;\n --wzl-select-focus-shadow: none;\n --wzl-select-focus-outline: 1px solid var(--wzl-focus-ring);\n}\n\n/* The rules from here to the select are for a native input a caller hands a\n row directly; every field kind draws a kit field that brings its own frame,\n and sits deeper than a child. */\n.row > input[type='number']:not(.readoutInput) {\n width: var(--wzl-prop-number-width, 9ch);\n max-width: 100%;\n -moz-appearance: textfield;\n appearance: textfield;\n}\n\n.row > input[type='text']:not(.readoutInput) {\n width: var(--wzl-prop-text-width, 16ch);\n max-width: 100%;\n}\n\n/* An inline row stays on one line: the field gives up width to the label as the\n column narrows, down to a floor that still shows a value. */\n.rowInline > input:not(.readoutInput),\n.rowInline > .numberField,\n.rowInline > .fieldUnitGroup,\n.rowInline > .textField {\n flex: 0 1 auto;\n min-width: 4ch;\n}\n\n/* Inline, a select fills the space beside its label and sets its value against\n the chevron, like a native one handed to the row. */\n.rowInline > .select {\n flex: 1 1 auto;\n width: auto;\n min-width: 4ch;\n --wzl-select-align: right;\n}\n\n/* Two runs of text on one line read as one line or they read as broken, and\n centering two boxes is not aligning the text in them: a 13px label centered\n against a 15px value left the two baselines 1px apart, which is exactly the\n distance the eye reads as a mistake. Only the rows whose control is text — a\n checkbox or a swatch has no baseline of its own and would hang off the line\n instead. */\n.rowInline:has(> .select) {\n align-items: var(--wzl-prop-row-align-text, baseline);\n}\n\n/* A select sized to its longest option starts wherever that width leaves it, so\n a column of them scatters its values. Filling the row and setting the value\n against the chevron gives them one rail. */\n.rowInline > select {\n flex: 1 1 auto;\n min-width: 4ch;\n text-align: right;\n text-align-last: right;\n}\n\n.rowInline input[type='range'] {\n width: auto;\n}\n\n.row > input[type='text']:not(.readoutInput),\n.row > input[type='number'] {\n background: var(--wzl-input-surface, var(--wzl-surface-sunken));\n color: var(--wzl-fg);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n /* Height is stated rather than padded to, because the display face's line box\n is half again its font size — padding a field to size makes it 27px tall\n around 13px of text and no amount of trimming the padding fixes that. */\n height: var(--wzl-field-h, var(--wzl-control-h));\n padding: 0 var(--wzl-field-pad-x);\n font-family: var(--wzl-font-ui);\n font-weight: var(--wzl-font-weight-medium);\n font-size: var(--wzl-font-size);\n line-height: var(--wzl-leading-tight);\n}\n\n/* Numbers right-align so a column of them shares a decimal position; text does\n not, so this cannot live in the rule the two share. */\n.row > input[type='number'] {\n text-align: right;\n}\n\n/* Chrome reserves the spin-button gutter at the right edge whether or not the\n arrows are painted, so a right-aligned value stops ~20px short of its own\n border and the row reads as if something is missing from that space. The\n panel drives numbers by typing and dragging, never by the steppers.\n `.readoutInput` has always dropped them; this is the same removal for the\n typed field beside it. */\n.row > input[type='number']::-webkit-inner-spin-button,\n.row > input[type='number']::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.row > input[type='text']:not(.readoutInput):focus,\n.row > input[type='number']:focus {\n outline: none;\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n/* A dialog row's trigger reads as a field holding the value's summary, so a\n column of them lines up with the text fields around it. */\n.dialogTrigger {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n width: 100%;\n min-width: 4ch;\n height: var(--wzl-field-h, var(--wzl-control-h));\n padding: 0 var(--wzl-field-pad-x);\n background: var(--wzl-input-surface, var(--wzl-surface-sunken));\n color: var(--wzl-fg);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n font-family: var(--wzl-font-ui);\n font-weight: var(--wzl-font-weight-medium);\n font-size: var(--wzl-font-size);\n line-height: var(--wzl-leading-tight);\n text-align: start;\n cursor: pointer;\n}\n\n.rowInline > .dialogTrigger {\n flex: 1 1 auto;\n width: auto;\n}\n\n.dialogTrigger:hover {\n border-color: var(--wzl-border-strong);\n}\n\n.dialogTrigger:focus-visible {\n outline: none;\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n.dialogSummary {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.dialogGlyph {\n flex: 0 0 auto;\n color: var(--wzl-fg-subtle);\n}\n\n/* A native select handed to a row renders borderless — chevron only,\n transparent background, no chrome. Keep the native arrow via appearance: auto\n so users still see something clickable. */\n.row > select {\n background: transparent;\n color: var(--wzl-fg);\n border: 0;\n border-radius: 0;\n height: var(--wzl-field-h, var(--wzl-control-h));\n padding: 0;\n font-family: var(--wzl-font-ui);\n font-weight: var(--wzl-font-weight-medium);\n font-size: var(--wzl-font-size);\n line-height: var(--wzl-leading-tight);\n cursor: pointer;\n}\n\n/* An outline rather than the boxed family's inset ring: a property-row select\n is borderless, so there is no border to recolour. */\n.row > select:focus {\n outline: 1px solid var(--wzl-focus-ring);\n outline-offset: 2px;\n}\n\n/* ── Color variant: label and swatch side-by-side, two per row in the grid.\n Switches to a 2-row grid when an alpha slider is rendered beneath. */\n/* `align-content: end` sinks the whole grid so a color row paired with a\n taller sibling keeps its alpha track on the neighbour's bottom edge. An\n explicit `align` overrides both that and the per-item alignment below, which\n is what a column of swatches read as a group needs. */\n.rowColor {\n display: grid;\n grid-template-columns: 1fr auto;\n grid-template-rows: auto;\n align-content: var(--wzl-prop-row-align-content, end);\n column-gap: var(--wzl-space-4);\n row-gap: 0;\n min-width: 0;\n}\n\n.rowColor .rowLabel {\n grid-column: 1;\n grid-row: 1;\n align-self: var(--wzl-prop-row-align, center);\n flex: initial;\n min-width: 0;\n}\n\n/* Padding: 0 is important — the native <input type=\"color\"> in some browsers (esp. Chrome) inflates beyond its\n declared box when given padding, which expands the grid row and pushes\n the paired slider track out of bottom alignment. */\n.rowColor > input[type='color'] {\n grid-column: 2;\n grid-row: 1;\n align-self: var(--wzl-prop-row-align, center);\n box-sizing: border-box;\n width: 36px;\n height: var(--wzl-control-h-xs);\n background: transparent;\n border: 0;\n border-radius: var(--wzl-radius-sm);\n padding: 0;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n/* A color field set directly in the row gives its parts to the row's grid:\n the swatch beside the label, and the opacity track with its readout on a\n second row beneath. Nested in another wrapper, it keeps its own line. */\n.rowColor > .colorField {\n display: contents;\n}\n\n.rowColor > .colorField > :first-child {\n grid-column: 2;\n grid-row: 1;\n align-self: var(--wzl-prop-row-align, center);\n justify-self: end;\n}\n\n.rowColor > .colorField > input[type='range'] {\n grid-column: 1;\n grid-row: 2;\n}\n\n.rowColor > .colorField > :last-child:not(:first-child):not(input) {\n grid-column: 2;\n grid-row: 2;\n align-self: center;\n}\n\n/* `layout=\"block\"` stacks the color row: label, then swatch, then alpha. */\n.rowColor.rowBlock {\n grid-template-columns: 1fr;\n}\n\n.rowColor.rowBlock .rowLabel {\n grid-column: 1;\n grid-row: 1;\n}\n\n.rowColor.rowBlock > input[type='color'],\n.rowColor.rowBlock > .colorField > :first-child {\n grid-column: 1;\n grid-row: 2;\n justify-self: start;\n}\n\n.rowColor.rowBlock > .colorField > input[type='range'] {\n grid-row: 3;\n}\n\n/* A block row has one column, so the readout rides at the track's end. */\n.rowColor.rowBlock > .colorField > :last-child:not(:first-child):not(input) {\n grid-column: 1;\n grid-row: 3;\n justify-self: end;\n}\n\n/* ── Checkbox variant: label-first inline layout. */\n.rowCheckbox {\n flex-direction: row;\n align-items: var(--wzl-prop-row-align, center);\n /* Label on the leading edge and box on the trailing one, like every other\n inline row: a column of settings is read down its labels, and a box that\n leads its own row puts each label at a different indent. */\n justify-content: space-between;\n gap: var(--wzl-space-4);\n cursor: pointer;\n}\n\n.rowCheckbox > input[type='checkbox']:not([role='switch']) {\n accent-color: var(--wzl-accent);\n width: 14px;\n height: 14px;\n cursor: pointer;\n}\n\n/* `layout=\"block\"` stacks the checkbox row: label above, box beneath, both on\n the leading edge — a block row's cross axis is the horizontal one. */\n.rowCheckbox.rowBlock {\n flex-direction: column;\n align-items: var(--wzl-prop-row-align, start);\n}\n\n\n/* A state the control cannot draw itself: a switch has no indeterminate form,\n and nothing has an \"unset\" one. */\n.dimmed {\n opacity: 0.55;\n}\n\n/* A slider cell's readout, beside its track rather than in a row's label line.\n Doubled so a row laying its cells out evenly does not stretch it. */\n.cellReadout.cellReadout {\n flex: none;\n min-inline-size: 3ch;\n text-align: end;\n}\n\n.textarea {\n width: 100%;\n padding: var(--wzl-space-2) var(--wzl-space-4);\n background: var(--wzl-input-surface, var(--wzl-surface-sunken));\n color: var(--wzl-fg);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n font: inherit;\n font-size: var(--wzl-font-size-sm);\n resize: vertical;\n}\n\n/* ── Segmented toggle ─────────────────────────────────────────────\n A `ToggleBar`, filling the row the way a field does and standing at the\n row's field height rather than its own small size. */\n.row > .toggleBar {\n display: flex;\n width: 100%;\n height: var(--wzl-field-h, var(--wzl-control-h));\n}\n\n/* ── PropertyGroup ──────────────────────────────────────────────────\n Bordered, sunken section inside a list. */\n.group {\n grid-column: 1 / -1;\n background: var(--_s-fill);\n border: var(--_s-border-width) var(--_s-border-style) var(--_s-border-color);\n border-radius: var(--_s-radius);\n padding: var(--_s-pad);\n}\n\n/* A toned group is one of a list of like groups; its edge says which. */\n.group[data-tone] {\n border-left: 4px solid var(--wzl-tone);\n}\n\n.groupHeadRow {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n margin: 0 0 var(--wzl-prop-group-title-gap, 4px);\n}\n\n/* The row takes the title's bottom margin, so the handle and actions center on the title itself. */\n.groupHeadRow > .groupTitle {\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n}\n\n.groupLeading,\n.groupActions {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n}\n\n/* BEGIN GENERATED stance rules: group — `npm run gen:stances`, do not edit. */\n\n.group {\n --wzl-tone: initial;\n}\n\n.group {\n --_s-surface: var(--wzl-surface-sunken);\n --_s-border-color: var(--wzl-border);\n --_s-border-style: solid;\n --_s-border-width: 0px;\n --_s-radius: var(--wzl-radius-md);\n --_s-pad: var(--wzl-prop-group-pad, 6px 10px 8px);\n --_s-tone-mix: var(--wzl-panel-tone-mix);\n --_s-tone: var(--wzl-tone, var(--_s-surface));\n --_s-accent: var(--wzl-tone);\n --_s-title-font: var(--wzl-font-display);\n --_s-title-weight: var(--wzl-font-weight-light);\n --_s-title-size: var(--wzl-font-size-sm);\n --_s-title-case: var(--wzl-params-label-case, uppercase);\n --_s-title-tracking: var(--wzl-params-label-tracking, var(--wzl-tracking-wider));\n --_s-title-color: var(--wzl-fg-subtle);\n}\n\n.group[data-stance='scope'] {\n --_s-surface: var(--wzl-stance-scope-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-scope-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-scope-border-style, solid);\n --_s-border-width: var(--wzl-stance-scope-border-width, 0px);\n --_s-radius: var(--wzl-stance-scope-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-scope-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-scope-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-scope-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-scope-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-scope-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-scope-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-scope-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-scope-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-scope-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-scope-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='aside'] {\n --_s-surface: var(--wzl-stance-aside-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-aside-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-aside-border-style, solid);\n --_s-border-width: var(--wzl-stance-aside-border-width, 0px);\n --_s-radius: var(--wzl-stance-aside-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-aside-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-aside-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-aside-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-aside-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-aside-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-aside-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-aside-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-aside-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-aside-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-aside-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='advanced'] {\n --_s-surface: var(--wzl-stance-advanced-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-advanced-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-advanced-border-style, solid);\n --_s-border-width: var(--wzl-stance-advanced-border-width, 0px);\n --_s-radius: var(--wzl-stance-advanced-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-advanced-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-advanced-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-advanced-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-advanced-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-advanced-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-advanced-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-advanced-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-advanced-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-advanced-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-advanced-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='debug'] {\n --_s-surface: var(--wzl-stance-debug-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-debug-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-debug-border-style, solid);\n --_s-border-width: var(--wzl-stance-debug-border-width, 0px);\n --_s-radius: var(--wzl-stance-debug-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-debug-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-debug-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-debug-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-debug-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-debug-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-debug-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-debug-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-debug-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-debug-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-debug-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='danger'] {\n --_s-surface: var(--wzl-stance-danger-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-danger-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-danger-border-style, solid);\n --_s-border-width: var(--wzl-stance-danger-border-width, 0px);\n --_s-radius: var(--wzl-stance-danger-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-danger-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-danger-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-danger-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-danger-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-danger-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-danger-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-danger-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-danger-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-danger-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-danger-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='notice'] {\n --_s-surface: var(--wzl-stance-notice-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-notice-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-notice-border-style, solid);\n --_s-border-width: var(--wzl-stance-notice-border-width, 0px);\n --_s-radius: var(--wzl-stance-notice-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-notice-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-notice-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-notice-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-notice-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-notice-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-notice-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-notice-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-notice-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-notice-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-notice-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='important'] {\n --_s-surface: var(--wzl-stance-important-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-important-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-important-border-style, solid);\n --_s-border-width: var(--wzl-stance-important-border-width, 0px);\n --_s-radius: var(--wzl-stance-important-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-important-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-important-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-important-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-important-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-important-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-important-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-important-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-important-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-important-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-important-title-color, var(--wzl-fg-subtle));\n}\n\n.group[data-stance='preview'] {\n --_s-surface: var(--wzl-stance-preview-surface, var(--wzl-surface-sunken));\n --_s-border-color: var(--wzl-stance-preview-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-preview-border-style, solid);\n --_s-border-width: var(--wzl-stance-preview-border-width, 0px);\n --_s-radius: var(--wzl-stance-preview-radius, var(--wzl-radius-md));\n --_s-pad: var(--wzl-stance-preview-pad, var(--wzl-prop-group-pad, 6px 10px 8px));\n --_s-tone-mix: var(--wzl-stance-preview-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-preview-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-preview-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-preview-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-preview-title-weight, var(--wzl-font-weight-light));\n --_s-title-size: var(--wzl-stance-preview-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-preview-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-preview-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-preview-title-color, var(--wzl-fg-subtle));\n}\n\n.group {\n --_s-fill: var(--_s-surface);\n}\n\n.group[data-tone],\n.group[data-stance] {\n --_s-fill: color-mix(in oklab, var(--_s-tone) var(--_s-tone-mix), var(--_s-surface));\n}\n\n.group[data-tone] {\n --wzl-accent: var(--_s-accent);\n --wzl-accent-base: var(--_s-accent);\n --wzl-accent-strong: color-mix(in oklab, var(--_s-accent) 70%, var(--wzl-fg));\n --wzl-accent-soft: color-mix(in oklab, var(--_s-accent) 45%, var(--wzl-surface));\n --wzl-accent-hover: var(--wzl-accent-strong);\n --wzl-accent-fg: var(--wzl-accent-strong);\n --wzl-focus-ring: var(--wzl-accent-strong);\n}\n\n/* END GENERATED stance rules: group */\n\n/* Group help text: spans the grid, sits above the rows it describes. */\n.note {\n grid-column: 1 / -1;\n margin: 0 0 var(--wzl-prop-group-title-gap, 4px);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n line-height: 1.35;\n}\n\n.groupTitle {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n gap: var(--wzl-space-4);\n margin: 0 0 var(--wzl-prop-group-title-gap, 4px);\n font-family: var(--_s-title-font);\n font-weight: var(--_s-title-weight);\n font-size: var(--_s-title-size);\n letter-spacing: var(--_s-title-tracking);\n text-transform: var(--_s-title-case);\n color: var(--_s-title-color);\n}\n\n.groupTitle hr {\n border: 0;\n border-top: 1px solid var(--_s-border-color);\n margin: 0;\n}\n\n/* The title between the rules. The twisty hangs off the text's leading edge,\n out of flow, so the text centers as though it were not there. */\n.groupTitleMid {\n position: relative;\n min-width: 0;\n}\n\n/* Being out of flow, the twisty would sit on the leading rule; the rule stops at its box instead. */\n.groupTitle:has(> .groupTitleMid > .groupTwisty) > hr:first-child {\n margin-inline-end: calc(\n var(--wzl-disclosure-target, var(--wzl-control-h-sm)) + var(--wzl-disclosure-gap, 4px) - var(--wzl-space-4)\n );\n}\n\n.groupTwisty {\n position: absolute;\n inset-inline-end: calc(100% + var(--wzl-disclosure-gap, 4px));\n top: 50%;\n translate: 0 -50%;\n}\n\n/* `hidden` on its own loses to the body's `display: grid` below. */\n.groupBody[hidden] {\n display: none;\n}\n\n.groupBody {\n display: grid;\n grid-template-columns: 1fr 1fr;\n column-gap: var(--wzl-prop-column-gap, 16px);\n row-gap: var(--wzl-prop-row-gap, 4px);\n /* Stretch so paired rows match in height — slider rows then bottom-align\n their tracks (via `margin-top: auto`) and stay lined up even when one\n sibling's label wraps to two lines. */\n align-items: stretch;\n}\n\n.group:not(.groupPairs) .groupBody > :not(.rowColor) {\n grid-column: 1 / -1;\n}\n\n.groupPairs .groupBody > * {\n grid-column: auto;\n}\n\n.groupPairs .groupBody > h3,\n.groupPairs .groupBody > .span {\n grid-column: 1 / -1;\n}\n\n.groupOneUp .groupBody > * {\n grid-column: 1 / -1;\n}\n\n/* ── Subpanel ────────────────────────────────────────────────────────\n Headered group of controls inside a list. The header is a typographic\n label flanked by a horizontal rule — no card chrome, just the divider. */\n.subpanel {\n display: grid;\n grid-template-columns: 1fr 1fr;\n column-gap: var(--wzl-prop-column-gap, 16px);\n row-gap: var(--wzl-prop-subpanel-row-gap, 3px);\n align-items: stretch;\n background: transparent;\n border: 0;\n padding: 0;\n margin: 0;\n}\n\n/* BEGIN GENERATED stance rules: subpanel — `npm run gen:stances`, do not edit. */\n\n.subpanel {\n --wzl-tone: initial;\n}\n\n.subpanel {\n --_s-border-color: var(--wzl-line-subtle);\n --_s-accent: var(--wzl-tone);\n --_s-title-font: var(--wzl-font-display);\n --_s-title-weight: var(--wzl-font-weight-medium);\n --_s-title-size: var(--wzl-font-size-sm);\n --_s-title-case: var(--wzl-params-label-case, uppercase);\n --_s-title-tracking: var(--wzl-params-label-tracking, var(--wzl-tracking-wider));\n --_s-title-color: var(--wzl-fg);\n}\n\n.subpanel[data-stance='scope'] {\n --_s-border-color: var(--wzl-stance-scope-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-scope-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-scope-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-scope-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-scope-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-scope-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-scope-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-scope-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='aside'] {\n --_s-border-color: var(--wzl-stance-aside-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-aside-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-aside-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-aside-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-aside-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-aside-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-aside-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-aside-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='advanced'] {\n --_s-border-color: var(--wzl-stance-advanced-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-advanced-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-advanced-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-advanced-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-advanced-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-advanced-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-advanced-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-advanced-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='debug'] {\n --_s-border-color: var(--wzl-stance-debug-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-debug-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-debug-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-debug-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-debug-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-debug-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-debug-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-debug-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='danger'] {\n --_s-border-color: var(--wzl-stance-danger-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-danger-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-danger-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-danger-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-danger-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-danger-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-danger-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-danger-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='notice'] {\n --_s-border-color: var(--wzl-stance-notice-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-notice-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-notice-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-notice-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-notice-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-notice-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-notice-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-notice-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='important'] {\n --_s-border-color: var(--wzl-stance-important-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-important-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-important-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-important-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-important-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-important-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-important-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-important-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-stance='preview'] {\n --_s-border-color: var(--wzl-stance-preview-border-color, var(--wzl-line-subtle));\n --_s-accent: var(--wzl-stance-preview-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-preview-title-font, var(--wzl-font-display));\n --_s-title-weight: var(--wzl-stance-preview-title-weight, var(--wzl-font-weight-medium));\n --_s-title-size: var(--wzl-stance-preview-title-size, var(--wzl-font-size-sm));\n --_s-title-case: var(--wzl-stance-preview-title-case, var(--wzl-params-label-case, uppercase));\n --_s-title-tracking: var(--wzl-stance-preview-title-tracking, var(--wzl-params-label-tracking, var(--wzl-tracking-wider)));\n --_s-title-color: var(--wzl-stance-preview-title-color, var(--wzl-fg));\n}\n\n.subpanel[data-tone] {\n --wzl-accent: var(--_s-accent);\n --wzl-accent-base: var(--_s-accent);\n --wzl-accent-strong: color-mix(in oklab, var(--_s-accent) 70%, var(--wzl-fg));\n --wzl-accent-soft: color-mix(in oklab, var(--_s-accent) 45%, var(--wzl-surface));\n --wzl-accent-hover: var(--wzl-accent-strong);\n --wzl-accent-fg: var(--wzl-accent-strong);\n --wzl-focus-ring: var(--wzl-accent-strong);\n}\n\n/* END GENERATED stance rules: subpanel */\n\n.subpanel > * {\n min-width: 0;\n}\n\n.subpanel > .subpanelTitle,\n.subpanel > .span {\n grid-column: 1 / -1;\n}\n\n.subpanelTitle {\n font-family: var(--_s-title-font);\n font-weight: var(--_s-title-weight);\n font-size: var(--_s-title-size);\n line-height: var(--wzl-leading-tight);\n color: var(--_s-title-color);\n text-transform: var(--_s-title-case);\n letter-spacing: var(--_s-title-tracking);\n margin: 0;\n padding: var(--wzl-space-3) 0 var(--wzl-space-2);\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n}\n\n.subpanelTitle > span {\n flex: 0 0 auto;\n}\n\n.subpanelTitle > hr {\n flex: 1 1 auto;\n border: 0;\n border-top: 1px solid var(--_s-border-color);\n margin: 0;\n}\n\n/* An auto row: the value is not pinned, and the row says only that. The\n control is hidden rather than removed, so the row keeps the height and the\n width it has while pinned and nothing below it moves on the toggle —\n `visibility` and not `opacity`, because a hidden control must also be out of\n reach of the pointer and the tab ring. The label and the readout are what\n stays: everything else in the row is the control. */\n.rowAuto > :not(.rowLabel):not(.readout) {\n visibility: hidden;\n}\n\n.rowAuto > .rowLabel {\n color: var(--wzl-fg-subtle);\n}\n\n/* An auto row that keeps drawing its control: the value is the one it inherits,\n shown faded so it reads as not chosen here. */\n.rowAutoDimmed > :not(.rowLabel) {\n opacity: 0.55;\n}\n\n/* Where an inherited value comes from, after the label. */\n.rowHint {\n font-size: var(--wzl-font-size-2xs);\n color: var(--wzl-fg-subtle);\n white-space: nowrap;\n}\n\n/* A stacked row's readout sits inside the label and an inline row's sits after\n the control, so the label's case reached one and not the other: the same word\n read `AUTO` in one row and `auto` in the next. An auto row's readout is a\n word, not a number, so it takes the label recipe and both rows read alike. */\n.rowAuto .readout {\n font-size: var(--wzl-font-size-xs);\n color: var(--wzl-secondary-fg);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n}\n","import {\n createContext,\n forwardRef,\n type ReactNode,\n type Ref,\n type RefObject,\n useContext,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { type StanceProps, useStance } from '../stance';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport s from './Properties.module.css';\n\n/**\n * How much room a container gives its rows — gaps, padding, and field height,\n * moved together. Set on any container in the family; it reaches every\n * descendant, so an inner group can differ from the panel around it.\n */\nexport type PropertyDensity = 'tight' | 'normal' | 'roomy';\n\n/** Where an inline row's label and control sit on the row's cross axis. Set on\n * a container to line a whole column of them up. */\nexport type PropertyAlign = 'start' | 'center' | 'end' | 'baseline';\n\n/** Metric props every container in the family takes. Both reach descendants,\n * so the nearest container that states one wins. */\nexport interface PropertyMetricProps {\n /** Room the rows get. Unset inherits from an outer container, else `normal`. */\n density?: PropertyDensity;\n /**\n * Cross-axis alignment of an inline row's label and control. `baseline` sits\n * the control on the label's first-line baseline, which is what lines a\n * column of swatches up against labels of different heights. Unset keeps each\n * variant's own alignment — a color row centers its label and swatch and\n * sinks the pair to the row's bottom edge, which keeps a paired alpha track\n * level with its neighbour.\n */\n align?: PropertyAlign;\n}\n\nconst DENSITY_CLASS: Record<PropertyDensity, string> = {\n tight: s.densityTight,\n normal: s.densityNormal,\n roomy: s.densityRoomy,\n};\n\nconst ALIGN_CLASS: Record<PropertyAlign, string> = {\n start: s.alignStart,\n center: s.alignCenter,\n end: s.alignEnd,\n baseline: s.alignBaseline,\n};\n\n/** Joins a container's base class with its metric classes and the consumer's.\n * Exported for the family's other files, which share the same two props. */\nexport function propertyMetricClass(\n base: string,\n { density, align }: PropertyMetricProps,\n className?: string,\n): string {\n return [base, density && DENSITY_CLASS[density], align && ALIGN_CLASS[align], className]\n .filter(Boolean)\n .join(' ');\n}\n\n/** Props for `<PropertyPanel>`. */\nexport interface PropertyPanelProps extends PropertyMetricProps, StanceProps {\n title?: ReactNode;\n /** Controls on the trailing edge of the title row — a switch, a clear\n * button. They sit outside the heading, so they neither take its type nor\n * join its accessible name. */\n actions?: ReactNode;\n /**\n * Lets text inside the panel be selected and copied. A panel is chrome by\n * default, so a drag across it moves a slider rather than painting a\n * selection; a `debug` panel defaults to selectable, since what it shows —\n * ids, keys, traces — is there to be copied.\n */\n selectable?: boolean;\n children: ReactNode;\n className?: string;\n}\n\nconst PanelNesting = createContext(false);\n\n/**\n * A titled panel holding property rows — the sidebar container the rest of\n * this module's components fill.\n *\n * `stance` says what kind of content it holds and `tone` which of its peers it\n * is; the theme's `--wzl-panel-*` and `--wzl-stance-*` slots decide how each looks. A stanced\n * panel's title takes the row-label recipe rather than the display title.\n */\nexport function PropertyPanel({\n title,\n actions,\n selectable,\n children,\n className,\n density,\n align,\n stance,\n tone,\n}: PropertyPanelProps) {\n const nested = useContext(PanelNesting);\n const attrs = useStance({ stance, tone });\n const heading = title != null && <h2 className={s.panelTitle}>{title}</h2>;\n return (\n <div\n className={propertyMetricClass(s.panel, { density, align }, className)}\n {...attrs}\n data-nested={nested || undefined}\n data-selectable={(selectable ?? stance === 'debug') || undefined}\n >\n {actions != null ? (\n <div className={s.panelHeader}>\n {heading}\n <div className={s.panelActions}>{actions}</div>\n </div>\n ) : heading}\n <PanelNesting.Provider value>{children}</PanelNesting.Provider>\n </div>\n );\n}\n\n/** How a property list packs its rows into two columns. */\nexport type PropertyListPack = 'auto-color' | 'pairs' | 'one-up';\n\n/** Props for `<PropertyList>`. */\nexport interface PropertyListProps extends PropertyMetricProps {\n children: ReactNode;\n className?: string;\n /**\n * How rows pack into the 2-column grid.\n * - `'auto-color'` (default): only color rows pair side-by-side; everything\n * else spans the full width. Right for sparse top-level panels.\n * - `'pairs'`: every row auto-places into the 2-column grid two-per-row.\n * Headers and subpanels still span the full width; wrap any other\n * full-width child in `<PropertySpan>`. Right for dense effect bodies.\n * - `'one-up'`: every row spans the full width, color rows included. Right\n * for a palette — a column of swatches read as a group.\n */\n pack?: PropertyListPack;\n}\n\n/**\n * Grid container for PropertyRows. Use standalone for chrome-less layouts, or\n * nest inside <PropertyPanel/> for the standard glass card.\n */\nexport const PropertyList = forwardRef(function PropertyList(\n { children, className, pack = 'auto-color', density, align }: PropertyListProps,\n ref: Ref<HTMLDivElement>,\n) {\n const base = `${s.list}${pack === 'pairs' ? ` ${s.listPairs}` : pack === 'one-up' ? ` ${s.listOneUp}` : ''}`;\n return (\n <div ref={ref} className={propertyMetricClass(base, { density, align }, className)}>\n {children}\n </div>\n );\n});\n\n/** Props for `<PropertySpan>`. */\nexport interface PropertySpanProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Wrapper that makes an arbitrary child span both columns of a\n * `<PropertyList pack=\"pairs\">`, a `<PropertyGroup pack=\"pairs\">` body, or a\n * `<Subpanel>`. `<PropertyRow span>` covers the row case; this covers\n * everything else a consumer puts in the grid.\n */\nexport function PropertySpan({ children, className }: PropertySpanProps) {\n return <div className={className ? `${s.span} ${className}` : s.span}>{children}</div>;\n}\n\n/** Props for `<PropertyNote>`. */\nexport interface PropertyNoteProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Muted paragraph that spans both columns of the grid — a group's help text,\n * sitting above the rows it describes rather than beside one of them.\n * `<PropertyRow description>` covers the per-row case.\n */\nexport function PropertyNote({ children, className }: PropertyNoteProps) {\n return <p className={className ? `${s.note} ${className}` : s.note}>{children}</p>;\n}\n\n/** Which control shape a row holds, which decides its intrinsic layout. */\nexport type PropertyRowVariant = 'default' | 'color' | 'checkbox';\n/** Whether a row's label sits above its control or beside it. */\nexport type PropertyRowLayout = 'block' | 'inline';\n\n/** Props for `<PropertyRow>`. */\nexport interface PropertyRowProps extends PropertyMetricProps {\n label: ReactNode;\n /** Right-aligned readout shown next to the label (e.g. current value). */\n readout?: ReactNode;\n /**\n * Help text for the row, shown in a tooltip off an ⓘ affordance beside the\n * label. Empty or absent renders no affordance.\n */\n description?: string;\n variant?: PropertyRowVariant;\n /**\n * Label position relative to the control. Unset takes the variant's own\n * orientation: `block` — label above control — for the default variant, and\n * `inline` for the color and checkbox variants, which read as a row.\n */\n layout?: PropertyRowLayout;\n /**\n * Take the full width of the enclosing grid. Only has an effect inside a\n * `<PropertyList pack=\"pairs\">` or a `<Subpanel>`; elsewhere rows are already\n * full width.\n */\n span?: boolean;\n children: ReactNode;\n htmlFor?: string;\n /** The control is a group of several (a segmented toggle), not one element.\n * The row then renders as a `<div>`: a `<label>` hands a click on its text to\n * its first control, which in a group means selecting the first option. Each\n * member has to carry its own name. */\n group?: boolean;\n className?: string;\n /** The row is auto: its value is not pinned and the owner computes it. The\n * control is hidden — its box kept, so the row does not resize — and the\n * row reads out the word instead. */\n auto?: boolean;\n /** Given, the row's label toggles `auto` when it is clicked. Omitted, the row\n * can show an auto state but not change it.\n *\n * The label then names that toggle, so a control passed as `children` has to\n * carry its own accessible name — every `<PropertyField>` does. */\n onAutoChange?: (next: boolean) => void;\n /** What an auto row does with its control. `'hidden'` (the default) keeps its\n * box and reads out the word instead; `'dimmed'` keeps drawing it, faded, for\n * an owner that passes the value the row inherits and pins on any edit. */\n autoControl?: 'hidden' | 'dimmed';\n /** Small muted text after the label — where an inherited value comes from. */\n hint?: ReactNode;\n}\n\n/** The label-plus-control frame `<PropertyField>` draws its rows in. Use it\n * directly for a control no field kind covers. */\nexport function PropertyRow({\n label,\n readout,\n description,\n variant = 'default',\n layout,\n span,\n children,\n htmlFor,\n group,\n className,\n density,\n align,\n auto,\n onAutoChange,\n autoControl = 'hidden',\n hint,\n}: PropertyRowProps) {\n const variantClass = variant === 'color' ? s.rowColor : variant === 'checkbox' ? s.rowCheckbox : '';\n // Each variant already lays out one way; a class is only needed for the\n // other one. The default variant stacks, so it needs `.rowInline`; color and\n // checkbox read as a row, so they need `.rowBlock`.\n const intrinsic: PropertyRowLayout = variant === 'default' ? 'block' : 'inline';\n const resolved = layout ?? intrinsic;\n const layoutClass =\n resolved === intrinsic ? '' : resolved === 'inline' ? s.rowInline : s.rowBlock;\n const cls = propertyMetricClass(\n [\n s.row,\n variantClass,\n layoutClass,\n span && s.span,\n auto && (autoControl === 'dimmed' ? s.rowAutoDimmed : s.rowAuto),\n ]\n .filter(Boolean)\n .join(' '),\n { density, align },\n className,\n );\n // A stacked row reads label, readout, control down the column, so its readout\n // belongs on the label line. An inline row would put a value of changing width\n // in front of the control, which then moves under the pointer as it changes.\n const trailing = resolved === 'inline' && readout != null;\n const rowRef = useRef<HTMLElement | null>(null);\n const labelRef = useRef<HTMLSpanElement | null>(null);\n const multiline = useMultiline(rowRef, labelRef, resolved === 'inline');\n const head = (\n <span className={s.rowLabel} ref={labelRef}>\n {onAutoChange ? (\n <AutoToggle auto={auto ?? false} label={label} onChange={onAutoChange} />\n ) : (\n label\n )}\n {hint != null && <span className={s.rowHint}>{hint}</span>}\n {description ? <PropertyHelp label={label} description={description} /> : null}\n {readout != null && !trailing && <em className={s.readout}>{readout}</em>}\n </span>\n );\n const tail = trailing ? <em className={`${s.readout} ${s.readoutAfter}`}>{readout}</em> : null;\n const multi = multiline ? { 'data-multiline': '' } : {};\n return group ? (\n <div className={cls} ref={rowRef as RefObject<HTMLDivElement>} {...multi}>\n {head}\n {children}\n {tail}\n </div>\n ) : (\n <label\n className={cls}\n htmlFor={htmlFor}\n ref={rowRef as RefObject<HTMLLabelElement>}\n {...multi}\n >\n {head}\n {children}\n {tail}\n </label>\n );\n}\n\n/**\n * Whether an inline row runs past one line — its label wraps, or a child is\n * taller than a field. CSS can name the tall controls it knows (`:has()`), but\n * not a label that wrapped at this width, so the row measures. Never set\n * without layout, so jsdom always reads single-line.\n */\nfunction useMultiline(\n rowRef: RefObject<HTMLElement | null>,\n labelRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n): boolean {\n const [multiline, setMultiline] = useState(false);\n useLayoutEffect(() => {\n const row = rowRef.current;\n const label = labelRef.current;\n if (!enabled || !row || !label || typeof ResizeObserver === 'undefined') {\n setMultiline(false);\n return;\n }\n const measure = (): void => {\n const labelStyle = getComputedStyle(label);\n const lineHeight =\n Number.parseFloat(labelStyle.lineHeight) ||\n Number.parseFloat(labelStyle.fontSize) * 1.2;\n const floor = Number.parseFloat(getComputedStyle(row).minHeight) || lineHeight;\n const labelWraps = label.getBoundingClientRect().height > lineHeight * 1.5;\n const tallChild = Array.from(row.children).some(\n (child) => child !== label && child.getBoundingClientRect().height > floor * 1.5,\n );\n setMultiline(labelWraps || tallChild);\n };\n const observer = new ResizeObserver(measure);\n observer.observe(row);\n observer.observe(label);\n for (const child of Array.from(row.children)) observer.observe(child);\n return () => observer.disconnect();\n }, [rowRef, labelRef, enabled]);\n return multiline;\n}\n\n/**\n * A row's label, doubling as the control for whether the row is auto: clicking\n * it hands the value back to whoever computes it, or takes it back.\n *\n * Pressed means pinned, to match the name — an auto row is the unpressed one.\n */\nfunction AutoToggle({\n auto,\n label,\n onChange,\n}: {\n auto: boolean;\n label: ReactNode;\n onChange: (next: boolean) => void;\n}) {\n const name = typeof label === 'string' ? label : 'this setting';\n const toggle = (e: { preventDefault: () => void; stopPropagation: () => void }) => {\n // The wrapping <label> would otherwise actuate the row's control.\n e.preventDefault();\n e.stopPropagation();\n onChange(!auto);\n };\n return (\n // A span, not a button: a <button> is a labelable element, so inside the\n // row's <label> it would take the row's name off the actual control.\n <span\n role=\"button\"\n tabIndex={0}\n className={s.autoToggle}\n aria-pressed={!auto}\n aria-label={`Pin ${name}`}\n onClick={toggle}\n onKeyDown={(e) => {\n // A native button gives Enter and Space for free; a span gives neither,\n // and Space would scroll the panel.\n if (e.key === 'Enter' || e.key === ' ') toggle(e);\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {label}\n </span>\n );\n}\n\n/** Props for `<PropertyHelp>`. */\nexport interface PropertyHelpProps {\n /** What the help is about; a string names the button `About <label>`. */\n label: ReactNode;\n description: string;\n}\n\n/** The ⓘ beside a row label that shows its `description` in a tooltip. Exported\n * for surfaces that draw a params label outside a `<PropertyRow>`. A tooltip\n * trigger has to be interactive to be keyboard-reachable, so this is a real\n * button. */\nexport function PropertyHelp({ label, description }: PropertyHelpProps) {\n const name = typeof label === 'string' ? label : 'this setting';\n return (\n <TooltipTrigger>\n <Focusable>\n <button\n type=\"button\"\n className={s.help}\n aria-label={`About ${name}`}\n onClick={(e) => {\n // The wrapping <label> would otherwise actuate the row's control.\n e.preventDefault();\n e.stopPropagation();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n ⓘ\n </button>\n </Focusable>\n <Tooltip>{description}</Tooltip>\n </TooltipTrigger>\n );\n}\n","import {\n type ComponentProps,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { getAlpha01, toHex8, withAlpha01, type FillStyle, type PaintKind } from '@weasel-js/core';\nimport { dlog } from '../../dlog';\nimport { decimal, parseAs, qty, type Display, type UnitTable } from '@weasel-js/quantity';\nimport { ColorField } from '../ColorField';\nimport { FontFamilySelect } from '../FontFamilySelect';\nimport { FontWeightSelect } from '../FontWeightSelect';\nimport { Input } from '../Input';\nimport { UnitField } from '../NumberField';\nimport { PaintField } from '../PaintField';\nimport { PaintInput } from '../PaintInput';\nimport { Radio, RadioGroup } from '../RadioGroup';\nimport { spinKey } from '../spin';\nimport { Select } from '../Select';\nimport { Switch } from '../Switch';\nimport { ToggleBar } from '../ToggleBar';\nimport sharedCheckbox from '../checkbox.module.css';\nimport shared from '../range.module.css';\nimport {\n type PropertyMetricProps,\n PropertyRow,\n type PropertyRowLayout,\n type PropertyRowVariant,\n} from './PropertyPanel';\nimport s from './Properties.module.css';\n\n/** One choice of an enum field. */\nexport interface PropertyOption<T extends string> {\n value: T;\n /** The option's name. A string also names its segment for a screen reader. */\n label: ReactNode;\n /** What a segment shows in place of `label` when the full one would not fit\n * — a glyph or a letter. `label` stays the accessible name. A select has\n * room for the label, so it draws a glyph beside it and leaves a letter out. */\n glyph?: ReactNode;\n /** Shown but not choosable: a value the control reports and cannot author. */\n disabled?: boolean;\n}\n\n/** Props every kind of field shares. */\ninterface FieldBase {\n /** The control's accessible name. A `<PropertyField>` takes it from a string\n * `label` when this is omitted. */\n name?: string;\n /** The sources the field reads disagree — a multi-selection whose nodes\n * differ. The control shows no value, in whatever form it has for that. */\n mixed?: boolean;\n /**\n * The sources agree on holding nothing: whatever is in effect comes from a\n * fallback further down. The control shows no chosen value rather than\n * inventing one, since the next edit would write the invention back.\n */\n unset?: boolean;\n /** Class on the control element itself. */\n className?: string;\n /** Id for the control element, for a `<label htmlFor>` outside it. */\n id?: string;\n}\n\n/** A boolean field. */\nexport interface PropertyBooleanFieldProps extends FieldBase {\n kind: 'boolean';\n /** `checkbox` (default), `switch`, or `toggle` — a one-segment pressable bar. */\n control?: 'checkbox' | 'switch' | 'toggle';\n /** Absent reads as off. */\n value: boolean | undefined;\n onChange: (next: boolean) => void;\n /** A `toggle`'s segment content. Defaults to the first letter of `name`. */\n glyph?: ReactNode;\n}\n\n/** A number field. */\nexport interface PropertyNumberFieldProps extends FieldBase {\n kind: 'number';\n /** `input` (default) for a typed number; `slider` for a track with an\n * editable readout, where the range matters more than the exact value. */\n control?: 'input' | 'slider';\n /** Absent reads as an empty field. */\n value: number | null | undefined;\n /**\n * The committed value. Given `onInput` as well, it fires once a drag ends,\n * or on blur, Enter or a step in a typed field; on its own it fires on every\n * move, keystroke and step. A caller wanting settled values only passes a\n * no-op `onInput`.\n */\n onChange: (next: number) => void;\n /** The live value, fired continuously. Pass it alongside `onChange` when the\n * write is expensive — cheap state here, the costly work there. */\n onInput?: (next: number) => void;\n /** A slider's track runs 0..100 where these are omitted. */\n min?: number;\n max?: number;\n step?: number;\n /**\n * Suffix after the value. A string becomes a dim word unit (`px`); pass JSX\n * like `<sup>°</sup>` for a symbol. Display only — the value stays a number.\n */\n unit?: ReactNode;\n /** Units a person may type into a typed field, each mapped to the factor\n * that turns it into the unit shown: `{ mm: 0.1, cm: 1 }`. */\n accepts?: Readonly<UnitTable>;\n /** How the value shows, is spoken, and reads back when typed —\n * `compact()` reads `2.00M`. A slider readout defaults to the value at\n * `step`'s precision. */\n display?: Display;\n /** A slider readout's text, for what no display expresses — a derived\n * value, a word at one end. Wins over `display`, and is spoken as shown. */\n format?: (value: number) => ReactNode;\n placeholder?: string;\n /** A typed field's up and down buttons. Default `false`: a dense panel\n * drives its numbers by typing, the arrow keys and the wheel. */\n steppers?: boolean;\n}\n\n/** A text field. */\nexport interface PropertyStringFieldProps extends FieldBase {\n kind: 'string';\n control?: 'input' | 'textarea';\n /** Absent reads as an empty field. */\n value: string | null | undefined;\n /**\n * The committed text. On its own it fires on every keystroke. Given\n * `onInput` as well, the field drafts: `onInput` gets each keystroke and\n * this fires once, on blur or Enter, and only if the text changed.\n */\n onChange: (next: string) => void;\n onInput?: (next: string) => void;\n placeholder?: string;\n maxLength?: number;\n}\n\n/** A choice among fixed options. */\nexport interface PropertyEnumFieldProps<T extends string = string> extends FieldBase {\n kind: 'enum';\n /**\n * `select` (default) is a dropdown. `radio` and `toggle` show every option\n * at once — a radio group lists them, and a toggle is a row of segments.\n */\n control?: 'select' | 'radio' | 'toggle';\n /** Absent, or not one of `options`, chooses nothing. */\n value: T | undefined;\n options: ReadonlyArray<PropertyOption<T>>;\n onChange: (next: T) => void;\n /**\n * Given, choosing nothing is a value of its own: a `toggle` lets the chosen\n * segment be clicked off, and calls this. Absent, a toggle always holds one.\n */\n onClear?: () => void;\n /** Shown while no option is chosen. Defaults to \"Choose option…\". */\n placeholder?: string;\n}\n\n/** A single color. */\nexport interface PropertyColorFieldProps extends FieldBase {\n kind: 'color';\n /** `#rrggbb`, or `#rrggbbaa` when `alpha` is `true`. */\n value: string | undefined;\n /**\n * The committed color. Given `onInput` as well, it fires once per gesture —\n * the picker closing, or the opacity track let go; on its own it fires on\n * every move. A caller wanting settled values only passes a no-op `onInput`.\n */\n onChange: (next: string) => void;\n onInput?: (next: string) => void;\n /**\n * Offer an opacity track. `true` keeps the alpha in `value` as `#rrggbbaa`;\n * a number is the 0..1 alpha held apart from it, reported through\n * `onAlphaChange` / `onAlphaInput`.\n */\n alpha?: boolean | number;\n onAlphaChange?: (next: number) => void;\n onAlphaInput?: (next: number) => void;\n /** Draw the opacity track inert, for a consumer that drops alpha. */\n alphaDisabled?: boolean;\n}\n\n/** A whole paint: a solid, a gradient, a pattern, or none. */\nexport interface PropertyPaintFieldProps extends FieldBase {\n kind: 'paint';\n /** `swatch` (default) opens the editor in a popover, for a narrow slot;\n * `inline` draws the kind bar and its editor in place. */\n control?: 'swatch' | 'inline';\n /** `null` is an explicit \"no paint\"; `undefined` is nothing to show. */\n value: FillStyle | null | undefined;\n onChange: (next: FillStyle | null) => void;\n onInput?: (next: FillStyle | null) => void;\n /** Offer \"None\". Default `true`. */\n allowNone?: boolean;\n /** Restrict the kinds offered. Default: every registered kind. */\n kinds?: readonly PaintKind[];\n}\n\n/** A font family, picked from the live font registry. */\nexport interface PropertyFontFamilyFieldProps extends FieldBase {\n kind: 'font-family';\n value: string | undefined;\n onChange: (next: string) => void;\n /** The weight and slant the family is drawn at, so the picker names the\n * variant that will actually paint. */\n weight?: number;\n fontStyle?: 'normal' | 'italic';\n}\n\n/** A font weight, picked from the weights its family has registered. */\nexport interface PropertyFontWeightFieldProps extends FieldBase {\n kind: 'font-weight';\n value: number | undefined;\n onChange: (next: number) => void;\n /** The family whose weights to offer. */\n family?: string;\n}\n\n/**\n * One field for {@link PropertyControl} and {@link PropertyField}, keyed by\n * `kind`.\n */\nexport type PropertyControlProps<T extends string = string> =\n | PropertyBooleanFieldProps\n | PropertyNumberFieldProps\n | PropertyStringFieldProps\n | PropertyEnumFieldProps<T>\n | PropertyColorFieldProps\n | PropertyPaintFieldProps\n | PropertyFontFamilyFieldProps\n | PropertyFontWeightFieldProps;\n\n/** The kinds a {@link PropertyControl} draws. */\nexport type PropertyFieldKind = PropertyControlProps['kind'];\n\n/** Row props {@link PropertyField} adds to the field it draws. */\nexport interface PropertyFieldRowProps extends PropertyMetricProps {\n label: ReactNode;\n /**\n * Text beside the label. On a slider it replaces the editable readout —\n * use it when the row is not showing a number a caller could type back,\n * such as an auto row's `auto`.\n */\n readout?: ReactNode;\n description?: string;\n layout?: PropertyRowLayout;\n /** Take the full width of the enclosing grid — see `<PropertyRow span>`. */\n span?: boolean;\n /** The row is auto — see `<PropertyRow auto>`. */\n auto?: boolean;\n /** Toggles `auto` from the row's label — see `<PropertyRow onAutoChange>`. */\n onAutoChange?: (next: boolean) => void;\n /** Class on the row. `controlClassName` reaches the control. */\n rowClassName?: string;\n controlClassName?: string;\n}\n\n/** Props for {@link PropertyField}: one field, and the row around it. */\nexport type PropertyFieldProps<T extends string = string> = PropertyFieldRowProps &\n DistributiveOmit<PropertyControlProps<T>, 'className' | 'id'>;\n\ntype DistributiveOmit<U, K extends PropertyKey> = U extends unknown ? Omit<U, K> : never;\n\n/**\n * A labeled settings row for one field, its control chosen by `kind` (and\n * `control`): `<PropertyField kind=\"number\" control=\"slider\" label=\"Blur\" …>`.\n *\n * The row is a {@link PropertyRow}; the control is the one\n * {@link PropertyControl} draws for the same props. Every schema-driven\n * settings surface in the kit — `ControlPanel`, `PrefsForm`, `SelectionPanel`\n * — draws its built-in kinds through that one mapping, so a kind's control\n * is decided once.\n *\n * Callbacks follow the field's shape: a discrete control (a box, a choice)\n * reports each pick; a continuous or typed one reports every change through\n * `onChange` alone, or splits them into live `onInput` and settled\n * `onChange` when given both. `mixed` and `unset` show a field whose sources\n * disagree, or agree on holding nothing.\n */\nexport function PropertyField<T extends string = string>(props: PropertyFieldProps<T>) {\n const {\n label,\n readout,\n description,\n layout,\n span,\n density,\n align,\n auto,\n onAutoChange,\n rowClassName,\n controlClassName,\n ...field\n } = props;\n const id = useId();\n // Internally a field's option type is erased to `string`: nothing below\n // reads it, and the caller's `onChange` still receives its own `T`.\n const control = {\n ...field,\n name: field.name ?? nameOf(label),\n className: controlClassName,\n id,\n } as unknown as PropertyControlProps;\n const shape = rowShape(control);\n\n const row = {\n label,\n description,\n layout,\n span,\n density,\n align,\n auto,\n onAutoChange,\n className: rowClassName,\n variant: shape.variant,\n group: shape.group,\n // The font pickers take no id; any other single control is named by the\n // row's `<label>` through this one.\n htmlFor: shape.group || control.kind === 'font-family' || control.kind === 'font-weight'\n ? undefined\n : id,\n };\n\n if (control.kind === 'number' && control.control === 'slider') {\n return <SliderRow row={row} readout={readout} control={control} />;\n }\n return (\n <PropertyRow {...row} readout={readout}>\n <ControlBody {...control} />\n </PropertyRow>\n );\n}\n\n/**\n * The control for one field, with no row around it — for a cell that shares\n * a row with others, or a surface that draws its own row. Keyed by `kind`\n * (and `control`), the same mapping {@link PropertyField} draws.\n *\n * A slider brings its readout beside the track. Several elements come back\n * as siblings rather than wrapped, so the surrounding row lays them out.\n */\nexport function PropertyControl<T extends string = string>(typed: PropertyControlProps<T>) {\n const props = typed as unknown as PropertyControlProps;\n if (props.kind === 'number' && props.control === 'slider') return <SliderCell {...props} />;\n return <ControlBody {...props} />;\n}\n\n/**\n * A slider's props with its drag held locally. A caller taking settled values\n * only ignores `onInput`, so `value` stands still through the drag; without the\n * draft the controlled track snaps back on every move and commits from there.\n */\nfunction useSliderDraft(p: PropertyNumberFieldProps): PropertyNumberFieldProps {\n const [draft, setDraft] = useState<number>();\n const { onInput, onChange } = p;\n if (!onInput) return p;\n return {\n ...p,\n value: draft ?? p.value,\n onInput: (next) => {\n setDraft(next);\n onInput(next);\n },\n onChange: (next) => {\n setDraft(undefined);\n onChange(next);\n },\n };\n}\n\nfunction SliderRow({ row, readout, control }: {\n row: Omit<ComponentProps<typeof PropertyRow>, 'children'>;\n readout: ReactNode;\n control: PropertyNumberFieldProps;\n}) {\n const p = useSliderDraft(control);\n return (\n <PropertyRow {...row} readout={boxedReadout(readout) ?? <SliderReadout {...p} />}>\n <SliderTrack {...p} />\n </PropertyRow>\n );\n}\n\nfunction SliderCell(props: PropertyNumberFieldProps) {\n const p = useSliderDraft(props);\n return (\n <>\n <SliderTrack {...p} />\n <span className={s.cellReadout}>\n <SliderReadout {...p} />\n </span>\n </>\n );\n}\n\n/** How a row holds a field's control. */\nfunction rowShape(p: PropertyControlProps<string>): { variant: PropertyRowVariant; group: boolean } {\n switch (p.kind) {\n case 'boolean':\n // A switch renders its own <label>, and a segment is a button: neither\n // may sit inside the row's.\n return { variant: 'checkbox', group: p.control === 'switch' || p.control === 'toggle' };\n case 'enum':\n // A <label> hands a click on its text to its first control, which in a\n // group of options means choosing the first one.\n return { variant: 'default', group: p.control === 'radio' || p.control === 'toggle' };\n case 'color':\n return { variant: 'color', group: false };\n case 'paint':\n return { variant: 'default', group: true };\n default:\n return { variant: 'default', group: false };\n }\n}\n\nfunction ControlBody(props: PropertyControlProps) {\n switch (props.kind) {\n case 'boolean':\n return <BooleanControl {...props} />;\n case 'number':\n return <NumberInput {...props} />;\n case 'string':\n return <StringControl {...props} />;\n case 'enum':\n return <EnumControl {...props} />;\n case 'color':\n return <ColorControl {...props} />;\n case 'paint':\n return <PaintControl {...props} />;\n case 'font-family':\n return (\n <FontFamilySelect\n className={props.className}\n value={props.mixed ? undefined : props.value}\n mixed={props.mixed}\n onChange={props.onChange}\n weight={props.weight}\n fontStyle={props.fontStyle}\n aria-label={props.name}\n />\n );\n case 'font-weight':\n return (\n <FontWeightSelect\n className={props.className}\n value={props.mixed ? undefined : props.value}\n mixed={props.mixed}\n family={props.family}\n onChange={props.onChange}\n aria-label={props.name}\n />\n );\n default: {\n // Unreachable while every kind has an arm; a new kind without one is a\n // compile error here rather than an empty cell.\n const _exhaustive: never = props;\n throw new Error(`PropertyControl: no control for kind \"${(_exhaustive as { kind: string }).kind}\"`);\n }\n }\n}\n\n// ── Kinds ────────────────────────────────────────────────────────────────\n\n/** A cue for a state the control itself cannot draw: a switch has no\n * indeterminate form, and nothing has an \"unset\" one. */\nfunction Dimmed({ mixed, unset, children }: { mixed?: boolean; unset?: boolean; children: ReactNode }) {\n if (!mixed && !unset) return <>{children}</>;\n return (\n <span className={s.dimmed} title={mixed ? 'Mixed' : 'Not set'}>\n {children}\n </span>\n );\n}\n\nfunction BooleanControl(p: PropertyBooleanFieldProps) {\n const on = !p.mixed && p.value === true;\n const box = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (box.current) box.current.indeterminate = p.mixed === true;\n });\n if (p.control === 'toggle') {\n // Unselected already is how a toggle button says \"not set\", and dimming it\n // would read as disabled; mixed has a real ARIA form on one.\n const key = 'on';\n return (\n <ToggleBar<string>\n mode=\"multiple\"\n size=\"sm\"\n variant=\"flat\"\n className={p.className}\n ariaLabel={p.name}\n items={[{ value: key, label: p.glyph ?? p.name?.slice(0, 1), ariaLabel: p.name }]}\n value={on ? [key] : []}\n mixedValues={p.mixed ? [key] : []}\n onChange={(next) => p.onChange(next.includes(key))}\n />\n );\n }\n if (p.control === 'switch') {\n return (\n <Dimmed mixed={p.mixed} unset={p.unset}>\n <Switch className={p.className} isSelected={on} onChange={p.onChange} aria-label={p.name} />\n </Dimmed>\n );\n }\n // A native box rather than the kit's `Checkbox`: that one renders a `<label>`\n // of its own, which may not sit inside the row's, and without the row's the\n // label text would no longer toggle it.\n return (\n <Dimmed unset={p.unset}>\n <input\n ref={box}\n id={p.id}\n type=\"checkbox\"\n className={p.className ? `${sharedCheckbox.checkbox} ${p.className}` : sharedCheckbox.checkbox}\n aria-label={p.name}\n checked={on}\n onChange={(e) => p.onChange(e.target.checked)}\n />\n </Dimmed>\n );\n}\n\n/**\n * A ref for an input whose commit half has to come off a real listener.\n *\n * A native `range` input fires `input` through a drag and `change` once at\n * the end, but React's synthetic `onChange` sees only the first: its value\n * tracker drops the unchanged second. So a track offering the live/committed\n * split reads the live half from React and the committed half from here.\n * `commit` is `undefined` when the track has one callback, which then fires\n * continuously.\n */\nfunction useCommitListener(\n commit: ((raw: string) => void) | undefined,\n): RefObject<HTMLInputElement | null> {\n const ref = useRef<HTMLInputElement>(null);\n const latest = useRef(commit);\n useEffect(() => {\n latest.current = commit;\n });\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const onCommit = () => latest.current?.(el.value);\n el.addEventListener('change', onCommit);\n return () => el.removeEventListener('change', onCommit);\n }, []);\n return ref;\n}\n\nfunction unitSuffix(unit: ReactNode, className: string): ReactNode {\n if (unit == null) return null;\n return typeof unit === 'string' ? <span className={className}>{unit}</span> : unit;\n}\n\nconst ignore = (): void => {};\n\nfunction NumberInput(p: PropertyNumberFieldProps) {\n const known = !p.mixed && typeof p.value === 'number' && Number.isFinite(p.value);\n const input = (\n <UnitField\n id={p.id}\n className={p.className ? `${s.numberField} ${p.className}` : s.numberField}\n value={known ? (p.value as number) : NaN}\n placeholder={p.mixed ? 'Mixed' : p.placeholder}\n minValue={p.min}\n maxValue={p.max}\n step={p.step}\n accepts={p.accepts}\n display={p.display}\n steppers={p.steppers}\n aria-label={p.name}\n // With one callback it is the live one: every keystroke and step reaches\n // it, and the commit on blur would only repeat the last of them.\n onInput={p.onInput ?? p.onChange}\n onChange={p.onInput ? p.onChange : ignore}\n />\n );\n if (p.unit == null) return input;\n return (\n <span className={s.fieldUnitGroup}>\n {input}\n {unitSuffix(p.unit, s.readoutUnit)}\n </span>\n );\n}\n\n/** A slider's bounds, with the 0..100 fallback for an unbounded track. */\nfunction sliderBounds(p: PropertyNumberFieldProps): { min: number; max: number; step: number } {\n return { min: p.min ?? 0, max: p.max ?? 100, step: p.step ?? 1 };\n}\n\nfunction SliderTrack(p: PropertyNumberFieldProps) {\n const { min, max, step } = sliderBounds(p);\n const live = p.onInput ?? p.onChange;\n const commit = p.onInput ? p.onChange : undefined;\n const range = useCommitListener(commit && ((raw) => commit(Number(raw))));\n const known = !p.mixed && typeof p.value === 'number' && Number.isFinite(p.value);\n // The thumb clamps to the track; the readout beside it does not, so a value\n // past `max` is still reported as what it is.\n const value = known ? Math.min(Math.max(p.value as number, min), max) : min;\n return (\n // The shared skin with no fill: `InlineRange`'s filled-to-value track is its\n // own, and the property rows' 18% track is the one the kit converges on.\n <input\n ref={range}\n type=\"range\"\n id={p.id}\n className={p.className ? `${shared.range} ${p.className}` : shared.range}\n aria-label={p.name}\n // The readout is the keyboard's way in, and steps as the track would; a\n // tab stop here too would be two stops for one value.\n tabIndex={-1}\n min={min}\n max={max}\n step={step}\n value={value}\n disabled={p.mixed}\n onChange={(e) => {\n const v = Number(e.target.value);\n dlog('property-panel', 'slider', { name: p.name, value: v });\n live(v);\n }}\n />\n );\n}\n\nfunction SliderReadout(p: PropertyNumberFieldProps) {\n const { min, max, step } = sliderBounds(p);\n const known = !p.mixed && typeof p.value === 'number' && Number.isFinite(p.value);\n if (!known) return <>{boxedReadout('—')}</>;\n // Precision tracks `step`: integer steps show none, 0.1 one, 0.05 two.\n const decimals = step >= 1 ? 0 : Math.min(6, Math.max(0, Math.ceil(-Math.log10(step))));\n const display = p.display ?? decimal({ places: decimals, grouping: false });\n return (\n <EditableReadout\n name={p.name}\n value={p.value as number}\n min={min}\n max={max}\n step={step}\n display={display}\n format={p.format}\n unit={p.unit}\n onCommit={(next) => {\n p.onInput?.(next);\n p.onChange(next);\n }}\n />\n );\n}\n\n/**\n * A replacement readout in the box `EditableReadout` would have occupied.\n *\n * A row that can go auto swaps its editable readout for a word, and the label\n * is a flex line: an input is taller than bare text — a text input's inner\n * editor will not shrink to a line-height below the font's own content area —\n * so the swap moved the label's baseline, and the whole row with it. Only the\n * slider owns an `EditableReadout`, so only it needs this; giving every text\n * readout the box moves the rows that never had an input.\n */\nfunction boxedReadout(readout: ReactNode): ReactNode {\n if (typeof readout !== 'string' && typeof readout !== 'number') return readout;\n return (\n <span className={s.readoutGroup}>\n <span className={s.readoutText}>{readout}</span>\n </span>\n );\n}\n\ninterface EditableReadoutProps {\n name: string | undefined;\n value: number;\n min: number;\n max: number;\n step: number;\n display: Display;\n format?: (value: number) => ReactNode;\n unit?: ReactNode;\n onCommit: (next: number) => void;\n}\n\n/**\n * Readout that swaps to a number input on click, commits on Enter/blur,\n * cancels on Escape, and steps like the track beside it. Clicks are stopped so\n * a wrapping <label> doesn't forward focus to the slider thumb.\n */\nfunction EditableReadout({ name, value, min, max, step, display, format, unit, onCommit }: EditableReadoutProps) {\n // Draft is non-null only while the input is focused; the live value mirrors\n // into the input otherwise.\n const [draft, setDraft] = useState<string | null>(null);\n const text = (n: number) => (format ? String(format(n)) : qty(n, display).text);\n const read = (typed: string) => parseAs(typed, display);\n const displayValue = draft !== null ? draft : text(value);\n // The widest value the range can show, which the stylesheet widens the box to fit.\n const fit = { '--wzl-property-readout-fit': `${Math.max(text(min).length, text(max).length)}ch` };\n\n const commit = () => {\n if (draft !== null) {\n const n = read(draft);\n if (Number.isFinite(n)) onCommit(Math.min(max, Math.max(min, n)));\n }\n setDraft(null);\n };\n\n return (\n <span className={s.readoutGroup}>\n <input\n type=\"text\"\n role=\"spinbutton\"\n aria-label={name}\n aria-valuenow={value}\n aria-valuetext={format ? text(value) : qty(value, display).spoken}\n aria-valuemin={min}\n aria-valuemax={max}\n inputMode=\"decimal\"\n className={s.readoutInput}\n style={fit as CSSProperties}\n value={displayValue}\n onFocus={(e) => {\n setDraft(text(value));\n e.currentTarget.select();\n }}\n onChange={(e) => setDraft(e.target.value.replace(/-/g, '−'))}\n onBlur={commit}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n e.currentTarget.focus();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n commit();\n e.currentTarget.blur();\n } else if (e.key === 'Escape') {\n setDraft(null);\n e.currentTarget.blur();\n } else {\n const typed = draft === null ? value : read(draft);\n const next = spinKey(e.key, Number.isFinite(typed) ? typed : value, { step, min, max });\n if (next === null) return;\n e.preventDefault();\n onCommit(next);\n // A step is committed already; the box shows the value it comes back as.\n setDraft(null);\n }\n }}\n />\n {unitSuffix(unit, s.readoutUnit)}\n </span>\n );\n}\n\n/**\n * The text a field shows and how an edit to it lands. With `onInput` the\n * field drafts: the draft shows while it differs from `value`, and settles\n * through `onChange` on blur or Enter. Without it, every keystroke is the\n * value.\n */\nfunction useTextEdit(p: PropertyStringFieldProps) {\n const [draft, setDraft] = useState<string | null>(null);\n const value = p.mixed ? '' : (p.value ?? '');\n const drafting = p.onInput !== undefined;\n return {\n shown: draft ?? value,\n type: (next: string) => {\n if (!drafting) {\n p.onChange(next);\n return;\n }\n setDraft(next);\n p.onInput?.(next);\n },\n settle: () => {\n if (draft !== null && draft !== value) p.onChange(draft);\n setDraft(null);\n },\n };\n}\n\nfunction StringControl(p: PropertyStringFieldProps) {\n const edit = useTextEdit(p);\n const placeholder = p.mixed ? 'Mixed' : p.placeholder;\n if (p.control === 'textarea') {\n return (\n <textarea\n id={p.id}\n className={p.className ? `${s.textarea} ${p.className}` : s.textarea}\n aria-label={p.name}\n value={edit.shown}\n placeholder={placeholder}\n maxLength={p.maxLength}\n rows={3}\n onChange={(e) => edit.type(e.target.value)}\n onBlur={edit.settle}\n />\n );\n }\n return (\n <Input\n id={p.id}\n className={p.className ? `${s.textField} ${p.className}` : s.textField}\n value={edit.shown}\n placeholder={placeholder}\n maxLength={p.maxLength}\n aria-label={p.name}\n onChange={edit.type}\n onBlur={edit.settle}\n onKeyDown={(e) => {\n if (e.key === 'Enter') (e.target as HTMLElement).blur();\n }}\n />\n );\n}\n\n// A row's <label> text also holds the help button's ⓘ and any readout, so a\n// control takes its name from the string label, not from the <label> that\n// `for` points at it.\nfunction nameOf(label: ReactNode): string | undefined {\n return typeof label === 'string' ? label : undefined;\n}\n\n/** `glyph` when it is drawn rather than a letter or two of text. */\nexport function drawnGlyph(glyph: ReactNode): ReactNode {\n return glyph === undefined || glyph === null || typeof glyph === 'string' || typeof glyph === 'number'\n ? undefined\n : glyph;\n}\n\n/** A segment drawing a glyph hides its label, so the label comes back as its tooltip. */\nfunction glyphTip(o: PropertyOption<string>): ReactNode {\n return o.glyph === undefined || o.glyph === null ? undefined : o.label;\n}\n\nfunction EnumControl(p: PropertyEnumFieldProps) {\n const chosen = !p.mixed && p.options.some((opt) => opt.value === p.value);\n const current = chosen ? (p.value as string) : null;\n\n if (p.control === 'radio') {\n return (\n <RadioGroup className={p.className} value={current} onChange={p.onChange} aria-label={p.name}>\n {p.options.map((o) => (\n <Radio key={o.value} value={o.value} isDisabled={o.disabled}>\n {o.label}\n </Radio>\n ))}\n </RadioGroup>\n );\n }\n if (p.control === 'toggle' && p.onClear) {\n // `multiple` for what `single` cannot give: a mixed state on each segment,\n // and arrow keys that move focus without choosing. At most one stays lit —\n // the segment just added wins, and adding none means the lit one was\n // clicked off.\n const { onClear } = p;\n const lit = current === null ? [] : [current];\n return (\n <ToggleBar<string>\n mode=\"multiple\"\n size=\"sm\"\n variant=\"flat\"\n className={p.className ? `${s.toggleBar} ${p.className}` : s.toggleBar}\n ariaLabel={p.name}\n items={p.options.map((o) => ({\n value: o.value,\n label: o.glyph ?? o.label,\n ariaLabel: nameOf(o.label),\n tooltip: glyphTip(o),\n disabled: o.disabled,\n }))}\n value={lit}\n mixedValues={p.mixed ? p.options.map((o) => o.value) : []}\n onChange={(next) => {\n const added = next.find((v) => !lit.includes(v));\n if (added !== undefined) p.onChange(added);\n else onClear();\n }}\n />\n );\n }\n if (p.control === 'toggle') {\n return (\n <ToggleBar<string>\n size=\"sm\"\n variant=\"flat\"\n className={p.className ? `${s.toggleBar} ${p.className}` : s.toggleBar}\n ariaLabel={p.name}\n items={p.options.map((o) => ({\n value: o.value,\n label: o.glyph ?? o.label,\n ariaLabel: nameOf(o.label),\n tooltip: glyphTip(o),\n disabled: o.disabled,\n }))}\n value={current}\n onChange={(next) => {\n if (next !== null) p.onChange(next);\n }}\n />\n );\n }\n return (\n <Select<string>\n className={p.className ? `${s.select} ${p.className}` : s.select}\n triggerId={p.id}\n aria-label={p.name}\n placeholder={p.mixed ? 'Mixed' : (p.placeholder ?? (p.unset ? '—' : 'Choose option…'))}\n selectedKey={current}\n options={p.options.map((o) => ({\n value: o.value,\n label: o.label,\n icon: drawnGlyph(o.glyph),\n isDisabled: o.disabled,\n }))}\n onSelectionChange={(v) => {\n dlog('property-panel', 'select', { name: p.name, value: v });\n p.onChange(v);\n }}\n />\n );\n}\n\n/** A hex color as the `#rrggbb` it paints and the 0..1 alpha beside it.\n * Anything unreadable is opaque black, which is what a swatch would show for\n * it anyway. */\nfunction splitAlpha(value: string | undefined): { rgb: string; alpha: number } {\n const eight = toHex8(value?.trim() ?? '');\n if (!/^#[0-9a-f]{8}$/i.test(eight)) return { rgb: '#000000', alpha: 1 };\n return { rgb: eight.slice(0, 7).toLowerCase(), alpha: getAlpha01(eight) };\n}\n\nfunction ColorControl(p: PropertyColorFieldProps) {\n const withAlpha = p.alpha !== undefined && p.alpha !== false;\n const apart = typeof p.alpha === 'number';\n const split = splitAlpha(p.value);\n const alpha = apart ? (p.alpha as number) : split.alpha;\n\n // `ColorField` holds alpha in the hex. One kept in a channel of its own goes\n // in with the color and comes back out of it, each half to its own callback.\n const route =\n (write: (hex: string) => void, own: ((a: number) => void) | undefined) => (hex: string) => {\n if (!apart) {\n write(hex);\n return;\n }\n const next = splitAlpha(hex);\n if (next.rgb !== split.rgb || !own) write(next.rgb);\n // Read back at the track's percent, which is all a hex byte can hold of it.\n const a = Math.round(next.alpha * 100) / 100;\n if (a !== Math.round(alpha * 100) / 100) own?.(a);\n };\n // As a number does: one callback is the live one, and the commit at the end\n // of a gesture would only repeat its last call.\n const drafting = p.onInput !== undefined || p.onAlphaInput !== undefined;\n const live = route(p.onInput ?? p.onChange, p.onAlphaInput ?? p.onAlphaChange);\n const settled = drafting ? route(p.onChange, p.onAlphaChange) : ignore;\n return (\n <ColorField\n id={p.id}\n className={p.className ? `${s.colorField} ${p.className}` : s.colorField}\n value={p.mixed ? undefined : withAlpha ? withAlpha01(split.rgb, alpha) : (p.value ?? '#000000')}\n mixed={p.mixed}\n alpha={withAlpha}\n alphaDisabled={p.alphaDisabled}\n onInput={live}\n onChange={settled}\n aria-label={p.name}\n />\n );\n}\n\nfunction PaintControl(p: PropertyPaintFieldProps) {\n const Editor = p.control === 'inline' ? PaintInput : PaintField;\n return (\n <Editor\n className={p.className}\n value={p.value}\n mixed={p.mixed}\n unset={p.unset}\n kinds={p.kinds}\n allowNone={p.allowNone}\n onChange={p.onChange}\n onInput={p.onInput}\n aria-label={p.name}\n />\n );\n}\n"],"mappings":"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"}
|