Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
76282bc
spec(AST-108): theme motion is three knobs — tempo, character, reduce…
cixzhang Oct 26, 2026
843655e
spec(AST-108): character offsets each role's measured bounce; BottomS…
cixzhang Oct 26, 2026
ef37748
spec(AST-090): restore FR1's opening, lost to an editing slip
cixzhang Oct 27, 2026
c33cc6a
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
8cbc8e7
spec(AST-108, AST-094, AST-090): exits keep --ease-standard; implied …
cixzhang Oct 27, 2026
e882416
spec(AST-108): a MotionScaleConfig's implied tempo drives CSS duratio…
cixzhang Oct 27, 2026
55ce12d
spec(AST-108 +): fixed timers named; 'always' reaches component style…
cixzhang Oct 27, 2026
0dcda09
spec(AST-108): busy loops read pre-tempo durations; adaptations set t…
cixzhang Oct 27, 2026
1b84c1b
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
5588985
spec(AST-108): extending themes merge field by field; 'system' adds n…
cixzhang Oct 27, 2026
ec298b6
spec(AST-108): legacy motion fields replace as a unit under extends; …
cixzhang Oct 27, 2026
13c5cfb
spec(AST-108): an extending theme inherits motion field by field, as …
cixzhang Oct 27, 2026
5149d4d
spec(AST-108): 'always' reaches script readers of the preference; imp…
cixzhang Oct 27, 2026
f97e777
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
bc1422a
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
0beff2d
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
e969525
spec(AST-108 +): FR4 scoped to tempo and character; 'always' reaches …
cixzhang Oct 27, 2026
73a1079
spec(AST-108): 'always' only adds; an ancestor's reaches nested themes
cixzhang Oct 27, 2026
8d3ab3c
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
1b4d396
spec(AST-108 +): theme-application INV1 names the 'always' exception;…
cixzhang Oct 27, 2026
1d6e560
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
7abce21
spec(AST-108 +): Spinner and Skeleton time loops before tempo; weight…
cixzhang Oct 27, 2026
74bd8ae
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
0bae4a3
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
6b94712
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
b61e4fa
Merge remote-tracking branch 'origin/main' into spec/theme-motion-knobs
cixzhang Oct 27, 2026
b84e8f2
Merge main into spec/theme-motion-knobs
cixzhang Oct 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/architecture/theme-application.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ verified_by:
packages/core/src/theme/themeRegistry.test.ts,
packages/core/src/AppShell/AppShell.test.tsx,
]
deciding_specs: [spec:AST-012/DEC-1, spec:AST-087/DEC-2]
deciding_specs: [spec:AST-012/DEC-1, spec:AST-087/DEC-2, spec:AST-108/DEC-1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Deciding specs section further down still lists only spec:AST-012/DEC-1 and spec:AST-087/DEC-2; one bullet for spec:AST-108/DEC-1 (a theme's reducedMotion: 'always' reaches nested providers, INV1) would keep it in step with this list.

---

# Theme application
Expand Down Expand Up @@ -95,7 +95,8 @@ standard width map.
## Boundaries and invariants

- **INV1 — The nearest provider wins.** Children read the closest Theme context
and CSS scope.
and CSS scope. One exception: a theme's `reducedMotion: 'always'` also reaches
every nested provider (`spec:AST-108` FR6).
- **INV2 — Only the root provider changes `<html>`.** Nested providers stay local
and cannot change browser chrome or portal-wide theme identity.
- **INV3 — Detached consumers share one root-theme store.** A separate React
Expand Down Expand Up @@ -159,6 +160,8 @@ which component parts are public theme targets.
- `spec:AST-012/DEC-1` owns the fixed width-point vocabulary AppShell consumes.
- `spec:AST-087/DEC-2` makes theme icon entries functions, so a theme holding
them reaches `Theme` from client code.
- `spec:AST-108/DEC-1` lets a theme's `reducedMotion: 'always'` reach nested
providers (INV1).

## Verification

Expand Down
6 changes: 6 additions & 0 deletions docs/architecture/theme-authoring-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ classify local references. Until the implementation lands, INV8's prefix-indepen
clauses are current authority but not enforcement. Existing explicit enrollment,
owner, lineage, collision, cycle, and legacy-unenrolled behavior remains shipped.

The motion resolver is accepted but unshipped: an internal, pure
`resolveThemeMotion(theme)` returns a theme's motion knobs, durations, easings,
and role tables for the animator and for server code, touching no DOM and with
no import-time side effects (`spec:AST-108` FR6). Until it lands, FR6's
resolution is current authority but not enforcement.

## Verification

| Invariant | Evidence | Failure signal |
Expand Down
4 changes: 3 additions & 1 deletion docs/design/motion.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ when motion is reduced.
- **DR2 — Weight determines timing.** Small local feedback SHOULD feel faster
than large entrances, exits, or continuous movement.
- **DR3 — Movement settles naturally.** Easing SHOULD communicate controlled
deceleration rather than ornamental bounce or elasticity.
deceleration rather than ornamental bounce or elasticity; a theme's
expressive character may overshoot on entrances and moves only
(`spec:AST-108`).
- **DR4 — Stable content stays stable.** Motion SHOULD avoid unnecessary layout
disruption and preserve reading and interaction context.
- **DR5 — Reduced motion preserves meaning.** Every animated transition MUST have
Expand Down
15 changes: 10 additions & 5 deletions docs/design/reduced-motion.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ trackpad, or keyboard the change is immediate.

## State representation

| State | Required representation | Allowed variation |
| --------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------- |
| reduced motion, coarse pointer | Opacity-only cross-fade of 200 ms or less (DR2); an in-place value change applies at once (DR2) | A shorter cross-fade |
| reduced motion, any other pointer | Immediate change (DR3), except a touch drag's release (DR2) | None |
| no reduced-motion preference | Outside this record | Component and theme motion |
| State | Required representation | Allowed variation |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------- |
| reduced motion, coarse pointer | Opacity-only cross-fade of 200 ms or less (DR2); an in-place value change applies at once (DR2) | A shorter cross-fade |
| reduced motion, any other pointer | Immediate change (DR3), except a touch drag's release (DR2) | None |
| no reduced-motion preference, theme on `'system'` | Outside this record | Component and theme motion |
| a theme on `'always'` (DR2a) | As reduced motion, whatever the person's setting | DR1–DR3 |

## Responsive and input behavior

Expand All @@ -75,6 +76,10 @@ trackpad, or keyboard the change is immediate.
under Reduce Motion. An in-place value change, such as a progress fill's length or
another continuous value, does not cross-fade: under reduced motion it
applies at once on any pointer, with no added element (DEC-3).
- **DR2a — A theme may reduce motion for everyone.** A theme's

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With DR2a, the State representation row "no reduced-motion preference | Outside this record | Component and theme motion" (line 61) no longer holds under 'always'. Could that row be scoped to a theme on 'system', or gain an 'always' row?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With DR2a, the State representation row "no reduced-motion preference | Outside this record | Component and theme motion" (line 61) no longer holds under 'always'. Could that row be scoped to a theme on 'system', or gain an 'always' row that points here?

`reducedMotion: 'always'` applies DR1–DR3 for every person, whatever their
setting; `'system'` follows each person's setting (`spec:AST-108`). No theme
option loosens DR1–DR4.
- **DR3 — Fine-pointer presentations change at once.** Under reduced motion,
every other DR1 transition, when the primary pointer is not coarse, MUST complete
immediately, with no animated property.
Expand Down
3 changes: 2 additions & 1 deletion docs/specs/AST-012/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ A breakpoint map alone emits no CSS. Only rules with adaptation values do.
`localTokens` or an enrolled exact base declares names. A rule may replace only
an exact name already enrolled in the effective lineage and uses AST-006's
`TokenValue` normalization and validation. Identity, inheritance, syntax, icons,
indicators, media-surface fields, and adaptations remain root-owned. Within one
indicators, media-surface fields, adaptations, and `motion.reducedMotion`
(`spec:AST-108` FR5) remain root-owned. Within one
rule, values use the root expansion, deep-merge, and kind precedence. A
generative axis expands against the root axis metadata, and every produced leaf
counts as a write by that rule except invariant type-scale component defaults
Expand Down
5 changes: 4 additions & 1 deletion docs/specs/AST-090-exit-motion/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ FR1–FR13 govern dialog and layer surfaces in a pointer presentation. FR14
governs them in a touch presentation.

- **FR1 — Exits are off by default.** `--duration-exit-dialog` and
`--duration-exit-layer` default to `0ms`. A surface whose kind's exit
`--duration-exit-layer` default to `0ms`. An exit duration a theme sets as a
reference to a tempo-scaled token, such as FR12's `var(--duration-exit)`,
follows the theme's tempo; one set as a literal plays as written
(`spec:AST-108` FR5). A surface whose kind's exit
duration is zero closes at once: it is hidden in the update that closes it,
and focus, callbacks, and dismissal behave as they do for a surface with no
exit.
Expand Down
Loading
Loading