stylegallery 0.1.7 → 0.1.9

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 (62) hide show
  1. package/AGENTS.md +15 -1
  2. package/DOMAINS.md +7 -3
  3. package/GOVERNANCE.md +13 -11
  4. package/LICENSE-DOCS +2 -2
  5. package/README.md +23 -10
  6. package/consumer-reference/agent-native/v2/admission-policy.json +32 -37
  7. package/consumer-reference/agent-native/v2/material-registry.json +1 -1
  8. package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +3 -3
  9. package/consumer-reference/agent-native/v2/schema/material-record.schema.json +1 -1
  10. package/design-engineering/state-management/index.md +1 -1
  11. package/design-engineering/state-management/patterns/derived-state.md +1 -1
  12. package/design-engineering/state-management/patterns/draft-and-baseline.md +1 -1
  13. package/design-engineering/state-management/patterns/id-selection.md +1 -1
  14. package/design-engineering/state-management/patterns/identity-reset.md +1 -1
  15. package/design-engineering/state-management/patterns/latest-request-wins.md +1 -1
  16. package/design-engineering/state-management/patterns/optimistic-overlay.md +1 -1
  17. package/design-engineering/state-management/patterns/single-flight.md +1 -1
  18. package/design-engineering/state-management/patterns/single-owner.md +1 -1
  19. package/design-engineering/state-management/patterns/submitted-snapshot.md +1 -1
  20. package/design-engineering/state-management/patterns/unsaved-navigation.md +1 -1
  21. package/design-engineering/state-management/patterns/url-state.md +1 -1
  22. package/design-engineering/state-management/patterns/versioned-restore.md +1 -1
  23. package/design-engineering/state-management/verification.md +1 -1
  24. package/design-terminology/conflict-cases.md +1 -1
  25. package/design-terminology/source-kinds.md +1 -1
  26. package/expression/brand-studies.md +50 -0
  27. package/expression/direction-brief.md +83 -0
  28. package/expression/directions/nocturne-editorial.md +81 -0
  29. package/expression/directions/warm-print.md +73 -0
  30. package/expression/index.md +52 -0
  31. package/expression/techniques/gradient-atmosphere.md +107 -0
  32. package/expression/techniques/grain-and-texture.md +83 -0
  33. package/expression/techniques/webgl-hero.md +123 -0
  34. package/guides/vocabulary.md +1 -1
  35. package/index.md +3 -3
  36. package/log.md +45 -0
  37. package/motion/index.md +71 -0
  38. package/motion/techniques/kinetic-type.md +145 -0
  39. package/motion/techniques/scroll-choreography.md +154 -0
  40. package/package.json +17 -14
  41. package/platform-guides/compatibility-matrix.md +1 -1
  42. package/quality/claim-records/samples.md +50 -0
  43. package/quality/claim-records/stylegallery-multidomain-scope.md +2 -2
  44. package/quality/claims.md +24 -1
  45. package/quality/evidence/executable-evidence.md +1 -1
  46. package/quality/index.md +1 -2
  47. package/scripts/agent-native/v2/material-admission.mjs +1 -1
  48. package/scripts/agent-native/v2/material-identity.mjs +2 -2
  49. package/scripts/compiler/README.md +5 -5
  50. package/showcase/README.md +127 -0
  51. package/game-ui/classification.md +0 -82
  52. package/game-ui/decision-tree.md +0 -81
  53. package/game-ui/index.md +0 -45
  54. package/game-ui/reference-record.md +0 -62
  55. package/game-ui/screen-hierarchy.md +0 -107
  56. package/game-ui/screen-recipes.md +0 -101
  57. package/game-ui/unity/architecture.md +0 -166
  58. package/game-ui/unity/cli-loop.md +0 -84
  59. package/game-ui/unity/org-wiki.md +0 -146
  60. package/game-ui/unity/repository-map.md +0 -102
  61. package/game-ui/unity/ui-systems.md +0 -85
  62. package/game-ui/verification-workflow.md +0 -100
