@3xhaust/oh-my-design 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +282 -0
  3. package/README.md +282 -0
  4. package/adapters/build.ts +184 -0
  5. package/adapters/claude.ts +111 -0
  6. package/adapters/codex.ts +68 -0
  7. package/adapters/tokens.ts +21 -0
  8. package/adapters/tool-map.json +7 -0
  9. package/bin/omd-install.ts +76 -0
  10. package/bin/omd.ts +1774 -0
  11. package/core/asset-sourcing/index.ts +187 -0
  12. package/core/coach/index.ts +98 -0
  13. package/core/composition/app-shell-workbench.md +168 -0
  14. package/core/composition/asymmetric-diagonal-grid.md +178 -0
  15. package/core/composition/bento-grid.md +223 -0
  16. package/core/composition/editorial-index-labels.md +173 -0
  17. package/core/composition/form-wizard-stepper.md +132 -0
  18. package/core/composition/master-detail-flow.md +129 -0
  19. package/core/composition/section-inversion.md +182 -0
  20. package/core/composition/sidebar-margin-annotation.md +184 -0
  21. package/core/composition/split-screen-hero.md +224 -0
  22. package/core/composition/sticky-sidebar-scroll.md +219 -0
  23. package/core/composition/typographic-hero.md +100 -0
  24. package/core/composition-contract/index.ts +233 -0
  25. package/core/composition-contract/visual-richness.ts +101 -0
  26. package/core/config/index.ts +27 -0
  27. package/core/copy/index.ts +296 -0
  28. package/core/craft/finish-pass.md +356 -0
  29. package/core/craft/index.ts +33 -0
  30. package/core/design/index.ts +581 -0
  31. package/core/design/interaction-states.ts +189 -0
  32. package/core/eval-harness/index.ts +225 -0
  33. package/core/evidence/final.ts +444 -0
  34. package/core/evidence/task.ts +459 -0
  35. package/core/figma/client.ts +312 -0
  36. package/core/figma/diff.ts +261 -0
  37. package/core/figma/responsive.ts +310 -0
  38. package/core/figma/system.ts +466 -0
  39. package/core/figma/types.ts +185 -0
  40. package/core/frame/check-ux.ts +180 -0
  41. package/core/frame/index.ts +39 -0
  42. package/core/frame/write.ts +168 -0
  43. package/core/graphics/css-illustration-primitives.md +189 -0
  44. package/core/graphics/duotone-image-presets.md +173 -0
  45. package/core/graphics/gradient-mesh.md +178 -0
  46. package/core/graphics/noise-grain-texture.md +150 -0
  47. package/core/graphics/placeholder-policy.md +185 -0
  48. package/core/graphics/svg-geometric-patterns.md +145 -0
  49. package/core/history/index.ts +39 -0
  50. package/core/install/detect.ts +32 -0
  51. package/core/install/install.ts +321 -0
  52. package/core/install/patch-claude.ts +109 -0
  53. package/core/install/patch-codex.ts +82 -0
  54. package/core/interaction/index.ts +101 -0
  55. package/core/interaction/recipes/signature-lighting.md +203 -0
  56. package/core/ir/dom.ts +352 -0
  57. package/core/ir/normalize.ts +177 -0
  58. package/core/motion/easing.md +151 -0
  59. package/core/motion/energy.ts +188 -0
  60. package/core/motion/recipes/image-hover-distortion.md +198 -0
  61. package/core/motion/recipes/magnetic-hover.md +229 -0
  62. package/core/motion/recipes/marquee.md +202 -0
  63. package/core/motion/recipes/number-counter.md +242 -0
  64. package/core/motion/recipes/page-loader.md +240 -0
  65. package/core/motion/recipes/parallax.md +233 -0
  66. package/core/motion/recipes/scroll-reveal.md +210 -0
  67. package/core/motion/recipes/section-color-inversion.md +217 -0
  68. package/core/motion/recipes/split-text-entrance.md +222 -0
  69. package/core/motion/recipes/stagger-orchestrator.md +227 -0
  70. package/core/motion/recipes/sticky-scene-transition.md +246 -0
  71. package/core/motion/recipes/view-transitions.md +239 -0
  72. package/core/probe/index.ts +186 -0
  73. package/core/probe/schema.json +46 -0
  74. package/core/protocol/composition-contract.md +192 -0
  75. package/core/protocol/copy-deck.md +96 -0
  76. package/core/protocol/human-design-loop.md +447 -0
  77. package/core/protocol/slop-review.md +71 -0
  78. package/core/ref/batch.ts +94 -0
  79. package/core/ref/blueprint.ts +199 -0
  80. package/core/ref/distance.ts +225 -0
  81. package/core/ref/invariants.ts +162 -0
  82. package/core/ref/signal.ts +37 -0
  83. package/core/ref/store.ts +122 -0
  84. package/core/render/index.ts +607 -0
  85. package/core/rules/attribution.ts +159 -0
  86. package/core/rules/builtin/contrast.yaml +8 -0
  87. package/core/rules/builtin/focus.yaml +8 -0
  88. package/core/rules/builtin/hit-area.yaml +8 -0
  89. package/core/rules/builtin/ko.yaml +6 -0
  90. package/core/rules/builtin/motion.yaml +80 -0
  91. package/core/rules/builtin/slop.yaml +365 -0
  92. package/core/rules/builtin/spacing.yaml +9 -0
  93. package/core/rules/builtin/system.yaml +42 -0
  94. package/core/rules/builtin/token.yaml +8 -0
  95. package/core/rules/builtin/ux.yaml +125 -0
  96. package/core/rules/engine.ts +88 -0
  97. package/core/rules/leakage.ts +72 -0
  98. package/core/rules/motion-spec.ts +204 -0
  99. package/core/site/index.ts +100 -0
  100. package/core/slop/index.ts +427 -0
  101. package/core/slop/text-slop.ts +220 -0
  102. package/core/source-seal/index.ts +174 -0
  103. package/core/stack/index.ts +53 -0
  104. package/core/target/index.ts +183 -0
  105. package/core/theory/color.md +285 -0
  106. package/core/theory/components.md +272 -0
  107. package/core/theory/craft.md +270 -0
  108. package/core/theory/expressive.md +213 -0
  109. package/core/theory/imagegen.md +105 -0
  110. package/core/theory/layout.md +159 -0
  111. package/core/theory/motion.md +283 -0
  112. package/core/theory/typography.md +134 -0
  113. package/core/theory/ux.md +580 -0
  114. package/core/theory/voice.md +595 -0
  115. package/core/types.ts +684 -0
  116. package/package.json +40 -0
  117. package/src/agents/composer.agent.yaml +174 -0
  118. package/src/agents/eye.agent.yaml +208 -0
  119. package/src/agents/framer.agent.yaml +52 -0
  120. package/src/agents/glance.agent.yaml +19 -0
  121. package/src/agents/hand.agent.yaml +200 -0
  122. package/src/agents/scout.agent.yaml +71 -0
  123. package/src/agents/sketch.agent.yaml +64 -0
  124. package/src/agents/typesetter.agent.yaml +52 -0
  125. package/src/agents/writer.agent.yaml +63 -0
  126. package/src/skills/omd-coach/SKILL.md +40 -0
  127. package/src/skills/omd-critique/SKILL.md +77 -0
  128. package/src/skills/omd-figma/SKILL.md +256 -0
  129. package/src/skills/omd-humanize/SKILL.md +160 -0
  130. package/src/skills/omd-scout/SKILL.md +77 -0
  131. package/src/skills/omd-ultradesign/SKILL.md +521 -0
