@wildo-ai/presets-components-3d 1.1.6

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.
Files changed (102) hide show
  1. package/LICENSE +34 -0
  2. package/dist/esm/frame/frame-3d-style.d.ts +156 -0
  3. package/dist/esm/frame/frame-3d-style.d.ts.map +1 -0
  4. package/dist/esm/frame/frame-3d-style.js +229 -0
  5. package/dist/esm/frame/frame-3d-style.js.map +1 -0
  6. package/dist/esm/frame/frame-appearance.d.ts +99 -0
  7. package/dist/esm/frame/frame-appearance.d.ts.map +1 -0
  8. package/dist/esm/frame/frame-appearance.js +207 -0
  9. package/dist/esm/frame/frame-appearance.js.map +1 -0
  10. package/dist/esm/frame/frame-canvas.d.ts +63 -0
  11. package/dist/esm/frame/frame-canvas.d.ts.map +1 -0
  12. package/dist/esm/frame/frame-canvas.js +134 -0
  13. package/dist/esm/frame/frame-canvas.js.map +1 -0
  14. package/dist/esm/frame/frame-canvas.lazy.d.ts +21 -0
  15. package/dist/esm/frame/frame-canvas.lazy.d.ts.map +1 -0
  16. package/dist/esm/frame/frame-canvas.lazy.js +31 -0
  17. package/dist/esm/frame/frame-canvas.lazy.js.map +1 -0
  18. package/dist/esm/frame/frame-color.d.ts +24 -0
  19. package/dist/esm/frame/frame-color.d.ts.map +1 -0
  20. package/dist/esm/frame/frame-color.js +52 -0
  21. package/dist/esm/frame/frame-color.js.map +1 -0
  22. package/dist/esm/frame/frame-driver.d.ts +60 -0
  23. package/dist/esm/frame/frame-driver.d.ts.map +1 -0
  24. package/dist/esm/frame/frame-driver.js +207 -0
  25. package/dist/esm/frame/frame-driver.js.map +1 -0
  26. package/dist/esm/frame/frame-renderer.d.ts +141 -0
  27. package/dist/esm/frame/frame-renderer.d.ts.map +1 -0
  28. package/dist/esm/frame/frame-renderer.js +635 -0
  29. package/dist/esm/frame/frame-renderer.js.map +1 -0
  30. package/dist/esm/frame/frame-shaders.d.ts +30 -0
  31. package/dist/esm/frame/frame-shaders.d.ts.map +1 -0
  32. package/dist/esm/frame/frame-shaders.js +97 -0
  33. package/dist/esm/frame/frame-shaders.js.map +1 -0
  34. package/dist/esm/frame/use-frame-appearance.d.ts +17 -0
  35. package/dist/esm/frame/use-frame-appearance.d.ts.map +1 -0
  36. package/dist/esm/frame/use-frame-appearance.js +38 -0
  37. package/dist/esm/frame/use-frame-appearance.js.map +1 -0
  38. package/dist/esm/index.d.ts +14 -0
  39. package/dist/esm/index.d.ts.map +1 -0
  40. package/dist/esm/index.js +14 -0
  41. package/dist/esm/index.js.map +1 -0
  42. package/dist/esm/layout/header-first-shell-container.d.ts +22 -0
  43. package/dist/esm/layout/header-first-shell-container.d.ts.map +1 -0
  44. package/dist/esm/layout/header-first-shell-container.js +31 -0
  45. package/dist/esm/layout/header-first-shell-container.js.map +1 -0
  46. package/dist/esm/layout/layout-3d-definition.d.ts +54 -0
  47. package/dist/esm/layout/layout-3d-definition.d.ts.map +1 -0
  48. package/dist/esm/layout/layout-3d-definition.js +106 -0
  49. package/dist/esm/layout/layout-3d-definition.js.map +1 -0
  50. package/dist/esm/layout/layout-3d-transition-choreography.d.ts +30 -0
  51. package/dist/esm/layout/layout-3d-transition-choreography.d.ts.map +1 -0
  52. package/dist/esm/layout/layout-3d-transition-choreography.js +43 -0
  53. package/dist/esm/layout/layout-3d-transition-choreography.js.map +1 -0
  54. package/dist/esm/layout/layout-3d-vocabulary.d.ts +118 -0
  55. package/dist/esm/layout/layout-3d-vocabulary.d.ts.map +1 -0
  56. package/dist/esm/layout/layout-3d-vocabulary.js +104 -0
  57. package/dist/esm/layout/layout-3d-vocabulary.js.map +1 -0
  58. package/dist/esm/layout/shell-layout-placement.d.ts +26 -0
  59. package/dist/esm/layout/shell-layout-placement.d.ts.map +1 -0
  60. package/dist/esm/layout/shell-layout-placement.js +18 -0
  61. package/dist/esm/layout/shell-layout-placement.js.map +1 -0
  62. package/dist/esm/layout-3d-main-container.d.ts +73 -0
  63. package/dist/esm/layout-3d-main-container.d.ts.map +1 -0
  64. package/dist/esm/layout-3d-main-container.js +124 -0
  65. package/dist/esm/layout-3d-main-container.js.map +1 -0
  66. package/dist/esm/register-3d-layout.d.ts +40 -0
  67. package/dist/esm/register-3d-layout.d.ts.map +1 -0
  68. package/dist/esm/register-3d-layout.js +72 -0
  69. package/dist/esm/register-3d-layout.js.map +1 -0
  70. package/dist/esm/shell-region-measurement.d.ts +75 -0
  71. package/dist/esm/shell-region-measurement.d.ts.map +1 -0
  72. package/dist/esm/shell-region-measurement.js +75 -0
  73. package/dist/esm/shell-region-measurement.js.map +1 -0
  74. package/dist/esm/spatial/spatial-camera.d.ts +106 -0
  75. package/dist/esm/spatial/spatial-camera.d.ts.map +1 -0
  76. package/dist/esm/spatial/spatial-camera.js +151 -0
  77. package/dist/esm/spatial/spatial-camera.js.map +1 -0
  78. package/dist/esm/spatial/spatial-environment.d.ts +6 -0
  79. package/dist/esm/spatial/spatial-environment.d.ts.map +1 -0
  80. package/dist/esm/spatial/spatial-environment.js +166 -0
  81. package/dist/esm/spatial/spatial-environment.js.map +1 -0
  82. package/dist/esm/spatial/spatial-environment.lazy.d.ts +10 -0
  83. package/dist/esm/spatial/spatial-environment.lazy.d.ts.map +1 -0
  84. package/dist/esm/spatial/spatial-environment.lazy.js +13 -0
  85. package/dist/esm/spatial/spatial-environment.lazy.js.map +1 -0
  86. package/dist/esm/spatial/spatial-shell-container.d.ts +21 -0
  87. package/dist/esm/spatial/spatial-shell-container.d.ts.map +1 -0
  88. package/dist/esm/spatial/spatial-shell-container.js +231 -0
  89. package/dist/esm/spatial/spatial-shell-container.js.map +1 -0
  90. package/dist/esm/spatial/spatial-stage-store.d.ts +27 -0
  91. package/dist/esm/spatial/spatial-stage-store.d.ts.map +1 -0
  92. package/dist/esm/spatial/spatial-stage-store.js +33 -0
  93. package/dist/esm/spatial/spatial-stage-store.js.map +1 -0
  94. package/dist/esm/tokens/design-token-resolution.d.ts +110 -0
  95. package/dist/esm/tokens/design-token-resolution.d.ts.map +1 -0
  96. package/dist/esm/tokens/design-token-resolution.js +410 -0
  97. package/dist/esm/tokens/design-token-resolution.js.map +1 -0
  98. package/dist/esm/tokens/use-design-token-resolution.d.ts +22 -0
  99. package/dist/esm/tokens/use-design-token-resolution.d.ts.map +1 -0
  100. package/dist/esm/tokens/use-design-token-resolution.js +49 -0
  101. package/dist/esm/tokens/use-design-token-resolution.js.map +1 -0
  102. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,34 @@