@@ -0,0 +1,107 @@
1
+ ---
2
+ type: Domain Recipe
3
+ title: Gradient Atmosphere
4
+ description: Copy-ready blurred gradient fields, card glows, and gradient text for expressive product pages.
5
+ domain: expression
6
+ lifecycle: experimental
7
+ provenance_kind: local
8
+ ---
9
+
10
+ # Gradient Atmosphere
11
+
12
+ Primary role: visual technique recipe.
13
+
14
+ ## Repository Boundary
15
+
16
+ Product-layer CSS for `showcase/` works and consumer pages. Never add these declarations to reusable Layout pattern CSS.
17
+
18
+ ## Reusable Method
19
+
20
+ ### Aurora Field
21
+
22
+ Three large radial gradients, blurred together and slowly drifting behind a section.
23
+
24
+ ```html
25
+ <section class="hero">
26
+ <div class="aurora" aria-hidden="true"><span></span><span></span><span></span></div>
27
+ <!-- content -->
28
+ </section>
29
+ ```
30
+
31
+ ```css
32
+ .hero { isolation: isolate; overflow: clip; position: relative; }
33
+ .aurora { filter: blur(70px) saturate(140%); inset: 0; opacity: 0.55; position: absolute; z-index: -2; }
34
+ .aurora span { animation: drift 18s ease-in-out infinite alternate; border-radius: 50%; position: absolute; }
35
+ .aurora span:nth-child(1) { background: radial-gradient(circle, #ff5a36, transparent 65%); block-size: 60vmax; inline-size: 60vmax; inset-block-start: -20vmax; inset-inline-end: -15vmax; }
36
+ .aurora span:nth-child(2) { animation-duration: 24s; background: radial-gradient(circle, #7b5cff, transparent 65%); block-size: 55vmax; inline-size: 55vmax; inset-block-end: -25vmax; inset-inline-start: -10vmax; }
37
+ .aurora span:nth-child(3) { animation-duration: 30s; background: radial-gradient(circle, #1f6fff, transparent 60%); block-size: 35vmax; inline-size: 35vmax; inset-block-start: 30%; inset-inline-start: 40%; }
38
+ @keyframes drift { to { transform: translate3d(-6vmax, 4vmax, 0) scale(1.15); } }
39
+ @media (prefers-reduced-motion: reduce) { .aurora span { animation: none; } }
40
+ ```
41
+
42
+ `overflow: clip` on the section keeps the oversized blobs from widening the document; without it the page scrolls sideways at 320px.
43
+
44
+ ### Legibility Scrim
45
+
46
+ When copy sits over the field, add a gradient between the atmosphere and the copy instead of dimming the atmosphere everywhere.
47
+
48
+ ```css
49
+ .hero::after {
50
+ background: linear-gradient(to top, rgb(7 7 10 / 0.7), transparent 55%), linear-gradient(to right, rgb(7 7 10 / 0.55), transparent 60%);
51
+ content: ""; inset: 0; pointer-events: none; position: absolute; z-index: -1;
52
+ }
53
+ ```
54
+
55
+ ### Card Glow
56
+
57
+ Two corner radial gradients per card, colored by custom properties set on the card, so each card gets its own light without new classes.
58
+
59
+ ```css
60
+ .card {
61
+ background:
62
+ radial-gradient(120% 90% at 100% 0%, color-mix(in oklab, var(--hue-a) 55%, transparent), transparent 60%),
63
+ radial-gradient(90% 80% at 0% 100%, color-mix(in oklab, var(--hue-b) 45%, transparent), transparent 60%),
64
+ #111118;
65
+ }
66
+ ```
67
+
68
+ ```html
69
+ <li class="card" style="--hue-a:#ff5a36; --hue-b:#7b5cff">...</li>
70
+ ```
71
+
72
+ ### Gradient Text
73
+
74
+ ```css
75
+ .accent {
76
+ background: linear-gradient(100deg, #ff5a36, #ffb454 40%, #7b5cff);
77
+ -webkit-background-clip: text;
78
+ background-clip: text;
79
+ color: transparent;
80
+ padding-inline-end: 0.06em; /* keeps italic overhang from being clipped */
81
+ }
82
+ ```
83
+
84
+ ## Opinionated Guidance
85
+
86
+ One atmosphere per viewport. An aurora behind the hero plus glowing cards plus gradient text in the same view reads as noise; stagger them down the page.
87
+
88
+ ## Platform-Specific Guidance
89
+
90
+ `filter: blur()` on large layers costs GPU memory. Blur the container once, not each blob, and keep blob sizes in `vmax` so the effect scales without re-rasterizing at many sizes. `color-mix()` needs a current engine; provide a plain `rgb()` fallback if you target older browsers.
91
+
92
+ ## Unsupported Absolutes
93
+
94
+ Blur radius, opacity, and drift duration here were tuned for one dark page. Light grounds need lower opacity and usually no `saturate()`.
95
+
96
+ ## Verification Contract
97
+
98
+ In the showcase check, the page has no horizontal overflow at 320px, and under reduced motion no infinite drift animation is running. Review the screenshots for text contrast over the brightest part of the field.
99
+
100
+ ## Source, License, And Attribution
101
+
102
+ Locally authored recipe. No upstream source.
103
+
104
+ ## IA Navigation
105
+
106
+ Parent: [Expression](../index.md).
107
+ Next: [Grain And Texture](grain-and-texture.md).
@@ -0,0 +1,83 @@
1
+ ---
2
+ type: Domain Recipe
3
+ title: Grain And Texture
4
+ description: Copy-ready film grain, noise, and halftone textures without image files.
5
+ domain: expression
6
+ lifecycle: experimental
7
+ provenance_kind: local
8
+ ---
9
+
10
+ # Grain And Texture
11
+
12
+ Primary role: visual technique recipe.
13
+
14
+ ## Repository Boundary
15
+
16
+ Product-layer CSS for `showcase/` works and consumer pages. Never add these declarations to reusable Layout pattern CSS.
17
+
18
+ ## Reusable Method
19
+
20
+ ### Film Grain Overlay
21
+
22
+ An SVG turbulence filter as a data URI, tiled over the whole page. No image file, about 400 bytes.
23
+
24
+ ```html
25
+ <div class="grain" aria-hidden="true"></div>
26
+ ```
27
+
28
+ ```css
29
+ .grain {
30
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
31
+ inset: 0;
32
+ mix-blend-mode: overlay;
33
+ opacity: 0.22;
34
+ pointer-events: none;
35
+ position: fixed;
36
+ z-index: 90;
37
+ }
38
+ ```
39
+
40
+ Tuning: `baseFrequency` 0.6 is coarse and filmic, 0.9 is fine and digital. Opacity 0.15-0.25 on dark grounds, 0.08-0.12 on light grounds with `mix-blend-mode: multiply` and a black `feColorMatrix` (replace the three `1` channel values with `0`).
41
+
42
+ ### Halftone
43
+
44
+ Dots from a repeating radial gradient, masked onto an image or a flat color block.
45
+
46
+ ```css
47
+ .halftone {
48
+ background-image: radial-gradient(circle at center, #141210 0.9px, transparent 1.1px);
49
+ background-size: 6px 6px;
50
+ mix-blend-mode: multiply;
51
+ }
52
+ ```
53
+
54
+ Place the `.halftone` layer over a grayscale image (`filter: grayscale(1) contrast(1.2)`) for a print look.
55
+
56
+ ### Paper Tooth
57
+
58
+ For light directions, a very low-frequency turbulence adds unevenness without visible grain: `baseFrequency='0.02'`, `numOctaves='2'`, opacity 0.35, `mix-blend-mode: multiply`.
59
+
60
+ ## Opinionated Guidance
61
+
62
+ Grain should be felt, not seen. If someone notices it in a screenshot at 100% zoom, it is too strong.
63
+
64
+ ## Platform-Specific Guidance
65
+
66
+ A fixed full-viewport overlay is composited on every scroll frame. With `pointer-events: none` it never blocks input; if scrolling stutters on low-end devices, switch `position: fixed` to `absolute` on a page-height container.
67
+
68
+ ## Unsupported Absolutes
69
+
70
+ Grain strength that works on a large desktop display can look dirty on a small high-density phone screen. Check both sizes.
71
+
72
+ ## Verification Contract
73
+
74
+ The overlay is `aria-hidden`, has `pointer-events: none`, and does not intercept focus. The showcase focus-order check passes with the overlay present.
75
+
76
+ ## Source, License, And Attribution
77
+
78
+ Locally authored recipe. No upstream source.
79
+
80
+ ## IA Navigation
81
+
82
+ Parent: [Expression](../index.md).
83
+ Next: [WebGL Hero Field](webgl-hero.md).
@@ -0,0 +1,123 @@
1
+ ---
2
+ type: Domain Recipe
3
+ title: WebGL Hero Field
4
+ description: A three.js point field behind a hero, with pointer parallax, offscreen pausing, and safe fallbacks.
5
+ domain: expression
6
+ lifecycle: experimental
7
+ provenance_kind: local
8
+ ---
9
+
10
+ # WebGL Hero Field
11
+
12
+ Primary role: visual technique recipe.
13
+
14
+ ## Repository Boundary
15
+
16
+ Product-layer script for `showcase/` works and consumer pages. The canvas is decorative atmosphere; no content or control may live only inside it.
17
+
18
+ ## Reusable Method
19
+
20
+ ```html
21
+ <section class="hero">
22
+ <canvas class="hero_canvas" aria-hidden="true"></canvas>
23
+ <!-- content -->
24
+ </section>
25
+ ```
26
+
27
+ ```css
28
+ .hero { isolation: isolate; overflow: clip; position: relative; }
29
+ .hero_canvas { block-size: 100%; inline-size: 100%; inset: 0; position: absolute; z-index: -1; }
30
+ ```
31
+
32
+ ```js
33
+ const reduceMotion = matchMedia("(prefers-reduced-motion: reduce)").matches;
34
+
35
+ async function startHeroField(canvas) {
36
+ let THREE, renderer;
37
+ try {
38
+ THREE = await import("https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js");
39
+ renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true, powerPreference: "low-power" });
40
+ } catch {
41
+ return; // CSS atmosphere behind the canvas remains
42
+ }
43
+ renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
44
+ const scene = new THREE.Scene();
45
+ const camera = new THREE.PerspectiveCamera(55, 1, 0.1, 100);
46
+ camera.position.set(0, 1.4, 7);
47
+
48
+ const columns = 140, rows = 70;
49
+ const positions = new Float32Array(columns * rows * 3);
50
+ const colors = new Float32Array(columns * rows * 3);
51
+ const a = new THREE.Color("#ff5a36"), b = new THREE.Color("#7b5cff");
52
+ for (let r = 0; r < rows; r++) for (let c = 0; c < columns; c++) {
53
+ const i = (r * columns + c) * 3;
54
+ positions[i] = (c / (columns - 1) - 0.5) * 18;
55
+ positions[i + 2] = (r / (rows - 1) - 0.5) * 12;
56
+ const color = a.clone().lerp(b, c / (columns - 1));
57
+ colors.set([color.r, color.g, color.b], i);
58
+ }
59
+ const geometry = new THREE.BufferGeometry();
60
+ geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
61
+ geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
62
+ const points = new THREE.Points(geometry, new THREE.PointsMaterial({
63
+ size: 0.045, vertexColors: true, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false,
64
+ }));
65
+ scene.add(points);
66
+
67
+ const pointer = { x: 0, y: 0 };
68
+ addEventListener("pointermove", (e) => { pointer.x = e.clientX / innerWidth - 0.5; pointer.y = e.clientY / innerHeight - 0.5; }, { passive: true });
69
+
70
+ function resize() {
71
+ renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
72
+ camera.aspect = canvas.clientWidth / Math.max(canvas.clientHeight, 1);
73
+ camera.updateProjectionMatrix();
74
+ points.position.y = camera.aspect < 1 ? -3.2 : -1.2; // keep the field under portrait copy
75
+ }
76
+ function frame(time) {
77
+ const t = time * 0.00045, p = geometry.attributes.position.array;
78
+ for (let i = 0; i < p.length; i += 3) {
79
+ p[i + 1] = Math.sin(p[i] * 0.55 + t * 2) * 0.35 + Math.cos(p[i + 2] * 0.7 + t * 1.4) * 0.3;
80
+ }
81
+ geometry.attributes.position.needsUpdate = true;
82
+ camera.position.x += (pointer.x * 1.6 - camera.position.x) * 0.04;
83
+ camera.position.y += (1.4 - pointer.y * 0.8 - camera.position.y) * 0.04;
84
+ camera.lookAt(0, 0, 0);
85
+ renderer.render(scene, camera);
86
+ }
87
+ resize();
88
+ addEventListener("resize", resize);
89
+ if (reduceMotion) return frame(0); // one still frame
90
+ let visible = true;
91
+ new IntersectionObserver(([entry]) => { visible = entry.isIntersecting; }).observe(canvas);
92
+ renderer.setAnimationLoop((time) => { if (visible) frame(time); });
93
+ }
94
+
95
+ startHeroField(document.querySelector(".hero_canvas"));
96
+ ```
97
+
98
+ Variations: swap the plane for `THREE.SphereGeometry` vertices for a globe of points, raise `size` and lower the count for bokeh, or map `scrollY` into `t` for a scroll-scrubbed field.
99
+
100
+ ## Opinionated Guidance
101
+
102
+ Put a [CSS gradient atmosphere](gradient-atmosphere.md) behind the canvas. When WebGL fails, the hero still looks intentional instead of empty.
103
+
104
+ ## Platform-Specific Guidance
105
+
106
+ Cap device pixel ratio at 2, request `low-power`, and pause rendering offscreen; a 10k-point field updated on the CPU is fine on laptops but should drop to about half the points on phones if frame rate matters. Import three.js as an ES module from a pinned version, never `@latest`.
107
+
108
+ ## Unsupported Absolutes
109
+
110
+ Point counts and wave constants were tuned for one hero. They are not a performance guarantee; measure on the slowest device you care about.
111
+
112
+ ## Verification Contract
113
+
114
+ The showcase check reports no page errors with or without network access to the CDN. Under reduced motion, only a still frame renders. The canvas is `aria-hidden` and holds no focusable content.
115
+
116
+ ## Source, License, And Attribution
117
+
118
+ Locally authored recipe. three.js is MIT licensed and loaded at runtime; no three.js source is reproduced.
119
+
120
+ ## IA Navigation
121
+
122
+ Parent: [Expression](../index.md).
123
+ Next: [Fintech Clarity Direction](../directions/fintech-clarity.md).
@@ -15,7 +15,7 @@ Primary role: vocabulary and scannability contract.
15
15
  - Canonical: `domain`
