mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
Adds the schema-compliant token + fixture pair for the next 10 brands in Tier E (consumer / hardware / global-cultural surfaces): - pinterest, airtable (visual discovery + no-code product) - bmw, tesla (automotive: German precision vs. EV minimalism) - spacex (aerospace cosmic minimalism, zero-shadow) - nike (sportswear, monochrome editorial) - playstation (gaming console, dark-first cobalt) - starbucks (warm cream + Siren Green) - wechat, xiaohongshu (CJK-primary consumer apps, bilingual stacks) Each pair declares all 56 shared tokens (26 A1 + 26 A2 + 4 B-slot) in :root with brand-rationale comments in tokens.css and a comment-free byte-equivalent :root in components.html. No C-extensions were needed. Validation: - pnpm guard: passed (66 brand pairs aligned, 3714 declarations, 66 brands declare all A1/A2/B-slot tokens, A2 defaults parity intact, flag parity unchanged) Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local> Co-authored-by: Cursor <cursoragent@cursor.com>
261 lines
15 KiB
CSS
261 lines
15 KiB
CSS
/* ─────────────────────────────────────────────────────────────────────────
|
||
* design-systems/airtable/tokens.css
|
||
*
|
||
* Structured token bindings for "Design System Inspired by Airtable" —
|
||
* the spreadsheet-database hybrid that talks to enterprise without
|
||
* shouting. A white canvas with deep-navy text, Airtable Blue as the
|
||
* single chromatic accent, Haas Swiss-precision typography, and a
|
||
* signature blue-tinted multi-layer shadow that makes cards feel
|
||
* built into the page rather than dropped onto it.
|
||
*
|
||
* Brand-specific schema decisions (each one bends a schema convention
|
||
* to match Airtable's voice rather than the cross-brand default):
|
||
*
|
||
* 1. `--accent` is Airtable Blue (#1b61c9), not deep navy. Deep
|
||
* navy is already `--fg`; the brand expresses primary CTAs by
|
||
* using `--accent` as the button background and reserves
|
||
* navy-on-white for headlines and body. `--accent-hover` binds
|
||
* to the documented "Mid Blue" #254fad rather than a generic
|
||
* color-mix darken — Airtable explicitly differentiates the
|
||
* hover tier as a discrete brand tone, not a calculated shade.
|
||
*
|
||
* 2. `--fg` is `#181d26` (Deep Navy), not `#000000`. The faint
|
||
* blue undertone at the top of the neutral ramp is part of the
|
||
* brand — pure black would clash with Airtable Blue and make
|
||
* the page read as harsh against the white canvas. `--fg-2`
|
||
* drops to `#333333` (documented Dark Gray) for body
|
||
* description; `--muted` binds to the documented Weak Text
|
||
* `rgba(4, 14, 32, 0.69)` so cross-brand `var(--muted)` calls
|
||
* land on Airtable's actual semitransparent navy tier instead
|
||
* of a flat gray.
|
||
*
|
||
* 3. `--surface-warm` aliases to `--surface` because Airtable has
|
||
* no warm tier — the canvas is white and the lifted surface is
|
||
* the documented `#f8fafc` light-surface, both cool. Adding a
|
||
* warm sibling would invent a tone the brand does not use.
|
||
*
|
||
* 4. `--elev-raised` is the full multi-layer Airtable shadow stack
|
||
* reproduced VERBATIM from DESIGN.md §6: a 1px dark hairline, a
|
||
* 2px ambient, a 3px blue-tinted (rgba(45,127,249,0.28))
|
||
* "Airtable glow" at 1px y-offset, and a 0.5px inner ring. The
|
||
* blue tint is the brand signature — it makes cards feel
|
||
* authored by the same hand as the Airtable Blue CTAs, instead
|
||
* of a generic gray-shadow drop. Never drop the third layer
|
||
* when overriding this token.
|
||
*
|
||
* 5. Radius scale binds 12 / 16 / 24 / 9999 (sm / md / lg / pill)
|
||
* per DESIGN.md §5. Buttons sit at 12px (documented), cards at
|
||
* 16px, large feature containers at 24px. The 2px "sharp"
|
||
* cookie-consent radius is component-specific and inlined
|
||
* where needed, not promoted to the schema. The 32px "large"
|
||
* radius is also section-specific; binding it to `--radius-lg`
|
||
* would over-round the typical card surface.
|
||
*
|
||
* 6. `--leading-body` is 1.35 (DESIGN.md body 18px / 24px), not
|
||
* the schema-conventional 1.5. Airtable runs body copy at a
|
||
* slightly tighter rhythm so dense product UI (table rows,
|
||
* record cards) does not feel sparse. `--leading-tight` is 1.2
|
||
* for headings, matching the documented 1.15–1.25 band.
|
||
*
|
||
* 7. `--tracking-display` is `0` (normal), not negative. DESIGN.md
|
||
* §3 explicitly lists display headings as `letter-spacing:
|
||
* normal` and body text as POSITIVE tracking (0.08–0.28px).
|
||
* The Haas family is engineered for positive tracking; mapping
|
||
* display to a negative em would fight the typeface. Body-tier
|
||
* positive tracking is applied at the component level (button,
|
||
* caption) since `--tracking-display` only covers display sizes.
|
||
*
|
||
* 8. `--success` is `#006400` (documented `--theme_success-text`),
|
||
* a darker forest green than the schema's #16a34a. Airtable's
|
||
* semantic green is intentionally deeper so it reads as a
|
||
* "confirmed / saved" tone against the white canvas rather
|
||
* than a vibrant alert.
|
||
*
|
||
* 9. Section rhythm is 96 / 64 / 48 (desktop / tablet / phone).
|
||
* DESIGN.md does not pin section padding numerically but the
|
||
* site's airy enterprise voice asks for generous vertical
|
||
* space — this matches the documented 8px-base spacing scale
|
||
* (96 = 12 × 8) without inventing a new tier. Container caps
|
||
* at 1200px, consistent with Airtable's documented
|
||
* 425–1664px responsive band centered on a desktop sweet spot.
|
||
*
|
||
* Source contracts:
|
||
* - Standard token names: design-systems/_schema/tokens.schema.ts
|
||
* - A2 fallback parity: design-systems/_schema/defaults.css
|
||
* - Lint enforcement: apps/daemon/src/lint-artifact.ts
|
||
*
|
||
* Keep this file additive: never invent token names not also
|
||
* documented in DESIGN.md or the schema. The Haas family does not
|
||
* need a CDN reference here — the font stack lists OS fallbacks
|
||
* (`-apple-system, system-ui, Segoe UI, Roboto`) per DESIGN.md §3
|
||
* so artifacts render acceptably even when Haas is not loaded.
|
||
* ─────────────────────────────────────────────────────────────────── */
|
||
|
||
:root {
|
||
/* ─── Surface ─────────────────────────────────────────────────────
|
||
* White canvas, white lifted card. Airtable explicitly does not
|
||
* vary background between sections — depth comes from the
|
||
* blue-tinted shadow stack, not from tinting one surface against
|
||
* another. `--surface-warm` aliases to surface because the brand
|
||
* has no warm tier (DESIGN.md §2 lists only cool neutrals). */
|
||
--bg: #ffffff; /* primary canvas */
|
||
--surface: #ffffff; /* card / lifted container */
|
||
--surface-warm: var(--surface); /* alias — Airtable has no warm tier */
|
||
|
||
/* ─── Foreground ──────────────────────────────────────────────────
|
||
* Deep Navy → Dark Gray → Weak Text (semitransparent navy) →
|
||
* tertiary alias. The four-tier ramp matches DESIGN.md §2 + §6
|
||
* exactly: `#181d26` headings, `#333333` body, the documented
|
||
* `rgba(4, 14, 32, 0.69)` weak tier for captions, and `--meta`
|
||
* aliasing to muted because Airtable does not differentiate a
|
||
* fourth tertiary tone. */
|
||
--fg: #181d26; /* Deep Navy — primary text */
|
||
--fg-2: #333333; /* Dark Gray — secondary text / body */
|
||
--muted: rgba(4, 14, 32, 0.69); /* Weak Text — captions, meta */
|
||
--meta: var(--muted); /* alias — no distinct tertiary tier */
|
||
|
||
/* ─── Border ──────────────────────────────────────────────────────
|
||
* `#e0e2e6` is the documented card-border tone from DESIGN.md §4.
|
||
* `--border-soft` drops to a lighter `#eef0f3` for inner row
|
||
* separators (table rows, list dividers) that must not visually
|
||
* compete with the outer card edge. */
|
||
--border: #e0e2e6; /* card / input edge */
|
||
--border-soft: #eef0f3; /* inner row separator */
|
||
|
||
/* ─── Accent ──────────────────────────────────────────────────────
|
||
* Airtable Blue — the single chromatic accent across the brand.
|
||
* Used for primary CTAs, links, focus rings, and active-state
|
||
* highlights. Hard cap of ≤2 visible uses per screen (lint
|
||
* enforced); decorative blue is forbidden because the brand reads
|
||
* the accent as "this is the action".
|
||
*
|
||
* `--accent-hover` binds to the documented "Mid Blue" #254fad
|
||
* rather than a generic color-mix darken — Airtable explicitly
|
||
* differentiates the hover tier as a discrete brand tone. */
|
||
--accent: #1b61c9; /* Airtable Blue — CTA, links */
|
||
--accent-on: #ffffff; /* white label on blue */
|
||
--accent-hover: #254fad; /* Mid Blue — documented hover tone */
|
||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||
|
||
/* ─── Semantic ────────────────────────────────────────────────────
|
||
* `--success` is the documented `--theme_success-text` (#006400),
|
||
* a deeper forest green than the schema's #16a34a — Airtable's
|
||
* green reads as "confirmed / saved" against white, not as a
|
||
* vivid alert. Warn / danger inherit schema defaults because the
|
||
* brand has no defined yellow / red. */
|
||
--success: #006400; /* documented Success Green */
|
||
--warn: #eab308;
|
||
--danger: #dc2626;
|
||
|
||
/* ─── Typography ──────────────────────────────────────────────────
|
||
* Haas (display + Groot Disp variant) is Airtable's proprietary
|
||
* Swiss family. The OS fallbacks `-apple-system, system-ui,
|
||
* Segoe UI, Roboto` are documented in DESIGN.md §3 and ensure
|
||
* artifacts render legibly when Haas is not loaded. The Groot
|
||
* Disp variant carries display headings; Haas regular carries
|
||
* body and UI. */
|
||
--font-display: "Haas Groot Disp", Haas, -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
|
||
--font-body: Haas, -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
|
||
--font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Monaco, Consolas, monospace;
|
||
|
||
/* Type scale — derived from DESIGN.md §3 hierarchy. The scale
|
||
* tops out at 48px (display hero); Airtable reads as "sophisticated
|
||
* simplicity" because hierarchy comes from weight + tracking
|
||
* variation within the Haas family, not from inflated px counts. */
|
||
--text-xs: 12px; /* metadata, tags */
|
||
--text-sm: 14px; /* caption, small UI */
|
||
--text-base: 16px; /* body medium, button */
|
||
--text-lg: 20px; /* feature copy */
|
||
--text-xl: 24px; /* card title */
|
||
--text-2xl: 32px; /* sub-heading */
|
||
--text-3xl: 40px; /* section heading */
|
||
--text-4xl: 48px; /* display hero */
|
||
|
||
/* `--leading-body` is 1.35 (DESIGN.md body 18px / 24px), not 1.5.
|
||
* Dense product UI (table rows, record cards) needs the tighter
|
||
* rhythm so rows do not feel sparse. `--leading-tight` is 1.2
|
||
* for headings, matching the documented 1.15–1.25 band.
|
||
* `--tracking-display` is `0` because DESIGN.md §3 explicitly
|
||
* lists display headings as `letter-spacing: normal`; positive
|
||
* body tracking (0.08–0.28px) is applied per-component. */
|
||
--leading-body: 1.35;
|
||
--leading-tight: 1.2;
|
||
--tracking-display: 0;
|
||
|
||
/* ─── Spacing ─────────────────────────────────────────────────────
|
||
* 8px base unit per DESIGN.md §5 (1–48px range). The 4/8/12/16/
|
||
* 20/24/32/48 tier covers structural rhythm; finer sub-tier
|
||
* increments (1–3px micro-padding inside chips and badges) are
|
||
* inlined per-component because they are too granular for the
|
||
* shared schema. */
|
||
--space-1: 4px;
|
||
--space-2: 8px;
|
||
--space-3: 12px;
|
||
--space-4: 16px;
|
||
--space-5: 20px;
|
||
--space-6: 24px;
|
||
--space-8: 32px;
|
||
--space-12: 48px;
|
||
|
||
/* Section rhythm — Airtable's enterprise voice asks for generous
|
||
* vertical space between marketing sections without going gallery-
|
||
* empty. 96 desktop / 64 tablet / 48 phone matches the 8px base
|
||
* (96 = 12 × 8) and stays within the documented responsive band. */
|
||
--section-y-desktop: 96px;
|
||
--section-y-tablet: 64px;
|
||
--section-y-phone: 48px;
|
||
|
||
/* ─── Radius ──────────────────────────────────────────────────────
|
||
* DESIGN.md §5 radius scale: 2 / 12 / 16 / 24 / 32 / 50%. We bind
|
||
* the four schema tiers to: 12 (button/input, documented), 16
|
||
* (card, documented), 24 (large feature container, documented),
|
||
* 9999 (pill). The 2px "sharp" cookie-consent radius is
|
||
* component-specific and inlined where it appears; the 32px
|
||
* section radius would over-round typical surfaces and is
|
||
* intentionally not bound here. */
|
||
--radius-sm: 12px; /* buttons, inputs, chips */
|
||
--radius-md: 16px; /* cards, modals */
|
||
--radius-lg: 24px; /* featured containers */
|
||
--radius-pill: 9999px; /* badges, avatars */
|
||
|
||
/* ─── Elevation ───────────────────────────────────────────────────
|
||
* Airtable's signature: blue-tinted multi-layer shadow that makes
|
||
* cards feel authored by the same hand as the Airtable Blue CTAs.
|
||
* Four layers reproduced verbatim from DESIGN.md §6:
|
||
* 1px dark hairline (defines the edge)
|
||
* 2px ambient (soft surround)
|
||
* 3px blue glow @ 1y (the Airtable signature — never drop)
|
||
* 0.5px inset ring (subtle inner highlight) */
|
||
--elev-flat: none;
|
||
--elev-ring: 0 0 0 1px var(--border);
|
||
--elev-raised:
|
||
0 0 1px rgba(0, 0, 0, 0.32),
|
||
0 0 2px rgba(0, 0, 0, 0.08),
|
||
0 1px 3px rgba(45, 127, 249, 0.28),
|
||
inset 0 0 0 0.5px rgba(0, 0, 0, 0.06);
|
||
|
||
/* ─── Focus ring ──────────────────────────────────────────────────
|
||
* 3px Airtable-Blue alpha glow — keyboard focus reads as
|
||
* "actionable" without competing with the saturated CTA fill.
|
||
* Matches schema default formula so cross-brand focus styles
|
||
* remain visually consistent. */
|
||
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--accent), transparent 70%);
|
||
|
||
/* ─── Motion ──────────────────────────────────────────────────────
|
||
* Standard durations + curve. Airtable's product UI uses motion
|
||
* to confirm direct manipulation (cell edits, drag-and-drop),
|
||
* not to choreograph entrances — 150/200ms feels responsive
|
||
* without dragging. */
|
||
--motion-fast: 150ms;
|
||
--motion-base: 200ms;
|
||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||
|
||
/* ─── Layout ──────────────────────────────────────────────────────
|
||
* 1200px max content width — sits in the middle of Airtable's
|
||
* documented 425–1664px responsive band. Gutters narrow on
|
||
* mobile to preserve line length on dense marketing copy. */
|
||
--container-max: 1200px;
|
||
--container-gutter-desktop: 24px;
|
||
--container-gutter-tablet: 16px;
|
||
--container-gutter-phone: 12px;
|
||
}
|