Colour
Fields, not gradients
Each section owns one field. Text colour follows from the field. Every pairing shown here clears WCAG AAA in both themes, and a build-time check enforces it.
-
Paper
--color-paperDefault page field -
Raised
--color-raisedMuted band, card wells -
Mint
--color-mintAiry band, calm sections -
Sand
--color-sandWarm band, admissions -
Deep
--color-deepHero and dark bands -
Slab
--color-slabFooter, statement bands -
Amber
--color-amberPrimary action, highlight -
Flame
--color-flameAccent mark, focus ring -
Teal
--color-tealSecond accent, bullets
Typography
Archivo for voice, Work Sans for reading
Six steps, all fluid. Display and headings are Archivo at a widened optical width. Body copy is Work Sans.
-
Learn a trade
.jt-display--text-displayHero statements only. One per page. -
Learn a trade
.jt-h1--text-h1Page titles and section statements. -
Learn a trade
.jt-h2--text-h2Section headings. -
Learn a trade
.jt-h3--text-h3Card and sub-section headings. -
Body copy sits at a comfortable measure and never runs past 68 characters. Long-form content uses the
.jt-prosewrapper..jt-lede--text-body -
Eyebrow label
.jt-eyebrow--text-meta
Controls
One geometry, every control
Buttons, inputs and selects share a baseline height driven by padding, a single radius, and a 44px minimum target.
Fields
Patterns
Disclosure and states
Accordions, tabs, and the states a product is judged on.
Accordion
This. The panel animates open on a grid-rows transition, so nothing jumps.
Yes. It is a button with aria-expanded controlling a labelled region.
Tabs
Arrow keys move between tabs. Home and End jump to the ends.
Only the selected panel is in the accessibility tree.
Panels are focusable so keyboard users can scroll long content.
Empty state
Nothing here yet
Empty, loading and error states are designed with the same care as the happy path.
Loading skeleton
Shape
Radius and elevation
-
--radius-uiEvery control: buttons, fields, icon buttons, tabs -
--radius-cardEverything that holds content: cards, frames, panels, menus -
--radius-insetA box nested flush inside a control -
--radius-pillChips, dots, rails — things that are a lozenge
-
--shadow-sm -
--shadow-md -
--shadow-lg
Motion
Spring, never linear
- --ease-spring
cubic-bezier(.22, 1, .36, 1). Used for entrances, hovers, reveals and carousel movement.- --ease-in-out-soft
cubic-bezier(.65, 0, .35, 1). Used for loops such as the loading shimmer.- Reduced motion
- Every animation and transition collapses to instant when
prefers-reduced-motion: reduceis set, and scroll reveals show immediately.