16
16
  - Concept: top-level knowledge ownership
17
17
  - Definition: A governed StyleGallery decision surface with a named scope, exclusions, lifecycle, source-of-truth, validator, and review owner.
18
- - Use for: Layout, Motion, Design Engineering, Game UI, Platform Guides, Design Terminology, root routing, and `domain` frontmatter on governed leaves.
18
+ - Use for: Layout, Motion, Design Engineering, Platform Guides, Design Terminology, Expression, root routing, and `domain` frontmatter on governed leaves.
19
19
  - Canonical: `category`
20
20
  - Concept: domain-local browse placement
21
21
  - Definition: A canonical grouping inside one domain; it cannot change the owning domain or its evidence boundary.
package/index.md CHANGED
@@ -4,7 +4,7 @@ okf_version: "0.1"
4
4
 
5
5
  # StyleGallery
6
6
 
7
- StyleGallery is an OKF-style knowledge bundle organized into governed interface-knowledge domains. Existing Layout paths remain canonical while Motion, Design Engineering, Game UI, Platform Guides, and Design Terminology own separate product and reference boundaries.
7
+ StyleGallery is an OKF-style knowledge bundle organized into governed interface-knowledge domains. Existing Layout paths remain canonical while Motion, Design Engineering, Platform Guides, Design Terminology, and Expression own separate product and reference boundaries. Finished expressive pages live in the Showcase work area.
8
8
 
