MindAbs Design System
Overview
MindAbs presents a refined dark-mode educational experience that feels equal parts academic institution and modern SaaS product. The design rests on a deep navy canvas—{colors.surface} at #1a1a2e—that creates an intimate, focused environment for reasoning practice. Against this near-black stage, warm gold ({colors.accent}) provides the sole brand voltage, reserved almost exclusively for interactive elements: the Register CTA, statistical callouts, and the circular logo mark. This restrained palette choice signals premium positioning without resorting to the saturated purples or electric blues common in ed-tech.
The typographic system represents the design's most distinctive move. Headlines deploy Fraunces—an elegant variable serif with soft, organic curves—at substantial sizes ({typography.display-xl} at 58px) but remarkably modest weights (never exceeding 400). The result reads as confident rather than shouty, scholarly rather than salesy. Body copy switches to Inter, the workhorse sans-serif, at a generous 19px ({typography.body-md}) with relaxed line-height (1.55), ensuring the philosophical content—"Build the mind that builds everything else"—breathes comfortably. This serif/sans pairing creates immediate hierarchy without requiring bold weights or uppercase transformations.
Shape language leans conservative: {rounded.DEFAULT} at 8px for most containers, {rounded.lg} at 12px for the signature stats card, and {rounded.full} for icon-only buttons and the logo mark. Nothing exceeds 12px except purely circular elements, which keeps the interface feeling structured rather than playful—an appropriate choice for a product targeting reasoning development in children aged 6–16. The one exception is the glassmorphic header, which uses backdrop-blur and a 95%-opacity surface tint to create depth without shadow.
Two sub-systems are detectable: the marketing hero dialect (dark background, cream serif headlines, gold CTAs, stats card) and what appears to be a content-section dialect (cream background {colors.surface-cream}, dark ink text) visible in the lower portion of the viewport. These likely alternate in a band pattern down the landing page.
Key Characteristics:
- Dark-first canvas (
{colors.surface}— #1a1a2e) with cream-white ({colors.cream}) as the primary light text token - Gold accent (
{colors.accent}— #c9a24b) exclusively on CTAs, stats, and brand marks—never as a background wash - Fraunces serif for all headline and display roles; Inter sans-serif for UI and body text
- Modest type weights (400 for everything except buttons/labels at 600)—hierarchy comes from size and color contrast, not weight
- Glass-elevation header with
{colors.surface-elevated}at 95% opacity plus backdrop-blur - Signature
{component.stats-card}with 1px{colors.hairline}border, no fill, containing{typography.title-md}gold stat values - Section alternating between dark hero bands and cream content bands
- Tab components using filled-background active state vs. transparent inactive state
Colors
Brand & Accent
- Primary (
{colors.primary}— #1a1a2e): The deep navy that serves as both the main brand color and the dominant surface background. Used for the page canvas, header background, filled tab states, and all dark text on light surfaces. - Primary Active (
{colors.primary-active}— #14132b): Slightly deepened variant for pressed/focused states on primary-colored surfaces. - Accent / Gold (
{colors.accent}— #c9a24b): The sole brand-voltage color. Appears on the primary{component.button-gold}, the circular logo mark, stat value numbers, and the "Reasoning Development" overline. Warm, muted gold—never neon or saturated. - Accent Light (
{colors.accent-light}— #e7cf93): Lighter gold variant used for the largest stat value ("Thousands") where emphasis is needed against the dark card. - Accent Hover (
{colors.accent-hover}— #b8923f): Darkened gold for hover/active states on the primary button.
Surface
- Canvas (
{colors.canvas}— #ffffff): Pure white, used sparingly—likely for modal interiors or authenticated-app surfaces not visible in this viewport. - Surface / Surface Soft (
{colors.surface}/{colors.surface-soft}— #1a1a2e): The dominant dark background. Covers the hero band, header, and any dark-section real estate. - Surface Strong (
{colors.surface-strong}— #121121): Deepest navy, potentially for nested cards or deeply-elevated modals. - Surface Elevated (
{colors.surface-elevated}— rgba(26, 26, 46, 0.95)): 95%-opacity navy with backdrop-blur for the sticky header, creating glassmorphic depth. - Surface Cream (
{colors.surface-cream}— #faf7ef): Warm off-white used for alternating content sections below the hero. Provides visual rhythm and houses dark-ink text. - Surface Glass (
{colors.surface-glass}— rgba(255, 255, 255, 0.02)): Near-invisible white tint (2% opacity) for hover states on icon buttons within the dark context.
Text
- Ink (
{colors.ink}— #1a1a2e): Darkest text color, used on light (cream/white) surfaces for body copy and headings. - Body / Muted (
{colors.body}/{colors.muted}— #6b6857): Medium-warm-gray tone. Used for secondary text on light surfaces, inactive tab labels, and stat description copy. - Muted Soft (
{colors.muted-soft}— rgba(250, 247, 239, 0.72)): Cream at 72% opacity—the primary body text color on dark surfaces. Provides softened contrast that reduces eye strain in dark-mode reading. - Cream (
{colors.cream}— #faf7ef): The primary light text color on dark surfaces. Used for headlines, nav links, button text (ghost), and high-emphasis copy. - Cream Muted (
{colors.cream-muted}— rgba(250, 247, 239, 0.7)): Cream at 70% opacity for icon-button fills and lower-emphasis navigational text. - On Primary (
{colors.on-primary}— #ffffff): Pure white, reserved for text sitting directly on{colors.accent}(gold) buttons. - On Dark (
{colors.on-dark}— #faf7ef): Alias for cream—text on dark surfaces. - On Accent (
{colors.on-accent}— #1a1a2e): Dark navy text on gold/accent backgrounds. - On Surface (
{colors.on-surface}— #faf7ef): Alias for cream—default text-on-surface token.
Hairlines & Borders
- Hairline (
{colors.hairline}— rgba(250, 247, 239, 0.1)): 10%-opacity cream border. Used for the header bottom edge and the stats card perimeter. Nearly invisible but provides structural definition. - Border Cream (
{colors.border-cream}— #faf7ef): Full-opacity cream border for the ghost button's visible outline. - Border Subtle (
{colors.border-subtle}— rgba(250, 247, 239, 0.15)): 15%-opacity cream for dividers inside the stats card between stat items.
Semantic
- Error (
{colors.error}— #c4622d): Burnt orange, detected in the color palette but not visible in the current viewport. Likely for validation states or destructive actions. - Success (
{colors.success}— #2e8b6f): Teal/green, present in the palette for success confirmations. - Info (
{colors.info}— #8b7ff8): Soft purple, available for informational badges or tooltip accents. - Neutral Gray (
{colors.neutral-gray}— #8a8a8a): True gray for disabled states or metadata outside the warm color story.
Typography
Font Family
The system employs a deliberate two-face strategy. Fraunces (a soft-serif variable font by Underware) handles all expressive typography: the hero headline at 58px, the stats-card values at 36px, the "Reasoning Development" overline, and likely any H2/H3 headings deeper in the page. Its organic, slightly irregular letterforms signal humanism and approachability—appropriate for a product about developing young minds. The fallback stack includes "Fraunces Fallback", ui-serif, Georgia, and finally serif, ensuring graceful degradation.
Inter (by Rasmus Andersson) serves as the UI and body face. It renders the 19px hero subhead, all button labels, tab text, navigation links, and stat descriptions. Inter's tall x-height and open apertures maintain readability at the relatively small sizes used for body copy on dark backgrounds. The fallback chain routes through "Inter Fallback" (a metric-mapped Arial), ui-sans-serif, system-ui, and sans-serif. A third face—DM Sans—appears in the font data (10 instances) but is not visible in the above-fold viewport; it may serve an authenticated-app or dashboard sub-system.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 58px | 400 | 1.12 | -0.58px | Hero headline (H1) |
| {typography.display-lg} | 58px | 400 | 1.12 | -0.58px | Large display text (alias) |
| {typography.title-md} | 36px | 400 | 1.12 | -0.36px | Stat values, H2 headings |
| {typography.title-sm} | 16.5px | 400 | 1.2 | -0.165px | Small serif labels, H3 |
| {typography.body-md} | 19px | 400 | 1.55 | 0 | Hero paragraph, body copy |
| {typography.body-sm} | 15px | 400 | 1.5 | 0 | Stat descriptions, secondary text |
| {typography.button} | 15px | 600 | 1.33 | 0 | Button labels, CTAs |
| {typography.label} | 14px | 600 | 1.43 | 0 | Tab labels, filter chips |
| {typography.overline} | 12px | 600 | 1.33 | 0.08em | "Reasoning Development" label |
Principles
The typography system's most striking characteristic is its weight restraint. Every serif role (display through title-sm) sits at exactly font-weight: 400. No bold. No semi-bold. The system achieves hierarchy through three mechanisms instead: size differential (58px → 36px → 16.5px is a 3.5× range), color contrast (cream at full opacity for headlines vs. 72% opacity for body), and letter-spacing tightening (negative tracking proportional to size: -0.58px at 58px, -0.165px at 16.5px). This negative tracking is a classic editorial technique that pulls large serif characters together for optically tighter word-shapes.
The sans-serif roles break the 400-weight rule only for interactive elements: buttons and tabs jump to 600. This creates a functional hierarchy—users learn that heavier text means "clickable"—without muddying the editorial voice of the content. The overline role adds text-transform: uppercase combined with expanded letter-spacing (+0.08em), a standard pattern for category labels that ensures the "Reasoning Development" tag reads as metadata rather than content.
Line heights are notably generous: 1.55 for body copy (vs. the typical 1.4–1.5) accommodates the dark-mode context where slightly looser leading improves readability. Display text sits tighter at 1.12, allowing the massive 58px headline to feel compact rather than sprawling.
Note on Font Substitutes
Fraunces is available on Google Fonts (https://fonts.google.com/specimen/Fraunces) and can be loaded as a variable font with weight range 100–900. For the specific optical size used here (58px–16.5px), the default Fraunces instance works well. If Google Fonts is unavailable, Lora (also a soft serif with similar warmth) or Source Serif Pro provide acceptable fallbacks with adjusted size offsets (-2% for Lora).
Inter is available at https://rsms.me/inter/ or via Google Fonts. The "Inter Fallback" defined in the @font-face block uses local Arial with metric overrides to match Inter's dimensions nearly exactly. If Inter cannot be loaded, Plus Jakarta Sans or Nunito Sans offer similar geometric-sans traits with tall x-heights suitable for dark-mode UI.
CSS variables to define for font configuration:
--font-serif: "Fraunces", "Fraunces Fallback", ui-serif, Georgia, serif;
--font-sans: "Inter", "Inter Fallback", ui-sans-serif, system-ui, sans-serif;
Layout
Spacing System
- Base unit: 4px (inferred from the 8/12/16/20 progression).
- Tokens:
{spacing.xxs}(2px — micro-adjustments),{spacing.xs}(4px — icon gaps),{spacing.sm}(8px — internal element spacing),{spacing.md}(12px — compact padding),{spacing.base}(16px — standard padding),{spacing.lg}(20px — comfortable padding),{spacing.xl}(25px — loose padding),{spacing.xxl}(40px — section-internal spacing),{spacing.section}(120px — major vertical band padding),{spacing.nav-height}(60px — fixed header height). - Section padding (vertical):
{spacing.section}(120px) — used on the hero band and likely all major landing-page sections. - Card internal padding:
{spacing.xxl}(40px) — the{component.stats-card}uses this generously padded interior. - Gutters: The main content container appears to use
{spacing.base}(16px) horizontal padding on mobile, collapsing to auto-centered withmax-width: 1200pxon desktop.
Grid & Container
- Max content width: 1200px for the centered marketing container (derived from the header's
max-w-[1200px]class). - Density choice: Editorial-airy. The hero places a single column of text (roughly 600–650px wide) alongside a ~360px stats card, with significant whitespace between them. This is not a dense dashboard—it's a narrative landing page.
- Grid behavior at desktop: The hero uses a two-column asymmetric grid: left column (~60% width) holds the overline + headline + subhead + CTAs; right column (~35% width) holds the
{component.stats-card}. The gap between them appears to be approximately{spacing.xxl}(40px) or slightly more. - Hero column splits: Text column is left-aligned with no indent; stats card is top-aligned with the headline baseline (not the overline), creating a visually anchored composition.
Whitespace Philosophy
The system practices generous vertical rhythm and constrained horizontal width. The 120px section paddings create a slow, scrollable cadence—each band feels like a "page" in its own right. Horizontally, content never spans full-viewport; the 1200px max-width ensures lines of body text (19px) stay within optimal 65–80 character counts. This is editorial whitespace, not marketplace density: the design trusts that the reader will invest time and rewards that investment with breathing room.
Header Architecture
┌─────────────────────────────────────────────────────────────────┐
│ [○ Logo] What's Inside The Research NCI Assessment Sign In [Register] │
└─────────────────────────────────────────────────────────────────┘
↑ ↑
px-4 (mobile) px-4 (mobile)
max-w-[1200px] centered max-w-[1200px] centered
h-[60px] fixed sticky h-[60px] fixed sticky
bg-{surface-elevated} + backdrop-blur border-b {colors.hairline}
The header is sticky (sticky top-0 z-50), 60px tall, with a bottom border of {colors.hairline} (10% cream). The logo (gold circle + "MindAbs" wordmark in Fraunces) sits flush left. Navigation links (What's Inside, The Research, NCI Assessment) center-left with gap-6 (24px) on desktop, collapsing on mobile. Flush right: "Sign in" text link and the gold {component.button-gold} Register button.
Hero Section
┌─────────────────────────────────────────────────────────────────┐
│ │
│ REASONING DEVELOPMENT ┌──────────────┐ │
│ │ 6–16 │ │
│ Build the mind │ The ages... │ │
│ that ├──────────────┤ │
│ builds everything else. │ Thousands │ │
│ │ Of real-life...│ │
│ Every child is taught what to think... ├──────────────┤ │
│ │ ~15 min │ │
│ [Register] [See a sample report] │ A session... │ │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
↑ ↑
{colors.surface} background {colors.hairline} border
{typography.overline} gold {component.stats-card}
{typography.display-xl} cream {typography.title-md} gold values
{typography.body-md} muted-cream {typography.body-sm} muted labels
The hero follows a classic left-text, right-object layout. The overline ("REASONING DEVELOPMENT") sits in {typography.overline} at {colors.accent} (gold), uppercase, with 0.08em letter-spacing. The H1 ("Build the mind that builds everything else.") wraps across three lines in {typography.display-xl} (58px Fraunces, cream, -0.58px tracking). Notably, "builds everything else." receives a gold underline decoration—a rare inline brand-color accent within body text. The subhead paragraph follows in {typography.body-md} (19px Inter, {colors.muted-soft}). Below, two CTAs sit in a flex row with {spacing.lg} (20px) gap: the primary {component.button-gold} and secondary {component.button-ghost}.
The stats card floats right, top-aligned roughly with the headline's first line. It contains three stat groups separated by {colors.border-subtle} horizontal rules. Each group has a gold {typography.title-md} value and a {typography.body-sm} muted description.
Stats Card Component
The {component.stats-card} is the hero's signature element. It has no background fill (transparent), relying entirely on its 1px {colors.hairline} border and {rounded.lg} (12px) corners to define its shape against the dark surface. Interior padding is {spacing.xxl} (40px) on all sides. The three stats (age range "6–16", volume "Thousands", duration "~15 min") use gold-colored values to draw the eye, while their descriptions recede into {colors.muted}. Horizontal dividers ({stat-divider}) use {colors.border-subtle} at 15% cream opacity—visible enough to separate, faint enough not to compete.
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| 0 (Flat) | No shadow, no border | Base surfaces: {colors.surface}, {colors.surface-cream} |
| 1 (Hairline) | 1px border {colors.hairline} (10% cream) | Header bottom edge, stats card perimeter |
| 2 (Glass) | {colors.surface-elevated} (95% opacity) + backdrop-blur | Sticky navigation header |
| 3 (Border-visible) | 1px solid {colors.border-cream} (full opacity) | Ghost button outline |
| 4 (Fill-elevation) | Solid {colors.surface} fill | Active tab state |
Philosophy: MindAbs employs a flat-to-glass elevation model, avoiding traditional drop shadows almost entirely (no box-shadow detected in the extracted data). Depth is communicated through opacity layering (the 95% header tint), border presence/absence (hairline edges define containment), and solid background fills (active tabs "lift" by filling with {colors.surface}). This shadowless approach suits the dark-mode context where shadows would be invisible or muddy. The glass header is the sole "fancy" elevation treatment, and even it relies on backdrop-blur rather than shadow for its effect.
If decorative depth exists elsewhere on the page (gradient meshes, noise textures, illustration layers), it was not visible in the above-fold viewport. The hero appears to use a flat {colors.surface} fill with no gradient, no noise, no image—pure color-and-type minimalism.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.xs} | 3px | Small internal elements, badge corners |
| {rounded.sm} | 7px | Tab components, small buttons |
| {rounded.DEFAULT} | 8px | Primary button, ghost button, standard containers |
| {rounded.md} | 10px | General-purpose medium rounding |
| {rounded.lg} | 12px | Stats card, larger panels |
| {rounded.full} | 9999px | Icon buttons, logo mark circle |
Pattern: The radius scale progresses in small increments (3→7→8→10→12) before jumping to infinite for circular elements. This granularity suggests intentional differentiation: tabs at 7px feel slightly sharper than CTA buttons at 8px, while the stats card at 12px reads as distinctly more "container-like." Nothing uses extremely round (24px+) non-circular radii, keeping the interface feeling precise rather than bubbly.
Photography Geometry
No photography, illustrations, or imagery were visible in the above-fold viewport. The hero is purely typographic + the stats card. If imagery exists lower on the page, its aspect ratios and corner treatments could not be determined from the provided screenshot.
Components
No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the
components:frontmatter (e.g.{component.button-gold-hover},{component.tab-active}); add hover styling at implementation time per your stack's conventions.
Buttons
{component.button-gold} — The primary call-to-action button. Background {colors.accent} (gold), text {colors.on-accent} (dark navy) in {typography.button} (15px Inter, weight 600). Rounded {rounded.DEFAULT} (8px), padding 13px 25px. No shadow, no border. This button appears twice: once in the top-nav's far-right slot ("Register") and once as the hero's primary CTA. Its hover/active state is {component.button-gold-hover}, which darkens the background to {colors.accent-hover}.
{component.button-gold-hover} — Active/hover state for the gold button. Background shifts to {colors.accent-hover} (darkened gold). All other properties inherit from {component.button-gold}. Implement with transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1).
{component.button-ghost} — Secondary CTA with transparent background and visible border. Text {colors.cream} in {typography.button}, rounded {rounded.DEFAULT}, padding 13px 25px. Border is 1px solid {colors.border-cream} (full-opacity cream). Used for "See a sample report" in the hero. On hover, expect background to gain subtle {colors.surface-glass} (2% white) fill and/or border to brighten.
{component.button-icon-circle} — Square icon-only button (mobile menu trigger, etc.). Size 36px (sm:h-9 sm:w-9), {rounded.full} (perfectly circular). Transparent background, text {colors.cream-muted} (70% opacity cream). Its hover state {component.button-icon-circle-hover} adds {colors.surface-glass} background and promotes text color to full {colors.cream}.
Cards & Containers
{component.stats-card} — The hero's signature right-rail element. Transparent background (no fill), defined by 1px {colors.hairline} border (10% cream), {rounded.lg} (12px) corners, and {spacing.xxl} (40px) internal padding. Contains three {stat-value} / {stat-label} pairs separated by {stat-divider} horizontal rules. This card is unique in the visible UI—no other bordered-transparent container appears above the fold.
{component.hero-band} — Full-viewport-width section with {colors.surface} (dark navy) background and {spacing.section} (120px) vertical padding. Houses the entire hero composition (overline, headline, subhead, CTAs, stats card).
{component.section-cream} — Alternating band section with {colors.surface-cream} (warm off-white) background and {spacing.xxl} (40px) vertical padding. Text color flips to {colors.ink} (dark navy) for readability. Visible at the bottom of the viewport as the next section begins.
Navigation
{component.top-nav} — Sticky header bar, height {spacing.nav-height} (60px). Background {colors.surface-elevated} (95% navy + backdrop-blur), creating a glass effect over scrolling content. Text color {colors.cream} for all nav elements. Contains {component.logo-mark}, {component.logo-text}, nav links, Sign In link, and {component.button-gold}.
{component.top-nav-border} — Bottom border treatment on the header: 1px solid {colors.hairline} (10% cream). Provides subtle separation between header and hero content.
{component.logo-mark} — Circular gold badge (32px, {rounded.full}) containing a triangle/warning icon in {colors.on-accent} (dark navy). Background {colors.accent}.
{component.logo-text} — "MindAbs" wordmark in {typography.title-md} (36px Fraunces, though rendered smaller in the nav context), color {colors.cream}.
{component.nav-link} — Navigation menu items ("What's Inside", "The Research", "NCI Assessment"). Text {colors.cream-muted} (70% opacity), {typography.body-sm}. Hover state ({component.nav-link-hover}) promotes to full {colors.cream}.
{component.nav-sign-in} — "Sign in" text link in the header's right slot. Color {colors.cream}, {typography.body-sm}.
Tabs & Filters
{component.tab} — Inactive tab/button (e.g., age-range selector "9–12"). Transparent background, text {colors.muted} (warm gray), {typography.label} (14px, weight 600), {rounded.sm} (7px), padding 8px 16px. No border.
{component.tab-active} — Active tab state (e.g., "6–8" or "6–16"). Background fills with {colors.surface} (solid navy), text becomes {colors.cream}. Same rounded, padding, and typography as inactive state. The filled-background treatment clearly distinguishes the active tab without requiring border or shadow.
Typography Components
{component.hero-overline} — "REASONING DEVELOPMENT" label above the headline. {typography.overline} (12px, weight 600, uppercase, +0.08em letter-spacing), color {colors.accent} (gold). Acts as a category tag.
{component.hero-headline} — H1 "Build the mind that builds everything else." {typography.display-xl} (58px Fraunces, weight 400, -0.58px tracking), color {colors.cream}. The phrase "builds everything else." receives a gold underline decoration (likely via a <span> or <mark> with custom styling).
{component.hero-subhead} — Paragraph below headline starting "Every child is taught what to think..." {typography.body-md} (19px Inter, weight 400, line-height 1.55), color {colors.muted-soft} (72% opacity cream).
{component.stat-value} — Large number inside stats card (e.g., "6–16", "Thousands", "~15 min"). {typography.title-md} (36px Fraunces), color {colors.accent-light} (light gold) for the middle stat or {colors.accent} (standard gold) for others.
{component.stat-label} — Description below each stat value (e.g., "The ages it's built for"). {typography.body-sm} (15px Inter), color {colors.muted} (warm gray).
{component.stat-divider} — Horizontal rule between stat items inside the card. 1px solid {colors.border-subtle} (15% opacity cream).
Do's and Don'ts
Do
- Do use
{typography.display-xl}(58px Fraunces, weight 400) for all H1 headlines—never increase the weight beyond 400 for serif text. - Do reserve
{colors.accent}(gold) exclusively for interactive elements, brand marks, and data highlights—never as a background wash or large-area fill. - Do apply
{colors.muted-soft}(72% opacity cream) for body copy on dark surfaces to reduce eye strain and establish hierarchy against{colors.cream}headlines. - Do use
{rounded.lg}(12px) for the stats card and any similar "signature container"—it should feel distinctly more rounded than standard{rounded.DEFAULT}(8px) buttons. - Do implement the sticky header with
{colors.surface-elevated}(95% opacity) andbackdrop-blur—this glass treatment is the system's only elevation mechanism. - Do maintain
letter-spacingnegative for all Fraunces display text (proportional to size: -0.58px at 58px, -0.36px at 36px) to achieve editorial tightness. - Do alternate between dark (
{colors.surface}) and cream ({colors.surface-cream}) section backgrounds to create visual rhythm down the landing page. - Do use
{typography.label}(14px, weight 600) for tab and filter elements, switching between{colors.muted}(inactive) and{colors.cream}(active) with background fill change. - Do keep button padding at
13px 25pxfor both{component.button-gold}and{component.button-ghost}to maintain consistent click-target sizing. - Do apply
{colors.hairline}(10% cream) borders for structural definition on the header and stats card—avoid thicker or higher-contrast borders unless indicating focus/validation states.
Don't
- Don't use
{colors.accent}(gold) for body text, headings, or paragraph content—it's reserved for CTAs, stats, and brand marks only. - Don't bold Fraunces headlines—the system achieves hierarchy through size (58px→36px) and color contrast, not weight increases beyond 400.
- Don't add drop shadows to cards or buttons—the system uses opacity-layering, borders, and background fills for depth; shadows don't appear in the extracted CSS.
- Don't use
{colors.canvas}(white) as a background for marketing sections—the dark-mode story relies on{colors.surface}and{colors.surface-cream}alternation. - Don't let tab active states rely solely on text color change—always pair
{colors.cream}text with{colors.surface}background fill (see{component.tab-active}). - Don't expand the radius vocabulary beyond the defined scale (
{rounded.xs}through{rounded.full})—no 16px, 20px, or 24px non-circular radii exist in this system. - Don't use font sizes between the defined tokens (e.g., 24px, 28px, 42px)—the type scale jumps from 16.5px→19px→36px→58px intentionally.
- Don't apply
text-transform: uppercaseoutside of{typography.overline}—the system avoids uppercase in headlines and body copy for a measured, scholarly voice. - Don't substitute
{colors.ink}(#1a1a2e) for{colors.surface}when they share the same hex—they serve different semantic roles (text vs. background) and should remain separate tokens for future divergence. - Don't place light text (
{colors.cream}) directly on{colors.surface-cream}—always switch to{colors.ink}on cream backgrounds to maintain accessibility.
Motion & Animation
Transition Tokens
--transition-standard: color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
--transition-transform: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
The extracted CSS reveals a comprehensive "all-properties" transition declaration (the Tailwind transition-all utility) using a 150ms duration with cubic-bezier(0.4, 0, 0.2, 1) ease (the standard Material Design ease-in-out curve). This applies to color, background, border, shadow, transform, opacity, and even backdrop-filter and display changes. A second, more targeted transition handles transform and shadow independently (likely for hover-lift effects).
Keyframe Animations
dc-reveal— Scroll-triggered reveal animation for content sections (likely fade-up + slight translate).mindabs-breathe— Subtle ambient scale/opacity pulse, probably applied to the logo mark or decorative background elements.mindabs-ripple— Ripple effect for click/tap feedback on interactive elements.mindabs-blob— Organic shape morphing for background decorative blobs (if any exist lower on the page).mindabs-dot— Pulsing dot animation for loading or attention states.sos-star-pulse— Star/badge pulse animation (possibly for achievement or gamification elements).spin— Standard rotation (loading spinners).ping— Radial expansion pulse (notification dots).pulse— Opacity pulse (generic attention-drawing).swipe-out-*(left/right/up/down) — Dismissal animations for toast notifications or removable elements.sonner-fade-in/out— Toast notification library (Sonner) enter/exit animations.sonner-spin— Spinner within Sonner toast notifications.
Interaction Patterns
- Hover color shift: Nav links, icon buttons, and ghost buttons transition text color from
{colors.cream-muted}to{colors.cream}over 150ms. - Hover background reveal: Icon buttons gain
{colors.surface-glass}(2% white) background on hover; tabs switch from transparent to{colors.surface}fill. - Button darkening:
{component.button-gold}background shifts from{colors.accent}to{colors.accent-hover}on press/hover. - Scroll-triggered reveal: Sections likely fade-up and translate-y slightly into view via
dc-revealkeyframe (IntersectionObserver-driven). - Sticky header gain: As the user scrolls past the hero, the header may transition from transparent to
{colors.surface-elevated}(already elevated in the static screenshot). - Toast notifications: Sonner library integration provides swipe-to-dismiss toasts with
swipe-out-*andsonner-fadeanimations. - Ambient breathing: Background decorative elements (logo, possibly floating shapes) use
mindabs-breathefor subtle life-like motion.
Imagery Style
- The above-fold viewport contains no photographs, illustrations, 3D renders, or gradient graphics—the hero is purely typographic with the stats card.
- The design relies on type-as-visual: the 58px Fraunces headline IS the hero image, with the gold underline on "builds everything else." serving as the sole graphic embellishment.
- If imagery exists below the fold (user testimonial photos, app screenshots, illustration scenes), it was not captured in this viewport and cannot be characterized.
- The logo mark (gold circle with triangle icon) is the only graphical element visible—a minimalist geometric symbol suggesting "alertness" or "attention" fitting the reasoning-development theme.
- Color treatment for any future imagery would likely follow the warm-toned, low-contrast philosophy: images would be desaturated slightly or overlaid with subtle
{colors.surface}tints to harmonize with the dark canvas. - Expect full-bleed imagery in cream-background sections (alternating band pattern) to break up the typographic density, possibly with
{rounded.lg}or{rounded.xl}corner treatment.
Icon System
- Library: Lucide (detected via
lucidein the framework's iconLibs array and consistent stroke-icon geometry). - Specific icons observed:
- AlertTriangle (or similar warning/caution icon) — inside the gold
{component.logo-mark}circle. - Menu (hamburger) — inside the mobile
{component.button-icon-circle}(visible in classes asmd:hidden). - Potentially: external-link icons, chevron-down (for dropdowns), checkmarks (for validation) — these are inferred from typical landing-page patterns but not explicitly visible in the screenshot.
- AlertTriangle (or similar warning/caution icon) — inside the gold
- Treatment: Stroke-based icons (not fill), colored with
currentColor(inheriting from parent{colors.cream-muted}or{colors.cream}). Size appears to be 16px–20px based on the 32px–36px button containers. Icons align centrally within their circular button containers via flexbox (items-center justify-center).
Recommended Frontend Stack
- Framework: Next.js (App Router) — detected via __next_f script tags and RSC payload
- Styling: Tailwind CSS v3+ — confirmed by utility class naming (max-w-, rounded-, gap-, etc.)
- Fonts: Self-hosted WOFF2 (Inter variable 100–900, Fraunces variable 100–900) with @font-face declarations and metric override fallbacks
- Animation: Tailwind transition utilities + custom @keyframes (dc-reveal, mindabs-*, sonner-*)
- Icons: Lucide React (@lucide/react)
- Component lib: Custom components (no shadcn/radix detected — likely hand-built or headless UI primitives)
- Toast: Sonner (detected via sonner-fade/spin keyframes)
Responsive Behavior
Breakpoints
| Name | Width | Key Changes |
|---|---|---|
| Mobile | < 640px | Single-column hero (stats card stacks below text), hamburger menu visible, reduced spacing |
| Tablet (sm) | ≥ 640px | Icon button grows to 36px, nav gap increases to 16px |
| Desktop (md) | ≥ 768px | Full nav links visible, hamburger hides (md:hidden), two-column hero layout |
| Large (lg) | ≥ 1024px | Max-content width (1200px) fully utilized, generous gutters |
Touch Targets
{component.button-gold}: ~51px height (13px × 2 padding + ~25px content) × ~115px width (25px × 2 + ~65px text) — exceeds WCAG AAA 44×44 minimum.{component.button-ghost}: Same dimensions as gold button — exceeds minimum.{component.button-icon-circle}: 36×36px (desktop) / 32×32px (mobile) — below 44×44 on mobile; consider increasing to 44px for touch accessibility or ensuring adequate surrounding whitespace.{component.tab}: ~38px height (8px × 2 + ~22px content) × ~100px+ width — within acceptable range but tight on height.- Nav links: Inherit line-height from
{typography.body-sm}(~21px) — below 44px; these are typically exempt as non-action links, but consider tap area padding.
Collapsing Strategy
- Navigation: Desktop shows full link row (What's Inside, The Research, NCI Assessment, Sign In, Register). Mobile collapses to: Logo (left) + Hamburger icon (right). Register button moves into mobile menu or remains visible as a small button.
- Hero layout: Mobile stacks vertically: overline → headline → subhead → CTAs → stats card (full-width, below CTAs). Desktop uses two-column asymmetric grid (text left ~60%, card right ~35%).
- Stats card: On mobile, likely stretches full content width with internal padding reduced from
{spacing.xxl}(40px) to{spacing.lg}(20px). The three stats may reflow from vertical stack to horizontal row if space permits, or remain stacked. - Header padding: Mobile uses
px-4(16px horizontal); desktop collapses topx-1(4px) within the 1200px max-width centered container. - Button sizing: Padding remains
13px 25pxacross breakpoints, but font-size may reduce to 14px on mobile (not explicitly detected but common pattern).
Image Behavior
- No hero imagery visible in the screenshot to characterize. If app-screenshots or illustrations appear lower on the page:
- Desktop: Likely displayed at 50–70% viewport width, possibly with
{rounded.lg}corners, positioned alongside text columns. - Mobile: Would expand to full-width (with 16px gutter), maintaining aspect ratio, potentially with reduced corner radius (
{rounded.md}or{rounded.DEFAULT}). - Lazy loading: Expected via Next.js Image component or native
loading="lazy"for below-fold visuals.
- Desktop: Likely displayed at 50–70% viewport width, possibly with
Iteration Guide
-
Build a landing page that closely mimics the design system in this DESIGN.md. Use Next.js with Tailwind CSS (the apparent production stack), pulling every color, font, radius, and spacing value from the YAML frontmatter via the
{section.token}paths. Never hard-code a value that has a token. -
Set up fonts first: Define
@font-facedeclarations for Inter (variable, 100–900) and Fraunces (variable, 100–900) using the provided WOFF2 URLs or substitute from Google Fonts/CDN. Create CSS variables--font-serifand--font-sansmapping to the full fallback stacks shown in the typography section. -
Implement the dark-first color mode: Set
background-color: {colors.surface}(#1a1a2e) andcolor: {colors.cream}(#faf7ef) as the body defaults. Build the alternating-band pattern (dark hero → cream section → dark section) using{component.hero-band}and{component.section-cream}as templates. -
Construct the sticky glass header (
{component.top-nav}) withposition: sticky; top: 0; z-index: 50; backdrop-filter: blur(), using{colors.surface-elevated}(95% opacity navy) and the 1px{colors.hairline}bottom border. Ensure it contains the logo (gold circle + Fraunces wordmark), nav links, Sign In, and Register button per the ASCII diagram. -
Build the hero section as a two-column grid (desktop) / single-column stack (mobile). Left column: overline (
{typography.overline}, gold) → headline ({typography.display-xl}, 58px Fraunces, cream, -0.58px tracking) → subhead ({typography.body-md}, 19px Inter, muted-cream) → CTA pair ({component.button-gold}+{component.button-ghost}with 20px gap). Right column:{component.stats-card}with transparent background, hairline border, 12px radius, 40px padding, three stat groups with gold values and dividers. -
Add state variants (
-hover,-active) per Tailwind conventions:hover:bg-[var(--accent-hover)]for the gold button,hover:text-[var(--cream)]for nav links,hover:bg-[var(--surface)]for tabs. The spec documents Default and Active/Pressed only; derive hover from active or add intermediate states as needed. -
When adding new components, decide which sub-system they belong to: marketing-hero dialect (dark background, cream text, gold accents, Fraunces headlines) or content-section dialect (cream background, dark ink text). Maintain strict separation—don't use gold text on cream backgrounds or cream text on cream backgrounds.
-
Variants of an existing component live as separate frontmatter entries (
button-gold-hover, never nested underbutton-gold). Each variant repeats only the properties that differ from the base; inherit the rest mentally (or via CSS class composition). -
Integrate animation keyframes for scroll-reveal (
dc-reveal), ambient motion (mindabs-breathe), and toast notifications (Sonner library withsonner-fade-in/out). Applytransition-all(or the more targeted--transition-standard) with 150ms duration andcubic-bezier(0.4, 0, 0.2, 1)ease to all interactive elements. -
Run accessibility checks: Verify contrast ratios meet WCAG AA (4.5:1 for normal text, 3:1 for large text). Key pairs to validate:
{colors.cream}on{colors.surface}(headline),{colors.muted-soft}on{colors.surface}(body),{colors.on-accent}on{colors.accent}(button text),{colors.ink}on{colors.surface-cream}(cream-section text).
Font Setup: Map proprietary fonts to Google Fonts equivalents if self-hosting isn't possible:
- Fraunces → Available on Google Fonts (weight range 100–900, optical sizing supported). Load as
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,100..900&display=swap" rel="stylesheet">. - Inter → Available on Google Fonts or rsms.me. Load as
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">. - Define CSS variables:
--font-serif: 'Fraunces', 'Fraunces Fallback', ui-serif, Georgia, serif; --font-sans: 'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif;.
Known Gaps
- Hover state styling: Per the no-hover policy, exact hover colors, transforms, and background changes for buttons, nav links, tabs, and icon buttons are inferred from the active/pressed states and standard patterns—not extracted from interaction.
- Loading skeletons / pending states: No skeleton screens, spinners (beyond the generic
spinkeyframe), or empty-state designs visible in the screenshot. - Form validation states: Beyond the detected tab component, no text inputs, checkboxes, radio buttons, or error/success validation styles appear above the fold.
- Dashboard / authenticated surfaces: The screenshot captures only the unauthenticated landing page. Post-login interfaces (student dashboard, parent view, admin panel) may introduce new components, colors, or layout patterns not represented here.
- Mobile-specific layouts: While responsive classes (
md:hidden,sm:h-9) hint at mobile behavior, the actual mobile-rendered DOM (stacked hero, collapsed nav, full-width stats card) was not captured as a separate screenshot. - Below-fold sections: Content below the stats card (features, testimonials, pricing, FAQ, footer) is not visible. These sections may introduce new component types (testimonial cards, pricing tables, accordion items) and potentially new color tokens.
- Pixel-exact values for oklab colors: Several colors in the extracted CSS use
oklab()notation (e.g., the header background, cream-muted text). These have been approximated to sRGB hex values for the design tokens, but the actual perceptual rendering may differ slightly in color-gamut-sensitive displays. - Misleading CSS variables: The
btn-goldandbtn-ghostclass names correctly signal their visual treatment, but the generictab/tab activenaming doesn't distinguish between age-range selectors and potential other tab usage (pricing tier, content category). Context matters for correct implementation.