1
+ Copyright (c) 2026 P2C Consulting, s.à r.l.-S
2
+ RCS Luxembourg B307591
3
+ 6C, Porte de France, L-4360 Esch-sur-Alzette, Luxembourg
4
+
5
+ All rights reserved.
6
+
7
+ This software and its accompanying materials (the "Software") are the
8
+ confidential and proprietary property of P2C Consulting, s.à r.l.-S (the
9
+ "Licensor"). The Software is made available for viewing only. No licence,
10
+ right, or permission of any kind is granted by its publication or by its
11
+ availability on any package registry or source repository.
12
+
13
+ Without the Licensor's prior written permission, you may not use, copy,
14
+ reproduce, modify, adapt, translate, merge, publish, distribute, sublicense,
15
+ sell, host, or create derivative works of the Software, in whole or in part,
16
+ nor use it to provide a service to any third party.
17
+
18
+ Publication of the Software in any public registry is for distribution to
19
+ authorised recipients and for technical evaluation of its packaging only. It
20
+ does not place the Software in the public domain, does not constitute an open
21
+ source release, and does not waive any right of the Licensor.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
+
30
+ Third-party components distributed with the Software remain governed by their
31
+ own licences.
32
+
33
+ Contact: P2C Consulting, s.à r.l.-S, 6C, Porte de France, L-4360
34
+ Esch-sur-Alzette, Luxembourg.
@@ -0,0 +1,156 @@
1
+ import { DesignSystemToken, ShellRegion } from '@wildo-ai/presets-components-models';
2
+ /** @wildo_source:part:start presets.3d.frame-style-overrides facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
3
+ /**
4
+ * What the frame draws under one shell region.
5
+ *
6
+ * A frame style is the 3D frame's OWN vocabulary: it says how a region's slab looks, never how the region
7
+ * itself looks. The region stays the 2D preset's HTML, with its recipes and Tailwind classes untouched; the
8
+ * engine's theme and recipe schemas are not extended for the frame.
9
+ */
10
+ export declare enum Frame3DSurfaceKind {
11
+ /** A frosted slab: a translucent tint over the in-scene background, with a rim and an optional shadow. */
12
+ FROSTED = "frosted",
13
+ /** Nothing is drawn under the region. */
14
+ NONE = "none"
15
+ }
16
+ /** The rim: a thin edge line along the slab, emphasised while the pointer is over the region. */
17
+ export interface Frame3DRimStyle {
18
+ /** The colour token of the rim. */
19
+ token: DesignSystemToken;
20
+ /** Rim opacity at rest, 0–1. */
21
+ opacity: number;
22
+ /** Rim opacity while the pointer is over the region, 0–1. The only thing hover changes. */
23
+ hoverOpacity: number;
24
+ /** Rim width as a multiple of the `border-width` token. */
25
+ widthScale: number;
26
+ }
27
+ /** The slab's shadow, drawn on the scene background just outside the slab. Its colour is black. */
28
+ export interface Frame3DShadowStyle {
29
+ offsetXPx: number;
30
+ offsetYPx: number;
31
+ /** Blur radius in CSS pixels; 0 draws a hard shadow. */
32
+ blurPx: number;
33
+ /** Shadow opacity, 0–1. */
34
+ opacity: number;
35
+ }
36
+ /** How the frame draws under one region kind. */
37
+ export interface Frame3DRegionStyle {
38
+ surface: Frame3DSurfaceKind;
39
+ /** The colour token the frost is tinted with. Ignored when `tintColor` is set. */
40
+ tintToken: DesignSystemToken;
41
+ /**
42
+ * An explicit CSS colour for the frost instead of a token: a brand colour, or the verification sentinel
43
+ * ({@link createSentinelFrameStyles}). The contrast bound still applies to it.
44
+ */
45
+ tintColor?: string;
46
+ /** Frost opacity over the scene background, 0–1. A glass theme's navigation material replaces it. */
47
+ frost: number;
48
+ /** How much lighter the lit side of the slab is than its shaded side, 0–1. */
49
+ gradient: number;
50
+ /** Corner radius as a multiple of the `radius` token. */
51
+ radiusScale: number;
52
+ rim: Frame3DRimStyle;
53
+ shadow: Frame3DShadowStyle;
54
+ }
55
+ /** The in-scene background the slabs sit on: the page's own `backgroundLayer` cannot be sampled by WebGL. */
56
+ export interface Frame3DBackgroundStyle {
57
+ /** The base colour token. */
58
+ baseToken: DesignSystemToken;
59
+ /** The token of the glow on the lit side. */
60
+ glowToken: DesignSystemToken;
61
+ /** Glow strength: how far the lit side moves from the base colour toward the glow colour, 0–1. */
62
+ glow: number;
63
+ }
64
+ /** Everything the frame draws for one theme. `regions` is total over `ShellRegion`: a new region kind must be styled. */
65
+ export interface Frame3DThemeStyle {
66
+ background: Frame3DBackgroundStyle;
67
+ /**
68
+ * The direction the light comes from, in degrees, y UP: 0 = from the right, 90 = from the top. (A glass
69
+ * navigation material replaces it, converted from the engine's y-down convention.)
70
+ */
71
+ lightAngleDeg: number;
72
+ /**
73
+ * The colour of the light: the lit side of every slab moves toward it. `primary` by default — the colour the
74
+ * background's glow uses too — so the lit side takes a cast of the theme's own light. (A surface token would be
75
+ * the frost's own colour, and a slab lit by itself shows no gradient at all.)
76
+ */
77
+ lightToken: DesignSystemToken;
78
+ /** In dark mode the lit side moves this share of the way it does in light mode (a dimmer light rig), 0–1. */
79
+ darkModeLightStrength: number;
80
+ regions: Record<ShellRegion, Frame3DRegionStyle>;
81
+ }
82
+ /**
83
+ * The ids of the themes the framework ships, which the built-in frame styles are keyed on. Theme ids are an
84
+ * open vocabulary (an application can author its own theme); any id not listed here takes the fallback style.
85
+ */
86
+ export declare enum Frame3DBuiltInThemeId {
87
+ DEFAULT = "default",
88
+ COZY = "cozy",
89
+ DENSE = "dense",
90
+ EDITORIAL = "editorial",
91
+ GLASS = "glass",
92
+ NEO_BRUTALIST = "neo-brutalist",
93
+ TERMINAL = "terminal",
94
+ TRADING = "trading"
95
+ }
96
+ /** A partial frame style an application layers over a built-in one; nested objects merge key by key. */
97
+ export interface Frame3DThemeStyleOverride {
98
+ background?: Partial<Frame3DBackgroundStyle>;
99
+ lightAngleDeg?: number;
100
+ lightToken?: DesignSystemToken;
101
+ darkModeLightStrength?: number;
102
+ regions?: Partial<Record<ShellRegion, Frame3DRegionStyleOverride>>;
103
+ }
104
+ export type Frame3DRegionStyleOverride = Partial<Omit<Frame3DRegionStyle, 'rim' | 'shadow'>> & {
105
+ rim?: Partial<Frame3DRimStyle>;
106
+ shadow?: Partial<Frame3DShadowStyle>;
107
+ };
108
+ /**
109
+ * An application's frame-style overrides, passed to `register3DLayout({ frameStyles })`. `all` applies to
110
+ * every theme; `byThemeId` applies to one theme id and is layered after `all`.
111
+ */
112
+ export interface Frame3DStyleOverrides {
113
+ all?: Frame3DThemeStyleOverride;
114
+ byThemeId?: Partial<Record<string, Frame3DThemeStyleOverride>>;
115
+ }
116
+ /** @wildo_source:part:end presets.3d.frame-style-overrides */
117
+ /** The styles a layout's scene ships: one per built-in theme, and the fallback for any other theme id. */
118
+ export interface Frame3DStyleCatalog {
119
+ byThemeId: Record<Frame3DBuiltInThemeId, Frame3DThemeStyle>;
120
+ fallback: Frame3DThemeStyle;
121
+ }
122
+ /**
123
+ * The INHERIT layout's styles. Each built-in entry expresses its theme's character in the frame's own terms:
124
+ * cozy is softer and rounder, dense and trading are tight and flat, editorial is nearly square and quiet,
125
+ * neo-brutalist is solid with a heavy rim and a hard offset shadow, terminal is square with a primary rim.
126
+ * Colours always come from the tokens; a style only chooses WHICH token and how strongly.
127
+ */
128
+ export declare const INHERIT_FRAME_STYLES: Frame3DStyleCatalog;
129
+ /**
130
+ * The HEADER_FIRST layout's styles: the INHERIT styles, lit from straight above — the menubar spans the whole
131
+ * width over the rails in that disposal, so the light falls from the header down.
132
+ */
133
+ export declare const HEADER_FIRST_FRAME_STYLES: Frame3DStyleCatalog;
134
+ /**
135
+ * The frame style for the active theme: the layout's catalog entry for a built-in theme id (its fallback for any
136
+ * other id), then the application's `all` override, then its override for that theme id.
137
+ */
138
+ export declare function resolveFrame3DThemeStyle(catalog: Frame3DStyleCatalog, themeId: string, overrides?: Frame3DStyleOverrides): Frame3DThemeStyle;
139
+ /**
140
+ * The frame's verification sentinel: a neon green (`#39ff14`) that appears in no theme, token or palette in the
141
+ * framework or the dogfood applications (checked 2026-09-29 by a repository search).
142
+ *
143
+ * That absence is the point. A cover check counts sentinel pixels in a screenshot: one where a region is
144
+ * transparent over its slab is expected, one over a region's CONTENT means the canvas covered it — and a colour
145
+ * a theme could also produce would make that count meaningless.
146
+ */
147
+ export declare const FRAME_SENTINEL_COLOR = "#39ff14";
148
+ /**
149
+ * Frame-style overrides that draw every region as a flat, square, rimless, shadowless slab in
150
+ * {@link FRAME_SENTINEL_COLOR}, for a cover-and-alignment check: `register3DLayout({ frameStyles:
151
+ * createSentinelFrameStyles() })`. The contrast bound still applies, so run the check where the sentinel passes
152
+ * it against the foreground (a light mode, whose foreground is dark) — and assert the sentinel is actually
153
+ * visible where regions are transparent, or a bound-adjusted colour would read as "nothing covered".
154
+ */
155
+ export declare function createSentinelFrameStyles(): Frame3DStyleOverrides;
156
+ //# sourceMappingURL=frame-3d-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-3d-style.d.ts","sourceRoot":"","sources":["../../../../src/frame/frame-3d-style.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ import { DesignSystemToken, ShellRegion } from '@wildo-ai/presets-components-models';
2
+ /** @wildo_source:part:start presets.3d.frame-style-overrides facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
3
+ /**
4
+ * What the frame draws under one shell region.
5
+ *
6
+ * A frame style is the 3D frame's OWN vocabulary: it says how a region's slab looks, never how the region
7
+ * itself looks. The region stays the 2D preset's HTML, with its recipes and Tailwind classes untouched; the
8
+ * engine's theme and recipe schemas are not extended for the frame.
9
+ */
10
+ export var Frame3DSurfaceKind;
11
+ (function (Frame3DSurfaceKind) {
12
+ /** A frosted slab: a translucent tint over the in-scene background, with a rim and an optional shadow. */
13
+ Frame3DSurfaceKind["FROSTED"] = "frosted";
14
+ /** Nothing is drawn under the region. */
15
+ Frame3DSurfaceKind["NONE"] = "none";
16
+ })(Frame3DSurfaceKind || (Frame3DSurfaceKind = {}));
17
+ /**
18
+ * The ids of the themes the framework ships, which the built-in frame styles are keyed on. Theme ids are an
19
+ * open vocabulary (an application can author its own theme); any id not listed here takes the fallback style.
20
+ */
21
+ export var Frame3DBuiltInThemeId;
22
+ (function (Frame3DBuiltInThemeId) {
23
+ Frame3DBuiltInThemeId["DEFAULT"] = "default";
24
+ Frame3DBuiltInThemeId["COZY"] = "cozy";
25
+ Frame3DBuiltInThemeId["DENSE"] = "dense";
26
+ Frame3DBuiltInThemeId["EDITORIAL"] = "editorial";
27
+ Frame3DBuiltInThemeId["GLASS"] = "glass";
28
+ Frame3DBuiltInThemeId["NEO_BRUTALIST"] = "neo-brutalist";
29
+ Frame3DBuiltInThemeId["TERMINAL"] = "terminal";
30
+ Frame3DBuiltInThemeId["TRADING"] = "trading";
31
+ })(Frame3DBuiltInThemeId || (Frame3DBuiltInThemeId = {}));
32
+ const NO_SHADOW = { offsetXPx: 0, offsetYPx: 0, blurPx: 0, opacity: 0 };
33
+ /**
34
+ * One theme's region table from a chrome style (the bars and rails) and a content style (the `<main>`). Written
35
+ * as an object literal over every `ShellRegion` member, so a member added to the enum fails to compile here
36
+ * instead of silently falling through to nothing.
37
+ */
38
+ function regionStyles(chrome, content) {
39
+ return {
40
+ [ShellRegion.MENUBAR]: chrome,
41
+ [ShellRegion.SIDEBAR]: chrome,
42
+ [ShellRegion.TOOLBAR]: chrome,
43
+ [ShellRegion.ACTIVITY_BAR]: chrome,
44
+ [ShellRegion.UTILITY_PANEL]: chrome,
45
+ [ShellRegion.STATUS_BAR]: chrome,
46
+ [ShellRegion.CONTENT]: content,
47
+ };
48
+ }
49
+ function theme(input) {
50
+ const chrome = {
51
+ surface: Frame3DSurfaceKind.FROSTED,
52
+ tintToken: DesignSystemToken.SURFACE_RAISED,
53
+ frost: input.frost,
54
+ gradient: input.gradient,
55
+ radiusScale: input.radiusScale,
56
+ rim: input.rim,
57
+ shadow: input.shadow,
58
+ };
59
+ const content = { ...chrome, tintToken: DesignSystemToken.SURFACE_DEFAULT, frost: input.contentFrost };
60
+ return {
61
+ background: { baseToken: DesignSystemToken.BACKGROUND, glowToken: input.glowToken ?? DesignSystemToken.PRIMARY, glow: input.glow },
62
+ lightAngleDeg: input.lightAngleDeg ?? 110,
63
+ lightToken: DesignSystemToken.PRIMARY,
64
+ darkModeLightStrength: 0.5,
65
+ regions: regionStyles(chrome, content),
66
+ };
67
+ }
68
+ const DEFAULT_STYLE = theme({
69
+ radiusScale: 1,
70
+ frost: 0.5,
71
+ contentFrost: 0.55,
72
+ gradient: 0.06,
73
+ rim: { token: DesignSystemToken.BORDER, opacity: 0.5, hoverOpacity: 0.9, widthScale: 1 },
74
+ shadow: { offsetXPx: 0, offsetYPx: 6, blurPx: 18, opacity: 0.12 },
75
+ glow: 0.08,
76
+ });
77
+ /**
78
+ * The INHERIT layout's styles. Each built-in entry expresses its theme's character in the frame's own terms:
79
+ * cozy is softer and rounder, dense and trading are tight and flat, editorial is nearly square and quiet,
80
+ * neo-brutalist is solid with a heavy rim and a hard offset shadow, terminal is square with a primary rim.
81
+ * Colours always come from the tokens; a style only chooses WHICH token and how strongly.
82
+ */
83
+ export const INHERIT_FRAME_STYLES = {
84
+ byThemeId: {
85
+ [Frame3DBuiltInThemeId.DEFAULT]: DEFAULT_STYLE,
86
+ [Frame3DBuiltInThemeId.COZY]: theme({
87
+ radiusScale: 1.5,
88
+ frost: 0.6,
89
+ contentFrost: 0.62,
90
+ gradient: 0.08,
91
+ rim: { token: DesignSystemToken.BORDER, opacity: 0.35, hoverOpacity: 0.75, widthScale: 1 },
92
+ shadow: { offsetXPx: 0, offsetYPx: 10, blurPx: 28, opacity: 0.1 },
93
+ glow: 0.1,
94
+ }),
95
+ [Frame3DBuiltInThemeId.DENSE]: theme({
96
+ radiusScale: 0.5,
97
+ frost: 0.4,
98
+ contentFrost: 0.45,
99
+ gradient: 0.03,
100
+ rim: { token: DesignSystemToken.BORDER, opacity: 0.6, hoverOpacity: 0.9, widthScale: 1 },
101
+ shadow: NO_SHADOW,
102
+ glow: 0.04,
103
+ }),
104
+ [Frame3DBuiltInThemeId.EDITORIAL]: theme({
105
+ radiusScale: 0.25,
106
+ frost: 0.3,
107
+ contentFrost: 0.35,
108
+ gradient: 0,
109
+ rim: { token: DesignSystemToken.BORDER, opacity: 0.25, hoverOpacity: 0.5, widthScale: 1 },
110
+ shadow: NO_SHADOW,
111
+ glow: 0.03,
112
+ }),
113
+ [Frame3DBuiltInThemeId.GLASS]: theme({
114
+ radiusScale: 1.25,
115
+ frost: 0.3,
116
+ contentFrost: 0.35,
117
+ gradient: 0.12,
118
+ rim: { token: DesignSystemToken.BORDER_STRONG, opacity: 0.6, hoverOpacity: 1, widthScale: 1 },
119
+ shadow: { offsetXPx: 0, offsetYPx: 8, blurPx: 24, opacity: 0.15 },
120
+ glow: 0.14,
121
+ }),
122
+ [Frame3DBuiltInThemeId.NEO_BRUTALIST]: theme({
123
+ radiusScale: 0,
124
+ frost: 0.92,
125
+ contentFrost: 0.92,
126
+ gradient: 0,
127
+ rim: { token: DesignSystemToken.FOREGROUND, opacity: 1, hoverOpacity: 1, widthScale: 2 },
128
+ shadow: { offsetXPx: 4, offsetYPx: 4, blurPx: 0, opacity: 1 },
129
+ glow: 0,
130
+ }),
131
+ [Frame3DBuiltInThemeId.TERMINAL]: theme({
132
+ radiusScale: 0,
133
+ frost: 0.25,
134
+ contentFrost: 0.3,
135
+ gradient: 0,
136
+ rim: { token: DesignSystemToken.PRIMARY, opacity: 0.5, hoverOpacity: 0.9, widthScale: 1 },
137
+ shadow: NO_SHADOW,
138
+ glow: 0.12,
139
+ }),
140
+ [Frame3DBuiltInThemeId.TRADING]: theme({
141
+ radiusScale: 0.5,
142
+ frost: 0.45,
143
+ contentFrost: 0.5,
144
+ gradient: 0.02,
145
+ rim: { token: DesignSystemToken.BORDER, opacity: 0.45, hoverOpacity: 0.8, widthScale: 1 },
146
+ shadow: NO_SHADOW,
147
+ glow: 0.05,
148
+ }),
149
+ },
150
+ fallback: DEFAULT_STYLE,
151
+ };
152
+ /**
153
+ * The HEADER_FIRST layout's styles: the INHERIT styles, lit from straight above — the menubar spans the whole
154
+ * width over the rails in that disposal, so the light falls from the header down.
155
+ */
156
+ export const HEADER_FIRST_FRAME_STYLES = withLightAngle(INHERIT_FRAME_STYLES, 90);
157
+ function withLightAngle(catalog, lightAngleDeg) {
158
+ const byThemeId = {};
159
+ for (const id of Object.values(Frame3DBuiltInThemeId))
160
+ byThemeId[id] = { ...catalog.byThemeId[id], lightAngleDeg };
161
+ return { byThemeId, fallback: { ...catalog.fallback, lightAngleDeg } };
162
+ }
163
+ function isBuiltInThemeId(id) {
164
+ return Object.values(Frame3DBuiltInThemeId).includes(id);
165
+ }
166
+ function mergeTheme(base, override) {
167
+ if (!override)
168
+ return base;
169
+ const regions = { ...base.regions };
170
+ for (const region of Object.values(ShellRegion)) {
171
+ const regionOverride = override.regions?.[region];
172
+ if (!regionOverride)
173
+ continue;
174
+ const current = regions[region];
175
+ regions[region] = {
176
+ ...current,
177
+ ...regionOverride,
178
+ rim: { ...current.rim, ...regionOverride.rim },
179
+ shadow: { ...current.shadow, ...regionOverride.shadow },
180
+ };
181
+ }
182
+ return {
183
+ background: { ...base.background, ...override.background },
184
+ lightAngleDeg: override.lightAngleDeg ?? base.lightAngleDeg,
185
+ lightToken: override.lightToken ?? base.lightToken,
186
+ darkModeLightStrength: override.darkModeLightStrength ?? base.darkModeLightStrength,
187
+ regions,
188
+ };
189
+ }
190
+ /**
191
+ * The frame style for the active theme: the layout's catalog entry for a built-in theme id (its fallback for any
192
+ * other id), then the application's `all` override, then its override for that theme id.
193
+ */
194
+ export function resolveFrame3DThemeStyle(catalog, themeId, overrides) {
195
+ const base = isBuiltInThemeId(themeId) ? catalog.byThemeId[themeId] : catalog.fallback;
196
+ return mergeTheme(mergeTheme(base, overrides?.all), overrides?.byThemeId?.[themeId]);
197
+ }
198
+ /**
199
+ * The frame's verification sentinel: a neon green (`#39ff14`) that appears in no theme, token or palette in the
200
+ * framework or the dogfood applications (checked 2026-09-29 by a repository search).
201
+ *
202
+ * That absence is the point. A cover check counts sentinel pixels in a screenshot: one where a region is
203
+ * transparent over its slab is expected, one over a region's CONTENT means the canvas covered it — and a colour
204
+ * a theme could also produce would make that count meaningless.
205
+ */
206
+ export const FRAME_SENTINEL_COLOR = '#39ff14';
207
+ /**
208
+ * Frame-style overrides that draw every region as a flat, square, rimless, shadowless slab in
209
+ * {@link FRAME_SENTINEL_COLOR}, for a cover-and-alignment check: `register3DLayout({ frameStyles:
210
+ * createSentinelFrameStyles() })`. The contrast bound still applies, so run the check where the sentinel passes
211
+ * it against the foreground (a light mode, whose foreground is dark) — and assert the sentinel is actually
212
+ * visible where regions are transparent, or a bound-adjusted colour would read as "nothing covered".
213
+ */
214
+ export function createSentinelFrameStyles() {
215
+ const sentinel = {
216
+ surface: Frame3DSurfaceKind.FROSTED,
217
+ tintColor: FRAME_SENTINEL_COLOR,
218
+ frost: 1,
219
+ gradient: 0,
220
+ radiusScale: 0,
221
+ rim: { opacity: 0, hoverOpacity: 0 },
222
+ shadow: NO_SHADOW,
223
+ };
224
+ const regions = {};
225
+ for (const region of Object.values(ShellRegion))
226
+ regions[region] = sentinel;
227
+ return { all: { regions } };
228
+ }
229
+ //# sourceMappingURL=frame-3d-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-3d-style.js","sourceRoot":"","sources":["../../../../src/frame/frame-3d-style.ts"],"names":[],"mappings":"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","sourcesContent":["import { DesignSystemToken, ShellRegion } from '@wildo-ai/presets-components-models';\n\n/** @wildo_source:part:start presets.3d.frame-style-overrides facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */\n/**\n * What the frame draws under one shell region.\n *\n * A frame style is the 3D frame's OWN vocabulary: it says how a region's slab looks, never how the region\n * itself looks. The region stays the 2D preset's HTML, with its recipes and Tailwind classes untouched; the\n * engine's theme and recipe schemas are not extended for the frame.\n */\nexport enum Frame3DSurfaceKind {\n /** A frosted slab: a translucent tint over the in-scene background, with a rim and an optional shadow. */\n FROSTED = 'frosted',\n /** Nothing is drawn under the region. */\n NONE = 'none',\n}\n\n/** The rim: a thin edge line along the slab, emphasised while the pointer is over the region. */\nexport interface Frame3DRimStyle {\n /** The colour token of the rim. */\n token: DesignSystemToken;\n /** Rim opacity at rest, 0–1. */\n opacity: number;\n /** Rim opacity while the pointer is over the region, 0–1. The only thing hover changes. */\n hoverOpacity: number;\n /** Rim width as a multiple of the `border-width` token. */\n widthScale: number;\n}\n\n/** The slab's shadow, drawn on the scene background just outside the slab. Its colour is black. */\nexport interface Frame3DShadowStyle {\n offsetXPx: number;\n offsetYPx: number;\n /** Blur radius in CSS pixels; 0 draws a hard shadow. */\n blurPx: number;\n /** Shadow opacity, 0–1. */\n opacity: number;\n}\n\n/** How the frame draws under one region kind. */\nexport interface Frame3DRegionStyle {\n surface: Frame3DSurfaceKind;\n /** The colour token the frost is tinted with. Ignored when `tintColor` is set. */\n tintToken: DesignSystemToken;\n /**\n * An explicit CSS colour for the frost instead of a token: a brand colour, or the verification sentinel\n * ({@link createSentinelFrameStyles}). The contrast bound still applies to it.\n */\n tintColor?: string;\n /** Frost opacity over the scene background, 0–1. A glass theme's navigation material replaces it. */\n frost: number;\n /** How much lighter the lit side of the slab is than its shaded side, 0–1. */\n gradient: number;\n /** Corner radius as a multiple of the `radius` token. */\n radiusScale: number;\n rim: Frame3DRimStyle;\n shadow: Frame3DShadowStyle;\n}\n\n/** The in-scene background the slabs sit on: the page's own `backgroundLayer` cannot be sampled by WebGL. */\nexport interface Frame3DBackgroundStyle {\n /** The base colour token. */\n baseToken: DesignSystemToken;\n /** The token of the glow on the lit side. */\n glowToken: DesignSystemToken;\n /** Glow strength: how far the lit side moves from the base colour toward the glow colour, 0–1. */\n glow: number;\n}\n\n/** Everything the frame draws for one theme. `regions` is total over `ShellRegion`: a new region kind must be styled. */\nexport interface Frame3DThemeStyle {\n background: Frame3DBackgroundStyle;\n /**\n * The direction the light comes from, in degrees, y UP: 0 = from the right, 90 = from the top. (A glass\n * navigation material replaces it, converted from the engine's y-down convention.)\n */\n lightAngleDeg: number;\n /**\n * The colour of the light: the lit side of every slab moves toward it. `primary` by default — the colour the\n * background's glow uses too — so the lit side takes a cast of the theme's own light. (A surface token would be\n * the frost's own colour, and a slab lit by itself shows no gradient at all.)\n */\n lightToken: DesignSystemToken;\n /** In dark mode the lit side moves this share of the way it does in light mode (a dimmer light rig), 0–1. */\n darkModeLightStrength: number;\n regions: Record<ShellRegion, Frame3DRegionStyle>;\n}\n\n/**\n * The ids of the themes the framework ships, which the built-in frame styles are keyed on. Theme ids are an\n * open vocabulary (an application can author its own theme); any id not listed here takes the fallback style.\n */\nexport enum Frame3DBuiltInThemeId {\n DEFAULT = 'default',\n COZY = 'cozy',\n DENSE = 'dense',\n EDITORIAL = 'editorial',\n GLASS = 'glass',\n NEO_BRUTALIST = 'neo-brutalist',\n TERMINAL = 'terminal',\n TRADING = 'trading',\n}\n\n/** A partial frame style an application layers over a built-in one; nested objects merge key by key. */\nexport interface Frame3DThemeStyleOverride {\n background?: Partial<Frame3DBackgroundStyle>;\n lightAngleDeg?: number;\n lightToken?: DesignSystemToken;\n darkModeLightStrength?: number;\n regions?: Partial<Record<ShellRegion, Frame3DRegionStyleOverride>>;\n}\n\nexport type Frame3DRegionStyleOverride = Partial<Omit<Frame3DRegionStyle, 'rim' | 'shadow'>> & {\n rim?: Partial<Frame3DRimStyle>;\n shadow?: Partial<Frame3DShadowStyle>;\n};\n\n/**\n * An application's frame-style overrides, passed to `register3DLayout({ frameStyles })`. `all` applies to\n * every theme; `byThemeId` applies to one theme id and is layered after `all`.\n */\nexport interface Frame3DStyleOverrides {\n all?: Frame3DThemeStyleOverride;\n byThemeId?: Partial<Record<string, Frame3DThemeStyleOverride>>;\n}\n/** @wildo_source:part:end presets.3d.frame-style-overrides */\n\n/** The styles a layout's scene ships: one per built-in theme, and the fallback for any other theme id. */\nexport interface Frame3DStyleCatalog {\n byThemeId: Record<Frame3DBuiltInThemeId, Frame3DThemeStyle>;\n fallback: Frame3DThemeStyle;\n}\n\nconst NO_SHADOW: Frame3DShadowStyle = { offsetXPx: 0, offsetYPx: 0, blurPx: 0, opacity: 0 };\n\n/**\n * One theme's region table from a chrome style (the bars and rails) and a content style (the `<main>`). Written\n * as an object literal over every `ShellRegion` member, so a member added to the enum fails to compile here\n * instead of silently falling through to nothing.\n */\nfunction regionStyles(chrome: Frame3DRegionStyle, content: Frame3DRegionStyle): Record<ShellRegion, Frame3DRegionStyle> {\n return {\n [ShellRegion.MENUBAR]: chrome,\n [ShellRegion.SIDEBAR]: chrome,\n [ShellRegion.TOOLBAR]: chrome,\n [ShellRegion.ACTIVITY_BAR]: chrome,\n [ShellRegion.UTILITY_PANEL]: chrome,\n [ShellRegion.STATUS_BAR]: chrome,\n [ShellRegion.CONTENT]: content,\n };\n}\n\nfunction theme(input: {\n radiusScale: number;\n frost: number;\n contentFrost: number;\n gradient: number;\n rim: Frame3DRimStyle;\n shadow: Frame3DShadowStyle;\n glow: number;\n glowToken?: DesignSystemToken;\n lightAngleDeg?: number;\n}): Frame3DThemeStyle {\n const chrome: Frame3DRegionStyle = {\n surface: Frame3DSurfaceKind.FROSTED,\n tintToken: DesignSystemToken.SURFACE_RAISED,\n frost: input.frost,\n gradient: input.gradient,\n radiusScale: input.radiusScale,\n rim: input.rim,\n shadow: input.shadow,\n };\n const content: Frame3DRegionStyle = { ...chrome, tintToken: DesignSystemToken.SURFACE_DEFAULT, frost: input.contentFrost };\n return {\n background: { baseToken: DesignSystemToken.BACKGROUND, glowToken: input.glowToken ?? DesignSystemToken.PRIMARY, glow: input.glow },\n lightAngleDeg: input.lightAngleDeg ?? 110,\n lightToken: DesignSystemToken.PRIMARY,\n darkModeLightStrength: 0.5,\n regions: regionStyles(chrome, content),\n };\n}\n\nconst DEFAULT_STYLE = theme({\n radiusScale: 1,\n frost: 0.5,\n contentFrost: 0.55,\n gradient: 0.06,\n rim: { token: DesignSystemToken.BORDER, opacity: 0.5, hoverOpacity: 0.9, widthScale: 1 },\n shadow: { offsetXPx: 0, offsetYPx: 6, blurPx: 18, opacity: 0.12 },\n glow: 0.08,\n});\n\n/**\n * The INHERIT layout's styles. Each built-in entry expresses its theme's character in the frame's own terms:\n * cozy is softer and rounder, dense and trading are tight and flat, editorial is nearly square and quiet,\n * neo-brutalist is solid with a heavy rim and a hard offset shadow, terminal is square with a primary rim.\n * Colours always come from the tokens; a style only chooses WHICH token and how strongly.\n */\nexport const INHERIT_FRAME_STYLES: Frame3DStyleCatalog = {\n byThemeId: {\n [Frame3DBuiltInThemeId.DEFAULT]: DEFAULT_STYLE,\n [Frame3DBuiltInThemeId.COZY]: theme({\n radiusScale: 1.5,\n frost: 0.6,\n contentFrost: 0.62,\n gradient: 0.08,\n rim: { token: DesignSystemToken.BORDER, opacity: 0.35, hoverOpacity: 0.75, widthScale: 1 },\n shadow: { offsetXPx: 0, offsetYPx: 10, blurPx: 28, opacity: 0.1 },\n glow: 0.1,\n }),\n [Frame3DBuiltInThemeId.DENSE]: theme({\n radiusScale: 0.5,\n frost: 0.4,\n contentFrost: 0.45,\n gradient: 0.03,\n rim: { token: DesignSystemToken.BORDER, opacity: 0.6, hoverOpacity: 0.9, widthScale: 1 },\n shadow: NO_SHADOW,\n glow: 0.04,\n }),\n [Frame3DBuiltInThemeId.EDITORIAL]: theme({\n radiusScale: 0.25,\n frost: 0.3,\n contentFrost: 0.35,\n gradient: 0,\n rim: { token: DesignSystemToken.BORDER, opacity: 0.25, hoverOpacity: 0.5, widthScale: 1 },\n shadow: NO_SHADOW,\n glow: 0.03,\n }),\n [Frame3DBuiltInThemeId.GLASS]: theme({\n radiusScale: 1.25,\n frost: 0.3,\n contentFrost: 0.35,\n gradient: 0.12,\n rim: { token: DesignSystemToken.BORDER_STRONG, opacity: 0.6, hoverOpacity: 1, widthScale: 1 },\n shadow: { offsetXPx: 0, offsetYPx: 8, blurPx: 24, opacity: 0.15 },\n glow: 0.14,\n }),\n [Frame3DBuiltInThemeId.NEO_BRUTALIST]: theme({\n radiusScale: 0,\n frost: 0.92,\n contentFrost: 0.92,\n gradient: 0,\n rim: { token: DesignSystemToken.FOREGROUND, opacity: 1, hoverOpacity: 1, widthScale: 2 },\n shadow: { offsetXPx: 4, offsetYPx: 4, blurPx: 0, opacity: 1 },\n glow: 0,\n }),\n [Frame3DBuiltInThemeId.TERMINAL]: theme({\n radiusScale: 0,\n frost: 0.25,\n contentFrost: 0.3,\n gradient: 0,\n rim: { token: DesignSystemToken.PRIMARY, opacity: 0.5, hoverOpacity: 0.9, widthScale: 1 },\n shadow: NO_SHADOW,\n glow: 0.12,\n }),\n [Frame3DBuiltInThemeId.TRADING]: theme({\n radiusScale: 0.5,\n frost: 0.45,\n contentFrost: 0.5,\n gradient: 0.02,\n rim: { token: DesignSystemToken.BORDER, opacity: 0.45, hoverOpacity: 0.8, widthScale: 1 },\n shadow: NO_SHADOW,\n glow: 0.05,\n }),\n },\n fallback: DEFAULT_STYLE,\n};\n\n/**\n * The HEADER_FIRST layout's styles: the INHERIT styles, lit from straight above — the menubar spans the whole\n * width over the rails in that disposal, so the light falls from the header down.\n */\nexport const HEADER_FIRST_FRAME_STYLES: Frame3DStyleCatalog = withLightAngle(INHERIT_FRAME_STYLES, 90);\n\nfunction withLightAngle(catalog: Frame3DStyleCatalog, lightAngleDeg: number): Frame3DStyleCatalog {\n const byThemeId = {} as Record<Frame3DBuiltInThemeId, Frame3DThemeStyle>;\n for (const id of Object.values(Frame3DBuiltInThemeId)) byThemeId[id] = { ...catalog.byThemeId[id], lightAngleDeg };\n return { byThemeId, fallback: { ...catalog.fallback, lightAngleDeg } };\n}\n\nfunction isBuiltInThemeId(id: string): id is Frame3DBuiltInThemeId {\n return (Object.values(Frame3DBuiltInThemeId) as string[]).includes(id);\n}\n\nfunction mergeTheme(base: Frame3DThemeStyle, override: Frame3DThemeStyleOverride | undefined): Frame3DThemeStyle {\n if (!override) return base;\n const regions = { ...base.regions };\n for (const region of Object.values(ShellRegion)) {\n const regionOverride = override.regions?.[region];\n if (!regionOverride) continue;\n const current = regions[region];\n regions[region] = {\n ...current,\n ...regionOverride,\n rim: { ...current.rim, ...regionOverride.rim },\n shadow: { ...current.shadow, ...regionOverride.shadow },\n };\n }\n return {\n background: { ...base.background, ...override.background },\n lightAngleDeg: override.lightAngleDeg ?? base.lightAngleDeg,\n lightToken: override.lightToken ?? base.lightToken,\n darkModeLightStrength: override.darkModeLightStrength ?? base.darkModeLightStrength,\n regions,\n };\n}\n\n/**\n * The frame style for the active theme: the layout's catalog entry for a built-in theme id (its fallback for any\n * other id), then the application's `all` override, then its override for that theme id.\n */\nexport function resolveFrame3DThemeStyle(catalog: Frame3DStyleCatalog, themeId: string, overrides?: Frame3DStyleOverrides): Frame3DThemeStyle {\n const base = isBuiltInThemeId(themeId) ? catalog.byThemeId[themeId] : catalog.fallback;\n return mergeTheme(mergeTheme(base, overrides?.all), overrides?.byThemeId?.[themeId]);\n}\n\n/**\n * The frame's verification sentinel: a neon green (`#39ff14`) that appears in no theme, token or palette in the\n * framework or the dogfood applications (checked 2026-09-29 by a repository search).\n *\n * That absence is the point. A cover check counts sentinel pixels in a screenshot: one where a region is\n * transparent over its slab is expected, one over a region's CONTENT means the canvas covered it — and a colour\n * a theme could also produce would make that count meaningless.\n */\nexport const FRAME_SENTINEL_COLOR = '#39ff14';\n\n/**\n * Frame-style overrides that draw every region as a flat, square, rimless, shadowless slab in\n * {@link FRAME_SENTINEL_COLOR}, for a cover-and-alignment check: `register3DLayout({ frameStyles:\n * createSentinelFrameStyles() })`. The contrast bound still applies, so run the check where the sentinel passes\n * it against the foreground (a light mode, whose foreground is dark) — and assert the sentinel is actually\n * visible where regions are transparent, or a bound-adjusted colour would read as \"nothing covered\".\n */\nexport function createSentinelFrameStyles(): Frame3DStyleOverrides {\n const sentinel: Frame3DRegionStyleOverride = {\n surface: Frame3DSurfaceKind.FROSTED,\n tintColor: FRAME_SENTINEL_COLOR,\n frost: 1,\n gradient: 0,\n radiusScale: 0,\n rim: { opacity: 0, hoverOpacity: 0 },\n shadow: NO_SHADOW,\n };\n const regions: Partial<Record<ShellRegion, Frame3DRegionStyleOverride>> = {};\n for (const region of Object.values(ShellRegion)) regions[region] = sentinel;\n return { all: { regions } };\n}\n"]}
@@ -0,0 +1,99 @@
1
+ import { DesignSystemToken, ShellRegion, type MaterialProfile } from '@wildo-ai/presets-components-models';
2
+ import { type Frame3DThemeStyle } from './frame-3d-style';
3
+ import { type FrameColor } from './frame-color';
4
+ import { type DesignTokenResolution } from '../tokens/design-token-resolution';
5
+ export type { FrameColor } from './frame-color';
6
+ /** How one region kind's slab is drawn, in frame units (CSS pixels, sRGB-encoded colours). */
7
+ export interface FrameSlabAppearance {
8
+ /** False when the style draws nothing here, or a colour it needs did not resolve. */
9
+ visible: boolean;
10
+ /** The shaded side of the frost. */
11
+ fillFrom: FrameColor;
12
+ /** The lit side of the frost. */
13
+ fillTo: FrameColor;
14
+ fillAlpha: number;
15
+ rim: FrameColor;
16
+ rimAlpha: number;
17
+ rimHoverAlpha: number;
18
+ rimWidthPx: number;
19
+ radiusPx: number;
20
+ shadowOffsetXPx: number;
21
+ shadowOffsetYPx: number;
22
+ shadowBlurPx: number;
23
+ shadowAlpha: number;
24
+ }
25
+ /** A cubic-Bézier easing, as its four control points. */
26
+ export type FrameEasing = readonly [number, number, number, number];
27
+ /** A damped spring, as motion.dev's gesture `transition` declares one. */
28
+ export interface FrameSpring {
29
+ stiffness: number;
30
+ damping: number;
31
+ mass: number;
32
+ }
33
+ /**
34
+ * Everything the frame draws, as plain data. It is computed in the DOM tree from the theme and handed to the
35
+ * canvas as props, so the canvas holds meshes only and reads no context (#1823).
36
+ */
37
+ export interface FrameAppearance {
38
+ /** The `--foreground` the bound was computed against. A change of it (a mode switch) is applied at once. */
39
+ foreground: FrameColor;
40
+ /** The in-scene background, shaded side then lit side. */
41
+ background: {
42
+ from: FrameColor;
43
+ to: FrameColor;
44
+ } | null;
45
+ /** The light direction in the FRAME's convention: degrees, 0 = from the right, 90 = from the top (y up). */
46
+ lightAngleDeg: number;
47
+ regions: Record<ShellRegion, FrameSlabAppearance>;
48
+ /** A theme change cross-fades over this. 0 under reduced motion. */
49
+ transitionSeconds: number;
50
+ transitionEasing: FrameEasing;
51
+ /** The rim's hover emphasis animates over this, when no spring is declared. */
52
+ hoverSeconds: number;
53
+ hoverEasing: FrameEasing;
54
+ /** The theme's surface gesture spring: when declared, the rim's hover emphasis follows it instead. */
55
+ hoverSpring: FrameSpring | null;
56
+ /** False under reduced motion: the frame is static, so the rim does not respond to hover at all. */
57
+ hoverResponse: boolean;
58
+ /**
59
+ * How long a shell CSS transition may run before the frame stops following it without a `transitionend`:
60
+ * the slowest motion-duration token, with half again as margin. The shell's own transitions use those tokens.
61
+ */
62
+ transitionCeilingSeconds: number;
63
+ }
64
+ export interface FrameAppearanceInputs {
65
+ resolutions: ReadonlyMap<DesignSystemToken, DesignTokenResolution>;
66
+ style: Frame3DThemeStyle;
67
+ /** The theme's navigation material (`MaterialProfileRole.GLASS_NAVIGATION`), when it has one. */
68
+ navigationMaterial: MaterialProfile | undefined;
69
+ /** The theme's surface gesture `transition` (motion.dev), when its surface recipe declares one. */
70
+ surfaceGestureTransition: Readonly<Record<string, string | number>> | undefined;
71
+ isDark: boolean;
72
+ prefersReducedMotion: boolean;
73
+ /** Converts the material's device-pixel rim width into CSS pixels. */
74
+ devicePixelRatio: number;
75
+ }
76
+ /**
77
+ * The lowest contrast any colour the frame can put behind text may have against `--foreground`: WCAG 2.x's
78
+ * AA minimum for normal text.
79
+ * spec-cite: WCAG 2.2 SC 1.4.3 Contrast (Minimum) — https://www.w3.org/TR/WCAG22/#contrast-minimum
80
+ */
81
+ export declare const FRAME_MINIMUM_CONTRAST = 4.5;
82
+ /**
83
+ * Derive the frame's appearance from the active theme, or `null` when the foreground did not resolve — without
84
+ * it no colour can be shown to be readable, and a frame that cannot be shown readable is not drawn.
85
+ *
86
+ * **The contrast bound** is part of the derivation, not a check after it. Every colour text can sit on is
87
+ * composited the way the framebuffer blends — in sRGB-encoded space, each written layer rounded to 8 bits — and
88
+ * must reach the target against `--foreground`:
89
+ * - the background, at several points along its gradient;
90
+ * - the background under a shadow (shadows combine by MAXIMUM in the renderer, never by stacking, so one
91
+ * shadow at its full opacity is the darkest a point can be);
92
+ * - the frost over either, along its own gradient;
93
+ * - the rim at its HOVER opacity over the frost.
94
+ *
95
+ * A style value that would break it is WEAKENED — a colour moved toward the pole with the most contrast, a
96
+ * shadow or rim made fainter — and the bound is never relaxed. A style is a preference; the bound is a guarantee.
97
+ */
98
+ export declare function deriveFrameAppearance(inputs: FrameAppearanceInputs): FrameAppearance | null;
99
+ //# sourceMappingURL=frame-appearance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-appearance.d.ts","sourceRoot":"","sources":["../../../../src/frame/frame-appearance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAgB,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAEzH,OAAO,EAA+C,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAgG,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9I,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAExG,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,8FAA8F;AAC9F,MAAM,WAAW,mBAAmB;IAClC,qFAAqF;IACrF,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,QAAQ,EAAE,UAAU,CAAC;IACrB,iCAAiC;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,yDAAyD;AACzD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpE,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,4GAA4G;IAC5G,UAAU,EAAE,UAAU,CAAC;IACvB,0DAA0D;IAC1D,UAAU,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,EAAE,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,4GAA4G;IAC5G,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAClD,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,WAAW,CAAC;IAC9B,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,sGAAsG;IACtG,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,oGAAoG;IACpG,aAAa,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IACnE,KAAK,EAAE,iBAAiB,CAAC;IACzB,iGAAiG;IACjG,kBAAkB,EAAE,eAAe,GAAG,SAAS,CAAC;IAChD,mGAAmG;IACnG,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAChF,MAAM,EAAE,OAAO,CAAC;IAChB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sEAAsE;IACtE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAmB1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,GAAG,IAAI,CA6G3F"}