9
9
  Primary role: OKF bundle map.
10
10
 
@@ -14,9 +14,10 @@ Primary role: OKF bundle map.
14
14
  - [Layout](layout/index.md) - Existing spatial patterns, recipes, planning guides, and layout quality routes.
15
15
  - [Motion](motion/index.md) - Motion terminology, review workflow, and evidence-bounded practice reference.
16
16
  - [Design Engineering](design-engineering/index.md) - Product-layer interface-craft decisions and verification questions.
17
- - [Game UI](game-ui/index.md) - Game-interface classification, hierarchy, reference records, and named engine implementation guides.
18
17
  - [Platform Guides](platform-guides/index.md) - Bounded comparative references for named platforms.
19
18
  - [Design Terminology](design-terminology/index.md) - Source-kind and concept-family classification, typed term relations, and cross-system conflict cases for named vocabulary sources.
19
+ - [Expression](expression/index.md) - Art-direction briefs, named directions with starting values, visual technique recipes, and brand-study policy.
20
+ - [Showcase](showcase/README.md) - Free-form expressive works checked by outcome instead of Layout authoring rules.
20
21
  - [Consumer reference](consumer-reference/index.md) - Shared non-domain receiver contract for declared repository-local JSON records or reasoned non-applicability.
21
22
  - [Agent-Native StyleGallery](consumer-reference/agent-native/README.md) - Machine-facing identity, retrieval, operation, CLI, read-only MCP, task projection, and governed-learning contracts.
22
23
  - [Consumer migration readiness](design-engineering/consumer-migration-readiness.md) - Experimental Design Engineering method for consumer-owned conformance, runtime proof, and source-bound page evidence.
@@ -40,6 +41,5 @@ Primary role: OKF bundle map.
40
41
 
41
42
  - [Motion Decision Tree](motion/decision-tree.md) - Choose a behavior from the user task.
42
43
  - [Design Engineering Decision Tree](design-engineering/decision-tree.md) - Route the uncertain product decision.
43
- - [Game UI Decision Tree](game-ui/decision-tree.md) - Choose by player task and ownership.
44
44
  - [Platform Adaptation Workflow](platform-guides/adaptation-workflow.md) - Record native facts, target decisions, and fallbacks.
