@mkbabb/glass-ui 3.9.0 → 3.10.1
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/{CardAction-DuArVky-.js → CardAction-DrAcAV4d.js} +2 -2
- package/dist/{CommandShortcut-CefCj5mt.js → CommandShortcut-mV2e1aG6.js} +2 -2
- package/dist/{DataTable-CUHMukiQ.js → DataTable-C3E6jZ5B.js} +2 -2
- package/dist/{DialogContent-BRkT1cjP.js → DialogContent-BxaaafFi.js} +1 -1
- package/dist/{HoverPopover-2LOIW34a.js → HoverPopover-CDA_SaCe.js} +1 -1
- package/dist/{MetricBadge-lTc002u2.js → MetricBadge-idgrkqoP.js} +1 -1
- package/dist/{Notification-BxK8LZMw.js → Notification-Cu0nN17_.js} +3 -3
- package/dist/{NumberFieldContent-BbLOh8RU.js → NumberFieldContent-CHEWghnY.js} +2 -2
- package/dist/{PopoverContent-BId6ggf_.js → PopoverContent-DpUvdYY-.js} +1 -1
- package/dist/{Progress-iEuD9pxG.js → Progress-BW-StFw2.js} +1 -1
- package/dist/{ScrollingText-BPP84wKo.js → ScrollingText-DruYCni_.js} +1 -1
- package/dist/{SelectScrollDownButton-T32cVFeM.js → SelectScrollDownButton-pirzjm--.js} +3 -3
- package/dist/{Switch-LDKLmmgx.js → Switch-DeAqg6pi.js} +1 -1
- package/dist/{TabsList-B8CVOQPC.js → TabsList-BAVzOZpg.js} +2 -2
- package/dist/{Toaster-1rYWrmAm.js → Toaster-CvuuW_y9.js} +49 -46
- package/dist/{ToggleGroupItem-Cev4pOVK.js → ToggleGroupItem-DtD37b4G.js} +4 -4
- package/dist/animated-digit.js +2 -2
- package/dist/api/index.d.ts +4 -4
- package/dist/api.js +1 -1
- package/dist/aurora.js +238 -547
- package/dist/{badge-BvwvT50i.js → badge-NdCQMvvB.js} +2 -2
- package/dist/badge.js +1 -1
- package/dist/{button-DN39cGqL.js → button-DyiWFAOE.js} +12 -12
- package/dist/button.js +1 -1
- package/dist/canvas.js +2 -2
- package/dist/card.js +1 -1
- package/dist/carousel.js +5 -5
- package/dist/collapsible.js +1 -1
- package/dist/{color-8jBjWiJ6.js → color-B65wWyQz.js} +9 -7
- package/dist/color.js +1 -1
- package/dist/command.js +1 -1
- package/dist/{compile-DAjIoEy2.js → compile-Ce_V55zi.js} +23 -23
- package/dist/components/custom/aurora/composables/atoms.d.ts +21 -4
- package/dist/components/custom/aurora/composables/runtime.d.ts +0 -9
- package/dist/components/custom/aurora/composables/uniformBridge.d.ts +0 -11
- package/dist/components/custom/aurora/constants/renderMode.d.ts +0 -32
- package/dist/components/custom/aurora/constants/shaders/brush.glsl.d.ts +1 -1
- package/dist/components/custom/aurora/constants/shaders/mediums.glsl.d.ts +2 -2
- package/dist/components/custom/aurora/constants/shaders/tonemap.glsl.d.ts +1 -1
- package/dist/components/custom/aurora/constants/shaders/vangogh-medium.glsl.d.ts +1 -0
- package/dist/components/custom/aurora/index.d.ts +1 -1
- package/dist/components/custom/constellation/Constellation.vue.d.ts +85 -1
- package/dist/components/custom/constellation/composables/createConstellationField.d.ts +35 -0
- package/dist/components/custom/constellation/composables/useConstellationPointer.d.ts +35 -0
- package/dist/components/custom/constellation/constants.d.ts +36 -0
- package/dist/components/custom/constellation/constellationDraw.d.ts +18 -0
- package/dist/components/custom/constellation/constellationField.d.ts +174 -63
- package/dist/components/custom/constellation/constellationInteraction.d.ts +102 -0
- package/dist/components/custom/constellation/index.d.ts +4 -2
- package/dist/components/custom/controls/DarkModeToggle.vue.d.ts +11 -0
- package/dist/components/custom/dock/GlassDock.vue.d.ts +2 -110
- package/dist/components/custom/dock/composables/dockMorphContext.d.ts +36 -0
- package/dist/components/custom/dock/composables/useDockMorphWindow.d.ts +15 -0
- package/dist/components/custom/dock/composables/useDockShellProps.d.ts +131 -0
- package/dist/components/custom/dock/composables/useLayerTransition.d.ts +44 -0
- package/dist/components/custom/dock/constants.d.ts +23 -0
- package/dist/components/custom/fourier-field/FourierField.vue.d.ts +6 -0
- package/dist/components/custom/fourier-field/index.d.ts +25 -1
- package/dist/components/custom/fourier-field/math.d.ts +20 -8
- package/dist/components/custom/fourier-field/presets.d.ts +54 -0
- package/dist/components/custom/goo-blob/GooBlob.vue.d.ts +8 -10
- package/dist/components/custom/goo-blob/composables/buildMetaballProgram.d.ts +18 -0
- package/dist/components/custom/goo-blob/composables/uploadBlobUniforms.d.ts +41 -0
- package/dist/components/custom/goo-blob/composables/useBlobPointer.d.ts +4 -3
- package/dist/components/custom/goo-blob/composables/useMetaballRenderer.d.ts +16 -21
- package/dist/components/custom/goo-blob/constants.d.ts +52 -0
- package/dist/components/custom/goo-blob/index.d.ts +1 -1
- package/dist/components/custom/goo-blob/shaders/metaball-uniforms.glsl.d.ts +1 -0
- package/dist/components/custom/goo-blob/types.d.ts +59 -25
- package/dist/components/custom/instrument-chassis/InstrumentChassis.vue.d.ts +2 -2
- package/dist/components/custom/tabs/constants.d.ts +12 -0
- package/dist/components/custom/underline/GlassUnderline.vue.d.ts +84 -0
- package/dist/components/custom/underline/index.d.ts +2 -0
- package/dist/components/custom/underline/types.d.ts +56 -0
- package/dist/components/ui/drawer/Drawer.vue.d.ts +1 -0
- package/dist/components/ui/dropdown-menu/DropdownMenuSubContent.vue.d.ts +2 -2
- package/dist/components/ui/slider/index.d.ts +25 -18
- package/dist/components/ui/toast/use-toast.d.ts +2 -2
- package/dist/composables/color/index.d.ts +24 -7
- package/dist/composables/glass/useSpecularTracking.d.ts +12 -3
- package/dist/composables/glass/webgl/shaders/procedural-color.glsl.d.ts +1 -6
- package/dist/composables/motion/curves.d.ts +48 -0
- package/dist/composables/motion/index.d.ts +2 -0
- package/dist/composables/motion/springPresets.d.ts +33 -0
- package/dist/composables/motion/suite.d.ts +2 -0
- package/dist/composables/motion/useSpringMount.d.ts +1 -1
- package/dist/configurator.js +1 -1
- package/dist/confirm-dialog.js +2 -2
- package/dist/constellation.js +322 -147
- package/dist/controls.js +48 -14
- package/dist/dark.js +1 -1
- package/dist/data-table.js +1 -1
- package/dist/dialog.js +2 -2
- package/dist/dock.js +340 -327
- package/dist/dockContext-bho8B1A4.js +17 -0
- package/dist/{dropdown-menu-D77jX6Df.js → dropdown-menu-DVnQcA0E.js} +7 -4
- package/dist/dropdown-menu.js +1 -1
- package/dist/expandable-container.js +1 -1
- package/dist/forms.js +2 -2
- package/dist/fourier-field.js +147 -120
- package/dist/fourier-math.d.ts +1 -0
- package/dist/fourier-math.js +2 -0
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +286 -207
- package/dist/goo-blob.js +368 -322
- package/dist/hover-popover.js +1 -1
- package/dist/icon-tooltip.js +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/keyboard.js +1 -1
- package/dist/labeled-field.js +5 -5
- package/dist/math-BUU9hHID.js +43 -0
- package/dist/metric-badge.js +1 -1
- package/dist/metric-stack.js +2 -2
- package/dist/motion-core.js +4 -4
- package/dist/motion-curves.d.ts +1 -0
- package/dist/motion-curves.js +130 -0
- package/dist/motion.js +38 -37
- package/dist/notification.js +1 -1
- package/dist/number-field.js +1 -1
- package/dist/popover.js +1 -1
- package/dist/progress.js +1 -1
- package/dist/pulse.js +1 -1
- package/dist/reactive.js +1 -1
- package/dist/scrolling-text.js +1 -1
- package/dist/search.js +6 -6
- package/dist/select.js +1 -1
- package/dist/{sheet-VZEtNFvO.js → sheet-ChSXcJpU.js} +1 -1
- package/dist/sheet.js +1 -1
- package/dist/{slider-DC2mwuoe.js → slider-sfl8gFDD.js} +8 -8
- package/dist/slider.js +1 -1
- package/dist/sortable-list.js +2 -2
- package/dist/springPresets-aRSm-4_k.js +40 -0
- package/dist/stacked-icons.js +6 -6
- package/dist/styles/cards.css +2 -2
- package/dist/styles/components.css +1 -1
- package/dist/styles/dock/layer-group.css +38 -4
- package/dist/styles/dock/layers.css +11 -1
- package/dist/styles/dock/morph.css +95 -19
- package/dist/styles/dock/shell.css +12 -0
- package/dist/styles/dock-controls.css +25 -12
- package/dist/styles/drawer.css +14 -4
- package/dist/styles/floating-panel.css +2 -0
- package/dist/styles/glass/a11y-fallback.css +245 -0
- package/dist/styles/glass/ladder.css +304 -0
- package/dist/styles/glass/material.css +238 -0
- package/dist/styles/glass/progress-rail.css +78 -0
- package/dist/styles/glass/squircle.css +66 -0
- package/dist/styles/glass/surfaces.css +306 -0
- package/dist/styles/glass-refract.css +2 -0
- package/dist/styles/glass.css +31 -1052
- package/dist/styles/hover-popover.css +2 -0
- package/dist/styles/index.css +24 -6
- package/dist/styles/instrument-chassis.css +4 -0
- package/dist/styles/theme.css +14 -14
- package/dist/styles/tokens/color-radius.css +250 -0
- package/dist/styles/tokens/dark-arm.css +194 -0
- package/dist/styles/tokens/glass.css +413 -0
- package/dist/styles/tokens/light-dark.css +158 -0
- package/dist/styles/tokens/offsets-sizing.css +406 -0
- package/dist/styles/tokens/property-regs.css +169 -0
- package/dist/styles/tokens/scale-paper.css +361 -0
- package/dist/styles/tokens/scheme-motion.css +334 -0
- package/dist/styles/tokens/shadow.css +132 -0
- package/dist/styles/tokens.css +22 -2269
- package/dist/styles/transitions.css +20 -2
- package/dist/styles/typography.css +18 -6
- package/dist/styles/utilities/a11y-overrides.css +140 -0
- package/dist/styles/utilities/animate.css +26 -0
- package/dist/styles/utilities/base.css +365 -0
- package/dist/styles/utilities/btn.css +399 -0
- package/dist/styles/utilities/components.css +317 -0
- package/dist/styles/utilities.css +19 -1170
- package/dist/switch.js +1 -1
- package/dist/tabs.js +98 -98
- package/dist/timeline.js +2 -2
- package/dist/toast.js +1 -1
- package/dist/toggle-group.js +1 -1
- package/dist/typewriter.js +1 -1
- package/dist/underline.d.ts +1 -0
- package/dist/underline.js +85 -0
- package/dist/{useAnimatedNumber-C5I3wWd8.js → useAnimatedNumber-DfVgP4te.js} +1 -1
- package/dist/{useConfiguratorState-DxAqksK6.js → useConfiguratorState-BdQXh9ie.js} +1 -1
- package/dist/useSpecularTracking-DFK_fhpG.js +32 -0
- package/dist/useSpringMount-DXUzxBjV.js +108 -0
- package/dist/watercolor-dot.js +2 -2
- package/package.json +62 -38
- package/src/styles/cards.css +2 -2
- package/src/styles/dock/layer-group.css +38 -4
- package/src/styles/dock/layers.css +11 -1
- package/src/styles/dock/morph.css +95 -19
- package/src/styles/dock/shell.css +12 -0
- package/src/styles/dock-controls.css +25 -12
- package/src/styles/drawer.css +12 -4
- package/src/styles/glass/a11y-fallback.css +245 -0
- package/src/styles/glass/ladder.css +304 -0
- package/src/styles/glass/material.css +238 -0
- package/src/styles/glass/progress-rail.css +78 -0
- package/src/styles/glass/squircle.css +66 -0
- package/src/styles/glass/surfaces.css +306 -0
- package/src/styles/glass.css +31 -1052
- package/src/styles/index.css +24 -6
- package/src/styles/theme.css +14 -14
- package/src/styles/tokens/color-radius.css +250 -0
- package/src/styles/tokens/dark-arm.css +194 -0
- package/src/styles/tokens/glass.css +413 -0
- package/src/styles/tokens/light-dark.css +158 -0
- package/src/styles/tokens/offsets-sizing.css +406 -0
- package/src/styles/tokens/property-regs.css +169 -0
- package/src/styles/tokens/scale-paper.css +361 -0
- package/src/styles/tokens/scheme-motion.css +334 -0
- package/src/styles/tokens/shadow.css +132 -0
- package/src/styles/tokens.css +22 -2269
- package/src/styles/transitions.css +20 -2
- package/src/styles/typography.css +18 -6
- package/src/styles/utilities/a11y-overrides.css +140 -0
- package/src/styles/utilities/animate.css +26 -0
- package/src/styles/utilities/base.css +365 -0
- package/src/styles/utilities/btn.css +399 -0
- package/src/styles/utilities/components.css +317 -0
- package/src/styles/utilities.css +19 -1170
- package/dist/DeckProgress-Dmk4_AKN.js +0 -23
- package/dist/InstrumentRail-CUJ05YVG.js +0 -44
- package/dist/components/custom/aurora/composables/gpuRuntime.d.ts +0 -16
- package/dist/components/custom/aurora/constants/shaders/aurora.wgsl.d.ts +0 -7
- package/dist/components/custom/deck-progress/DeckProgress.vue.d.ts +0 -27
- package/dist/components/custom/deck-progress/index.d.ts +0 -2
- package/dist/components/custom/dialog-native/GlassDialogNative.vue.d.ts +0 -57
- package/dist/components/custom/dialog-native/index.d.ts +0 -1
- package/dist/components/custom/glass-panel/GlassPanel.vue.d.ts +0 -41
- package/dist/components/custom/glass-panel/index.d.ts +0 -2
- package/dist/components/custom/header-ribbon/HeaderRibbon.vue.d.ts +0 -31
- package/dist/components/custom/header-ribbon/index.d.ts +0 -2
- package/dist/components/custom/header-ribbon/types.d.ts +0 -7
- package/dist/components/custom/instrument-rail/InstrumentRail.vue.d.ts +0 -91
- package/dist/components/custom/instrument-rail/index.d.ts +0 -2
- package/dist/composables/glass/createGPUCanvas.d.ts +0 -40
- package/dist/deck-progress.d.ts +0 -1
- package/dist/deck-progress.js +0 -2
- package/dist/dockContext-BKeIMmNk.js +0 -9
- package/dist/glass-panel.d.ts +0 -1
- package/dist/glass-panel.js +0 -44
- package/dist/header-ribbon.d.ts +0 -1
- package/dist/header-ribbon.js +0 -63
- package/dist/instrument-rail.d.ts +0 -1
- package/dist/instrument-rail.js +0 -2
- package/dist/useGlassRenderer-5I0YkI4t.js +0 -69
- package/dist/useSpecularTracking-BVRZsRHA.js +0 -26
- package/dist/useSpringMount-BJSHcLl3.js +0 -113
- /package/dist/{CollapsibleContent-CP9qF1v4.js → CollapsibleContent-Drow5WkV.js} +0 -0
- /package/dist/{DialogFooter-Gprw8H_A.js → DialogFooter-DufLHi0y.js} +0 -0
- /package/dist/{IconTooltip-yefK7cJc.js → IconTooltip-BrQ5p181.js} +0 -0
- /package/dist/{Input-DWQQIOC4.js → Input-B-F818RU.js} +0 -0
- /package/dist/{_plugin-vue_export-helper-ok8pgSl5.js → _plugin-vue_export-helper-DWghtRt7.js} +0 -0
- /package/dist/{constants-CS75AWHG.js → constants-C8NMonuo.js} +0 -0
- /package/dist/{presets-BKVyQfbt.js → presets-1OhFpaIC.js} +0 -0
- /package/dist/{prng-wHuHlNHE.js → prng-CjVgzjQT.js} +0 -0
- /package/dist/{resolveCanvasColor-BBiYfp8g.js → resolveCanvasColor-CRvVzOvP.js} +0 -0
- /package/dist/{useCanvas2D-ClrQuZtp.js → useCanvas2D-CSeH8h16.js} +0 -0
- /package/dist/{useGlobalDark-yhL4Wp-s.js → useGlobalDark-D7R9OypB.js} +0 -0
- /package/dist/{useIntersectionPause-Cc-H9ees.js → useIntersectionPause-DAdVPVp4.js} +0 -0
- /package/dist/{useInterval-Dsmqwi03.js → useInterval-D3USn0yc.js} +0 -0
- /package/dist/{useKeyboardShortcuts-Be3w_Rwk.js → useKeyboardShortcuts-i8tHd5WO.js} +0 -0
- /package/dist/{useScrollProgress-CAH8Ofwt.js → useScrollProgress-CcgmgMQt.js} +0 -0
- /package/dist/{useSortable-C8ReQ50P.js → useSortable-DnyGXKKY.js} +0 -0
- /package/dist/{useTextHighlight-DON84L8w.js → useTextHighlight-B3b10W6r.js} +0 -0
|
@@ -184,10 +184,28 @@
|
|
|
184
184
|
* surface). The grammar is single-event entrance + dwell + exit;
|
|
185
185
|
* the next toast (if any) enters on its own contract.
|
|
186
186
|
*
|
|
187
|
+
* §6 EASING-DOCTRINE EXEMPTION (AY.W-MOTION — DELIBERATE KEEP).
|
|
188
|
+
* Every glass-ui-OWNED entrance surface (`dialog-scale`, `pop`,
|
|
189
|
+
* `dropdown`, `fade-slide`, `dock-in`) rides the house `--spring-*`
|
|
190
|
+
* enter / `--ease-out`/`--ease-standard` exit vocabulary (the §6
|
|
191
|
+
* doctrine, tokens.css:162-190). The Toast does NOT — and that is
|
|
192
|
+
* BY DESIGN, not an unexamined default. The reka-ui `ToastRoot`
|
|
193
|
+
* primitive OWNS its data-state choreography: the entrance slide
|
|
194
|
+
* direction tracks the viewport origin AND the swipe-end gesture
|
|
195
|
+
* (`data-[swipe=end]:slide-out-to-right-full`), so the entrance/exit
|
|
196
|
+
* are coupled to reka's `tw-animate-css` data-state machinery. The §6
|
|
197
|
+
* spring vocabulary governs glass-ui-OWNED surfaces; the reka-Toast
|
|
198
|
+
* entrance is not one — re-authoring it onto a `<Transition>` would
|
|
199
|
+
* fork the primitive's swipe-coupled contract (and `tw-animate-css`
|
|
200
|
+
* is the shipped optionalPeer this contract depends on). The gate
|
|
201
|
+
* (proof:animation-coherence) carries the Toast surface in its
|
|
202
|
+
* REGISTER_ASSIGNMENT_ALLOW set so this keep reads as a gated,
|
|
203
|
+
* deliberate exemption.
|
|
204
|
+
*
|
|
187
205
|
* PRM is honoured at the `@media (prefers-reduced-motion: reduce)`
|
|
188
206
|
* block below — the slide motion retires; the fade-in/out
|
|
189
|
-
* remains. No source change
|
|
190
|
-
* documentation closure for the
|
|
207
|
+
* remains. No source motion change; this comment block IS the
|
|
208
|
+
* documentation closure for the toast contract row.
|
|
191
209
|
*/
|
|
192
210
|
|
|
193
211
|
/* ── Reduced motion: preserve fades, remove transform/scale motion ── */
|
|
@@ -96,12 +96,24 @@
|
|
|
96
96
|
references `"Fira Code"` first then the fallback chain. */
|
|
97
97
|
|
|
98
98
|
/* Scale tokens */
|
|
99
|
-
--type-admin-label: 0.625rem; /* 10px */
|
|
100
|
-
--type-micro: 0.6875rem; /* 11px */
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
--type-admin-label: 0.625rem; /* 10px — fixed sub-control micro (NOT fluid) */
|
|
100
|
+
--type-micro: 0.6875rem; /* 11px — fixed sub-control micro (NOT fluid) */
|
|
101
|
+
/* BODY/CONTROL register (AY.W-SCALE1 — the desktop-fluid half of corpus #4):
|
|
102
|
+
a GENTLE clamp() viewport base so the control/body register grows ~1-2 steps
|
|
103
|
+
on a wide display (the 27" "font too small" the user flagged) WITHOUT a
|
|
104
|
+
media-query staircase. The <min> of every clamp is the rung's prior fixed rem
|
|
105
|
+
— byte-identical at narrow/mobile (no shipped-narrow reflow; the coarse 1.5×
|
|
106
|
+
--ui-scale still lifts the comfort axis ON TOP). The vw slope is the body
|
|
107
|
+
register's GENTLE slope (not the φ-display ladder's aggressive vw) — the
|
|
108
|
+
"non-contrived" bar. The vw fluid term lives HERE (the typographic base),
|
|
109
|
+
exactly ONCE; the --ui-scale comfort scalar multiplies it exactly ONCE LATER
|
|
110
|
+
(tokens.css --control-text/-sm) — NO double-vw under coarse. The φ-identity
|
|
111
|
+
rungs below (--type-subheading/-heading/-title + the --type-display-* ladder)
|
|
112
|
+
are EXCLUDED — a hero/title is a typographic identity, not a control. */
|
|
113
|
+
--type-caption: clamp(0.75rem, 0.71rem + 0.21vw, 1rem); /* 12px floor — --control-text-sm source */
|
|
114
|
+
--type-small: clamp(0.875rem, 0.8rem + 0.25vw, 1.25rem); /* 14px floor — --control-text source (the workhorse) */
|
|
115
|
+
--type-body: clamp(1rem, 0.92rem + 0.27vw, 1.375rem); /* 16px floor — global body cascade */
|
|
116
|
+
--type-prose: clamp(1.125rem, 1.04rem + 0.28vw, 1.5rem); /* 18px floor — long-form prose */
|
|
105
117
|
--type-subheading: 1.272rem; /* 20.4px — √φ */
|
|
106
118
|
--type-heading: 1.618rem; /* 25.9px — φ */
|
|
107
119
|
--type-title: 2.058rem; /* 32.9px — φ^(3/2) */
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/* utilities/a11y-overrides.css
|
|
2
|
+
The accessibility + capability tail — @media (prefers-reduced-motion: reduce) (+ the .no-transition class), @media (forced-colors: active) focus/silhouette, @media (pointer: coarse) touch-target floor, and the @utility touch-hit-area. LAST in cascade.
|
|
3
|
+
Carved from the utilities.css cascade root; @import-ed by utilities.css in
|
|
4
|
+
cascade order. See docs/precepts/design-idioms.md §cohesion-aware partials. */
|
|
5
|
+
/* ── Reduced motion: nuanced — preserve opacity, remove spatial motion ── */
|
|
6
|
+
@media (prefers-reduced-motion: reduce) {
|
|
7
|
+
*:not([data-allow-motion]) {
|
|
8
|
+
animation-duration: 0.01ms !important;
|
|
9
|
+
animation-iteration-count: 1 !important;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* Keep opacity transitions (safe, non-spatial) but shorten */
|
|
13
|
+
*:not([data-allow-motion]) {
|
|
14
|
+
transition-duration: 0.1s !important;
|
|
15
|
+
transition-property: opacity, color, background-color, border-color, box-shadow !important;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* ── No-transition class (for theme switches, etc.) ── */
|
|
20
|
+
html.no-transition,
|
|
21
|
+
html.no-transition *,
|
|
22
|
+
html.no-transition *::before,
|
|
23
|
+
html.no-transition *::after {
|
|
24
|
+
transition-duration: 0s !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ── Forced-colors focus + silhouette rung (AQ.W2 §5 · generalized AX.W36) ────
|
|
28
|
+
Windows High Contrast / forced-colors mode STRIPS `box-shadow` — so the
|
|
29
|
+
glass focus rings (box-shadow + `outline: none`) vanish, leaving keyboard
|
|
30
|
+
users with no visible focus. Restore a real `outline` keyed to the system
|
|
31
|
+
`Highlight` color (outline survives forced-colors; box-shadow does not). The
|
|
32
|
+
box-shadow ring stays the primary in normal mode (it carries the glass
|
|
33
|
+
aesthetic) — these two are mutually exclusive by media query, NOT a parallel
|
|
34
|
+
path.
|
|
35
|
+
|
|
36
|
+
AX.W36 — the focus-survival selector set is GENERALIZED to the broader
|
|
37
|
+
interactive surface: the dock CONTROLS (`.dock-icon-button` / `.dock-tab-button`
|
|
38
|
+
/ `.dock-select-trigger` / `.dock-dropdown-trigger`) + the pill button base
|
|
39
|
+
(`.btn-pill`) all carry a box-shadow focus ring (dock.css / utilities.css) that
|
|
40
|
+
vanishes under WHC just like the original five. This is the SAME `Highlight`
|
|
41
|
+
outline rung extended to cover them — ONE block, ONE path (the glass-language
|
|
42
|
+
structure-survival skin for the tier panes / StatusDot / floating surfaces lives
|
|
43
|
+
co-located with the ladder it skins, in glass.css).
|
|
44
|
+
|
|
45
|
+
`forced-color-adjust: none` is deliberately NOT used — glass-ui's glassmorphic
|
|
46
|
+
chrome is decorative and yields to the user's forced palette (css forced-colors
|
|
47
|
+
guidance). Baseline Widely Available; this IS the fallback mechanism (it only
|
|
48
|
+
activates under forced-colors), so no nested guard. */
|
|
49
|
+
@media (forced-colors: active) {
|
|
50
|
+
.focus-ring:focus-visible,
|
|
51
|
+
.glass-btn:focus-visible,
|
|
52
|
+
.interactive-item:focus-visible,
|
|
53
|
+
.btn-pill:focus-visible,
|
|
54
|
+
.dock-icon-button:focus-visible,
|
|
55
|
+
.dock-tab-button:focus-visible,
|
|
56
|
+
.dock-select-trigger:focus-visible,
|
|
57
|
+
.dock-dropdown-trigger:focus-visible,
|
|
58
|
+
.input-pill:focus,
|
|
59
|
+
.input-pill:focus-visible {
|
|
60
|
+
outline: 2px solid Highlight;
|
|
61
|
+
outline-offset: 2px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Structural edges borne ONLY by box-shadow (the hairline catch-light + the
|
|
65
|
+
dock SHELL pill edge) also vanish — restore a real border so the silhouette
|
|
66
|
+
survives. CanvasText is the system text/border color. The `.glass-dock`
|
|
67
|
+
shell is OUT of the glass-material group BY DESIGN (it hand-rolls a parallel
|
|
68
|
+
surface — see glass.css), so it keeps its WHC edge HERE; the five-rung ladder
|
|
69
|
+
+ `.glass-card` get their WHC border from the co-located glass-language skin
|
|
70
|
+
in glass.css (one source per surface family, no double-declaration). */
|
|
71
|
+
.hairline-accent,
|
|
72
|
+
.glass-dock {
|
|
73
|
+
border: 1px solid CanvasText;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* ── Coarse-pointer touch-target floor (AQ.W3 §7) ───────────────────────────
|
|
78
|
+
General-surface companion to the dock-scoped R0G-6 floor (dock.css). On
|
|
79
|
+
coarse pointers the small icon-button/trigger surfaces OUTSIDE the dock lift
|
|
80
|
+
to the WCAG 2.5.5 (44px) minimum — ONE amendment retiring the per-consumer
|
|
81
|
+
`min-h-[44px]` one-liners. Token-driven (`--touch-target`); fine-pointer
|
|
82
|
+
byte-identical. Targets `Button size="icon"` (via the `data-size="icon"`
|
|
83
|
+
attr Button.vue reflects), ExpandableContainer + SegmentedTabs (responsive
|
|
84
|
+
mobile Select) triggers.
|
|
85
|
+
`min-block/inline-size` only RAISES — a larger explicit size is never lost. */
|
|
86
|
+
@media (pointer: coarse) {
|
|
87
|
+
[data-size="icon"],
|
|
88
|
+
.expandable-container__trigger,
|
|
89
|
+
.segmented-tabs__trigger {
|
|
90
|
+
min-block-size: var(--touch-target, 2.75rem);
|
|
91
|
+
min-inline-size: var(--touch-target, 2.75rem);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ── @utility touch-hit-area (AY.W-SCALE2) ──────────────────────────────────
|
|
96
|
+
The hit-target is DECOUPLED from the visual size: a 16px Checkbox stays
|
|
97
|
+
16px visually, but on a COARSE pointer it acquires a ≥44px pointer-receptive
|
|
98
|
+
hit-rect via a centred `::before` overlay (WCAG 2.5.5). The six sub-44 form
|
|
99
|
+
atoms (Switch / Checkbox / RadioGroupItem / Slider-thumb / TagsInput-delete /
|
|
100
|
+
MultiSelect-remove-X) compose this ONE shared utility — DRY, one source, ≥2
|
|
101
|
+
consumers — instead of per-atom `min-h-[44px]` balloons.
|
|
102
|
+
|
|
103
|
+
DIVERGENCE-WITH-RATIONALE from the timeline precedent (ContinuousMarkers.vue
|
|
104
|
+
`.continuous-dot::before`, SegmentedTimeline `.boundary-dot::before`): the
|
|
105
|
+
timeline uses a FIXED symmetric `inset: calc((--touch-target - dot-size)/-2)`
|
|
106
|
+
— exact ONLY because its dot is a KNOWN fixed square. Our atoms are NOT square
|
|
107
|
+
and NOT a known size (a 24×44 Switch, a 16px Checkbox, a ~7px-wide Slider cap),
|
|
108
|
+
so a single symmetric inset would under/over-shoot one axis. This utility uses
|
|
109
|
+
the size-AGNOSTIC centred-min-size form: `min-width/min-height: var(--touch-
|
|
110
|
+
target)` + `top/left:50%` + `translate:-50% -50%` floors BOTH dimensions at
|
|
111
|
+
44px for ANY visual size, the generalization the timeline's known-square inset
|
|
112
|
+
cannot do.
|
|
113
|
+
|
|
114
|
+
COARSE-ONLY (the fine-pointer-byte-identical invariant, STRICTER than the
|
|
115
|
+
timeline whose `::before` exists at fine pointer too): the DEFAULT (fine)
|
|
116
|
+
path declares NO overlay box — `::before` has no `content`, so its min-width/
|
|
117
|
+
height resolve to `auto`/0 and the composited rect equals the bare visual box
|
|
118
|
+
(the AX.W51 fine-pointer-identical invariant). Only the nested `@media
|
|
119
|
+
(pointer: coarse)` block mints the `content:""` + the 44px overlay.
|
|
120
|
+
|
|
121
|
+
NO new floor token (D4): the overlay reads `var(--touch-target)`. */
|
|
122
|
+
@utility touch-hit-area {
|
|
123
|
+
position: relative;
|
|
124
|
+
|
|
125
|
+
@media (pointer: coarse) {
|
|
126
|
+
&::before {
|
|
127
|
+
content: "";
|
|
128
|
+
position: absolute;
|
|
129
|
+
top: 50%;
|
|
130
|
+
left: 50%;
|
|
131
|
+
translate: -50% -50%;
|
|
132
|
+
min-width: var(--touch-target, 2.75rem);
|
|
133
|
+
min-height: var(--touch-target, 2.75rem);
|
|
134
|
+
/* Inherit the host's pointer-events so a tap within the halo
|
|
135
|
+
registers on the atom; the overlay itself is decorative (no
|
|
136
|
+
paint), so it never occludes the host's own interaction. */
|
|
137
|
+
pointer-events: auto;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* utilities/animate.css
|
|
2
|
+
The popover/dropdown shared @utility animation pair — popover-animate + slide-in-from-side (the data-state / data-side entry choreography for popover-class containers). FIRST (before the @layer components block, matching source order).
|
|
3
|
+
Carved from the utilities.css cascade root; @import-ed by utilities.css in
|
|
4
|
+
cascade order. See docs/precepts/design-idioms.md §cohesion-aware partials. */
|
|
5
|
+
/* ── Popover/dropdown shared animation ──
|
|
6
|
+
`@utility` form (V.W3.T8 / A5 §5.9 standardisation): data-state animation
|
|
7
|
+
pair for popover-class containers (Popover, DropdownMenu, ContextMenu,
|
|
8
|
+
Tooltip, HoverCard, Select). Composed alongside `.slide-in-from-side`
|
|
9
|
+
for direction-keyed entries. */
|
|
10
|
+
@utility popover-animate {
|
|
11
|
+
@apply data-[state=open]:animate-in data-[state=closed]:animate-out
|
|
12
|
+
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0
|
|
13
|
+
data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* ── Slide-in entry by side data-attr ──
|
|
17
|
+
`@utility` form (V.W3.T8). Side-keyed slide entry that pairs with
|
|
18
|
+
reka-ui's `data-side` (`top|right|bottom|left`). The animation
|
|
19
|
+
direction inverts each side so panels enter from outside the
|
|
20
|
+
anchor's edge. */
|
|
21
|
+
@utility slide-in-from-side {
|
|
22
|
+
@apply data-[side=bottom]:slide-in-from-top-2
|
|
23
|
+
data-[side=left]:slide-in-from-right-2
|
|
24
|
+
data-[side=right]:slide-in-from-left-2
|
|
25
|
+
data-[side=top]:slide-in-from-bottom-2;
|
|
26
|
+
}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/* utilities/base.css
|
|
2
|
+
The @layer components base half — section-description, labeled-field, popover-content, scrollbar, focus-ring, hairline-accent, interactive-item, tap-squish, status-dot, depth-text, preserve-3d, ios input fix, scroll-fade masks, deferred-section, scroll-timeline host, shimmer text, keyboard key.
|
|
3
|
+
Carved from the utilities.css cascade root; @import-ed by utilities.css in
|
|
4
|
+
cascade order. See docs/precepts/design-idioms.md §cohesion-aware partials. */
|
|
5
|
+
@layer components {
|
|
6
|
+
/* ── Section description (V.W3.T7) ──────────────────────────────
|
|
7
|
+
Canonical recipe for the `<Section>` primitive's description
|
|
8
|
+
paragraph. Composes the body type + muted-foreground color in
|
|
9
|
+
one declaration so consumers don't fight twMerge's
|
|
10
|
+
typography-class collapse. */
|
|
11
|
+
.section-description {
|
|
12
|
+
font-size: var(--type-body);
|
|
13
|
+
color: var(--muted-foreground);
|
|
14
|
+
line-height: 1.5;
|
|
15
|
+
text-wrap: pretty; /* AQ.W3 §W3.3 — prose-register orphan/river fix */
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* ── Labeled-field label (V.W3.T5 / A5 §5.5) ────────────────────
|
|
19
|
+
Canonical recipe for `<LabeledField>`'s tooltip-wrapped label
|
|
20
|
+
layer. Four sibling wrappers (LabeledInput, LabeledSelect,
|
|
21
|
+
LabeledSlider, LabeledSwitch) used to repeat this literal across
|
|
22
|
+
their templates; promoting it to a utility lets the parent SFC
|
|
23
|
+
own one canonical declaration. */
|
|
24
|
+
.labeled-field-label {
|
|
25
|
+
font-family: var(--font-display);
|
|
26
|
+
font-size: var(--type-body);
|
|
27
|
+
/* AQ.W4 §W3.1c — the label color reads the group-state variable so the
|
|
28
|
+
`:has(:user-invalid)` rule below reddens it (one source of the
|
|
29
|
+
override value, shared with the `.has-error` fallback class). */
|
|
30
|
+
color: var(--field-label-color, var(--muted-foreground));
|
|
31
|
+
cursor: help;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* AQ.W4 §W3.1c — LabeledField group error highlight. When any descendant
|
|
35
|
+
control is `:user-invalid`, the whole field group marks (the label
|
|
36
|
+
reddens via `--field-label-color`, the error region reveals). Scoped to
|
|
37
|
+
`.labeled-field` — never `body`, never a bare element. `:has()` Baseline
|
|
38
|
+
Widely; the `.has-error` / `.has-valid` fallback classes (toggled by the
|
|
39
|
+
`useUserInvalidAria` fallback path) are the SOLE degradation for engines
|
|
40
|
+
without `:has()`/`:user-invalid` (not a live+dead alias). */
|
|
41
|
+
.labeled-field {
|
|
42
|
+
--field-label-color: var(--muted-foreground);
|
|
43
|
+
}
|
|
44
|
+
.labeled-field:has(:user-invalid),
|
|
45
|
+
.labeled-field.has-error {
|
|
46
|
+
--field-label-color: var(--destructive);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* The error region: hidden at rest, revealed once a descendant is
|
|
50
|
+
`:user-invalid` (or the `.has-error` fallback class is set). Non-color
|
|
51
|
+
reinforcement for the validity tint — the error TEXT is the primary
|
|
52
|
+
cue, the border/bg shift the supplement (forms guide: never color
|
|
53
|
+
alone). */
|
|
54
|
+
.labeled-field-error {
|
|
55
|
+
display: none;
|
|
56
|
+
font-size: var(--type-small);
|
|
57
|
+
color: var(--destructive);
|
|
58
|
+
margin-block-start: 0.25rem;
|
|
59
|
+
}
|
|
60
|
+
.labeled-field:has(:user-invalid) .labeled-field-error,
|
|
61
|
+
.labeled-field.has-error .labeled-field-error {
|
|
62
|
+
display: block;
|
|
63
|
+
}
|
|
64
|
+
/* Hide the error text once the field reads valid (the user corrected it). */
|
|
65
|
+
.labeled-field:has(:user-valid) .labeled-field-error,
|
|
66
|
+
.labeled-field.has-valid .labeled-field-error {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ── Popover-content recipe (V.W3.T3 / A5 §3.2) ─────────────────
|
|
71
|
+
Canonical recipe for floating-tier portal containers
|
|
72
|
+
(PopoverContent, DropdownMenuContent, SelectContent, etc.).
|
|
73
|
+
Covers radius + outline + popover-foreground; consumers compose
|
|
74
|
+
this with `.glass-floating` (bg + blur + border + shadow), with
|
|
75
|
+
`.popover-animate` (data-state animation), and with the per-host
|
|
76
|
+
z-rung. The floating-tier shadow comes from
|
|
77
|
+
`--glass-shadow-floating` via `.glass-floating`, replacing the
|
|
78
|
+
`shadow-md`/`shadow-lg` literals that bypassed the canonical
|
|
79
|
+
cascade. */
|
|
80
|
+
.popover-content {
|
|
81
|
+
border-radius: var(--radius-panel);
|
|
82
|
+
color: var(--popover-foreground);
|
|
83
|
+
outline: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ── Scrollbar ── */
|
|
87
|
+
.scrollbar-hidden {
|
|
88
|
+
scrollbar-width: none;
|
|
89
|
+
}
|
|
90
|
+
.scrollbar-hidden::-webkit-scrollbar {
|
|
91
|
+
display: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* AQ.W3 §W3.4 — tokenized thin scrollbar. Standard `scrollbar-width` +
|
|
95
|
+
`scrollbar-color` (Baseline Widely, Chromium 121+) is the primary path,
|
|
96
|
+
reading `--scrollbar-{thumb,track}` (auto-dark via `--muted-foreground`).
|
|
97
|
+
The legacy `::-webkit-scrollbar` family is the SOLE fallback for older
|
|
98
|
+
WebKit/Blink, gated on `@supports not (scrollbar-color: auto)` so modern
|
|
99
|
+
engines never paint it — not a live+dead alias. */
|
|
100
|
+
.scrollbar-thin {
|
|
101
|
+
scrollbar-width: thin;
|
|
102
|
+
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
|
|
103
|
+
}
|
|
104
|
+
@supports not (scrollbar-color: auto) {
|
|
105
|
+
.scrollbar-thin::-webkit-scrollbar {
|
|
106
|
+
width: 8px;
|
|
107
|
+
height: 8px;
|
|
108
|
+
}
|
|
109
|
+
.scrollbar-thin::-webkit-scrollbar-track {
|
|
110
|
+
background: var(--scrollbar-track);
|
|
111
|
+
}
|
|
112
|
+
.scrollbar-thin::-webkit-scrollbar-thumb {
|
|
113
|
+
background: var(--scrollbar-thumb);
|
|
114
|
+
border-radius: var(--radius-pill);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* ── Focus ring — auto-activates on :focus-visible ── */
|
|
119
|
+
.focus-ring:focus-visible {
|
|
120
|
+
outline: none;
|
|
121
|
+
border-radius: var(--radius-pill);
|
|
122
|
+
box-shadow: var(--focus-ring-shadow);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ── Hairline-accent — 0.5px catch-light + under-shadow pair ──
|
|
126
|
+
Composes the canonical `--border-hairline` token (tokens.css §
|
|
127
|
+
Glass-decorative). Adopt at any surface that wants the canonical
|
|
128
|
+
2-stop hairline (dock surfaces, instrument-chassis). Auto-mirrors
|
|
129
|
+
in dark via the .dark token override. */
|
|
130
|
+
.hairline-accent {
|
|
131
|
+
box-shadow: var(--border-hairline);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ── Interactive item (hover bg + focus ring + active scale) ── */
|
|
135
|
+
.interactive-item {
|
|
136
|
+
/* AQ.W3 §W3.2 identity base */
|
|
137
|
+
scale: 1;
|
|
138
|
+
border-radius: var(--radius-lg);
|
|
139
|
+
user-select: none;
|
|
140
|
+
transition:
|
|
141
|
+
background-color var(--duration-fast) var(--ease-standard),
|
|
142
|
+
color var(--duration-fast) var(--ease-standard),
|
|
143
|
+
border-color var(--duration-fast) var(--ease-standard),
|
|
144
|
+
box-shadow var(--duration-fast) var(--ease-standard),
|
|
145
|
+
scale var(--duration-fast) var(--ease-standard);
|
|
146
|
+
}
|
|
147
|
+
.interactive-item:hover {
|
|
148
|
+
background-color: color-mix(in srgb, var(--accent) 50%, transparent);
|
|
149
|
+
}
|
|
150
|
+
.interactive-item:focus-visible {
|
|
151
|
+
outline: none;
|
|
152
|
+
box-shadow: var(--focus-ring-shadow);
|
|
153
|
+
}
|
|
154
|
+
.interactive-item:active {
|
|
155
|
+
/* AW.W31.a — fold the residual literal press scale onto the canonical
|
|
156
|
+
`--scale-press*` cohort (the prior `0.98` was the sole per-atom press
|
|
157
|
+
literal surviving the W2/W3/W25 sweeps). `--scale-press-sm` (0.97) is
|
|
158
|
+
the soft press rung the button + slider recipes consume — ONE press
|
|
159
|
+
vocabulary, no per-atom literal. The 0.98→0.97 delta is sub-perceptual. */
|
|
160
|
+
scale: var(--scale-press-sm);
|
|
161
|
+
}
|
|
162
|
+
.interactive-item:disabled,
|
|
163
|
+
.interactive-item[data-disabled] {
|
|
164
|
+
pointer-events: none;
|
|
165
|
+
opacity: var(--opacity-disabled);
|
|
166
|
+
cursor: not-allowed;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* ── Tap-squish — universal press-state choreography ──
|
|
170
|
+
AL-W10 SLIM (X6 §M-1 + Y7 §3 + DESIGN.md §L3). I compose this
|
|
171
|
+
class onto every interactive surface that wants the iOS tap-
|
|
172
|
+
squish idiom; the press scales to `--scale-press` (0.96, the
|
|
173
|
+
canonical iOS `.regular` control rung). I keep this as a single
|
|
174
|
+
canonical rung — NOT a 3-rung ladder. The one outlier I leave
|
|
175
|
+
alone is the button `0.97` (`--scale-press-btn`), which consumes
|
|
176
|
+
its own slightly-softer token directly. The dock control now
|
|
177
|
+
tracks the canonical `--scale-press` (0.96) too (AT.W7-dock-b
|
|
178
|
+
press canon — the prior deeper `0.92` was retired to ONE source).
|
|
179
|
+
|
|
180
|
+
AX.W52 §6 doctrine — the `scale` register is reconciled onto
|
|
181
|
+
`--spring-smooth` (was `--spring-snappy`), the ONE button/interactive
|
|
182
|
+
scale register the §6 easing doctrine records and the gate asserts
|
|
183
|
+
across `.btn-pill`/`.tap-squish`/`.glass-btn`/`btn-interactive`. At
|
|
184
|
+
ζ=0.86 `--spring-smooth` settles a press crisply with a sub-perceptual
|
|
185
|
+
(~0.5%) peak — no visible bounce — so press still reads alive while
|
|
186
|
+
hover reads as a smooth glide on the SAME spring.
|
|
187
|
+
|
|
188
|
+
The transition lists the SURFACE legs (bg/border/box-shadow/color/
|
|
189
|
+
opacity) on the bezier `--ease-standard` alongside the spring `scale`
|
|
190
|
+
leg — the SAME coherent set `.btn-pill` carries. This is load-bearing:
|
|
191
|
+
`.tap-squish` and `.btn-pill` are co-composed on the button base and
|
|
192
|
+
this `transition` shorthand would otherwise CLOBBER `.btn-pill`'s
|
|
193
|
+
surface legs down to a scale-only animation (the cascade bug that left
|
|
194
|
+
every button transitioning ONLY `scale` — the live-readback RED). With
|
|
195
|
+
both classes carrying the full set, whichever wins the surface cross-
|
|
196
|
+
fade survives. On a non-button press surface the extra legs are inert
|
|
197
|
+
unless that prop changes, in which case a smooth cross-fade is the
|
|
198
|
+
desired interactive read anyway.
|
|
199
|
+
|
|
200
|
+
Under PRM I retire the press transform entirely and lean on the
|
|
201
|
+
consumer's own hover/active bg-tint cascade to acknowledge the
|
|
202
|
+
press. */
|
|
203
|
+
.tap-squish {
|
|
204
|
+
/* AQ.W3 §W3.2 identity base */
|
|
205
|
+
scale: 1;
|
|
206
|
+
transition:
|
|
207
|
+
background-color var(--duration-fast) var(--ease-standard),
|
|
208
|
+
border-color var(--duration-fast) var(--ease-standard),
|
|
209
|
+
box-shadow var(--duration-fast) var(--ease-standard),
|
|
210
|
+
color var(--duration-fast) var(--ease-standard),
|
|
211
|
+
opacity var(--duration-fast) var(--ease-standard),
|
|
212
|
+
scale var(--duration-fast) var(--spring-smooth);
|
|
213
|
+
transform-origin: center center;
|
|
214
|
+
}
|
|
215
|
+
.tap-squish:active {
|
|
216
|
+
scale: var(--scale-press);
|
|
217
|
+
}
|
|
218
|
+
@media (prefers-reduced-motion: reduce) {
|
|
219
|
+
.tap-squish:active {
|
|
220
|
+
/* Reset to the longhand identity (not `transform: none`) so the
|
|
221
|
+
press scale is neutralized under PRM. */
|
|
222
|
+
scale: 1;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* ── Status dot indicator ── */
|
|
227
|
+
.status-dot {
|
|
228
|
+
display: inline-block;
|
|
229
|
+
width: 0.5rem;
|
|
230
|
+
height: 0.5rem;
|
|
231
|
+
border-radius: var(--radius-pill);
|
|
232
|
+
flex-shrink: 0;
|
|
233
|
+
transition:
|
|
234
|
+
color var(--duration-fast) var(--ease-standard),
|
|
235
|
+
background var(--duration-fast) var(--ease-standard),
|
|
236
|
+
box-shadow var(--duration-fast) var(--ease-standard);
|
|
237
|
+
}
|
|
238
|
+
/* ── Depth text (layered offset stamp) ──
|
|
239
|
+
AW.W26 — composes the `--text-shadow-depth` @theme identity token (the
|
|
240
|
+
hard offset stack + soft ambient tail) instead of a hand-rolled multi-stop
|
|
241
|
+
literal. The token holds the stack inside the `@theme` defs (gate 4) and
|
|
242
|
+
re-tints under `.dark` via `--shadow`/`--shadow-color` BY CONSTRUCTION. */
|
|
243
|
+
.depth-text {
|
|
244
|
+
--depth-color-primary: var(--primary);
|
|
245
|
+
|
|
246
|
+
color: var(--depth-color-primary);
|
|
247
|
+
text-shadow: var(--text-shadow-depth);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* ── 3D preserve ── */
|
|
251
|
+
.preserve-3d {
|
|
252
|
+
transform-style: preserve-3d;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* ── iOS input font-size fix (prevent auto-zoom) ── */
|
|
256
|
+
.ios input,
|
|
257
|
+
.ios select,
|
|
258
|
+
.ios textarea,
|
|
259
|
+
.ios [contenteditable] {
|
|
260
|
+
font-size: max(1rem, 1em);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* ── Scroll fade masks ──
|
|
264
|
+
Single-source `mask-image` (AV.W16 TW7): the `-webkit-` companion is
|
|
265
|
+
dropped — Tailwind v4's Lightning CSS build pipeline auto-prefixes per
|
|
266
|
+
the browserslist targets, mirroring the glass ladder's single-source
|
|
267
|
+
`backdrop-filter` (glass.css). NOTE: this is the consistency cut; it
|
|
268
|
+
does NOT conflict with W15's `@supports`-gated older-Safari mask
|
|
269
|
+
fallback (that fallback is the distinct case where the companion is
|
|
270
|
+
genuinely needed and W15 gates it). */
|
|
271
|
+
.scroll-fade-mask {
|
|
272
|
+
mask-image: linear-gradient(to right, transparent, black var(--mask-fade-width), black calc(100% - var(--mask-fade-width)), transparent);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.scroll-fade-top {
|
|
276
|
+
mask-image: linear-gradient(to bottom, transparent, black var(--mask-fade-width));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.scroll-fade-bottom {
|
|
280
|
+
mask-image: linear-gradient(to bottom, black calc(100% - var(--mask-fade-width)), transparent);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.scroll-fade-y {
|
|
284
|
+
mask-image: linear-gradient(to bottom, transparent, black var(--mask-fade-width), black calc(100% - var(--mask-fade-width)), transparent);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* ── Deferred section — render-skip an offscreen subtree (AQ.W3 §5) ──────
|
|
288
|
+
`content-visibility: auto` skips layout/paint/style of an offscreen
|
|
289
|
+
subtree — the INP-under-load lever (fourier γ, muster, speedtest, words).
|
|
290
|
+
`contain-intrinsic-size: auto <estimate>` is measurement-safe: the `auto`
|
|
291
|
+
prefix makes the engine REMEMBER the last-rendered size (no scroll-jump on
|
|
292
|
+
re-entry); plain `<estimate>` freezes the section + thrashes the scrollbar
|
|
293
|
+
— the trap this closes. Estimate is token-driven (`--deferred-section-
|
|
294
|
+
size`, default 30rem). `.deferred-section--cached` →
|
|
295
|
+
`content-visibility: hidden` (always skipped, state CACHED — cheaper to
|
|
296
|
+
re-show than `display:none`). Baseline Widely; unsupporting engines render
|
|
297
|
+
normally. JS HOOK: the engine fires `contentvisibilityautostatechange`
|
|
298
|
+
{ skipped } at the render-skip boundary — pair with `useRAFLoop`
|
|
299
|
+
pause/resume: `el.addEventListener('contentvisibilityautostatechange',
|
|
300
|
+
e => e.skipped ? loop.pause() : loop.resume())`. */
|
|
301
|
+
.deferred-section {
|
|
302
|
+
content-visibility: auto;
|
|
303
|
+
contain-intrinsic-size: auto var(--deferred-section-size, 30rem);
|
|
304
|
+
}
|
|
305
|
+
.deferred-section--cached {
|
|
306
|
+
content-visibility: hidden;
|
|
307
|
+
contain-intrinsic-size: auto var(--deferred-section-size, 30rem);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* ── Card scroll-timeline host (AI.W1-α) ───────────────────────────────
|
|
311
|
+
Canonical scroll-overflow host that emits the `--card-scroll` named
|
|
312
|
+
scroll-timeline consumed by `<CardHeader shrink>`. Apply to the
|
|
313
|
+
scroll-overflow ancestor (typically the `<Card>` itself OR a wrapper
|
|
314
|
+
inside it that carries `overflow-y: auto`).
|
|
315
|
+
|
|
316
|
+
`contain: layout style paint` isolates the named timeline so child
|
|
317
|
+
animations respond to THIS host's scroll only — not to portal-
|
|
318
|
+
triggered layout shifts in ancestor containers (the load-bearing
|
|
319
|
+
isolation guarantee the value.js `PaneHeader.vue:18-29` comment
|
|
320
|
+
called out and the AI.W1 spec §1.2 ratified as canon).
|
|
321
|
+
|
|
322
|
+
Disambiguated from `.scroll-fade-*` (mask-image fade gradient at
|
|
323
|
+
the container's leading/trailing edge) — `.card-scroll-host` does
|
|
324
|
+
NOT paint any visual; it only emits the timeline. */
|
|
325
|
+
.card-scroll-host {
|
|
326
|
+
contain: layout style paint;
|
|
327
|
+
scroll-timeline: --card-scroll block;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* ── Shimmer text effects ──
|
|
331
|
+
The text-fill + background-clip composition is load-bearing visual
|
|
332
|
+
(the gold gradient itself); only the `animation:` line is wrapped in
|
|
333
|
+
the PRM no-preference bracket so PRM users see the static gradient
|
|
334
|
+
without the slide animation. */
|
|
335
|
+
.gold-shimmer {
|
|
336
|
+
background: linear-gradient(90deg, var(--color-gold-dark), var(--color-gold-light), var(--color-gold), var(--color-gold-light), var(--color-gold-dark));
|
|
337
|
+
background-size: 250% 100%;
|
|
338
|
+
background-clip: text;
|
|
339
|
+
-webkit-background-clip: text;
|
|
340
|
+
color: transparent;
|
|
341
|
+
}
|
|
342
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
343
|
+
.gold-shimmer {
|
|
344
|
+
animation: gold-shimmer-slide var(--duration-shimmer) linear infinite;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* ── Keyboard key ── */
|
|
349
|
+
.kbd {
|
|
350
|
+
display: inline-flex;
|
|
351
|
+
align-items: center;
|
|
352
|
+
justify-content: center;
|
|
353
|
+
min-height: 1.5rem;
|
|
354
|
+
min-width: 1.5rem;
|
|
355
|
+
padding: 0 0.375rem;
|
|
356
|
+
font-family: var(--font-mono);
|
|
357
|
+
font-size: var(--type-micro);
|
|
358
|
+
background: var(--muted);
|
|
359
|
+
border: 1px solid var(--border);
|
|
360
|
+
border-radius: var(--radius-sm);
|
|
361
|
+
box-shadow: 0 1px 0 1px color-mix(in srgb, var(--border) 30%, transparent);
|
|
362
|
+
line-height: 1;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
}
|