Foundations
Responsive
One breakpoint scale, three design tiers, one authoring convention. The grid is Bootstrap’s and is mobile-first; component CSS layers a small set of desktop-first overrides on top. This page is the single source of truth for how anything in the system behaves across viewports.
Overview
- The scale is Bootstrap 5’s. 576 / 768 / 992 / 1200 / 1400 px. We add no custom cuts and remove none.
- Three design tiers, not five. Designers plan three layouts — Mobile, Tablet, Desktop. The xs/sm split and xl/xxl steps are refinements (tight-phone tweaks, container width), never separate layouts.
- Markup first. Column behaviour belongs in Bootstrap grid classes (
col-12 col-md-6 col-lg-4). Component CSS only handles what the grid can’t: structural reflows, density changes, repositioning. - Intrinsic before breakpoints. Prefer
repeat(auto-fit, minmax()),flex-wrap, andclamp()— half the system’s components (badge, alert, modal, forms…) need no width media query because their layout is intrinsic or grid-driven. That is the goal state, not a gap. - Tokens can’t enter media queries (a CSS limitation), so the canonical values live here and as a reference block in
tokens.css.
Breakpoint Standard
| Key | Min width | Design tier | What changes here |
|---|---|---|---|
xs | 0 | Mobile | Base layout: single column, stacked nav, compressed rhythm |
sm | 576 px | Refinement only — wider cards, inline pagination, restored hero radius | |
md | 768 px | Tablet | Two-column grids, side-by-side media, restored section rhythm |
lg | 992 px | Desktop | The big switch: full navigation bar + mega menu, hero overlay positioning, sidebars, 3–4 column grids |
xl | 1200 px | Container widens to 1140 px — no layout change | |
xxl | 1400 px | Container widens to 1320 px — no layout change |
The .98px convention
Max-width queries always subtract .02px from the next breakpoint (575.98 / 767.98 / 991.98) — Bootstrap’s own convention. A max-width: 992px query and a min-width: 992px query are both true at exactly 992 px and double-fire; the .98 form makes that impossible.
Design Tiers
Every page and component is designed at three widths. Hand off three artboards — 375 px (Mobile), 834 px (Tablet), 1440 px (Desktop) — and rely on the rules below for everything in between.
| Mobile < 768 | Tablet 768–991.98 | Desktop ≥ 992 | |
|---|---|---|---|
| Design artboard | 375 px | 834 px | 1440 px |
| Columns | 1 (col-12) | 2 (col-md-6) | 3–4 (col-lg-4 / col-lg-3) |
| Navigation | Collapsed (toggler) | Collapsed (toggler) | Full bar + mega menu |
| Section rhythm | 48 px (--caat-space-7) | 64 px (--caat-space-8) | |
| Display type | 2.5 rem | 3.5 rem (--caat-font-size-5xl) | |
| Hero card | Stacked below media (negative-margin overlap) | Absolute overlay on media | |
| Touch targets | ≥ 44×44 px | ≥ 24×24 px (aim 44) | |
| Hover effects | Never required to discover or operate anything (touch) | Lift tiers per Interaction States | |
Mobile / Tablet / Desktop Plan
Mobile (< 768 px) — linearize and compress
- Everything single-column; source order is reading order (the grid never reorders content except
orderutilities used deliberately, e.g. feature-hero preview moves above text). - Section padding compresses one spacing step (64→48, 96→64, 48→32 px) —
layout.cssdoes this automatically. - Display headings step down (3.5→2.5 rem); body sizes never change.
- Buttons may go full-width via
.caat-button--full-mobile; pagination switches to the compact wrapper; breadcrumbs scroll horizontally rather than wrap. - Tables use
.caat-table--stacked(label/value rows) or live in a scroll container — never shrink type to fit. - Stat strips, footer columns, video rows, download rows: stack vertically.
Tablet (768–991.98 px) — two columns, still collapsed nav
- Grids move to two columns (
col-md-6); footer link columns go 2-up; logo wall at mid density. - Navigation is still collapsed — the full bar with mega menu needs ≥ 992 px. Don’t design tablet layouts that assume visible top-level links.
- Hero remains stacked; side-by-side media layouts (feature-hero) come back at this tier.
- Full section rhythm (64 px) resumes at 768 px.
Desktop (≥ 992 px) — full layout
- The lg cut is the system’s one “big switch”: full navigation bar, mega menu (full-width dropdown via static positioning), hero card becomes an absolute overlay, article sidebar appears, 3–4 column grids.
- xl / xxl change only the container max-width (1140 / 1320 px). If a design needs a layout change above 992 px, question the design before adding a query.
Component State Matrix
What actually changes, per component, at each tier. Components not listed are intrinsic / grid-driven and render identically at every width. “—” = no change from the previous tier.
| Component | Mobile < 768 | Tablet 768–991.98 | Desktop ≥ 992 |
|---|---|---|---|
| Navigation | Collapsed behind toggler; mega menu hidden; offcanvas drill-down panels — forward to L4, Back per level (navigation.js) | — | Full bar; mega menu opens as a full-width dropdown (position: static enabler) |
| Layout / sections | Rhythm compressed one step (48/32/64 px) | Full rhythm (64/48/96 px) | — |
| Hero | Media 14–18 rem tall; card stacked below with negative-margin overlap; smaller radius & padding < 576 | Media 18 rem; card still stacked | Media 22 rem; card absolutely positioned over media |
| Feature/Resource Hero | Single column, centred; preview image moves above text (order: -1), max 12 rem; accent border moves left→top | Two-column grid returns | — |
| Card grid | 1-up < 576 (auto-fit handles 576–767) | Auto-fit 2–3-up | Auto-fit 3–4-up |
| Blog listing | 1-up < 576; featured card stacks; list-view rows stack | 2-up | 3-up |
| Footer | 1 link column < 576; bottom row stacks left-aligned | 2 link columns | 4 link columns; bottom row logo · legal · social |
| Stat strip | Vertical stack < 576, dividers rotate to horizontal; optional icon slot stays hidden | Horizontal row (max 3 stats — the component rule exists for this tier; icons may appear above each stat) | — |
| Tables | --stacked variant: header row hidden, cells become label/value pairs | Standard table | — |
| Testimonials | Single column; carousel item padding reduced | Grid 2-up | — |
| Download list | Rows stack; action button full-width | Inline rows | — |
| Tabs (vertical) | Pill rail rotates to a horizontal wrapping row above the panel | Side-by-side rail + panel | — |
| Pagination | Compact < 576: smaller targets, wrapper centres | Full size | — |
| Breadcrumb | Horizontal scroll < 576 (no wrap) | Inline | — |
| Logo wall | 2-up grid | 3-up (tablet-only query) | 4–6-up |
| Side Navigation | Collapses behind an “In this section” disclosure toggle (< 992, side-nav.js); expanded if JS unavailable; sticky disabled | Left column (col-lg-3), always expanded, sticky below header | |
| Article layout | Sidebar stacks below article (< 992) | Two-column with sticky sidebar | |
| Text / Title | Display 3.5→2.5 rem | Full scale | — |
| Data visualization | Bar rows stack; labels above bars | Inline rows | — |
| Image / Embed | Corner radius halves < 576 (denser frame) | Standard radius | — |
| Buttons | --full-mobile goes 100% width < 576 | Auto width | — |
QA Checklist
- ☐ Page reviewed at 375, 576, 768, 834, 992, 1200 and 1440 px — and at each cut (991 px and 992 px both look intentional).
- ☐ Only the five sanctioned query shapes appear in component CSS; every max-width uses the
.98pxform. - ☐ No horizontal scrollbar at any width ≥ 320 px (except sanctioned scroll patterns: breadcrumb, table scroll container).
- ☐ Nothing reachable on desktop is unreachable on mobile (mega-menu promos may simplify, never disappear as destinations).
- ☐ Touch targets ≥ 44×44 px below 992 px.
- ☐ Section rhythm compresses on mobile (via
layout.css) — no template re-implements it. - ☐ ARIA state (expanded/current/busy) behaves identically at every width.