@dustin-riley/design 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +219 -0
- package/README.md +35 -0
- package/package.json +20 -0
- package/skill/dustinriley-design/SKILL.md +31 -0
- package/src/core.css +231 -0
- package/src/tailwind.css +94 -0
- package/src/tailwind.head.css +63 -0
- package/src/tokens.css +178 -0
package/DESIGN.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Design system — @dustin-riley/design
|
|
2
|
+
|
|
3
|
+
This file is the source of truth for visual / interaction decisions. If you are an agent or contributor about to add UI, **read this file first**, then follow the pointers into the package's CSS for the actual tokens and component styles.
|
|
4
|
+
|
|
5
|
+
This doc is the source of truth; the bundled `dustinriley-design` skill mirrors it.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Tl;dr — non-negotiables
|
|
10
|
+
|
|
11
|
+
- **One primary** (burnt orange `#B8541C`), **two accents** (ochre, teal). Don't invent colors.
|
|
12
|
+
- **Three radii only**: `8px` (inputs/chips), `16px` (cards/modals), `999px` (buttons/toggles). Nothing else.
|
|
13
|
+
- **Three shadows only**: `sm`, `md`, `lg` — all warm-tinted (`rgba(74, 52, 28, …)`), never gray or black.
|
|
14
|
+
- **Sentence case everywhere.** No Title Case. No ALL CAPS for emphasis. Even nav: "experiments", "writing", "about".
|
|
15
|
+
- **First person.** Address the reader as "you". No marketing puffery.
|
|
16
|
+
- **No emoji.** Use Lucide icons or unicode arrows (`→ ↗ ↓ ←`).
|
|
17
|
+
- **Color is never the only state signal.** Pair it with elevation, motion, or an icon.
|
|
18
|
+
- **Motion is feedback, not decoration.** Spring-based, resolves under 300ms.
|
|
19
|
+
- **WCAG AA throughout.** For burnt-orange text-as-link, use `--ds-link` (`#9E4615`), not `--ds-primary` — primary doesn't clear 4.5:1 against the canvas.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Where things live
|
|
24
|
+
|
|
25
|
+
| Concern | File |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Design tokens (color, type, spacing, radius, shadow, motion) | `@dustin-riley/design/tokens.css` |
|
|
28
|
+
| Component / primitive styles (buttons, container, panel, typographic helpers, etc.) | `@dustin-riley/design/core.css` |
|
|
29
|
+
| Tailwind v4 base + theme bridge + shadcn bridge | `@dustin-riley/design/tailwind.css` |
|
|
30
|
+
|
|
31
|
+
**All design tokens are CSS custom properties prefixed `--ds-*`.** Always reference the token, never hard-code a hex / px value. If you need something the token set doesn't cover, that's a signal to push back on the design, not invent a one-off value.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Voice & content
|
|
36
|
+
|
|
37
|
+
The voice is personal but not confessional. A builder showing his work, not a brand selling something. Curious, plainspoken, slightly dry.
|
|
38
|
+
|
|
39
|
+
- **Casing:** sentence case, always.
|
|
40
|
+
- **First person:** "I built this", "I'm Dustin".
|
|
41
|
+
- **Address the reader as "you":** "drag the slider", "try changing the seed".
|
|
42
|
+
- **Verb-first button labels:** "open it", "try the demo", "read the notes" — lowercase, no ceremony.
|
|
43
|
+
- **Punctuation:** em-dashes ok, oxford commas on, sentence fragments fine. Avoid semicolons in UI copy.
|
|
44
|
+
- **Numbers:** spell out one through nine in prose; numerals for ten and up, and always for measurements/dates. Dates as "April 2026", not "04/18/26".
|
|
45
|
+
- **Empty states:** terse. e.g. "Nothing here yet. Check back."
|
|
46
|
+
- **Avoid:** marketing puffery ("revolutionary", "seamless"), exclamation points in running copy, onboarding-speak ("welcome aboard!"), placeholder copy ("your content here"), emoji.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Color
|
|
51
|
+
|
|
52
|
+
Warm-neutral canvas with one primary and two accents. Color is reserved for interaction and emphasis — chrome stays neutral.
|
|
53
|
+
|
|
54
|
+
| Token | Hex | Use |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `--ds-bg` | `#FAF6F0` | Page canvas |
|
|
57
|
+
| `--ds-surface` | `#F3ECE0` | Cards, raised surfaces, nav-link hover |
|
|
58
|
+
| `--ds-surface-sunken` | `#EDE4D3` | Insets, code, segmented "off" track |
|
|
59
|
+
| `--ds-border` | `#E0D5C2` | 1px hairlines (never heavier) |
|
|
60
|
+
| `--ds-text` | `#1F1A14` | Body text (warm-shifted near-black) |
|
|
61
|
+
| `--ds-text-muted` | `#6B5F50` | Captions, secondary, mono meta |
|
|
62
|
+
| `--ds-primary` | `#B8541C` | Brand surfaces (button bg, brand dot, focus ring). **Not for text.** |
|
|
63
|
+
| `--ds-primary-hover` | `#9E4615` | Hover state for primary surfaces |
|
|
64
|
+
| `--ds-primary-pressed` | `#85390F` | Active/pressed state |
|
|
65
|
+
| `--ds-link` | `#9E4615` | Text-as-link (passes AA on bg + surface) |
|
|
66
|
+
| `--ds-link-hover` | `#85390F` | Link hover |
|
|
67
|
+
| `--ds-accent-ochre` | `#C9922B` | Accent + warning |
|
|
68
|
+
| `--ds-accent-teal` | `#2E7D7A` | Accent |
|
|
69
|
+
| `--ds-success` | `#5C7A3E` | Warm olive |
|
|
70
|
+
| `--ds-error` | `#A8392E` | Warm brick red |
|
|
71
|
+
|
|
72
|
+
**Backgrounds:** flat warm neutrals only. No gradients behind content, no photo backgrounds, no repeating patterns, no noise/grain. A soft warm "blob" radial is permitted in empty states / large heading areas built per project — never behind anything that needs focus.
|
|
73
|
+
|
|
74
|
+
**Shadows are warm-tinted**, never gray:
|
|
75
|
+
```
|
|
76
|
+
--ds-shadow-sm resting cards
|
|
77
|
+
--ds-shadow-md hover lift, dropdowns
|
|
78
|
+
--ds-shadow-lg modals, popovers
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Borders disappear when elevation replaces them.** Cards use shadow, not border, unless they sit on a same-color surface.
|
|
82
|
+
|
|
83
|
+
**Transparency / blur:** modal scrims only (`rgba(31, 26, 20, 0.4)` over a blur). No glassmorphism, no frosted chrome.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Type
|
|
88
|
+
|
|
89
|
+
Outfit (display) × DM Sans (body) — geometric × rounded — JetBrains Mono for code and meta only. No italics in UI chrome.
|
|
90
|
+
|
|
91
|
+
| Token | Family | Use |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `--ds-font-display` | Outfit | h1–h6, brand wordmark, post titles, large headings |
|
|
94
|
+
| `--ds-font-body` | DM Sans | Paragraph, buttons, inputs |
|
|
95
|
+
| `--ds-font-mono` | JetBrains Mono | Captions, dates, tags, eyebrow labels (`.grid-label`), code |
|
|
96
|
+
|
|
97
|
+
Scale (1.25 ratio, 16px root) — see `tokens.css` for the full set. h1=36, h2=28, h3=22, h4=18, h5=16, h6=14. h4–h6 land at body sizes intentionally — they read as headings via the display font + 600 weight, not via raw size, and are rare in practice. Tracking tightens as type grows: `-0.02em` at display, `0` at body. Body weight 400; display 500–600.
|
|
98
|
+
|
|
99
|
+
**Mono is the "meta" face.** Anything date-y, tag-y, or label-y belongs in mono with `text-transform: uppercase` and `letter-spacing: 0.06em` (see `.grid-label`).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Spacing
|
|
104
|
+
|
|
105
|
+
Strict 4px base scale: `--ds-space-{0..9}` = `0, 4, 8, 12, 16, 24, 32, 48, 64, 96`.
|
|
106
|
+
|
|
107
|
+
- `16 → 24 → 32` is the "room rhythm" inside components.
|
|
108
|
+
- `48+` is reserved for section-level breaks.
|
|
109
|
+
- Two density modes: comfortable (default) and compact.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Radius
|
|
114
|
+
|
|
115
|
+
Three values. **No others allowed.**
|
|
116
|
+
|
|
117
|
+
| Token | Value | Use |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `--ds-radius-sm` | `8px` | Inputs, chips, code, inline keys |
|
|
120
|
+
| `--ds-radius-md` | `16px` | Cards, modals, panels, hero images |
|
|
121
|
+
| `--ds-radius-pill` | `999px` | Buttons, toggles, segmented controls, tag chips |
|
|
122
|
+
|
|
123
|
+
Corners are continuous / squircle-adjacent — that's why `16px` and `999px` feel right.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Motion
|
|
128
|
+
|
|
129
|
+
Spring easing over linear. **Everything resolves under 300ms.**
|
|
130
|
+
|
|
131
|
+
For CSS, use `--ds-ease-standard` (`cubic-bezier(0.2, 0.8, 0.2, 1)`) at one of:
|
|
132
|
+
- `--ds-duration-fast` (120ms) — color shifts, tiny chrome moves
|
|
133
|
+
- `--ds-duration-base` (200ms) — most transitions, hover lifts
|
|
134
|
+
- `--ds-duration-slow` (280ms) — layout, modal in/out
|
|
135
|
+
|
|
136
|
+
For framework motion (Framer Motion etc.), use spring presets:
|
|
137
|
+
- `spring-snappy` — stiffness 400, damping 30 — buttons, toggles, presses
|
|
138
|
+
- `spring-smooth` — stiffness 260, damping 26 — cards, modals, layout
|
|
139
|
+
- `spring-gentle` — stiffness 180, damping 24 — page transitions
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Interactive states
|
|
144
|
+
|
|
145
|
+
| State | Effect |
|
|
146
|
+
|---|---|
|
|
147
|
+
| Hover (cards, buttons) | `translateY(-1px)` + elevation bump `sm → md`. Color shift secondary. |
|
|
148
|
+
| Hover (text links) | Color shift only — no underline toggling. |
|
|
149
|
+
| Press / active | `scale(0.97)` snappy spring. Buttons may shift to `--ds-primary-pressed`. Elevation drops to resting. |
|
|
150
|
+
| Focus | `--ds-focus-ring` (2px primary at 40% opacity, 2px offset). Always visible. **Never `outline: none` without a replacement** — wire `:focus-visible` to the ring globally. |
|
|
151
|
+
| Disabled | 40% opacity, no pointer events, no hover lift. Never communicated by color alone. |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Layout
|
|
156
|
+
|
|
157
|
+
- The page container tops out at **960px** (`.ds-container`, `max-width: 960px` + `--ds-space-5` horizontal padding).
|
|
158
|
+
- Long-form articles should narrow to ~**680px** so the reading measure stays ~65–75ch — build that per project.
|
|
159
|
+
- Headers are static; **no sticky/blur-over-content navs.** If a header needs to be sticky later, it must remain neutral chrome — never tinted glass.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Iconography
|
|
164
|
+
|
|
165
|
+
- **Set:** [Lucide](https://lucide.dev). Lucide's clean line style matches the type pairing. If you swap to another set, swap the whole set, not one icon at a time.
|
|
166
|
+
- **Stroke:** `1.5px`. Never 1 (spindly), never ≥2 (cartoonish).
|
|
167
|
+
- **Sizes:** 20px inline with body, 24px standalone, 16px caption minimum, never above 32px outside empty-state illustrations.
|
|
168
|
+
- **Color:** `currentColor`. Inherit `--ds-text` in chrome, `--ds-text-muted` for supporting rails, `--ds-link` only when the icon itself is a CTA / active marker.
|
|
169
|
+
- **Unicode arrows are fair game** in button labels and footer links: `→ ↗ ↓ ←`. Set in the body face so they align with adjacent text. No other unicode substitutions (use Lucide `star`, not `★`).
|
|
170
|
+
- **No emoji. Anywhere.**
|
|
171
|
+
- **No custom illustrations** at the system level. Per-experiment illustrations are scoped to that experiment.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Component anchors
|
|
176
|
+
|
|
177
|
+
When building or modifying UI, prefer extending these existing patterns over inventing parallel ones. They're all defined in `@dustin-riley/design/core.css`:
|
|
178
|
+
|
|
179
|
+
| Pattern | Class |
|
|
180
|
+
|---|---|
|
|
181
|
+
| Page container | `.ds-container` |
|
|
182
|
+
| Section spacing | `.ds-section` |
|
|
183
|
+
| Headings | `.h1`–`.h6` |
|
|
184
|
+
| Display headline | `.ds-display` |
|
|
185
|
+
| Lede paragraph | `.ds-lede` |
|
|
186
|
+
| Mono caption / label | `.ds-caption`, `.grid-label`, `.ds-mono-note` |
|
|
187
|
+
| Page header (eyebrow + h1 + lede) | `.ds-page-header` |
|
|
188
|
+
| Buttons | `.ds-btn`, `.ds-btn-primary`, `.ds-btn-secondary`, `.ds-btn-ghost` |
|
|
189
|
+
| Back link | `.ds-back-link` |
|
|
190
|
+
| Panel / card surface | `.ds-panel` |
|
|
191
|
+
| Inline key chip | `.kbd` |
|
|
192
|
+
|
|
193
|
+
Site-specific furniture (nav, footer, hero, content grids, article body, pagers, search) is intentionally **not** in the package — build it per project from these primitives and tokens.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Anti-overdesign checklist
|
|
198
|
+
|
|
199
|
+
If you are about to do any of the following, stop and reconsider:
|
|
200
|
+
|
|
201
|
+
- Adding a new color token, accent, or semantic shade
|
|
202
|
+
- Adding a fourth radius
|
|
203
|
+
- Adding a fourth shadow, or any cool-toned / pure-gray shadow
|
|
204
|
+
- Reaching for italics in UI chrome
|
|
205
|
+
- Using gradients behind content
|
|
206
|
+
- Title-casing something
|
|
207
|
+
- Adding an emoji
|
|
208
|
+
- Removing a focus outline without replacing it
|
|
209
|
+
- Communicating state with color alone
|
|
210
|
+
- Hard-coding a hex / px value instead of a `--ds-*` token
|
|
211
|
+
|
|
212
|
+
The system is intentionally lean. **Cohesion is the product; novelty is a liability.**
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Caveats
|
|
217
|
+
|
|
218
|
+
- `--ds-*` tokens are the contract. If you self-host fonts later, drop `.woff2` files into a `fonts/` dir and update `tokens.css`; the family tokens stay the same.
|
|
219
|
+
- There is no real logo asset yet — the wordmark is a brand-dot + name lockup built per project.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @dustin-riley/design
|
|
2
|
+
|
|
3
|
+
Warm mid-century-modern design system: tokens, base resets, and a curated set of
|
|
4
|
+
reusable CSS primitives. Framework-neutral, with an optional Tailwind v4 +
|
|
5
|
+
shadcn bridge.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @dustin-riley/design
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Use
|
|
14
|
+
|
|
15
|
+
```css
|
|
16
|
+
/* any project */
|
|
17
|
+
@import "@dustin-riley/design/tokens.css";
|
|
18
|
+
@import "@dustin-riley/design/core.css";
|
|
19
|
+
|
|
20
|
+
/* Tailwind v4 + shadcn projects instead just need: */
|
|
21
|
+
@import "@dustin-riley/design/tailwind.css"; /* pulls in core + tokens */
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## What's in / out
|
|
25
|
+
|
|
26
|
+
In: `--ds-*` tokens, base element resets, focus ring, and generic primitives
|
|
27
|
+
(`.ds-btn*`, `.ds-container`, `.ds-panel`, typographic helpers, `.kbd`, …).
|
|
28
|
+
|
|
29
|
+
Out by design: site furniture (nav, footer, hero, content grids). Build those
|
|
30
|
+
per project from the tokens. See `DESIGN.md`.
|
|
31
|
+
|
|
32
|
+
## Maintaining the bridge
|
|
33
|
+
|
|
34
|
+
`src/tailwind.css` is generated. Never edit it by hand. After changing
|
|
35
|
+
`src/tokens.css`, run `npm run generate && npm test`.
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dustin-riley/design",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Dustin Riley design system — warm mid-century modern tokens and primitives.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": ["src", "DESIGN.md", "skill", "README.md"],
|
|
8
|
+
"exports": {
|
|
9
|
+
"./tokens.css": "./src/tokens.css",
|
|
10
|
+
"./core.css": "./src/core.css",
|
|
11
|
+
"./tailwind.css": "./src/tailwind.css",
|
|
12
|
+
"./DESIGN.md": "./DESIGN.md"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"generate": "node scripts/generate-bridge.mjs",
|
|
16
|
+
"test": "node --test"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": { "access": "public" },
|
|
19
|
+
"keywords": ["design-system", "css", "design-tokens"]
|
|
20
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dustinriley-design
|
|
3
|
+
description: Use when building or modifying any UI in a project that consumes @dustin-riley/design — enforces the warm mid-century-modern token system, the three-radii/three-shadow rules, sentence-case voice, and the curated .ds-* primitive vocabulary.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dustinriley design system
|
|
7
|
+
|
|
8
|
+
Apply this whenever you add or change UI in a project importing `@dustin-riley/design`.
|
|
9
|
+
|
|
10
|
+
## Non-negotiables
|
|
11
|
+
- One primary (burnt orange `#B8541C`), accents ochre + teal. Never invent colors.
|
|
12
|
+
- Three radii only: 8 / 16 / 999px. Three warm-tinted shadows only: sm / md / lg.
|
|
13
|
+
- Sentence case everywhere. First person. No emoji. Lucide icons or unicode arrows.
|
|
14
|
+
- Color is never the only state signal. Motion resolves under 300ms.
|
|
15
|
+
- For text-as-link in burnt orange use `--ds-link`, never `--ds-primary` (WCAG AA).
|
|
16
|
+
- Never hard-code a hex/px value — reference a `--ds-*` token.
|
|
17
|
+
|
|
18
|
+
## How to consume
|
|
19
|
+
- Always: `@import "@dustin-riley/design/tokens.css"; @import "@dustin-riley/design/core.css";`
|
|
20
|
+
- Tailwind v4 + shadcn projects additionally: `@import "@dustin-riley/design/tailwind.css";`
|
|
21
|
+
|
|
22
|
+
## Vocabulary (prefer extending these over inventing parallels)
|
|
23
|
+
Buttons `.ds-btn` + `.ds-btn-primary|secondary|ghost`; layout `.ds-container`,
|
|
24
|
+
`.ds-section`; type `.ds-display`, `.ds-lede`, `.ds-caption`, `.ds-mono-note`,
|
|
25
|
+
`.grid-label`, `.h1`–`.h6`; chrome bits `.ds-page-header`, `.ds-back-link`;
|
|
26
|
+
surfaces `.ds-panel`, `.kbd`.
|
|
27
|
+
|
|
28
|
+
Site-specific furniture (nav, footer, hero, grids) is NOT in the package by
|
|
29
|
+
design — build it per project from these primitives and tokens.
|
|
30
|
+
|
|
31
|
+
See the full rationale in `@dustin-riley/design/DESIGN.md`.
|
package/src/core.css
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
@import "./tokens.css";
|
|
2
|
+
|
|
3
|
+
/* ============================================================
|
|
4
|
+
@dustin-riley/design — core primitives
|
|
5
|
+
Curated, reusable component classes copied verbatim from the
|
|
6
|
+
canonical dustinriley.com design-system.css and scorigami
|
|
7
|
+
globals.css. Site furniture (nav, footer, hero, content
|
|
8
|
+
grids, article, chart bits) is intentionally excluded.
|
|
9
|
+
============================================================ */
|
|
10
|
+
|
|
11
|
+
/* ----- Type helpers ----- */
|
|
12
|
+
h1,
|
|
13
|
+
.h1 {
|
|
14
|
+
font-size: var(--ds-fs-h1);
|
|
15
|
+
line-height: var(--ds-lh-h1);
|
|
16
|
+
letter-spacing: var(--ds-tracking-h1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
h2,
|
|
20
|
+
.h2 {
|
|
21
|
+
font-size: var(--ds-fs-h2);
|
|
22
|
+
line-height: var(--ds-lh-h2);
|
|
23
|
+
letter-spacing: var(--ds-tracking-h2);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
h3,
|
|
27
|
+
.h3 {
|
|
28
|
+
font-size: var(--ds-fs-h3);
|
|
29
|
+
line-height: var(--ds-lh-h3);
|
|
30
|
+
letter-spacing: var(--ds-tracking-h3);
|
|
31
|
+
font-weight: 500;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h4,
|
|
35
|
+
.h4 {
|
|
36
|
+
font-size: var(--ds-fs-h4);
|
|
37
|
+
line-height: var(--ds-lh-h4);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h5,
|
|
41
|
+
.h5 {
|
|
42
|
+
font-size: var(--ds-fs-h5);
|
|
43
|
+
line-height: var(--ds-lh-h5);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
h6,
|
|
47
|
+
.h6 {
|
|
48
|
+
font-size: var(--ds-fs-h6);
|
|
49
|
+
line-height: var(--ds-lh-h6);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.ds-display {
|
|
53
|
+
font-family: var(--ds-font-display);
|
|
54
|
+
font-size: var(--ds-fs-display);
|
|
55
|
+
line-height: var(--ds-lh-display);
|
|
56
|
+
letter-spacing: var(--ds-tracking-display);
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (max-width: 640px) {
|
|
61
|
+
.ds-display {
|
|
62
|
+
font-size: 2.25rem;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ds-lede {
|
|
67
|
+
font-size: var(--ds-fs-body-lg);
|
|
68
|
+
line-height: var(--ds-lh-body-lg);
|
|
69
|
+
color: var(--ds-text-muted);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.ds-caption {
|
|
73
|
+
font-size: var(--ds-fs-caption);
|
|
74
|
+
line-height: 1.4;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
color: var(--ds-text-muted);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* ----- Layout ----- */
|
|
80
|
+
.ds-container {
|
|
81
|
+
max-width: 960px;
|
|
82
|
+
margin: 0 auto;
|
|
83
|
+
padding: 0 var(--ds-space-5);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ds-section {
|
|
87
|
+
padding-top: var(--ds-space-7);
|
|
88
|
+
padding-bottom: var(--ds-space-7);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* ----- Buttons ----- */
|
|
92
|
+
.ds-btn {
|
|
93
|
+
font-family: var(--ds-font-body);
|
|
94
|
+
font-weight: 500;
|
|
95
|
+
font-size: 14px;
|
|
96
|
+
padding: 10px 20px;
|
|
97
|
+
border-radius: var(--ds-radius-pill);
|
|
98
|
+
border: none;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
gap: 8px;
|
|
103
|
+
transition:
|
|
104
|
+
transform var(--ds-duration-fast) var(--ds-ease-standard),
|
|
105
|
+
box-shadow var(--ds-duration-base) var(--ds-ease-standard),
|
|
106
|
+
background var(--ds-duration-fast) var(--ds-ease-standard);
|
|
107
|
+
text-decoration: none;
|
|
108
|
+
line-height: 1.2;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.ds-btn-primary {
|
|
112
|
+
background: var(--ds-primary);
|
|
113
|
+
color: var(--ds-on-primary);
|
|
114
|
+
box-shadow: var(--ds-shadow-sm);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ds-btn-primary:hover {
|
|
118
|
+
background: var(--ds-primary-hover);
|
|
119
|
+
color: var(--ds-on-primary);
|
|
120
|
+
transform: translateY(-1px);
|
|
121
|
+
box-shadow: var(--ds-shadow-md);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.ds-btn-primary:active {
|
|
125
|
+
background: var(--ds-primary-pressed);
|
|
126
|
+
transform: scale(0.97);
|
|
127
|
+
box-shadow: var(--ds-shadow-sm);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ds-btn-secondary {
|
|
131
|
+
background: var(--ds-surface);
|
|
132
|
+
color: var(--ds-text);
|
|
133
|
+
border: 1px solid var(--ds-border);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.ds-btn-secondary:hover {
|
|
137
|
+
color: var(--ds-text);
|
|
138
|
+
transform: translateY(-1px);
|
|
139
|
+
box-shadow: var(--ds-shadow-sm);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.ds-btn-secondary:active {
|
|
143
|
+
transform: scale(0.97);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.ds-btn-ghost {
|
|
147
|
+
background: transparent;
|
|
148
|
+
color: var(--ds-text);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.ds-btn-ghost:hover {
|
|
152
|
+
background: var(--ds-surface);
|
|
153
|
+
color: var(--ds-text);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ----- Section labels ----- */
|
|
157
|
+
.grid-label {
|
|
158
|
+
font-family: var(--ds-font-mono);
|
|
159
|
+
font-size: var(--ds-fs-caption);
|
|
160
|
+
font-weight: 500;
|
|
161
|
+
text-transform: uppercase;
|
|
162
|
+
letter-spacing: 0.06em;
|
|
163
|
+
color: var(--ds-text-muted);
|
|
164
|
+
margin: 0 0 var(--ds-space-4);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* ----- Back link ----- */
|
|
168
|
+
.ds-back-link {
|
|
169
|
+
font-family: var(--ds-font-body);
|
|
170
|
+
font-size: 13px;
|
|
171
|
+
color: var(--ds-text-muted);
|
|
172
|
+
text-decoration: none;
|
|
173
|
+
display: inline-flex;
|
|
174
|
+
gap: 6px;
|
|
175
|
+
align-items: center;
|
|
176
|
+
margin-bottom: var(--ds-space-4);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.ds-back-link:hover {
|
|
180
|
+
color: var(--ds-link);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* ----- Page header (eyebrow + h1 + lede) ----- */
|
|
184
|
+
.ds-page-header {
|
|
185
|
+
padding-top: var(--ds-space-7);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.ds-page-header > .grid-label {
|
|
189
|
+
margin: 0 0 var(--ds-space-2);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.ds-page-header > h1 {
|
|
193
|
+
margin: 0 0 var(--ds-space-3);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.ds-page-header > .ds-lede {
|
|
197
|
+
margin: 0 0 var(--ds-space-6);
|
|
198
|
+
max-width: 620px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* ----- Small mono note (inline meta text) ----- */
|
|
202
|
+
.ds-mono-note {
|
|
203
|
+
font-family: var(--ds-font-mono);
|
|
204
|
+
font-size: 12px;
|
|
205
|
+
color: var(--ds-text-muted);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* ----- Panel (cards that don't need shadcn's internal structure) ----- */
|
|
209
|
+
.ds-panel {
|
|
210
|
+
background: var(--ds-surface);
|
|
211
|
+
border-radius: var(--ds-radius-md);
|
|
212
|
+
padding: var(--ds-space-5);
|
|
213
|
+
box-shadow: var(--ds-shadow-sm);
|
|
214
|
+
transition: transform var(--ds-duration-base) var(--ds-ease-standard),
|
|
215
|
+
box-shadow var(--ds-duration-base) var(--ds-ease-standard);
|
|
216
|
+
}
|
|
217
|
+
.ds-panel.interactive:hover {
|
|
218
|
+
transform: translateY(-2px);
|
|
219
|
+
box-shadow: var(--ds-shadow-md);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ----- kbd chip ----- */
|
|
223
|
+
.kbd {
|
|
224
|
+
font-family: var(--ds-font-mono);
|
|
225
|
+
font-size: 11px;
|
|
226
|
+
padding: 2px 6px;
|
|
227
|
+
background: var(--ds-surface);
|
|
228
|
+
border: 1px solid var(--ds-border);
|
|
229
|
+
border-radius: var(--ds-radius-sm);
|
|
230
|
+
color: var(--ds-text);
|
|
231
|
+
}
|
package/src/tailwind.css
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* GENERATED by scripts/generate-bridge.mjs from src/tokens.css.
|
|
2
|
+
Do not edit by hand. Run `npm run generate`. */
|
|
3
|
+
@import "./core.css";
|
|
4
|
+
|
|
5
|
+
@theme {
|
|
6
|
+
/* Design system only allows three radii (8px / 16px / 999px).
|
|
7
|
+
Map every Tailwind rounded-* utility into one of them, treating 8px
|
|
8
|
+
as the "input/chip" default and 16px as the "card/panel" default.
|
|
9
|
+
Anything that should be a pill uses rounded-full explicitly. */
|
|
10
|
+
--radius-sm: 8px;
|
|
11
|
+
--radius-md: 8px;
|
|
12
|
+
--radius-lg: 16px;
|
|
13
|
+
--radius-xl: 16px;
|
|
14
|
+
--radius-2xl: 16px;
|
|
15
|
+
--radius-3xl: 16px;
|
|
16
|
+
|
|
17
|
+
--color-background: hsl(var(--background));
|
|
18
|
+
--color-foreground: hsl(var(--foreground));
|
|
19
|
+
--color-card: hsl(var(--card));
|
|
20
|
+
--color-card-foreground: hsl(var(--card-foreground));
|
|
21
|
+
--color-popover: hsl(var(--popover));
|
|
22
|
+
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
23
|
+
--color-primary: hsl(var(--primary));
|
|
24
|
+
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
25
|
+
--color-secondary: hsl(var(--secondary));
|
|
26
|
+
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
27
|
+
--color-muted: hsl(var(--muted));
|
|
28
|
+
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
29
|
+
--color-accent: hsl(var(--accent));
|
|
30
|
+
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
31
|
+
--color-destructive: hsl(var(--destructive));
|
|
32
|
+
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
33
|
+
--color-border: hsl(var(--border));
|
|
34
|
+
--color-input: hsl(var(--input));
|
|
35
|
+
--color-ring: hsl(var(--ring));
|
|
36
|
+
--color-chart-1: hsl(var(--chart-1));
|
|
37
|
+
--color-chart-2: hsl(var(--chart-2));
|
|
38
|
+
--color-chart-3: hsl(var(--chart-3));
|
|
39
|
+
--color-chart-4: hsl(var(--chart-4));
|
|
40
|
+
--color-chart-5: hsl(var(--chart-5));
|
|
41
|
+
|
|
42
|
+
--font-display: "Outfit", system-ui, sans-serif;
|
|
43
|
+
--font-body: "DM Sans", system-ui, sans-serif;
|
|
44
|
+
--font-mono: "JetBrains Mono", ui-monospace, monospace;
|
|
45
|
+
|
|
46
|
+
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
47
|
+
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
48
|
+
|
|
49
|
+
@keyframes accordion-down {
|
|
50
|
+
from { height: 0; }
|
|
51
|
+
to { height: var(--radix-accordion-content-height); }
|
|
52
|
+
}
|
|
53
|
+
@keyframes accordion-up {
|
|
54
|
+
from { height: var(--radix-accordion-content-height); }
|
|
55
|
+
to { height: 0; }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@layer base {
|
|
60
|
+
*, ::after, ::before, ::backdrop, ::file-selector-button {
|
|
61
|
+
border-color: hsl(var(--border));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
html { font-size: 16px; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* shadcn HSL bridge — derived from --ds-* tokens */
|
|
68
|
+
:root {
|
|
69
|
+
--background: 36 50% 96%;
|
|
70
|
+
--foreground: 33 22% 10%;
|
|
71
|
+
--card: 36 50% 96%;
|
|
72
|
+
--card-foreground: 33 22% 10%;
|
|
73
|
+
--popover: 36 50% 96%;
|
|
74
|
+
--popover-foreground: 33 22% 10%;
|
|
75
|
+
--primary: 22 74% 42%;
|
|
76
|
+
--primary-foreground: 0 0% 100%;
|
|
77
|
+
--secondary: 38 44% 92%;
|
|
78
|
+
--secondary-foreground: 33 22% 10%;
|
|
79
|
+
--muted: 39 42% 88%;
|
|
80
|
+
--muted-foreground: 33 14% 37%;
|
|
81
|
+
--accent: 38 44% 92%;
|
|
82
|
+
--accent-foreground: 33 22% 10%;
|
|
83
|
+
--destructive: 5 57% 42%;
|
|
84
|
+
--destructive-foreground: 0 0% 100%;
|
|
85
|
+
--border: 38 33% 82%;
|
|
86
|
+
--input: 38 33% 82%;
|
|
87
|
+
--ring: 22 74% 42%;
|
|
88
|
+
--chart-1: 22 74% 42%;
|
|
89
|
+
--chart-2: 39 65% 48%;
|
|
90
|
+
--chart-3: 178 46% 34%;
|
|
91
|
+
--chart-4: 90 33% 36%;
|
|
92
|
+
--chart-5: 5 57% 42%;
|
|
93
|
+
--radius: 1rem;
|
|
94
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@import "./core.css";
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
/* Design system only allows three radii (8px / 16px / 999px).
|
|
5
|
+
Map every Tailwind rounded-* utility into one of them, treating 8px
|
|
6
|
+
as the "input/chip" default and 16px as the "card/panel" default.
|
|
7
|
+
Anything that should be a pill uses rounded-full explicitly. */
|
|
8
|
+
--radius-sm: 8px;
|
|
9
|
+
--radius-md: 8px;
|
|
10
|
+
--radius-lg: 16px;
|
|
11
|
+
--radius-xl: 16px;
|
|
12
|
+
--radius-2xl: 16px;
|
|
13
|
+
--radius-3xl: 16px;
|
|
14
|
+
|
|
15
|
+
--color-background: hsl(var(--background));
|
|
16
|
+
--color-foreground: hsl(var(--foreground));
|
|
17
|
+
--color-card: hsl(var(--card));
|
|
18
|
+
--color-card-foreground: hsl(var(--card-foreground));
|
|
19
|
+
--color-popover: hsl(var(--popover));
|
|
20
|
+
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
21
|
+
--color-primary: hsl(var(--primary));
|
|
22
|
+
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
23
|
+
--color-secondary: hsl(var(--secondary));
|
|
24
|
+
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
25
|
+
--color-muted: hsl(var(--muted));
|
|
26
|
+
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
27
|
+
--color-accent: hsl(var(--accent));
|
|
28
|
+
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
29
|
+
--color-destructive: hsl(var(--destructive));
|
|
30
|
+
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
31
|
+
--color-border: hsl(var(--border));
|
|
32
|
+
--color-input: hsl(var(--input));
|
|
33
|
+
--color-ring: hsl(var(--ring));
|
|
34
|
+
--color-chart-1: hsl(var(--chart-1));
|
|
35
|
+
--color-chart-2: hsl(var(--chart-2));
|
|
36
|
+
--color-chart-3: hsl(var(--chart-3));
|
|
37
|
+
--color-chart-4: hsl(var(--chart-4));
|
|
38
|
+
--color-chart-5: hsl(var(--chart-5));
|
|
39
|
+
|
|
40
|
+
--font-display: "Outfit", system-ui, sans-serif;
|
|
41
|
+
--font-body: "DM Sans", system-ui, sans-serif;
|
|
42
|
+
--font-mono: "JetBrains Mono", ui-monospace, monospace;
|
|
43
|
+
|
|
44
|
+
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
45
|
+
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
46
|
+
|
|
47
|
+
@keyframes accordion-down {
|
|
48
|
+
from { height: 0; }
|
|
49
|
+
to { height: var(--radix-accordion-content-height); }
|
|
50
|
+
}
|
|
51
|
+
@keyframes accordion-up {
|
|
52
|
+
from { height: var(--radix-accordion-content-height); }
|
|
53
|
+
to { height: 0; }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@layer base {
|
|
58
|
+
*, ::after, ::before, ::backdrop, ::file-selector-button {
|
|
59
|
+
border-color: hsl(var(--border));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
html { font-size: 16px; }
|
|
63
|
+
}
|
package/src/tokens.css
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
Dustin Riley Design System — Colors & Type tokens
|
|
3
|
+
Digital mid-century modern. Warm neutrals + restrained color.
|
|
4
|
+
Fonts are loaded via <link> tags in Base.astro.
|
|
5
|
+
============================================================ */
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
/* Color: Warm Neutrals */
|
|
9
|
+
--ds-bg: #faf6f0;
|
|
10
|
+
--ds-surface: #f3ece0;
|
|
11
|
+
--ds-surface-sunken: #ede4d3;
|
|
12
|
+
--ds-border: #e0d5c2;
|
|
13
|
+
--ds-text: #1f1a14;
|
|
14
|
+
--ds-text-muted: #6b5f50;
|
|
15
|
+
|
|
16
|
+
/* Color: Primary (burnt orange) — used for surfaces, buttons, the brand mark.
|
|
17
|
+
--ds-primary itself does NOT meet 4.5:1 against --ds-bg, so for
|
|
18
|
+
text-as-brand (links, active nav, hover titles) use --ds-link instead. */
|
|
19
|
+
--ds-primary: #b8541c;
|
|
20
|
+
--ds-primary-hover: #9e4615;
|
|
21
|
+
--ds-primary-pressed: #85390f;
|
|
22
|
+
|
|
23
|
+
/* Color: Link — darker burnt orange shades that clear WCAG AA (~5.9:1
|
|
24
|
+
and ~7.5:1 respectively) on both --ds-bg and --ds-surface. */
|
|
25
|
+
--ds-link: #9e4615;
|
|
26
|
+
--ds-link-hover: #85390f;
|
|
27
|
+
|
|
28
|
+
/* Color: Accents */
|
|
29
|
+
--ds-accent-ochre: #c9922b;
|
|
30
|
+
--ds-accent-teal: #2e7d7a;
|
|
31
|
+
--ds-accent-plum: #8b5e83;
|
|
32
|
+
|
|
33
|
+
/* Color: Semantic */
|
|
34
|
+
--ds-success: #5c7a3e;
|
|
35
|
+
--ds-warning: #c9922b;
|
|
36
|
+
--ds-error: #a8392e;
|
|
37
|
+
|
|
38
|
+
/* On-color foregrounds */
|
|
39
|
+
--ds-on-primary: #ffffff;
|
|
40
|
+
|
|
41
|
+
/* Typography: families */
|
|
42
|
+
--ds-font-display: "Outfit", system-ui, sans-serif;
|
|
43
|
+
--ds-font-body: "DM Sans", system-ui, sans-serif;
|
|
44
|
+
--ds-font-mono: "JetBrains Mono", ui-monospace, monospace;
|
|
45
|
+
|
|
46
|
+
/* Typography: scale (1.25 ratio, 16px root) */
|
|
47
|
+
--ds-fs-display: 3rem;
|
|
48
|
+
--ds-fs-h1: 2.25rem;
|
|
49
|
+
--ds-fs-h2: 1.75rem;
|
|
50
|
+
--ds-fs-h3: 1.375rem;
|
|
51
|
+
--ds-fs-h4: 1.125rem;
|
|
52
|
+
--ds-fs-h5: 1rem;
|
|
53
|
+
--ds-fs-h6: 0.875rem;
|
|
54
|
+
--ds-fs-body-lg: 1.125rem;
|
|
55
|
+
--ds-fs-body: 1rem;
|
|
56
|
+
--ds-fs-body-sm: 0.875rem;
|
|
57
|
+
--ds-fs-caption: 0.75rem;
|
|
58
|
+
|
|
59
|
+
--ds-lh-display: 1.1;
|
|
60
|
+
--ds-lh-h1: 1.15;
|
|
61
|
+
--ds-lh-h2: 1.2;
|
|
62
|
+
--ds-lh-h3: 1.3;
|
|
63
|
+
--ds-lh-h4: 1.35;
|
|
64
|
+
--ds-lh-h5: 1.4;
|
|
65
|
+
--ds-lh-h6: 1.4;
|
|
66
|
+
--ds-lh-body-lg: 1.5;
|
|
67
|
+
--ds-lh-body: 1.5;
|
|
68
|
+
|
|
69
|
+
--ds-tracking-display: -0.02em;
|
|
70
|
+
--ds-tracking-h1: -0.02em;
|
|
71
|
+
--ds-tracking-h2: -0.01em;
|
|
72
|
+
--ds-tracking-h3: -0.01em;
|
|
73
|
+
|
|
74
|
+
/* Spacing: 4px base */
|
|
75
|
+
--ds-space-0: 0;
|
|
76
|
+
--ds-space-1: 4px;
|
|
77
|
+
--ds-space-2: 8px;
|
|
78
|
+
--ds-space-3: 12px;
|
|
79
|
+
--ds-space-4: 16px;
|
|
80
|
+
--ds-space-5: 24px;
|
|
81
|
+
--ds-space-6: 32px;
|
|
82
|
+
--ds-space-7: 48px;
|
|
83
|
+
--ds-space-8: 64px;
|
|
84
|
+
--ds-space-9: 96px;
|
|
85
|
+
|
|
86
|
+
/* Radius (3 only) */
|
|
87
|
+
--ds-radius-sm: 8px;
|
|
88
|
+
--ds-radius-md: 16px;
|
|
89
|
+
--ds-radius-pill: 999px;
|
|
90
|
+
|
|
91
|
+
/* Shadow (warm-tinted) */
|
|
92
|
+
--ds-shadow-sm: 0 1px 2px rgba(74, 52, 28, 0.06),
|
|
93
|
+
0 1px 1px rgba(74, 52, 28, 0.04);
|
|
94
|
+
--ds-shadow-md: 0 4px 8px rgba(74, 52, 28, 0.08),
|
|
95
|
+
0 2px 4px rgba(74, 52, 28, 0.05);
|
|
96
|
+
--ds-shadow-lg: 0 16px 32px rgba(74, 52, 28, 0.12),
|
|
97
|
+
0 4px 8px rgba(74, 52, 28, 0.06);
|
|
98
|
+
|
|
99
|
+
/* Motion */
|
|
100
|
+
--ds-duration-fast: 120ms;
|
|
101
|
+
--ds-duration-base: 200ms;
|
|
102
|
+
--ds-duration-slow: 280ms;
|
|
103
|
+
--ds-ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
104
|
+
|
|
105
|
+
/* Focus ring */
|
|
106
|
+
--ds-focus-ring:
|
|
107
|
+
0 0 0 2px var(--ds-bg), 0 0 0 4px rgba(184, 84, 28, 0.4);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
:focus-visible {
|
|
111
|
+
outline: none;
|
|
112
|
+
box-shadow: var(--ds-focus-ring);
|
|
113
|
+
border-radius: var(--ds-radius-sm);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* ============================================================
|
|
117
|
+
Base element resets
|
|
118
|
+
(sourced from scorigami globals.css @layer base, layer-neutral)
|
|
119
|
+
============================================================ */
|
|
120
|
+
|
|
121
|
+
html { font-size: 16px; }
|
|
122
|
+
|
|
123
|
+
body {
|
|
124
|
+
background: var(--ds-bg);
|
|
125
|
+
color: var(--ds-text);
|
|
126
|
+
font-family: var(--ds-font-body);
|
|
127
|
+
font-size: var(--ds-fs-body);
|
|
128
|
+
line-height: var(--ds-lh-body);
|
|
129
|
+
-webkit-font-smoothing: antialiased;
|
|
130
|
+
text-rendering: optimizeLegibility;
|
|
131
|
+
overflow-x: clip;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
h1, h2, h3, h4, h5, h6 {
|
|
135
|
+
font-family: var(--ds-font-display);
|
|
136
|
+
color: var(--ds-text);
|
|
137
|
+
font-weight: 600;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
h1, .h1 {
|
|
141
|
+
font-size: var(--ds-fs-h1);
|
|
142
|
+
line-height: var(--ds-lh-h1);
|
|
143
|
+
letter-spacing: var(--ds-tracking-h1);
|
|
144
|
+
}
|
|
145
|
+
h2, .h2 {
|
|
146
|
+
font-size: var(--ds-fs-h2);
|
|
147
|
+
line-height: var(--ds-lh-h2);
|
|
148
|
+
letter-spacing: var(--ds-tracking-h2);
|
|
149
|
+
}
|
|
150
|
+
h3, .h3 {
|
|
151
|
+
font-size: var(--ds-fs-h3);
|
|
152
|
+
line-height: var(--ds-lh-h3);
|
|
153
|
+
letter-spacing: var(--ds-tracking-h3);
|
|
154
|
+
font-weight: 500;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
a {
|
|
158
|
+
color: var(--ds-link);
|
|
159
|
+
text-decoration: underline;
|
|
160
|
+
text-decoration-thickness: 1px;
|
|
161
|
+
text-underline-offset: 3px;
|
|
162
|
+
transition: color var(--ds-duration-fast) var(--ds-ease-standard);
|
|
163
|
+
}
|
|
164
|
+
a:hover { color: var(--ds-link-hover); }
|
|
165
|
+
|
|
166
|
+
code, pre, kbd, samp {
|
|
167
|
+
font-family: var(--ds-font-mono);
|
|
168
|
+
font-size: 0.9em;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
code {
|
|
172
|
+
background: var(--ds-surface-sunken);
|
|
173
|
+
padding: 2px 6px;
|
|
174
|
+
border-radius: var(--ds-radius-sm);
|
|
175
|
+
border: 1px solid var(--ds-border);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
::selection { background: rgba(184, 84, 28, 0.2); }
|