45
45
  - [Design Term Comparison Workflow](design-terminology/comparison-workflow.md) - Resolve a source-specific question and produce a scoped handoff.
package/log.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # StyleGallery Log
2
2
 
3
+ ## 2026-10-15
4
+
5
+ Understood as: release `stylegallery@0.1.9` with the machine-verifiable claim records and the scroll-body-shell render oracle from PR #53.
6
+
7
+ - Bumped the package version from `0.1.8` to `0.1.9`. The release carries PR #53: `scripts/validate-claim-records.mjs` checks the machine-readable fields of every `## Claim Record` section under `quality/claim-records/`, `scripts/check-pattern-oracle.mjs` renders `tests/fixtures/pattern-oracle/scroll-body-shell/index.html` at 320, 768, and 1440 CSS pixels, and the Claim record checks workflow runs both with their fixture tests.
8
+ - The package `files` list is unchanged. The updated `quality/claims.md` and the new `quality/claim-records/samples.md` were already packaged. The two new checks stay repository-only like the other validators (`validate-domains`, `check-showcase`): the claim-record validator imports the unpackaged `scripts/markdown-structure.mjs`, and the oracle needs the development dependencies Playwright and `@axe-core/playwright` plus a fixture under `tests/`, which the package does not ship. Run them from a repository checkout.
9
+
10
+ Consumer reference: not_applicable
11
+ Consumer reference reason: This change releases a package version and selects no consumer-reference profile or record.
12
+
13
+ ## 2026-09-28
14
+
15
+ Understood as: switch the repository package manager from npm to Bun and release `stylegallery@0.1.8`.
16
+
17
+ - Replaced `package-lock.json` with `bun.lock`, migrated from the npm lockfile so every one of the 184 resolved package versions and the `brace-expansion` override are unchanged, and declared `"packageManager": "bun@1.3.14"`. Scripts still run on Node.js 22; Bun installs dependencies and runs package scripts.
18
+ - CI workflows add `oven-sh/setup-bun` pinned by commit, install with `bun install --frozen-lockfile --ignore-scripts`, and run `bun run` and `bunx playwright`. Playwright container jobs install `unzip` first because the pinned image does not include it. The setup-bun pin joins the immutable action pins.
19
+ - New capture sessions and the conformance matrix source binding hash `bun.lock` in place of `package-lock.json`; the capture-session schema accepts `bun.lock` as a source path and still accepts `package-lock.json` for earlier sessions. Existing capture evidence remains bound to its recorded revision.
20
+ - With owner approval, the sentinel-calibration and page-evidence records and their validator constants were refreshed for the new workflow bytes, including the calibration and page-evidence job hashes and the protected hashes of `scripts/run-consumer-page-evidence-ci.mjs` and `quality/evidence/executable-evidence.md`, whose commands now name Bun. Owners, deadlines, and decisions are unchanged.
21
+ - Development commands in the documentation now use `bun run`. Consumer install commands such as `npx stylegallery` and `npm install --global stylegallery` are unchanged because the package is still published to the npm registry.
22
+
23
+ Consumer reference: not_applicable
24
+ Consumer reference reason: This change replaces the repository package manager and selects no consumer-reference profile or record.
25
+
26
+ Understood as: remove the Game UI domain from the repository together with the Expression change.
27
+
28
+ - Removed the Game UI domain: its thirteen governed files under `game-ui/`, the Unity organization-wiki and Unity source-contract validators with their fixture tests and CI steps, and every route, manifest row, governance row, ownership entry, quality scenario, validator requirement, example link, and packaged path that referred to it. Earlier log entries remain as history.
29
+ - The domain set is Layout, Motion, Design Engineering, Platform Guides, Design Terminology, and Expression. Domain-count sentences return to six governed domains, so `quality/evidence/executable-evidence.md` returns to its previously sealed bytes. Material v2 admits 180 documents.
30
+ - Removing the two Unity steps changed `.github/workflows/validate.yml`. With owner approval, only the whole-file active and derived retired workflow hashes were refreshed in the sentinel-calibration and page-evidence records and their validator constants; the calibration and page-evidence job bytes, owners, deadlines, and decisions are unchanged. The A2A and AG-UI extension source inventories were regenerated for the edited documents.
31
+
32
+ Consumer reference: not_applicable
33
+ Consumer reference reason: This change removes a documentation domain and its validators and selects no consumer-reference profile or record.
34
+
35
+ ## 2026-09-27
36
+
37
+ Understood as: let StyleGallery produce finished, expressive pages without loosening the Layout contract, and keep only the parts that belong in the official repository.
38
+
39
+ - Added Expression as a governed domain: a direction brief, an unofficial brand-study policy, two named directions with concrete values (Nocturne Editorial, Warm Print), and three visual technique recipes (gradient atmosphere, grain and texture, WebGL hero field). Expression owns art direction; it owns no Layout mechanics, motion timing, or governed tokens.
40
+ - Added two executable Motion techniques: scroll choreography (GSAP ScrollTrigger with Lenis on one ticker, pinned horizontal travel, a CSS scroll-timeline alternative) and kinetic type (split-word rises, scroll-lit paragraphs, count-ups, marquees).
41
+ - Added the `showcase/` work area, which is not a domain: a work contract, a QA contract with fifteen ideal-state properties and twenty-one scenarios, the outcome checker `scripts/check-showcase.mjs`, its fixture self-test, and `scripts/serve-showcase.mjs`. Layout authoring rules do not apply to showcase CSS; outcome checks for overflow, focus, contrast, reduced motion, honest actions, hash navigation, short viewports, offscreen loops, and offline and no-script reading do. No works are committed.
42
+ - Added the Creative Build Route to AGENTS.md and registered the domain in the manifest, root routes, governance, ownership, IA, and domain validators and fixtures, and admitted the eleven new documents to Material v2.
43
+ - The A2A and AG-UI extension source inventories were regenerated for the edited caller documents, as in the 2026-09-21 research expansion.
44
+
45
+ Consumer reference: not_applicable
46
+ Consumer reference reason: This change adds domain guidance and showcase tooling and selects no consumer-reference profile or record.
47
+
3
48
  ## 2026-09-22
