@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
@@ -0,0 +1,106 @@
1
+ import { ShellAppearance } from '@wildo-ai/presets-components-models';
2
+ import { HEADER_FIRST_FRAME_STYLES, INHERIT_FRAME_STYLES } from '../frame/frame-3d-style.js';
3
+ import { HeaderFirstShellContainer } from './header-first-shell-container.js';
4
+ import { SpatialShellContainer } from '../spatial/spatial-shell-container.js';
5
+ import { ShellLayoutPlacementKind } from './shell-layout-placement.js';
6
+ import { crossFadesAppearance, frameChoreography, rimsFocusedZone } from './layout-3d-transition-choreography.js';
7
+ import { Layout3DAppearanceTransition, Layout3DCamera, Layout3DId, Layout3DFrameChoreography, Layout3DRestPose, Layout3DZoneFocusTransition, } from './layout-3d-vocabulary.js';
8
+ /**
9
+ * The 2D disposal, unchanged, with the frame under it. On navigation the content slab lifts and settles; when
10
+ * the sidebar collapses or expands, the light swings across and back.
11
+ */
12
+ export const INHERIT_LAYOUT_3D = {
13
+ id: Layout3DId.INHERIT,
14
+ placement: { kind: ShellLayoutPlacementKind.INHERIT },
15
+ scene: { camera: Layout3DCamera.FLAT_ORTHOGRAPHIC, frameStyles: INHERIT_FRAME_STYLES },
16
+ transitions: {
17
+ appearance: Layout3DAppearanceTransition.CROSS_FADE,
18
+ navigation: Layout3DFrameChoreography.ELEVATION_SETTLE,
19
+ sidebarResize: Layout3DFrameChoreography.LIGHT_SWEEP,
20
+ zoneFocus: Layout3DZoneFocusTransition.RIM,
21
+ },
22
+ constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },
23
+ };
24
+ /**
25
+ * The header-first disposal, with the frame lit from the header down. On navigation the light swings from the header
26
+ * and returns; when the sidebar collapses or expands, the content slab lifts and settles.
27
+ */
28
+ export const HEADER_FIRST_LAYOUT_3D = {
29
+ id: Layout3DId.HEADER_FIRST,
30
+ placement: { kind: ShellLayoutPlacementKind.COMPOSED, container: HeaderFirstShellContainer },
31
+ scene: { camera: Layout3DCamera.FLAT_ORTHOGRAPHIC, frameStyles: HEADER_FIRST_FRAME_STYLES },
32
+ transitions: {
33
+ appearance: Layout3DAppearanceTransition.CROSS_FADE,
34
+ navigation: Layout3DFrameChoreography.LIGHT_SWEEP,
35
+ sidebarResize: Layout3DFrameChoreography.ELEVATION_SETTLE,
36
+ zoneFocus: Layout3DZoneFocusTransition.RIM,
37
+ },
38
+ constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },
39
+ };
40
+ /** @wildo_source:part:end presets.3d.layout-contract */
41
+ /**
42
+ * PROTOTYPE (Paul, 2026-09-30): the shell's panels in space, seen through a moving perspective camera — clean spatial,
43
+ * content facing the camera, side columns angled, the camera gliding on arrival, navigation, pane focus and sidebar
44
+ * resize. Not a built-in yet (its id is its own, and it is absent from {@link BUILT_IN_LAYOUTS_3D}): it is here to be
45
+ * seen and judged in the running application before it is designed into a production layout.
46
+ */
47
+ export const SPATIAL_PROTOTYPE_LAYOUT_3D = {
48
+ id: 'spatial-prototype',
49
+ placement: { kind: ShellLayoutPlacementKind.COMPOSED, container: SpatialShellContainer },
50
+ scene: { camera: Layout3DCamera.SPATIAL_PERSPECTIVE, frameStyles: INHERIT_FRAME_STYLES },
51
+ transitions: {
52
+ appearance: Layout3DAppearanceTransition.CROSS_FADE,
53
+ navigation: Layout3DFrameChoreography.NONE,
54
+ sidebarResize: Layout3DFrameChoreography.NONE,
55
+ zoneFocus: Layout3DZoneFocusTransition.NONE,
56
+ },
57
+ constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },
58
+ };
59
+ /** Every built-in layout, keyed by its id: total over {@link Layout3DId}, so a new member must ship a layout. */
60
+ export const BUILT_IN_LAYOUTS_3D = {
61
+ [Layout3DId.INHERIT]: INHERIT_LAYOUT_3D,
62
+ [Layout3DId.HEADER_FIRST]: HEADER_FIRST_LAYOUT_3D,
63
+ };
64
+ /**
65
+ * Refuses a layout the renderer cannot draw as declared: a camera, a transition or a rest pose it does not
66
+ * implement. Exhaustive switches, so a member added to one of those vocabularies fails to compile here until the
67
+ * renderer supports it — and a value that reaches it at runtime anyway (an application's own layout, built without
68
+ * the types) is refused instead of being silently drawn as something else.
69
+ */
70
+ export function assertSupportedLayout3D(layout) {
71
+ const camera = layout.scene.camera;
72
+ switch (camera) {
73
+ case Layout3DCamera.FLAT_ORTHOGRAPHIC:
74
+ break;
75
+ case Layout3DCamera.SPATIAL_PERSPECTIVE:
76
+ // Only a placement that builds the CSS 3D stage can be seen through the spatial camera; the captured flat
77
+ // container cannot.
78
+ if (layout.placement.kind !== ShellLayoutPlacementKind.COMPOSED) {
79
+ throw new Error(`3D layout '${layout.id}': the spatial camera needs a composed placement that builds the spatial stage.`);
80
+ }
81
+ break;
82
+ default: {
83
+ const unsupported = camera;
84
+ throw new Error(`3D layout '${layout.id}': the frame has no camera '${String(unsupported)}'.`);
85
+ }
86
+ }
87
+ // Each throws on a member the frame does not play (a value built without the types).
88
+ crossFadesAppearance(layout.transitions.appearance);
89
+ frameChoreography(layout.transitions.navigation);
90
+ frameChoreography(layout.transitions.sidebarResize);
91
+ rimsFocusedZone(layout.transitions.zoneFocus);
92
+ const pose = layout.constraints.restPose;
93
+ switch (pose) {
94
+ // FLAT is what the container renders: the placement, untransformed.
95
+ case Layout3DRestPose.FLAT:
96
+ break;
97
+ default: {
98
+ const unsupported = pose;
99
+ throw new Error(`3D layout '${layout.id}': the rest pose '${String(unsupported)}' is not supported (only FLAT exists: no region is transformed at rest).`);
100
+ }
101
+ }
102
+ if (layout.placement.kind !== ShellLayoutPlacementKind.INHERIT && layout.placement.kind !== ShellLayoutPlacementKind.COMPOSED) {
103
+ throw new Error(`3D layout '${layout.id}': unknown placement kind '${String(layout.placement.kind)}'.`);
104
+ }
105
+ }
106
+ //# sourceMappingURL=layout-3d-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-definition.js","sourceRoot":"","sources":["../../../../src/layout/layout-3d-definition.ts"],"names":[],"mappings":"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","sourcesContent":["import { ShellAppearance } from '@wildo-ai/presets-components-models';\n\nimport { HEADER_FIRST_FRAME_STYLES, INHERIT_FRAME_STYLES, type Frame3DStyleCatalog } from '../frame/frame-3d-style';\nimport { HeaderFirstShellContainer } from './header-first-shell-container';\nimport { SpatialShellContainer } from '../spatial/spatial-shell-container';\nimport { ShellLayoutPlacementKind, type ShellLayoutPlacement } from './shell-layout-placement';\nimport { crossFadesAppearance, frameChoreography, rimsFocusedZone } from './layout-3d-transition-choreography';\nimport {\n Layout3DAppearanceTransition,\n Layout3DCamera,\n Layout3DId,\n Layout3DFrameChoreography,\n Layout3DRestPose,\n Layout3DZoneFocusTransition,\n type Layout3DTransitions,\n} from './layout-3d-vocabulary';\n\n/** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */\n/**\n * A 3D layout: where the regions go (`placement`, 3D-free), and what the frame draws around them (`scene`,\n * `transitions`), under `constraints`.\n */\nexport interface Layout3DDefinition {\n /** A {@link Layout3DId} for a built-in layout; an application's own layout names itself. */\n id: string;\n placement: ShellLayoutPlacement;\n scene: {\n camera: Layout3DCamera;\n /** The frame styles, per theme, with a fallback for any theme id the catalog does not name. */\n frameStyles: Frame3DStyleCatalog;\n };\n /** What the frame plays on an appearance change, a navigation, a sidebar resize and a zone focus. */\n transitions: Layout3DTransitions;\n constraints: {\n /** The shell appearance the layout is designed for; any other is reported once (a console warning), never switched. */\n requiredShellAppearance: ShellAppearance | null;\n restPose: Layout3DRestPose;\n };\n}\n\n/**\n * The 2D disposal, unchanged, with the frame under it. On navigation the content slab lifts and settles; when\n * the sidebar collapses or expands, the light swings across and back.\n */\nexport const INHERIT_LAYOUT_3D: Layout3DDefinition = {\n id: Layout3DId.INHERIT,\n placement: { kind: ShellLayoutPlacementKind.INHERIT },\n scene: { camera: Layout3DCamera.FLAT_ORTHOGRAPHIC, frameStyles: INHERIT_FRAME_STYLES },\n transitions: {\n appearance: Layout3DAppearanceTransition.CROSS_FADE,\n navigation: Layout3DFrameChoreography.ELEVATION_SETTLE,\n sidebarResize: Layout3DFrameChoreography.LIGHT_SWEEP,\n zoneFocus: Layout3DZoneFocusTransition.RIM,\n },\n constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },\n};\n\n/**\n * The header-first disposal, with the frame lit from the header down. On navigation the light swings from the header\n * and returns; when the sidebar collapses or expands, the content slab lifts and settles.\n */\nexport const HEADER_FIRST_LAYOUT_3D: Layout3DDefinition = {\n id: Layout3DId.HEADER_FIRST,\n placement: { kind: ShellLayoutPlacementKind.COMPOSED, container: HeaderFirstShellContainer },\n scene: { camera: Layout3DCamera.FLAT_ORTHOGRAPHIC, frameStyles: HEADER_FIRST_FRAME_STYLES },\n transitions: {\n appearance: Layout3DAppearanceTransition.CROSS_FADE,\n navigation: Layout3DFrameChoreography.LIGHT_SWEEP,\n sidebarResize: Layout3DFrameChoreography.ELEVATION_SETTLE,\n zoneFocus: Layout3DZoneFocusTransition.RIM,\n },\n constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },\n};\n/** @wildo_source:part:end presets.3d.layout-contract */\n\n/**\n * PROTOTYPE (Paul, 2026-09-30): the shell's panels in space, seen through a moving perspective camera — clean spatial,\n * content facing the camera, side columns angled, the camera gliding on arrival, navigation, pane focus and sidebar\n * resize. Not a built-in yet (its id is its own, and it is absent from {@link BUILT_IN_LAYOUTS_3D}): it is here to be\n * seen and judged in the running application before it is designed into a production layout.\n */\nexport const SPATIAL_PROTOTYPE_LAYOUT_3D: Layout3DDefinition = {\n id: 'spatial-prototype',\n placement: { kind: ShellLayoutPlacementKind.COMPOSED, container: SpatialShellContainer },\n scene: { camera: Layout3DCamera.SPATIAL_PERSPECTIVE, frameStyles: INHERIT_FRAME_STYLES },\n transitions: {\n appearance: Layout3DAppearanceTransition.CROSS_FADE,\n navigation: Layout3DFrameChoreography.NONE,\n sidebarResize: Layout3DFrameChoreography.NONE,\n zoneFocus: Layout3DZoneFocusTransition.NONE,\n },\n constraints: { requiredShellAppearance: ShellAppearance.CONTINUOUS, restPose: Layout3DRestPose.FLAT },\n};\n\n/** Every built-in layout, keyed by its id: total over {@link Layout3DId}, so a new member must ship a layout. */\nexport const BUILT_IN_LAYOUTS_3D: Record<Layout3DId, Layout3DDefinition> = {\n [Layout3DId.INHERIT]: INHERIT_LAYOUT_3D,\n [Layout3DId.HEADER_FIRST]: HEADER_FIRST_LAYOUT_3D,\n};\n\n/**\n * Refuses a layout the renderer cannot draw as declared: a camera, a transition or a rest pose it does not\n * implement. Exhaustive switches, so a member added to one of those vocabularies fails to compile here until the\n * renderer supports it — and a value that reaches it at runtime anyway (an application's own layout, built without\n * the types) is refused instead of being silently drawn as something else.\n */\nexport function assertSupportedLayout3D(layout: Layout3DDefinition): void {\n const camera = layout.scene.camera;\n switch (camera) {\n case Layout3DCamera.FLAT_ORTHOGRAPHIC:\n break;\n case Layout3DCamera.SPATIAL_PERSPECTIVE:\n // Only a placement that builds the CSS 3D stage can be seen through the spatial camera; the captured flat\n // container cannot.\n if (layout.placement.kind !== ShellLayoutPlacementKind.COMPOSED) {\n throw new Error(`3D layout '${layout.id}': the spatial camera needs a composed placement that builds the spatial stage.`);\n }\n break;\n default: {\n const unsupported: never = camera;\n throw new Error(`3D layout '${layout.id}': the frame has no camera '${String(unsupported)}'.`);\n }\n }\n // Each throws on a member the frame does not play (a value built without the types).\n crossFadesAppearance(layout.transitions.appearance);\n frameChoreography(layout.transitions.navigation);\n frameChoreography(layout.transitions.sidebarResize);\n rimsFocusedZone(layout.transitions.zoneFocus);\n const pose = layout.constraints.restPose;\n switch (pose) {\n // FLAT is what the container renders: the placement, untransformed.\n case Layout3DRestPose.FLAT:\n break;\n default: {\n const unsupported: never = pose;\n throw new Error(`3D layout '${layout.id}': the rest pose '${String(unsupported)}' is not supported (only FLAT exists: no region is transformed at rest).`);\n }\n }\n if (layout.placement.kind !== ShellLayoutPlacementKind.INHERIT && layout.placement.kind !== ShellLayoutPlacementKind.COMPOSED) {\n throw new Error(`3D layout '${layout.id}': unknown placement kind '${String((layout.placement as { kind: unknown }).kind)}'.`);\n }\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import { Layout3DAppearanceTransition, Layout3DFrameChoreography, Layout3DZoneFocusTransition } from './layout-3d-vocabulary';
2
+ /**
3
+ * The numbers each transition member plays (#1826), in one module both the registration check and the lazily loaded
4
+ * renderer read — so the members are interpreted in one place, and a member added to a vocabulary fails to compile
5
+ * HERE until it has numbers. Imports only the vocabulary, so the frame's chunk pulls in nothing else through it.
6
+ */
7
+ /**
8
+ * A frame choreography's numbers. A pulse RISES to full strength over the first half of its duration and
9
+ * SETTLES back over the second, each half eased by the theme's default easing; the strength shown is `sin(π/2 · v)`
10
+ * of that eased value, so it swells in and out without a corner at the peak.
11
+ */
12
+ export interface FrameChoreography {
13
+ /** Whether the trigger plays anything. */
14
+ plays: boolean;
15
+ /** How far the content slab's shadow blur and offset grow at the pulse's peak: 0.8 is 80% further. */
16
+ shadowSpread: number;
17
+ /** How far the content slab's rim moves from its rest opacity toward its hover opacity at the peak: 0 to 1. */
18
+ rimLift: number;
19
+ /** How far the light swings at the peak, in degrees. */
20
+ lightSweepDeg: number;
21
+ /** The pulse lasts this many times the theme's normal motion duration: one half to rise, one to settle. */
22
+ durationFactor: number;
23
+ }
24
+ /** The numbers of a frame choreography. Exhaustive over {@link Layout3DFrameChoreography}. */
25
+ export declare function frameChoreography(kind: Layout3DFrameChoreography): FrameChoreography;
26
+ /** Whether the focused zone gets a rim. Exhaustive over {@link Layout3DZoneFocusTransition}. */
27
+ export declare function rimsFocusedZone(kind: Layout3DZoneFocusTransition): boolean;
28
+ /** Whether the frame cross-fades an appearance change. Exhaustive over {@link Layout3DAppearanceTransition}. */
29
+ export declare function crossFadesAppearance(kind: Layout3DAppearanceTransition): boolean;
30
+ //# sourceMappingURL=layout-3d-transition-choreography.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-transition-choreography.d.ts","sourceRoot":"","sources":["../../../../src/layout/layout-3d-transition-choreography.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAE9H;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,KAAK,EAAE,OAAO,CAAC;IACf,sGAAsG;IACtG,YAAY,EAAE,MAAM,CAAC;IACrB,+GAA+G;IAC/G,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,yBAAyB,GAAG,iBAAiB,CAcpF;AAED,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAW1E;AAED,gHAAgH;AAChH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,4BAA4B,GAAG,OAAO,CAShF"}
@@ -0,0 +1,43 @@
1
+ import { Layout3DAppearanceTransition, Layout3DFrameChoreography, Layout3DZoneFocusTransition } from './layout-3d-vocabulary.js';
2
+ const STILL = { plays: false, shadowSpread: 0, rimLift: 0, lightSweepDeg: 0, durationFactor: 0 };
3
+ /** The numbers of a frame choreography. Exhaustive over {@link Layout3DFrameChoreography}. */
4
+ export function frameChoreography(kind) {
5
+ switch (kind) {
6
+ case Layout3DFrameChoreography.NONE:
7
+ return STILL;
8
+ case Layout3DFrameChoreography.ELEVATION_SETTLE:
9
+ // Rim capped at 1 (the hover opacity): the bound was proved for the rim at hover opacity over the frost.
10
+ return { plays: true, shadowSpread: 0.8, rimLift: 1, lightSweepDeg: 0, durationFactor: 2 };
11
+ case Layout3DFrameChoreography.LIGHT_SWEEP:
12
+ return { plays: true, shadowSpread: 0, rimLift: 0, lightSweepDeg: 40, durationFactor: 2 };
13
+ default: {
14
+ const unsupported = kind;
15
+ throw new Error(`The 3D frame plays no frame choreography '${String(unsupported)}'.`);
16
+ }
17
+ }
18
+ }
19
+ /** Whether the focused zone gets a rim. Exhaustive over {@link Layout3DZoneFocusTransition}. */
20
+ export function rimsFocusedZone(kind) {
21
+ switch (kind) {
22
+ case Layout3DZoneFocusTransition.NONE:
23
+ return false;
24
+ case Layout3DZoneFocusTransition.RIM:
25
+ return true;
26
+ default: {
27
+ const unsupported = kind;
28
+ throw new Error(`The 3D frame plays no zone-focus transition '${String(unsupported)}'.`);
29
+ }
30
+ }
31
+ }
32
+ /** Whether the frame cross-fades an appearance change. Exhaustive over {@link Layout3DAppearanceTransition}. */
33
+ export function crossFadesAppearance(kind) {
34
+ switch (kind) {
35
+ case Layout3DAppearanceTransition.CROSS_FADE:
36
+ return true;
37
+ default: {
38
+ const unsupported = kind;
39
+ throw new Error(`The 3D frame plays no appearance transition '${String(unsupported)}'.`);
40
+ }
41
+ }
42
+ }
43
+ //# sourceMappingURL=layout-3d-transition-choreography.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-transition-choreography.js","sourceRoot":"","sources":["../../../../src/layout/layout-3d-transition-choreography.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AA0B9H,MAAM,KAAK,GAAsB,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;AAEpH,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,IAA+B;IAC/D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,yBAAyB,CAAC,IAAI;YACjC,OAAO,KAAK,CAAC;QACf,KAAK,yBAAyB,CAAC,gBAAgB;YAC7C,yGAAyG;YACzG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAC7F,KAAK,yBAAyB,CAAC,WAAW;YACxC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAC5F,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,eAAe,CAAC,IAAiC;IAC/D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,2BAA2B,CAAC,IAAI;YACnC,OAAO,KAAK,CAAC;QACf,KAAK,2BAA2B,CAAC,GAAG;YAClC,OAAO,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;AACH,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,oBAAoB,CAAC,IAAkC;IACrE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,4BAA4B,CAAC,UAAU;YAC1C,OAAO,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,IAAI,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { Layout3DAppearanceTransition, Layout3DFrameChoreography, Layout3DZoneFocusTransition } from './layout-3d-vocabulary';\n\n/**\n * The numbers each transition member plays (#1826), in one module both the registration check and the lazily loaded\n * renderer read — so the members are interpreted in one place, and a member added to a vocabulary fails to compile\n * HERE until it has numbers. Imports only the vocabulary, so the frame's chunk pulls in nothing else through it.\n */\n\n/**\n * A frame choreography's numbers. A pulse RISES to full strength over the first half of its duration and\n * SETTLES back over the second, each half eased by the theme's default easing; the strength shown is `sin(π/2 · v)`\n * of that eased value, so it swells in and out without a corner at the peak.\n */\nexport interface FrameChoreography {\n /** Whether the trigger plays anything. */\n plays: boolean;\n /** How far the content slab's shadow blur and offset grow at the pulse's peak: 0.8 is 80% further. */\n shadowSpread: number;\n /** How far the content slab's rim moves from its rest opacity toward its hover opacity at the peak: 0 to 1. */\n rimLift: number;\n /** How far the light swings at the peak, in degrees. */\n lightSweepDeg: number;\n /** The pulse lasts this many times the theme's normal motion duration: one half to rise, one to settle. */\n durationFactor: number;\n}\n\nconst STILL: FrameChoreography = { plays: false, shadowSpread: 0, rimLift: 0, lightSweepDeg: 0, durationFactor: 0 };\n\n/** The numbers of a frame choreography. Exhaustive over {@link Layout3DFrameChoreography}. */\nexport function frameChoreography(kind: Layout3DFrameChoreography): FrameChoreography {\n switch (kind) {\n case Layout3DFrameChoreography.NONE:\n return STILL;\n case Layout3DFrameChoreography.ELEVATION_SETTLE:\n // Rim capped at 1 (the hover opacity): the bound was proved for the rim at hover opacity over the frost.\n return { plays: true, shadowSpread: 0.8, rimLift: 1, lightSweepDeg: 0, durationFactor: 2 };\n case Layout3DFrameChoreography.LIGHT_SWEEP:\n return { plays: true, shadowSpread: 0, rimLift: 0, lightSweepDeg: 40, durationFactor: 2 };\n default: {\n const unsupported: never = kind;\n throw new Error(`The 3D frame plays no frame choreography '${String(unsupported)}'.`);\n }\n }\n}\n\n/** Whether the focused zone gets a rim. Exhaustive over {@link Layout3DZoneFocusTransition}. */\nexport function rimsFocusedZone(kind: Layout3DZoneFocusTransition): boolean {\n switch (kind) {\n case Layout3DZoneFocusTransition.NONE:\n return false;\n case Layout3DZoneFocusTransition.RIM:\n return true;\n default: {\n const unsupported: never = kind;\n throw new Error(`The 3D frame plays no zone-focus transition '${String(unsupported)}'.`);\n }\n }\n}\n\n/** Whether the frame cross-fades an appearance change. Exhaustive over {@link Layout3DAppearanceTransition}. */\nexport function crossFadesAppearance(kind: Layout3DAppearanceTransition): boolean {\n switch (kind) {\n case Layout3DAppearanceTransition.CROSS_FADE:\n return true;\n default: {\n const unsupported: never = kind;\n throw new Error(`The 3D frame plays no appearance transition '${String(unsupported)}'.`);\n }\n }\n}\n"]}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The 3D layout vocabularies (#1843), in a module that imports NOTHING: the lazily loaded frame canvas reads
3
+ * `Layout3DCamera`, and must not pull the layout definitions (and their shell containers) into its chunk to do so.
4
+ */
5
+ /** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
6
+ /**
7
+ * The built-in 3D layouts. An application uses exactly ONE, chosen when it registers the library; there
8
+ * is no switch. An application may also define its own layout with an id of its own.
9
+ */
10
+ export declare enum Layout3DId {
11
+ /** The 2D shell's own disposal, unchanged, with the 3D frame drawn under its regions. */
12
+ INHERIT = "inherit",
13
+ /**
14
+ * The menubar and the status bars span the whole width; the navigation rails (activity bar, sidebar, utility
15
+ * panel) sit between them, beside the content. The default disposal is sidebar-first; this one is header-first.
16
+ */
17
+ HEADER_FIRST = "header-first"
18
+ }
19
+ /**
20
+ * The cameras the frame renderer supports. The transitions need none beyond this one: every choreography is
21
+ * drawn IN the flat frame (elevation, light, rims), so a slab never leaves its region's box.
22
+ */
23
+ export declare enum Layout3DCamera {
24
+ /** Orthographic, matched 1:1 to CSS pixels: the frame lies flat under the regions, exactly on their boxes. */
25
+ FLAT_ORTHOGRAPHIC = "flat-orthographic",
26
+ /**
27
+ * PROTOTYPE (Paul, 2026-09-30: "a real camera aspect", clean spatial). A perspective camera looks at the shell's
28
+ * panels placed in space: the content faces it (crisp at rest), side columns stand angled, and the camera MOVES on
29
+ * transitions. The panels are the live HTML, in a CSS 3D stage driven by the same camera as the WebGL environment
30
+ * around them. Only a placement that builds that stage can use it (`SPATIAL_PROTOTYPE_LAYOUT_3D`).
31
+ */
32
+ SPATIAL_PERSPECTIVE = "spatial-perspective"
33
+ }
34
+ /**
35
+ * How the frame answers an APPEARANCE change: a theme, a density, a reduced-motion switch.
36
+ *
37
+ * Whatever the member, a light/dark switch SNAPS: text changes colour at once, and a backdrop halfway between two
38
+ * modes is bounded against neither foreground.
39
+ */
40
+ export declare enum Layout3DAppearanceTransition {
41
+ /** The frame cross-fades to the new appearance over the theme's normal motion duration. */
42
+ CROSS_FADE = "cross-fade"
43
+ }
44
+ /**
45
+ * A choreography the frame plays once, as a PULSE that rises and settles, when a shell state changes. The same
46
+ * vocabulary serves every pulse-shaped trigger of {@link Layout3DTransitions} (a navigation, a sidebar resize), so a
47
+ * layout picks per trigger and a new choreography is available to every trigger at once.
48
+ *
49
+ * Every member is drawn in the FRAME. No member transforms a region: a CSS transform blurs text while it runs and
50
+ * makes the region the containing block of its `position: fixed` overlays. A choreography that moved regions would
51
+ * need an untransformed portal target on the shell providers (a default-off option, not built) and its own
52
+ * member here; none exists.
53
+ *
54
+ * Every member stays inside the contrast bound (see each), and plays nothing under reduced motion, where the theme's
55
+ * motion duration is zero.
56
+ */
57
+ export declare enum Layout3DFrameChoreography {
58
+ /** Nothing moves. For an application's own layout that wants a still frame on this trigger. */
59
+ NONE = "none",
60
+ /**
61
+ * The content slab lifts toward the reader and settles back: its shadow spreads and drops further, and its rim
62
+ * brightens toward its hover opacity, then both return. Only blur, offset and rim move — never the shadow's
63
+ * opacity, and never the rim past the hover opacity the bound was proved for.
64
+ */
65
+ ELEVATION_SETTLE = "elevation-settle",
66
+ /**
67
+ * The light swings across the frame and back: every gradient re-orients along the moving light. Every colour it
68
+ * shows is a point of a gradient the bound already covers; only its direction changes.
69
+ */
70
+ LIGHT_SWEEP = "light-sweep"
71
+ }
72
+ /**
73
+ * What the frame shows for the FOCUSED navigation zone (`useNavigationState().focusedZone`), when two or more zones
74
+ * are side by side.
75
+ */
76
+ export declare enum Layout3DZoneFocusTransition {
77
+ /** Nothing marks the focused zone in the frame. */
78
+ NONE = "none",
79
+ /**
80
+ * A rim in the content slab's rim colour, at most its hover opacity, around the focused zone; it moves to another
81
+ * zone with the theme's gesture spring. Inset clear of the content slab's own rim band, so where it is drawn it is
82
+ * the case the bound was proved for — a rim at hover opacity over the frost — except that it is written as a second
83
+ * framebuffer layer, rounded to 8 bits twice rather than once (at most 1/255 apart), and that the emphasis values
84
+ * between rest and hover are not checked one by one: both limits are shared with the slab rim's own hover emphasis.
85
+ */
86
+ RIM = "rim"
87
+ }
88
+ /**
89
+ * What a layout does to the regions at rest. Only FLAT exists: a CSS 3D transform blurs text, and any transform
90
+ * makes a region the containing block of its `position: fixed` descendants. A layout that wants a persistent tilt
91
+ * needs an untransformed portal target on the shell providers (not built: no choreography moves a region) and a new member here.
92
+ */
93
+ export declare enum Layout3DRestPose {
94
+ /** The regions are never transformed at rest. */
95
+ FLAT = "flat"
96
+ }
97
+ /**
98
+ * What a layout plays, per trigger. The triggers are read from existing state only: the navigation state
99
+ * (`useNavigationState`) and the shell's own region measurement. Whatever a layout picks, the frame FOLLOWS every
100
+ * region's box frame by frame while the shell animates (the alignment invariant); these are what it plays
101
+ * ON TOP of following.
102
+ */
103
+ export interface Layout3DTransitions {
104
+ /** A theme, density or reduced-motion change. */
105
+ appearance: Layout3DAppearanceTransition;
106
+ /**
107
+ * The content changed: any structural zone's top entry is a different place (its URL). The route sync hooks mirror
108
+ * router navigations into those stacks, so a sidebar link and a record opened beside a list both count; the
109
+ * overlay zone does not (a dialog is not a place).
110
+ */
111
+ navigation: Layout3DFrameChoreography;
112
+ /** The sidebar collapsed, expanded or was resized: its measured width changed while it stayed on screen. */
113
+ sidebarResize: Layout3DFrameChoreography;
114
+ /** The navigation state's focused zone changed while two or more zones are side by side. */
115
+ zoneFocus: Layout3DZoneFocusTransition;
116
+ }
117
+ /** @wildo_source:part:end presets.3d.layout-contract */
118
+ //# sourceMappingURL=layout-3d-vocabulary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-vocabulary.d.ts","sourceRoot":"","sources":["../../../../src/layout/layout-3d-vocabulary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mIAAmI;AACnI;;;GAGG;AACH,oBAAY,UAAU;IACpB,yFAAyF;IACzF,OAAO,YAAY;IACnB;;;OAGG;IACH,YAAY,iBAAiB;CAC9B;AAED;;;GAGG;AACH,oBAAY,cAAc;IACxB,8GAA8G;IAC9G,iBAAiB,sBAAsB;IACvC;;;;;OAKG;IACH,mBAAmB,wBAAwB;CAC5C;AAED;;;;;GAKG;AACH,oBAAY,4BAA4B;IACtC,2FAA2F;IAC3F,UAAU,eAAe;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,oBAAY,yBAAyB;IACnC,+FAA+F;IAC/F,IAAI,SAAS;IACb;;;;OAIG;IACH,gBAAgB,qBAAqB;IACrC;;;OAGG;IACH,WAAW,gBAAgB;CAC5B;AAED;;;GAGG;AACH,oBAAY,2BAA2B;IACrC,mDAAmD;IACnD,IAAI,SAAS;IACb;;;;;;OAMG;IACH,GAAG,QAAQ;CACZ;AAED;;;;GAIG;AACH,oBAAY,gBAAgB;IAC1B,iDAAiD;IACjD,IAAI,SAAS;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,UAAU,EAAE,4BAA4B,CAAC;IACzC;;;;OAIG;IACH,UAAU,EAAE,yBAAyB,CAAC;IACtC,4GAA4G;IAC5G,aAAa,EAAE,yBAAyB,CAAC;IACzC,4FAA4F;IAC5F,SAAS,EAAE,2BAA2B,CAAC;CACxC;AACD,wDAAwD"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The 3D layout vocabularies (#1843), in a module that imports NOTHING: the lazily loaded frame canvas reads
3
+ * `Layout3DCamera`, and must not pull the layout definitions (and their shell containers) into its chunk to do so.
4
+ */
5
+ /** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
6
+ /**
7
+ * The built-in 3D layouts. An application uses exactly ONE, chosen when it registers the library; there
8
+ * is no switch. An application may also define its own layout with an id of its own.
9
+ */
10
+ export var Layout3DId;
11
+ (function (Layout3DId) {
12
+ /** The 2D shell's own disposal, unchanged, with the 3D frame drawn under its regions. */
13
+ Layout3DId["INHERIT"] = "inherit";
14
+ /**
15
+ * The menubar and the status bars span the whole width; the navigation rails (activity bar, sidebar, utility
16
+ * panel) sit between them, beside the content. The default disposal is sidebar-first; this one is header-first.
17
+ */
18
+ Layout3DId["HEADER_FIRST"] = "header-first";
19
+ })(Layout3DId || (Layout3DId = {}));
20
+ /**
21
+ * The cameras the frame renderer supports. The transitions need none beyond this one: every choreography is
22
+ * drawn IN the flat frame (elevation, light, rims), so a slab never leaves its region's box.
23
+ */
24
+ export var Layout3DCamera;
25
+ (function (Layout3DCamera) {
26
+ /** Orthographic, matched 1:1 to CSS pixels: the frame lies flat under the regions, exactly on their boxes. */
27
+ Layout3DCamera["FLAT_ORTHOGRAPHIC"] = "flat-orthographic";
28
+ /**
29
+ * PROTOTYPE (Paul, 2026-09-30: "a real camera aspect", clean spatial). A perspective camera looks at the shell's
30
+ * panels placed in space: the content faces it (crisp at rest), side columns stand angled, and the camera MOVES on
31
+ * transitions. The panels are the live HTML, in a CSS 3D stage driven by the same camera as the WebGL environment
32
+ * around them. Only a placement that builds that stage can use it (`SPATIAL_PROTOTYPE_LAYOUT_3D`).
33
+ */
34
+ Layout3DCamera["SPATIAL_PERSPECTIVE"] = "spatial-perspective";
35
+ })(Layout3DCamera || (Layout3DCamera = {}));
36
+ /**
37
+ * How the frame answers an APPEARANCE change: a theme, a density, a reduced-motion switch.
38
+ *
39
+ * Whatever the member, a light/dark switch SNAPS: text changes colour at once, and a backdrop halfway between two
40
+ * modes is bounded against neither foreground.
41
+ */
42
+ export var Layout3DAppearanceTransition;
43
+ (function (Layout3DAppearanceTransition) {
44
+ /** The frame cross-fades to the new appearance over the theme's normal motion duration. */
45
+ Layout3DAppearanceTransition["CROSS_FADE"] = "cross-fade";
46
+ })(Layout3DAppearanceTransition || (Layout3DAppearanceTransition = {}));
47
+ /**
48
+ * A choreography the frame plays once, as a PULSE that rises and settles, when a shell state changes. The same
49
+ * vocabulary serves every pulse-shaped trigger of {@link Layout3DTransitions} (a navigation, a sidebar resize), so a
50
+ * layout picks per trigger and a new choreography is available to every trigger at once.
51
+ *
52
+ * Every member is drawn in the FRAME. No member transforms a region: a CSS transform blurs text while it runs and
53
+ * makes the region the containing block of its `position: fixed` overlays. A choreography that moved regions would
54
+ * need an untransformed portal target on the shell providers (a default-off option, not built) and its own
55
+ * member here; none exists.
56
+ *
57
+ * Every member stays inside the contrast bound (see each), and plays nothing under reduced motion, where the theme's
58
+ * motion duration is zero.
59
+ */
60
+ export var Layout3DFrameChoreography;
61
+ (function (Layout3DFrameChoreography) {
62
+ /** Nothing moves. For an application's own layout that wants a still frame on this trigger. */
63
+ Layout3DFrameChoreography["NONE"] = "none";
64
+ /**
65
+ * The content slab lifts toward the reader and settles back: its shadow spreads and drops further, and its rim
66
+ * brightens toward its hover opacity, then both return. Only blur, offset and rim move — never the shadow's
67
+ * opacity, and never the rim past the hover opacity the bound was proved for.
68
+ */
69
+ Layout3DFrameChoreography["ELEVATION_SETTLE"] = "elevation-settle";
70
+ /**
71
+ * The light swings across the frame and back: every gradient re-orients along the moving light. Every colour it
72
+ * shows is a point of a gradient the bound already covers; only its direction changes.
73
+ */
74
+ Layout3DFrameChoreography["LIGHT_SWEEP"] = "light-sweep";
75
+ })(Layout3DFrameChoreography || (Layout3DFrameChoreography = {}));
76
+ /**
77
+ * What the frame shows for the FOCUSED navigation zone (`useNavigationState().focusedZone`), when two or more zones
78
+ * are side by side.
79
+ */
80
+ export var Layout3DZoneFocusTransition;
81
+ (function (Layout3DZoneFocusTransition) {
82
+ /** Nothing marks the focused zone in the frame. */
83
+ Layout3DZoneFocusTransition["NONE"] = "none";
84
+ /**
85
+ * A rim in the content slab's rim colour, at most its hover opacity, around the focused zone; it moves to another
86
+ * zone with the theme's gesture spring. Inset clear of the content slab's own rim band, so where it is drawn it is
87
+ * the case the bound was proved for — a rim at hover opacity over the frost — except that it is written as a second
88
+ * framebuffer layer, rounded to 8 bits twice rather than once (at most 1/255 apart), and that the emphasis values
89
+ * between rest and hover are not checked one by one: both limits are shared with the slab rim's own hover emphasis.
90
+ */
91
+ Layout3DZoneFocusTransition["RIM"] = "rim";
92
+ })(Layout3DZoneFocusTransition || (Layout3DZoneFocusTransition = {}));
93
+ /**
94
+ * What a layout does to the regions at rest. Only FLAT exists: a CSS 3D transform blurs text, and any transform
95
+ * makes a region the containing block of its `position: fixed` descendants. A layout that wants a persistent tilt
96
+ * needs an untransformed portal target on the shell providers (not built: no choreography moves a region) and a new member here.
97
+ */
98
+ export var Layout3DRestPose;
99
+ (function (Layout3DRestPose) {
100
+ /** The regions are never transformed at rest. */
101
+ Layout3DRestPose["FLAT"] = "flat";
102
+ })(Layout3DRestPose || (Layout3DRestPose = {}));
103
+ /** @wildo_source:part:end presets.3d.layout-contract */
104
+ //# sourceMappingURL=layout-3d-vocabulary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-vocabulary.js","sourceRoot":"","sources":["../../../../src/layout/layout-3d-vocabulary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mIAAmI;AACnI;;;GAGG;AACH,MAAM,CAAN,IAAY,UAQX;AARD,WAAY,UAAU;IACpB,yFAAyF;IACzF,iCAAmB,CAAA;IACnB;;;OAGG;IACH,2CAA6B,CAAA;AAC/B,CAAC,EARW,UAAU,KAAV,UAAU,QAQrB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,cAUX;AAVD,WAAY,cAAc;IACxB,8GAA8G;IAC9G,yDAAuC,CAAA;IACvC;;;;;OAKG;IACH,6DAA2C,CAAA;AAC7C,CAAC,EAVW,cAAc,KAAd,cAAc,QAUzB;AAED;;;;;GAKG;AACH,MAAM,CAAN,IAAY,4BAGX;AAHD,WAAY,4BAA4B;IACtC,2FAA2F;IAC3F,yDAAyB,CAAA;AAC3B,CAAC,EAHW,4BAA4B,KAA5B,4BAA4B,QAGvC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAN,IAAY,yBAcX;AAdD,WAAY,yBAAyB;IACnC,+FAA+F;IAC/F,0CAAa,CAAA;IACb;;;;OAIG;IACH,kEAAqC,CAAA;IACrC;;;OAGG;IACH,wDAA2B,CAAA;AAC7B,CAAC,EAdW,yBAAyB,KAAzB,yBAAyB,QAcpC;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,2BAWX;AAXD,WAAY,2BAA2B;IACrC,mDAAmD;IACnD,4CAAa,CAAA;IACb;;;;;;OAMG;IACH,0CAAW,CAAA;AACb,CAAC,EAXW,2BAA2B,KAA3B,2BAA2B,QAWtC;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,iDAAiD;IACjD,iCAAa,CAAA;AACf,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAsBD,wDAAwD","sourcesContent":["/**\n * The 3D layout vocabularies (#1843), in a module that imports NOTHING: the lazily loaded frame canvas reads\n * `Layout3DCamera`, and must not pull the layout definitions (and their shell containers) into its chunk to do so.\n */\n\n/** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */\n/**\n * The built-in 3D layouts. An application uses exactly ONE, chosen when it registers the library; there\n * is no switch. An application may also define its own layout with an id of its own.\n */\nexport enum Layout3DId {\n /** The 2D shell's own disposal, unchanged, with the 3D frame drawn under its regions. */\n INHERIT = 'inherit',\n /**\n * The menubar and the status bars span the whole width; the navigation rails (activity bar, sidebar, utility\n * panel) sit between them, beside the content. The default disposal is sidebar-first; this one is header-first.\n */\n HEADER_FIRST = 'header-first',\n}\n\n/**\n * The cameras the frame renderer supports. The transitions need none beyond this one: every choreography is\n * drawn IN the flat frame (elevation, light, rims), so a slab never leaves its region's box.\n */\nexport enum Layout3DCamera {\n /** Orthographic, matched 1:1 to CSS pixels: the frame lies flat under the regions, exactly on their boxes. */\n FLAT_ORTHOGRAPHIC = 'flat-orthographic',\n /**\n * PROTOTYPE (Paul, 2026-09-30: \"a real camera aspect\", clean spatial). A perspective camera looks at the shell's\n * panels placed in space: the content faces it (crisp at rest), side columns stand angled, and the camera MOVES on\n * transitions. The panels are the live HTML, in a CSS 3D stage driven by the same camera as the WebGL environment\n * around them. Only a placement that builds that stage can use it (`SPATIAL_PROTOTYPE_LAYOUT_3D`).\n */\n SPATIAL_PERSPECTIVE = 'spatial-perspective',\n}\n\n/**\n * How the frame answers an APPEARANCE change: a theme, a density, a reduced-motion switch.\n *\n * Whatever the member, a light/dark switch SNAPS: text changes colour at once, and a backdrop halfway between two\n * modes is bounded against neither foreground.\n */\nexport enum Layout3DAppearanceTransition {\n /** The frame cross-fades to the new appearance over the theme's normal motion duration. */\n CROSS_FADE = 'cross-fade',\n}\n\n/**\n * A choreography the frame plays once, as a PULSE that rises and settles, when a shell state changes. The same\n * vocabulary serves every pulse-shaped trigger of {@link Layout3DTransitions} (a navigation, a sidebar resize), so a\n * layout picks per trigger and a new choreography is available to every trigger at once.\n *\n * Every member is drawn in the FRAME. No member transforms a region: a CSS transform blurs text while it runs and\n * makes the region the containing block of its `position: fixed` overlays. A choreography that moved regions would\n * need an untransformed portal target on the shell providers (a default-off option, not built) and its own\n * member here; none exists.\n *\n * Every member stays inside the contrast bound (see each), and plays nothing under reduced motion, where the theme's\n * motion duration is zero.\n */\nexport enum Layout3DFrameChoreography {\n /** Nothing moves. For an application's own layout that wants a still frame on this trigger. */\n NONE = 'none',\n /**\n * The content slab lifts toward the reader and settles back: its shadow spreads and drops further, and its rim\n * brightens toward its hover opacity, then both return. Only blur, offset and rim move — never the shadow's\n * opacity, and never the rim past the hover opacity the bound was proved for.\n */\n ELEVATION_SETTLE = 'elevation-settle',\n /**\n * The light swings across the frame and back: every gradient re-orients along the moving light. Every colour it\n * shows is a point of a gradient the bound already covers; only its direction changes.\n */\n LIGHT_SWEEP = 'light-sweep',\n}\n\n/**\n * What the frame shows for the FOCUSED navigation zone (`useNavigationState().focusedZone`), when two or more zones\n * are side by side.\n */\nexport enum Layout3DZoneFocusTransition {\n /** Nothing marks the focused zone in the frame. */\n NONE = 'none',\n /**\n * A rim in the content slab's rim colour, at most its hover opacity, around the focused zone; it moves to another\n * zone with the theme's gesture spring. Inset clear of the content slab's own rim band, so where it is drawn it is\n * the case the bound was proved for — a rim at hover opacity over the frost — except that it is written as a second\n * framebuffer layer, rounded to 8 bits twice rather than once (at most 1/255 apart), and that the emphasis values\n * between rest and hover are not checked one by one: both limits are shared with the slab rim's own hover emphasis.\n */\n RIM = 'rim',\n}\n\n/**\n * What a layout does to the regions at rest. Only FLAT exists: a CSS 3D transform blurs text, and any transform\n * makes a region the containing block of its `position: fixed` descendants. A layout that wants a persistent tilt\n * needs an untransformed portal target on the shell providers (not built: no choreography moves a region) and a new member here.\n */\nexport enum Layout3DRestPose {\n /** The regions are never transformed at rest. */\n FLAT = 'flat',\n}\n\n/**\n * What a layout plays, per trigger. The triggers are read from existing state only: the navigation state\n * (`useNavigationState`) and the shell's own region measurement. Whatever a layout picks, the frame FOLLOWS every\n * region's box frame by frame while the shell animates (the alignment invariant); these are what it plays\n * ON TOP of following.\n */\nexport interface Layout3DTransitions {\n /** A theme, density or reduced-motion change. */\n appearance: Layout3DAppearanceTransition;\n /**\n * The content changed: any structural zone's top entry is a different place (its URL). The route sync hooks mirror\n * router navigations into those stacks, so a sidebar link and a record opened beside a list both count; the\n * overlay zone does not (a dialog is not a place).\n */\n navigation: Layout3DFrameChoreography;\n /** The sidebar collapsed, expanded or was resized: its measured width changed while it stayed on screen. */\n sidebarResize: Layout3DFrameChoreography;\n /** The navigation state's focused zone changed while two or more zones are side by side. */\n zoneFocus: Layout3DZoneFocusTransition;\n}\n/** @wildo_source:part:end presets.3d.layout-contract */\n"]}
@@ -0,0 +1,26 @@
1
+ import type React from 'react';
2
+ import type { AppLayoutPreset_MainContainer_DefaultProps } from '@wildo-ai/saas-frontend-lib';
3
+ /** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
4
+ /**
5
+ * How a shell layout disposes the regions — the half of a layout with nothing 3D in it.
6
+ *
7
+ * Named for the SHELL, not for 3D, on purpose: a composed placement is an ordinary shell container built from the
8
+ * building blocks of `@wildo-ai/saas-frontend-lib` (`AppShellProviders`, the region, content and overlays outlets,
9
+ * `AppShellLoadingState`), so the same shape can serve a general layout system for 2D shells — planned, not built —
10
+ * without renaming. The 3D half (scene, transitions, rest pose) lives in `Layout3DDefinition`.
11
+ */
12
+ export declare enum ShellLayoutPlacementKind {
13
+ /** The main container the registration captured (the 2D default, or an application's own), rendered unchanged. */
14
+ INHERIT = "inherit",
15
+ /** A container of the layout's own, composed from the shell building blocks. */
16
+ COMPOSED = "composed"
17
+ }
18
+ /** A shell layout's disposal. */
19
+ export type ShellLayoutPlacement = {
20
+ kind: ShellLayoutPlacementKind.INHERIT;
21
+ } | {
22
+ kind: ShellLayoutPlacementKind.COMPOSED;
23
+ container: React.ComponentType<AppLayoutPreset_MainContainer_DefaultProps>;
24
+ };
25
+ /** @wildo_source:part:end presets.3d.layout-contract */
26
+ //# sourceMappingURL=shell-layout-placement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-layout-placement.d.ts","sourceRoot":"","sources":["../../../../src/layout/shell-layout-placement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,0CAA0C,EAAE,MAAM,6BAA6B,CAAC;AAE9F,mIAAmI;AACnI;;;;;;;GAOG;AACH,oBAAY,wBAAwB;IAClC,kHAAkH;IAClH,OAAO,YAAY;IACnB,gFAAgF;IAChF,QAAQ,aAAa;CACtB;AAED,iCAAiC;AACjC,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,wBAAwB,CAAC,OAAO,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,wBAAwB,CAAC,QAAQ,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAA;CAAE,CAAC;AAC5H,wDAAwD"}
@@ -0,0 +1,18 @@
1
+ /** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
2
+ /**
3
+ * How a shell layout disposes the regions — the half of a layout with nothing 3D in it.
4
+ *
5
+ * Named for the SHELL, not for 3D, on purpose: a composed placement is an ordinary shell container built from the
6
+ * building blocks of `@wildo-ai/saas-frontend-lib` (`AppShellProviders`, the region, content and overlays outlets,
7
+ * `AppShellLoadingState`), so the same shape can serve a general layout system for 2D shells — planned, not built —
8
+ * without renaming. The 3D half (scene, transitions, rest pose) lives in `Layout3DDefinition`.
9
+ */
10
+ export var ShellLayoutPlacementKind;
11
+ (function (ShellLayoutPlacementKind) {
12
+ /** The main container the registration captured (the 2D default, or an application's own), rendered unchanged. */
13
+ ShellLayoutPlacementKind["INHERIT"] = "inherit";
14
+ /** A container of the layout's own, composed from the shell building blocks. */
15
+ ShellLayoutPlacementKind["COMPOSED"] = "composed";
16
+ })(ShellLayoutPlacementKind || (ShellLayoutPlacementKind = {}));
17
+ /** @wildo_source:part:end presets.3d.layout-contract */
18
+ //# sourceMappingURL=shell-layout-placement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-layout-placement.js","sourceRoot":"","sources":["../../../../src/layout/shell-layout-placement.ts"],"names":[],"mappings":"AAIA,mIAAmI;AACnI;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,wBAKX;AALD,WAAY,wBAAwB;IAClC,kHAAkH;IAClH,+CAAmB,CAAA;IACnB,gFAAgF;IAChF,iDAAqB,CAAA;AACvB,CAAC,EALW,wBAAwB,KAAxB,wBAAwB,QAKnC;AAMD,wDAAwD","sourcesContent":["import type React from 'react';\n\nimport type { AppLayoutPreset_MainContainer_DefaultProps } from '@wildo-ai/saas-frontend-lib';\n\n/** @wildo_source:part:start presets.3d.layout-contract facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */\n/**\n * How a shell layout disposes the regions — the half of a layout with nothing 3D in it.\n *\n * Named for the SHELL, not for 3D, on purpose: a composed placement is an ordinary shell container built from the\n * building blocks of `@wildo-ai/saas-frontend-lib` (`AppShellProviders`, the region, content and overlays outlets,\n * `AppShellLoadingState`), so the same shape can serve a general layout system for 2D shells — planned, not built —\n * without renaming. The 3D half (scene, transitions, rest pose) lives in `Layout3DDefinition`.\n */\nexport enum ShellLayoutPlacementKind {\n /** The main container the registration captured (the 2D default, or an application's own), rendered unchanged. */\n INHERIT = 'inherit',\n /** A container of the layout's own, composed from the shell building blocks. */\n COMPOSED = 'composed',\n}\n\n/** A shell layout's disposal. */\nexport type ShellLayoutPlacement =\n | { kind: ShellLayoutPlacementKind.INHERIT }\n | { kind: ShellLayoutPlacementKind.COMPOSED; container: React.ComponentType<AppLayoutPreset_MainContainer_DefaultProps> };\n/** @wildo_source:part:end presets.3d.layout-contract */\n"]}
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import { type AppLayoutPreset_MainContainer_DefaultProps } from '@wildo-ai/saas-frontend-lib';
3
+ import type { Frame3DStyleOverrides } from './frame/frame-3d-style';
4
+ import { type Layout3DDefinition } from './layout/layout-3d-definition';
5
+ /**
6
+ * The brand a 3D main container carries. `Symbol.for`, not `Symbol`: the component registry lives on
7
+ * `globalThis` and survives a hot reload, while a reloaded module would mint a new `Symbol` and fail to
8
+ * recognise the container it registered last time — and then capture it as "the 2D shell".
9
+ */
10
+ declare const LAYOUT_3D_MAIN_CONTAINER_BRAND: unique symbol;
11
+ type MainContainerComponent = React.ComponentType<AppLayoutPreset_MainContainer_DefaultProps>;
12
+ /** @wildo_source:part:start presets.3d.register-layout facet:layer:frontend facet:family:layout-3d facet:audience:app-developer */
13
+ /** What a 3D main container draws: the layout, and the application's frame-style overrides. */
14
+ export interface Layout3DOptions {
15
+ /**
16
+ * The layout: its disposal, its scene and its transitions. Defaults to {@link INHERIT_LAYOUT_3D}, the 2D disposal
17
+ * with the frame under it. An application uses ONE layout for its whole life.
18
+ */
19
+ layout?: Layout3DDefinition;
20
+ /** Frame-style overrides layered over the layout's built-in styles. */
21
+ frameStyles?: Frame3DStyleOverrides;
22
+ }
23
+ /** @wildo_source:part:end presets.3d.register-layout */
24
+ /** A 3D main container: the component, the 2D container it captured, and the layout it draws. */
25
+ export type Layout3DMainContainer = MainContainerComponent & {
26
+ readonly [LAYOUT_3D_MAIN_CONTAINER_BRAND]: true;
27
+ /**
28
+ * The 2D main container captured at registration: rendered unchanged by an INHERIT placement, and kept by every
29
+ * layout so a re-registration wraps IT rather than a 3D container.
30
+ */
31
+ readonly captured: MainContainerComponent;
32
+ /** The layout this container draws. */
33
+ readonly layout: Layout3DDefinition;
34
+ /** The application's frame-style overrides, when it registered any. */
35
+ readonly frameStyles: Frame3DStyleOverrides | undefined;
36
+ };
37
+ /** Whether a registered main container is a 3D one — and so carries the 2D container it wraps. */
38
+ export declare function isLayout3DMainContainer(component: unknown): component is Layout3DMainContainer;
39
+ /**
40
+ * Build the 3D main container: a captured 2D container, and a layout that either renders it (INHERIT) or arranges
41
+ * the regions with a container of its own (COMPOSED).
42
+ *
43
+ * It renders exactly two children, at FIXED positions:
44
+ *
45
+ * - **index 0, the frame slot** ({@link FrameSlot}): the decorative canvas behind its lazy door (`FrameCanvasDoor`),
46
+ * whose `LazyDoorErrorBoundary` contains any failure of it. The theme and the navigation state are read in the
47
+ * slot, in the DOM tree, and passed to the canvas as props: a theme, mode, breakpoint or navigation change
48
+ * re-renders index 0 and never touches index 1.
49
+ * It is `position: fixed` with NO z-index, `aria-hidden` and `pointer-events: none`.
50
+ * - **index 1, the placement**: the captured 2D container, unchanged, for an INHERIT layout; the layout's own
51
+ * container, composed from the same shell building blocks, otherwise. Either way every region, provider,
52
+ * context, portal and latch is the application's own.
53
+ *
54
+ * Why no wrapper, and no `isolate` (the #1821 text proposed `<div class="isolate">` with the canvas at
55
+ * `-z-10`): `isolate` would make the whole shell ONE stacking context, so anything positioned OUTSIDE it
56
+ * with a lower z-index — the consent prompt (`z-50`) — would paint over the shell's own dialogs
57
+ * (`--z-overlay`, 300). #1830 measured that exact reordering and chose `relative` for the 2D shell root
58
+ * for that reason. Instead, a positioned element with no z-index paints at the z-index:0 level in TREE
59
+ * order, which puts the canvas after the theme's background layer (`UIContext`'s `isolate` wrapper,
60
+ * earlier in the tree) and before the shell root (`relative`, the next sibling) — frame above the theme
61
+ * background, shell above the frame — while every z-index inside the shell keeps its global order.
62
+ *
63
+ * The precondition this places on the placement: its ROOT must be positioned (the 2D default and the
64
+ * header-first container are `relative`, #1830), or its in-flow content paints at a lower level than the frame and
65
+ * under it. The frame never takes a click either way — it handles no pointer events at all.
66
+ *
67
+ * Why fixed positions: a canvas failure empties only index 0. The placement never moves and keeps one component
68
+ * type for the application's life, so it never remounts — a remount there would unmount every navigation zone and
69
+ * lose its state.
70
+ */
71
+ export declare function create3DMainContainer(captured: MainContainerComponent, options?: Layout3DOptions): Layout3DMainContainer;
72
+ export {};
73
+ //# sourceMappingURL=layout-3d-main-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-3d-main-container.d.ts","sourceRoot":"","sources":["../../../src/layout-3d-main-container.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAA6B,KAAK,0CAA0C,EAAE,MAAM,6BAA6B,CAAC;AAGzH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAA8C,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAMpH;;;;GAIG;AACH,QAAA,MAAM,8BAA8B,eAA+D,CAAC;AAEpG,KAAK,sBAAsB,GAAG,KAAK,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAC;AAE9F,mIAAmI;AACnI,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,uEAAuE;IACvE,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AACD,wDAAwD;AAExD,iGAAiG;AACjG,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG;IAC3D,QAAQ,CAAC,CAAC,8BAA8B,CAAC,EAAE,IAAI,CAAC;IAChD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,qBAAqB,GAAG,SAAS,CAAC;CACzD,CAAC;AAEF,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,IAAI,qBAAqB,CAE9F;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,OAAO,GAAE,eAAoB,GAAG,qBAAqB,CA4C5H"}