Tustel design system — Astro
Content-free building blocks of the Tustel template, mirrored from the Framer components and from the Next.js
version’s design system (same names, props and classes). Components never import src/content; sections pass data in
through props. See them all together at /style-guide.
Tokens
Section titled “Tokens”| File | Holds |
|---|---|
theme.css |
Colours (ink, soft, orange, background), breakpoints (md 810, lg 1200), the font variable, the ticker and spinner keyframes |
tokens/text.ts |
Text styles: display, h1–h6 (Inter Display: Inter’s optical size 32), paragraph, small, menu, button, label, tiny (Inter, optical size 14) |
tokens/motion.ts |
spring (no bounce, 0.5 s), springQuick (0.4 s), springSoft (bounce 0.2, 0.4 s), slideSpring (the slideshows), the appear ease, distances and staggers |
Translucent colours use opacity modifiers: Black 60 = ink/60, Black 30 = ink/30, Black 10 = ink/10. Inter is one
variable font with its optical-size axis (astro.config.mjs → fonts), so one file serves “Inter” and “Inter Display”.
Components
Section titled “Components”| Group | Component | Framer |
|---|---|---|
| actions | Button (black, white, secondary-black, secondary-white) |
Button/Primary (Black, White, Secondary/Black, Secondary/White) |
| actions | TextLink, MenuLink |
Button/Menu (Secondary/Black and /White; Black and White) |
| brand | Logo |
Misc/Logo (Black, White) |
| icons | Icon |
Phosphor (ArrowRight) |
| motion | TextAppear (letters, words, lines), Reveal, HeroBlock |
text effects, appear and scroll-in effects |
| navigation | Hamburger |
the phone menu button of Section/Header |
| layout | Section, SectionLabel, SectionTitle |
Section, Label text style, Title Section |
| cards | ProjectCard |
Portfoilo (sic) |
| cards | PostCard |
Post |
| media | FillImage, SizedImage |
images (next/image fill / fixed size) |
| media | Slideshow |
Slideshow/Hero Background, Slideshow/Testimonial |
| data | Counter, FactList |
Number Counter code component, Misc/Stats |
| patterns | Ticker |
the client logos and the specialities |
| patterns | SpecialtiesCard |
Card/Point List |
| patterns | PagedList |
collection lists with load on scroll and the Spinner |
| patterns | RichText (RichTextBlock, RichTextInline) |
CMS rich text |
| forms | Form, FormField, FieldControl, SubmitButton |
Form, inputs, selects, Submit |
| utils | CurrentYear |
the copyright year |
Page sections (the hero, the portfolio, the services…) live in src/components/sections/; the header and footer in
src/components/site/.
Interactivity
Section titled “Interactivity”No framework: each interactive component has a script in scripts/ with an init*() function (no arguments — the
HTML edition calls every one) that finds its elements by data-* attributes. The markup carries the first state
inline, so the page looks right before the scripts run.
| Script | Plays |
|---|---|
hover.ts |
hover and keyboard-focus states: data-hover on the hoverable element, data-motion (rest / hover) on each changing part, data-transition (spring · quick · soft) when the part has a transition of its own — without it Motion’s defaults apply, as in the Next.js version |
appear.ts |
Reveal, HeroBlock, TextAppear |
slideshow.ts, ticker.ts, counter.ts, paged-list.ts |
Slideshow, Ticker, Counter, PagedList |
hamburger.ts |
the hamburger lines (the header script and the style guide’s demo) |
portfolio.ts, services.ts |
the Home portfolio’s Catalog / List switch, the Home services list |
form.ts |
the forms (demo, endpoint or server mode: src/lib/forms/README.md) |
current-year.ts |
CurrentYear |
toggle.ts |
a helper for open / closed class lists (not used by Tustel’s own parts) |
Reduced motion is honoured as the Next.js version’s MotionConfig does it (utils/play.ts): moves, turns and size
changes jump to their end, fades and colour changes still play; tickers stop, slideshows stay on their first slide and
counters show their final value.
New component: put it in the right group, add it to /style-guide and to this table.