wizz-method 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills-registry.yaml +12 -2
- package/src/modules/wizz/_shared/token-economy.md +3 -0
- package/src/modules/wizz/agents/wizz-ads/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-copy/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-designer/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-growth/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-maestro/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-memoria/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-qa/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-seo/customize.toml +1 -0
- package/src/modules/wizz/agents/wizz-social/customize.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-analyst.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-architect.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-dev.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-pm.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +1 -0
- package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +1 -0
- package/src/skills-lib/ai-product-design/SKILL.md +85 -0
- package/src/skills-lib/ai-product-design/references/LICENSE +21 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/bias-detection-design/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/consent-and-agency/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/escalation-design/SKILL.md +40 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/guardrail-design/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/harm-anticipation/SKILL.md +108 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/transparency-patterns/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/trust-calibration/SKILL.md +102 -0
- package/src/skills-lib/ai-product-design/references/ai-alignment-reasoning/value-specification/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/agent-role-design/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/failure-recovery/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/handoff-protocols/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/human-in-the-loop/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/observability-design/SKILL.md +48 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/state-management/SKILL.md +95 -0
- package/src/skills-lib/ai-product-design/references/design-agent-orchestration/task-decomposition/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/evaluation/comparative-evaluation/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/evaluation/failure-taxonomy/SKILL.md +47 -0
- package/src/skills-lib/ai-product-design/references/evaluation/heuristic-evaluation-ai/SKILL.md +46 -0
- package/src/skills-lib/ai-product-design/references/evaluation/longitudinal-measurement/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/evaluation/output-quality-rubrics/SKILL.md +41 -0
- package/src/skills-lib/ai-product-design/references/evaluation/task-success-metrics/SKILL.md +35 -0
- package/src/skills-lib/ai-product-design/references/evaluation/user-satisfaction-signals/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/context-window-design/SKILL.md +28 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/conversation-patterns/SKILL.md +37 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/feedback-loops/SKILL.md +35 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/frustration-detection/SKILL.md +91 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/generative-ui/SKILL.md +34 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/mixed-initiative-flow/SKILL.md +39 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/multimodal-orchestration/SKILL.md +94 -0
- package/src/skills-lib/ai-product-design/references/model-interaction-design/progressive-disclosure/SKILL.md +33 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/chain-of-thought-design/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/constraint-specification/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/context-engineering/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/few-shot-patterns/SKILL.md +47 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/prompt-versioning/SKILL.md +42 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/system-prompt-structure/SKILL.md +50 -0
- package/src/skills-lib/ai-product-design/references/prompt-architecture/template-design/SKILL.md +42 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/behavioral-consistency/SKILL.md +36 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/cultural-adaptation/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/domain-voice/SKILL.md +51 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/emotional-design/SKILL.md +51 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/error-personality/SKILL.md +45 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/persona-architecture/SKILL.md +38 -0
- package/src/skills-lib/ai-product-design/references/system-behavior-shaping/tone-calibration/SKILL.md +39 -0
- package/src/skills-lib/algorithmic-art/LICENSE.txt +202 -0
- package/src/skills-lib/algorithmic-art/SKILL.md +405 -0
- package/src/skills-lib/algorithmic-art/templates/generator_template.js +223 -0
- package/src/skills-lib/algorithmic-art/templates/viewer.html +599 -0
- package/src/skills-lib/animate/README.md +41 -0
- package/src/skills-lib/animate/SKILL.md +179 -0
- package/src/skills-lib/animate/examples/animate-height.tsx +75 -0
- package/src/skills-lib/animate/examples/app-store-card.tsx +164 -0
- package/src/skills-lib/animate/examples/card-hover.tsx +79 -0
- package/src/skills-lib/animate/examples/feedback-popover.tsx +119 -0
- package/src/skills-lib/animate/examples/multi-step-flow.tsx +128 -0
- package/src/skills-lib/animate/examples/shared-layout.tsx +64 -0
- package/src/skills-lib/animate/examples/text-reveal.tsx +70 -0
- package/src/skills-lib/animate/examples/toast-stacking.tsx +95 -0
- package/src/skills-lib/animate/references/css-animations.md +232 -0
- package/src/skills-lib/animate/references/easing-and-timing.md +105 -0
- package/src/skills-lib/animate/references/framer-motion.md +356 -0
- package/src/skills-lib/animate/references/performance-accessibility.md +185 -0
- package/src/skills-lib/auth-and-secrets/SKILL.md +10 -0
- package/src/skills-lib/canvas-design/LICENSE.txt +202 -0
- package/src/skills-lib/canvas-design/SKILL.md +130 -0
- package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/src/skills-lib/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/src/skills-lib/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/src/skills-lib/design-motion-principles/SKILL.md +122 -0
- package/src/skills-lib/design-motion-principles/references/accessibility.md +52 -0
- package/src/skills-lib/design-motion-principles/references/anti-checklist.md +274 -0
- package/src/skills-lib/design-motion-principles/references/audit-checklist.md +137 -0
- package/src/skills-lib/design-motion-principles/references/creation-gotchas.md +36 -0
- package/src/skills-lib/design-motion-principles/references/demo-shell.html +275 -0
- package/src/skills-lib/design-motion-principles/references/emil-kowalski.md +121 -0
- package/src/skills-lib/design-motion-principles/references/jakub-krehel.md +80 -0
- package/src/skills-lib/design-motion-principles/references/jhey-tompkins.md +122 -0
- package/src/skills-lib/design-motion-principles/references/motion-cookbook.md +529 -0
- package/src/skills-lib/design-motion-principles/references/output-format.md +346 -0
- package/src/skills-lib/design-motion-principles/references/performance.md +82 -0
- package/src/skills-lib/design-motion-principles/references/report-template.html +1006 -0
- package/src/skills-lib/design-motion-principles/workflows/audit.md +203 -0
- package/src/skills-lib/design-motion-principles/workflows/create.md +87 -0
- package/src/skills-lib/web-security/SKILL.md +47 -4
- package/src/skills-lib/wizz-router/SKILL.md +4 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Demo Shell — design-motion-principles
|
|
3
|
+
=====================================
|
|
4
|
+
|
|
5
|
+
Minimal, isolated reference for a single demo card. The agent reads this
|
|
6
|
+
during STEP 3 of the audit workflow (see ../SKILL.md) and uses it as the
|
|
7
|
+
per-finding template — one .demo block per Critical or Important finding
|
|
8
|
+
(Opportunities don't get demo cards).
|
|
9
|
+
|
|
10
|
+
The full worked example with five demo cards in context lives in
|
|
11
|
+
references/report-template.html. This file is intentionally minimal:
|
|
12
|
+
one card, every contract visible, no report scaffolding.
|
|
13
|
+
|
|
14
|
+
How the agent uses this file
|
|
15
|
+
----------------------------
|
|
16
|
+
1. Copy the entire <style> block into the report's <head>. The shell's
|
|
17
|
+
tokens, .demo layout, stage colors, segmented control, and the
|
|
18
|
+
prefers-reduced-motion guard are SHARED across every demo card in the
|
|
19
|
+
report and must not be duplicated per finding.
|
|
20
|
+
|
|
21
|
+
2. For each finding {n} (1-indexed across the whole report):
|
|
22
|
+
a. Replace the MOTION-CODE-SLOT-{n} comment with the per-finding
|
|
23
|
+
@keyframes m{n} block AND the .demo-{n}__mt selector rule.
|
|
24
|
+
Suffix {n} so multiple findings cannot collide on keyframe
|
|
25
|
+
names or selectors.
|
|
26
|
+
b. Replace the DEMO-CARD-MOTION-SLOT-{n} comment in the .demo__stage
|
|
27
|
+
markup with the actual motion-target element. Its class must be
|
|
28
|
+
.demo-{n}__mt so it matches the rules above.
|
|
29
|
+
c. Set .demo__title to a short title for the recommended motion
|
|
30
|
+
(e.g., "Quick tab crossfade", "Sheet enter (mirror for exit)").
|
|
31
|
+
d. Set .demo__timing to the duration plus easing (e.g.,
|
|
32
|
+
"180ms · ease-out", "300ms · ease-out-quint"). The subhead
|
|
33
|
+
ALWAYS renders — populate it for every demo so card heights
|
|
34
|
+
stay consistent across the report.
|
|
35
|
+
e. Renumber the four radio ids from st1-* to st{n}-*, and the
|
|
36
|
+
labels' for= attributes to match.
|
|
37
|
+
|
|
38
|
+
3. Per-finding code MUST honor these contracts:
|
|
39
|
+
- Do NOT redefine the shell's tokens (--ink, --paper, --surface-2,
|
|
40
|
+
--line, --line-strong, --st-bg, --st-fg, --st-line, --st-dim,
|
|
41
|
+
--sans, --mono). Use them via var().
|
|
42
|
+
- Do NOT modify the prefers-reduced-motion block. The shell's
|
|
43
|
+
guard collapses all .demo-{n}__mt animations to none. The
|
|
44
|
+
per-finding @keyframes 100% state MUST match the motion-target
|
|
45
|
+
element's default static rendering so the reduce-motion fallback
|
|
46
|
+
shows the correct final visual.
|
|
47
|
+
- Per-finding @keyframes use the 0% / ~60% / 100% cadence:
|
|
48
|
+
0% = start state, ~60% = motion complete (~1.8s in),
|
|
49
|
+
100% = hold (~1.2s). The shell uses animation-duration: 3s.
|
|
50
|
+
|
|
51
|
+
4. Motion targets and ANY UI primitives inside the stage (.ui-btn,
|
|
52
|
+
.ui-card, .ui-row, .ui-check, .ui-num, .ui-label, badge, etc.)
|
|
53
|
+
use --st-bg / --st-fg / --st-line / --st-dim — NEVER --accent or
|
|
54
|
+
other page tokens. This guarantees the demo contrasts correctly
|
|
55
|
+
when its stage is locked to a different theme than the report.
|
|
56
|
+
|
|
57
|
+
5. Demo cards are non-interactive. The stage toggle radios are the
|
|
58
|
+
only interactive element. tabindex on the radios is fine; the
|
|
59
|
+
stage itself stays out of focus order.
|
|
60
|
+
|
|
61
|
+
Loop pacing
|
|
62
|
+
-----------
|
|
63
|
+
animation-duration: 3s. Keyframes 0% / ~60% / 100%. Motion 0–60% ≈ 1.8s,
|
|
64
|
+
hold 60–100% ≈ 1.2s, then restart. Every demo in a report uses this
|
|
65
|
+
cadence so all cards share the same rhythm.
|
|
66
|
+
|
|
67
|
+
Standalone preview
|
|
68
|
+
------------------
|
|
69
|
+
Opening this file directly in a browser shows one .demo card with the
|
|
70
|
+
loop indicator, the segmented Auto/Light/Dark stage toggle, and a
|
|
71
|
+
placeholder motion target (a simple shape that fades in). No real
|
|
72
|
+
per-finding motion plays — the agent injects motion per finding when
|
|
73
|
+
this template is embedded in a report. The shell also honors the
|
|
74
|
+
viewer's prefers-color-scheme for standalone rendering.
|
|
75
|
+
-->
|
|
76
|
+
<!DOCTYPE html>
|
|
77
|
+
<html lang="en">
|
|
78
|
+
<head>
|
|
79
|
+
<meta charset="utf-8">
|
|
80
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
81
|
+
<title>Demo Shell — design-motion-principles</title>
|
|
82
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
83
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
84
|
+
<link href="https://fonts.googleapis.com/css2?family=Familjen+Grotesk:wght@400;500;600;700&family=Public+Sans:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
85
|
+
<style>
|
|
86
|
+
:root {
|
|
87
|
+
/* Cool slate-graphite neutrals (hue 255). In the full report these
|
|
88
|
+
are overridden by a global theme toggle; here the shell flips via
|
|
89
|
+
prefers-color-scheme for standalone preview. */
|
|
90
|
+
--ink: oklch(0.155 0.006 255);
|
|
91
|
+
--surface: oklch(0.195 0.007 255);
|
|
92
|
+
--surface-2: oklch(0.235 0.008 255);
|
|
93
|
+
--paper: oklch(0.945 0.004 255);
|
|
94
|
+
--paper-dim: oklch(0.800 0.006 255);
|
|
95
|
+
--muted: oklch(0.680 0.008 255);
|
|
96
|
+
--faint: oklch(0.505 0.008 255);
|
|
97
|
+
--line: oklch(0.95 0.01 255 / 0.09);
|
|
98
|
+
--line-strong:oklch(0.95 0.01 255 / 0.16);
|
|
99
|
+
|
|
100
|
+
--display: "Familjen Grotesk", "Hanken Grotesk", system-ui, sans-serif;
|
|
101
|
+
--sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
102
|
+
--mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@media (prefers-color-scheme: light) {
|
|
106
|
+
:root {
|
|
107
|
+
--ink: oklch(0.985 0.003 255);
|
|
108
|
+
--surface: oklch(0.965 0.004 255);
|
|
109
|
+
--surface-2: oklch(0.940 0.005 255);
|
|
110
|
+
--paper: oklch(0.180 0.006 255);
|
|
111
|
+
--paper-dim: oklch(0.330 0.008 255);
|
|
112
|
+
--muted: oklch(0.475 0.010 255);
|
|
113
|
+
--faint: oklch(0.640 0.009 255);
|
|
114
|
+
--line: oklch(0.180 0.010 255 / 0.12);
|
|
115
|
+
--line-strong:oklch(0.180 0.010 255 / 0.22);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
* { box-sizing: border-box; }
|
|
120
|
+
body {
|
|
121
|
+
background: var(--ink);
|
|
122
|
+
color: var(--paper);
|
|
123
|
+
font-family: var(--sans);
|
|
124
|
+
margin: 0;
|
|
125
|
+
padding: 48px;
|
|
126
|
+
display: flex;
|
|
127
|
+
justify-content: center;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* visually-hidden (stage-toggle radios) */
|
|
131
|
+
.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
132
|
+
|
|
133
|
+
/* ───────────── Demo card ───────────── */
|
|
134
|
+
.demo { position: relative; width: 380px; }
|
|
135
|
+
.demo__bar { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
|
|
136
|
+
.demo__meta { min-width: 0; }
|
|
137
|
+
.demo__title { display: block; font-size: 13.5px; font-weight: 600; color: var(--paper); line-height: 1.3; }
|
|
138
|
+
.demo__timing { display: block; font-family: var(--mono); font-size: 11px; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }
|
|
139
|
+
.demo__controls { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
|
|
140
|
+
.demo__loop { font-family: var(--mono); font-size: 12px; color: var(--faint); }
|
|
141
|
+
|
|
142
|
+
/* segmented Auto / Light / Dark stage toggle (pure CSS).
|
|
143
|
+
Auto = follow ambient theme via --surface-2 + --paper.
|
|
144
|
+
Light / Dark = locked overrides (hardcoded values, ignore ambient). */
|
|
145
|
+
.seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 100px; overflow: hidden; }
|
|
146
|
+
.seg label { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); padding: 4px 9px; cursor: pointer; user-select: none; transition: background 0.15s ease, color 0.15s ease; }
|
|
147
|
+
.demo input[id$="-a"]:checked ~ .demo__bar .seg label[for$="-a"],
|
|
148
|
+
.demo input[id$="-l"]:checked ~ .demo__bar .seg label[for$="-l"],
|
|
149
|
+
.demo input[id$="-d"]:checked ~ .demo__bar .seg label[for$="-d"] {
|
|
150
|
+
background: color-mix(in oklch, var(--paper) 12%, transparent);
|
|
151
|
+
color: var(--paper);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.demo__stage {
|
|
155
|
+
/* AUTO default — stage uses the ambient elevated surface */
|
|
156
|
+
--st-bg: var(--surface-2);
|
|
157
|
+
--st-fg: var(--paper);
|
|
158
|
+
--st-line: var(--line-strong);
|
|
159
|
+
--st-dim: color-mix(in oklch, var(--paper) 55%, transparent);
|
|
160
|
+
background: var(--st-bg); color: var(--st-fg);
|
|
161
|
+
border: 1px solid var(--line); border-radius: 10px;
|
|
162
|
+
padding: 32px 24px; min-height: 168px;
|
|
163
|
+
display: flex; align-items: center; justify-content: center; overflow: hidden;
|
|
164
|
+
}
|
|
165
|
+
/* Locked Light: hardcoded light, regardless of ambient theme */
|
|
166
|
+
.demo input[id$="-l"]:checked ~ .demo__stage {
|
|
167
|
+
--st-bg: oklch(0.985 0.003 255);
|
|
168
|
+
--st-fg: oklch(0.180 0.006 255);
|
|
169
|
+
--st-line: oklch(0.180 0.010 255 / 0.18);
|
|
170
|
+
--st-dim: oklch(0.180 0.010 255 / 0.45);
|
|
171
|
+
}
|
|
172
|
+
/* Locked Dark: hardcoded dark, regardless of ambient theme */
|
|
173
|
+
.demo input[id$="-d"]:checked ~ .demo__stage {
|
|
174
|
+
--st-bg: oklch(0.180 0.006 255);
|
|
175
|
+
--st-fg: oklch(0.985 0.003 255);
|
|
176
|
+
--st-line: oklch(0.985 0.010 255 / 0.18);
|
|
177
|
+
--st-dim: oklch(0.985 0.010 255 / 0.50);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Generic UI primitives for use inside motion targets. All theme via
|
|
181
|
+
stage tokens, NEVER page tokens — so they contrast correctly when a
|
|
182
|
+
stage is locked to a different theme than the report. */
|
|
183
|
+
.ui-btn { display: inline-flex; align-items: center; justify-content: center; padding: 9px 18px; border-radius: 8px; background: var(--st-fg); color: var(--st-bg); font-family: var(--sans); font-size: 13px; font-weight: 600; }
|
|
184
|
+
.ui-card { background: var(--st-bg); border: 1px solid var(--st-line); border-radius: 10px; padding: 14px 16px; min-width: 180px; box-shadow: 0 8px 24px oklch(0 0 0 / 0.12); }
|
|
185
|
+
.ui-row { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--st-fg); }
|
|
186
|
+
.ui-check { width: 22px; height: 22px; border-radius: 7px; background: var(--st-fg); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
|
187
|
+
.ui-check svg { width: 13px; height: 13px; stroke: var(--st-bg); }
|
|
188
|
+
.ui-num { font-family: var(--display); font-size: 34px; font-weight: 700; color: var(--st-fg); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
|
|
189
|
+
.ui-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--st-dim); }
|
|
190
|
+
|
|
191
|
+
/* prefers-reduced-motion — disables every per-finding animation and
|
|
192
|
+
hides the loop indicator. The per-finding @keyframes 100% state
|
|
193
|
+
must match the motion-target's default rendering so the reduce
|
|
194
|
+
fallback shows the correct final visual. */
|
|
195
|
+
@media (prefers-reduced-motion: reduce) {
|
|
196
|
+
.demo__loop { display: none; }
|
|
197
|
+
[class*="__mt"], [class*="__mt"] * { animation: none !important; transition: none !important; }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* MOTION-CODE-SLOT-{n}
|
|
201
|
+
Per-finding @keyframes and .demo-{n}__mt rules go here. {n} is the
|
|
202
|
+
finding's 1-indexed position across the report.
|
|
203
|
+
|
|
204
|
+
Example shape (replace per finding — wrap in
|
|
205
|
+
@media (prefers-reduced-motion: no-preference) { ... }):
|
|
206
|
+
|
|
207
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
208
|
+
@keyframes m1 {
|
|
209
|
+
0% { opacity: 0; transform: translateY(8px); filter: blur(4px); }
|
|
210
|
+
60% { opacity: 1; transform: translateY(0); filter: blur(0); }
|
|
211
|
+
100% { opacity: 1; transform: translateY(0); filter: blur(0); }
|
|
212
|
+
}
|
|
213
|
+
.demo-1__mt {
|
|
214
|
+
animation: m1 3s cubic-bezier(0.22, 1, 0.36, 1) infinite;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
/* Placeholder motion for standalone preview only — agent strips this
|
|
220
|
+
when composing the report. Demonstrates the 0 / 60 / 100 cadence. */
|
|
221
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
222
|
+
@keyframes m-placeholder {
|
|
223
|
+
0% { opacity: 0; transform: translateY(8px); filter: blur(4px); }
|
|
224
|
+
60% { opacity: 1; transform: translateY(0); filter: blur(0); }
|
|
225
|
+
100% { opacity: 1; transform: translateY(0); filter: blur(0); }
|
|
226
|
+
}
|
|
227
|
+
.demo-1__mt {
|
|
228
|
+
animation: m-placeholder 3s cubic-bezier(0.22, 1, 0.36, 1) infinite;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
</style>
|
|
232
|
+
</head>
|
|
233
|
+
<body>
|
|
234
|
+
|
|
235
|
+
<div class="demo">
|
|
236
|
+
<input class="vh" type="radio" name="st1" id="st1-a" checked>
|
|
237
|
+
<input class="vh" type="radio" name="st1" id="st1-l">
|
|
238
|
+
<input class="vh" type="radio" name="st1" id="st1-d">
|
|
239
|
+
<div class="demo__bar">
|
|
240
|
+
<div class="demo__meta">
|
|
241
|
+
<span class="demo__title">Recommended motion title</span>
|
|
242
|
+
<span class="demo__timing">300ms · ease-out</span>
|
|
243
|
+
</div>
|
|
244
|
+
<div class="demo__controls">
|
|
245
|
+
<div class="seg">
|
|
246
|
+
<label for="st1-a">Auto</label>
|
|
247
|
+
<label for="st1-l">Light</label>
|
|
248
|
+
<label for="st1-d">Dark</label>
|
|
249
|
+
</div>
|
|
250
|
+
<span class="demo__loop">↻</span>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
<div class="demo__stage">
|
|
254
|
+
<!-- DEMO-CARD-MOTION-SLOT-{n}
|
|
255
|
+
Per-finding motion-target element goes here. Its class must
|
|
256
|
+
match the rules in MOTION-CODE-SLOT-{n} above:
|
|
257
|
+
<div class="demo-{n}__mt">...content...</div>
|
|
258
|
+
The element's contents are agent-determined (a button shape,
|
|
259
|
+
a card, an icon, a row of items for stagger demos, a number,
|
|
260
|
+
a badge, etc.). All inner UI primitives use the stage tokens
|
|
261
|
+
(--st-fg / --st-bg / --st-line / --st-dim) — NEVER page tokens. -->
|
|
262
|
+
<div class="demo-1__mt">
|
|
263
|
+
<div class="ui-card">
|
|
264
|
+
<div class="ui-label" style="margin-bottom: 6px;">Placeholder</div>
|
|
265
|
+
<div class="ui-row">
|
|
266
|
+
<span class="ui-check"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5"><path d="M5 13l4 4L19 7"/></svg></span>
|
|
267
|
+
<span>(motion preview renders here per finding)</span>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
</body>
|
|
275
|
+
</html>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Emil Kowalski's Animation Principles
|
|
2
|
+
|
|
3
|
+
Emil Kowalski is a Design Engineer at Linear (previously Vercel). Creator of Sonner, Vaul, and the "Animations on the Web" course. His approach emphasizes **restraint, speed, and purposeful motion**.
|
|
4
|
+
|
|
5
|
+
This file is Emil's **philosophy and decision frameworks** — the judgment for *whether* and *when* to animate. Implementation code lives in `motion-cookbook.md` (cross-referenced below).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Philosophy: Restraint & Purpose
|
|
10
|
+
|
|
11
|
+
Emil's defining contribution to motion design thinking is knowing **when NOT to animate**.
|
|
12
|
+
|
|
13
|
+
> "The goal is not to animate for animation's sake, it's to build great user interfaces."
|
|
14
|
+
|
|
15
|
+
His key question for any interaction: **"Should this animate at all?"**
|
|
16
|
+
|
|
17
|
+
### The Frequency Rule
|
|
18
|
+
|
|
19
|
+
Animation appropriateness depends on interaction frequency:
|
|
20
|
+
|
|
21
|
+
| Frequency | Recommendation |
|
|
22
|
+
|-----------|----------------|
|
|
23
|
+
| Rare (monthly) | Delightful, morphing animations welcome |
|
|
24
|
+
| Occasional (daily) | Subtle, fast animations |
|
|
25
|
+
| Frequent (100s/day) | No animation or instant transitions |
|
|
26
|
+
| Keyboard-initiated | Never animate |
|
|
27
|
+
|
|
28
|
+
**The Raycast example**: A tool used constantly throughout the day benefits from zero animation. Users with clear goals "don't expect to be delighted" and prioritize frictionless workflow.
|
|
29
|
+
|
|
30
|
+
### Speed is Non-Negotiable
|
|
31
|
+
|
|
32
|
+
> "UI animations should generally stay under 300ms."
|
|
33
|
+
|
|
34
|
+
A 180ms animation feels more responsive than 400ms. Speed creates perceived performance. When in doubt, go faster.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## The 7 Practical Animation Tips
|
|
39
|
+
|
|
40
|
+
Emil's decision checklist. Code for each is in the cookbook section noted.
|
|
41
|
+
|
|
42
|
+
1. **Scale your buttons** — Subtle `scale(0.97)` on `:active` for immediate tactile feedback. → cookbook §10
|
|
43
|
+
2. **Don't animate from `scale(0)`** — It creates unnatural motion. Start from `scale(0.9)` or higher. → cookbook §10
|
|
44
|
+
3. **Tooltip delay patterns** — First tooltip in a group: delay + animation. Subsequent: instant. → cookbook §10
|
|
45
|
+
4. **Custom easing is essential** — *"Easing is the most important part of any animation. It can make a bad animation feel great."* Built-in `ease`/`ease-in-out` lack strength; use custom Bézier curves (easing.dev, easings.co). → cookbook §2
|
|
46
|
+
5. **Origin-aware animations** — Motion should originate from its logical source; a dropdown expands from its trigger, not from center. → cookbook §13
|
|
47
|
+
6. **Keep animations fast** — Under 300ms for UI; remove animation entirely for high-frequency interactions.
|
|
48
|
+
7. **Use blur when nothing else works** — `filter: blur(2px)` masks imperfections during rough state transitions. → cookbook §10
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Signature Techniques (decision context — code in cookbook)
|
|
53
|
+
|
|
54
|
+
| Technique | When Emil reaches for it | Cookbook |
|
|
55
|
+
|-----------|--------------------------|----------|
|
|
56
|
+
| Clip-path animations | Reveals and tab transitions — hardware-accelerated, no layout shift, no extra DOM | §9 |
|
|
57
|
+
| Spring physics | Any value that should interpolate smoothly rather than snap (e.g. mouse position) | §12 |
|
|
58
|
+
| CSS transitions over keyframes | Anything the user can rapidly re-trigger — keyframes can't retarget mid-flight | §11 |
|
|
59
|
+
| Direct style updates | Frequent updates like drag — CSS variables cause cascade recalculation | §11 |
|
|
60
|
+
| Momentum-based dismissal | Swipe-to-dismiss — use velocity, not distance thresholds | §11 |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Interruptibility
|
|
65
|
+
|
|
66
|
+
Great animations can be interrupted mid-play and respond naturally. Framer Motion supports this natively; CSS transitions allow smooth interruption before completion. **Test by clicking rapidly** — animations should blend, not queue.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## When to Use Each Approach
|
|
71
|
+
|
|
72
|
+
| Context | Approach |
|
|
73
|
+
|---------|----------|
|
|
74
|
+
| Keyboard shortcuts | No animation |
|
|
75
|
+
| High-frequency tool | Minimal or no animation |
|
|
76
|
+
| Daily-use feature | Fast, subtle animation (180-250ms) |
|
|
77
|
+
| Onboarding/first-time | Delightful animations welcome |
|
|
78
|
+
| Marketing/landing page | Full creative expression |
|
|
79
|
+
| Banking/serious UI | Minimal, functional motion |
|
|
80
|
+
| Playful brand | Bouncy, elastic easing appropriate |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Invisible Quality: Lessons from Sonner & Vaul
|
|
85
|
+
|
|
86
|
+
Emil's open-source libraries (Sonner for toasts, Vaul for drawers) reveal his philosophy in shipped code. The throughline: every detail serves **invisible quality** — users shouldn't notice polished interactions, they should just feel right.
|
|
87
|
+
|
|
88
|
+
> "When a feature functions as you assume it should, you proceed without giving it a second thought, which is our goal."
|
|
89
|
+
|
|
90
|
+
Details that matter: matching native motion curves for familiarity (Vaul uses iOS's `cubic-bezier(0.32, 0.72, 0, 1)`), damping near boundaries (*"things in real life don't suddenly stop, they slow down first"*), multi-touch protection, pointer capture during drags, pausing timers when the tab is inactive.
|
|
91
|
+
|
|
92
|
+
### Sonner Defaults
|
|
93
|
+
|
|
94
|
+
| Setting | Value | Rationale |
|
|
95
|
+
|---------|-------|-----------|
|
|
96
|
+
| Duration | 4000ms | Long enough to read, short enough to not annoy |
|
|
97
|
+
| Animation | 400ms ease | Smooth but snappy |
|
|
98
|
+
| Position | bottom-right | Convention, out of primary content |
|
|
99
|
+
| Dismissible | true | User control by default |
|
|
100
|
+
|
|
101
|
+
### Vaul Defaults
|
|
102
|
+
|
|
103
|
+
| Setting | Value | Rationale |
|
|
104
|
+
|---------|-------|-----------|
|
|
105
|
+
| Duration | 500ms | Match iOS sheet feel |
|
|
106
|
+
| Easing | cubic-bezier(0.32, 0.72, 0, 1) | iOS-native curve |
|
|
107
|
+
| Modal | true | Focus management, overlay |
|
|
108
|
+
| Direction | bottom | Convention for mobile sheets |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Emil vs. Jakub vs. Jhey
|
|
113
|
+
|
|
114
|
+
| Aspect | Emil | Jakub | Jhey |
|
|
115
|
+
|--------|------|-------|------|
|
|
116
|
+
| **Focus** | Restraint & speed | Subtle polish | Playful experimentation |
|
|
117
|
+
| **Key question** | "Should this animate?" | "Is this subtle enough?" | "What could this become?" |
|
|
118
|
+
| **Signature technique** | Frequency-based decisions | Blur + opacity + translateY | CSS custom properties |
|
|
119
|
+
| **Ideal context** | High-frequency tools | Production polish | Learning & exploration |
|
|
120
|
+
|
|
121
|
+
**Synthesis**: Use Emil's framework to decide IF you should animate. Use Jakub's techniques for HOW to animate in production. Use Jhey's approach for learning and experimentation.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Jakub Krehel's Animation Principles
|
|
2
|
+
|
|
3
|
+
Jakub Krehel is a design engineer known for his work at jakub.kr. His approach emphasizes **subtle production polish** — animations that enhance the experience invisibly, designed for real client work where users interact repeatedly.
|
|
4
|
+
|
|
5
|
+
This file is Jakub's **philosophy and decision frameworks** — the judgment for *how polished* and *how subtle* motion should be. Implementation code lives in `motion-cookbook.md` (cross-referenced below).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Philosophy: Invisible Enhancement
|
|
10
|
+
|
|
11
|
+
> "The best animation is that which goes unnoticed."
|
|
12
|
+
|
|
13
|
+
His key question for any interaction: **"Is this subtle and polished enough for production?"**
|
|
14
|
+
|
|
15
|
+
Jakub's work embodies **refinement for production use**. His animations are:
|
|
16
|
+
|
|
17
|
+
- **Barely noticeable** — If users consciously notice the animation, it's probably too much
|
|
18
|
+
- **Production-ready** — Designed for real client work, not demos
|
|
19
|
+
- **Contextually appropriate** — Adapts to light mode, varied backgrounds, real content
|
|
20
|
+
- **Subtle over flashy** — The goal is to make interfaces feel smooth and responsive, not impressive
|
|
21
|
+
|
|
22
|
+
**The best compliment**: "This feels really nice" — not "cool animation!"
|
|
23
|
+
|
|
24
|
+
**The test**: If you remove the animation, do users feel something is missing? Good. If users comment "nice animation!" every time they see it? Too prominent.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## When to Apply Jakub's Mindset
|
|
29
|
+
|
|
30
|
+
- Production applications and client work
|
|
31
|
+
- Professional/enterprise interfaces
|
|
32
|
+
- When users will interact repeatedly (animations must not get tiresome)
|
|
33
|
+
- When accessibility and performance are critical
|
|
34
|
+
- When you need polish without distraction
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Signature Techniques (decision context — code in cookbook)
|
|
39
|
+
|
|
40
|
+
| Technique | When Jakub reaches for it | Cookbook |
|
|
41
|
+
|-----------|---------------------------|----------|
|
|
42
|
+
| Enter recipe (opacity + translateY + blur) | Any element appearing — blur creates a "materializing" feel more physical than fade alone | §1 |
|
|
43
|
+
| Subtler exits | Always — exits don't need the same movement or attention as enters; the user is moving on | §1 |
|
|
44
|
+
| Spring animations (`bounce: 0`) | Production motion — smooth deceleration without overshoot; reserve `bounce > 0` for playful contexts | §2 |
|
|
45
|
+
| Shadows instead of borders | Light mode on varied backgrounds — shadows adapt via transparency where solid borders clash | §3 |
|
|
46
|
+
| oklch gradients | Any gradient — interpolates through perceptually uniform space, avoiding muddy midpoints | §3 |
|
|
47
|
+
| Blur as a signal | Materializing in/out — blur→sharp = entering focus, sharp→blur = losing relevance | §3 |
|
|
48
|
+
| Optical alignment | Buttons with icons, play buttons, asymmetric shapes — trust your eyes over math | §4 |
|
|
49
|
+
| Animated icon swaps (opacity + scale + blur) | Contextual icon changes (copy→check) — instant swaps feel jarring and get missed | §5 |
|
|
50
|
+
| Shared layout via `layoutId` | Smooth FLIP transitions between different components (card→modal) | §6 |
|
|
51
|
+
| Targeted `will-change` | Specific properties about to animate — never global | see `performance.md` |
|
|
52
|
+
|
|
53
|
+
**Decision rules baked into the techniques:**
|
|
54
|
+
- Exits should always be subtler than enters — smaller movement, same blur.
|
|
55
|
+
- `bounce: 0` is the production default; bounce above zero reads as playful.
|
|
56
|
+
- Borders are fine in dark mode or when you want intentional hard edges.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Common Mistakes (Jakub's Perspective)
|
|
61
|
+
|
|
62
|
+
- **Making enter and exit animations equally prominent** — Exits should be subtler
|
|
63
|
+
- **Using solid borders when shadows would adapt better** — Especially on varied backgrounds
|
|
64
|
+
- **Forgetting optical alignment** — Buttons with icons, play buttons, asymmetric shapes
|
|
65
|
+
- **Over-animating** — If users notice the animation itself, it's too much
|
|
66
|
+
- **Using the same animation everywhere** — Context should drive timing and easing choices
|
|
67
|
+
- **Ignoring hover state transitions** — Even small transitions (150-200ms) feel more polished than instant changes
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Jakub vs. Emil vs. Jhey
|
|
72
|
+
|
|
73
|
+
| Aspect | Jakub | Emil | Jhey |
|
|
74
|
+
|--------|-------|------|------|
|
|
75
|
+
| **Focus** | Subtle polish | Restraint & speed | Playful experimentation |
|
|
76
|
+
| **Key question** | "Is this subtle enough?" | "Should this animate?" | "What could this become?" |
|
|
77
|
+
| **Signature technique** | Blur + opacity + translateY | Frequency-based decisions | CSS custom properties |
|
|
78
|
+
| **Ideal context** | Production polish | High-frequency tools | Learning & exploration |
|
|
79
|
+
|
|
80
|
+
**When to use Jakub**: You've decided something should animate (passed Emil's gate) and need to make it production-ready and polished.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Jhey Tompkins' Animation Principles
|
|
2
|
+
|
|
3
|
+
Jhey Tompkins (@jh3yy) is a design engineer known for pushing the boundaries of CSS and creative coding. His approach emphasizes **playful experimentation** — learning through building whimsical projects where the joy of creation drives skill development.
|
|
4
|
+
|
|
5
|
+
This file is Jhey's **philosophy and decision frameworks** — the judgment for *creative expression* and *easing personality*. Implementation code lives in `motion-cookbook.md` (cross-referenced below).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Core Philosophy: Learn Through Play
|
|
10
|
+
|
|
11
|
+
> "I went from 'I want to learn X, so how do I fit it into Y' to 'I want to make Y, can I learn X to do it?'"
|
|
12
|
+
|
|
13
|
+
His key question for any interaction: **"What could this become?"**
|
|
14
|
+
|
|
15
|
+
**The motivation should be making something cool — learning is a happy side effect.**
|
|
16
|
+
|
|
17
|
+
### Core Beliefs
|
|
18
|
+
|
|
19
|
+
- **No idea is a bad idea** — Document every spark, however weird
|
|
20
|
+
- **Don't ask "Why?" or "Is this practical?"** — Make what brings you joy first
|
|
21
|
+
- **"Useless" demos teach real skills** — CSS art teaches clip-path mastery, border-radius tricks, stacking contexts
|
|
22
|
+
- **Lateral learning** — Building diverse demos trains you to switch contexts and rise to challenges
|
|
23
|
+
- **You'll never have time to make everything** — And that's okay. The act of documenting ideas matters.
|
|
24
|
+
|
|
25
|
+
**Keep notebooks everywhere** — including by your bed. Creative sparks happen at random times.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## When to Apply Jhey's Mindset
|
|
30
|
+
|
|
31
|
+
- Creative sites, portfolios, kids apps — contexts where delight is the point
|
|
32
|
+
- Learning new techniques
|
|
33
|
+
- Personal projects and experiments
|
|
34
|
+
- When you're stuck in a creative rut
|
|
35
|
+
- Exploring what's possible with new CSS features
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## The Golden Rule (Even in Play)
|
|
40
|
+
|
|
41
|
+
> "The best animation is that which goes unnoticed."
|
|
42
|
+
|
|
43
|
+
Even in playful contexts, effective motion enhances the experience without demanding attention, feels natural and expected, serves a functional purpose, and doesn't fatigue users on repeated interactions.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Easing Has Personality (Decision Framework)
|
|
48
|
+
|
|
49
|
+
> "Duration is all about timing, and timing has a big impact on the movement's naturalness."
|
|
50
|
+
|
|
51
|
+
Each easing curve communicates something. **Context matters more than rules.**
|
|
52
|
+
|
|
53
|
+
> "You wouldn't use 'Elastic' for a bank's website, but it might work perfectly for an energetic site for children."
|
|
54
|
+
|
|
55
|
+
Brand personality should drive easing choices — a playful brand can use bouncy/elastic easing, a professional brand should use subtle springs or `ease-out`.
|
|
56
|
+
|
|
57
|
+
**When NOT to use bouncy/elastic easing:**
|
|
58
|
+
- Professional/enterprise applications
|
|
59
|
+
- Frequently repeated interactions (gets tiresome)
|
|
60
|
+
- Error states or serious UI
|
|
61
|
+
- When users need to complete tasks quickly
|
|
62
|
+
|
|
63
|
+
(Easing-feel reference table and the `linear()` recipe for pure-CSS bounce/elastic/spring → cookbook §2.)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Signature Techniques (decision context — code in cookbook)
|
|
68
|
+
|
|
69
|
+
| Technique | When Jhey reaches for it | Cookbook |
|
|
70
|
+
|-----------|--------------------------|----------|
|
|
71
|
+
| `linear()` function | Pure-CSS bounce, elastic, spring effects without JS | §2 |
|
|
72
|
+
| `@property` | Animating CSS custom properties — type declaration unlocks interpolation | §7 |
|
|
73
|
+
| Decomposed transforms | Curved motion paths impossible with a monolithic transform | §7 |
|
|
74
|
+
| `animation-fill-mode` | Delayed fade-in sequences — `backwards` prevents the pre-animation flash | §1 |
|
|
75
|
+
| Negative delays | "Already in progress" stagger effects | §2 |
|
|
76
|
+
| Scoped CSS variables | Varied behavior from a single animation definition | §7 |
|
|
77
|
+
| 3D CSS ("think in cubes") | Decompose 3D objects into cuboids; `preserve-3d` + `perspective` | §8 |
|
|
78
|
+
| Scroll-driven with duration | Decouple animation timing from scroll speed | §14 |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Why "Useless" CSS Art Matters
|
|
83
|
+
|
|
84
|
+
CSS art teaches real skills that transfer to production: clip-path mastery, border-radius tricks, stacking contexts, complex gradients, pseudo-element layering. For complex illustrations — break into simple shapes, use pseudo-elements liberally, layer with z-index carefully, use CSS variables for repeated values, don't fear many elements.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## When to Experiment vs. Ship
|
|
89
|
+
|
|
90
|
+
| Situation | Approach |
|
|
91
|
+
|-----------|----------|
|
|
92
|
+
| Learning a new CSS feature | Build something weird and fun |
|
|
93
|
+
| Portfolio piece | Push boundaries, show creativity |
|
|
94
|
+
| Personal project | Follow your joy |
|
|
95
|
+
| Client work | Apply Jakub's production polish instead |
|
|
96
|
+
| High-frequency tool | Apply Emil's restraint instead |
|
|
97
|
+
|
|
98
|
+
The playful approach is for **learning and exploration**. For production, switch to Jakub or Emil's mindset.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Common Mistakes (Jhey's Perspective)
|
|
103
|
+
|
|
104
|
+
- **Filtering ideas based on "usefulness" too early** — Make first, judge later
|
|
105
|
+
- **Not documenting random creative sparks** — Keep notebooks everywhere
|
|
106
|
+
- **Thinking CSS art is useless** — It teaches real skills
|
|
107
|
+
- **Focusing on "How do I learn X?" instead of "How do I make Y?"** — Let ideas drive learning
|
|
108
|
+
- **Following tutorials without experimenting** — Tutorials teach techniques; experimentation teaches problem-solving
|
|
109
|
+
- **Giving up when something doesn't work** — The struggle is where learning happens
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Jhey vs. Emil vs. Jakub
|
|
114
|
+
|
|
115
|
+
| Aspect | Jhey | Emil | Jakub |
|
|
116
|
+
|--------|------|------|-------|
|
|
117
|
+
| **Focus** | Playful experimentation | Restraint & speed | Subtle polish |
|
|
118
|
+
| **Key question** | "What could this become?" | "Should this animate?" | "Is this subtle enough?" |
|
|
119
|
+
| **Signature technique** | CSS custom properties | Frequency-based decisions | Blur + opacity + translateY |
|
|
120
|
+
| **Ideal context** | Learning & exploration | High-frequency tools | Production polish |
|
|
121
|
+
|
|
122
|
+
**When to use Jhey**: You're building something where delight is the goal, exploring what's possible, or learning a new technique. The skills transfer to production work later.
|