Strata brand patterns, motion & marketing templates
The brand surface lives mostly in
apps/marketing. This doc indexes the reusable patterns so you extend them instead of inventing parallels. Illustration work: readapps/marketing/docs/ILLUSTRATIONS.mdfirst — it is the authoritative system for the hairline art.
Brand patterns
| Pattern | Source | Rules |
|---|---|---|
| Pixel-mosaic backdrop | src/components/marketing/pixelated-backdrop.tsx (+ baked variant via scripts/pixelate-backdrops.ts) | 4px cells everywhere; cell color by dominant-color vote, never average; grout is rgb(0 0 0 / 5%) (.pixel-grout); source images near-lossless. |
| Hairline illustrations | agent-card-carousel.tsx, system doc docs/ILLUSTRATIONS.md | Single-pixel currentColor strokes (vector-effect="non-scaling-stroke"), real occluding objects painted back-to-front; ~50/50 iso Slab volumes vs 2D signal diagrams; reading direction bottom-left → top-right; svg aria-hidden. |
| Accent bands | section-kit.tsx → accentBand(color) | Paints the band AND injects a runtime --brand override so text-brand/color-mix() follow inside the band. Use it; don’t hand-set band colors. Mono captions sit mt-4 BELOW the band, never padded inside. |
| Section kit | section-kit.tsx | SectionEyebrow, SectionHeader, MoreLink, QuietLink — the only section scaffolding. |
| Dot grid | .marketing-dot-grid / -loose (global.css) | Backdrop texture; fill via the --dot-grid token (fainter in dark). |
| Noise | inline SVG feTurbulence (global.css hero grain) + --noise-url | Film-grain overlays. |
| Squircle | .logo-wrap, BrandMark.astro | corner-shape: squircle behind @supports, half-radius fallback (see tokens.md). |
| Closers | product-pages/product-closing.astro, orbit-closing-section.tsx | Linear-style: bare CTA (no card) + numbered hairline-column index with the current page’s number skipped. linear.app is the standing reference. |
The Elle orb is the hero-sheet sun ONLY; every chat surface uses the static
black-and-white ElleAvatar.
Motion rules
Motion lives in apps/marketing/src/styles/global.css (named keyframes) and
component-local rAF loops. The conventions:
- The house ease is
cubic-bezier(0.2, 0.7, 0.2, 1)(used byelle-reveal-up,journey-in); otherwise stockease-out/ease-in-out. New entrance animations use the house curve. - Every animation ships a
prefers-reduced-motionguard (animation: noneblock or an active-gate on the rAF loop). No exceptions. - Entrance patterns set only
animation-*properties, leavingtransitionfree for theme color changes (the.hero-enterdiscipline; staggering via a--enter-delaycustom property). - Component animation is rAF-driven and active-gated (only animates on-screen/hovered) per the illustration system’s “Animating” rules.
- Route transitions are the native
@view-transitioncross-document fade. - Named keyframe vocabulary (reuse before adding):
elle-reveal-up,journey-in/journey-blink,goal-flow-in/out,m-orbit-drift,stage-art-in,hero-enter,canvas-sheet-in,goal-loops-shimmer,agent-carousel-ring.
There is no centralized easing/duration token set yet — when one lands it
belongs in packages/ui/src/css/, not per-app.
Marketing templates
Page-level building blocks (all under apps/marketing/src/):
- Layouts:
layouts/Layout.astro(owns<head>),layouts/ContentLayout.astro(static header/footer content pages),layouts/LegalLayout.astro. - Page shell:
components/marketing/marketing-page.tsx. - Product pages:
components/marketing/product-pages/—product-hero.astro,spread-row.astro,loop-beats.astro,elle-transcript.tsx,product-closing.astro. - Sections:
why-layers-section.tsx,developer-section.tsx,pricing-section.tsx,manifesto.tsx,content-showcase.tsx,product/{social,elle,goal-loops,ads}-section.tsx(the ads bento). - Blog: MDX per
docs/BLOG_STRUCTURE.md; authoring via the/blogcommand.
New marketing pages compose from these; a genuinely new block joins this list (and the section kit) rather than living as one-off page DOM.