4
49
 
5
50
  - Prepared `stylegallery@0.1.7` with direct website capture, transcription, and workflow commands in the SG CLI and MCP. The compiler remains a separately installed checkout; frozen v1 knowledge entrypoints remain available.
package/motion/index.md CHANGED
@@ -17,6 +17,8 @@ Out of scope: universal timing or easing rules, unmeasured performance claims, a
17
17
  | Build a scroll-driven product story and inspect runnable examples. | [Scroll-driven Story](interaction-recipes.md#scroll-driven-story) and [Scroll Story Lab](../examples/scroll-story/README.md) |
18
18
  | Keep the page fixed while navigating between full-screen chapters. | [Full-viewport Scene Navigation](interaction-recipes.md#full-viewport-scene-navigation) and [runnable example](../examples/scene-navigation/README.md) |
19
19
  | Apply feedback, disclosure, modal, reorder, progress, and drag contracts. | [Motion Interaction Recipes](interaction-recipes.md) |
20
+ | Copy a working GSAP ScrollTrigger and Lenis setup, pinned horizontal travel, or a CSS scroll-timeline scrub. | [Scroll Choreography Technique](techniques/scroll-choreography.md) |
21
+ | Copy split-word headline rises, scroll-lit paragraphs, count-ups, or a marquee. | [Kinetic Type Technique](techniques/kinetic-type.md) |
20
22
 
21
23
  These workflows and worked cases are usable experimental guidance. Expected-result tables are test designs; actual product, engine, and reader evidence must be recorded separately. Review on a failed task, a source change, or a changed ownership contract.
22
24
 
@@ -33,6 +35,75 @@ These workflows and worked cases are usable experimental guidance. Expected-resu
33
35
  - [Interruption And Retargeting](interruption-and-retargeting.md). Resolve repeated input, cancellation, and stale completion callbacks.
34
36
  - [Motion Rendering And Performance](rendering-and-performance.md). Choose native mechanisms and diagnose measured delivery failures.
35
37
 
38
+ ## Visual Reference: Motion Prompt
39
+
40
+ [Motion Prompt by @ssaengcho](https://motion-prompt-ssaengcho.soldaeng-guri.chatgpt.site/#top) is an external Korean motion dictionary for comparing effects visually and describing the intended movement. Its interface lists 36 effects and five combinations across entrance/exit, emphasis, sequencing, space, scene transitions, shape/focus, timing, and text.
41
+
42
+ Use it to select an observable effect, then record the actual product behavior in the [Motion Brief](motion-brief.md): trigger, moving property, start/end state, interruption, reduced-motion alternative, and completion feedback. For example, distinguish moving an element from moving imagery inside a stationary frame, and distinguish changing opacity from revealing through a moving mask.
43
+
44
+ The dictionary's example durations and prompts are reference choices, not StyleGallery defaults or measured performance guarantees. Its naming is not a replacement for the [Motion Vocabulary](vocabulary.md).
45
+
46
+ [Run all 41 local examples](https://style.gallery/examples/category/guide/?q=Motion%20Prompt). Every effect and combination has its own execution page, timeline scrubber, restart, pause, reverse, final-state control, and reduced-motion alternative. Local examples use StyleGallery's theme rather than copying the reference site's presentation.
47
+
48
+ ### Complete Effect Inventory
49
+
50
+ | No. | Source effect | Local execution |
51
+ | --- | --- | --- |
52
+ | 1 | Fade in | [페이드 인](https://style.gallery/examples/guide/motion-prompt-fade/) |
53
+ | 2 | Slide in | [슬라이드 인](https://style.gallery/examples/guide/motion-prompt-slide/) |
54
+ | 3 | Scale in | [스케일 인](https://style.gallery/examples/guide/motion-prompt-scale/) |
55
+ | 4 | Mask reveal | [마스크 리빌](https://style.gallery/examples/guide/motion-prompt-mask/) |
56
+ | 5 | Overshoot | [오버슈트](https://style.gallery/examples/guide/motion-prompt-over/) |
57
+ | 6 | Bounce | [바운스](https://style.gallery/examples/guide/motion-prompt-bounce/) |
58
+ | 7 | Pulse | [펄스](https://style.gallery/examples/guide/motion-prompt-pulse/) |
59
+ | 8 | Shake | [셰이크](https://style.gallery/examples/guide/motion-prompt-shake/) |
60
+ | 9 | Stagger | [스태거](https://style.gallery/examples/guide/motion-prompt-stagger/) |
61
+ | 10 | Typewriter | [타이프라이터](https://style.gallery/examples/guide/motion-prompt-type/) |
62
+ | 11 | Tracking animation | [트래킹 애니메이션](https://style.gallery/examples/guide/motion-prompt-tracking/) |
63
+ | 12 | Trim paths | [트림 패스](https://style.gallery/examples/guide/motion-prompt-line/) |
64
+ | 13 | Zoom in | [줌 인](https://style.gallery/examples/guide/motion-prompt-zoom/) |
65
+ | 14 | Panning | [패닝](https://style.gallery/examples/guide/motion-prompt-pan/) |
66
+ | 15 | Position inside mask | [프레임 내부 이동](https://style.gallery/examples/guide/motion-prompt-crop/) |
67
+ | 16 | Parallax | [패럴랙스](https://style.gallery/examples/guide/motion-prompt-parallax/) |
68
+ | 17 | Cross dissolve | [크로스 디졸브](https://style.gallery/examples/guide/motion-prompt-dissolve/) |
69
+ | 18 | Wipe | [와이프](https://style.gallery/examples/guide/motion-prompt-wipe/) |
70
+ | 19 | Push | [푸시](https://style.gallery/examples/guide/motion-prompt-push/) |
71
+ | 20 | Iris reveal | [아이리스 리빌](https://style.gallery/examples/guide/motion-prompt-iris/) |
72
+ | 21 | Rotation | [로테이션](https://style.gallery/examples/guide/motion-prompt-rotate/) |
73
+ | 22 | Floating | [플로팅](https://style.gallery/examples/guide/motion-prompt-float/) |
74
+ | 23 | Morphing | [모핑](https://style.gallery/examples/guide/motion-prompt-morph/) |
75
+ | 24 | Blur reveal | [블러 리빌](https://style.gallery/examples/guide/motion-prompt-blur/) |
76
+ | 25 | Linear | [리니어](https://style.gallery/examples/guide/motion-prompt-linear/) |
77
+ | 26 | Ease in | [이즈 인](https://style.gallery/examples/guide/motion-prompt-easein/) |
78
+ | 27 | Ease out | [이즈 아웃](https://style.gallery/examples/guide/motion-prompt-easeout/) |
79
+ | 28 | Ease in out | [이즈 인 아웃](https://style.gallery/examples/guide/motion-prompt-easeboth/) |
80
+ | 29 | Text scramble | [텍스트 스크램블](https://style.gallery/examples/guide/motion-prompt-scramble/) |
81
+ | 30 | Karaoke highlight | [가라오케 하이라이트](https://style.gallery/examples/guide/motion-prompt-karaoke/) |
82
+ | 31 | Word by word | [워드 바이 워드](https://style.gallery/examples/guide/motion-prompt-wordreveal/) |
83
+ | 32 | Line by line reveal | [라인 바이 라인 리빌](https://style.gallery/examples/guide/motion-prompt-linereveal/) |
84
+ | 33 | Text wave | [텍스트 웨이브](https://style.gallery/examples/guide/motion-prompt-charwave/) |
85
+ | 34 | Character flip | [캐릭터 플립](https://style.gallery/examples/guide/motion-prompt-charflip/) |
86
+ | 35 | Count up | [카운트업](https://style.gallery/examples/guide/motion-prompt-countup/) |
87
+ | 36 | Text stroke reveal | [텍스트 스트로크 리빌](https://style.gallery/examples/guide/motion-prompt-textstroke/) |
88
+
89
+ ### Complete Combination Inventory
90
+
91
+ | No. | Source combination | Local execution |
92
+ | --- | --- | --- |
93
+ | 1 | Zoom and fade | [제품을 부드럽게 보여주기](https://style.gallery/examples/guide/motion-prompt-soft-zoom/) |
94
+ | 2 | Upward slide and fade | [제목이 올라오며 나타나기](https://style.gallery/examples/guide/motion-prompt-title-slide/) |
95
+ | 3 | Overshoot and rotation | [로고가 돌면서 톡 나타나기](https://style.gallery/examples/guide/motion-prompt-logo-pop/) |
96
+ | 4 | Tracking contraction and fade | [넓게 퍼진 글자가 모이기](https://style.gallery/examples/guide/motion-prompt-tracking-title/) |
97
+ | 5 | Staggered image and title | [사진 다음에 제목 등장](https://style.gallery/examples/guide/motion-prompt-image-title/) |
98
+
99
+ ### Source And Verification Boundary
100
+
101
+ Source review: 2026-09-29. The public page, all 36 rendered effects, all five rendered combinations, and their Web Animations tracks were inspected. The first definition file contains 28 effects; a second script adds eight text effects. The local inventory checks both sets and the five combination presets rather than trusting the headline count alone.
102
+
103
+ The local implementations preserve the observed durations, delays, repetitions, keyframe sequence, and moving properties. Two corrections are explicit: the reference's whole-timeline step easing hides intermediate count-up and scramble values; the local versions step each segment so those values appear. Theme colors and image-example materials differ intentionally. Image combinations reuse an existing project photograph instead of the reference's schematic placeholder.
104
+
105
+ These are independent implementations with attribution to Motion Prompt / @ssaengcho, not a distribution of its source bundle, prompt collection, or a claim of an upstream license. The website repository records source-file hashes and captured tracks alongside its coverage tests. Chromium observations are not a cross-browser or native-platform conformance claim.
106
+
36
107
  ## Domain Contract
37
108
 
38
109
  See [StyleGallery Domains](../DOMAINS.md) for lifecycle, provenance, page membership, and staleness rules.
@@ -0,0 +1,145 @@
1
+ ---
2
+ type: Domain Recipe
3
+ title: Kinetic Type Technique
4
+ description: Copy-ready split-word headline rises, scroll-lit paragraphs, count-ups, and marquees that keep accessible text intact.
5
+ domain: motion
6
+ lifecycle: experimental
7
+ provenance_kind: local
8
+ ---
9
+
10
+ # Kinetic Type Technique
11
+
12
+ Primary role: executable motion technique.
13
+
14
+ ## Repository Boundary
15
+
16
+ Product-layer script and CSS for `showcase/` works and consumer pages. Setup and the `.motion` enhancement gate come from [Scroll Choreography Technique](scroll-choreography.md).
17
+
18
+ ## Reusable Method
19
+
20
+ ### Split-Word Rise
21
+
22
+ Each word rises out of its own clipped line box. The heading keeps its full sentence as the accessible name, and the visual word spans are hidden from assistive technology.
23
+
24
+ ```js
25
+ function splitHeadings() {
26
+ for (const heading of document.querySelectorAll("[data-split]")) {
27
+ heading.setAttribute("aria-label", heading.textContent.replace(/\s+/g, " ").trim());
28
+ const fragment = document.createDocumentFragment();
29
+ for (const node of [...heading.childNodes]) {
30
+ const tag = node.nodeName === "EM" ? "em" : "span";
31
+ for (const word of node.textContent.split(/(\s+)/)) {
32
+ if (!word) continue;
33
+ if (/^\s+$/.test(word)) { fragment.append(" "); continue; }
34
+ const outer = document.createElement("span");
35
+ outer.className = "split_word";
36
+ outer.setAttribute("aria-hidden", "true");
37
+ const inner = document.createElement(tag);
38
+ inner.className = "split_inner";
39
+ inner.textContent = word;
40
+ outer.append(inner);
41
+ fragment.append(outer);
42
+ }
43
+ }
44
+ heading.replaceChildren(fragment);
45
+ }
46
+ }
47
+ splitHeadings();
48
+ gsap.to(".split_inner", { y: 0, duration: 1.3, ease: "expo.out", stagger: 0.06, delay: 0.15 });
49
+ ```
50
+
51
+ ```css
52
+ .motion .split_word { display: inline-block; overflow: clip; padding-block-end: 0.08em; vertical-align: top; }
53
+ .motion .split_inner { display: inline-block; transform: translateY(105%); }
54
+ ```
55
+
56
+ The `padding-block-end` keeps descenders from being clipped. Run the split before measuring anything, and only once.
57
+
58
+ ### Scroll-Lit Paragraph
59
+
60
+ Words start dim and light up with scroll progress.
61
+
62
+ ```js
63
+ for (const paragraph of document.querySelectorAll("[data-words]")) {
64
+ const words = paragraph.textContent.trim().split(/\s+/);
65
+ paragraph.replaceChildren(...words.flatMap((word, index) => {
66
+ const span = Object.assign(document.createElement("span"), { className: "word_dim", textContent: word });
67
+ return index === 0 ? [span] : [" ", span];
68
+ }));
69
+ }
70
+ gsap.to(".word_dim", {
71
+ opacity: 1, ease: "none", stagger: 0.4,
72
+ scrollTrigger: { trigger: "[data-words]", start: "top 78%", end: "bottom 45%", scrub: true },
73
+ });
74
+ ```
75
+
76
+ ```css
77
+ .motion .word_dim { opacity: 0.16; }
78
+ ```
79
+
80
+ ### Count-Up
81
+
82
+ The final number is in the HTML; motion only animates toward it.
83
+
84
+ ```html
85
+ <dd data-count="41920">41,920</dd>
86
+ ```
87
+
88
+ ```js
89
+ for (const element of document.querySelectorAll("[data-count]")) {
90
+ const state = { value: 0 };
91
+ gsap.to(state, {
92
+ value: Number(element.dataset.count), duration: 2, ease: "power3.out",
93
+ onUpdate: () => { element.textContent = Math.round(state.value).toLocaleString("en-US"); },
94
+ scrollTrigger: { trigger: element, start: "top 88%", once: true },
95
+ });
96
+ }
97
+ ```
98
+
99
+ Use `font-variant-numeric: tabular-nums` so the width does not jitter while counting.
100
+
101
+ ### Marquee
102
+
103
+ Pure CSS. Duplicate the content once and translate by half.
104
+
105
+ ```html
106
+ <div class="marquee" aria-hidden="true">
107
+ <div class="marquee_track"><span>One</span><span>Two</span><span>One</span><span>Two</span></div>
108
+ </div>
109
+ ```
110
+
111
+ ```css
112
+ .marquee { overflow: clip; }
113
+ .marquee_track { animation: marquee 32s linear infinite; display: flex; gap: 2.5rem; inline-size: max-content; white-space: nowrap; }
114
+ @keyframes marquee { to { transform: translateX(-50%); } }
115
+ @media (prefers-reduced-motion: reduce) {
116
+ .marquee_track { animation: none; flex-wrap: wrap; inline-size: auto; white-space: normal; }
117
+ }
118
+ ```
119
+
120
+ The marquee is decorative and `aria-hidden`. Never put the only copy of important text in it.
121
+
122
+ ## Opinionated Guidance
123
+
124
+ Animate words, not letters. Letter-by-letter reveals look impressive once and read slowly every time after that.
125
+
126
+ ## Platform-Specific Guidance
127
+
128
+ Splitting text breaks browser hyphenation and some `text-wrap: balance` results across word spans; check the split headline at 320px. Screen readers read the `aria-label`, so keep it identical to the visible sentence.
129
+
130
+ ## Unsupported Absolutes
131
+
132
+ Stagger and duration values suit short display headlines. Long paragraphs should not rise word by word.
133
+
134
+ ## Verification Contract
135
+
136
+ Under reduced motion or with no GSAP, every split heading and lit paragraph is fully visible and the marquee is static. `node scripts/check-showcase.mjs` enforces both.
137
+
138
+ ## Source, License, And Attribution
139
+
140
+ Locally authored technique. GSAP is loaded at runtime under its own license; no library source is reproduced.
141
+
142
+ ## IA Navigation
143
+
144
+ Parent: [Motion](../index.md).
145
+ Next: [Showcase](../../showcase/README.md).