The system exactly as it stands today, with no recommendations and nothing I would change. Every value is read from the stylesheets, every example is rendered live in the real typeface. Built to be handed to another platform as a baseline.
One family does every job: wordmark, headline, body and UI. Nunito Variable, self-hosted, weight axis 200 to 1000. Rendered below in the real file.
Eyebrow above a section
Body copy sits at just over seventeen pixels with generous leading, and is capped at sixty-two characters so a line never runs longer than the eye wants to track. Weight five hundred rather than four hundred, which is what gives the system its slightly soft, rounded feel.
Sixteen tokens. Contrast pairings are fixed by the spec, not chosen per screen.
--ds-sun is always --ds-navy. Body text on white is always --ds-ink-body. Text on navy is always --ds-on-navy. No gradients anywhere in the system.White, 24px radius, 1px line border, card shadow, 28px padding. Laid out as an equal-height grid, one column on mobile, 24px gap. The icon chip is a 48px rounded square in a soft tint.
Your state's registration checklist, filled in from what you told us.
Every subject, every week, built around what your child actually likes.
What they wrote, how sure they felt, and what to do next.
One compact centred row directly beneath the hero, wrapping two-by-two on mobile. Check glyphs in a 22px teal circle.
One shared single-crest curve, reused and flipped everywhere a saturated block meets white. 60px tall, 32px on mobile. No diagonals, no blobs, no second curve.
Child screens layer a set of overrides on top of everything above. It is applied by adding a class to a wrapper element; it is not driven by session state.
| Property | Parent side | Child side |
|---|---|---|
| Body size | 1.0625rem | 1.15rem |
| Body line-height | 1.65 | 1.5 |
| Eyebrow size | 0.8125rem | 1rem |
| Button height | auto (15px padding) | min 56px |
| Button type size | 1rem, weight 800 | 1.5rem, weight 700 |
| Radius | 24px cards, 16px buttons | 1.5rem |
| Minimum tap target | not specified | 44px |
| Accent | --ds-sun #FFB703 | --child-amber #E4941A |
Five hues assigned deterministically per child, each with a solid and a soft tint, so a child keeps the same colour everywhere they appear.
#C2447A#2E86AB#3E7566#E4941A#6C5B7BContainer is min(100% - 48px, 1120px), centred. Section padding is 96px top and bottom, 60px at 768px and below. No other section padding values are permitted.
Hard bans: gradients; diagonal, rotated or scattered elements; floating cut-out people; text over photos; any second display font; invented numbers or testimonials; section padding outside spec.
Nine of them. Buttons, cards, inputs and badges are CSS classes rather than components.
| File | Lines | What it is |
|---|---|---|
SiteHeader.astro | 78 | Marketing site header |
SiteFooter.astro | 59 | Marketing site footer |
WaveDivider.astro | 17 | The single shared wave curve between sections |
AustraliaMap.astro | 87 | State picker map |
ChildChip.astro | 27 | Per-child colour identity chip, the one fully token-driven component |
HomeTrail.astro | 64 | Progress trail on the child home |
InterestsEditor.astro | 80 | Interest tag picker used in child setup |
LanternGlow.astro | 47 | Decorative lantern glow |
LanternTip.astro | 50 | Inline tip callout |
The spec names three references and attributes specific parts of itself to each:
| Reference | What it contributed |
|---|---|
| Duolingo | Layout grammar, whitespace, chunky buttons, zig-zag rows |
| Euka | Saturated colour blocking, navy anchor band |
| godslittlelightkeepers.com | Warmth, wave dividers, trust strip, review cards |
Same content, no styling, ready to paste.
LIGHTKEEPERS DESIGN SYSTEM v1 Reference-locked 2026-07-17. This is the current specification as built. === TYPEFACE === Nunito Variable, self-hosted woff2, weight axis 200-1000. Stack: "Nunito Variable", "Nunito", ui-rounded, system-ui, sans-serif. One typeface for everything: wordmark, headlines, body and UI. === COLOUR TOKENS === --ds-white #FFFFFF Default page and card background --ds-cream #FFF7EA Warm section background --ds-navy #1E2B4A Headlines, mid-page band, footer --ds-navy-deep #16223C Deeper navy --ds-on-navy #F4F7FB Text on navy --ds-ink-body #4A5568 Body text on white --ds-sun #FFB703 Primary button fill --ds-sun-deep #E59D00 Accent word in a headline --ds-sun-edge #D08700 Hard edge under a primary button --ds-sun-soft #FFF1CC Icon chip background --ds-teal #14B8A6 Buttons on navy, check icons --ds-teal-deep #0E9384 Teal edge, eyebrow colour --ds-sky #3B82F6 Secondary accent --ds-coral #FF6B57 Attention, warning --ds-gold-star #F59E0B Review stars --ds-line #E7ECF2 Borders and hairlines CONTRAST RULES (fixed, not optional): - Text on --ds-sun is always --ds-navy. - Body text on white is always --ds-ink-body. - Text on navy is always --ds-on-navy. - No gradients anywhere in the system. === RADII AND SHADOW === Cards 24px. Buttons 16px. Framed images 20px. Icon chips 14px. Card shadow: 0 1px 2px rgba(20,35,58,.05), 0 10px 30px rgba(20,35,58,.07). === TYPE SCALE === h1 clamp(2.5rem, 5.2vw, 3.9rem) weight 900, line-height 1.08, colour navy h2 clamp(1.85rem, 3.4vw, 2.5rem) weight 800, line-height 1.15, colour navy h3 weight 800, colour navy body 1.0625rem / 1.65 weight 500, colour ink-body, max-width 62ch eyebrow 0.8125rem weight 800, uppercase, letter-spacing 0.08em HEADLINE RULE: exactly one accent-coloured word or short phrase per headline. Never more. === BUTTONS (the signature component) === A hard bottom edge, no blur. Radius 16px, padding 15px 30px, weight 800, size 1rem. Hover: translateY(-1px). Active: translateY(3px) and the edge collapses to 1px. Transition 0.15s on transform and box-shadow. Primary background #FFB703, text #1E2B4A, box-shadow 0 4px 0 #D08700 Secondary background #FFFFFF, text #1E2B4A, 2px solid #E7ECF2, box-shadow 0 4px 0 #DCE4EE On navy background #14B8A6, text #FFFFFF, box-shadow 0 4px 0 #0E9384 Small padding 10px 20px, font-size 0.9rem === CARDS === Background white, radius 24px, 1px border in --ds-line, card shadow, 28px padding. Laid out as an equal-height three-column grid, one column on mobile, 24px gap. === ICON CHIP === 48x48px, radius 14px, centred glyph at 1.4rem. Default background --ds-sun-soft, glyph colour --ds-sun-edge. === TRUST STRIP === A single centred flex row that wraps, 24px vertical and 32px horizontal gap. Each item is weight 700 at 0.9375rem in navy, preceded by a 22px teal circle containing a white check glyph. Sits directly beneath the hero. === LAYOUT === Container: width min(100% - 48px, 1120px), centred. Section padding-block: 96px desktop, 60px at 768px and below. No other section padding values are permitted. === COMPOSITION LAWS === 1. Content maxes at 1120px with 24px side padding. Sections 96px, 60px on mobile. No other values. 2. Page rhythm alternates: white section, then at most one saturated full-bleed block, then white again. Never two saturated blocks adjacent. Exactly one navy band mid-page plus the navy footer. 3. Saturated blocks meet white via one shared gentle single-crest wave SVG divider, the same curve reused and flipped everywhere. No diagonals, no blobs. 4. Zig-zag feature rows: two-column grid at 1.05fr text to .95fr image, 64px gap, image side alternates per row. Headline 6 words or fewer, body 45 words or fewer. Illustrations sit directly on the background with no card, frame or box. The hero banner is the one framed image, 20px radius. 5. Cards: white, radius 24px, 1px line border plus card shadow, 28px padding, equal-height three-column grid, one column on mobile, 24px gap. Icon chip is a 48px rounded square in a soft tint. 6. Characters and illustrations appear only in zig-zag image slots or peeking over section seams. Never floating cut-outs scattered in empty space. 7. Every section runs: eyebrow, then h2, then at most one short paragraph, then content. Centred intros max 62ch. 8. The trust strip sits directly under the hero as one compact row, wrapping 2x2 on mobile, with check icons in teal. 9. Stars use --ds-gold-star. Reviews are three-up white cards. 10. Mobile: single column, image above text in zig-zag rows, full-width buttons, white space preserved. === HARD BANS === No gradients. No diagonal, rotated or scattered elements. No floating cut-out people. No text over photos. No second display font. No invented numbers or testimonials. No section padding outside the spec. === CHILD MODE === Child screens layer these overrides on top of everything above: - Body font-size 1.15rem, line-height 1.5. - Eyebrows 1rem. - Child button: min-height 56px, font-size 1.5rem, weight 700, padding 0.9rem 1.8rem, background --child-amber #E4941A, text white, gap 0.6rem. - Child radius: 1.5rem. Minimum tap target: 44px. - Child palette, brighter than the parent side: --child-amber #E4941A, --child-amber-soft #FCE4B8, --child-forest #3E7566, --child-forest-soft #CFE9DE, --child-sky #2E86AB, --child-berry #C2447A, --child-paper #FFFBF2. Child mode is applied by adding a class to a wrapper element. It is not driven by session state. === PER-CHILD IDENTITY PALETTE === Five hues assigned deterministically per child, each with a solid and a soft tint: --chip-1 #C2447A / #F7DCE8 --chip-2 #2E86AB / #D9EAF3 --chip-3 #3E7566 / #DCEEE7 --chip-4 #E4941A / #FBE7C7 --chip-5 #6C5B7B / #E7E1ED === PACE INDICATOR TONE === Ahead and on-track use the positive forest tone. Behind uses a calm amber. Never red, never shaming. This is a stated rule in the code, not an accident. === EXISTING COMPONENTS === SiteHeader, SiteFooter, WaveDivider, AustraliaMap, ChildChip, HomeTrail, InterestsEditor, LanternGlow, LanternTip. Buttons, cards, inputs and badges exist as CSS classes rather than components. === REFERENCES THE SYSTEM WAS BUILT FROM === Duolingo: layout grammar, whitespace, chunky buttons, zig-zag rows. Euka: saturated colour blocking, navy anchor band. godslittlelightkeepers.com: warmth, wave dividers, trust strip, review cards.