@nurix/etna 0.19.66 → 0.19.68
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/bin/etna.js +10 -1
- package/data/harness-index.json +1 -5
- package/data/harnesses/code/CLAUDE.md +2 -0
- package/data/harnesses/code/agents/maintenance.md +4 -1
- package/data/harnesses/code/harness.json +7 -2
- package/data/harnesses/code/hooks/awareness.mjs +69 -0
- package/data/harnesses/code/hooks/compliance.mjs +2 -14
- package/data/harnesses/code/hooks/lib/approved.mjs +30 -0
- package/data/harnesses/code/hooks/lib/frozen.mjs +3 -0
- package/data/harnesses/code/hooks/lib/ownership.mjs +3 -1
- package/data/harnesses/code/skills/documentation/references/frontmatter.md +1 -1
- package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/code/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/code/skills/documentation/templates/structure.md +1 -0
- package/data/harnesses/delivery/agents/maintenance.md +4 -1
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +1 -1
- package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/delivery/skills/documentation/templates/structure.md +1 -0
- package/data/harnesses/etna/agents/maintenance.md +4 -1
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/documentation/references/frontmatter.md +1 -1
- package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/etna/skills/documentation/templates/Readme.md +2 -0
- package/data/harnesses/etna/skills/documentation/templates/structure.md +1 -0
- package/lib/install/materialize.mjs +51 -57
- package/package.json +2 -2
- package/data/harnesses/apollo/.mcp.json +0 -8
- package/data/harnesses/apollo/.prettierignore +0 -29
- package/data/harnesses/apollo/.prettierrc.json +0 -3
- package/data/harnesses/apollo/.vscode/settings.json +0 -19
- package/data/harnesses/apollo/CLAUDE.md +0 -162
- package/data/harnesses/apollo/agents/bookkeeper.md +0 -28
- package/data/harnesses/apollo/agents/brainstorm.md +0 -144
- package/data/harnesses/apollo/agents/change-review.md +0 -251
- package/data/harnesses/apollo/agents/lld-mode.md +0 -58
- package/data/harnesses/apollo/agents/maintenance.md +0 -234
- package/data/harnesses/apollo/agents/performance-review.md +0 -223
- package/data/harnesses/apollo/agents/retro.md +0 -46
- package/data/harnesses/apollo/codex/agents/bookkeeper.toml +0 -26
- package/data/harnesses/apollo/codex/agents/brainstorm.toml +0 -142
- package/data/harnesses/apollo/codex/agents/change-review.toml +0 -249
- package/data/harnesses/apollo/codex/agents/lld-mode.toml +0 -52
- package/data/harnesses/apollo/codex/agents/maintenance.toml +0 -228
- package/data/harnesses/apollo/codex/agents/performance-review.toml +0 -222
- package/data/harnesses/apollo/codex/agents/retro.toml +0 -45
- package/data/harnesses/apollo/harness.json +0 -19
- package/data/harnesses/apollo/hooks/approved-packages.md +0 -44
- package/data/harnesses/apollo/hooks/awareness.mjs +0 -405
- package/data/harnesses/apollo/hooks/check-bookkeeping-clean.mjs +0 -19
- package/data/harnesses/apollo/hooks/check-changelog-presence.mjs +0 -57
- package/data/harnesses/apollo/hooks/check-completion-integrity.mjs +0 -71
- package/data/harnesses/apollo/hooks/check-ownership.mjs +0 -22
- package/data/harnesses/apollo/hooks/compliance.mjs +0 -457
- package/data/harnesses/apollo/hooks/hooks.json +0 -23
- package/data/harnesses/apollo/hooks/lib/frozen.mjs +0 -58
- package/data/harnesses/apollo/hooks/lib/ownership.mjs +0 -242
- package/data/harnesses/apollo/hooks/lib/state.mjs +0 -170
- package/data/harnesses/apollo/rules/changelog.md +0 -27
- package/data/harnesses/apollo/rules/database.md +0 -34
- package/data/harnesses/apollo/rules/frontend.md +0 -30
- package/data/harnesses/apollo/rules/general.md +0 -40
- package/data/harnesses/apollo/rules/nomenclature.md +0 -30
- package/data/harnesses/apollo/rules/pnpm.md +0 -57
- package/data/harnesses/apollo/rules/testing.md +0 -64
- package/data/harnesses/apollo/skills/boundary/SKILL.md +0 -75
- package/data/harnesses/apollo/skills/boundary/references/index.md +0 -16
- package/data/harnesses/apollo/skills/boundary/references/mechanisms.md +0 -99
- package/data/harnesses/apollo/skills/boundary/references/packs/async-messaging.md +0 -81
- package/data/harnesses/apollo/skills/boundary/references/packs/auth.md +0 -93
- package/data/harnesses/apollo/skills/boundary/references/packs/build-config-runtime.md +0 -93
- package/data/harnesses/apollo/skills/boundary/references/packs/cloudflare.md +0 -93
- package/data/harnesses/apollo/skills/boundary/references/packs/frontend.md +0 -93
- package/data/harnesses/apollo/skills/boundary/references/packs/generic-tail.md +0 -55
- package/data/harnesses/apollo/skills/boundary/references/packs/persistence.md +0 -93
- package/data/harnesses/apollo/skills/boundary/references/packs/wire-api.md +0 -87
- package/data/harnesses/apollo/skills/brainstorm/README.md +0 -56
- package/data/harnesses/apollo/skills/brainstorm/SKILL.md +0 -173
- package/data/harnesses/apollo/skills/brainstorm/references/doctrine.md +0 -98
- package/data/harnesses/apollo/skills/brainstorm/references/harvest.md +0 -86
- package/data/harnesses/apollo/skills/brainstorm/references/session-schema.md +0 -186
- package/data/harnesses/apollo/skills/brainstorm/scripts/detector.mjs +0 -460
- package/data/harnesses/apollo/skills/design/SKILL.md +0 -121
- package/data/harnesses/apollo/skills/design/components/charts.md +0 -76
- package/data/harnesses/apollo/skills/design/components/collections.md +0 -132
- package/data/harnesses/apollo/skills/design/components/feedback.md +0 -47
- package/data/harnesses/apollo/skills/design/components/hooks.md +0 -35
- package/data/harnesses/apollo/skills/design/components/index.md +0 -143
- package/data/harnesses/apollo/skills/design/components/inputs.md +0 -327
- package/data/harnesses/apollo/skills/design/components/layout.md +0 -52
- package/data/harnesses/apollo/skills/design/components/media.md +0 -66
- package/data/harnesses/apollo/skills/design/components/motion.md +0 -82
- package/data/harnesses/apollo/skills/design/components/navigation.md +0 -29
- package/data/harnesses/apollo/skills/design/components/overlays.md +0 -72
- package/data/harnesses/apollo/skills/design/components/setup.md +0 -40
- package/data/harnesses/apollo/skills/design/components/typography.md +0 -46
- package/data/harnesses/apollo/skills/design/components/utils.md +0 -37
- package/data/harnesses/apollo/skills/design/data/blueprints/browse.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/creation-flow.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/dashboard.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/grid.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/queue.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/record-detail.md +0 -38
- package/data/harnesses/apollo/skills/design/data/blueprints/settings.md +0 -38
- package/data/harnesses/apollo/skills/design/data/charts/census.csv +0 -58
- package/data/harnesses/apollo/skills/design/data/checklists/browse.md +0 -21
- package/data/harnesses/apollo/skills/design/data/checklists/creation-flow.md +0 -20
- package/data/harnesses/apollo/skills/design/data/checklists/dashboard.md +0 -21
- package/data/harnesses/apollo/skills/design/data/checklists/grid.md +0 -21
- package/data/harnesses/apollo/skills/design/data/checklists/queue.md +0 -21
- package/data/harnesses/apollo/skills/design/data/checklists/record-detail.md +0 -21
- package/data/harnesses/apollo/skills/design/data/checklists/settings.md +0 -21
- package/data/harnesses/apollo/skills/design/data/chrome/board-column.md +0 -68
- package/data/harnesses/apollo/skills/design/data/chrome/data-table.md +0 -63
- package/data/harnesses/apollo/skills/design/data/chrome/side-panel.md +0 -60
- package/data/harnesses/apollo/skills/design/data/chrome/sidebar.md +0 -78
- package/data/harnesses/apollo/skills/design/data/chrome/stat-cards.md +0 -62
- package/data/harnesses/apollo/skills/design/data/chrome/topbar.md +0 -65
- package/data/harnesses/apollo/skills/design/data/elevation/ant-design-directional-shadow.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/apple-liquid-glass-material.md +0 -18
- package/data/harnesses/apollo/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +0 -20
- package/data/harnesses/apollo/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +0 -20
- package/data/harnesses/apollo/skills/design/data/elevation/github-primer-sparing-shadow.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/ibm-carbon-layer-and-border.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/linear-dark-surface-ladder.md +0 -17
- package/data/harnesses/apollo/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/material-3-tonal-elevation.md +0 -21
- package/data/harnesses/apollo/skills/design/data/elevation/neobrutalist-hard-offset.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +0 -18
- package/data/harnesses/apollo/skills/design/data/elevation/notion-warm-minimal-hairline.md +0 -17
- package/data/harnesses/apollo/skills/design/data/elevation/polaris-elevation-inset-bevel.md +0 -21
- package/data/harnesses/apollo/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/shadcn-neutral-derived-radius.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +0 -18
- package/data/harnesses/apollo/skills/design/data/elevation/tailwind-default-utility-scale.md +0 -19
- package/data/harnesses/apollo/skills/design/data/elevation/vercel-geist-shadow-as-border.md +0 -20
- package/data/harnesses/apollo/skills/design/data/iconography.md +0 -199
- package/data/harnesses/apollo/skills/design/data/motion/accordion-expand.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/destructive-hold-confirm.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/drag-dismiss-momentum.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/empty-state-arrive.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/hover-lift.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/modal-center-arrive.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/number-ticker-roll.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/onboarding-bounce.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/panel-slide.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/press-feedback.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/progress-linear-loop.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/route-crossfade.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/rubber-band-overscroll.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/skeleton-shimmer.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/stagger-arrive.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/toast-enter-stack.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/tooltip-chain-instant.md +0 -18
- package/data/harnesses/apollo/skills/design/data/motion/trigger-anchored-reveal.md +0 -18
- package/data/harnesses/apollo/skills/design/data/tells.csv +0 -34
- package/data/harnesses/apollo/skills/design/data/voices/bright-collaborator.md +0 -29
- package/data/harnesses/apollo/skills/design/data/voices/direct-operator.md +0 -29
- package/data/harnesses/apollo/skills/design/data/voices/earnest-helper.md +0 -29
- package/data/harnesses/apollo/skills/design/data/voices/editorial-composed.md +0 -29
- package/data/harnesses/apollo/skills/design/data/voices/quiet-concierge.md +0 -29
- package/data/harnesses/apollo/skills/design/data/voices/warm-guide.md +0 -29
- package/data/harnesses/apollo/skills/design/references/compose.md +0 -23
- package/data/harnesses/apollo/skills/design/references/content.md +0 -28
- package/data/harnesses/apollo/skills/design/references/emission.md +0 -21
- package/data/harnesses/apollo/skills/design/references/existing-apps.md +0 -27
- package/data/harnesses/apollo/skills/design/references/foundations.md +0 -57
- package/data/harnesses/apollo/skills/design/references/intake.md +0 -40
- package/data/harnesses/apollo/skills/design/references/object-pass.md +0 -24
- package/data/harnesses/apollo/skills/design/references/ship-gate.md +0 -29
- package/data/harnesses/apollo/skills/design/references/ux-patterns/Readme.md +0 -195
- package/data/harnesses/apollo/skills/design/references/ux-patterns/ai-layer.md +0 -49
- package/data/harnesses/apollo/skills/design/references/ux-patterns/attributes-lifecycle.md +0 -43
- package/data/harnesses/apollo/skills/design/references/ux-patterns/container-choice.md +0 -44
- package/data/harnesses/apollo/skills/design/references/ux-patterns/creation-paths.md +0 -46
- package/data/harnesses/apollo/skills/design/references/ux-patterns/dashboards.md +0 -42
- package/data/harnesses/apollo/skills/design/references/ux-patterns/modes.md +0 -42
- package/data/harnesses/apollo/skills/design/references/ux-patterns/object-model.md +0 -46
- package/data/harnesses/apollo/skills/design/references/ux-patterns/page-archetype.md +0 -48
- package/data/harnesses/apollo/skills/design/references/ux-patterns/promotion-demotion.md +0 -37
- package/data/harnesses/apollo/skills/design/references/ux-patterns/settings.md +0 -42
- package/data/harnesses/apollo/skills/design/references/ux-patterns/standard-pages.md +0 -46
- package/data/harnesses/apollo/skills/design/references/ux-patterns/state-matrix.md +0 -41
- package/data/harnesses/apollo/skills/design/references/ux-patterns/table-mechanics.md +0 -48
- package/data/harnesses/apollo/skills/design/references/ux-patterns/verbs.md +0 -45
- package/data/harnesses/apollo/skills/design/references/ux-patterns/viewer-context.md +0 -40
- package/data/harnesses/apollo/skills/design/scripts/README-validator.md +0 -27
- package/data/harnesses/apollo/skills/design/scripts/select-chart.mjs +0 -622
- package/data/harnesses/apollo/skills/design/scripts/validate-design-md.mjs +0 -1198
- package/data/harnesses/apollo/skills/documentation/SKILL.md +0 -135
- package/data/harnesses/apollo/skills/documentation/references/examples.md +0 -279
- package/data/harnesses/apollo/skills/documentation/references/frontmatter.md +0 -44
- package/data/harnesses/apollo/skills/documentation/references/instruction-style.md +0 -50
- package/data/harnesses/apollo/skills/documentation/references/style-guide.md +0 -384
- package/data/harnesses/apollo/skills/documentation/references/untemplated.md +0 -38
- package/data/harnesses/apollo/skills/documentation/scripts/doc-lint.mjs +0 -140
- package/data/harnesses/apollo/skills/documentation/templates/Readme.md +0 -35
- package/data/harnesses/apollo/skills/documentation/templates/api-reference.md +0 -20
- package/data/harnesses/apollo/skills/documentation/templates/architecture-decision.md +0 -121
- package/data/harnesses/apollo/skills/documentation/templates/backlog.md +0 -33
- package/data/harnesses/apollo/skills/documentation/templates/behavioral-checklist.md +0 -81
- package/data/harnesses/apollo/skills/documentation/templates/bookkeeping.md +0 -18
- package/data/harnesses/apollo/skills/documentation/templates/changelog-entry.md +0 -57
- package/data/harnesses/apollo/skills/documentation/templates/changelog-index.md +0 -41
- package/data/harnesses/apollo/skills/documentation/templates/docs-readme.md +0 -72
- package/data/harnesses/apollo/skills/documentation/templates/domain-model.md +0 -30
- package/data/harnesses/apollo/skills/documentation/templates/environment-registry.md +0 -15
- package/data/harnesses/apollo/skills/documentation/templates/feature.md +0 -150
- package/data/harnesses/apollo/skills/documentation/templates/glossary.md +0 -11
- package/data/harnesses/apollo/skills/documentation/templates/implementation-map.md +0 -42
- package/data/harnesses/apollo/skills/documentation/templates/journal.md +0 -13
- package/data/harnesses/apollo/skills/documentation/templates/memory-main.md +0 -25
- package/data/harnesses/apollo/skills/documentation/templates/migration-runbook.md +0 -34
- package/data/harnesses/apollo/skills/documentation/templates/non-goals.md +0 -11
- package/data/harnesses/apollo/skills/documentation/templates/operations-procedure.md +0 -36
- package/data/harnesses/apollo/skills/documentation/templates/plan.md +0 -88
- package/data/harnesses/apollo/skills/documentation/templates/protected-files.md +0 -37
- package/data/harnesses/apollo/skills/documentation/templates/root-readme.md +0 -104
- package/data/harnesses/apollo/skills/documentation/templates/security-overview.md +0 -27
- package/data/harnesses/apollo/skills/documentation/templates/structure.md +0 -65
- package/data/harnesses/apollo/skills/documentation/templates/system-overview.md +0 -32
- package/data/harnesses/apollo/skills/documentation/templates/testing-strategy.md +0 -29
- package/data/harnesses/apollo/skills/schema-design/SKILL.md +0 -141
- package/data/harnesses/apollo/skills/test/SKILL.md +0 -104
- package/data/harnesses/apollo/skills/testing/SKILL.md +0 -166
- package/data/harnesses/apollo/skills/workflow-mapper/SKILL.md +0 -451
- package/data/harnesses/apollo/skills/workflow-mapper/references/patterns.md +0 -214
- /package/data/harnesses/{apollo → code}/docs/README.md +0 -0
- /package/data/harnesses/{apollo → code}/docs/history/CHANGELOG.md +0 -0
- /package/data/harnesses/{apollo → code}/docs/history/backlog.md +0 -0
- /package/data/harnesses/{apollo → code}/docs/memory/main.md +0 -0
- /package/data/harnesses/{apollo → code}/docs/structure.md +0 -0
- /package/data/harnesses/{apollo → code}/rules/cloudflare.md +0 -0
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: material-3-tonal-elevation
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from m3.material.io/styles/elevation/tokens; shadow figures approximate Material Web's published elevation-level tokens"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "quiet tech-forward calm; depth reads as a warm color shift more than a cast shadow, corners softly rounded"
|
|
8
|
-
---
|
|
9
|
-
Material 3's headline move: elevation is expressed primarily through **tonal surface tint** (a translucent overlay of the primary brand color, stronger at higher levels) with a thin shadow underneath as a secondary cue. No borders — surfaces separate by tone, not line. Best where a single brand hue should visibly "light up" whatever floats highest.
|
|
10
|
-
|
|
11
|
-
Approximation note: shadow figures approximate Material Web's published elevation-level tokens — check exact rgba/opacity figures against the live source before shipping.
|
|
12
|
-
|
|
13
|
-
```yaml values
|
|
14
|
-
radius: { sm: 8, md: 12, lg: 16 }
|
|
15
|
-
hairline: none
|
|
16
|
-
shadow:
|
|
17
|
-
level1: "0px 1px 2px rgba(0,0,0,0.30), 0px 1px 3px 1px rgba(0,0,0,0.15) + {primary-hue tint / ~5% overlay}"
|
|
18
|
-
level2: "0px 1px 2px rgba(0,0,0,0.30), 0px 2px 6px 2px rgba(0,0,0,0.15) + {primary-hue tint / ~8% overlay}"
|
|
19
|
-
level3: "0px 4px 8px 3px rgba(0,0,0,0.15), 0px 1px 3px rgba(0,0,0,0.30) + {primary-hue tint / ~11% overlay}"
|
|
20
|
-
dark-ladder: { step: "+~3% primary-tint per level (approx 5/8/11/12/14%)", hue: drift }
|
|
21
|
-
```
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: neobrutalist-hard-offset
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from neubrutalism.com and community neobrutalism CSS references (community pattern, no single owning org)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "loud, tactile, intentionally raw; a solid offset shadow with zero blur reads as a physical card lifted straight off the page"
|
|
8
|
-
---
|
|
9
|
-
Neobrutalism inverts the entire elevation vocabulary: no blur, ever. A thick (3–4px) solid black border plus a flat, hard-edged offset shadow in pure black (or a bold flat color) does all the depth work — the shadow is a solid silhouette displaced down-right, not a soft cast. Radius stays at or near zero to keep the "raw" read.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 0, md: 0, lg: 4 }
|
|
13
|
-
hairline: "not a hairline — a 3-4px solid black border replaces the border/shadow distinction entirely"
|
|
14
|
-
shadow:
|
|
15
|
-
sm: "4px 4px 0px #000000"
|
|
16
|
-
md: "6px 6px 0px #000000"
|
|
17
|
-
lg: "8px 8px 0px #000000"
|
|
18
|
-
dark-ladder: { step: "n/a — most kits binary-invert black/white rather than laddering surfaces", hue: held }
|
|
19
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: neumorphic-soft-dual-shadow
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from neumorphism.io and community soft-UI CSS references (community pattern, no single owning org)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "soft, extruded, monochrome; elements look pressed into or popped out of a background that shares their exact color"
|
|
8
|
-
---
|
|
9
|
-
Neumorphism fakes physical extrusion with a **paired light+dark shadow** on an element whose background exactly matches its parent's — no border, no color contrast, only two offset shadows (one lighter, one darker than the shared base) doing all the modeling. Pressed/inset states simply invert the pair. Contrast-fragile by construction: raising shadow strength enough to pass accessibility checks destroys the soft illusion that is the entire point.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 12, md: 16, lg: 24 }
|
|
13
|
-
hairline: "none — a drawn border would break the illusion; edges exist only via the shadow pair"
|
|
14
|
-
shadow:
|
|
15
|
-
raised: "10px 10px 20px #bebebe, -10px -10px 20px #ffffff"
|
|
16
|
-
pressed: "inset 6px 6px 12px #bebebe, inset -6px -6px 12px #ffffff"
|
|
17
|
-
dark-ladder: { step: "n/a — dark variant is a manual per-surface retune (e.g. base #2d3239, shadows #23272d / #373d46), not a formula", hue: held }
|
|
18
|
-
```
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: notion-warm-minimal-hairline
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from github.com/VoltAgent/awesome-design-md — notion/DESIGN.md"
|
|
6
|
-
license: reference-only
|
|
7
|
-
feel: "warm, paper-like minimalism; content over chrome, separation is almost always a thin line rather than a cast shadow"
|
|
8
|
-
---
|
|
9
|
-
Notion's house rule is explicit: don't apply heavy shadows on flat documentation cards. Separation is carried almost entirely by a single hairline border token reused across nav, cards, and containers; the rare exception is a very soft lift on preview/mockup cards, kept subtle enough not to compete with content.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 4, md: 6, lg: 10 }
|
|
13
|
-
hairline: "1px solid {colors.hairline} #EDEEEC — the default separator for nav, cards, and containers; heavy shadows explicitly avoided"
|
|
14
|
-
shadow:
|
|
15
|
-
rare-lift: "used sparingly, only on mockup/preview cards — e.g. 0 4px 16px rgba(0,0,0,.06)"
|
|
16
|
-
dark-ladder: { step: "+~2-3L per level (approx #191919 → #202020 → #2f2f2f surfaces)", hue: held }
|
|
17
|
-
```
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: polaris-elevation-inset-bevel
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from polaris-react.shopify.com/design/depth/shadow-tokens; radius px approximated, exact figures not published in source"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "commerce-admin friendly; raised surfaces read as physically thick, machined edges rather than flat cards floated on a shadow"
|
|
8
|
-
---
|
|
9
|
-
Polaris splits shadow into three distinct token families used in combination: elevation (the classic cast drop-shadow), inset (an embedded/pressed look), and bevel (a thin inner highlight+shadow edge that gives a raised surface the sense of physical thickness). Combining bevel with elevation is the house move for "this is a real, liftable object."
|
|
10
|
-
|
|
11
|
-
Approximation note: radius px approximated — exact figures are not published in the source and should be checked before shipping.
|
|
12
|
-
|
|
13
|
-
```yaml values
|
|
14
|
-
radius: { sm: 4, md: 8, lg: 12 }
|
|
15
|
-
hairline: "implicit — bevel-100 supplies a 1px inner highlight/shadow edge in place of a plain border"
|
|
16
|
-
shadow:
|
|
17
|
-
elevation-100: "cast shadow, lightest — resting cards"
|
|
18
|
-
elevation-300: "cast shadow, medium — popovers and overlays"
|
|
19
|
-
bevel-100: "inset highlight + inset shadow — thick machined edge on raised surfaces"
|
|
20
|
-
dark-ladder: { step: "n/a — Shopify admin ships no official dark theme", hue: held }
|
|
21
|
-
```
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: radix-themes-alpha-ring-scale
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from radix-ui.com/themes/docs/theme/shadows, /radius, and the shadow.css token source"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "quiet, correct, slightly clinical; a 6-step alpha ramp any accent color can flow through without redoing the shadows"
|
|
8
|
-
---
|
|
9
|
-
Radix builds its shadow ramp entirely from **gray-alpha and black-alpha overlays** rather than fixed opaque colors, so the same six shadow steps stay correct across every accent and every light/dark theme automatically. `shadow-1` is an inset ring that doubles as the hairline for flush, level-0 surfaces.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 4, md: 8, lg: 12 }
|
|
13
|
-
hairline: "shadow-1 — inset 0 0 0 1px var(--gray-a5), inset 0 1.5px 2px var(--gray-a2)/var(--black-a2)"
|
|
14
|
-
shadow:
|
|
15
|
-
shadow-2: "0 0 0 1px var(--gray-a3), 0 0 0 .5px var(--black-a1), 0 1px 1px var(--gray-a2), 0 2px 1px -1px var(--black-a1), 0 1px 3px var(--black-a1)"
|
|
16
|
-
shadow-3: "0 0 0 1px var(--gray-a3), 0 2px 3px -2px var(--gray-a3), 0 3px 12px -4px var(--black-a2), 0 4px 16px -8px var(--black-a2)"
|
|
17
|
-
shadow-5: "0 0 0 1px var(--gray-a3), 0 12px 60px var(--black-a3), 0 12px 32px -16px var(--gray-a5)"
|
|
18
|
-
dark-ladder: { step: "n/a — alpha-step ramp (gray-a3 → a5 → a7 in dark), not a lightness ladder", hue: held }
|
|
19
|
-
```
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: shadcn-neutral-derived-radius
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from ui.shadcn.com/docs/theming; shadow values are the Tailwind defaults shadcn themes typically inherit"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "neutral, restrained utility feel; nearly flat, with one hairline border doing most of the separating work"
|
|
8
|
-
---
|
|
9
|
-
shadcn/ui derives its entire radius scale from a single `--radius` variable (multiplied up/down for sm/md/lg/xl), and leans on a plain neutral `border` token rather than shadow for everyday separation — shadow is reserved for popovers/menus. The whole system is intentionally colorless so any brand palette can sit on top of it unchanged.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 6, md: 8, lg: 10 }
|
|
13
|
-
hairline: "border token — 1px solid, neutral gray/oklch; default separator for card, input, and popover"
|
|
14
|
-
shadow:
|
|
15
|
-
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
16
|
-
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
17
|
-
popover: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
18
|
-
dark-ladder: { step: "+0.03–0.05 L per surface (oklch background → card)", hue: held }
|
|
19
|
-
```
|
package/data/harnesses/apollo/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: stripe-brand-tinted-dual-shadow
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from designmd.run/blog/stripe-design-system-breakdown and docs.stripe.com/elements/appearance-api"
|
|
6
|
-
license: reference-only
|
|
7
|
-
feel: "warm, trustworthy, faintly atmospheric; shadows carry Stripe's navy-purple brand hue instead of reading as neutral gray"
|
|
8
|
-
---
|
|
9
|
-
Stripe's shadows are two stacked layers where the far/ambient layer is tinted `rgba(50,50,93,...)` — the same blue-gray family as its navy-purple brand palette — with only the near/contact layer left as neutral black. Radius is deliberately conservative (Elements' own default is 4px) — Stripe treats restraint on both shadow and radius as part of feeling "trustworthy."
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 4, md: 6, lg: 8 }
|
|
13
|
-
hairline: "none specified — separation relies on shadow against a cool-gray canvas (#F6F9FC)"
|
|
14
|
-
shadow:
|
|
15
|
-
near: "rgba(0,0,0,.1) 0px 1px 2px 0px"
|
|
16
|
-
card: "rgba(50,50,93,.25) 0px 6px 12px -2px, rgba(0,0,0,.3) 0px 3px 7px -3px — {navy-purple tint / 0.25 alpha on far layer}"
|
|
17
|
-
dark-ladder: { step: "unconfirmed — Stripe's public brand system is light-first with no published dark ramp", hue: held }
|
|
18
|
-
```
|
package/data/harnesses/apollo/skills/design/data/elevation/tailwind-default-utility-scale.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: tailwind-default-utility-scale
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from tailwindcss.com/docs/box-shadow default theme values"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "the internet's default; a neutral gray shadow ramp so common it reads as 'no design system' unless overridden"
|
|
8
|
-
---
|
|
9
|
-
Tailwind's out-of-the-box shadow scale is the de facto baseline for a huge share of the web: six pure-neutral steps (sm → 2xl) with no brand tint, used independently of its separate border-color utilities rather than paired with them. Its very ubiquity is the point of including it here — it's the "control group" every more opinionated system in this list is reacting against.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 4, md: 6, lg: 8 }
|
|
13
|
-
hairline: "border-gray-200 (or theme border color), 1px solid — used independently of the shadow scale, not paired with it"
|
|
14
|
-
shadow:
|
|
15
|
-
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)"
|
|
16
|
-
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
|
|
17
|
-
xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
|
|
18
|
-
dark-ladder: { step: "n/a — no shipped dark ramp; convention is dark:shadow-none or a manual opacity boost", hue: held }
|
|
19
|
-
```
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: vercel-geist-shadow-as-border
|
|
3
|
-
class: a3
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from vercel.com/geist/materials"
|
|
6
|
-
license: reference-only
|
|
7
|
-
feel: "razor-flat product chrome; the resting 'border' is secretly a zero-blur shadow, softness saved entirely for menus and modals"
|
|
8
|
-
---
|
|
9
|
-
Geist's signature trick: a zero-offset, zero-blur, 1px-spread shadow (`0 0 0 1px rgba(0,0,0,.08)`) stands in for a border at rest, avoiding box-model side effects. As elements go from card → menu → modal, additional shadow layers stack on top of that same base line rather than replacing it, so the "border" never disappears.
|
|
10
|
-
|
|
11
|
-
```yaml values
|
|
12
|
-
radius: { sm: 6, md: 12, lg: 16 }
|
|
13
|
-
hairline: "shadow-emulated hairline — 0px 0px 0px 1px rgba(0,0,0,.08), zero blur, present at every rest state"
|
|
14
|
-
shadow:
|
|
15
|
-
base: "0px 0px 0px 1px rgba(0,0,0,.08)"
|
|
16
|
-
small: "0px 0px 0px 1px rgba(0,0,0,.08), 0px 2px 4px rgba(0,0,0,.04)"
|
|
17
|
-
menu: "0px 0px 0px 1px rgba(0,0,0,.08), 0px 8px 24px -8px rgba(0,0,0,.12)"
|
|
18
|
-
modal: "0px 0px 0px 1px rgba(0,0,0,.08), 0px 16px 48px -12px rgba(0,0,0,.18)"
|
|
19
|
-
dark-ladder: { step: "+1 surface swap per level (#000 → #0a0a0a → #111), occasional {blue-hue tint / low-alpha} wash surface", hue: drift }
|
|
20
|
-
```
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: iconography
|
|
3
|
-
class: a5
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "distilled from the A5 iconography phase-1 research sweep — Lucide, Tabler Icons, Radix Icons, Heroicons, Phosphor (Regular + Duotone), Material Symbols, IBM Carbon, Octicons, Linear, and Stripe Apps"
|
|
6
|
-
license: mixed — nine of the eleven conventions below are open (OSS icon sets under ISC/MIT/Apache-2.0); two are licensed (Linear, Stripe) because they describe a proprietary product's house convention rather than a redistributable asset — see the `license` line inside each convention's own values block
|
|
7
|
-
feel: "the register this file spans: quiet neutral utility (Lucide, Tabler) through dense-precision (Radix), paired-weight (Heroicons), rounded-friendly and illustrative (Phosphor), mechanically variable (Material Symbols), rectilinear enterprise (Carbon), hand-tuned developer precision (Octicons), to near-monochrome restraint (Linear, Stripe) — pick the register the product needs, not just a glyph shape"
|
|
8
|
-
---
|
|
9
|
-
A small conventions database, not a big catalog — eleven curated iconography conventions, each a coherent bundle of icon set, stroke/fill treatment, size grid, default color role, and type-pairing rule, because real products never choose these independently. The standing complaint every entry below answers is the same one: a bare, icon-less nav reads as unfinished; each convention states plainly where icons are obligatory (nav, status glyphs, empty states) versus optional (body copy, pure decoration).
|
|
10
|
-
|
|
11
|
-
## Convention: lucide-quiet-utility
|
|
12
|
-
|
|
13
|
-
**Feel:** "quiet, neutral utility line-work — reads as structural chrome, not decoration"
|
|
14
|
-
|
|
15
|
-
Lucide (ISC-licensed fork of Feather) is the default pick for stroke-based quiet utility icons in SaaS dashboards. Obligatory in nav rails, sidebar items, and empty-state graphics — the failure mode this convention guards against is exactly a bare, icon-less nav; optional inline in body copy or button labels where the text alone already carries the meaning.
|
|
16
|
-
|
|
17
|
-
```yaml values
|
|
18
|
-
set: Lucide (ISC license)
|
|
19
|
-
stroke: "2px, currentColor, round caps/joins, no fills"
|
|
20
|
-
grid: [24, 24]
|
|
21
|
-
default-color: muted-foreground
|
|
22
|
-
pairing: "absoluteStrokeWidth keeps the 2px line constant across sizes; optically matches a 14-16px UI sans at regular weight"
|
|
23
|
-
obligatory: [nav-rail, sidebar-items, empty-state-graphics]
|
|
24
|
-
optional: [body-copy, button-labels]
|
|
25
|
-
license: open
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Convention: tabler-technical-outline
|
|
29
|
-
|
|
30
|
-
**Feel:** "sharp, technical, exhaustive — the 'there's an icon for everything' catalog reads as engineering completeness, not a curated voice"
|
|
31
|
-
|
|
32
|
-
Tabler's 6,000+ MIT icon catalog is the pick when coverage matters more than a distinct personality — admin panels, internal tools, anywhere a designer needs an icon for a niche concept without commissioning custom art. Obligatory in dense toolbars and table row-actions where recognition beats charm; optional as pure decoration, where its neutrality reads generic rather than intentional.
|
|
33
|
-
|
|
34
|
-
```yaml values
|
|
35
|
-
set: Tabler Icons (MIT license)
|
|
36
|
-
stroke: "2px, adjustable, currentColor"
|
|
37
|
-
grid: [24, 24]
|
|
38
|
-
default-color: "neutral-500 / muted-foreground"
|
|
39
|
-
pairing: "2px stroke reads correctly against 14px UI text; bump to ~2.5px only above 32px display sizes so the line doesn't thin out"
|
|
40
|
-
obligatory: [dense-toolbars, table-row-actions]
|
|
41
|
-
optional: [pure-decoration]
|
|
42
|
-
license: open
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Convention: radix-dense-precision
|
|
46
|
-
|
|
47
|
-
**Feel:** "crisp, hard-edged precision built for the smallest interactive targets — dropdowns, toolbars, table cells, badges"
|
|
48
|
-
|
|
49
|
-
Radix Icons' 15x15 grid (not the usual 24) exists because at the sizes dense UI actually renders icons — inside buttons, selects, table cells — a 24-grid icon scaled down loses pixel-snap crispness, while a native 15px drawing keeps strokes on-pixel. Obligatory wherever the paired control is itself sub-20px (combobox triggers, sort carets, badge glyphs); skip above ~20px, where the fixed grid stops paying off and a 24-grid set reads better — there is no "optional" tier here, only a hard size threshold.
|
|
50
|
-
|
|
51
|
-
```yaml values
|
|
52
|
-
set: "Radix Icons (MIT license, designed by WorkOS)"
|
|
53
|
-
stroke: "single fixed weight per icon — redrawn per size, not algorithmically scaled"
|
|
54
|
-
grid: [15, 15]
|
|
55
|
-
default-color: "gray-11 / muted-foreground"
|
|
56
|
-
pairing: "matches the cap-height of 12-13px UI text used across Radix-based component libraries (Radix Themes, shadcn primitives)"
|
|
57
|
-
obligatory: [combobox-triggers, sort-carets, badge-glyphs]
|
|
58
|
-
optional: []
|
|
59
|
-
skip-above: "~20px — hand off to a 24-grid set past this threshold"
|
|
60
|
-
license: open
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Convention: heroicons-outline-solid-pair
|
|
64
|
-
|
|
65
|
-
**Feel:** "Tailwind-native default — outline for resting state, solid for the moment something becomes true"
|
|
66
|
-
|
|
67
|
-
Heroicons ships two coherent weights meant to be switched, never mixed within one context: 24px/1.5px-stroke outline for default and primary nav, 20px solid (plus a 16px mini and micro variant) for active/selected states and compact controls. Obligatory swap pattern: an outline icon in a nav item becomes its solid twin exactly when that item is current — the fill change is the only state signal, so don't blend outline and solid within the same list.
|
|
68
|
-
|
|
69
|
-
```yaml values
|
|
70
|
-
set: "Heroicons (MIT license, Tailwind Labs)"
|
|
71
|
-
stroke: "1.5px outline / filled solid — paired variants, not a weight slider"
|
|
72
|
-
grid: [24, 24] # outline; solid ships at 20px, mini at 16px, micro at 16px
|
|
73
|
-
default-color: "text-gray-500 (outline, resting) -> text-gray-900 or accent (solid, active)"
|
|
74
|
-
pairing: "built on Tailwind's own h-4/h-5/h-6 scale, so icon size always lands exactly on a text-size step"
|
|
75
|
-
obligatory: [nav-active-state-swap]
|
|
76
|
-
optional: []
|
|
77
|
-
license: open
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Convention: phosphor-rounded-friendly
|
|
81
|
-
|
|
82
|
-
**Feel:** "rounded, approachable, slightly playful without tipping into cartoonish — the friendly-SaaS register between Lucide's neutrality and duotone's illustration"
|
|
83
|
-
|
|
84
|
-
Phosphor's Regular weight is the rounded-friendly middle ground: softer terminals than Lucide or Tabler, but still a line icon, not a shape. Obligatory in consumer-facing or community products (onboarding flows, empty states, nav) where the brand voice is warm rather than clinical; match icon weight to type weight — Regular icon beside regular/medium body text, Bold icon only beside semibold-or-heavier headings, so the icon never visually undershoots its label.
|
|
85
|
-
|
|
86
|
-
```yaml values
|
|
87
|
-
set: "Phosphor Icons — Regular weight (MIT license)"
|
|
88
|
-
stroke: "~1.5px-equivalent stroke, rounded caps and joins"
|
|
89
|
-
grid: [24, 24] # authored on a 256x256 source grid, shipped at 24px
|
|
90
|
-
default-color: "muted-foreground, warms to accent on hover/active"
|
|
91
|
-
pairing: "weight axis tracks type weight: Regular <-> body/UI text, Bold <-> semibold+ headings"
|
|
92
|
-
obligatory: [onboarding-flows, empty-states, nav]
|
|
93
|
-
optional: []
|
|
94
|
-
license: open
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Convention: phosphor-duotone-expressive
|
|
98
|
-
|
|
99
|
-
**Feel:** "filled, two-tone, illustrative — reads as a fragment of an illustration more than a clickable control"
|
|
100
|
-
|
|
101
|
-
Phosphor's Duotone weight layers a full-opacity foreground shape over a 20%-opacity fill of the same color, giving flat icons a sense of depth without a second hue. Obligatory in empty states, onboarding checklists, and marketing-adjacent surfaces where an icon needs to carry emotional weight; never use duotone for functional nav or toolbar icons — the two-tone fill reads as illustration rather than an actionable control, and it undermines click affordance.
|
|
102
|
-
|
|
103
|
-
```yaml values
|
|
104
|
-
set: "Phosphor Icons — Duotone weight (MIT license)"
|
|
105
|
-
stroke: "filled: 100% opacity primary shape + 20% opacity secondary layer, same hue"
|
|
106
|
-
grid: [24, 24]
|
|
107
|
-
default-color: "brand/accent (duotone is inherently expressive, rarely neutral gray)"
|
|
108
|
-
pairing: "sized 1.5-2x the adjacent display headline's cap height; never paired directly with dense UI text"
|
|
109
|
-
obligatory: [empty-states, onboarding-checklists, marketing-adjacent-surfaces]
|
|
110
|
-
optional: []
|
|
111
|
-
never-use: [functional-nav, toolbar-icons]
|
|
112
|
-
license: open
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Convention: material-symbols-variable-axes
|
|
116
|
-
|
|
117
|
-
**Feel:** "mechanically consistent, endlessly adjustable — one variable font file standing in for what other systems ship as five separate icon sets"
|
|
118
|
-
|
|
119
|
-
Material Symbols collapses weight, fill, grade, and optical size into a single variable font (`wght` 100-700, `FILL` 0/1, `GRAD` -50 to 200, `opsz` 20-48), so "outline vs. filled" and "thin vs. bold" become live CSS values instead of separate asset swaps. Obligatory pattern: `FILL 0` for resting nav items, animated to `FILL 1` on select — the fill toggle is the selected-state affordance itself, so a nav that skips it loses its only state signal.
|
|
120
|
-
|
|
121
|
-
```yaml values
|
|
122
|
-
set: "Material Symbols (Apache-2.0 license, Google)"
|
|
123
|
-
stroke: "variable FILL axis: 0 (outlined) to 1 (filled); wght 100-700, GRAD -50 to 200"
|
|
124
|
-
grid: [24, 24] # opsz axis spans 20-48 on the same glyph
|
|
125
|
-
default-color: "on-surface-variant (Material's muted-foreground equivalent)"
|
|
126
|
-
pairing: "opsz should numerically track the paired text's rendered px/pt size 1:1, or stroke weight looks wrong at the range's edges"
|
|
127
|
-
obligatory: [nav-fill-toggle-as-selected-state]
|
|
128
|
-
optional: []
|
|
129
|
-
license: open
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Convention: carbon-enterprise-grid
|
|
133
|
-
|
|
134
|
-
**Feel:** "rectilinear, high-density, unmistakably enterprise — icons read as instrumentation, not ornament"
|
|
135
|
-
|
|
136
|
-
IBM Carbon draws every icon on a 32x32 master grid with 2px padding, then scales linearly down to 24/20/16px rather than redrawing per size, keeping optical alignment exact across a data-dense UI. Obligatory at 16px inside buttons and inputs, where IBM Plex Sans runs at 14px; 24/32px reserved for standalone actions and empty-state illustration slots. Touch targets stay 44px+ regardless of the visual icon size — a Carbon-specific accessibility floor worth keeping alongside the visual convention.
|
|
137
|
-
|
|
138
|
-
```yaml values
|
|
139
|
-
set: "IBM Carbon icons (Apache-2.0 license)"
|
|
140
|
-
stroke: "solid/filled glyph forms scaled from one master grid, not a stroke-weight system"
|
|
141
|
-
grid: [32, 32] # scales down linearly to 24/20/16 for actual component use
|
|
142
|
-
default-color: "icon-primary token (near-black in light theme, near-white in dark)"
|
|
143
|
-
pairing: "16/20px icons pair with 14/16px IBM Plex Sans UI text; 24/32px reserved for standalone or empty-state use"
|
|
144
|
-
obligatory: [buttons-and-inputs-at-16px, standalone-actions-at-24-32px, empty-state-illustration]
|
|
145
|
-
optional: []
|
|
146
|
-
touch-target-floor: "44px+ regardless of visual icon size"
|
|
147
|
-
license: open
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Convention: octicons-dual-precision
|
|
151
|
-
|
|
152
|
-
**Feel:** "hand-tuned developer-tool precision — every icon individually redrawn per size rather than mechanically scaled"
|
|
153
|
-
|
|
154
|
-
GitHub's Octicons draws each icon twice — a 16px version and a separately hand-corrected 24px version, rather than one scaled from the other — with a consistent 1.5px stroke, round caps/joins, and 1px corner radius across both. Obligatory at 16px in repo/PR/issue navigation chrome, where an icon-less nav row reads as visibly broken against GitHub's own conventions; 24px reserved for section headers and empty-state glyphs, never mixed with 16px in the same row.
|
|
155
|
-
|
|
156
|
-
```yaml values
|
|
157
|
-
set: "Octicons — GitHub Primer (MIT license)"
|
|
158
|
-
stroke: "1.5px, round caps and joins, 1px corner radius (0.25px on small filled arrowheads)"
|
|
159
|
-
grid: [16, 16] # plus a separately hand-drawn 24x24 variant
|
|
160
|
-
default-color: "fg.muted (Primer token)"
|
|
161
|
-
pairing: "16px icon pairs with Primer's 14px UI text baseline; 24px pairs with section headers only"
|
|
162
|
-
obligatory: [repo-pr-issue-nav-chrome-at-16px, section-headers-and-empty-states-at-24px]
|
|
163
|
-
optional: []
|
|
164
|
-
license: open
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
## Convention: linear-icon-restraint
|
|
168
|
-
|
|
169
|
-
**Feel:** "near-monochrome restraint — icons are load-bearing wayfinding, never decoration, and the restraint itself is the brand voice"
|
|
170
|
-
|
|
171
|
-
Linear confines icons almost exclusively to two obligatory slots — the sidebar nav rail and issue/status glyphs (priority, workflow state) — and deliberately withholds them everywhere else (body text, secondary inline actions) to protect density. The one place Linear over-indexes on icons rather than under-indexing is exactly where the standing complaint bites hardest: a nav with missing icons reads as unfinished, so nav iconography is treated as non-negotiable even though icons everywhere else stay optional.
|
|
172
|
-
|
|
173
|
-
```yaml values
|
|
174
|
-
set: "product convention (implementation-agnostic thin outline, Lucide-class)"
|
|
175
|
-
stroke: "~1.5px, single weight, no fill states except the active accent swap"
|
|
176
|
-
grid: [16, 16]
|
|
177
|
-
default-color: "muted-foreground, promotes to the single accent color only on active/selected state"
|
|
178
|
-
pairing: "icon optical size matches the 13px UI sans cap height in the sidebar; icon and label baseline-align, never icon-only in primary nav"
|
|
179
|
-
obligatory: [sidebar-nav-rail, issue-status-glyphs]
|
|
180
|
-
optional: [body-text, secondary-inline-actions]
|
|
181
|
-
license: licensed
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Convention: stripe-restrained-fintech
|
|
185
|
-
|
|
186
|
-
**Feel:** "near-monochromatic, trustworthy, financial-instrument register — icons are quiet infrastructure, color is spent on one accent only"
|
|
187
|
-
|
|
188
|
-
Stripe's Icon component ships a fixed five-step size scale (xsmall through xlarge) rather than free pixel values, keeping every icon on-grid with the dashboard's type scale by construction; icons default to inherit surrounding text color and only break to the brand indigo for strokes that need to signal interactivity. Obligatory in the dashboard nav rail and the app-indicator badge (the colored bar + icon identifying which Stripe App is active); optional-to-discouraged as decoration inside data-dense tables, where Stripe's own guidance limits custom styling to preserve platform consistency.
|
|
189
|
-
|
|
190
|
-
```yaml values
|
|
191
|
-
set: "product convention (Stripe Dashboard / Stripe Apps Icon component)"
|
|
192
|
-
stroke: "thin outline, inherits currentColor by default"
|
|
193
|
-
grid: [16, 20, 24, 28, 32] # xsmall..xlarge step scale, not free px
|
|
194
|
-
default-color: "inherits surrounding text color (currentColor); accent indigo for interactive strokes only"
|
|
195
|
-
pairing: "icon size step always matches the adjacent text's type-scale step, never set independently"
|
|
196
|
-
obligatory: [dashboard-nav-rail, app-indicator-badge]
|
|
197
|
-
optional: [decoration-in-dense-tables]
|
|
198
|
-
license: licensed
|
|
199
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: accordion-expand
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/animation-vocabulary/SKILL.md (Accordion/Collapse term) + review-animations/STANDARDS.md (easing decision order — on-screen morph → strong ease-in-out; interruptibility)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a 240ms reveal on a strong ease-in-out reads smooth; snapping open or drifting past 300ms reads clunky"
|
|
8
|
-
aliases: { clunky: "a plain built-in easing instead of the strong custom ease-in-out curve", "snap-open": "no transition at all — content appears/disappears instantly", janky: "keyframes (or animated height) instead of an interruptible transition on transform/clip-path" }
|
|
9
|
-
---
|
|
10
|
-
Expand/collapse sections, FAQ rows, nested tree rows — an on-screen morph, so ease-in-out, not the entrance curve. Prefer `clip-path`/transform reveals over animated `height` (layout property — off-GPU). Rapid toggling must retarget mid-animation, not restart from collapsed.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 240ms
|
|
14
|
-
easing: cubic-bezier(0.77, 0, 0.175, 1)
|
|
15
|
-
element-class: panel
|
|
16
|
-
interruptible: required
|
|
17
|
-
budget: { panel: 200-300ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: destructive-hold-confirm
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (asymmetric timing — press slow/release fast example, values verbatim class)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a slow deliberate fill on hold with a fast release reads like the system is making you mean it; a symmetric hold/release reads accidental-prone"
|
|
8
|
-
aliases: { "trigger-happy": "hold and release animating at the same speed, so a brief accidental hold nearly commits", "accidental-prone": "no hold gate at all — a single tap commits the destructive action" }
|
|
9
|
-
---
|
|
10
|
-
Delete/destructive confirmations gated behind a hold, not a second click. The hold phase (user deciding) animates slow and must be abortable mid-hold; release or completion (system responding) snaps back fast.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 2000ms (hold-to-fill) / 200ms (release)
|
|
14
|
-
easing: linear (hold) / cubic-bezier(0.23, 1, 0.32, 1) (release)
|
|
15
|
-
element-class: control
|
|
16
|
-
interruptible: required
|
|
17
|
-
budget: { control: 1500-2500ms hold, 150-250ms release }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: drag-dismiss-momentum
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (gestures & drag — velocity dismissal; springs config) + apple-design/SKILL.md §5 (velocity handoff)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a flick that keeps its exact velocity into the dismiss reads thrown away on purpose; a fixed-duration tween to the edge reads like the drag didn't matter"
|
|
8
|
-
aliases: { disconnected: "velocity discarded at release in favor of a fixed-duration keyframe to the exit point", stuck: "dismissal gated on a distance threshold instead of release velocity (~0.11 px/ms)" }
|
|
9
|
-
---
|
|
10
|
-
Swipe-to-dismiss on toasts, cards, sheets. The spring here is a correctness mechanism (velocity continuity for gesture-driven motion), not styling — it carries the pointer's release velocity into the exit and stays grabbable and reversible mid-flight. Bounce is canon-sanctioned specifically for drag-to-dismiss; it doesn't generalize.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 500ms (spring settle; no fixed duration)
|
|
14
|
-
easing: spring(bounce 0.2, damping ~0.8)
|
|
15
|
-
element-class: overlay
|
|
16
|
-
interruptible: required
|
|
17
|
-
budget: { overlay: 350-550ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: empty-state-arrive
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (springs — subtle bounce) + improve-animations/AUDIT.md §1 (rare moments); A6 admission law (identity-moment scope)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "an illustration that gently scales and settles in reads intentional, like the empty state was designed on purpose; a plain instant fade reads unfinished"
|
|
8
|
-
aliases: { unfinished: "the empty-state illustration/copy just appearing with no entrance at all", overdone: "spring bounce strong enough to feel jokey rather than reassuring" }
|
|
9
|
-
---
|
|
10
|
-
First-visit or true-zero-data empty states (no rows yet, no results yet). Low-frequency identity moment — springy motion is admissible, but keep bounce subtle since the tone is reassuring, not playful.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 450ms (spring; no fixed duration)
|
|
14
|
-
easing: spring(bounce 0.15)
|
|
15
|
-
element-class: identity-moment
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { identity-moment: 350-550ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: hover-lift
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/emil-design-eng/SKILL.md (easing decision — hover → ease) + review-animations/STANDARDS.md (frequency tiers; hover gating); Easing Blueprint agrees as secondary"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a soft `ease` color/elevation shift under 200ms reads responsive; past 250ms or on touch it reads laggy and fake"
|
|
8
|
-
aliases: { laggy: "hover duration pushed past the control budget", "fake-hover": "hover motion firing on a touch tap because it isn't gated to hover:hover and pointer:fine" }
|
|
9
|
-
---
|
|
10
|
-
List rows, nav items, cards, toolbar icons on mouse-hover. Gate behind `@media (hover: hover) and (pointer: fine)` always. Sits in the "tens of times/day — reduce, don't eliminate" frequency tier; drop it first on any list scrolled constantly.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 150ms
|
|
14
|
-
easing: ease
|
|
15
|
-
element-class: control
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { control: 120-200ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: modal-center-arrive
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (physicality — modal exemption; duration table, modal row) + improve-animations/AUDIT.md §3; Material emphasized-decelerate agrees as secondary"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a centered scale-from-0.95-and-fade at ~250ms on a strong ease-out reads deliberate and important; scale(0) or a snap-open reads like it teleported in"
|
|
8
|
-
aliases: { teleported: "scale(0) or an opacity-only entrance with no initial transform", "snap-open": "no interpolation at all — the dialog just appears" }
|
|
9
|
-
---
|
|
10
|
-
Dialogs and confirmation modals only — the one place `transform-origin: center` is correct, exempt from the trigger-anchoring rule. Entrance starts from scale 0.9-0.97 + opacity 0, never scale(0); the longer end of the budget is the modal's prominence — don't reuse it on tooltips or dropdowns.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 250ms
|
|
14
|
-
easing: cubic-bezier(0.23, 1, 0.32, 1)
|
|
15
|
-
element-class: overlay
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { overlay: 200-500ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: number-ticker-roll
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/animation-vocabulary/SKILL.md (Number ticker; Tabular numbers) + review-animations/STANDARDS.md (sub-300ms rule; interruptibility)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "digits rolling to the new value at ~250ms read like a live counter; an instant jump-cut reads like the number just glitched"
|
|
8
|
-
aliases: { glitched: "value changes with no roll/interpolation at all", "tabular-drift": "digits set without tabular figures, so the number visibly shifts width as it rolls", janky: "keyframe roll restarting from zero on each rapid update instead of retargeting" }
|
|
9
|
-
---
|
|
10
|
-
Live counters, stat tiles, KPI cards, running totals — system-driven value changes, so the sub-300ms UI rule applies. Requires tabular figures so surrounding layout doesn't shift while digits roll. Rapid successive updates retarget the roll (transition, not keyframes), never restart from zero.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 250ms
|
|
14
|
-
easing: cubic-bezier(0.23, 1, 0.32, 1)
|
|
15
|
-
element-class: control
|
|
16
|
-
interruptible: required
|
|
17
|
-
budget: { control: 200-300ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: onboarding-bounce
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (springs — bounce 0.1-0.3, reserved for playful moments) + improve-animations/AUDIT.md §1 (rare/first-time → delight)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a springy overshoot on a first-run welcome card reads warm and considered; the same bounce on anything seen daily reads gimmicky"
|
|
8
|
-
aliases: { gimmicky: "spring bounce applied outside a rare/first-time identity moment — the same overshoot on a daily-use control", overdone: "bounce pushed above the 0.1-0.3 range into cartoonish territory" }
|
|
9
|
-
---
|
|
10
|
-
Onboarding welcome screens, first-run tours — rare, high-emotion, seen once or a handful of times ever. The scoped exception where springy/physical vocabulary is admissible; it does not license bounce anywhere else.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 500ms (spring; no fixed duration)
|
|
14
|
-
easing: spring(bounce 0.3)
|
|
15
|
-
element-class: identity-moment
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { identity-moment: 400-600ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: panel-slide
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (--ease-drawer curve; duration table, modal/drawer row) + apple-design/SKILL.md §3 (interruption; velocity continuity)"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a 260ms slide on the iOS drawer curve reads native and grabbable; a keyframe slide that restarts on repeated taps reads broken"
|
|
8
|
-
aliases: { broken: "keyframes restarting from zero instead of a transition/spring retargeting mid-slide", floaty: "duration pushed past the panel budget" }
|
|
9
|
-
---
|
|
10
|
-
Side panels, drawers, bottom sheets. Must be interruptible and carry velocity on a gesture-driven close — grabbing a closing panel should follow the pointer, not fight it.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 260ms
|
|
14
|
-
easing: cubic-bezier(0.32, 0.72, 0, 1)
|
|
15
|
-
element-class: panel
|
|
16
|
-
interruptible: required
|
|
17
|
-
budget: { panel: 200-500ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: press-feedback
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (physicality — press feedback; duration table) + improve-animations/AUDIT.md §2-3"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "160ms scale-to-0.97 on pointer-down reads tactile and instant; slower or absent reads dead under the finger"
|
|
8
|
-
aliases: { dead: "no press feedback at all, or duration pushed above the 160ms control budget", mushy: "an easing softer than ease-out, delaying the visible response" }
|
|
9
|
-
---
|
|
10
|
-
Any pressable control — buttons, icon buttons, tap-target rows. The canon prescribes this on every pressable element while forbidding animation on keyboard-initiated actions: it fires on pointer-down only (a tap affordance, not a state transition), and keyboard activation (Enter/Space) never replays it.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 160ms
|
|
14
|
-
easing: cubic-bezier(0.23, 1, 0.32, 1)
|
|
15
|
-
element-class: control
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { control: 100-160ms }
|
|
18
|
-
```
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: progress-linear-loop
|
|
3
|
-
class: a6
|
|
4
|
-
sourced: 2026-07-12
|
|
5
|
-
source: "emilkowalski.skills/skills/review-animations/STANDARDS.md (easing decision order — constant motion → linear) + animation-vocabulary/SKILL.md (Loop; Marquee); Material's linear token agrees as secondary"
|
|
6
|
-
license: open
|
|
7
|
-
feel: "a constant linear sweep reads honest about an unknown wait; any easing that speeds up and slows down reads like a fake promise"
|
|
8
|
-
aliases: { "fake-promise": "eased (non-linear) motion on an indeterminate progress indicator, implying a completion point that doesn't exist", twitchy: "loop cycle faster than ~1s, reading anxious rather than calm" }
|
|
9
|
-
---
|
|
10
|
-
Indeterminate progress bars, loading spinners, marquees. Constant-speed motion only — the one place `linear` is correct and `ease` curves are wrong.
|
|
11
|
-
|
|
12
|
-
```yaml values
|
|
13
|
-
duration: 1200ms (loop)
|
|
14
|
-
easing: linear
|
|
15
|
-
element-class: control
|
|
16
|
-
interruptible: n/a
|
|
17
|
-
budget: { control: 1000-1500ms }
|
|
18
|
-
```
|