7k-design-system 1.1.0 → 1.2.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/CHANGELOG.md +34 -0
- package/CONSUMER_GUIDE.md +109 -50
- package/DESIGN.md +631 -439
- package/README.md +76 -75
- package/SKILL.md +107 -78
- package/build/icons/icon-7kgroup-light.svg +10 -0
- package/build/icons/icon-7kgroup.svg +10 -0
- package/build/icons/icon-7kminato-light.svg +10 -0
- package/build/icons/icon-7kminato.svg +10 -0
- package/build/icons/icon-base.svg +10 -0
- package/build/icons/icon-inari-light.svg +10 -0
- package/build/icons/icon-inari.svg +10 -0
- package/dist/7k-design-system.css +1 -1
- package/dist/animations.css +1 -1
- package/dist/build/icons/icon-7kgroup-light.svg +10 -0
- package/dist/build/icons/icon-7kgroup.svg +10 -0
- package/dist/build/icons/icon-7kminato-light.svg +10 -0
- package/dist/build/icons/icon-7kminato.svg +10 -0
- package/dist/build/icons/icon-base.svg +10 -0
- package/dist/build/icons/icon-inari-light.svg +10 -0
- package/dist/build/icons/icon-inari.svg +10 -0
- package/dist/components.css +1 -1
- package/dist/mockServiceWorker.js +361 -0
- package/dist/projects.css +1 -0
- package/dist/react/components/Alert.d.ts +2 -0
- package/dist/react/components/Avatar.d.ts +2 -0
- package/dist/react/{react/components → components}/Badge.d.ts +0 -1
- package/dist/react/{react/components → components}/Button.d.ts +0 -1
- package/dist/react/components/Card.d.ts +4 -0
- package/dist/react/components/Checkbox.d.ts +2 -0
- package/dist/react/components/Drawer.d.ts +2 -0
- package/dist/react/components/Icon.d.ts +2 -0
- package/dist/react/{react/components → components}/Input.d.ts +0 -1
- package/dist/react/components/IsometricBackground.d.ts +2 -0
- package/dist/react/components/Listbox.d.ts +2 -0
- package/dist/react/components/Modal.d.ts +4 -0
- package/dist/react/components/Nav.d.ts +3 -0
- package/dist/react/components/Progress.d.ts +2 -0
- package/dist/react/components/ProjectIcon.d.ts +6 -0
- package/dist/react/components/Radio.d.ts +2 -0
- package/dist/react/components/Select.d.ts +3 -0
- package/dist/react/components/Skeleton.d.ts +2 -0
- package/dist/react/components/Spinner.d.ts +2 -0
- package/dist/react/components/Tabs.d.ts +8 -0
- package/dist/react/components/TextureOverlay.d.ts +2 -0
- package/dist/react/components/Toast.d.ts +2 -0
- package/dist/react/components/Toggle.d.ts +2 -0
- package/dist/react/components/Tooltip.d.ts +2 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +32 -0
- package/dist/react/index.js +1188 -128
- package/dist/react/mockServiceWorker.js +361 -0
- package/dist/react/theme/ProjectProvider.d.ts +14 -0
- package/dist/react/{react/theme → theme}/ThemeContext.d.ts +0 -1
- package/dist/react/{react/theme → theme}/ThemeProvider.d.ts +0 -1
- package/dist/react/theme/projects.d.ts +4 -0
- package/dist/react/theme/useProject.d.ts +2 -0
- package/dist/react/{react/theme → theme}/useTheme.d.ts +0 -1
- package/dist/react/types.d.ts +160 -0
- package/dist/textures.css +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +49 -35
- package/dist/preview/brand-assets.html +0 -83
- package/dist/preview/colors-primary.html +0 -101
- package/dist/preview/components-buttons.html +0 -84
- package/dist/preview/spacing-tokens.html +0 -79
- package/dist/preview/textures-backgrounds.html +0 -102
- package/dist/preview/typography-specimens.html +0 -73
- package/dist/react/react/components/Badge.stories.d.ts +0 -12
- package/dist/react/react/components/Button.stories.d.ts +0 -16
- package/dist/react/react/components/Input.stories.d.ts +0 -11
- package/dist/react/react/components/ThemeToggle.stories.d.ts +0 -7
- package/dist/react/react/index.d.ts +0 -8
- package/dist/react/react/types.d.ts +0 -33
- package/dist/react/stories/Components.stories.d.ts +0 -10
- package/dist/react/stories/Textures.stories.d.ts +0 -11
- package/preview/brand-assets.html +0 -83
- package/preview/colors-primary.html +0 -101
- package/preview/components-buttons.html +0 -84
- package/preview/spacing-tokens.html +0 -79
- package/preview/textures-backgrounds.html +0 -102
- package/preview/typography-specimens.html +0 -73
- /package/build/{icon.svg → icons/icon.svg} +0 -0
- /package/build/{logo-7k-light.svg → logos/logo-7k-light.svg} +0 -0
- /package/build/{logo-7k.svg → logos/logo-7k.svg} +0 -0
- /package/dist/build/{icon.svg → icons/icon.svg} +0 -0
- /package/dist/build/{logo-7k-light.svg → logos/logo-7k-light.svg} +0 -0
- /package/dist/build/{logo-7k.svg → logos/logo-7k.svg} +0 -0
- /package/dist/react/{react/components → components}/ThemeToggle.d.ts +0 -0
package/DESIGN.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> Version: 1.0.0-alpha.1 (production-ready)
|
|
4
4
|
> Category: Custom · Surface: web, mobile, desktop
|
|
5
|
-
> Font: Geist + Geist Mono + Geist Pixel ·
|
|
5
|
+
> Font: Geist + Geist Mono + Geist Pixel · Major neon: #FF0FF · Secondary neon: cyan (thematic per project) · Logo: 7K · Theme: Dark-first
|
|
6
6
|
> 1-bit textures: 10 patterns · 1-bit components: 40+ · 1-bit animations: 20+ keyframes
|
|
7
|
-
> React UI kit: Button, Input, Badge, ThemeToggle, ThemeProvider, useTheme
|
|
7
|
+
> React UI kit: Button, Input, Badge, Card, Modal, Drawer, Toast, Tooltip, Alert, Tabs, Nav, Checkbox, Radio, Toggle, Select, Textarea, ThemeToggle, ThemeProvider, ProjectProvider, useTheme, useProject
|
|
8
8
|
> Build: Vite + PostCSS + TypeScript · Test: Vitest + Testing Library · Docs: Storybook
|
|
9
9
|
|
|
10
10
|
## Source context
|
|
@@ -14,16 +14,18 @@ Dark-first dual-theme design system for a tech holding. One parent brand (7K ·
|
|
|
14
14
|
The brand brief specifies: "We only have 1 font and it's Geist. Our logo is just '7K' and our main brand color is #FF0FF. We are a tech company with different projects and we're open on an approach to differentiate brand wise the 'main company' with the other projects. We want to use inspiration from Tokyo's neon atmosphere and Manga-influenced 1-bit using black and white as well as abstract 1-bit animations. We're using a dark theme for websites."
|
|
15
15
|
|
|
16
16
|
Key constraints derived from the source:
|
|
17
|
+
|
|
17
18
|
- **Three-font system** → Geist (sans-serif) for body and headings, Geist Mono for labels, code, and tabular data, Geist Pixel (5 geometric variants: Square, Circle, Grid, Line, Triangle) for ornamental and pixel-constrained display use.
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
19
|
+
- **Major neon accent** → #FF0FF (vivid magenta) as the primary brand accent.
|
|
20
|
+
- **Secondary neon accent** → Cyan by default (`--brand-secondary`), dynamically themable per project via `data-project` or `ProjectProvider`.
|
|
21
|
+
- **Logo** → Star-burst pattern logo in `build/logos/logo-7k.svg`: a geometric radial pattern with #FF0FF brand accent tones. Light variant at `build/logos/logo-7k-light.svg` (black polygons for light backgrounds). App icon at `build/icons/icon.svg`.
|
|
20
22
|
- **Dark theme** → All surfaces start from near-black. Light theme is opt-in only.
|
|
21
|
-
- **Project differentiation** →
|
|
23
|
+
- **Project differentiation** → Each project gets its own secondary accent on the same dark base: **magenta = 7KGroup** (parent, also `--brand-primary`), **cyan = 7KMinato**, **inari (burnt orange) = Inari**. Projects theme `--brand-secondary` to their hue via `data-project` or `ProjectProvider`.
|
|
22
24
|
- **Tokyo neon** → High contrast, nocturnal canvas, electric accents, no warm/beige tones.
|
|
23
25
|
- **1-bit manga influence** → 10-texture background pattern library (scanline, halftone, dot matrix, stripes, crosshatch, checkerboard, noise, vignette). All textures are CSS gradients — no images, no SVG humans.
|
|
24
26
|
- **Abstract 1-bit animations** → 20+ animation keyframes organized as ambient (continuous) and trigger (burst) categories. Step timing for retro feel, reduced-motion collapse.
|
|
25
27
|
- **1-bit component system** → 40+ components with zero radius, 2px white borders, invert hover state. Unified black/white visual language with thin accent layer modifiers for color moments.
|
|
26
|
-
- **React UI kit** → TypeScript React components (Button, Input, Badge, ThemeToggle) with ThemeProvider
|
|
28
|
+
- **React UI kit** → TypeScript React components (Button, Input, Badge, Card, Modal, Drawer, Toast, Tooltip, Alert, Tabs, Nav, Checkbox, Radio, Toggle, Select, Textarea, ThemeToggle) with ThemeProvider, ProjectProvider, useTheme, and useProject hooks.
|
|
27
29
|
- **Modular CSS** → 10 source files in `src/css/` compiled into `dist/7k-design-system.css`.
|
|
28
30
|
|
|
29
31
|
## Package Structure
|
|
@@ -69,13 +71,6 @@ The design system is distributed as an npm package with dual entry points: CSS-o
|
|
|
69
71
|
│ ├── ThemeProvider.test.tsx
|
|
70
72
|
│ ├── ThemeToggle.test.tsx
|
|
71
73
|
│ └── a11y.test.tsx
|
|
72
|
-
├── preview/ # 6 HTML review cards
|
|
73
|
-
│ ├── colors-primary.html
|
|
74
|
-
│ ├── typography-specimens.html
|
|
75
|
-
│ ├── spacing-tokens.html
|
|
76
|
-
│ ├── components-buttons.html
|
|
77
|
-
│ ├── textures-backgrounds.html
|
|
78
|
-
│ └── brand-assets.html
|
|
79
74
|
├── build/ # Brand assets
|
|
80
75
|
│ ├── logo-7k.svg
|
|
81
76
|
│ ├── logo-7k-light.svg
|
|
@@ -124,15 +119,17 @@ The design system is distributed as an npm package with dual entry points: CSS-o
|
|
|
124
119
|
```
|
|
125
120
|
|
|
126
121
|
**CSS-only usage:**
|
|
122
|
+
|
|
127
123
|
```typescript
|
|
128
|
-
import '7k-design-system/css';
|
|
129
|
-
import '7k-design-system/css/tokens';
|
|
124
|
+
import '7k-design-system/css'; // Full bundle
|
|
125
|
+
import '7k-design-system/css/tokens'; // Tokens only
|
|
130
126
|
import '7k-design-system/css/components'; // Components only
|
|
131
|
-
import '7k-design-system/css/textures';
|
|
127
|
+
import '7k-design-system/css/textures'; // Textures only
|
|
132
128
|
import '7k-design-system/css/animations'; // Animations only
|
|
133
129
|
```
|
|
134
130
|
|
|
135
131
|
**React usage:**
|
|
132
|
+
|
|
136
133
|
```typescript
|
|
137
134
|
import { Button, Input, Badge, ThemeToggle, ThemeProvider, useTheme } from '7k-design-system/react';
|
|
138
135
|
import '7k-design-system/css';
|
|
@@ -142,7 +139,7 @@ import '7k-design-system/css';
|
|
|
142
139
|
|
|
143
140
|
- **CSS build:** `vite build --config vite.css.config.ts` — compiles `src/css/index.css` into `dist/7k-design-system.css` with PostCSS pipeline (postcss-import, postcss-nesting, autoprefixer, cssnano)
|
|
144
141
|
- **React build:** `vite build --config vite.react.config.ts` — compiles TypeScript React components into ESM + CJS bundles with `.d.ts` declarations via vite-plugin-dts
|
|
145
|
-
- **Asset copy:** `node scripts/copy-assets.js` — copies
|
|
142
|
+
- **Asset copy:** `node scripts/copy-assets.js` — copies fonts/ and build/ to dist/
|
|
146
143
|
- **Development:** `npm run dev` — Vite dev server; `npm run storybook` — Storybook at port 6006
|
|
147
144
|
- **Testing:** `npm test` — Vitest + jsdom + @testing-library/react; `npm run test:a11y` — axe-core accessibility tests
|
|
148
145
|
- **Linting:** `npm run lint` — ESLint (TS/TSX) + Stylelint (CSS); `npm run typecheck` — `tsc --noEmit`
|
|
@@ -153,11 +150,12 @@ import '7k-design-system/css';
|
|
|
153
150
|
|
|
154
151
|
Tokyo neon meets manga-influenced 1-bit. The canvas is deep near-black, with sharp white text, electric magenta (`#FF0FF`) as the primary brand accent, and cyan as a secondary project accent. Black-and-white 1-bit textures — scanline overlays, halftone dot noise, glitch keyframes — provide rhythm and atmosphere. The mood is nocturnal, high-contrast, and unapologetically digital.
|
|
155
152
|
|
|
156
|
-
Company/project differentiation:
|
|
153
|
+
Company/project differentiation: 7KGroup (parent) uses vivid magenta (`--brand-primary` baseline). Inside a project scope the project accent becomes dominant, overriding the full `--brand-primary` chain: 7KMinato runs cyan, Inari runs burnt orange (Fushimi Inari palette). Same system, distinct at a glance.
|
|
157
154
|
|
|
158
|
-
**Logo:** Star-burst pattern logo in `build/logo-7k.svg` — a geometric radial pattern with #FF0FF brand accent tones. Light variant at `build/logo-7k-light.svg` (light backgrounds). App icon at `build/icon.svg`.
|
|
155
|
+
**Logo:** Star-burst pattern logo in `build/logos/logo-7k.svg` — a geometric radial pattern with #FF0FF brand accent tones. Light variant at `build/logos/logo-7k-light.svg` (light backgrounds). App icon at `build/icons/icon.svg`.
|
|
159
156
|
|
|
160
157
|
**1-bit texture primitives (background patterns):**
|
|
158
|
+
|
|
161
159
|
- **Scanline**: `repeating-linear-gradient(0deg, transparent 2px, rgba(255,255,255,0.03) 2px)` — horizontal scan lines, scroll-animated. Two speeds: slow (8s) and fast (3s).
|
|
162
160
|
- **Halftone dots**: `radial-gradient(color 1px, transparent 1px)` at 4px/6px/10px spacing — manga screentone at three densities (sm/md/lg). Accent-tinted variant uses magenta dots.
|
|
163
161
|
- **Dot matrix**: Uniform dot grid at 3px (dense), 6px (standard), or 12px (sparse) spacing for texture depth.
|
|
@@ -169,6 +167,7 @@ Company/project differentiation: the parent 7K brand uses vivid magenta (`--bran
|
|
|
169
167
|
- **Vignette**: Radial gradient from transparent center to black edge. Sharp variant clips tighter for manga panel corner fade.
|
|
170
168
|
|
|
171
169
|
**Glitch primitives:**
|
|
170
|
+
|
|
172
171
|
- Basic glitch: 5-frame translate jitter, 0.3s, 3 iterations
|
|
173
172
|
- Complex glitch: multi-axis + skew + clip-path splits, 0.8s, 2 iterations
|
|
174
173
|
- Invert flash: full-screen filter inversion, 0.15s burst
|
|
@@ -179,25 +178,25 @@ Company/project differentiation: the parent 7K brand uses vivid magenta (`--bran
|
|
|
179
178
|
|
|
180
179
|
### Texture categories
|
|
181
180
|
|
|
182
|
-
| Category
|
|
183
|
-
|
|
184
|
-
| Scanline
|
|
185
|
-
| Halftone dots
|
|
186
|
-
| Dot matrix
|
|
187
|
-
| Diagonal stripes
|
|
188
|
-
| Horizontal stripes | `.stripes-h`, `.stripes-h-dense`
|
|
189
|
-
| Vertical stripes
|
|
190
|
-
| Crosshatch
|
|
191
|
-
| Checkerboard
|
|
192
|
-
| Noise
|
|
193
|
-
| Vignette
|
|
181
|
+
| Category | Classes | Density variants | Use case |
|
|
182
|
+
| ------------------ | ---------------------------------------------------------------------------- | -------------------------------- | -------------------------------------- |
|
|
183
|
+
| Scanline | `.scanline`, `.scanline-fast` | slow (8s), fast (3s) | Hero sections, full-bleed walls |
|
|
184
|
+
| Halftone dots | `.halftone-sm`, `.halftone-md`, `.halftone-lg`, `.halftone-accent` | 4px/6px/10px grid, accent-tinted | Manga panel backgrounds, card surfaces |
|
|
185
|
+
| Dot matrix | `.dot-matrix-dense`, `.dot-matrix`, `.dot-matrix-sparse` | 3px/6px/12px grid | Texture depth behind text, dividers |
|
|
186
|
+
| Diagonal stripes | `.diagonal-stripes`, `.diagonal-stripes-dense`, `.diagonal-stripes-negative` | 7px/4px pitch, pure B/W | Directional cues, loading areas |
|
|
187
|
+
| Horizontal stripes | `.stripes-h`, `.stripes-h-dense` | 9px/5px pitch | Section rhythm, horizontal dividers |
|
|
188
|
+
| Vertical stripes | `.stripes-v`, `.stripes-v-dense` | 9px/5px pitch | Sidebar textures, column dividers |
|
|
189
|
+
| Crosshatch | `.crosshatch`, `.crosshatch-dense` | 7px/4px dual-angle | Dense manga shading, error states |
|
|
190
|
+
| Checkerboard | `.checkerboard`, `.checkerboard-contrast` | 12px/16px grid, pure B/W | Retro sections, QR motifs |
|
|
191
|
+
| Noise | `.noise`, `.noise-heavy`, `.noise-animated` | 4%/12% opacity, SVG fractal | CRT grain, analog texture |
|
|
192
|
+
| Vignette | `.vignette-ink`, `.vignette-ink-sharp` | Soft/sharp radial fade | Panel corner fade, hero-edge vignette |
|
|
194
193
|
|
|
195
194
|
### Texture composition rules
|
|
196
195
|
|
|
197
196
|
1. **One texture per section layer.** Apply at most one texture on the background layer and one on the overlay layer (`::after`). Scanline + halftone is the default pair for hero sections.
|
|
198
197
|
2. **Opacity scales with section density.** Hero/landing sections use lighter textures (5–10% opacity). Data-dense utility sections use stronger textures (10–15% opacity) or none.
|
|
199
|
-
3. **
|
|
200
|
-
4. **Texture as section separator.** When transitioning between full-bleed sections, add a `.separator-
|
|
198
|
+
3. **Texture on components is allowed with restraint.** Cards, panels, modals, drawers, and buttons can carry low-opacity texture overlays (`::before`, `pointer-events: none`) as long as the texture sits behind content and does not reduce contrast. Inputs and form controls should remain solid to preserve legibility. Use `.card-halftone`, `.surface-scanline`, `.btn-halftone`, `.modal-noise`, etc.
|
|
199
|
+
4. **Texture as section separator.** When transitioning between full-bleed sections, add a `.separator-solid` or `.stripes-h` band (40–80px tall) as a visual break — never use shadow or blur transitions.
|
|
201
200
|
5. **Layering order:** Base color → texture background → content container → optional scanline overlay. The overlay must have `pointer-events: none` and `z-index: 1` so it does not block interaction.
|
|
202
201
|
6. **Full-bleed hero walls** use scanline + vignette simultaneously: scanline on `::after` for the line pattern, vignette on `::before` for the edge fade. Both get `pointer-events: none`.
|
|
203
202
|
|
|
@@ -205,21 +204,21 @@ Company/project differentiation: the parent 7K brand uses vivid magenta (`--bran
|
|
|
205
204
|
|
|
206
205
|
```
|
|
207
206
|
Section 1 (hero) — Scanline overlay + noise grain, full-bleed
|
|
208
|
-
↓ separator-
|
|
207
|
+
↓ separator-solid
|
|
209
208
|
Section 2 (content) — Solid surface, no texture (reading zone)
|
|
210
|
-
↓ separator-
|
|
209
|
+
↓ separator-solid
|
|
211
210
|
Section 3 (stats) — Halftone-md background with accent tint
|
|
212
|
-
↓ separator-
|
|
211
|
+
↓ separator-solid
|
|
213
212
|
Section 4 (cta) — Scanline-fast overlay, invert section if 1-bit
|
|
214
213
|
```
|
|
215
214
|
|
|
216
215
|
### 1-bit section variants
|
|
217
216
|
|
|
218
|
-
- **Full invert section**: swap `--bg-base` with `--
|
|
217
|
+
- **Full invert section**: swap `--bg-base` with `--color-paper`, `--text-primary` with `--color-ink`. Used for CTAs, callout panels, or manga-style splash panels. Add `.diagonal-stripes-negative` for max contrast.
|
|
219
218
|
- **Scanline hero**: dark canvas, scanline overlay, accent headline with glow. The scanline `::after` sits above the background but below all content (`z-index: 1`). Content gets `position: relative; z-index: 2`.
|
|
220
219
|
- **Halftone card wall**: grid of cards with `.halftone-sm` or `.halftone-md` on the section container. Each card has solid `.card` background that breaks the texture — texture only lives between cards.
|
|
221
220
|
- **Noise backdrop**: `.noise` on full-page backgrounds for analog feel. Use `.noise-heavy` only on splash/loading screens where content density is low.
|
|
222
|
-
- **Vignette frame**: `.vignette-
|
|
221
|
+
- **Vignette frame**: `.vignette-ink` on slide/scene containers to draw the eye center. Used in intro animations and splash panels.
|
|
223
222
|
|
|
224
223
|
## 1c. Isometric Backgrounds — CSS-only 3D Perspective Patterns
|
|
225
224
|
|
|
@@ -227,192 +226,187 @@ Section 4 (cta) — Scanline-fast overlay, invert section if 1-bit
|
|
|
227
226
|
|
|
228
227
|
### Isometric pattern library
|
|
229
228
|
|
|
230
|
-
| Class
|
|
231
|
-
|
|
232
|
-
| `.isometric-grid`
|
|
233
|
-
| `.isometric-grid-dense`
|
|
234
|
-
| `.isometric-grid-accent`
|
|
235
|
-
| `.isometric-cubes`
|
|
236
|
-
| `.isometric-cubes-dense`
|
|
237
|
-
| `.isometric-cubes-accent` | Magenta-tinted cube wall
|
|
238
|
-
| `.isometric-pyramid`
|
|
239
|
-
| `.isometric-hex`
|
|
240
|
-
| `.isometric-pipes`
|
|
241
|
-
| `.isometric-pipes-fast`
|
|
242
|
-
| `.isometric-terrain`
|
|
229
|
+
| Class | Description | Technique |
|
|
230
|
+
| ------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
231
|
+
| `.isometric-grid` | Diamond tiling from dual 30°/-30° hatch lines at 24px pitch | `repeating-linear-gradient(30deg)` + `(-30deg)` |
|
|
232
|
+
| `.isometric-grid-dense` | Tighter 12px diamond grid | Same technique, denser pitch |
|
|
233
|
+
| `.isometric-grid-accent` | Magenta-tinted 24px diamond grid | Same, with `--magenta-500 / 0.12` stroke |
|
|
234
|
+
| `.isometric-cubes` | 3-face cube wall: right (150°), top (-30°), left (30°) faces at 40px | 3 `repeating-linear-gradient` layers with face-specific opacity |
|
|
235
|
+
| `.isometric-cubes-dense` | 20px cube wall | Same, finer resolution |
|
|
236
|
+
| `.isometric-cubes-accent` | Magenta-tinted cube wall | Same, with accent hue fills |
|
|
237
|
+
| `.isometric-pyramid` | Ascending zigzag steps: 150° + -30° gradients | Dual gradient with offset phase |
|
|
238
|
+
| `.isometric-hex` | Honeycomb hex grid from 60°/-60°/0° overlapping | 3 `repeating-linear-gradient` layers |
|
|
239
|
+
| `.isometric-pipes` | Converging tunnel perspective: left/right walls (30°/-30°) + floor (0°) | 3-gradient tunnel simulation |
|
|
240
|
+
| `.isometric-pipes-fast` | Denser tunnel, 8px walls | Same, tighter spacing |
|
|
241
|
+
| `.isometric-terrain` | Multi-layer depth: horizontal + 30° + -30° zigzag | 3-layer parallax-ready composition |
|
|
243
242
|
|
|
244
243
|
### Composition rules
|
|
245
244
|
|
|
246
245
|
1. **One isometric pattern per section.** Apply at most one isometric gradient per container. Stack with scanline overlay via class stacking.
|
|
247
|
-
2. **No
|
|
246
|
+
2. **No isometric background on interactive surfaces.** Cards, buttons, inputs, and form controls must not carry isometric backgrounds — use solid `--bg-elevated` instead. Isometric patterns are for section backgrounds only.
|
|
248
247
|
3. **Animate with animation classes.** Combine with `.iso-grid-scroll` for diagonal grid movement, `.iso-terrain-shift` for parallax depth layers.
|
|
249
248
|
4. **Reduced motion:** All isometric animations collapse at `prefers-reduced-motion: reduce`.
|
|
250
249
|
|
|
251
250
|
## 2. Color
|
|
252
251
|
|
|
253
|
-
**Source context reference:** The brand hex #FF0FF is the
|
|
252
|
+
**Source context reference:** The brand hex #FF0FF is the major neon accent. A secondary neon accent (cyan by default) is used for complementary actions and can be themed per project. All color tokens use hex values mapped through CSS custom properties.
|
|
254
253
|
|
|
255
254
|
The color system has three strict layers:
|
|
256
255
|
|
|
257
|
-
1. **Raw ramps** — 11-step scales (50–950) for Neutral, Magenta
|
|
256
|
+
1. **Raw ramps** — 11-step scales (50–950) for Neutral, Magenta (7KGroup), Cyan (7KMinato), Inari (Inari), plus extended below-ramp values (1000, void) and 4 semantic ramps (Success, Warning, Danger, Info). Never reference these directly in components.
|
|
258
257
|
2. **Theme role mapping** — `--bg-*`, `--text-*`, `--border-*`, `--brand-*`, `--status-*`, `--accent-*` tokens that map ramp values to functional roles. Remap per dark/light theme. This is the only layer components touch.
|
|
259
258
|
3. **Semantic colors** — `--status-success/warning/danger/info` tokens bound by **meaning, not decoration**. Use only for actual machine-state indication (badges, toasts, validation). Never use for decorative borders, accent accents, or non-status backgrounds.
|
|
260
259
|
|
|
261
|
-
> See
|
|
260
|
+
> See Storybook for live color swatches of the default dark theme and the opt-in light theme.
|
|
262
261
|
|
|
263
262
|
---
|
|
263
|
+
|
|
264
264
|
### Layer 1 — Raw Color Ramps
|
|
265
265
|
|
|
266
266
|
All ramps follow the same 11-step pattern (50 = lightest, 950 = darkest). Two extra steps exist below the ramp for true backgrounds.
|
|
267
267
|
|
|
268
268
|
#### Neutral ramp (slight cool cast, hue ~330)
|
|
269
269
|
|
|
270
|
-
| Token
|
|
271
|
-
|
|
272
|
-
| `--neutral-50`
|
|
273
|
-
| `--neutral-100`
|
|
274
|
-
| `--neutral-200`
|
|
275
|
-
| `--neutral-300`
|
|
276
|
-
| `--neutral-400`
|
|
277
|
-
| `--neutral-500`
|
|
278
|
-
| `--neutral-600`
|
|
279
|
-
| `--neutral-700`
|
|
280
|
-
| `--neutral-800`
|
|
281
|
-
| `--neutral-900`
|
|
282
|
-
| `--neutral-950`
|
|
283
|
-
| `--neutral-1000` | `#0A0A0D` | `--bg-base`
|
|
284
|
-
| `--neutral-void` | `#000000` | `--bg-void`, `--text-on-brand`, `--text-inverse` | —
|
|
285
|
-
|
|
286
|
-
**Usage rule:** Components reference the
|
|
270
|
+
| Token | Hex | Dark role | Light role |
|
|
271
|
+
| ---------------- | --------- | ------------------------------------------------ | -------------------------------------------------------- |
|
|
272
|
+
| `--neutral-50` | `#FAFAFB` | — | `--bg-base`, `--bg-void` |
|
|
273
|
+
| `--neutral-100` | `#EEEEF1` | — | `--bg-elevated` |
|
|
274
|
+
| `--neutral-200` | `#D7D7DC` | — | `--bg-raised`, `--status-neutral-bg` |
|
|
275
|
+
| `--neutral-300` | `#B0B0B8` | `--text-secondary` | `--bg-overlay`, `--text-disabled`, `--status-neutral-fg` |
|
|
276
|
+
| `--neutral-400` | `#82828A` | `--text-tertiary`, `--status-neutral` | `--bg-pressed`, `--text-placeholder` |
|
|
277
|
+
| `--neutral-500` | `#6B6B72` | `--text-placeholder` | `--text-secondary` |
|
|
278
|
+
| `--neutral-600` | `#50505A` | `--text-disabled` | — |
|
|
279
|
+
| `--neutral-700` | `#3A3A42` | `--bg-pressed` | — |
|
|
280
|
+
| `--neutral-800` | `#26262B` | `--bg-overlay`, `--status-neutral-bg` | — |
|
|
281
|
+
| `--neutral-900` | `#1C1C22` | `--bg-raised` | `--text-primary` |
|
|
282
|
+
| `--neutral-950` | `#131318` | `--bg-elevated` | — |
|
|
283
|
+
| `--neutral-1000` | `#0A0A0D` | `--bg-base` | — |
|
|
284
|
+
| `--neutral-void` | `#000000` | `--bg-void`, `--text-on-brand`, `--text-inverse` | — |
|
|
285
|
+
|
|
286
|
+
**Usage rule:** Components reference the _role_ tokens (e.g. `var(--bg-elevated)`), never the raw ramp tokens (e.g. `var(--neutral-950)`). The ramp table above documents what each step maps to — not what you should write.
|
|
287
287
|
|
|
288
288
|
#### Brand ramp — Magenta (hue ~330)
|
|
289
289
|
|
|
290
|
-
| Token
|
|
291
|
-
|
|
292
|
-
| `--magenta-50` | `#FFE5FF` | `--brand-primary-subtle` (dark)
|
|
293
|
-
| `--magenta-100` | `#FFC2FF` | —
|
|
294
|
-
| `--magenta-200` | `#FF99FF` | —
|
|
295
|
-
| `--magenta-300` | `#FF66FF` | —
|
|
296
|
-
| `--magenta-400` | `#FF33FF` | `--brand-primary-hover` (dark)
|
|
297
|
-
| `--magenta-500` | `#FF00FF` | `--brand-primary` · `--border-focus` · `--border-brand` · `--accent-square` | same across themes
|
|
298
|
-
| `--magenta-600` | `#D600D6` | `--brand-primary-active` (dark)
|
|
299
|
-
| `--magenta-700` | `#A800A8` | —
|
|
300
|
-
| `--magenta-800` | `#800080` | `--brand-primary-muted` (dark)
|
|
301
|
-
| `--magenta-900` | `#570057` | —
|
|
302
|
-
| `--magenta-950` | `#330033` | `--brand-primary-subtle` (dark)
|
|
303
|
-
|
|
304
|
-
#### Project accent ramps — Solar / Cyan / Acid / Ember
|
|
290
|
+
| Token | Hex | Dark role | Light role |
|
|
291
|
+
| --------------- | --------- | --------------------------------------------------------------------------- | -------------------------------- |
|
|
292
|
+
| `--magenta-50` | `#FFE5FF` | `--brand-primary-subtle` (dark) | — |
|
|
293
|
+
| `--magenta-100` | `#FFC2FF` | — | `--brand-primary-subtle` (light) |
|
|
294
|
+
| `--magenta-200` | `#FF99FF` | — | `--brand-primary-muted` (light) |
|
|
295
|
+
| `--magenta-300` | `#FF66FF` | — | — |
|
|
296
|
+
| `--magenta-400` | `#FF33FF` | `--brand-primary-hover` (dark) | — |
|
|
297
|
+
| `--magenta-500` | `#FF00FF` | `--brand-primary` · `--border-focus` · `--border-brand` · `--accent-square` | same across themes |
|
|
298
|
+
| `--magenta-600` | `#D600D6` | `--brand-primary-active` (dark) | `--brand-primary-hover` (light) |
|
|
299
|
+
| `--magenta-700` | `#A800A8` | — | `--brand-primary-active` (light) |
|
|
300
|
+
| `--magenta-800` | `#800080` | `--brand-primary-muted` (dark) | — |
|
|
301
|
+
| `--magenta-900` | `#570057` | — | — |
|
|
302
|
+
| `--magenta-950` | `#330033` | `--brand-primary-subtle` (dark) | — |
|
|
305
303
|
|
|
306
|
-
|
|
304
|
+
#### Project accent ramps — 7KMinato (Cyan) / Inari
|
|
307
305
|
|
|
308
|
-
|
|
306
|
+
Each project gets a single accent hue. Same 11-step structure; only the base (--500) and the theme-mapped hover (--600 in light) differ. (7KGroup's accent is the magenta primary ramp above.)
|
|
309
307
|
|
|
310
|
-
|
|
311
|
-
Accent token: `--accent-triangle`. Dark: `var(--solar-500)`, Light: `var(--solar-600)`.
|
|
312
|
-
|
|
313
|
-
**Cyan — Circle (hue ~190)**
|
|
308
|
+
**Cyan — 7KMinato (hue ~190)**
|
|
314
309
|
|
|
315
310
|
`--cyan-50: #E5FBFF` → `--cyan-500: #00E5FF` → `--cyan-950: #002A2E`.
|
|
316
|
-
Accent token: `--accent-
|
|
317
|
-
|
|
318
|
-
**Acid — Grid (hue ~105)**
|
|
311
|
+
Accent token: `--accent-7kminato`. Dark: `var(--cyan-500)`, Light: `var(--cyan-600)`.
|
|
319
312
|
|
|
320
|
-
|
|
321
|
-
Accent token: `--accent-grid`. Dark: `var(--acid-500)`, Light: `var(--acid-600)`.
|
|
313
|
+
**Inari — Inari project (hue ~18, Fushimi Inari palette)**
|
|
322
314
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
`--
|
|
326
|
-
Accent token: `--accent-line`. Dark: `var(--ember-500)`, Light: `var(--ember-600)`.
|
|
315
|
+
`--inari-50: #FDEEE7` → `--inari-500: #EE560D` (Orangealicious) → `--inari-950: #2B1C17` (Tetsu-Guro Black).
|
|
316
|
+
Named stops: `--inari-400` Knockout Orange `#E56F3F`, `--inari-600` Red Panda `#C44813`, `--inari-800` Rogan Josh `#8B310D`.
|
|
317
|
+
Accent token: `--accent-inari`. Dark: `var(--inari-500)`, Light: `var(--inari-600)`.
|
|
327
318
|
|
|
328
319
|
#### Semantic ramps (raw)
|
|
329
320
|
|
|
330
321
|
Each has a full 11-step scale (50–950). Never use directly — always go through `--status-{name}`, `--status-{name}-bg`, or `--status-{name}-fg`.
|
|
331
322
|
|
|
332
|
-
| Ramp
|
|
333
|
-
|
|
334
|
-
| Success | `#E5FCEF` | `#B8F5D2` | `#5CE69A` | `#00E676`
|
|
335
|
-
| Warning | `#FFF8E5` | `#FFEAB8` | `#FFCE5C` | `#FFB300`
|
|
336
|
-
| Danger | `#FFE5EB` | `#FFB8C5` | `#FF5C7A` | `#FF3B5C`
|
|
337
|
-
| Info | `#E5EFFF` | `#B8D2FF` | `#5C99FF` | `#3F8EFF`
|
|
323
|
+
| Ramp | 50 | 100 | 300 | 500 (base) | 700 | 950 |
|
|
324
|
+
| ------- | --------- | --------- | --------- | ---------- | --------- | --------- |
|
|
325
|
+
| Success | `#E5FCEF` | `#B8F5D2` | `#5CE69A` | `#00E676` | `#008A46` | `#002915` |
|
|
326
|
+
| Warning | `#FFF8E5` | `#FFEAB8` | `#FFCE5C` | `#FFB300` | `#A87600` | `#332400` |
|
|
327
|
+
| Danger | `#FFE5EB` | `#FFB8C5` | `#FF5C7A` | `#FF3B5C` | `#A82338` | `#330A10` |
|
|
328
|
+
| Info | `#E5EFFF` | `#B8D2FF` | `#5C99FF` | `#3F8EFF` | `#1F58A8` | `#091A33` |
|
|
338
329
|
|
|
339
330
|
#### 1-bit primitives
|
|
340
331
|
|
|
341
|
-
- `--
|
|
342
|
-
- `--
|
|
332
|
+
- `--color-ink: #000000` (`oklch(0% 0 0)`)
|
|
333
|
+
- `--color-paper: #FFFFFF` (`oklch(100% 0 0)`)
|
|
343
334
|
|
|
344
335
|
---
|
|
336
|
+
|
|
345
337
|
### Layer 2 — Theme Role Mapping
|
|
346
338
|
|
|
347
339
|
**Dark is the default.** Light is opt-in via `@media (prefers-color-scheme: light)` or `html[data-theme="light"` (set by `ThemeToggle` component in `src/react/components/ThemeToggle.tsx`). The same ramp primitives are used by both themes — only the role-to-ramp mapping changes.
|
|
348
340
|
|
|
349
341
|
#### Surface ladder — backgrounds
|
|
350
342
|
|
|
351
|
-
| Token
|
|
352
|
-
|
|
353
|
-
| `--bg-void`
|
|
354
|
-
| `--bg-base`
|
|
355
|
-
| `--bg-elevated`
|
|
356
|
-
| `--bg-raised`
|
|
357
|
-
| `--bg-overlay`
|
|
358
|
-
| `--bg-pressed`
|
|
359
|
-
| `--bg-translucent` | `rgba(255,255,255,0.04)` | `rgba(0,0,0,0.04)` | Subtle backdrop overlay.
|
|
343
|
+
| Token | Dark value | Light value | Usage rule |
|
|
344
|
+
| ------------------ | ------------------------ | ------------------ | --------------------------------------- |
|
|
345
|
+
| `--bg-void` | `--neutral-void` | `--neutral-50` | Page background only. Outermost canvas. |
|
|
346
|
+
| `--bg-base` | `--neutral-1000` | `--neutral-50` | Default surface. Most common container. |
|
|
347
|
+
| `--bg-elevated` | `--neutral-950` | `--neutral-100` | Cards, panels, section backgrounds. |
|
|
348
|
+
| `--bg-raised` | `--neutral-900` | `--neutral-200` | Modals, dropdowns, popovers, inputs. |
|
|
349
|
+
| `--bg-overlay` | `--neutral-800` | `--neutral-300` | Hover surfaces, tooltip backgrounds. |
|
|
350
|
+
| `--bg-pressed` | `--neutral-700` | `--neutral-400` | Active/pressed state. |
|
|
351
|
+
| `--bg-translucent` | `rgba(255,255,255,0.04)` | `rgba(0,0,0,0.04)` | Subtle backdrop overlay. |
|
|
360
352
|
|
|
361
353
|
**Ladder rule:** Step one level for each layer of depth. Never skip from `--bg-void` to `--bg-raised`.
|
|
362
354
|
`void → base → elevated → raised → overlay → pressed`
|
|
363
355
|
|
|
364
356
|
#### Text ladder
|
|
365
357
|
|
|
366
|
-
| Token
|
|
367
|
-
|
|
368
|
-
| `--text-primary`
|
|
369
|
-
| `--text-secondary`
|
|
370
|
-
| `--text-tertiary`
|
|
371
|
-
| `--text-placeholder` | `--neutral-500`
|
|
372
|
-
| `--text-disabled`
|
|
373
|
-
| `--text-inverse`
|
|
358
|
+
| Token | Dark value | Light value | Usage rule |
|
|
359
|
+
| -------------------- | ---------------- | --------------- | ----------------------------------- |
|
|
360
|
+
| `--text-primary` | `--neutral-50` | `--neutral-900` | Headlines, body paragraphs, labels. |
|
|
361
|
+
| `--text-secondary` | `--neutral-300` | `--neutral-500` | Lede, card body, subtle headings. |
|
|
362
|
+
| `--text-tertiary` | `--neutral-500` | `--neutral-400` | Captions, mono labels, metadata. |
|
|
363
|
+
| `--text-placeholder` | `--neutral-500` | `--neutral-400` | Form field hints and placeholders. |
|
|
364
|
+
| `--text-disabled` | `--neutral-600` | `--neutral-300` | Truly inactive elements. |
|
|
365
|
+
| `--text-inverse` | `--neutral-void` | `--neutral-50` | Text on inverted/dark surfaces. |
|
|
374
366
|
|
|
375
367
|
#### Border ladder
|
|
376
368
|
|
|
377
|
-
| Token
|
|
378
|
-
|
|
379
|
-
| `--border-subtle`
|
|
369
|
+
| Token | Dark value | Light value | Usage rule |
|
|
370
|
+
| ------------------ | ------------------------ | ------------------ | --------------------------------- |
|
|
371
|
+
| `--border-subtle` | `rgba(255,255,255,0.06)` | `rgba(0,0,0,0.06)` | Internal dividers, hr rules. |
|
|
380
372
|
| `--border-default` | `rgba(255,255,255,0.10)` | `rgba(0,0,0,0.10)` | Cards, inputs, container strokes. |
|
|
381
|
-
| `--border-strong`
|
|
382
|
-
| `--border-focus`
|
|
383
|
-
| `--border-brand`
|
|
373
|
+
| `--border-strong` | `rgba(255,255,255,0.18)` | `rgba(0,0,0,0.18)` | Hover emphasis, focus rings. |
|
|
374
|
+
| `--border-focus` | `--magenta-500` | `--magenta-500` | Form focus rings (brand). |
|
|
375
|
+
| `--border-brand` | `--magenta-500` | `--magenta-500` | Decorative brand border. |
|
|
384
376
|
|
|
385
377
|
**Ladder rule:** `subtle → default → strong → focus/brand`. Use `--border-subtle` for separators, `--border-default` for card outlines.
|
|
386
378
|
|
|
387
379
|
#### Brand tokens
|
|
388
380
|
|
|
389
|
-
| Token
|
|
390
|
-
|
|
391
|
-
| `--brand-primary`
|
|
392
|
-
| `--brand-primary-hover`
|
|
393
|
-
| `--brand-primary-active`
|
|
394
|
-
| `--brand-primary-muted`
|
|
395
|
-
| `--brand-primary-subtle`
|
|
396
|
-
| `--brand-primary-glow`
|
|
397
|
-
| `--
|
|
381
|
+
| Token | Dark value | Light value | Usage rule |
|
|
382
|
+
| ------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------ |
|
|
383
|
+
| `--brand-primary` | `--magenta-500` | `--magenta-500` | CTAs, focus rings, active nav, brand text. |
|
|
384
|
+
| `--brand-primary-hover` | `--magenta-400` | `--magenta-600` | Accent hover state. |
|
|
385
|
+
| `--brand-primary-active` | `--magenta-600` | `--magenta-700` | Accent pressed state. |
|
|
386
|
+
| `--brand-primary-muted` | `--magenta-800` | `--magenta-200` | Muted brand backgrounds. |
|
|
387
|
+
| `--brand-primary-subtle` | `--magenta-950` | `--magenta-100` | Subtle brand surfaces. |
|
|
388
|
+
| `--brand-primary-glow` | `color-mix(in srgb, var(--magenta-500) 25%, transparent)` | `color-mix(in srgb, var(--magenta-500) 15%, transparent)` | Glow shadow source. |
|
|
389
|
+
| `--brand-secondary` | `--cyan-500` (thematic per project) | `--cyan-600` (thematic per project) | Secondary CTAs, project accents. |
|
|
390
|
+
| `--brand-secondary-hover` | `--cyan-400` | `--cyan-500` | Secondary hover state. |
|
|
391
|
+
| `--text-on-brand` | `--neutral-void` | `--neutral-void` | Text on brand-colored fills. |
|
|
398
392
|
|
|
399
393
|
#### Status tokens
|
|
400
394
|
|
|
401
|
-
| Token
|
|
402
|
-
|
|
403
|
-
| `--status-success`
|
|
395
|
+
| Token | Dark value | Light value | Usage rule |
|
|
396
|
+
| --------------------- | --------------- | --------------- | ------------------------------ |
|
|
397
|
+
| `--status-success` | `--success-500` | `--success-500` | Positive outcome / online. |
|
|
404
398
|
| `--status-success-bg` | `--success-950` | `--success-100` | Background for success badges. |
|
|
405
399
|
| `--status-success-fg` | `--success-300` | `--success-700` | Foreground for success badges. |
|
|
406
|
-
| `--status-warning`
|
|
400
|
+
| `--status-warning` | `--warning-500` | `--warning-500` | Attention needed. |
|
|
407
401
|
| `--status-warning-bg` | `--warning-950` | `--warning-100` | Background for warning badges. |
|
|
408
402
|
| `--status-warning-fg` | `--warning-300` | `--warning-700` | Foreground for warning badges. |
|
|
409
|
-
| `--status-danger`
|
|
410
|
-
| `--status-danger-bg`
|
|
411
|
-
| `--status-danger-fg`
|
|
412
|
-
| `--status-info`
|
|
413
|
-
| `--status-info-bg`
|
|
414
|
-
| `--status-info-fg`
|
|
415
|
-
| `--status-neutral`
|
|
403
|
+
| `--status-danger` | `--danger-500` | `--danger-500` | Error / destructive. |
|
|
404
|
+
| `--status-danger-bg` | `--danger-950` | `--danger-100` | Background for danger badges. |
|
|
405
|
+
| `--status-danger-fg` | `--danger-300` | `--danger-700` | Foreground for danger badges. |
|
|
406
|
+
| `--status-info` | `--info-500` | `--info-500` | Informational. |
|
|
407
|
+
| `--status-info-bg` | `--info-950` | `--info-100` | Background for info badges. |
|
|
408
|
+
| `--status-info-fg` | `--info-300` | `--info-700` | Foreground for info badges. |
|
|
409
|
+
| `--status-neutral` | `--neutral-400` | `--neutral-400` | Default / inactive. |
|
|
416
410
|
| `--status-neutral-bg` | `--neutral-900` | `--neutral-200` | Background for neutral badges. |
|
|
417
411
|
| `--status-neutral-fg` | `--neutral-300` | `--neutral-700` | Foreground for neutral badges. |
|
|
418
412
|
|
|
@@ -420,43 +414,44 @@ Each has a full 11-step scale (50–950). Never use directly — always go throu
|
|
|
420
414
|
|
|
421
415
|
#### Project accent tokens
|
|
422
416
|
|
|
423
|
-
| Token
|
|
424
|
-
|
|
425
|
-
| `--accent-
|
|
426
|
-
| `--accent-
|
|
427
|
-
| `--accent-
|
|
428
|
-
| `--accent-grid` | `--acid-500` | `--acid-600` | Grid |
|
|
429
|
-
| `--accent-line` | `--ember-500` | `--ember-600` | Line |
|
|
417
|
+
| Token | Dark base | Light base | Project |
|
|
418
|
+
| ------------------ | --------------- | --------------- | ---------------- |
|
|
419
|
+
| `--accent-7kgroup` | `--magenta-500` | `--magenta-500` | 7KGroup (parent) |
|
|
420
|
+
| `--accent-7kminato` | `--cyan-500` | `--cyan-600` | 7KMinato |
|
|
421
|
+
| `--accent-inari` | `--inari-500` | `--inari-600` | Inari |
|
|
430
422
|
|
|
431
|
-
Light theme shifts project accents one step darker (500→600) to maintain contrast against the brighter background.
|
|
423
|
+
These tokens are the canonical hue for each project. They also feed `--brand-secondary` when a project scope is applied via `data-project` or `ProjectProvider`. Light theme shifts project accents one step darker (500→600) to maintain contrast against the brighter background.
|
|
432
424
|
|
|
433
425
|
---
|
|
426
|
+
|
|
434
427
|
### Layer 3 — Semantic Colors: Meaning, Not Decoration
|
|
435
428
|
|
|
436
429
|
Semantic colors exist **only** for status indication. Each maps to exactly one meaning.
|
|
437
430
|
|
|
438
|
-
| Match
|
|
439
|
-
|
|
440
|
-
| Positive outcome / online | `--status-success` + `--status-success-bg` | Badge: "Online" in green
|
|
441
|
-
| Attention needed
|
|
442
|
-
| Error / destructive
|
|
443
|
-
| Informational
|
|
444
|
-
| Default / inactive
|
|
431
|
+
| Match | Token | Example |
|
|
432
|
+
| ------------------------- | ------------------------------------------ | ------------------------- |
|
|
433
|
+
| Positive outcome / online | `--status-success` + `--status-success-bg` | Badge: "Online" in green |
|
|
434
|
+
| Attention needed | `--status-warning` + `--status-warning-bg` | Badge: "Pending" in amber |
|
|
435
|
+
| Error / destructive | `--status-danger` + `--status-danger-bg` | Badge: "Error" in red |
|
|
436
|
+
| Informational | `--status-info` + `--status-info-bg` | Badge: "Info" in blue |
|
|
437
|
+
| Default / inactive | `--status-neutral` + `--status-neutral-bg` | Badge: "Offline" in grey |
|
|
445
438
|
|
|
446
439
|
**Do not use semantic colors for:**
|
|
440
|
+
|
|
447
441
|
- Decorative borders on cards
|
|
448
442
|
- Accent accent headers
|
|
449
443
|
- Non-status icon fills
|
|
450
444
|
- Background washes for sections
|
|
451
445
|
|
|
452
446
|
---
|
|
447
|
+
|
|
453
448
|
### Usage rules
|
|
454
449
|
|
|
455
450
|
1. **Neutral ladder** — Step one surface layer per depth level: `void → base → elevated → raised → overlay → pressed`. Never skip a level for visual emphasis.
|
|
456
451
|
2. **Accent on action, not surface** — Brand appears on primary CTAs, focus rings, active borders, brand typography. Never as a full surface background fill.
|
|
457
452
|
3. **Semantic = meaning only** — Status hues exist for machine-state communication (badge bg, toast icon, validation message, online/offline dot). If it doesn't communicate a machine state, use the raw ramps instead.
|
|
458
453
|
4. **Status bg uses `--*-bg`** — Status badges and pills use the `--status-*-bg` token, never the solid `--*-500` as a fill.
|
|
459
|
-
5. **Project scoping** —
|
|
454
|
+
5. **Project scoping** — 7KGroup uses magenta, 7KMinato cyan, Inari burnt orange. Within a project scope (`data-project` or `ProjectProvider`), the project accent takes over the **entire brand chain** — `--brand-primary` and `--brand-secondary` (primary/glow buttons, focus rings, brand borders) — making the project hue more prevalent than the 7KGroup baseline. Magenta only persists in constant identity marks (`--accent-7kgroup`, logo/icon strokes). Semantic status colors and the neutral ramp stay unchanged.
|
|
460
455
|
6. **No raw ramp references in components** — Always reference role tokens (`--bg-elevated`, `--text-primary`, `--border-default`), never raw ramp tokens (`--neutral-950`, `--neutral-50`, etc.). This is how theme switching works.
|
|
461
456
|
7. **Dark is default, light is opt-in** — `:root` holds dark token mappings. `@media (prefers-color-scheme: light)` overrides only the role tokens. Primitive ramps are shared and unchanged.
|
|
462
457
|
|
|
@@ -466,23 +461,24 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
466
461
|
|
|
467
462
|
### Three-font system
|
|
468
463
|
|
|
469
|
-
| Family
|
|
470
|
-
|
|
471
|
-
| **Geist** (sans)
|
|
472
|
-
| **Geist Mono**
|
|
473
|
-
| **Geist Pixel** (5 variants) | Ornamental display, pixel-constrained surfaces, hero wordmarks | 400–800 (one per variant) | Local `fonts/` TTFs
|
|
464
|
+
| Family | Role | Weight range | Source |
|
|
465
|
+
| ---------------------------- | -------------------------------------------------------------- | ------------------------- | ------------------------- |
|
|
466
|
+
| **Geist** (sans) | Display, headings, body, UI text | 100–900 | CDN (`geist` npm package) |
|
|
467
|
+
| **Geist Mono** | Labels, code, tabular data, metadata | 400, 500 | CDN (`geist` npm package) |
|
|
468
|
+
| **Geist Pixel** (5 variants) | Ornamental display, pixel-constrained surfaces, hero wordmarks | 400–800 (one per variant) | Local `fonts/` TTFs |
|
|
474
469
|
|
|
475
470
|
### Geist Pixel variant → project accent pairing
|
|
476
471
|
|
|
477
|
-
| Variant
|
|
478
|
-
|
|
479
|
-
| **Square**
|
|
480
|
-
| **Circle**
|
|
481
|
-
| **Grid**
|
|
482
|
-
| **Line**
|
|
483
|
-
| **Triangle** | 800 (ExtraBold) |
|
|
472
|
+
| Variant | Weight | Pairs with | Best for |
|
|
473
|
+
| ------------ | --------------- | ------------------------ | ------------------------------------ |
|
|
474
|
+
| **Square** | 400 (Regular) | Magenta (7KGroup) | Body-sized pixel text, data displays |
|
|
475
|
+
| **Circle** | 500 (Medium) | Cyan (7KMinato) | Buttons, badges, navigation |
|
|
476
|
+
| **Grid** | 600 (SemiBold) | Neutral | Section titles, stat values |
|
|
477
|
+
| **Line** | 700 (Bold) | Neutral | Display headlines, hero text |
|
|
478
|
+
| **Triangle** | 800 (ExtraBold) | Inari (Inari project) | Hero wordmarks, giant headlines |
|
|
484
479
|
|
|
485
480
|
### Font stacks
|
|
481
|
+
|
|
486
482
|
```
|
|
487
483
|
--font-sans: 'Geist', system-ui, -apple-system, sans-serif;
|
|
488
484
|
--font-mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
|
|
@@ -491,21 +487,22 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
491
487
|
|
|
492
488
|
### Type scale — engineering blueprint
|
|
493
489
|
|
|
494
|
-
| Token
|
|
495
|
-
|
|
496
|
-
| `--text-display`
|
|
497
|
-
| `--text-h1`
|
|
498
|
-
| `--text-h2`
|
|
499
|
-
| `--text-h3`
|
|
500
|
-
| `--text-h4`
|
|
501
|
-
| `--text-body-lg`
|
|
502
|
-
| `--text-body`
|
|
503
|
-
| `--text-body-sm`
|
|
504
|
-
| `--text-caption`
|
|
505
|
-
| `--text-mono-label` | 0.6875rem (11px)
|
|
506
|
-
| `--text-mono-body`
|
|
490
|
+
| Token | Size | Family / Weight | Usage |
|
|
491
|
+
| ------------------- | ------------------------- | ------------------------------- | ----------------------------------------------------- |
|
|
492
|
+
| `--text-display` | `clamp(48px, 8vw, 160px)` | Geist 900 -0.04em | Hero numerals, giant headlines |
|
|
493
|
+
| `--text-h1` | 4rem (64px) | Geist 700 -0.04em | Page titles |
|
|
494
|
+
| `--text-h2` | 3rem (48px) | Geist 700 -0.03em | Section titles |
|
|
495
|
+
| `--text-h3` | 2rem (32px) | Geist 600 -0.02em | Sub-section headers |
|
|
496
|
+
| `--text-h4` | 1.5rem (24px) | Geist 600 -0.02em | Card titles |
|
|
497
|
+
| `--text-body-lg` | 1.125rem (18px) | Geist 400 -0.01em | Larger body / lede |
|
|
498
|
+
| `--text-body` | 1rem (16px) | Geist 400 -0.01em | Body paragraphs |
|
|
499
|
+
| `--text-body-sm` | 0.875rem (14px) | Geist 400 -0.01em | Secondary text |
|
|
500
|
+
| `--text-caption` | 0.75rem (12px) | Geist 500 | Metadata, timestamps |
|
|
501
|
+
| `--text-mono-label` | 0.6875rem (11px) | Geist Mono 500 0.12em uppercase | Labels, badges, form labels — the "connective tissue" |
|
|
502
|
+
| `--text-mono-body` | 0.8125rem (13px) | Geist Mono 400 | Code blocks, tabular data |
|
|
507
503
|
|
|
508
504
|
### Legacy alignment tokens (deprecated but kept for compatibility)
|
|
505
|
+
|
|
509
506
|
```
|
|
510
507
|
--text-7xl 7.5rem (120px) --text-6xl 5.5rem (88px)
|
|
511
508
|
--text-5xl 4rem (64px) --text-4xl 3rem (48px)
|
|
@@ -516,6 +513,7 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
516
513
|
```
|
|
517
514
|
|
|
518
515
|
### Weight scale
|
|
516
|
+
|
|
519
517
|
```
|
|
520
518
|
--weight-thin: 100 --weight-extralight: 200 --weight-light: 300
|
|
521
519
|
--weight-regular: 400 --weight-medium: 500 --weight-semibold: 600
|
|
@@ -523,6 +521,7 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
523
521
|
```
|
|
524
522
|
|
|
525
523
|
### Line heights
|
|
524
|
+
|
|
526
525
|
```
|
|
527
526
|
--leading-none: 1 --leading-tight: 1.15
|
|
528
527
|
--leading-snug: 1.3 --leading-normal: 1.5
|
|
@@ -530,6 +529,7 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
530
529
|
```
|
|
531
530
|
|
|
532
531
|
### Letter spacing
|
|
532
|
+
|
|
533
533
|
```
|
|
534
534
|
--tracking-tightest: -0.04em --tracking-tighter: -0.02em
|
|
535
535
|
--tracking-tight: -0.01em --tracking-normal: 0
|
|
@@ -538,9 +538,11 @@ Semantic colors exist **only** for status indication. Each maps to exactly one m
|
|
|
538
538
|
```
|
|
539
539
|
|
|
540
540
|
### Mono-label language — "connective tissue"
|
|
541
|
+
|
|
541
542
|
Every label, badge, form label, tab, breadcrumb, and status indicator uses `--text-mono-label` (Geist Mono, 11px, 500 weight, 0.12em uppercase). This creates the engineering-blueprint aesthetic: the reader always knows which layer they are looking at because the meta-information reads like a schematic.
|
|
542
543
|
|
|
543
544
|
### Numerics
|
|
545
|
+
|
|
544
546
|
- All data / metrics use `font-family: var(--font-mono)` with `font-variant-numeric: tabular-nums`
|
|
545
547
|
- Display: -0.04em, h1: -0.04em, h2: -0.03em, h3: -0.02em, h4: -0.02em
|
|
546
548
|
|
|
@@ -597,6 +599,7 @@ Sharp (0px) and subtle (2–4px) are preferred for 1-bit elements. 8–12px for
|
|
|
597
599
|
**Source context reference:** The brief's "tech company with different projects" suggests a dashboard/app-shell layout pattern. The 12-column grid supports both marketing pages and data-dense project dashboards.
|
|
598
600
|
|
|
599
601
|
### Container widths
|
|
602
|
+
|
|
600
603
|
```
|
|
601
604
|
--container-sm: 640px
|
|
602
605
|
--container-md: 960px
|
|
@@ -606,6 +609,7 @@ Sharp (0px) and subtle (2–4px) are preferred for 1-bit elements. 8–12px for
|
|
|
606
609
|
```
|
|
607
610
|
|
|
608
611
|
### Z-index scale
|
|
612
|
+
|
|
609
613
|
```
|
|
610
614
|
--z-base: 0
|
|
611
615
|
--z-raised: 10
|
|
@@ -617,23 +621,27 @@ Sharp (0px) and subtle (2–4px) are preferred for 1-bit elements. 8–12px for
|
|
|
617
621
|
```
|
|
618
622
|
|
|
619
623
|
### Grid
|
|
624
|
+
|
|
620
625
|
- 12-column responsive grid, `--grid-gutter` (24px) gutter
|
|
621
626
|
- Breakpoints: 480px (mobile), 768px (tablet), 1024px (desktop), 1440px (wide)
|
|
622
627
|
- Max content width: 1280px, centered
|
|
623
628
|
|
|
624
629
|
### Navigation
|
|
630
|
+
|
|
625
631
|
- Sticky top nav (frosted glass) on dark bg
|
|
626
632
|
- Bottom tab bar on mobile, side nav for app shells
|
|
627
633
|
- Active nav item: accent dot indicator
|
|
628
634
|
|
|
629
635
|
### 1-bit section rhythm
|
|
636
|
+
|
|
630
637
|
- Scanline overlay on hero / full-bleed sections
|
|
631
638
|
- Halftone dot separators between content blocks
|
|
632
|
-
- Full-bleed sections use `.separator-
|
|
639
|
+
- Full-bleed sections use `.separator-solid` (2px white line at 25% opacity) as rhythm breaks
|
|
633
640
|
- Texture shift between sections: scanline → solid → halftone → solid → scanline. Never two textured sections adjacent.
|
|
634
|
-
- Manga panel composition: content is the "panel" (solid black border), background is the "page" (noise or scanline). Each panel gets a `.vignette-
|
|
641
|
+
- Manga panel composition: content is the "panel" (solid black border), background is the "page" (noise or scanline). Each panel gets a `.vignette-ink` edge fade.
|
|
635
642
|
|
|
636
643
|
### Product shell layout
|
|
644
|
+
|
|
637
645
|
```
|
|
638
646
|
┌──────────────────────────────────────────┐
|
|
639
647
|
│ Sidebar (240px) │ Main content area │
|
|
@@ -658,156 +666,161 @@ Sharp (0px) and subtle (2–4px) are preferred for 1-bit elements. 8–12px for
|
|
|
658
666
|
|
|
659
667
|
**Modern neon** — the only button system. All buttons use `mono-label` typography (Geist Mono, 11px, 500 weight, 0.12em uppercase) and 4px border-radius. Accent fills use the brand-primary ramp (500→hover:400→active:600). Button groups, split buttons, and loading state are built on the same base.
|
|
660
668
|
|
|
661
|
-
| Class
|
|
662
|
-
|
|
663
|
-
| `.btn
|
|
664
|
-
| `.btn-
|
|
665
|
-
| `.btn-
|
|
666
|
-
| `.btn-
|
|
667
|
-
| `.btn-
|
|
668
|
-
| `.btn-
|
|
669
|
-
| `.btn-
|
|
670
|
-
| `.btn-
|
|
671
|
-
| `.btn-
|
|
672
|
-
| `.btn-
|
|
673
|
-
| `.btn-
|
|
674
|
-
| `.btn-
|
|
675
|
-
| `.btn-
|
|
676
|
-
| `.btn
|
|
669
|
+
| Class | Description |
|
|
670
|
+
| --------------------------- | ------------------------------------------------------------------------------------------ |
|
|
671
|
+
| `.btn` | Base: mono-label typography, 12px/20px padding, `rounded.sm` (4px) |
|
|
672
|
+
| `.btn-primary` | Magenta outline, `--brand-primary-subtle` fill tint on hover, white text when active |
|
|
673
|
+
| `.btn-secondary` | `--bg-raised` fill, `--bg-overlay` on hover |
|
|
674
|
+
| `.btn-ghost` | Transparent, `--text-secondary` text, subtle bg on hover |
|
|
675
|
+
| `.btn-glow` | Magenta outline + persistent neon glow, intensifies on hover |
|
|
676
|
+
| `.btn-accent` | Dynamic `--brand-secondary` outline + fill tint on hover (per-project accent) |
|
|
677
|
+
| `.btn-glow-accent` | `--brand-secondary` fill + glow (the filled "neon" button; magenta for the parent brand) |
|
|
678
|
+
| `.btn-glow-secondary`| Cyan/`--brand-secondary` outline + glow variant of `.btn-glow` |
|
|
679
|
+
| `.btn-danger` | Transparent + danger border, danger fill on hover |
|
|
680
|
+
| `.btn-sm/lg` | Size variants (8px/16px small, 16px/28px large) |
|
|
681
|
+
| `.btn-icon` | 40×40 square icon button |
|
|
682
|
+
| `.btn-lg-icon` | 52×52 large icon button |
|
|
683
|
+
| `.btn-loading` | Loading state — `spin-steps` replaces icon |
|
|
684
|
+
| `.btn:disabled` | 40% opacity, no pointer events, glow removed — applies to every variant |
|
|
685
|
+
| `.btn-group` | Inline flex container for grouped buttons (adjacent borders merge) |
|
|
686
|
+
| `.btn-split` | Split button trigger — last child gets narrower padding + left border |
|
|
677
687
|
|
|
678
688
|
All variants use standard CSS transitions for interaction states:
|
|
679
|
-
|
|
689
|
+
|
|
690
|
+
- **`:hover`** → border/fill shifts to the `-hover` step of the variant's ramp, optional glow shadow intensifies
|
|
680
691
|
- **`:focus-visible`** → outline ring
|
|
681
|
-
- **`:active`** → fill shifts to `--
|
|
682
|
-
-
|
|
692
|
+
- **`:active`** → fill shifts to the `-muted` step with `--color-paper` text (keeps contrast ≥ 7:1)
|
|
693
|
+
- **`:disabled`** → 40% opacity, `not-allowed` cursor, no glow
|
|
694
|
+
- **`Loading`** → `spin-steps` (0.6s steps(4) infinite — square frame rotation)
|
|
683
695
|
|
|
684
696
|
### 6b. Form controls
|
|
685
697
|
|
|
686
|
-
| Class
|
|
687
|
-
|
|
688
|
-
| `.input`
|
|
689
|
-
| `.textarea`
|
|
690
|
-
| `.select-native` | Custom dropdown, SVG chevron
|
|
691
|
-
| `.checkbox`
|
|
692
|
-
| `.radio`
|
|
693
|
-
| `.toggle`
|
|
694
|
-
| `.range`
|
|
695
|
-
| `.form-group`
|
|
696
|
-
| `.form-label`
|
|
697
|
-
| `.field-error`
|
|
698
|
-
| `.input-group`
|
|
699
|
-
| `.input-addon`
|
|
700
|
-
| `.color-swatch`
|
|
698
|
+
| Class | Description |
|
|
699
|
+
| ---------------- | -------------------------------------------------------------------- |
|
|
700
|
+
| `.input` | Text input: black bg, 2px white border, accent glow on focus |
|
|
701
|
+
| `.textarea` | Multi-line input, same tokens |
|
|
702
|
+
| `.select-native` | Custom dropdown, SVG chevron |
|
|
703
|
+
| `.checkbox` | 16px square, checked fills white (`.checkbox-accent`: fills `--brand-secondary`) |
|
|
704
|
+
| `.radio` | 16px square, selected fills white (`.radio-accent`: fills `--brand-secondary`) |
|
|
705
|
+
| `.toggle` | 36x18 switch, on state fills white (`.toggle-accent`: fills `--brand-secondary`) |
|
|
706
|
+
| `.range` | 6px track, 16px square thumb |
|
|
707
|
+
| `.form-group` | Flex column with gap |
|
|
708
|
+
| `.form-label` | Mono uppercase label, 11px |
|
|
709
|
+
| `.field-error` | Red mono error text |
|
|
710
|
+
| `.input-group` | Inline input + addon |
|
|
711
|
+
| `.input-addon` | Prefix/suffix decoration |
|
|
712
|
+
| `.color-swatch` | 32px square, accent shadow on selected |
|
|
701
713
|
|
|
702
714
|
### 6c. Navigation
|
|
703
715
|
|
|
704
|
-
| Class
|
|
705
|
-
|
|
706
|
-
| `.nav`
|
|
707
|
-
| `.nav-item`
|
|
708
|
-
| `.nav-item-accent` | Magenta border on active
|
|
709
|
-
| `.tabs`
|
|
710
|
-
| `.tab`
|
|
711
|
-
| `.tab-accent`
|
|
712
|
-
| `.pagination`
|
|
713
|
-
| `.page-btn`
|
|
714
|
-
| `.breadcrumb`
|
|
715
|
-
| `.stepper`
|
|
716
|
+
| Class | Description |
|
|
717
|
+
| ------------------ | ----------------------------------------------- |
|
|
718
|
+
| `.nav` | Vertical nav container |
|
|
719
|
+
| `.nav-item` | Nav link with optional bullet, invert on active |
|
|
720
|
+
| `.nav-item-accent` | Magenta border on active |
|
|
721
|
+
| `.tabs` | Horizontal tab bar, 2px bottom border |
|
|
722
|
+
| `.tab` | Mono uppercase tab, white underline on active |
|
|
723
|
+
| `.tab-accent` | Magenta underline on active |
|
|
724
|
+
| `.pagination` | Inline page button group |
|
|
725
|
+
| `.page-btn` | 32px square, invert on active |
|
|
726
|
+
| `.breadcrumb` | Mono slash-separated trail |
|
|
727
|
+
| `.stepper` | Numbered step indicator with connecting line |
|
|
716
728
|
|
|
717
729
|
### 6d. Data display
|
|
718
730
|
|
|
719
|
-
| Class
|
|
720
|
-
|
|
721
|
-
| `.table`
|
|
722
|
-
| `.badge`
|
|
723
|
-
| `.badge-inverted`
|
|
724
|
-
| `.badge-accent` / `.badge-success` / `.badge-warning` / `.badge-danger` | Colored border variants
|
|
725
|
-
| `.tag`
|
|
726
|
-
| `.chip`
|
|
727
|
-
| `.chip-accent`
|
|
728
|
-
| `.avatar`
|
|
729
|
-
| `.avatar-sm` / `.avatar-lg` / `.avatar-group`
|
|
730
|
-
| `.stat`
|
|
731
|
-
| `.stat-accent`
|
|
732
|
-
| `.kbd`
|
|
733
|
-
| `.code-block`
|
|
734
|
-
| `.code-inline`
|
|
735
|
-
| `.link`
|
|
736
|
-
| `.link-accent`
|
|
737
|
-
| `.list`
|
|
738
|
-
| `.list-item`
|
|
739
|
-
| `.tree`
|
|
740
|
-
| `.tree-item`
|
|
731
|
+
| Class | Description |
|
|
732
|
+
| ----------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
733
|
+
| `.table` | Collapsed table, 2px header border, mono uppercase headers |
|
|
734
|
+
| `.badge` | Inline uppercase label, 11px, 1px border |
|
|
735
|
+
| `.badge-inverted` | White bg, black text |
|
|
736
|
+
| `.badge-accent` / `.badge-success` / `.badge-warning` / `.badge-danger` | Colored border variants |
|
|
737
|
+
| `.tag` | 11px uppercase inline, 3 variants (default, outlined, inverted) |
|
|
738
|
+
| `.chip` | Removable inline tag with close button |
|
|
739
|
+
| `.chip-accent` | Magenta border variant |
|
|
740
|
+
| `.avatar` | 32x32 square, 2px border, mono initial |
|
|
741
|
+
| `.avatar-sm` / `.avatar-lg` / `.avatar-group` | Size + overlap group |
|
|
742
|
+
| `.stat` | Value + label vertical pair |
|
|
743
|
+
| `.stat-accent` | Magenta value color |
|
|
744
|
+
| `.kbd` | Keyboard key with 3px bottom border weight |
|
|
745
|
+
| `.code-block` | Pre block, 2px border, 13px mono |
|
|
746
|
+
| `.code-inline` | Inline code snippet |
|
|
747
|
+
| `.link` | Underlined white text, thicker hover |
|
|
748
|
+
| `.link-accent` | Magenta colored link |
|
|
749
|
+
| `.list` | Bordered list group with 2px border |
|
|
750
|
+
| `.list-item` | 13px item with hover/active states |
|
|
751
|
+
| `.tree` | Nested tree with lines |
|
|
752
|
+
| `.tree-item` | Indented with left border, accent on active |
|
|
741
753
|
|
|
742
754
|
### 6e. Overlays
|
|
743
755
|
|
|
744
|
-
| Class
|
|
745
|
-
|
|
746
|
-
| `.modal`
|
|
747
|
-
| `.drawer`
|
|
748
|
-
| `.toast`
|
|
749
|
-
| `.toast-success` / `.toast-error` / `.toast-warning` | Colored icon variants
|
|
750
|
-
| `.tooltip`
|
|
751
|
-
| `.alert`
|
|
752
|
-
| `.alert-success` / `.alert-error` / `.alert-warning` | Colored border variants
|
|
756
|
+
| Class | Description |
|
|
757
|
+
| ---------------------------------------------------- | ------------------------------------------------------------ |
|
|
758
|
+
| `.modal` | Black bg, 2px border, 8px hard offset shadow |
|
|
759
|
+
| `.drawer` | Side panel, 300-480px width |
|
|
760
|
+
| `.toast` | Notification with 4px hard offset shadow, slide-up animation |
|
|
761
|
+
| `.toast-success` / `.toast-error` / `.toast-warning` | Colored icon variants |
|
|
762
|
+
| `.tooltip` | Positioned label on hover |
|
|
763
|
+
| `.alert` | Inline message with icon |
|
|
764
|
+
| `.alert-success` / `.alert-error` / `.alert-warning` | Colored border variants |
|
|
753
765
|
|
|
754
766
|
### 6f. Feedback
|
|
755
767
|
|
|
756
|
-
| Class
|
|
757
|
-
|
|
758
|
-
| `.progress`
|
|
759
|
-
| `.progress-accent`
|
|
760
|
-
| `.progress-indeterminate`
|
|
761
|
-
| `.progress-striped`
|
|
762
|
-
| `.spinner`
|
|
763
|
-
| `.spinner-accent` / `.spinner-cyan` | Colored border variants
|
|
764
|
-
| `.skeleton`
|
|
765
|
-
| `.empty`
|
|
766
|
-
| `.loading-screen`
|
|
767
|
-
| `.banner`
|
|
768
|
+
| Class | Description |
|
|
769
|
+
| ----------------------------------- | ------------------------------------------- |
|
|
770
|
+
| `.progress` | 12px bar, 2px border |
|
|
771
|
+
| `.progress-accent` | `--brand-secondary` (project accent) fill |
|
|
772
|
+
| `.progress-indeterminate` | Scanning bar animation |
|
|
773
|
+
| `.progress-striped` | Striped fill overlay |
|
|
774
|
+
| `.spinner` | 20px square rotating frame, 90° steps |
|
|
775
|
+
| `.spinner-accent` / `.spinner-cyan` | Colored border variants |
|
|
776
|
+
| `.skeleton` | Loading placeholder, opacity pulse |
|
|
777
|
+
| `.empty` | Dashed border placeholder, centered content |
|
|
778
|
+
| `.loading-screen` | Full block loading with blinking label |
|
|
779
|
+
| `.banner` | Full-width colored message bar |
|
|
768
780
|
|
|
769
781
|
### 6g. Media & Layout
|
|
770
782
|
|
|
771
|
-
| Class
|
|
772
|
-
|
|
773
|
-
| `.image-frame`
|
|
774
|
-
| `.video-frame`
|
|
775
|
-
| `.icon-box`
|
|
776
|
-
| `.icon-box-sm` / `.icon-box-lg` / `.icon-box-accent` / `.icon-box-cyan` | Variants
|
|
777
|
-
| `.container`
|
|
778
|
-
| `.grid` / `.grid-2` / `.grid-3` / `.grid-4`
|
|
779
|
-
| `.hr` / `.hr-thick`
|
|
783
|
+
| Class | Description |
|
|
784
|
+
| ----------------------------------------------------------------------- | -------------------------------------- |
|
|
785
|
+
| `.image-frame` | 2px border placeholder |
|
|
786
|
+
| `.video-frame` | 16:9 frame with play button + timeline |
|
|
787
|
+
| `.icon-box` | 40x40 square icon container |
|
|
788
|
+
| `.icon-box-sm` / `.icon-box-lg` / `.icon-box-accent` / `.icon-box-cyan` | Variants |
|
|
789
|
+
| `.container` | 1280px centered max-width |
|
|
790
|
+
| `.grid` / `.grid-2` / `.grid-3` / `.grid-4` | Grid with 24px gap |
|
|
791
|
+
| `.hr` / `.hr-thick` | Horizontal rules |
|
|
780
792
|
|
|
781
793
|
### 6h. Misc
|
|
782
794
|
|
|
783
|
-
| Class
|
|
784
|
-
|
|
785
|
-
| `.menu`
|
|
786
|
-
| `.menu-item`
|
|
787
|
-
| `.toolbar`
|
|
788
|
-
| `.status-dot` | 8px square dot (live/away/busy/offline)
|
|
789
|
-
| `.timeline`
|
|
790
|
-
| `.countdown`
|
|
791
|
-
| `.rating`
|
|
792
|
-
| `.combobox`
|
|
793
|
-
| `.date-input` | Date field with segmented parts
|
|
795
|
+
| Class | Description |
|
|
796
|
+
| ------------- | -------------------------------------------- |
|
|
797
|
+
| `.menu` | Dropdown menu list |
|
|
798
|
+
| `.menu-item` | Menu entry with divider support |
|
|
799
|
+
| `.toolbar` | Icon button row with separators |
|
|
800
|
+
| `.status-dot` | 8px square dot (live/away/busy/offline) |
|
|
801
|
+
| `.timeline` | Vertical timeline with dots + lines |
|
|
802
|
+
| `.countdown` | Tabular numeric countdown with labels |
|
|
803
|
+
| `.rating` | 5-star rating, 20px squares, accent on hover |
|
|
804
|
+
| `.combobox` | Searchable select with dropdown menu |
|
|
805
|
+
| `.date-input` | Date field with segmented parts |
|
|
794
806
|
|
|
795
807
|
### 6i. Accent layer modifiers
|
|
796
808
|
|
|
797
809
|
These classes add thin color to any 1-bit component without breaking the black/white base. Apply alongside the component class.
|
|
798
810
|
|
|
799
|
-
| Class
|
|
800
|
-
|
|
801
|
-
| `.accent-border-top` / `.accent-border-left` / `.accent-border-bottom`
|
|
802
|
-
| `.
|
|
803
|
-
| `.accent-underline` / `.
|
|
804
|
-
| `.accent-dot` / `.
|
|
805
|
-
| `.accent-bar` / `.
|
|
806
|
-
| `.glow-mod` / `.glow-mod-
|
|
807
|
-
| `.border-mod-accent` / `.border-mod-
|
|
808
|
-
| `.accent-corner` / `.
|
|
811
|
+
| Class | Effect |
|
|
812
|
+
| -------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
813
|
+
| `.accent-border-top` / `.accent-border-left` / `.accent-border-bottom` | 3px `--brand-primary` (magenta) border on one edge |
|
|
814
|
+
| `.accent-secondary-border-top` / `-left` / `-bottom` | 3px `--brand-secondary` (per-project) border |
|
|
815
|
+
| `.accent-underline` / `.accent-secondary-underline` | Colored underline on text |
|
|
816
|
+
| `.accent-dot` / `.accent-secondary-dot` | Small colored dot after element |
|
|
817
|
+
| `.accent-bar` / `.accent-secondary-bar` | Thin colored bar across top |
|
|
818
|
+
| `.glow-mod` / `.glow-mod-secondary` | Colored glow shadow |
|
|
819
|
+
| `.border-mod-accent` / `.border-mod-secondary` | Border color override |
|
|
820
|
+
| `.accent-corner` / `.accent-secondary-corner` | Small colored corner badge |
|
|
809
821
|
|
|
810
822
|
### 1-bit composition rules
|
|
823
|
+
|
|
811
824
|
- **No radii.** Every 1-bit component uses `border-radius: 0`. Sharp corners are part of the identity.
|
|
812
825
|
- **No blur shadows.** Only hard offset shadows (`box-shadow: 8px 8px 0 #FFFFFF`) on modal and toast.
|
|
813
826
|
- **2px borders.** All bordered 1-bit components use 2px `solid` white borders unless specified.
|
|
@@ -822,6 +835,7 @@ These classes add thin color to any 1-bit component without breaking the black/w
|
|
|
822
835
|
**Source context reference:** The brief's "abstract 1-bit animations" directly motivates the scanline-scroll, glitch, and halftone keyframe primitives. Reduced-motion support is a standard accessibility requirement.
|
|
823
836
|
|
|
824
837
|
### Durations & easing
|
|
838
|
+
|
|
825
839
|
```
|
|
826
840
|
--ease-out: cubic-bezier(0.16, 1, 0.3, 1)
|
|
827
841
|
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1)
|
|
@@ -835,43 +849,43 @@ These classes add thin color to any 1-bit component without breaking the black/w
|
|
|
835
849
|
|
|
836
850
|
### Full 1-bit Animation Library
|
|
837
851
|
|
|
838
|
-
| Animation
|
|
839
|
-
|
|
840
|
-
| Scanline scroll | `.scanline` (::after)
|
|
841
|
-
| Scanline fast
|
|
842
|
-
| Basic glitch
|
|
843
|
-
| Complex glitch
|
|
844
|
-
| Glitch accent
|
|
845
|
-
| CRT flicker
|
|
846
|
-
| Binary blink
|
|
847
|
-
| Typewriter
|
|
848
|
-
| Neon pulse
|
|
849
|
-
| Noise shift
|
|
850
|
-
| Scan reveal
|
|
851
|
-
| Pixel fade-in
|
|
852
|
-
| Invert flash
|
|
853
|
-
| Pixel dots
|
|
854
|
-
| Progress scan
|
|
855
|
-
| Skeleton pulse
|
|
856
|
-
| Slide-up reveal | `.slide-up-reveal`
|
|
857
|
-
| Shimmer sweep
|
|
858
|
-
| Frame step
|
|
859
|
-
| One-bit spin
|
|
860
|
-
| Matrix rain
|
|
861
|
-
| Accent flicker
|
|
852
|
+
| Animation | Class | Duration | Type | Description |
|
|
853
|
+
| --------------- | ---------------------------------- | ---------------------------- | ------- | ------------------------------------------------------------------------- |
|
|
854
|
+
| Scanline scroll | `.scanline` (::after) | 8s linear infinite | Ambient | Horizontal lines scroll down — signature 7K texture |
|
|
855
|
+
| Scanline fast | `.scanline-fast` (::after) | 3s linear infinite | Ambient | Faster variant for high-energy sections |
|
|
856
|
+
| Basic glitch | `.glitch` | 0.3s, 3 iterations | Trigger | Translate jitter on 5 random frames |
|
|
857
|
+
| Complex glitch | `.glitch-complex` | 0.8s, 2 iterations | Trigger | Multi-axis + skew + clip-path splits |
|
|
858
|
+
| Glitch accent | `.glitch-accent` | 0.4s, 2 iterations | Trigger | Glitch with magenta glow trail |
|
|
859
|
+
| CRT flicker | `.flicker` / `.flicker-fast` | 4s / 1.5s infinite | Ambient | Opacity stutter at irregular intervals |
|
|
860
|
+
| Binary blink | `.blink` / `.blink-fast` | 1s / 0.4s step-end | Ambient | Sharp on/off toggle |
|
|
861
|
+
| Typewriter | `.typewriter` | 1.5s (30 steps) | Trigger | Text reveal from left |
|
|
862
|
+
| Neon pulse | `.neon-pulse` / `.neon-pulse-cyan` | 2s ease-in-out | Ambient | Accent glow oscillation |
|
|
863
|
+
| Noise shift | `.noise-animated` | 0.5s, steps(5) | Ambient | SVG noise translates in discrete positions |
|
|
864
|
+
| Scan reveal | `.scan-reveal` | 2s, 1 iteration | Trigger | White bar sweeps down |
|
|
865
|
+
| Pixel fade-in | `.pixel-fade-in` | 0.6s, steps(8) | Trigger | Left-to-right reveal in pixel steps |
|
|
866
|
+
| Invert flash | `.invert-flash` | 0.15s, 2 iterations | Trigger | Full filter inversion burst |
|
|
867
|
+
| Pixel dots | `.pixel-dots` / `.pixel-dots-fast` | 0.3s, steps(4), 2 iterations | Trigger | Small black squares scatter at random positions — 1-bit corruption effect |
|
|
868
|
+
| Progress scan | `.progress-indeterminate` | 1.5s | Loading | Bar sweeps left-to-right |
|
|
869
|
+
| Skeleton pulse | `.skeleton` | 1.2s ease-in-out | Loading | Opacity pulse |
|
|
870
|
+
| Slide-up reveal | `.slide-up-reveal` | 0.5s ease-out | Trigger | Content rises with clip-path |
|
|
871
|
+
| Shimmer sweep | `.shimmer` | 2s linear infinite | Loading | Horizontal gradient sweep |
|
|
872
|
+
| Frame step | `.frame-step` (::after) | 0.8s steps(1) | Ambient | Binary character cycle (▌▐█▀) |
|
|
873
|
+
| One-bit spin | `.spinner` | 0.6s linear | Loading | Square frame in 90° increments |
|
|
874
|
+
| Matrix rain | `.matrix-rain-char` | 2s linear infinite | Ambient | Falling character column |
|
|
875
|
+
| Accent flicker | `.accent-flicker` | 1.8s step-end infinite | Ambient | Blinking accent color text |
|
|
862
876
|
|
|
863
877
|
### Isometric Animation Library
|
|
864
878
|
|
|
865
|
-
| Animation
|
|
866
|
-
|
|
867
|
-
| Isometric float
|
|
868
|
-
| Float + spin
|
|
869
|
-
| Grid scroll
|
|
870
|
-
| Terrain shift
|
|
871
|
-
| Rotate cube
|
|
872
|
-
| Assemble blocks
|
|
873
|
-
| Perspective dolly | `.iso-perspective-dolly` | 1s ease-out forwards
|
|
874
|
-
| Step build
|
|
879
|
+
| Animation | Class | Duration | Type | Description |
|
|
880
|
+
| ----------------- | ------------------------ | ----------------------- | ------- | --------------------------------------------------------------------------------------- |
|
|
881
|
+
| Isometric float | `.iso-float` | 3s ease-in-out infinite | Ambient | Block bobs up/down with subtle scale depth shift |
|
|
882
|
+
| Float + spin | `.iso-float-spin` | 4s ease-in-out infinite | Ambient | Float + slow Y-axis rotation (90° steps) |
|
|
883
|
+
| Grid scroll | `.iso-grid-scroll` | 4s linear infinite | Ambient | Isometric diamond grid scrolls diagonally |
|
|
884
|
+
| Terrain shift | `.iso-terrain-shift` | 6s linear infinite | Ambient | 3 parallax layers move at different speeds |
|
|
885
|
+
| Rotate cube | `.iso-rotate-cube` | 6s linear infinite | Ambient | Full 3D cube rotation in isometric space |
|
|
886
|
+
| Assemble blocks | `.iso-assemble` | 0.8s ease-out forwards | Trigger | Blocks rise from below into position (5 delay variants: `.iso-assemble-2` through `-5`) |
|
|
887
|
+
| Perspective dolly | `.iso-perspective-dolly` | 1s ease-out forwards | Trigger | Content zooms toward viewer with blur-in |
|
|
888
|
+
| Step build | `.iso-step-build` | 0.4s steps(6) forwards | Trigger | Square reveals in pixel-step sequence |
|
|
875
889
|
|
|
876
890
|
### Animation composition rules
|
|
877
891
|
|
|
@@ -884,16 +898,16 @@ These classes add thin color to any 1-bit component without breaking the black/w
|
|
|
884
898
|
|
|
885
899
|
### Animation timing — when 1-bit animations apply
|
|
886
900
|
|
|
887
|
-
| Surface
|
|
888
|
-
|
|
889
|
-
| Landing / marketing hero
|
|
890
|
-
| Dashboard / app shell
|
|
891
|
-
| Loading state
|
|
892
|
-
| Error state
|
|
893
|
-
| 1-bit splash / manga panel | `.scanline-fast` (3s)
|
|
894
|
-
| Toast / notification
|
|
895
|
-
| Button (accent)
|
|
896
|
-
| Accent text
|
|
901
|
+
| Surface | Ambient animation | Trigger animation |
|
|
902
|
+
| -------------------------- | ------------------------- | ------------------------------ |
|
|
903
|
+
| Landing / marketing hero | `.scanline` (8s) | `.scan-reveal` on load |
|
|
904
|
+
| Dashboard / app shell | None | `.glitch` on filter change |
|
|
905
|
+
| Loading state | `.skeleton` or `.shimmer` | None |
|
|
906
|
+
| Error state | None | `.glitch-complex` on container |
|
|
907
|
+
| 1-bit splash / manga panel | `.scanline-fast` (3s) | `.invert-flash` on page enter |
|
|
908
|
+
| Toast / notification | None | `.slide-up-reveal` on mount |
|
|
909
|
+
| Button (accent) | None | Color transition on hover |
|
|
910
|
+
| Accent text | `.accent-flicker` | None |
|
|
897
911
|
|
|
898
912
|
## 8. React UI Kit
|
|
899
913
|
|
|
@@ -908,12 +922,14 @@ npm install 7k-design-system
|
|
|
908
922
|
```typescript
|
|
909
923
|
// App entry point
|
|
910
924
|
import '7k-design-system/css';
|
|
911
|
-
import { ThemeProvider } from '7k-design-system/react';
|
|
925
|
+
import { ThemeProvider, ProjectProvider } from '7k-design-system/react';
|
|
912
926
|
|
|
913
927
|
function App() {
|
|
914
928
|
return (
|
|
915
929
|
<ThemeProvider defaultTheme="dark">
|
|
916
|
-
<
|
|
930
|
+
<ProjectProvider defaultProject="7k">
|
|
931
|
+
<YourApp />
|
|
932
|
+
</ProjectProvider>
|
|
917
933
|
</ThemeProvider>
|
|
918
934
|
);
|
|
919
935
|
}
|
|
@@ -925,9 +941,10 @@ function App() {
|
|
|
925
941
|
import { Button } from '7k-design-system/react';
|
|
926
942
|
|
|
927
943
|
<Button
|
|
928
|
-
variant="primary" // 'primary' | 'secondary' | 'ghost' | 'glow' | 'glow-
|
|
944
|
+
variant="primary" // 'primary' | 'secondary' | 'ghost' | 'glow' | 'accent' | 'glow-accent' | 'glow-secondary' | 'danger'
|
|
929
945
|
size="md" // 'sm' | 'md' | 'lg'
|
|
930
946
|
disabled={false}
|
|
947
|
+
loading={false}
|
|
931
948
|
onClick={() => {}}
|
|
932
949
|
type="button" // 'button' | 'submit' | 'reset'
|
|
933
950
|
className=""
|
|
@@ -937,11 +954,13 @@ import { Button } from '7k-design-system/react';
|
|
|
937
954
|
```
|
|
938
955
|
|
|
939
956
|
**CSS classes applied:**
|
|
940
|
-
- Base: `.btn-modern`
|
|
941
|
-
- Variant: `.btn-modern-{variant}` (e.g., `.btn-modern-primary`)
|
|
942
|
-
- Size: `.btn-modern-sm` | `.btn-modern-lg` (md applies no extra class)
|
|
943
957
|
|
|
944
|
-
|
|
958
|
+
- Base: `.btn`
|
|
959
|
+
- Variant: `.btn-{variant}` (e.g., `.btn-primary`)
|
|
960
|
+
- Size: `.btn-sm` | `.btn-lg` (md applies no extra class)
|
|
961
|
+
- Loading: `.btn-loading` when `loading={true}`
|
|
962
|
+
|
|
963
|
+
**Behavior:** Forwards ref to `<button>`. Combines `className` prop with generated classes. Sets `aria-busy` when loading.
|
|
945
964
|
|
|
946
965
|
### Input
|
|
947
966
|
|
|
@@ -954,29 +973,194 @@ import { Input } from '7k-design-system/react';
|
|
|
954
973
|
disabled={false}
|
|
955
974
|
value={value}
|
|
956
975
|
onChange={(value) => setValue(value)} // string callback, not event
|
|
976
|
+
label="Email"
|
|
977
|
+
error="Required"
|
|
957
978
|
className=""
|
|
958
979
|
/>
|
|
959
980
|
```
|
|
960
981
|
|
|
961
|
-
**CSS
|
|
982
|
+
**CSS classes applied:** `.input`, `.form-group`, `.form-label`, `.field-error`
|
|
962
983
|
|
|
963
|
-
**Behavior:** Forwards ref to `<input>`. `onChange` receives the raw string value
|
|
984
|
+
**Behavior:** Forwards ref to `<input>`. `onChange` receives the raw string value. Renders an associated `<label>` when `label` is provided and wires error text via `aria-describedby`.
|
|
964
985
|
|
|
965
986
|
### Badge
|
|
966
987
|
|
|
967
988
|
```typescript
|
|
968
989
|
import { Badge } from '7k-design-system/react';
|
|
969
990
|
|
|
970
|
-
<Badge variant="default"> // 'default' | 'success' | 'warning' | 'danger' | 'info' | 'neutral'
|
|
991
|
+
<Badge variant="default" role="status"> // 'default' | 'accent' | 'success' | 'warning' | 'danger' | 'info' | 'neutral'
|
|
971
992
|
Status
|
|
972
993
|
</Badge>
|
|
973
994
|
```
|
|
974
995
|
|
|
975
996
|
**CSS classes applied:**
|
|
997
|
+
|
|
976
998
|
- Base: `.badge`
|
|
977
999
|
- Variant: `.badge-{variant}` (e.g., `.badge-success`)
|
|
978
1000
|
|
|
979
|
-
**Behavior:** Forwards ref to `<span>`.
|
|
1001
|
+
**Behavior:** Forwards ref to `<span>`. Renders with `role="status"` by default for accessibility.
|
|
1002
|
+
|
|
1003
|
+
### Card
|
|
1004
|
+
|
|
1005
|
+
```typescript
|
|
1006
|
+
import { Card, CardHeader, CardBody } from '7k-design-system/react';
|
|
1007
|
+
|
|
1008
|
+
<Card texture="halftone" hover={true}>
|
|
1009
|
+
<CardHeader>Title</CardHeader>
|
|
1010
|
+
<CardBody>Content</CardBody>
|
|
1011
|
+
</Card>
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
**CSS classes applied:** `.card`, `.card-halftone` | `.card-scanline` | `.card-noise` | `.card-dots` | `.card-crosshatch`, `.card-header`, `.card-body`
|
|
1015
|
+
|
|
1016
|
+
### Modal
|
|
1017
|
+
|
|
1018
|
+
```typescript
|
|
1019
|
+
import { Modal, ModalHeader, ModalFooter } from '7k-design-system/react';
|
|
1020
|
+
|
|
1021
|
+
<Modal open={isOpen} onClose={close} texture="noise" aria-labelledby="modal-title">
|
|
1022
|
+
<ModalHeader>
|
|
1023
|
+
<h2 id="modal-title">Modal Title</h2>
|
|
1024
|
+
</ModalHeader>
|
|
1025
|
+
<p>Modal content</p>
|
|
1026
|
+
<ModalFooter>
|
|
1027
|
+
<Button onClick={close}>Close</Button>
|
|
1028
|
+
</ModalFooter>
|
|
1029
|
+
</Modal>
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
**CSS classes applied:** `.modal`, `.modal-backdrop`, `.modal-header`, `.modal-footer`, texture variants
|
|
1033
|
+
|
|
1034
|
+
**Behavior:** Renders a fixed backdrop with `role="dialog"`, `aria-modal="true"`, and focus management. Body scroll is locked while open.
|
|
1035
|
+
|
|
1036
|
+
### Drawer
|
|
1037
|
+
|
|
1038
|
+
```typescript
|
|
1039
|
+
import { Drawer } from '7k-design-system/react';
|
|
1040
|
+
|
|
1041
|
+
<Drawer open={isOpen} onClose={close} side="right" texture="scanline">
|
|
1042
|
+
Drawer content
|
|
1043
|
+
</Drawer>
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
**CSS classes applied:** `.drawer`, `.drawer-backdrop`, texture variants
|
|
1047
|
+
|
|
1048
|
+
### Toast
|
|
1049
|
+
|
|
1050
|
+
```typescript
|
|
1051
|
+
import { Toast } from '7k-design-system/react';
|
|
1052
|
+
|
|
1053
|
+
<Toast variant="success" onDismiss={dismiss} role="status">
|
|
1054
|
+
Operation completed
|
|
1055
|
+
</Toast>
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
**CSS classes applied:** `.toast`, `.toast-success` | `.toast-error` | `.toast-warning`, `.toast-icon`, `.toast-dismiss`
|
|
1059
|
+
|
|
1060
|
+
### Tooltip
|
|
1061
|
+
|
|
1062
|
+
```typescript
|
|
1063
|
+
import { Tooltip } from '7k-design-system/react';
|
|
1064
|
+
|
|
1065
|
+
<Tooltip content="Helper text" position="top">
|
|
1066
|
+
<Button>Hover me</Button>
|
|
1067
|
+
</Tooltip>
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
**CSS classes applied:** `.tooltip`, `.tooltip-trigger`
|
|
1071
|
+
|
|
1072
|
+
### Alert
|
|
1073
|
+
|
|
1074
|
+
```typescript
|
|
1075
|
+
import { Alert } from '7k-design-system/react';
|
|
1076
|
+
|
|
1077
|
+
<Alert variant="warning" onClose={close}>
|
|
1078
|
+
Please review your settings
|
|
1079
|
+
</Alert>
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
**CSS classes applied:** `.alert`, `.alert-success` | `.alert-warning` | `.alert-danger` | `.alert-info`
|
|
1083
|
+
|
|
1084
|
+
### Tabs
|
|
1085
|
+
|
|
1086
|
+
```typescript
|
|
1087
|
+
import { Tabs, TabList, Tab, TabPanel } from '7k-design-system/react';
|
|
1088
|
+
|
|
1089
|
+
<Tabs defaultIndex={0}>
|
|
1090
|
+
<TabList>
|
|
1091
|
+
<Tab index={0}>First</Tab>
|
|
1092
|
+
<Tab index={1}>Second</Tab>
|
|
1093
|
+
</TabList>
|
|
1094
|
+
<TabPanel index={0}>Panel 1</TabPanel>
|
|
1095
|
+
<TabPanel index={1}>Panel 2</TabPanel>
|
|
1096
|
+
</Tabs>
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
**CSS classes applied:** `.tabs`, `.tab-list`, `.tab`, `.tab-panel`
|
|
1100
|
+
|
|
1101
|
+
### Nav
|
|
1102
|
+
|
|
1103
|
+
```typescript
|
|
1104
|
+
import { Nav, NavItem } from '7k-design-system/react';
|
|
1105
|
+
|
|
1106
|
+
<Nav orientation="horizontal">
|
|
1107
|
+
<NavItem href="/" active>Home</NavItem>
|
|
1108
|
+
<NavItem href="/about">About</NavItem>
|
|
1109
|
+
</Nav>
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
**CSS classes applied:** `.nav`, `.nav-horizontal` | `.nav-vertical`, `.nav-item`
|
|
1113
|
+
|
|
1114
|
+
### Checkbox, Radio, Toggle
|
|
1115
|
+
|
|
1116
|
+
```typescript
|
|
1117
|
+
import { Checkbox, Radio, Toggle } from '7k-design-system/react';
|
|
1118
|
+
|
|
1119
|
+
<Checkbox label="Accept terms" />
|
|
1120
|
+
<Radio label="Option A" name="group" />
|
|
1121
|
+
<Toggle label="Enable notifications" checked={on} onChange={setOn} />
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
**CSS classes applied:** `.checkbox`, `.radio`, `.toggle`
|
|
1125
|
+
|
|
1126
|
+
### Select & Textarea
|
|
1127
|
+
|
|
1128
|
+
```typescript
|
|
1129
|
+
import { Select, Textarea } from '7k-design-system/react';
|
|
1130
|
+
|
|
1131
|
+
<Select>
|
|
1132
|
+
<option>One</option>
|
|
1133
|
+
<option>Two</option>
|
|
1134
|
+
</Select>
|
|
1135
|
+
|
|
1136
|
+
<Textarea rows={4} />
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
**CSS classes applied:** `.select-native`, `.textarea`
|
|
1140
|
+
|
|
1141
|
+
### TextureOverlay
|
|
1142
|
+
|
|
1143
|
+
```typescript
|
|
1144
|
+
import { TextureOverlay } from '7k-design-system/react';
|
|
1145
|
+
|
|
1146
|
+
<TextureOverlay texture="halftone" animate>
|
|
1147
|
+
<section>Content</section>
|
|
1148
|
+
</TextureOverlay>
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
**CSS classes applied:** `.texture-halftone`, `.texture-animated`
|
|
1152
|
+
|
|
1153
|
+
### IsometricBackground
|
|
1154
|
+
|
|
1155
|
+
```typescript
|
|
1156
|
+
import { IsometricBackground } from '7k-design-system/react';
|
|
1157
|
+
|
|
1158
|
+
<IsometricBackground pattern="grid" animated>
|
|
1159
|
+
<section>Hero content</section>
|
|
1160
|
+
</IsometricBackground>
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
**CSS classes applied:** `.isometric-grid`, `.isometric-grid-animated`
|
|
980
1164
|
|
|
981
1165
|
### ThemeToggle
|
|
982
1166
|
|
|
@@ -986,7 +1170,7 @@ import { ThemeToggle } from '7k-design-system/react';
|
|
|
986
1170
|
<ThemeToggle className="" />
|
|
987
1171
|
```
|
|
988
1172
|
|
|
989
|
-
**Behavior:** Renders a 32×32 square button with
|
|
1173
|
+
**Behavior:** Renders a 32×32 square button with sun/moon icon. Uses `useTheme()` internally. Calls `toggleTheme()` on click. Sets `data-theme` attribute on `<html>` and persists to `localStorage` under key `7k-theme`.
|
|
990
1174
|
|
|
991
1175
|
### ThemeProvider
|
|
992
1176
|
|
|
@@ -1002,6 +1186,7 @@ import { ThemeProvider } from '7k-design-system/react';
|
|
|
1002
1186
|
```
|
|
1003
1187
|
|
|
1004
1188
|
**Behavior:**
|
|
1189
|
+
|
|
1005
1190
|
- On mount: reads `localStorage` for stored theme, falls back to `defaultTheme`
|
|
1006
1191
|
- On theme change: sets `document.documentElement.setAttribute('data-theme', theme)` and writes to `localStorage`
|
|
1007
1192
|
- Exposes context value: `{ theme, toggleTheme, setTheme }`
|
|
@@ -1015,6 +1200,7 @@ const { theme, toggleTheme, setTheme } = useTheme();
|
|
|
1015
1200
|
```
|
|
1016
1201
|
|
|
1017
1202
|
**Returns:**
|
|
1203
|
+
|
|
1018
1204
|
- `theme: 'dark' | 'light'` — current active theme
|
|
1019
1205
|
- `toggleTheme: () => void` — flips dark ↔ light
|
|
1020
1206
|
- `setTheme: (theme: 'dark' | 'light') => void` — sets explicit theme
|
|
@@ -1031,7 +1217,14 @@ interface BaseProps {
|
|
|
1031
1217
|
children?: ReactNode;
|
|
1032
1218
|
}
|
|
1033
1219
|
|
|
1034
|
-
type ButtonVariant =
|
|
1220
|
+
type ButtonVariant =
|
|
1221
|
+
| 'primary'
|
|
1222
|
+
| 'secondary'
|
|
1223
|
+
| 'ghost'
|
|
1224
|
+
| 'glow'
|
|
1225
|
+
| 'glow-cyan'
|
|
1226
|
+
| 'glow-grid'
|
|
1227
|
+
| 'danger';
|
|
1035
1228
|
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
1036
1229
|
interface ButtonProps extends BaseProps {
|
|
1037
1230
|
variant?: ButtonVariant;
|
|
@@ -1066,18 +1259,18 @@ interface ThemeContextValue {
|
|
|
1066
1259
|
|
|
1067
1260
|
The CSS is split into 10 source files under `src/css/`, compiled into `dist/7k-design-system.css`. Each file has a single responsibility. Import `src/css/index.css` to load all modules, or import individual modules for tree-shaking.
|
|
1068
1261
|
|
|
1069
|
-
| File
|
|
1070
|
-
|
|
1071
|
-
| `fonts.css`
|
|
1072
|
-
| `tokens.css`
|
|
1073
|
-
| `themes.css`
|
|
1074
|
-
| `base.css`
|
|
1075
|
-
| `textures.css`
|
|
1076
|
-
| `isometric.css`
|
|
1077
|
-
| `components.css`
|
|
1078
|
-
| `modifiers.css`
|
|
1079
|
-
| `animations.css`
|
|
1080
|
-
| `accessibility.css` | ~0.6KB
|
|
1262
|
+
| File | Size | Responsibility |
|
|
1263
|
+
| ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
1264
|
+
| `fonts.css` | ~1.7KB | `@font-face` for Geist Pixel 5 variants; CDN imports for Geist Sans/Mono |
|
|
1265
|
+
| `tokens.css` | ~12.5KB | All design tokens: color ramps, semantic roles, typography, spacing, radii, shadows, motion, layout, z-index |
|
|
1266
|
+
| `themes.css` | ~7.2KB | Dark default in `:root`; light overrides in `@media (prefers-color-scheme: light)` and `html[data-theme="light"]` |
|
|
1267
|
+
| `base.css` | ~7.6KB | CSS reset, body/html base styles, `.mono-label` utility, `.display`/`.h1`–`.h4`/`.body` type utilities |
|
|
1268
|
+
| `textures.css` | ~12.4KB | 10 texture categories: scanline, halftone, dot matrix, stripes, crosshatch, checkerboard, noise, vignette |
|
|
1269
|
+
| `isometric.css` | ~12.5KB | 11 isometric patterns: grid, cubes, pyramid, hex, pipes, terrain + animation variants |
|
|
1270
|
+
| `components.css` | ~36KB | 40+ component classes: buttons, forms, nav, data display, overlays, feedback, media, misc |
|
|
1271
|
+
| `modifiers.css` | ~2.2KB | Accent layer modifiers: border-top, underline, dot, bar, glow, corner |
|
|
1272
|
+
| `animations.css` | ~15.8KB | 20+ keyframe animations: glitch, flicker, blink, typewriter, neon-pulse, scan-reveal, pixel-fade, iso-float |
|
|
1273
|
+
| `accessibility.css` | ~0.6KB | `prefers-reduced-motion` collapse, `:focus-visible` rings, `prefers-contrast` support, screen-reader utilities |
|
|
1081
1274
|
|
|
1082
1275
|
### PostCSS Pipeline
|
|
1083
1276
|
|
|
@@ -1093,10 +1286,10 @@ src/css/index.css
|
|
|
1093
1286
|
### Standalone CSS Exports
|
|
1094
1287
|
|
|
1095
1288
|
```typescript
|
|
1096
|
-
import '7k-design-system/css';
|
|
1097
|
-
import '7k-design-system/css/tokens';
|
|
1289
|
+
import '7k-design-system/css'; // Full bundle (~115KB)
|
|
1290
|
+
import '7k-design-system/css/tokens'; // Tokens only (~12KB)
|
|
1098
1291
|
import '7k-design-system/css/components'; // Components only (~36KB)
|
|
1099
|
-
import '7k-design-system/css/textures';
|
|
1292
|
+
import '7k-design-system/css/textures'; // Textures only (~12KB)
|
|
1100
1293
|
import '7k-design-system/css/animations'; // Animations only (~16KB)
|
|
1101
1294
|
```
|
|
1102
1295
|
|
|
@@ -1105,7 +1298,7 @@ import '7k-design-system/css/animations'; // Animations only (~16KB)
|
|
|
1105
1298
|
```bash
|
|
1106
1299
|
npm run build:css # Compile CSS bundle + standalone modules
|
|
1107
1300
|
npm run build:react # Compile React ESM + CJS + .d.ts
|
|
1108
|
-
npm run build:copy-assets # Copy
|
|
1301
|
+
npm run build:copy-assets # Copy fonts/ and build/ to dist/
|
|
1109
1302
|
npm run build # Run all three build steps
|
|
1110
1303
|
```
|
|
1111
1304
|
|
|
@@ -1116,16 +1309,17 @@ npm run build # Run all three build steps
|
|
|
1116
1309
|
Location: `tests/`
|
|
1117
1310
|
Runner: Vitest + jsdom + @testing-library/react + jest-axe
|
|
1118
1311
|
|
|
1119
|
-
| File
|
|
1120
|
-
|
|
1121
|
-
| `Button.test.tsx`
|
|
1122
|
-
| `Input.test.tsx`
|
|
1123
|
-
| `Badge.test.tsx`
|
|
1312
|
+
| File | Coverage |
|
|
1313
|
+
| ------------------------ | --------------------------------------------------------------- |
|
|
1314
|
+
| `Button.test.tsx` | Rendering, variant/size classes, click handler, disabled state |
|
|
1315
|
+
| `Input.test.tsx` | Rendering, value/onChange callback, disabled state, placeholder |
|
|
1316
|
+
| `Badge.test.tsx` | Rendering, variant classes, children content |
|
|
1124
1317
|
| `ThemeProvider.test.tsx` | Default theme, localStorage persistence, `data-theme` attribute |
|
|
1125
|
-
| `ThemeToggle.test.tsx`
|
|
1126
|
-
| `a11y.test.tsx`
|
|
1318
|
+
| `ThemeToggle.test.tsx` | Click toggles theme, icon changes, aria-label updates |
|
|
1319
|
+
| `a11y.test.tsx` | axe-core accessibility checks on Button, Input, Badge |
|
|
1127
1320
|
|
|
1128
1321
|
**Run tests:**
|
|
1322
|
+
|
|
1129
1323
|
```bash
|
|
1130
1324
|
npm test # Unit tests
|
|
1131
1325
|
npm run test:a11y # Accessibility tests
|
|
@@ -1137,36 +1331,34 @@ npm run test:watch # Watch mode
|
|
|
1137
1331
|
Location: `src/stories/`
|
|
1138
1332
|
Port: 6006
|
|
1139
1333
|
|
|
1140
|
-
| Story
|
|
1141
|
-
|
|
1142
|
-
| `Design System/Overview` (`Overview.mdx`)
|
|
1143
|
-
| `Design System/Tokens` (`Tokens.mdx`)
|
|
1144
|
-
| `Components/Button` (`Components.stories.tsx`)
|
|
1145
|
-
| `Components/
|
|
1146
|
-
| `Components/
|
|
1147
|
-
| `Components/
|
|
1148
|
-
| `
|
|
1149
|
-
| `
|
|
1334
|
+
| Story | Content |
|
|
1335
|
+
| ---------------------------------------------------- | ------------------------------------------------ |
|
|
1336
|
+
| `Design System/Overview` (`Overview.mdx`) | Design principles, color palette, usage examples |
|
|
1337
|
+
| `Design System/Tokens` (`Tokens.mdx`) | Token reference tables |
|
|
1338
|
+
| `Components/Button` (`Components.stories.tsx`) | All Button variants and sizes |
|
|
1339
|
+
| `Components/TexturedButtons` | Textured button variants |
|
|
1340
|
+
| `Components/Inputs` (`Components.stories.tsx`) | Input states |
|
|
1341
|
+
| `Components/Badges` (`Components.stories.tsx`) | Badge variants |
|
|
1342
|
+
| `Components/Cards` (`Components.stories.tsx`) | Card styles and textures |
|
|
1343
|
+
| `Components/TexturedCards` | Textured card variants |
|
|
1344
|
+
| `Components/Navigation` (`Components.stories.tsx`) | Nav patterns |
|
|
1345
|
+
| `Components/Alerts` (`Components.stories.tsx`) | Alert variants |
|
|
1346
|
+
| `Components/Toasts` (`Components.stories.tsx`) | Toast variants |
|
|
1347
|
+
| `Components/FormControls` (`Components.stories.tsx`) | Checkbox, radio, toggle |
|
|
1348
|
+
| `Components/ThemeToggle` (`Components.stories.tsx`) | Theme toggle button |
|
|
1349
|
+
| `Textures/All` (`Textures.stories.tsx`) | All texture patterns |
|
|
1350
|
+
| `Textures/Isometric` (`Textures.stories.tsx`) | Isometric patterns |
|
|
1351
|
+
| `Textures/IsometricAnimated` | Animated isometric backgrounds |
|
|
1150
1352
|
|
|
1151
1353
|
**Run Storybook:**
|
|
1354
|
+
|
|
1152
1355
|
```bash
|
|
1153
1356
|
npm run storybook # Dev server at http://localhost:6006
|
|
1154
1357
|
npm run build-storybook # Static build for deployment
|
|
1155
1358
|
npm run chromatic # Visual regression testing
|
|
1156
1359
|
```
|
|
1157
1360
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
Location: `preview/` (copied to `dist/preview/` on build)
|
|
1161
|
-
|
|
1162
|
-
| File | Purpose |
|
|
1163
|
-
|------|---------|
|
|
1164
|
-
| `colors-primary.html` | Accent swatches, ramps, project overrides |
|
|
1165
|
-
| `typography-specimens.html` | Type scale + weights + pixel variants |
|
|
1166
|
-
| `spacing-tokens.html` | 4px grid, radii, shadows |
|
|
1167
|
-
| `components-buttons.html` | Product component states |
|
|
1168
|
-
| `textures-backgrounds.html` | 10 background texture categories with composition demos |
|
|
1169
|
-
| `brand-assets.html` | Logo variants + brand in context |
|
|
1361
|
+
> **Note:** Preview HTML cards were removed in favor of Storybook as the canonical preview surface.
|
|
1170
1362
|
|
|
1171
1363
|
## 11. Voice & Brand
|
|
1172
1364
|
|
|
@@ -1175,7 +1367,7 @@ Location: `preview/` (copied to `dist/preview/` on build)
|
|
|
1175
1367
|
- **Tone**: Direct, technical, slightly playful. "Built for midnight."
|
|
1176
1368
|
- **Capitalization**: Sentence case for headings, uppercase only for kickers/labels
|
|
1177
1369
|
- **Company**: 7K (always uppercase with the numeral). Child projects: "7K Project Neon"
|
|
1178
|
-
- **Logo**: Star-burst pattern SVG in `build/logo-7k.svg` with #FF0FF brand accent tones. Light variant at `build/logo-7k-light.svg` (black polygons for light backgrounds). App icon at `build/icon.svg`.
|
|
1370
|
+
- **Logo**: Star-burst pattern SVG in `build/logos/logo-7k.svg` with #FF0FF brand accent tones. Light variant at `build/logos/logo-7k-light.svg` (black polygons for light backgrounds). App icon at `build/icons/icon.svg`.
|
|
1179
1371
|
- **Terminology**: "Surface" for pages, "module" for components, "canvas" for background
|
|
1180
1372
|
- **No filler**: never use "streamlined", "innovative", "leveraging" unless literal
|
|
1181
1373
|
- **Error messages**: direct, no "oops". "Connection failed. Retry." not "Something went wrong."
|
|
@@ -1184,24 +1376,24 @@ Location: `preview/` (copied to `dist/preview/` on build)
|
|
|
1184
1376
|
|
|
1185
1377
|
**Source context reference:** Each anti-pattern below derives from a specific brief constraint: dark theme (no warm backgrounds), three-font system kept to Geist family only, 1-bit influence (no rounded corners on 1-bit elements), neon Tokyo (no generic purple gradients), brand-color-only accent (no color proliferation).
|
|
1186
1378
|
|
|
1187
|
-
| Anti-pattern
|
|
1188
|
-
|
|
1189
|
-
| Warm beige/cream/peach backgrounds
|
|
1190
|
-
| Multiple font families outside the system
|
|
1191
|
-
| Over-rounded everything
|
|
1192
|
-
| Gradient overload
|
|
1193
|
-
| Emoji iconography
|
|
1194
|
-
| Drop shadows on text
|
|
1195
|
-
| Stock photography
|
|
1196
|
-
| Generic purple/violet gradients
|
|
1197
|
-
| Invented metrics/fake stats
|
|
1198
|
-
| Circular spinners on 1-bit elements
|
|
1199
|
-
| Rounded checkboxes/radios
|
|
1200
|
-
| Blurred drop shadows on 1-bit components
|
|
1201
|
-
| SVG humans / scenery / illustrations
|
|
1202
|
-
| Glitch as a continuous loop
|
|
1203
|
-
| Warm/beige tones anywhere
|
|
1204
|
-
| Multiple textures on the same section layer
|
|
1205
|
-
| Continuous animation on UI surfaces
|
|
1206
|
-
| Isometric animation on interactive UI
|
|
1207
|
-
| Mixing 1-bit button patterns into product surfaces | Use the modern button system (.btn
|
|
1379
|
+
| Anti-pattern | Why |
|
|
1380
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1381
|
+
| Warm beige/cream/peach backgrounds | System is dark-first; light theme is precise white |
|
|
1382
|
+
| Multiple font families outside the system | Three fonts only: Geist (sans), Geist Mono, Geist Pixel (5 variants). No other families. |
|
|
1383
|
+
| Over-rounded everything | Sharp 0px or subtle 4px preferred |
|
|
1384
|
+
| Gradient overload | Max one gradient per page; no full-page gradient backgrounds |
|
|
1385
|
+
| Emoji iconography | Use CSS/SVG instead |
|
|
1386
|
+
| Drop shadows on text | Use high-contrast fg instead |
|
|
1387
|
+
| Stock photography | Use 1-bit halftone texture library |
|
|
1388
|
+
| Generic purple/violet gradients | Accent is magenta (#FF0FF), not purple |
|
|
1389
|
+
| Invented metrics/fake stats | Use real data or grey stubs |
|
|
1390
|
+
| Circular spinners on 1-bit elements | Spinner is square — never mix circular |
|
|
1391
|
+
| Rounded checkboxes/radios | One-bit form controls are square |
|
|
1392
|
+
| Blurred drop shadows on 1-bit components | Shadow is a hard offset, not a blur |
|
|
1393
|
+
| SVG humans / scenery / illustrations | 1-bit means abstract texture, not hand-drawn |
|
|
1394
|
+
| Glitch as a continuous loop | Glitch is a 2–3 iteration burst |
|
|
1395
|
+
| Warm/beige tones anywhere | System is nocturnal dark + neon |
|
|
1396
|
+
| Multiple textures on the same section layer | Max one background + one overlay per section |
|
|
1397
|
+
| Continuous animation on UI surfaces | Ambient animations are for hero/landing sections only |
|
|
1398
|
+
| Isometric animation on interactive UI | Isometric bg + motion is for hero/splash sections only; never on cards, buttons, or form controls |
|
|
1399
|
+
| Mixing 1-bit button patterns into product surfaces | Use the modern button system (.btn\*) for all product surfaces. 1-bit button classes (.btn, .btn-primary, .btn-accent) are removed — do not reintroduce raw invert-hover buttons in place of modern neon buttons. |
|