Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ src/
tokens/ colors, typography, spacing, shadows — design tokens only
base/ reset.css — bare-element resets (*, html, body, a, section);
icon-glyph.css — shared .csa-icon-glyph mask primitive used
by tags.css and badges.css
by tags.css and badges.css; utility.css — text alignment,
.csa-center, and .csa-sr-only (visually hidden, still read by
screen readers and focusable)
components/ one CSS file per component — no shipped JS, see
"Styling only, not behavior" above
assets/ real brand assets that ship with the library — see below
Expand Down Expand Up @@ -153,13 +155,25 @@ exist, per spec. Layout: `--maxw` (1200px) + `.csa-wrap` / `.csa-section`
utilities. Headings: h1–h3 are weight 900, h4 is 700 — the one heading
level that isn't unified to 900.

Text sizes: body is 16px and `.csa-block` (lead paragraph) is 18px. Below
body there are two steps, each a value plus a matching class:
`--text-small` (14.5px) with `.csa-block-small` for short paragraphs —
card copy, notes — and `--text-caption` (12px) with `.csa-caption` for
small supporting text — dates, bylines, footnotes, captions, form hints.
Components use the values directly (buttons, `.csa-go`, tabs, nav links,
form hints/errors, quote and carousel card text), so the scale reads
12 / 14.5 / 16 / 18. 14.5 is the one deliberate half size — the library's
other former half sizes were rounded to whole pixels. `.csa-caption` uses
`--n400` on light and `--n200` on dark/black, the lightest grays that pass
WCAG AA at 12px (`--n300` doesn't).

## Components

| File | Source |
|---|---|
| `grid.css` | `.csa-grid` / `.csa-cell` — CSS Grid system equivalent to Bulma's `.grid` / `.cell`. Defaults to 12 columns; `.csa-grid-{2–6}` presets for common card grids; `--col-count` inline for any other count. `.csa-cell-col-{1–12}` for column spans, `.csa-cell-row-{1–6}` for row spans. Supports true 2D layouts unlike `.csa-columns` (flexbox). **Responsive:** mobile-first breakpoint prefix classes — `.csa-grid-{sm\|md\|lg}-{1–6}` changes column count at ≥576/768/1024 px; `.csa-cell-col-{sm\|md\|lg}-{1–12}` changes a cell's span. Typical card grid: `csa-grid-1 csa-grid-md-2 csa-grid-lg-4`. Typical sidebar: `csa-grid-1 csa-grid-lg-4` with `csa-cell-col-lg-1` / `csa-cell-col-lg-3` on the cells (25%/75% split). |
| `surfaces.css` | Built fresh per spec — light/gradient/dark/black backgrounds + surface-aware `.csa-card`. Also defines **tones**: an optional second attribute, `data-tone`, that nudges a surface one step without becoming a new surface (so every component's existing `data-surface` rules keep applying). `data-surface="light" data-tone="neutral"` gives an `n25` band with white cards — the formalised form of the older `.csa-bg-n25` hook, which still works on a light surface as an alias and now sets the band color itself. `data-surface="dark" data-tone="deep"` drops the band to `b800` and lifts cards to `b700`, since dark's own `b800` cards would disappear into it; the progress track, toggle tracks, and disabled pagination fills step up to `b700` for the same reason, each in its own component file. Known gap: dark table rows alternate `b700`/`b800`, so the `b800` rows blend into a deep band |
| `cards.css` | `.csa-card` shell synthesized from a handful of bespoke card patterns seen across CSA's early pages (no shared class existed at the time); `.csa-card-glass` is the frost glass material (shared with `.csa-card-reveal-panel`): a light and a dark recipe tuned against CSA's Illustrator marketing comps — 8px backdrop blur, dark glass darkening the backdrop (`brightness(.45)`) under a thin `--b600` cast so the light behind glows through instead of graying out, light glass at 60% white, a ~4% grain layer, and an even edge line inset 1px from the card's edge (pale-blue `--b50` on dark, with a faint outer hairline, fading toward the bottom). **Dark glass is the default on every surface** (it holds body-text contrast over almost any backdrop) and sets its own text colors — headings, body, kickers, `.csa-go`, `.csa-hr` — so it works on light pages too; for other surface-aware components nested inside (buttons, badges, tags, form fields), add `data-surface="dark"` to the glass card itself. Light glass is opt-in via `.csa-card-glass-light` (or `.csa-hero-glass-light` for the hero) and is meant for lighter backgrounds only — over dark imagery it turns gray and body text loses contrast. The values are a small set of `--glass-*` custom properties per tone; blur/brightness are literal per tone for older-Safari safety. Near-opaque fallbacks for no `backdrop-filter` support and `prefers-reduced-transparency`, and a real border in Windows High Contrast. Also: `.csa-card-hover` (lift/shadow/border-color modifier, matching the hover treatment consistently used across CSA's early interactive cards), `.csa-card-media` (16:9 image-top card, surface-aware like `.csa-card`), `.csa-card-reveal` (4:3 photo card — kicker + heading sit permanently on a thin frosted-glass strip at the bottom; `.csa-card-reveal-more`/`-more-inner` grow that strip on hover via a `grid-template-rows` 0fr→1fr transition, not `max-height`, so it fits body copy of any length without a guessed cutoff; always dark regardless of page surface), `.csa-go` (shared CTA link utility, `font-size:14.5px` to read as a peer of body copy rather than a caption — `--b500` default, `--b300` on hover and on dark surfaces; promoted out of `carousel.css` where it started), `.csa-card-brand-cloud`/`-ai`/`-zt` (one per CSA sub-brand, white-background only, no `data-surface` variants — top-down fill + gradient border via the same double-background-clip trick buttons.css uses for a gradient border, plus a non-uniform border-width and a hard gradient stop so the border-box layer also carries a solid 4px top accent bar; border gradient (not the top accent, not the fill) swaps colors on `:hover`, and `.csa-go` is recolored to match each brand's own accent), `.csa-card-quote` (testimonial card — quote glyph, body copy, then a footer with a headshot slot, name, and title; the headshot is a plain `<img>`, not a mask, since a photo doesn't need to recolor with surrounding text the way an icon glyph does), and `.csa-card-raised` (always-on elevation for a card that needs more emphasis than the rest of its grid — swaps the base `--shadow-sm` for the bigger `--shadow` token, the same shadow `.csa-card-hover` only shows on `:hover`; background/border are untouched, so it's a pure modifier always paired with `.csa-card`; dark/black reuse `.csa-card-hover`'s own black shadow value rather than a new one). An icon as a card's first child just needs `.csa-icon` — no new class |
| `surfaces.css` | Built fresh per spec — light/gradient/dark/black backgrounds + surface-aware `.csa-card`. Also defines **tones**: an optional second attribute, `data-tone`, that nudges a surface one step without becoming a new surface (so every component's existing `data-surface` rules keep applying). `data-surface="light" data-tone="neutral"` gives an `n25` band with white cards. It replaces the older `.csa-bg-n25` hook: that name now belongs to `color-helpers.css` as a plain `!important` background utility, so it no longer adjusts cards, tags, or toggles inside it — use `data-tone="neutral"` for that. Tags and toggles inside a `.csa-card`/`.csa-card-media` on a plain light surface — inside a `data-surface="light"` section or carrying that attribute itself, where the card is `n25` get the same one-step step-up automatically, so no hook is needed on the card. `data-surface="dark" data-tone="deep"` drops the band to `b800` and lifts cards to `b700`, since dark's own `b800` cards would disappear into it; the progress track, toggle tracks, and disabled pagination fills step up to `b700` for the same reason, each in its own component file. Known gap: dark table rows alternate `b700`/`b800`, so the `b800` rows blend into a deep band |
| `cards.css` | `.csa-card` shell synthesized from a handful of bespoke card patterns seen across CSA's early pages (no shared class existed at the time); `.csa-card-glass` is the frost glass material (shared with `.csa-card-reveal-panel`): a light and a dark recipe tuned against CSA's Illustrator marketing comps — 8px backdrop blur, dark glass darkening the backdrop (`brightness(.45)`) under a thin `--b600` cast so the light behind glows through instead of graying out, light glass at 60% white, a ~4% grain layer, and an even edge line inset 1px from the card's edge (pale-blue `--b50` on dark, with a faint outer hairline, fading toward the bottom). **Dark glass is the default on every surface** (it holds body-text contrast over almost any backdrop) and sets its own text colors — headings, body, kickers, `.csa-go`, `.csa-hr` — so it works on light pages too; for other surface-aware components nested inside (buttons, badges, tags, form fields), add `data-surface="dark"` to the glass card itself. Light glass is opt-in via `.csa-card-glass-light` (or `.csa-hero-glass-light` for the hero) and is meant for lighter backgrounds only — over dark imagery it turns gray and body text loses contrast. The values are a small set of `--glass-*` custom properties per tone; blur/brightness are literal per tone for older-Safari safety. Near-opaque fallbacks for no `backdrop-filter` support and `prefers-reduced-transparency`, and a real border in Windows High Contrast. Also: `.csa-card-hover` (lift/shadow/border-color modifier, matching the hover treatment consistently used across CSA's early interactive cards), `.csa-card-media` (16:9 image-top card, surface-aware like `.csa-card`), `.csa-card-reveal` (4:3 photo card — kicker + heading sit permanently on a thin frosted-glass strip at the bottom; `.csa-card-reveal-more`/`-more-inner` grow that strip on hover via a `grid-template-rows` 0fr→1fr transition, not `max-height`, so it fits body copy of any length without a guessed cutoff; always dark regardless of page surface), `.csa-go` (shared CTA link utility, `font-size: var(--text-small)` (14.5px) to read as a peer of body copy rather than a caption — `--b500` default, `--b300` on hover and on dark surfaces; promoted out of `carousel.css` where it started), `.csa-card-brand-cloud`/`-ai`/`-zt` (one per CSA sub-brand, white-background only, no `data-surface` variants — top-down fill + gradient border via the same double-background-clip trick buttons.css uses for a gradient border, plus a non-uniform border-width and a hard gradient stop so the border-box layer also carries a solid 4px top accent bar; border gradient (not the top accent, not the fill) swaps colors on `:hover`, and `.csa-go` is recolored to match each brand's own accent), `.csa-card-quote` (testimonial card — quote glyph, body copy, then a footer with a headshot slot, name, and title; the headshot is a plain `<img>`, not a mask, since a photo doesn't need to recolor with surrounding text the way an icon glyph does), and `.csa-card-raised` (always-on elevation for a card that needs more emphasis than the rest of its grid — swaps the base `--shadow-sm` for the bigger `--shadow` token, the same shadow `.csa-card-hover` only shows on `:hover`; background/border are untouched, so it's a pure modifier always paired with `.csa-card`; dark/black reuse `.csa-card-hover`'s own black shadow value rather than a new one), and `.csa-card-flip` (a card with a front and a back that turns over on click — CSS only, no script: a visually hidden checkbox (`.csa-card-flip-toggle.csa-sr-only`) holds the flipped state, and a `<label>` covering each face (`.csa-card-flip-hit`) makes the whole card the click target while links on the back stay clickable; keyboard users Tab to the checkbox and flip with Space. Both faces are ordinary `.csa-card`s stacked in one grid cell, so they pick up the surface's card colors and the card is always as tall as its taller face. Hover tilts it 12° toward the turn and lifts it with the raised-card shadow; a corner cue icon (`.csa-card-flip-cue`) shows on touch screens only, where there's no hover hint. The face turned away is `visibility:hidden`, so its links can't be clicked or tabbed to, and reduced motion swaps the rotation for a cross-fade. Each card needs its own unique checkbox `id`/label `for` pair — the full markup contract is in the comment above the rules). An icon as a card's first child just needs `.csa-icon` — no new class |
| `buttons.css` | `.csa-btn-primary` is always `--o500` — no blue variant, no surface-conditional switching. 4 standardized variants, all surface-aware (work unmodified on light/gradient/dark/black): `.csa-btn-primary`, `.csa-btn-secondary`, `.csa-btn-tertiary`, `.csa-btn-disabled`. `.csa-btn-light`/`.csa-btn-ghost`/`.csa-btn-onnavy` are retired — Disabled replaces Light, Secondary is Ghost renamed (it already worked on dark surfaces unmodified, making Onnavy redundant there). Replaces `.btn-gold`/`.btn-gold-outline` (removed). Disabled's colors are surface-aware per surface, not just light-vs-dark: black uses its own `n800`/`n500` values (matching the n-scale `.csa-card` already uses for its own black-surface background/border), rather than reusing dark's blue-scale `b800`/`b500` on a surface that's otherwise neutral, not navy |
| `action.css` | A surface-aware interactive tile for `<a>` or `<button>` — shares `.csa-card`'s border treatment (`n50` resting border, matching `.csa-pagination-btn`'s convention). `aria-selected="true"` (the same attribute used for selected items in listboxes/grids/tab lists) switches it to an orange border + warm tint, plus a resting `--shadow` drop shadow (dark/black get their own higher-contrast black shadow, same technique as `.csa-card-hover`'s dark override in `cards.css`) so a selected tile reads as chosen even before a pointer gets near it — deliberately static once selected, with no further color/lift shift on `:hover`, since a second signal on top of an already-selected tile read as redundant. Dark surface additionally gets a `backdrop-filter: blur(3px)`. `.csa-action-arrow` adds a trailing chevron that tracks every state the border goes through via `currentColor`. Wrap multiple in `.csa-actions` to stack them in a full-width column, 10px gap |
| `badges.css` | The original extracted-as-is glass pill (`.csa-badge-hot`, the spec's "Eyebrow") has been retired. Ships `.csa-badge-primary`/`-secondary`/`-outlined`/`-orange` instead — designed fresh, icon + italic label, surface-aware (light/gradient share one treatment, dark/black another). `-orange` is a solid `o700` pill with white text/icon on light surfaces, and flips to an `o400`-at-20% fill with `o200` text and an `o200/` token-color icon on dark/black. Outlined's dark/black text is `b100` (not `b300`, which is only ~3.3:1 on the `b700` dark surface) and takes the `b100` icon Icon is either a plain `<img>` (when a pre-colored file exists for the exact color, e.g. Calendar's b500/b100/b300/white variants) or the shared `.csa-icon-glyph` mask primitive (`base/icon-glyph.css`) when it doesn't |
Expand Down
9 changes: 9 additions & 0 deletions src/base/utility.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@
flex-direction: column;
align-items: center;
}

/* Visually hidden, but still read by screen readers and still focusable.
For text that only assistive tech needs (e.g. naming the target of a
repeated "View Working Group" link) and for native controls that drive
a CSS-only component without being seen (the .csa-card-flip checkbox). */
.csa-sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
4 changes: 2 additions & 2 deletions src/components/accordion.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
.csa-accordion-trigger {
display: flex; align-items: center; justify-content: space-between; gap: 20px;
cursor: pointer; list-style: none;
padding: 20px 0; font-weight: 700; font-size: 17.5px; letter-spacing: -.01em;
padding: 20px 0; font-weight: 700; font-size: 18px; letter-spacing: -.01em;
color: var(--b800);
}
.csa-accordion-trigger::-webkit-details-marker { display: none; }
Expand All @@ -97,5 +97,5 @@
max-height: var(--csa-accordion-max-height, 900px);
padding-bottom: 22px;
}
.csa-accordion-panel p { font-size: 15.5px; line-height: 1.65; color: var(--n500); max-width: 74ch; }
.csa-accordion-panel p { font-size: 16px; line-height: 1.65; color: var(--n500); max-width: 74ch; }
.csa-accordion-panel p + p { margin-top: 10px; }
5 changes: 3 additions & 2 deletions src/components/buttons.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
.csa-btn {
display: inline-flex; align-items: center; justify-content: center; gap: 9px;
padding: 13px 22px; border-radius: 8px;
font-weight: 400; font-size: 14.5px;
font-weight: 400; font-size: var(--text-small);
border: 1px solid transparent; transition: .18s; cursor: pointer;
min-width: 120px;
transition: .35s ease;
Expand Down Expand Up @@ -150,7 +150,8 @@
#FF7A00 → rgb(255,122,0) (see colors.css). transition overrides the
base .csa-btn's .18s to match Primary/Secondary's .35s pace. */
.csa-btn-tertiary, .csa-btn-tertiary:visited { background: transparent; border: 2px solid transparent; color: var(--o500); transition: .35s ease; }
.csa-btn-tertiary:hover { background: rgba(255,122,0,.2); color: var(--o500); }
/* color restated so the base .csa-btn:hover white (same specificity, earlier) can't win */
.csa-btn-tertiary:hover { background: rgba(255,122,0,.2); color: var(--o500); }
/* Persistent underline (not just on :hover) — a text-only button has no
fill or border to read as clickable at rest, so the line is the
resting affordance. On hover it retracts away and disappears (the
Expand Down
Loading
Loading