SPB Git

Repository Public MIT Selected

DESIGN.md 9.8 KB 135 lines markdown

1<!--2  ─────────────────────────────────────────────3   SPB Git — Personal Git Platform4  ─────────────────────────────────────────────5   Author  : Simon-Pierre Boucher6   Contact : contact@spboucher.ai7   File    : docs/DESIGN.md8   Purpose : SPB Git 3.0 design system "Monograph" — direction, tokens, type scale, components, rules9   License : MIT © Simon-Pierre Boucher10  ─────────────────────────────────────────────11-->12# SPB Git 3.0 — design system "Monograph"1314SPB Git shares the visual language of [www.spboucher.ai](https://www.spboucher.ai):15an editorial monograph, not a dashboard. Warm paper, ink, one indigo accent,16hairlines, square corners, generous white space. Colour carries meaning (links,17active state, additions/deletions, languages) and is never decoration.1819## 1. Direction (the fifteen lines)20211. Paper and ink. The page is warm paper with a faint graph grid in the top corner; surfaces are a slightly lighter sheet.222. One accent, indigo (`oklch(0.44 0.155 268)` on paper). No gradients, no glow, no second brand colour.233. Three voices: **Fraunces** for names, titles and numerals; **Inter** for text; **IBM Plex Mono** for labels, metadata and code.244. Labels are small uppercase mono with wide tracking (10.5–11 px, 0.14–0.2 em). Sections open with a short rule and a numbered eyebrow ("01 SELECTED").255. Square corners everywhere; 2 px only softens small controls. Borders are 1 px hairlines; a 2 px ink rule opens a block of figures or a document.266. No shadows at rest. A card lifts 1 px on hover; only dialogs cast a shadow.277. Figures are set like a table of statistics: rule, "01", serif numeral, mono caption — never rounded stat tiles.288. Lists are typographic indexes and ledgers (hairlines, aligned columns, tabular numerals), not grids of identical cards.299. The primary action is ink on paper (black button, paper text), inverted in the dark themes. Secondary actions are outlined; tertiary are text.3010. Code is quiet: house syntax themes "paper" and "ink" (ink text, grey italic comments, indigo keywords, sienna strings, ochre constants, teal functions, plum types).3111. A README is a document page: a sheet with a measured column and an "On this page" outline beside it.3212. Captions speak like a paper: "Fig. 1 — clone over HTTPS".3313. Motion is short (120–280 ms) and functional; everything honours `prefers-reduced-motion`.3414. Mobile first: the base styles are the phone layout; nothing scrolls sideways except code, diffs, the calendar and tab strips, inside their own block.3515. One icon set (Lucide, ISC, stroke 1.75) and one monogram: the black "SB" tile.3637## 2. Tokens (`src/web/assets/css/tokens.css`)3839Semantic only; components never use raw colours.4041| Group | Tokens |42|---|---|43| Surfaces | `--bg` (paper) · `--surface-0` (sheet, cards, code) · `--surface-1..3` (bands, hover, tracks) · `--bg-elev` (dialogs) · `--glass`, `--nav-bg` |44| Ink | `--fg` · `--fg-bright` · `--fg-muted` · `--fg-faint` (all ≥ 4.5:1 on `--bg` and `--surface-0`) · `--ink` / `--on-ink` (primary button, monogram, selected states) |45| Lines | `--border` (hairline) · `--border-strong` (controls) · `--rule` (2 px ink rules) · `--grid-line` |46| Accent | `--accent` · `--accent-hover` · `--accent-soft` · `--accent-line` |47| Status | `--ok` · `--warn` · `--danger` (+ `-soft`) · `--ember` (rare warm marker) |48| Diff | `--add-bg` · `--add-bg-strong` · `--add-text` · `--del-bg` · `--del-bg-strong` · `--del-text` · `--hunk-bg` |49| Code | `--code-bg` · `--code-head`; syntax colours come from the shiki themes (`--shiki-light`, `--shiki-dark`) |50| Calendar | `--heat-0..4` — a single indigo ramp |51| Space | `--space-1..11` = 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 88 px |52| Geometry | `--radius` 2 px (controls) · `--radius-lg` 0 (cards) · `--touch` 44 px · `--header-h` 60/54 px · `--container` 1200 px · `--measure` 860 px |53| Motion | `--dur-fast` 120 ms · `--dur` 180 ms · `--dur-slow` 280 ms · `--ease` · `--ease-out` |5455### Themes5657| Theme | Paper | Ink | Accent | Use |58|---|---|---|---|---|59| `light` | `oklch(0.972 0.006 85)` | `oklch(0.245 0.016 75)` | `oklch(0.44 0.155 268)` | the paper of spboucher.ai (default when the OS is light) |60| `dark` | `oklch(0.185 0.008 75)` | `oklch(0.925 0.01 85)` | `oklch(0.77 0.105 268)` | its night edition (default when the OS is dark) |61| `midnight` | `#000` | `oklch(0.955 0.004 270)` | `oklch(0.82 0.1 268)` | true black, maximum contrast, for OLED screens |6263`theme-boot.js` resolves `auto | light | dark | midnight` from64`localStorage['spbgit-theme']` before first paint. Every theme is checked with65`scripts/qa/axe.py` (WCAG 2.1 AA).6667## 3. Type6869| Role | Family | Size / weight | Where |70|---|---|---|---|71| Masthead | Fraunces 600, italic 400 for the name | `--text-hero` clamp(40, 6vw, 70) / 1.04 | front page |72| Page title | Fraunces 600 | `--text-3xl` clamp(30, 3.6vw, 40) | search, about pages |73| Repository title | Fraunces 600 (owner 400) | clamp(30, 4.6vw, 50); 22–28 on sub-pages | repository header |74| Section title | Fraunces 600 | `--text-2xl` 28 | numbered sections |75| Numerals | Fraunces 600, lining tabular | 40 / 36 / 24 | figure rows |76| Names in lists | Fraunces 600 | 19–22 | index rows, cards, results |77| Text | Inter 400/500/600 | `--text-base` 15 / 1.6; README 16 / 1.65 | everything else |78| Label | IBM Plex Mono 500, uppercase | `--text-2xs` 10.5–11, tracking 0.14–0.2 em | eyebrows, captions, tabs, nav, column heads |79| Meta | IBM Plex Mono 400/500 | 11–12.5, tabular | dates, sizes, SHAs, paths |80| Code | IBM Plex Mono 400 (italic for comments) | 12.75 / 1.7 | blobs, diffs, blame, fences |8182Fonts are self-hosted and tracked in git (`src/web/assets/fonts/`, OFL, latin83subset, from the `@fontsource` packages): Fraunces variable (opsz + wght) and84italic 400, Inter variable, IBM Plex Mono 400/400i/500/600. Inter and Fraunces85are preloaded; `font-display: swap` with metric-adjusted fallbacks86(`Inter Fallback`, `Fraunces Fallback`, `Plex Mono Fallback`) so the swap does87not move the layout. `scripts/fetch-fonts.mjs` only verifies/repairs the files.8889## 4. Components (`views/components/ui.njk`, `assets/css/app.css`)9091| Component | Markup | Notes |92|---|---|---|93| Icon | `ui.icon(name, size)` | Lucide subset, generated path data; add the name to the macro before use; `app.js` carries the client-side subset (`svgIcon`) |94| Monogram | `.brand-mark` | "SB" in Plex Mono 600 on an ink tile; `assets/img/logo.svg` and the PNG icons are the same outlines |95| Eyebrow | `.eyebrow` + `.eyebrow-rule` | short accent rule, optional number, mono caps |96| Section head | `ui.sectionHead(id, no, eyebrow, title, sub, count)` | caller block = trailing control or link |97| Figure row | `ui.statStrip(items, cls)` | `.stat-strip-hero` (one rule per figure) · `.stat-strip-repo` (one rule for the row) |98| Label head | `.label-head` | mono caps over a 2 px rule: side lists, result groups |99| Button | `.btn` · `.btn-primary` · `.btn-ghost` · `.btn-sm` · `.seg` | 38/30 px, 44 px on touch; pressed/active = ink |100| Tag | `ui.chip(label, kind)` | square mono tag; `topic`, `accent`, `ok`, `warn`, `danger` |101| Tabs | `ui.tabs(items, active)` | mono caps, 2 px accent underline, scrolls inside its strip |102| Breadcrumbs / ref picker | `ui.breadcrumbs`, `ui.refSelect` | mono; native `<select>` for iOS |103| Card | `.card` (+ `.card-head`, `.card-pad`) | hairline sheet, no radius, no shadow |104| Feature card | `partials/repo-card.njk` | numbered plate ("No. 01"), lifts 1 px on hover |105| Index row | `partials/repo-row.njk` | CSS counter numbering, serif name, mono facts, sparkline |106| Ledger | `.ref-list`, `.rank-list`, `.activity-feed`, `.search-results` | hairline rows, mono meta |107| Plate / figure | `.plate`, `.figure-block` + `figcaption` | framed specimen with offset grid; captions "Fig. n — …" |108| File list | `partials/file-table.njk` | latest-commit strip, 40 px rows |109| Document | `.readme-section`, `.prose-layout`, `markdown.css` | sheet + outline (`.readme-toc`, `.prose-nav`) |110| Code | `.code-view`, `.diff-file`, `.blame-table` | sticky file header, line numbers behind a hairline |111| States | `ui.emptyState`, `ui.errorState`, `ui.skeleton`, `.notice` | dashed frame, serif title; notice = accent bar |112| Dialogs | `.sheet`, `.popover`, `.cmdk`, `.confirm`, `.toast` | bottom sheets under 768 px, ink-bordered panels above |113| Progress | `html.is-loading` | 2 px accent hairline while the next page loads |114115## 5. Rules116117- Run `python3 -I scripts/qa/screens.py <url> <out>` (must print `OK — 0 failing`) and118  `python3 -I scripts/qa/axe.py <url>` (0 violations) before any CSS change ships.119- Every grid track is `minmax(0, 1fr)`; scroll containers are bounded and keyboard-focusable.120- Essential controls are ≥ 44 × 44 px on coarse pointers.121- Cards with sticky headers use `overflow: clip`, never `overflow: hidden`.122- No emoji or text glyphs as icons in the chrome; no gradient fills; no pill shapes.123- Dates show a relative label with the exact instant in `title` (`dateexact` filter).124- Repository authors' Markdown is content: badges keep their natural height, centred blocks stay centred, tables scroll inside themselves.125- Bump `package.json` on every release: assets are cache-busted with `?v=<version>`.126- Print: README, files and prose print as plain documents (`@media print` in `app.css`).127128## 6. Screenshots129130`docs/screenshots/v3/` holds eight before/after pairs of the 2.0 → 3.0 redesign131(`before-<page>-<width>-<theme>.png` / `after-…`, development data) and the132production views taken after the deployment (`prod-*.png`). The 1.1 and 2.0133sets (`docs/screenshots/baseline/`, `docs/screenshots/v2/`) were removed from134the tree in 3.0; they remain in the git history (commit `7864e4d`).135
Files main
Menu

Theme