@@ -0,0 +1,159 @@
1
+ # Layout — conditional decision material
2
+
3
+ Layout is a hypothesis about reading order, task order, and relationships. No single scan
4
+ pattern, hierarchy signal, grid unit, density, or breakpoint is universally correct. State
5
+ the condition, predict the effect, render real content, and revise from evidence.
6
+
7
+ ## Start from the experience spine
8
+
9
+ Before choosing a visual arrangement, write the dependency chain: what the user must notice,
10
+ understand, compare, decide, and do. The DOM and keyboard order should follow that meaningful
11
+ sequence even when CSS creates a different spatial composition. W3C Focus Order and technique
12
+ C27 both make this source-order relationship an accessibility requirement, not a stylistic
13
+ preference.
14
+
15
+ Use hierarchy signals in combination. Size, weight, contrast, position, grouping, imagery,
16
+ and motion can all attract or suppress attention; their effect depends on surrounding mass,
17
+ content, language, viewport, and user intent. There is no authoritative universal ranking
18
+ among them. Predict the first three attention stops, then inspect fixed-viewport squint and
19
+ sharp renders.
20
+
21
+ ## Gestalt as testable grouping hypotheses
22
+
23
+ - **Proximity:** closer items may be perceived as a unit. Keep an internal relationship
24
+ distinguishable from the gap to neighboring groups, then test at actual density.
25
+ - **Similarity:** shared treatment may imply shared function or category. Deliberately vary
26
+ treatment when the semantic role differs.
27
+ - **Closure:** space, background, edge alignment, or an incomplete contour may establish a
28
+ group without a border. Add containment only when the boundary is otherwise ambiguous.
29
+ - **Common fate:** elements moving together may be interpreted as related. Choreograph only
30
+ relationships the content supports.
31
+
32
+ These are predictions, not pixel prescriptions. A compact data table and an editorial story
33
+ can need very different gaps while preserving the same grouping logic.
34
+
35
+ ## Scan behavior is conditional
36
+
37
+ NN/g's F-shaped pattern describes a recurring behavior on text-heavy web content, especially
38
+ when people scan rather than read every word. It is not a universal template and does not
39
+ prove that every key action belongs at a particular coordinate. Use it as a warning: weak
40
+ front-loading, uninformative headings, and long undifferentiated text make important content
41
+ easy to miss. Strengthen information scent and meaningful headings before forcing an
42
+ F-shaped composition.
43
+
44
+ Other tasks produce other paths: comparison can move across aligned rows, search can jump to
45
+ landmarks, and sparse storytelling can follow media or an explicit sequence. Do not claim a
46
+ "Z-pattern law" without task-specific evidence. Record the expected path and verify it with
47
+ content, hierarchy, focus order, and interaction evidence.
48
+
49
+ ## Grid and alignment
50
+
51
+ A grid coordinates edges, columns, and intervals so relationships remain legible. Carbon's
52
+ 2x Grid is one documented system that combines a 2x mini unit, 8px base unit, columns,
53
+ gutters, and margins; it is an example of a coherent system, not proof that every product
54
+ must use those values. Apple similarly frames layout through platform context, safe areas,
55
+ readability, and adaptation rather than a single web grid.
56
+
57
+ Choose a base interval that fits the existing system, platform, type metrics, target density,
58
+ and device-pixel behavior. Optical corrections, borders, glyph geometry, and compact control
59
+ anatomy can legitimately fall outside it. The useful rule is traceability: repeated values
60
+ belong to a scale; deviations name the visible problem they solve.
61
+
62
+ An alignment break earns its cost when it reinforces the experience spine or concept. If
63
+ several elements break different edges without a shared reason, the result usually weakens
64
+ relationships. Compare an aligned and a deliberately broken candidate rather than treating
65
+ either as inherently sophisticated.
66
+
67
+ ## Density and visual mass
68
+
69
+ Density depends on frequency of use, expertise, task speed, content volume, screen size, and
70
+ error cost. High density can support scanning and comparison for expert, frequent workflows;
71
+ lower density can support comprehension, onboarding, reading, or infrequent decisions.
72
+ "More whitespace" and "more information" are not goals by themselves.
73
+
74
+ Map visual mass, not just element count. Large dark areas, saturated media, dense type,
75
+ borders, and repeated cards can outweigh their semantic importance. Predict which regions
76
+ dominate at desktop and mobile, render real copy/data, and correct accidental competition.
77
+
78
+ ## Responsive recomposition
79
+
80
+ WCAG Reflow requires content to work without loss of information or functionality and
81
+ without two-dimensional scrolling at the specified narrow equivalent, except for content
82
+ that genuinely needs two dimensions. This is an outcome requirement, not a mandate for a
83
+ particular breakpoint set.
84
+
85
+ Add breakpoints where content, controls, relationships, or readable measures fail—not at a
86
+ fixed list of device labels. At each transition decide explicitly whether regions:
87
+
88
+ - stack while preserving dependency;
89
+ - change order while keeping DOM/focus order meaningful;
90
+ - collapse behind a disclosed control;
91
+ - become horizontally scrollable because two-dimensional context is essential;
92
+ - switch from simultaneous comparison to a staged flow.
93
+
94
+ Test widths between named targets as well as the targets themselves. Fixed viewport renders
95
+ show hierarchy and cropping; optional full-page renders show page continuity but cannot
96
+ replace viewport evidence.
97
+
98
+ ## Cards and repeated modules
99
+
100
+ Cards are appropriate when each item is a portable unit with a meaningful boundary. They are
101
+ not a default composition. Repeated modules should expose the information users compare and
102
+ distinguish true priority without manufacturing a featured item. One containment signal may
103
+ be enough; borders, shadows, and tinted backgrounds used together can add noise, but dense or
104
+ low-contrast contexts may need more than one signal.
105
+
106
+ Ask whether section dependency would be clearer as a list, table, annotated narrative,
107
+ split view, or continuous document before choosing cards.
108
+
109
+ ## Forms and task order
110
+
111
+ A single vertical flow often reduces ambiguous traversal, but compact, semantically coupled
112
+ fields can share a row when their relationship and responsive order stay clear. Labels,
113
+ instructions, errors, and controls must remain associated programmatically and visually.
114
+ Choose label placement from available width, translation length, scan burden, and error
115
+ recovery—not from a universal completion-time claim.
116
+
117
+ Build only reachable states. Empty, loading, error, success, disabled, and offline layouts
118
+ must preserve the primary task, explain what changed, and provide an applicable next action.
119
+ Do not invent states to make a checklist appear complete.
120
+
121
+ ## Media and memorable moments
122
+
123
+ Assign media a job: establish domain, carry evidence, explain structure, demonstrate state,
124
+ or create a concept-bearing moment. Decorative media should not claim hierarchy needed by
125
+ the task. Distinctiveness can aid recall, but "exactly one memorable element" is not a law;
126
+ the number and intensity depend on page length, narrative beats, and competing tasks.
127
+
128
+ ## Composition recipes are hypotheses
129
+
130
+ The files under `core/composition/` are candidate mechanisms, not templates or defaults.
131
+ Their breakpoint values and token slots are demonstration values. A composer may cite a
132
+ recipe only after its condition gate matches the experience spine and must rewrite its
133
+ structure, values, and responsive transitions for the actual content. Candidate sketches
134
+ should compare meaningful axes rather than merely choosing different recipes.
135
+
136
+ ## Decision record
137
+
138
+ For every consequential layout choice record:
139
+
140
+ 1. condition and user task;
141
+ 2. predicted attention/dependency effect;
142
+ 3. chosen mechanism and rejected alternative;
143
+ 4. desktop and mobile recomposition;
144
+ 5. fixed-viewport evidence and resulting correction.
145
+
146
+ ## Authoritative sources
147
+
148
+ - [NN/g — F-Shaped Pattern of Reading on the Web](https://www.nngroup.com/articles/f-shaped-pattern-reading-web-content/)
149
+ — conditional behavior for scanning text-heavy content, not a universal page template.
150
+ - [W3C — Understanding Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html)
151
+ — responsive outcome and exceptions for genuinely two-dimensional content.
152
+ - [W3C — Understanding Focus Order](https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html)
153
+ — meaningful sequential navigation.
154
+ - [W3C Technique C27](https://www.w3.org/WAI/WCAG22/Techniques/css/C27)
155
+ — matching DOM order to visual order.
156
+ - [Carbon Design System — 2x Grid](https://carbondesignsystem.com/guidelines/2x-grid/)
157
+ — one documented grid system and its parts.
158
+ - [Apple Human Interface Guidelines — Layout](https://developer.apple.com/design/human-interface-guidelines/layout)
159
+ — platform-aware layout and adaptation guidance.
@@ -0,0 +1,283 @@
1
+ # Motion — decision material
2
+
3
+ Motion in UI is not decoration. It is a communication channel — one that operates faster
4
+ than reading and carries information the visual state alone cannot. Used correctly, it
5
+ confirms what happened, shows what belongs together, and tells the eye where to look next.
6
+ Used incorrectly, it competes with the content for attention and loses.
7
+
8
+ ---
9
+
10
+ ## Duration: what the research says
11
+
12
+ Nielsen's 1993 response time research establishes three thresholds that remain empirically
13
+ reliable across interface contexts:
14
+
15
+ **Under 100ms**: perceived as instantaneous. No transition is needed or helpful — adding
16
+ one makes a fast action feel slow, because the animation is the only delay. A hover state
17
+ change, a button press response, a tooltip appearing: if these resolve in under 100ms,
18
+ animating them costs more than it buys.
19
+
20
+ **100–300ms**: the transition zone. Perceptible, processable, not distracting. This is
21
+ where UI transitions belong — tab switches, modal entrances, panel slides, state changes
22
+ the user initiated and expects to see confirmed. Material Design's motion research places
23
+ navigation transitions at 200–300ms. Fast enough to feel responsive; long enough to read
24
+ as an intentional event, not a glitch.
25
+
26
+ **300–400ms**: the edge of interactive. Above this, the user has moved on cognitively
27
+ before the animation resolves. Transitions over 400ms feel broken unless they are
28
+ communicating a spatial relationship (a bottom sheet rising into position from below) or
29
+ the concept demands it (a luxury product whose register is unhurried).
30
+
31
+ **Above 400ms**: attention-consuming. Every millisecond above 400 spends attention budget
32
+ without certain return. Micro-interactions, hover effects, and state changes must never
33
+ exceed 400ms. Entrance animations for content on first load can reach 600ms if the page is
34
+ itself the delivery — a portfolio case study, a campaign page — but not if the page is a
35
+ tool the user came to use.
36
+
37
+ The single most common error is 500ms ease-in-out applied uniformly. This number is wrong
38
+ for three independent reasons: too slow for micro-interactions, too fast for meaningful
39
+ spatial motion, and the uniform easing removes any semantic distinction between different
40
+ kinds of change. Everything becomes the same sentence in the same tone of voice.
41
+
42
+ ---
43
+
44
+ ## Easing: the semantics of the curve
45
+
46
+ The easing curve is not an aesthetic choice. It carries a specific meaning about what kind
47
+ of event just occurred. Using ease-in where ease-out belongs is not a stylistic difference
48
+ — it communicates the wrong thing.
49
+
50
+ **ease-out** (fast start, gradual deceleration): an object arriving. The quick onset reads
51
+ as responsive — something arrived immediately because the system responded to you. The
52
+ gradual end reads as the object finding its place, settling. Use for: elements entering
53
+ from outside the viewport, overlays appearing, content loading in, drawer panels opening.
54
+ This is the "responsive" easing curve: it tells the user that the system heard them
55
+ immediately.
56
+
57
+ **ease-in** (gradual start, fast finish): an object leaving. The slow start reads as
58
+ reluctance; the fast finish reads as completion. Use for: dismissals, removals, transitions
59
+ out of a context. Almost never correct for entrances — a slow start reads as latency, which
60
+ reads as a slow system, which reads as broken.
61
+
62
+ **ease-in-out** (gradual start, gradual finish): an object transitioning between two
63
+ significant states. The equal deceleration at both ends signals that the before state and
64
+ the after state both matter — this is a state transition, not an arrival or departure.
65
+ Use for: position changes, size changes, content crossfades where both the source and
66
+ destination are meaningful.
67
+
68
+ **linear**: no easing. Use for opacity changes on hover states only — eased opacity on a
69
+ hover feels sluggish in a way that is hard to name but immediate to feel. Also correct for
70
+ looping animations (a spinner, a progress bar) where acceleration and deceleration would
71
+ produce visible stuttering on each cycle.
72
+
73
+ A design system that uses a single easing curve for all motion has a vocabulary of one word.
74
+ It can make things move, but it cannot say anything different about different movements.
75
+
76
+ ---
77
+
78
+ ## Choreography: the rules
79
+
80
+ **Entrance animations fire once.** On first load, and not again. If they replay on scroll,
81
+ the user eventually understands that scrolling triggers a performance, and they stop
82
+ scrolling slowly enough to watch it. The animation then delays their reading without
83
+ informing it. Scroll-triggered entrance is appropriate only when the interface is a
84
+ *presentation* — a long-scroll narrative, a portfolio case study — not when it is a
85
+ product the user came to use.
86
+
87
+ **Sibling stagger: 40–80ms offset.** When related elements enter together, staggering their
88
+ arrivals reads the group as a sequence — semantically correct when the elements have an
89
+ implied order. Below 40ms the stagger is imperceptible and the stagger code is wasted.
90
+ Above 80ms it becomes a waterfall: the user reads each element individually before the
91
+ next arrives, turning a group reveal into a slow-loading list.
92
+
93
+ **Hover feedback: under 150ms.** A hover state that takes more than 150ms to reach its
94
+ final state reads as slow. At 80–120ms with ease-out, the system reads as immediate and
95
+ precise. The user's pointer moved; the interface answered. Rauno Freiberg's web interface
96
+ guidelines (interfaces.rauno.me) specify that animation duration should not exceed 200ms
97
+ for interactions to feel immediate — 150ms for hover is the stricter constraint.
98
+
99
+ **Animate only `transform` and `opacity`.** Animating `width`, `height`, `top`, `left`,
100
+ or any property that triggers layout recalculation causes the browser to reflow and repaint
101
+ the document on every frame. The GPU cannot help. At 60 frames per second, this causes
102
+ visible jank on mid-range hardware. `transform: translate()` and `opacity` are composited
103
+ off the main thread — they animate at 60fps on all reasonable hardware without touching
104
+ layout. This is not a performance tradeoff to weigh against visual quality; it is a hard
105
+ rule with no exceptions.
106
+
107
+ **No scroll-jacking.** The user controls scroll. Intercepting scroll events to drive
108
+ animations or reposition content removes control from the user in a way they can feel but
109
+ not name — which is worse than a failure they can describe. NN/g ("Parallax Scrolling",
110
+ 2013) measured it: usability scores drop, and users who notice report frustration without
111
+ being able to articulate what broke. The concept must be extraordinary to justify the cost.
112
+
113
+ **`prefers-reduced-motion` is not optional.** WCAG 2.1 criterion 2.3.3 (Level AAA) requires a
114
+ mechanism to disable non-essential animation. In practice: one media query wraps the
115
+ entire motion layer, and in its presence, all transitions reduce to instant opacity changes
116
+ or disappear entirely. Not because most users trigger it — because those who need it need
117
+ it completely. A motion system that does not honour it is broken for those users,
118
+ regardless of how thoughtfully it was built for everyone else.
119
+
120
+ ---
121
+
122
+ ## The motion budget: where to spend it
123
+
124
+ Every page has an attention budget. Motion spends it. The question is not "what should
125
+ move" — it is "what earns the most from being seen moving."
126
+
127
+ The answer is almost always: one thing per context. The first-load entrance of the primary
128
+ content. The hover state of the primary CTA. The transition between two major views. A page
129
+ where everything moves is a screensaver: the eye has no hierarchy to follow, so it follows
130
+ nothing in particular.
131
+
132
+ Material Design's motion research (2023): assign motion to the element that carries the
133
+ most meaning at the moment the animation fires. A form submission success animation is
134
+ wasted if the success state is not the most important thing happening at that moment. Make
135
+ the most important thing move; make everything else still. Still elements make moving
136
+ elements visible; a page where everything moves makes nothing visible.
137
+
138
+ ---
139
+
140
+ ## Parallax and scroll-linked animation: the restraint case
141
+
142
+ Scroll-linked parallax — backgrounds moving at a different rate than foreground content as
143
+ the user scrolls — became a signature technique of the early 2010s and has since produced
144
+ measurable usability damage.
145
+
146
+ NN/g's research ("What Parallax Lacks", nngroup.com) documents three specific problems:
147
+ users scroll quickly to scan for keywords of interest; parallax animations require slow
148
+ scrolling to be processed, and users who scroll at their normal speed miss the animated
149
+ content entirely. The animation becomes invisible to the audience it was designed for.
150
+ Second: banner blindness — users who have seen parallax repeatedly have learned to classify
151
+ it as decorative noise and ignore it. Third: for users with vestibular disorders, the
152
+ dissociation between their scroll movement and the movement on screen reliably triggers
153
+ discomfort or nausea. `prefers-reduced-motion: reduce` removes this for users who set it;
154
+ it does not help users who have not discovered the setting.
155
+
156
+ The performance case is equally clear. In 2024, real-world examples of parallax-heavy pages
157
+ showed Largest Contentful Paint (LCP) times exceeding 8 seconds and poor INP (Interaction
158
+ to Next Paint) scores — Core Web Vitals failures that affect search ranking as well as
159
+ user experience.
160
+
161
+ Condition → choice → reason: use scroll-linked animation only when the content is itself
162
+ a scroll-narrative (a case study, a product demo that teaches while scrolling) and the
163
+ concept explicitly requires it. For product UI, remove all parallax. The budget it consumes
164
+ returns nothing.
165
+
166
+ ---
167
+
168
+ ## Microinteractions: the Saffer framework
169
+
170
+ Dan Saffer's *Microinteractions: Designing with Details* (O'Reilly, 2013) defines the
171
+ four-component structure that governs every small moment in a UI:
172
+
173
+ **Trigger**: what initiates the microinteraction. Either a user action (clicking a button,
174
+ focusing an input, swiping) or a system condition (a value threshold crossed, a timer
175
+ expiring, a notification arriving). The trigger must be discoverable — hidden triggers are
176
+ interaction debt, not delight.
177
+
178
+ **Rules**: what happens after the trigger fires. The complete behaviour of the system in
179
+ response — what changes, in what order, by how much. Every edge case the rules don't
180
+ cover produces unexpected behaviour the user did not expect and the designer did not intend.
181
+
182
+ **Feedback**: the signal to the user that their action was received and the rule is
183
+ executing. Feedback can be visual (a checkbox check animates in), auditory (a success
184
+ tone), haptic (a vibration), or motion-based (a button compresses on press). Absent
185
+ feedback, the user cannot confirm their action was registered and will repeat it — the
186
+ mechanism behind double-submissions on slow forms.
187
+
188
+ **Loops and modes**: how long the microinteraction runs and whether it changes behaviour
189
+ on repetition. A "like" animation that runs once is a loop of one. A notification badge
190
+ that counts up is a loop that runs until cleared. A mode is a variant of the
191
+ microinteraction that activates under a different state (the muted mode of a volume
192
+ control).
193
+
194
+ The design implication: every interactive element should be audited against these four
195
+ components. If any component is missing or undefined, the interaction is incomplete. Missing
196
+ feedback is the most common defect — it produces the user experience of interacting with
197
+ a broken system.
198
+
199
+ ---
200
+
201
+ ## Skeleton screens vs spinners: the performance perception research
202
+
203
+ Loading states are not equally effective at managing the perception of time. The choice
204
+ between a spinner and a skeleton screen changes what the user believes about the system's
205
+ responsiveness.
206
+
207
+ **Spinners** communicate system activity: "I am working." They provide no information
208
+ about what is coming, how much there is, or how long it will take. Under any uncertainty
209
+ about wait duration, spinners increase anxiety — the user cannot estimate, and estimation
210
+ is how humans manage waiting.
211
+
212
+ **Skeleton screens** communicate structural presence: "The layout is here; the content is
213
+ arriving." By showing the shape of the content before the content loads, the skeleton
214
+ gives the brain a structure to place the incoming data. Research comparing skeleton screens
215
+ to spinners and progress bars (NN/g, "Skeleton Screens vs. Progress Bars vs. Spinners",
216
+ 2020) shows that skeleton screens are perceived as faster even at identical actual load
217
+ times, and studies show they can reduce abandonment by up to 30% by communicating that
218
+ progress is already happening.
219
+
220
+ Condition → choice → reason: use skeleton screens for page-level content loads where the
221
+ layout is predictable (a list of cards, a article page, a dashboard grid). Use spinners for
222
+ short indeterminate operations where the structural result cannot be previewed (file upload
223
+ progress, authentication, payment processing). Never use a skeleton where the actual
224
+ layout will be substantially different from the skeleton — a skeleton that does not match
225
+ what loads is more disorienting than a spinner that made no promises.
226
+
227
+ ---
228
+
229
+ ## The FLIP technique: performance as a design constraint
230
+
231
+ FLIP (First, Last, Invert, Play) is a browser animation technique that enables smooth
232
+ transitions between arbitrary layout states by computing the difference between two static
233
+ positions and animating that difference as a `transform`, rather than animating the layout
234
+ property directly.
235
+
236
+ The technique: record the element's position before the change (First). Apply the change
237
+ and record the new position (Last). Apply a `transform` that moves the element back to its
238
+ First position instantly (Invert). Animate the transform to zero (Play — which visually
239
+ moves the element from its old to its new position while only touching `transform`).
240
+
241
+ The design consequence: FLIP enables animations that would otherwise require animating
242
+ layout properties — a card expanding to fill the screen, an item reordering in a list, a
243
+ grid reconfiguring. Without FLIP, these are either unanimated (abrupt, disorienting) or
244
+ animated with layout-touching properties (jank, dropped frames). FLIP makes them smooth
245
+ at 60fps.
246
+
247
+ The constraint: FLIP only works when the start and end states are both valid layout states.
248
+ A design that requires animating through an intermediate state that is not a valid layout
249
+ state cannot use FLIP. This is a genuine design constraint — some transitions need to be
250
+ re-designed so that their start and end states are both in CSS, not procedurally computed.
251
+
252
+ ---
253
+
254
+ ## Motion cookbook
255
+
256
+ The implementation primitives that put this theory into practice — split-text entrance,
257
+ scroll-reveal, stagger orchestrator, sticky scene, section colour inversion, marquee,
258
+ magnetic hover, page loader, number counter, image hover distortion, view transitions,
259
+ and parallax — are in `core/motion/recipes/`. The easing token vocabulary (--ease-out-expo,
260
+ --ease-out-back, --ease-spring, and the full curated set) is in `core/motion/easing.md`.
261
+ Recipes reference the theory here; the hand wires the recipe parameters from the board's
262
+ motion studies.
263
+
264
+ ## Sources
265
+
266
+ - Nielsen, "Response Times: The 3 Important Limits" (1993) — 0.1s / 1s / 10s thresholds
267
+ and their perceptual basis
268
+ - Material Design, Motion (2023) — duration guidelines, easing system, choreography rules,
269
+ budget allocation
270
+ - NN/g, "Parallax Scrolling" / "What Parallax Lacks" (2013, nngroup.com) — usability
271
+ evidence against scroll position–driven animation; banner blindness and goal-oriented
272
+ scanning
273
+ - WCAG 2.1, criterion 2.3.3 — Animation from Interactions; the accessibility baseline
274
+ - Saffer, *Microinteractions: Designing with Details* (O'Reilly, 2013) — trigger/rules/
275
+ feedback/loops framework for small interaction design
276
+ - NN/g, "Skeleton Screens vs. Progress Bars vs. Spinners" (2020) — perceived performance
277
+ comparison; skeleton screen abandonment reduction evidence
278
+ - Rauno Freiberg, Web Interface Guidelines (interfaces.rauno.me) — 200ms interaction
279
+ ceiling, animation proportional to trigger size
280
+ - Fast Company, "Why parallax scrolling needs to die" (2019) — performance and cognitive
281
+ load argument
282
+ - Gamache, "Parallax Done Right" (Medium, 2014) — performance constraints and the GPU
283
+ compositing argument for transform-only animation
@@ -0,0 +1,134 @@
1
+ # Typography: prove the text that will ship
2
+
3
+ Typography starts with the reader, task, register, and actual copy. A font name or ratio is
4
+ not a decision until the target-language specimen shows what it does to meaning, hierarchy,
5
+ wrapping, loading, and fallback.
6
+
7
+ ## Evidence order
8
+
9
+ Work in this order:
10
+
11
+ 1. Read the target-language copy deck and identify productive and expressive roles.
12
+ 2. Name the task and register: dense scanning, long reading, transactional UI, editorial
13
+ authority, playful showpiece, or another evidenced need.
14
+ 3. Study cited typography references for visible anatomy and behavior, not brand prestige.
15
+ 4. Build neutral specimens with the real headline, body, labels, CTA, numerals, punctuation,
16
+ dates, prices, identifiers, and the longest representative strings.
17
+ 5. Render at 1280x900 and 390x844 after `document.fonts.ready`.
18
+ 6. Record requested and computed browser evidence, then judge the visible result.
19
+
20
+ Do not start from a generic font-name default. A familiar family can still be wrong for the
21
+ copy, language coverage, voice, or production constraints.
22
+
23
+ ## Role map
24
+
25
+ Separate two jobs:
26
+
27
+ - **Productive type** carries navigation, body, metadata, forms, tables, states, and repeated
28
+ actions. It needs calm differentiation, durable glyph coverage, and predictable density.
29
+ - **Expressive type** carries a concept-bearing display line or rare editorial moment. Its
30
+ face and weight must contribute meaning; size alone cannot supply the concept.
31
+
32
+ One family can cover both roles. Two families can be justified when their visible anatomy
33
+ creates a useful distinction. Start with one or two families and add another only when a
34
+ specimen proves the existing set cannot express a required role.
35
+
36
+ ## Target-language and glyph coverage
37
+
38
+ List the scripts and symbols that the product actually uses. For a Korean product this often
39
+ includes Hangul syllables and jamo, Latin names and URLs, Arabic numerals, currency, dates,
40
+ punctuation, arrows, and product-specific symbols. Test the real strings.
41
+
42
+ Browser `document.fonts.check()` can show only that the browser considers a requested face
43
+ ready for a sample; it does not prove glyph coverage. FontFace status reports declared-face
44
+ loading state. Computed CSS can show the requested/computed family, size, weight, and line
45
+ height. None identifies the physical font that painted every glyph.
46
+ Visible tofu, style jumps, mismatched punctuation, or a fallback-shaped substring is a
47
+ failure even when the API reports loaded.
48
+
49
+ Hangul line breaking is a contextual author choice. W3C KLREQ describes both word-based and
50
+ character-based practices. Test the chosen `word-break` and wrapping policy with actual copy
51
+ at the intended container widths; do not enforce one policy for every Korean interface.
52
+
53
+ ## Visible anatomy and voice
54
+
55
+ Compare what is visible in the specimen:
56
+
57
+ - Hangul square density, counters, terminals, stroke modulation, and punctuation alignment;
58
+ - Latin x-height, width, apertures, numeral shapes, and compatibility with Hangul color;
59
+ - the rhythm of mixed Korean, Latin, and numeral lines;
60
+ - whether the face sounds aligned with the recorded register rather than merely “modern.”
61
+
62
+ Reject an alternative by naming the visible condition and consequence. “Too generic” is not
63
+ enough; “the narrow Latin numerals create a second texture inside Korean prices” is evidence.
64
+
65
+ ## Size, measure, and line height
66
+
67
+ Choose size from reading distance, role, actual copy, and container. Useful starting ranges
68
+ are hypotheses to render, not mandates: body text often begins around the mid-teens in CSS
69
+ pixels, compact UI may begin lower, and display roles may begin much larger. Adjust only from
70
+ specimen evidence.
71
+
72
+ Likewise, a body line height around 1.4–1.7 can be a starting test. KLREQ's 160% example is
73
+ an example, not a universal Korean requirement. Display lines often need tighter leading,
74
+ but the specimen must show that stacked glyphs, accents, and wrapping remain clear.
75
+
76
+ Record desktop and mobile container widths, line counts, deliberate breaks, accidental
77
+ orphans, clipping, and the relationship between primary, secondary, and CTA text. Never hide
78
+ a heading's overflow to make a failed proof look clean.
79
+
80
+ ## Weight, axes, and optical size
81
+
82
+ Request only weights the source provides. Compare requested and computed weights and inspect
83
+ whether the visible face actually changes. A synthetic bold or faux italic fails when it
84
+ distorts the intended anatomy.
85
+
86
+ For variable fonts, record the file, supported axes, requested values, and relevant named
87
+ instances. Test intermediate weights rather than assuming the browser interpolates as
88
+ intended. Variable fonts can reduce requests in some deployments, but are not inherently
89
+ smaller than every static subset.
90
+
91
+ When the face provides an `opsz` axis, test `font-optical-sizing: auto` against an explicit
92
+ setting. MDN documents the mechanism; the actual specimen decides whether it helps this
93
+ face, copy, and size.
94
+
95
+ ## Fallback, loading, CLS, and performance
96
+
97
+ Record source, licence, hosting choice, formats, unicode subsets, preload decision, and
98
+ `font-display` behavior. Build a fallback stack that covers the same scripts. Compare its
99
+ metrics and wraps with the primary face; use metric overrides only with measured source data.
100
+
101
+ Test:
102
+
103
+ - first render and post-font render for layout shift;
104
+ - fallback and primary wraps at both proof viewports;
105
+ - unavailable, slow, and failed font states;
106
+ - whether critical text stays readable while loading;
107
+ - the network cost of the files and subsets actually shipped.
108
+
109
+ web.dev's font guidance is a starting reference for preload, subsetting, and layout shift.
110
+ Performance claims belong to measured project output, never a fixed file-size promise.
111
+
112
+ ## Typography proof record
113
+
114
+ `.omd/type-proof.md` records:
115
+
116
+ - role map and target task/register;
117
+ - family source, licence, hosting, scripts, glyphs, weights, and axes;
118
+ - actual copy specimens;
119
+ - requested and computed family/weight evidence;
120
+ - desktop/mobile line, wrap, clip, orphan, and hierarchy observations;
121
+ - fallback/loading/CLS/performance plan;
122
+ - alternatives rejected with visible evidence;
123
+ - a fingerprint of copy, font family/files, weights/axes, and container widths.
124
+
125
+ Changing any fingerprint input invalidates the proof. After a structure is selected, repeat
126
+ the proof inside the real production container before the visual craft checkpoint.
127
+
128
+ ## Sources
129
+
130
+ - W3C, *Requirements for Hangul Text Layout and Typography (KLREQ)*.
131
+ - web.dev, *Font best practices*.
132
+ - MDN, *CSS Font Loading API* and *font-optical-sizing*.
133
+ - U.S. Web Design System, typography guidance.
134
+ - Carbon Design System, productive and expressive type roles.