Skip to content

feat(templates): give each style its own voice, and replace generated artwork - #50

Open
Bccorb wants to merge 1 commit into
mainfrom
feat/cinematic-views
Open

feat(templates): give each style its own voice, and replace generated artwork#50
Bccorb wants to merge 1 commit into
mainfrom
feat/cinematic-views

Conversation

@Bccorb

@Bccorb Bccorb commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

The shared React kit gains a font token per role, a Vista backdrop component, and full-viewport views with scroll-driven transitions. The per-application SVG motif concept is removed.

Edited in shared/react-app and copied out with npm run sync:shared, so both web starters move together.

What changed

Type. Three styles that differed only in colour still read as one look, because all three set every word in the same typeface. --app-font-display, --app-font-body and --app-font-label name system stacks only, so nothing is downloaded and the lever is which of the faces an OS already ships each style reaches for.

Vista. A fixed stack of four layers behind the page: two concentrated light sources, concentric rings, a slow conic sweep, and a ruled grid. Every layer is a gradient built from the application's own two colours, so one component still comes out looking like that application. Cinematic sets all four, Professional keeps only the grid, Generic sets none.

Views. Each region a Screen renders is now a view. Cinematic makes a view a full height of the window and lets the page settle between them. The other two resolve it to auto and the same markup is an ordinary scrolling page.

Motif removal. A drawing had to be invented on every run, came out differently each time, and was reliably the least convincing thing on the screen. Screen, AuthFrame and EmptyState no longer accept a motif prop.

Riding along, worth a look

Screen.tsx adds board to BANDED, so board screens go from unbanded to a full brand-coloured header. That is a real visual change to an existing archetype and was not called out in the original commit message. It is in the changeset now.

Degradation, since this is the risky part

The four usual ways this kind of change breaks are handled, and I checked each:

  • 100svh, not 100vh, so mobile browser chrome does not clip a view
  • scroll-snap-type: y proximity, not mandatory, so content taller than the viewport never becomes unreachable
  • min-height, not height, so an overflowing section still grows
  • animation-range: cover, not entry, because a view as tall as the window never finishes entering and an entry range strands it at opacity: 0 mid-screen

Both scroll-driven behaviours sit behind @supports and prefers-reduced-motion. Where a browser has no view timeline the content is simply visible.

Coordination required

This must land together with the pipeline side in seamless-idea-api. reference.ts already tells the generator there is no Motif file, but spec.ts still asks the model for presentation.motif, still validates it as a representational scene, and renderSpec still prints it to the user as backdrop, which nothing draws any more. That work is in flight and removes the stale validation. Two spots to catch while you are there: the doc comment on SpecPresentation.motif in types.ts still describes an SVG scene, and renderSpec still labels the line backdrop.

Separately, and not this PR's job: renderThemeCss in seamless-idea-api/src/pipeline/theme.ts overwrites index.css wholesale for generated apps, so this CSS now exists in two hand-maintained copies in two repos. npm run validate only checks shared to template inside this repo, so nothing catches drift between them. They agree today, verified by comparing class and custom-property sets. Worth an issue.

Checks

npm run validate passes, no drift. npm run check (typecheck, lint, format:check, test) and npm run build pass in both web starters.

… artwork

Three styles that differed only in colour still read as one look, because all
three set every word in the same typeface. Nothing is downloaded, so the lever
is which of the faces an OS already ships each style reaches for: a heavy
grotesque in tracked capitals, a neutral UI face, and a monospace for small
labels are three genuinely different voices, and every platform has all three.

Cinematic gains a backdrop, views, and transitions between them.

Vista is a fixed stack of four layers behind the page: two concentrated light
sources, concentric rings, a slow conic sweep, and a ruled grid. Every layer is
a gradient built from the application's own two colours, so one component still
comes out looking like that application, and a style that wants no backdrop sets
each layer to none. Cinematic sets all four; Professional keeps only the grid.

This replaced per-application SVG artwork. A drawing had to be invented on every
run, came out differently each time, and was reliably the least convincing thing
on the screen. Light and geometry come out the same every time and cost nothing
to produce, so Screen, AuthFrame and EmptyState no longer take a motif at all.

Each region a Screen renders is now a view. Cinematic makes a view a full height
of the window and lets the page settle between them; the other two resolve it to
auto and the same markup is an ordinary scrolling page. The backdrop's layers are
scroll-driven and pan against each other, so arriving at the next view changes
what is behind it. No JavaScript, and it degrades to visible.

The reveal animation is ranged over cover rather than entry. A view as tall as
the window never finishes entering, so an entry range stranded it part-way
through the animation with its content invisible: opacity 0 on a section sitting
square in the middle of the screen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant