SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
4.7 KB · 154 lines markdown
Rendered Raw Blame History
1<!--2Author: Simon-Pierre Boucher3Contact: contact@spboucher.ai4-->56# Patterns — Design Tokens & Theming78## Contents9- Starter token sheet (primitives)10- Semantic tokens, light + dark11- Component tier example12- Theme toggle (no-flash)13- Contrast quick-check14- Gotchas1516## Starter token sheet (primitives)1718```css19:root {20  /* Neutral ramp (5 steps is enough to start) */21  --gray-50:  #f8fafc;22  --gray-200: #e2e8f0;23  --gray-500: #64748b;24  --gray-800: #1e293b;25  --gray-950: #0b1220;2627  /* Accent ramp */28  --blue-400: #60a5fa;29  --blue-600: #2563eb;30  --blue-700: #1d4ed8;3132  /* Status */33  --green-600: #16a34a;34  --amber-600: #d97706;35  --red-600:   #dc2626;3637  /* Spacing — base-4 scale */38  --space-1: 0.25rem;  --space-2: 0.5rem;  --space-3: 0.75rem;39  --space-4: 1rem;     --space-6: 1.5rem;  --space-8: 2rem;40  --space-12: 3rem;    --space-16: 4rem;4142  /* Radius & shadows — 3 levels each */43  --radius-sm: 0.25rem; --radius-md: 0.5rem; --radius-full: 9999px;44  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.06);45  --shadow-2: 0 4px 8px rgb(0 0 0 / 0.10);46  --shadow-3: 0 12px 24px rgb(0 0 0 / 0.14);4748  color-scheme: light dark;49}50```5152## Semantic tokens, light + dark5354```css55/* Light (default) */56:root, [data-theme="light"] {57  --color-bg-page:     var(--gray-50);58  --color-bg-surface:  #ffffff;59  --color-text:        var(--gray-800);   /* on bg-page: 12.6:1 ✓ */60  --color-text-muted:  var(--gray-500);   /* on surface: 4.8:1 ✓  */61  --color-border:      var(--gray-200);62  --color-accent:      var(--blue-600);   /* as text on surface: 5.2:1 ✓ */63  --color-accent-hover: var(--blue-700);64  --color-danger:      var(--red-600);65}6667/* Dark via system preference (only when no explicit choice) */68@media (prefers-color-scheme: dark) {69  :root:not([data-theme]) {70    --color-bg-page:     var(--gray-950);71    --color-bg-surface:  var(--gray-800);72    --color-text:        var(--gray-50);73    --color-text-muted:  #94a3b8;         /* on gray-800: 5.9:1 ✓ */74    --color-border:      #334155;75    --color-accent:      var(--blue-400); /* lighter accent for dark bg: 6.6:1 ✓ */76    --color-accent-hover: #93c5fd;77  }78}7980/* Dark via explicit user choice — identical block, attribute-scoped */81[data-theme="dark"] {82  --color-bg-page:     var(--gray-950);83  --color-bg-surface:  var(--gray-800);84  --color-text:        var(--gray-50);85  --color-text-muted:  #94a3b8;86  --color-border:      #334155;87  --color-accent:      var(--blue-400);88  --color-accent-hover: #93c5fd;89}90```9192## Component tier example9394```css95.button-primary {96  background: var(--color-accent);97  color: var(--color-bg-surface);98  padding: var(--space-2) var(--space-4);99  border-radius: var(--radius-md);100  box-shadow: var(--shadow-1);101}102.button-primary:hover { background: var(--color-accent-hover); }103104.card {105  background: var(--color-bg-surface);106  border: 1px solid var(--color-border);107  border-radius: var(--radius-md);108  padding: var(--space-6);109}110```111112## Theme toggle (no-flash)113114```html115<!-- In <head>, BEFORE any stylesheet, so first paint is themed -->116<script>117  const t = localStorage.getItem("theme");           // "light" | "dark" | null118  if (t) document.documentElement.dataset.theme = t; // absent = follow system119</script>120```121122```js123function setTheme(next) {           // next: "light" | "dark" | "system"124  if (next === "system") {125    delete document.documentElement.dataset.theme;126    localStorage.removeItem("theme");127  } else {128    document.documentElement.dataset.theme = next;129    localStorage.setItem("theme", next);130  }131}132```133134## Contrast quick-check135136Compute ratio = (L1 + 0.05) / (L2 + 0.05) with relative luminance, or verify in137devtools (element → color picker shows the ratio). Thresholds to enforce **in138the token sheet**:139140| Pair | Minimum |141|---|---|142| Body/label text on its background | 4.5:1 (AA) |143| Large text ≥24px (or 18.7px bold) | 3:1 |144| UI component borders, icons, focus rings | 3:1 |145146## Gotchas147148- **`prefers-color-scheme` block must exclude explicit choices** — scope it with `:root:not([data-theme])` or a user who picked "light" gets system-dark anyway.149- **Forgetting `color-scheme: light dark`** leaves scrollbars, form controls, and default UA styles stuck in light mode.150- **Muted text is the #1 AA failure** — grays around `#999` fail on white (2.8:1). Nothing lighter than `#767676` for body-size text on white.151- **Same accent in both themes usually fails one of them** — accents need a per-theme value (darker for light bg, lighter for dark bg).152- **`rgb(0 0 0 / 0.5)`-style translucent text** has no fixed contrast ratio (depends on what's behind) — use opaque token colors for text.153- **Tokens in shadows:** define whole shadows as tokens, not just colors — dark themes often need different alpha, not different hue.154