feat(designbook): technology-neutral IR + stack-adapter pipeline (WHYNOT-WP-0002 T01-T06)
Author the design language once in the canonical React designbook and project it
one-way onto each stack: React -> designbook/ -> ir/ -> adapters/<stack>/.
Phase 0 — contracts & governance (T01-T03):
- ir/SCHEMA.md + ir/schema/{component,tokens}.schema.json — neutral IR contract
(W3C DTCG tokens; React prop -> HTML attribute mapping; non-portable props flagged).
- adapters/ADAPTER_CONTRACT.md — inputs, drift-report + parity-result shapes,
idempotency rules, CI exit codes (0 ok / 2 usage / 3 drift / 4 parity / 5 internal).
- .claude/rules/designbook-propagation.md + DesignSystemIntroduction.md §5.1 —
one-way directionality + drift-resolution workflow.
T04 — canonical React designbook + the missing pull tool:
- The bundled /design-sync skill only PUSHES repo->cloud; it cannot populate
designbook/. Added scripts/designbook_pull.py + `make designbook-pull`, which drives
the local claude binary headless (acceptEdits) so DesignSync fetch+write runs in a
subprocess (contents never hit the orchestrator's context). Pulled 44 files;
excludes the _whynot-design-seed/ self-copy. Corrected the docs that wrongly called
/design-sync the pull.
T05 — IR extractor (scripts/ir-extract.mjs + `make ir`):
- ir/tokens.json (80 tokens, DTCG, var() -> {ref} alias resolution); ir/components/*.json
(10 contracts parsed from .jsx signatures: enum/boolean/number inference, prop->attr
map, style/callback marked non-portable); ir/exemplars/*.
T06 — Lit token adapter (adapters/lit/ + `make adapt-lit`):
- Full-gen tokens into src/styles/colors_and_type.css :root (marker-bounded, idempotent
no-op on re-run; hand-authored type CSS preserved).
NOTE: token regen synced Lit to canonical React — fonts IBM Plex -> system stacks and 8
status tokens added. This is a VISUAL change: review and run `pnpm test:visual:update`
before merge. Remaining: T07 scaffold+drift, T08 parity, T09 runbook, T10 2nd-adapter.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
36
designbook/preview/brand-iconography.html
Normal file
36
designbook/preview/brand-iconography.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Brand" name="Brand · Iconography" subtitle="Lucide · 1.5px stroke · 16 of set" viewport="700x240" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Iconography — Lucide @ 1.5px</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 22px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 14px 12px; }
|
||||
.cell { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 6px; border: 1px solid var(--border-soft); border-radius: 2px; }
|
||||
.cell svg { width: 22px; height: 22px; stroke: currentColor; stroke-width: 1.5; fill: none; }
|
||||
.cell .n { font: 500 10px var(--ff-mono); color: var(--fg-3); letter-spacing: 0.04em; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Lucide · stroke-width 1.5 · currentColor</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><i data-lucide="inbox"></i><span class="n">inbox</span></div>
|
||||
<div class="cell"><i data-lucide="lightbulb"></i><span class="n">lightbulb</span></div>
|
||||
<div class="cell"><i data-lucide="flask-conical"></i><span class="n">flask</span></div>
|
||||
<div class="cell"><i data-lucide="activity"></i><span class="n">signal</span></div>
|
||||
<div class="cell"><i data-lucide="users"></i><span class="n">beta</span></div>
|
||||
<div class="cell"><i data-lucide="git-branch"></i><span class="n">branch</span></div>
|
||||
<div class="cell"><i data-lucide="check-square"></i><span class="n">decision</span></div>
|
||||
<div class="cell"><i data-lucide="archive"></i><span class="n">park</span></div>
|
||||
<div class="cell"><i data-lucide="arrow-right"></i><span class="n">promote</span></div>
|
||||
<div class="cell"><i data-lucide="x"></i><span class="n">reject</span></div>
|
||||
<div class="cell"><i data-lucide="search"></i><span class="n">search</span></div>
|
||||
<div class="cell"><i data-lucide="filter"></i><span class="n">filter</span></div>
|
||||
<div class="cell"><i data-lucide="file-text"></i><span class="n">doc</span></div>
|
||||
<div class="cell"><i data-lucide="folder"></i><span class="n">folder</span></div>
|
||||
<div class="cell"><i data-lucide="circle-help"></i><span class="n">question</span></div>
|
||||
<div class="cell"><i data-lucide="circle-alert"></i><span class="n">caveat</span></div>
|
||||
</div>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<script>lucide.createIcons();</script>
|
||||
</body></html>
|
||||
26
designbook/preview/brand-lockups.html
Normal file
26
designbook/preview/brand-lockups.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Brand" name="Brand · Lockups" subtitle="Mark + slug · 3 sizes" viewport="700x260" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Logo Lockups</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 22px 32px; background: var(--paper); display: grid; grid-template-columns: 1fr; gap: 18px; align-content: start; }
|
||||
.lock { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border: 1px solid var(--border); border-radius: 4px; }
|
||||
.lock img { width: 28px; height: 28px; }
|
||||
.lock .word { font: 500 18px var(--ff-sans); letter-spacing: -0.01em; }
|
||||
.lock .org { font: 400 14px var(--ff-mono); color: var(--fg-3); letter-spacing: 0.02em; }
|
||||
.lock .sep { color: var(--ink-5); }
|
||||
.lock.lg img { width: 36px; height: 36px; }
|
||||
.lock.lg .word { font-size: 22px; }
|
||||
.lock.foot { background: var(--ink); border-color: var(--ink); }
|
||||
.lock.foot img { filter: invert(1); }
|
||||
.lock.foot .word, .lock.foot .org, .lock.foot .sep { color: var(--paper); }
|
||||
.lock.foot .org, .lock.foot .sep { opacity: 0.55; }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 4px; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Lockups — mark + wordmark + organisation slug</div>
|
||||
<div class="lock lg"><img src="../assets/whynot-logo.png" alt=""><span class="word">whynot</span><span class="sep">/</span><span class="org">control</span></div>
|
||||
<div class="lock"><img src="../assets/whynot-logo.png" alt=""><span class="word">whynot</span><span class="sep">/</span><span class="org">prototypes</span></div>
|
||||
<div class="lock foot"><img src="../assets/whynot-logo.png" alt=""><span class="word">whynot</span><span class="sep">·</span><span class="org">2026 · A1 incubating</span></div>
|
||||
</body></html>
|
||||
21
designbook/preview/brand-logo.html
Normal file
21
designbook/preview/brand-logo.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Brand" name="Brand · Logo" subtitle="Primary · inverted · ?! wordmark" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Logo</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 20px 32px; background: var(--paper); display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 22px; align-items: center; }
|
||||
.cell { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 14px; }
|
||||
.cell.dark { background: var(--ink); border-radius: 4px; }
|
||||
.cell img { width: 120px; height: 120px; object-fit: contain; }
|
||||
.cell.dark img { filter: invert(1); }
|
||||
.cell .lbl { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.cell.dark .lbl { color: var(--fg-on-dark); opacity: 0.55; }
|
||||
.wordmark { font: 600 56px/1 var(--ff-sans); letter-spacing: -0.04em; color: var(--ink); }
|
||||
.wordmark .q { color: var(--ink); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="cell"><img src="../assets/whynot-logo.png" alt="whynot logo"><span class="lbl">Primary · black on white</span></div>
|
||||
<div class="cell dark"><img src="../assets/whynot-logo.png" alt="whynot logo"><span class="lbl">Inverted · white on black</span></div>
|
||||
<div class="cell"><div class="wordmark">?!</div><span class="lbl">Mini · ?! wordmark (favicon size)</span></div>
|
||||
</body></html>
|
||||
43
designbook/preview/brand-wireframe-motif.html
Normal file
43
designbook/preview/brand-wireframe-motif.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Brand" name="Brand · Wireframe Motif" subtitle="Graph paper + draft stamp" viewport="700x240" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Wireframe Motif</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 20px; background: var(--paper); margin: 0; }
|
||||
.frame {
|
||||
background: var(--paper-2);
|
||||
background-image:
|
||||
linear-gradient(to right, var(--border-soft) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, var(--border-soft) 1px, transparent 1px);
|
||||
background-size: 16px 16px;
|
||||
border: 1px solid var(--border);
|
||||
padding: 22px 24px;
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr;
|
||||
gap: 24px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.frame .stamp { background: var(--hi); color: var(--hi-ink); padding: 6px 10px 4px; font: 500 10px/1 var(--ff-mono); letter-spacing: 0.12em; text-transform: uppercase; transform: rotate(-1.5deg); display: inline-block; align-self: flex-start; }
|
||||
.frame .col { display: flex; flex-direction: column; gap: 12px; }
|
||||
.frame h4 { font: 500 18px/1.2 var(--ff-sans); margin: 0; }
|
||||
.frame .l { height: 10px; background: var(--ink-5); border-radius: 2px; opacity: 0.6; }
|
||||
.frame .l.s { width: 50% } .frame .l.m { width: 75% }
|
||||
.frame .l.x { width: 30% }
|
||||
.frame .meta { font: 500 11px var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="frame">
|
||||
<div class="col">
|
||||
<span class="stamp">Draft · WNO-014</span>
|
||||
<span class="meta">Stage 2 · Prototype</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>A field-notebook for catching weird ideas before they evaporate.</h4>
|
||||
<div class="l m"></div>
|
||||
<div class="l s"></div>
|
||||
<div class="l x"></div>
|
||||
<div class="l m"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
33
designbook/preview/colors-accent.html
Normal file
33
designbook/preview/colors-accent.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Colors" name="Colors · Accent" subtitle="Annotation yellow — highlighter only" viewport="700x200" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Accent — Annotation Yellow</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); display: grid; grid-template-columns: 1.1fr 1fr; gap: 28px; align-items: start; }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 10px; }
|
||||
.sw-row { display: flex; gap: 10px; }
|
||||
.sw { width: 84px; height: 64px; padding: 8px; display: flex; flex-direction: column; justify-content: flex-end; }
|
||||
.sw .name { font: 500 11px var(--ff-mono); }
|
||||
.sw .hex { font: 400 10px var(--ff-mono); color: var(--hi-ink); opacity: 0.6; }
|
||||
.usage { display: flex; flex-direction: column; gap: 10px; font-size: 13px; }
|
||||
.usage .row { display: flex; gap: 10px; align-items: baseline; }
|
||||
.stamp { display:inline-block; background: var(--hi); color: var(--hi-ink); padding: 4px 10px; font: 500 10px var(--ff-mono); letter-spacing: 0.12em; text-transform: uppercase; transform: rotate(-2deg); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div>
|
||||
<div class="row-label">Accent — used as highlighter, never as button fill</div>
|
||||
<div class="sw-row">
|
||||
<div class="sw" style="background:#FFE14A"><span class="name">--hi</span><span class="hex">#FFE14A</span></div>
|
||||
<div class="sw" style="background:#FFD400"><span class="name">--hi-2</span><span class="hex">#FFD400</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="row-label">Usage</div>
|
||||
<div class="usage">
|
||||
<div class="row"><span>Signals are <mark>evidence</mark>, not vibes.</span></div>
|
||||
<div class="row"><span class="stamp">Draft · S2</span></div>
|
||||
<div class="row" style="color: var(--fg-2); font-family: var(--ff-mono); font-size: 11px;">— only for marker / annotation / status</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
25
designbook/preview/colors-borders.html
Normal file
25
designbook/preview/colors-borders.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Colors" name="Colors · Borders" subtitle="Hairline · default · strong" viewport="700x180" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Borders & Lines</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
|
||||
.cell { background: var(--paper); padding: 14px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.cell .name { font: 500 12px var(--ff-mono); }
|
||||
.cell .hex { font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
.demo { height: 32px; display: flex; align-items: center; padding-left: 10px; font-size: 12px; color: var(--fg-2); }
|
||||
.d1 { border: 1px solid var(--border-soft); }
|
||||
.d2 { border: 1px solid var(--border); }
|
||||
.d3 { border: 1px solid var(--border-strong); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Lines — hairline · default · strong</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><div class="demo d1">soft hairline</div><span class="name">--border-soft</span><span class="hex">#F0F0EC · within cards</span></div>
|
||||
<div class="cell"><div class="demo d2">default border</div><span class="name">--border</span><span class="hex">#E5E5E2 · cards, inputs</span></div>
|
||||
<div class="cell"><div class="demo d3">strong divider</div><span class="name">--border-strong</span><span class="hex">#C9C9C5 · sections</span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
36
designbook/preview/colors-neutrals.html
Normal file
36
designbook/preview/colors-neutrals.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Colors" name="Colors · Neutrals" subtitle="Ink scale + paper surfaces" viewport="700x290" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Neutrals — Paper & Ink</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); }
|
||||
.group { display: flex; flex-direction: column; gap: 18px; }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
|
||||
.swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
|
||||
.sw { border: 1px solid var(--border); padding: 14px 12px; display: flex; flex-direction: column; gap: 6px; min-height: 72px; }
|
||||
.sw .name { font: 500 12px var(--ff-mono); letter-spacing: 0.02em; }
|
||||
.sw .hex { font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="group">
|
||||
<div>
|
||||
<div class="row-label">Ink — text & fills</div>
|
||||
<div class="swatches">
|
||||
<div class="sw" style="background:#0A0A0A;color:#FAFAF7"><span class="name">--ink</span><span class="hex" style="color:#9A9A98">#0A0A0A</span></div>
|
||||
<div class="sw" style="background:#1F1F1F;color:#FAFAF7"><span class="name">--ink-2</span><span class="hex" style="color:#9A9A98">#1F1F1F</span></div>
|
||||
<div class="sw" style="background:#5C5C5C;color:#FAFAF7"><span class="name">--ink-3</span><span class="hex" style="color:#C9C9C5">#5C5C5C</span></div>
|
||||
<div class="sw" style="background:#8A8A8A;color:#FAFAF7"><span class="name">--ink-4</span><span class="hex" style="color:#E5E5E2">#8A8A8A</span></div>
|
||||
<div class="sw" style="background:#B5B5B3"><span class="name">--ink-5</span><span class="hex">#B5B5B3</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="row-label">Paper — surfaces</div>
|
||||
<div class="swatches">
|
||||
<div class="sw" style="background:#FFFFFF"><span class="name">--paper</span><span class="hex">#FFFFFF</span></div>
|
||||
<div class="sw" style="background:#FAFAF7"><span class="name">--paper-2</span><span class="hex">#FAFAF7</span></div>
|
||||
<div class="sw" style="background:#F4F4EF"><span class="name">--paper-3</span><span class="hex">#F4F4EF</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
25
designbook/preview/colors-signal.html
Normal file
25
designbook/preview/colors-signal.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Colors" name="Colors · Signal Strength" subtitle="S0–S4 ramp, S4 uses accent" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Signal Strength Ramp</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 26px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.ramp { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
|
||||
.step { border: 1px solid var(--border); padding: 12px 12px 14px; min-height: 96px; display: flex; flex-direction: column; gap: 6px; }
|
||||
.step .dot { width: 14px; height: 14px; border-radius: 999px; }
|
||||
.step .lvl { font: 500 11px var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.step .name { font: 500 13px var(--ff-sans); color: var(--fg-1); }
|
||||
.step .meaning { font: 400 11px/1.35 var(--ff-sans); color: var(--fg-2); margin-top: auto; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Signal strength — desaturated, S4 only uses the accent</div>
|
||||
<div class="ramp">
|
||||
<div class="step"><span class="dot" style="background:#B5B5B3"></span><span class="lvl">S0</span><span class="name">No signal</span><span class="meaning">No observable interest or usefulness.</span></div>
|
||||
<div class="step"><span class="dot" style="background:#8A8A8A"></span><span class="lvl">S1</span><span class="name">Weak</span><span class="meaning">Some curiosity or informal interest.</span></div>
|
||||
<div class="step"><span class="dot" style="background:#5C5C5C"></span><span class="lvl">S2</span><span class="name">Medium</span><span class="meaning">Repeated interest, specific feedback.</span></div>
|
||||
<div class="step"><span class="dot" style="background:#0A0A0A"></span><span class="lvl">S3</span><span class="name">Strong</span><span class="meaning">Action, return, referral, contribution.</span></div>
|
||||
<div class="step"><span class="dot" style="background:#FFD400"></span><span class="lvl">S4</span><span class="name">Commercial</span><span class="meaning">Payment, pre-order, budget commit.</span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
31
designbook/preview/colors-status-functional.html
Normal file
31
designbook/preview/colors-status-functional.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Colors" name="Colors · Functional Status" subtitle="Error / warn / success / info — borders & dots only" viewport="700x280" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Functional Status Colours</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
|
||||
.sw { padding: 12px 12px 14px; min-height: 92px; display: flex; flex-direction: column; gap: 6px; background: var(--paper); border-left: 2px solid; position: relative; }
|
||||
.sw .dot { width: 10px; height: 10px; border-radius: 999px; position: absolute; right: 12px; top: 12px; }
|
||||
.sw .name { font: 500 13px var(--ff-sans); color: var(--fg-1); }
|
||||
.sw .tok { font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
.sw .hex { font: 400 11px var(--ff-mono); color: var(--fg-3); margin-top: auto; }
|
||||
.e { border-color: var(--status-error); } .e .dot { background: var(--status-error); }
|
||||
.w { border-color: var(--status-warn); background: var(--status-warn-bg); }
|
||||
.w .dot { background: var(--status-warn); }
|
||||
.s { border-color: var(--status-success); } .s .dot { background: var(--status-success); }
|
||||
.i { border-color: var(--status-info); } .i .dot { background: var(--status-info); }
|
||||
.caveat { font: 400 11px/1.45 var(--ff-mono); color: var(--fg-3); margin-top: 4px; max-width: 64ch; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Functional status — borders + dots only, never fills</div>
|
||||
<div class="grid">
|
||||
<div class="sw e"><span class="dot"></span><span class="name">Error</span><span class="tok">--status-error</span><span class="hex">#B33A2E · brick red</span></div>
|
||||
<div class="sw w"><span class="dot"></span><span class="name">Warning</span><span class="tok">--status-warn</span><span class="hex">#C28000 · deep mustard</span></div>
|
||||
<div class="sw s"><span class="dot"></span><span class="name">Success</span><span class="tok">--status-success</span><span class="hex">#2F6B3A · muted forest</span></div>
|
||||
<div class="sw i"><span class="dot"></span><span class="name">Info</span><span class="tok">--status-info</span><span class="hex">#2E5C8A · muted ink-blue</span></div>
|
||||
</div>
|
||||
<p class="caveat">Distinct from S0–S4 signal strength. Use sparingly: a 2px left-border on banners, a small dot next to status text, or as <code class="mono">currentColor</code> on an icon. If even this feels too colourful for a context, fall back to ink and the existing yellow accent — the system still parses without these.</p>
|
||||
</body></html>
|
||||
40
designbook/preview/comp-buttons.html
Normal file
40
designbook/preview/comp-buttons.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Buttons" subtitle="Primary · secondary · ghost" viewport="700x240" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Buttons</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 16px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(4, max-content); gap: 12px 14px; align-items: center; }
|
||||
.col-h { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.row-h { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.btn { font: 500 13px var(--ff-sans); letter-spacing: -0.005em; padding: 9px 16px; border-radius: var(--r-2); border: 1px solid transparent; cursor: pointer; transition: background 120ms ease, border-color 120ms ease, color 120ms ease; }
|
||||
.btn.primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
|
||||
.btn.primary.hover { background: var(--ink-2); border-color: var(--ink-2); }
|
||||
.btn.primary.disabled { background: var(--ink-5); border-color: var(--ink-5); color: var(--paper); cursor: not-allowed; }
|
||||
.btn.secondary { background: var(--paper); color: var(--ink); border-color: var(--border); }
|
||||
.btn.secondary.hover { border-color: var(--ink); }
|
||||
.btn.secondary.disabled { color: var(--ink-5); border-color: var(--border); cursor: not-allowed; }
|
||||
.btn.ghost { background: transparent; color: var(--ink); border-color: transparent; padding-left: 8px; padding-right: 8px; }
|
||||
.btn.ghost.hover { background: var(--paper-3); }
|
||||
.btn.ghost.disabled { color: var(--ink-5); cursor: not-allowed; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Buttons — primary · secondary · ghost</div>
|
||||
<div class="grid">
|
||||
<div></div><div class="col-h">Default</div><div class="col-h">Hover</div><div class="col-h">Disabled</div>
|
||||
<div class="row-h">Primary</div>
|
||||
<button class="btn primary">Promote prototype</button>
|
||||
<button class="btn primary hover">Promote prototype</button>
|
||||
<button class="btn primary disabled">Promote prototype</button>
|
||||
<div class="row-h">Secondary</div>
|
||||
<button class="btn secondary">Park</button>
|
||||
<button class="btn secondary hover">Park</button>
|
||||
<button class="btn secondary disabled">Park</button>
|
||||
<div class="row-h">Ghost</div>
|
||||
<button class="btn ghost">View signal</button>
|
||||
<button class="btn ghost hover">View signal</button>
|
||||
<button class="btn ghost disabled">View signal</button>
|
||||
</div>
|
||||
</body></html>
|
||||
38
designbook/preview/comp-empty-placeholder.html
Normal file
38
designbook/preview/comp-empty-placeholder.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Empty State" subtitle="Dashed border · wireframe lines" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Empty / Placeholder State</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 12px; }
|
||||
.empty { border: 1px dashed var(--border-strong); padding: 24px; min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; color: var(--fg-3); }
|
||||
.empty .ttl { font: 500 13px var(--ff-sans); color: var(--fg-2); }
|
||||
.empty .sub { font: 400 12px/1.4 var(--ff-mono); color: var(--fg-3); }
|
||||
.empty .cta { font: 500 12px var(--ff-mono); color: var(--fg-1); text-decoration: underline; text-underline-offset: 3px; }
|
||||
.wire { display: flex; flex-direction: column; gap: 10px; padding: 18px; border: 1px solid var(--border); }
|
||||
.wire .l { height: 10px; background: var(--paper-3); border-radius: 2px; }
|
||||
.wire .l.s { width: 60% }
|
||||
.wire .l.m { width: 80% }
|
||||
.wire .l.x { width: 40% }
|
||||
</style></head>
|
||||
<body>
|
||||
<div>
|
||||
<div class="row-label">Empty — dashed border + caption</div>
|
||||
<div class="empty">
|
||||
<div class="ttl">No signals yet.</div>
|
||||
<div class="sub">Lack of signal is also information.</div>
|
||||
<a href="#" class="cta">Record a signal →</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="row-label">Wireframe — placeholder content</div>
|
||||
<div class="wire">
|
||||
<div class="l m"></div>
|
||||
<div class="l s"></div>
|
||||
<div class="l x"></div>
|
||||
<div class="l m"></div>
|
||||
<div class="l s"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
30
designbook/preview/comp-inputs.html
Normal file
30
designbook/preview/comp-inputs.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Inputs" subtitle="Default · focus · error" viewport="700x280" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Inputs & Form Fields</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 26px 32px; background: var(--paper); display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 12px; }
|
||||
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
|
||||
.field label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.input { font: 400 14px var(--ff-sans); padding: 10px 12px; border: 1px solid var(--border); background: var(--paper); border-radius: var(--r-1); color: var(--fg-1); outline: none; }
|
||||
.input.focus { border-color: var(--ink); }
|
||||
.input.error { border-color: var(--ink); border-bottom-width: 2px; }
|
||||
.input::placeholder { color: var(--ink-5); }
|
||||
.help { font-size: 11px; color: var(--fg-3); font-family: var(--ff-mono); }
|
||||
.err { font-size: 11px; color: var(--ink); font-family: var(--ff-mono); }
|
||||
textarea.input { resize: none; min-height: 64px; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div>
|
||||
<div class="row-label">Text · Default / Focus</div>
|
||||
<div class="field"><label>Prototype name</label><input class="input" placeholder="e.g. relevant-coronapolitics-timeline" /></div>
|
||||
<div class="field"><label>One-line pitch</label><input class="input focus" value="Discover the weird and the useful." /><span class="help">120 char limit · plain sentence</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="row-label">Textarea · Error</div>
|
||||
<div class="field"><label>Learning question</label><textarea class="input">What would we need to learn to know whether this idea deserves another step?</textarea></div>
|
||||
<div class="field"><label>Smallest useful test</label><input class="input error" value="" /><span class="err">Required — describe in one sentence.</span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
44
designbook/preview/comp-labels-tags.html
Normal file
44
designbook/preview/comp-labels-tags.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Labels & Tags" subtitle="Stage tags · signal dots" viewport="700x200" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Labels & Tags</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.stack { display: flex; flex-direction: column; gap: 18px; }
|
||||
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
|
||||
.tag { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 10px; border-radius: var(--r-pill); border: 1px solid var(--border); color: var(--fg-2); background: var(--paper); }
|
||||
.tag.active { color: var(--paper); background: var(--ink); border-color: var(--ink); }
|
||||
.tag.draft { background: var(--hi); color: var(--hi-ink); border-color: transparent; }
|
||||
.stage { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 10px; color: var(--fg-2); display: inline-flex; align-items: center; gap: 6px; }
|
||||
.stage .dot { width: 8px; height: 8px; border-radius: 999px; background: var(--ink); }
|
||||
.stage.s0 .dot { background: #B5B5B3 } .stage.s1 .dot { background: #8A8A8A }
|
||||
.stage.s2 .dot { background: #5C5C5C } .stage.s3 .dot { background: #0A0A0A }
|
||||
.stage.s4 .dot { background: #FFD400 }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="stack">
|
||||
<div>
|
||||
<div class="row-label">Tags — default · active · draft</div>
|
||||
<div class="row">
|
||||
<span class="tag">Raw Idea</span>
|
||||
<span class="tag">Prototype Candidate</span>
|
||||
<span class="tag active">Experiment</span>
|
||||
<span class="tag">Promotion Candidate</span>
|
||||
<span class="tag">Parked</span>
|
||||
<span class="tag draft">Draft</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="row-label">Signal dots — inline indicator</div>
|
||||
<div class="row">
|
||||
<span class="stage s0"><span class="dot"></span>S0 · No signal</span>
|
||||
<span class="stage s1"><span class="dot"></span>S1 · Weak</span>
|
||||
<span class="stage s2"><span class="dot"></span>S2 · Medium</span>
|
||||
<span class="stage s3"><span class="dot"></span>S3 · Strong</span>
|
||||
<span class="stage s4"><span class="dot"></span>S4 · Commercial</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
85
designbook/preview/comp-left-nav.html
Normal file
85
designbook/preview/comp-left-nav.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Left Navigation" subtitle="Grouped sidebar · active state · minimal variant" viewport="700x420" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Left Navigation</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { margin: 0; padding: 20px; background: var(--paper); display: flex; gap: 28px; align-items: stretch; }
|
||||
.frame { display: flex; flex-direction: column; gap: 8px; }
|
||||
.frame > .cap { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); padding-left: 12px; }
|
||||
.leftnav {
|
||||
width: 220px; box-sizing: border-box;
|
||||
display: flex; flex-direction: column; gap: 28px;
|
||||
padding: 24px 8px 24px 12px;
|
||||
border-right: 1px solid var(--line-soft);
|
||||
min-height: 360px;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 8px; padding: 0 10px; }
|
||||
.brand img { width: 20px; height: 20px; }
|
||||
.brand .nm { font: 500 14px var(--ff-sans); color: var(--fg-1); }
|
||||
.brand .slug { font: 400 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.body { display: flex; flex-direction: column; gap: 28px; flex: 1; }
|
||||
.section { display: flex; flex-direction: column; gap: 8px; }
|
||||
.section .lbl { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); padding-left: 12px; opacity: 0.7; }
|
||||
.items { display: flex; flex-direction: column; gap: 1px; }
|
||||
.item {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 6px 10px; border-left: 2px solid transparent;
|
||||
color: var(--fg-3); font: 400 13px var(--ff-sans); cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.item .ic { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.5; fill: none; flex: none; }
|
||||
.item .t { flex: 1; }
|
||||
.item .n { margin-left: auto; font: 400 11px var(--ff-mono); color: var(--ink-5); }
|
||||
.item.active { color: var(--fg-1); font-weight: 500; border-left-color: var(--ink); }
|
||||
.item.active .n { color: var(--fg-3); }
|
||||
.item.doc { font: 400 12px var(--ff-mono); }
|
||||
.footer { margin-top: auto; display: flex; align-items: center; gap: 8px; padding: 0 12px; font: 400 11px var(--ff-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.footer .dot { width: 5px; height: 5px; border-radius: 999px; background: var(--ink-4); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="frame">
|
||||
<span class="cap">Default · grouped, with active state</span>
|
||||
<nav class="leftnav">
|
||||
<div class="brand"><img src="../assets/whynot-logo.png" alt=""><span class="nm">whynot</span><span class="slug">/ control</span></div>
|
||||
<div class="body">
|
||||
<div class="section">
|
||||
<span class="lbl">Work</span>
|
||||
<div class="items">
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg><span class="t">Inbox</span><span class="n">7</span></a>
|
||||
<a class="item active"><svg class="ic" viewBox="0 0 24 24"><path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"/><path d="M6.453 15h11.094"/><path d="M8.5 2h7"/></svg><span class="t">Prototypes</span><span class="n">4</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.5.5 0 0 1-.96 0L9.24 2.18a.5.5 0 0 0-.96 0l-2.35 8.36A2 2 0 0 1 4 12H2"/></svg><span class="t">Signals</span><span class="n">12</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/><path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/></svg><span class="t">Betas</span><span class="n">1</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg><span class="t">Decisions</span><span class="n">3</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<span class="lbl">Control docs</span>
|
||||
<div class="items">
|
||||
<a class="item doc"><span class="t">INTENT.md</span></a>
|
||||
<a class="item doc"><span class="t">SCOPE.md</span></a>
|
||||
<a class="item doc"><span class="t">OPERATING_MODEL.md</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer"><span class="dot"></span><span>A1 · Incubating</span></div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="frame">
|
||||
<span class="cap">Minimal · no brand, no icons</span>
|
||||
<nav class="leftnav" style="min-height: 360px;">
|
||||
<div class="body">
|
||||
<div class="section">
|
||||
<span class="lbl">Navigate</span>
|
||||
<div class="items">
|
||||
<a class="item active"><span class="t">Overview</span></a>
|
||||
<a class="item"><span class="t">Prototypes</span><span class="n">4</span></a>
|
||||
<a class="item"><span class="t">Signals</span><span class="n">12</span></a>
|
||||
<a class="item"><span class="t">Settings</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</body></html>
|
||||
30
designbook/preview/comp-pipeline.html
Normal file
30
designbook/preview/comp-pipeline.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Pipeline" subtitle="Lifecycle stage tracker" viewport="700x180" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Pipeline / Lifecycle</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 22px; }
|
||||
.pipeline { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; position: relative; }
|
||||
.stage { padding: 10px 12px 14px; border-top: 2px solid var(--border); display: flex; flex-direction: column; gap: 4px; position: relative; }
|
||||
.stage.done { border-top-color: var(--ink); }
|
||||
.stage.active { border-top-color: var(--hi-2); }
|
||||
.stage .num { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.stage.done .num, .stage.active .num { color: var(--fg-1); }
|
||||
.stage .name { font: 500 14px/1.25 var(--ff-sans); color: var(--fg-1); }
|
||||
.stage.pending .name { color: var(--fg-3); }
|
||||
.stage .meta { font: 400 11px/1.35 var(--ff-mono); color: var(--fg-3); }
|
||||
.arrow { position: absolute; top: -8px; right: -7px; font: 400 14px var(--ff-mono); color: var(--ink-5); }
|
||||
.stage.active .arrow, .stage.done .arrow { color: var(--ink); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Pipeline — Raw → Candidate → Experiment → Signal → Decision</div>
|
||||
<div class="pipeline">
|
||||
<div class="stage done"><span class="num">Stage 0</span><span class="name">Raw idea</span><span class="meta">inbox/</span></div>
|
||||
<div class="stage done"><span class="num">Stage 1</span><span class="name">Triage</span><span class="meta">2026-02-12</span><span class="arrow">→</span></div>
|
||||
<div class="stage done"><span class="num">Stage 2</span><span class="name">Prototype card</span><span class="meta">prototypes/</span><span class="arrow">→</span></div>
|
||||
<div class="stage active"><span class="num">Stage 3</span><span class="name">Experiment</span><span class="meta">ends 2026-04-01</span><span class="arrow">→</span></div>
|
||||
<div class="stage pending"><span class="num">Stage 4</span><span class="name">Signal review</span><span class="meta">— pending</span><span class="arrow">→</span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
46
designbook/preview/comp-prototype-card.html
Normal file
46
designbook/preview/comp-prototype-card.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Prototype Card" subtitle="Default + hover (black left bar)" viewport="700x290" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Prototype Card</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper-2); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||
.card { background: var(--paper); border: 1px solid var(--border); border-radius: var(--r-2); padding: 20px 22px; display: flex; flex-direction: column; gap: 10px; position: relative; }
|
||||
.card.hover::before { content:""; position: absolute; left: -1px; top: -1px; bottom: -1px; width: 2px; background: var(--ink); }
|
||||
.head { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.meta { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.head .stage { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-2); display: inline-flex; align-items: center; gap: 6px; }
|
||||
.head .stage .dot { width: 8px; height: 8px; border-radius: 999px; background: #5C5C5C; }
|
||||
.pitch { font: 500 17px/1.35 var(--ff-sans); margin: 4px 0 8px; }
|
||||
.qrow { display: flex; gap: 8px; font-size: 13px; color: var(--fg-2); }
|
||||
.qrow .k { color: var(--fg-3); font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; min-width: 96px; flex: none; padding-top: 2px; }
|
||||
.qrow .v { color: var(--fg-1); }
|
||||
.foot { display: flex; justify-content: space-between; padding-top: 12px; margin-top: 4px; border-top: 1px solid var(--border-soft); font-size: 12px; color: var(--fg-3); font-family: var(--ff-mono); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Prototype card — default · hover</div>
|
||||
<div class="grid">
|
||||
<article class="card">
|
||||
<div class="head">
|
||||
<span class="meta">WNO-014 · Prototype</span>
|
||||
<span class="stage"><span class="dot"></span>Experiment</span>
|
||||
</div>
|
||||
<h3 class="pitch">A pocket field-notebook for catching weird ideas before they evaporate.</h3>
|
||||
<div class="qrow"><span class="k">Learning q.</span><span class="v">Do people return to capture more than once?</span></div>
|
||||
<div class="qrow"><span class="k">Smallest test</span><span class="v">One-page landing + email capture, 14 days.</span></div>
|
||||
<div class="foot"><span>→ Coulomb</span><span>S1 · weak</span></div>
|
||||
</article>
|
||||
<article class="card hover">
|
||||
<div class="head">
|
||||
<span class="meta" style="color: var(--fg-1)">WNO-017 · Prototype</span>
|
||||
<span class="stage"><span class="dot" style="background:#0A0A0A"></span>Signal review</span>
|
||||
</div>
|
||||
<h3 class="pitch">A LEGO-brick mood board for engineers who don't think in mood boards.</h3>
|
||||
<div class="qrow"><span class="k">Learning q.</span><span class="v">Will engineers attach metaphors to their tickets?</span></div>
|
||||
<div class="qrow"><span class="k">Smallest test</span><span class="v">Slack bot, three teams, two weeks.</span></div>
|
||||
<div class="foot"><span>→ Helix</span><span>S3 · strong</span></div>
|
||||
</article>
|
||||
</div>
|
||||
</body></html>
|
||||
37
designbook/preview/comp-topnav.html
Normal file
37
designbook/preview/comp-topnav.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Components" name="Components · Top Navigation" subtitle="56px · 1px hairline · ⌘K search" viewport="900x160" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Top Navigation</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { margin: 0; background: var(--paper-2); font-family: var(--ff-sans); min-height: 200px; }
|
||||
.nav { height: 56px; background: rgba(255,255,255,0.92); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 32px; padding: 0 24px; }
|
||||
.brand { display: flex; align-items: center; gap: 10px; font: 500 14px var(--ff-sans); }
|
||||
.brand img { width: 22px; height: 22px; }
|
||||
.brand .org { font-family: var(--ff-mono); font-size: 12px; color: var(--fg-3); letter-spacing: 0.04em; }
|
||||
.links { display: flex; gap: 22px; }
|
||||
.links a { font: 500 13px var(--ff-sans); color: var(--fg-2); text-decoration: none; padding: 6px 0; border-bottom: 1px solid transparent; }
|
||||
.links a.active { color: var(--fg-1); border-bottom-color: var(--ink); }
|
||||
.right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
|
||||
.right .search { font: 400 12px var(--ff-mono); color: var(--fg-3); border: 1px solid var(--border); padding: 6px 10px; border-radius: var(--r-1); display: flex; align-items: center; gap: 8px; min-width: 200px; }
|
||||
.right .kbd { margin-left: auto; padding: 1px 5px; border: 1px solid var(--border); border-radius: 2px; font-size: 10px; }
|
||||
.right .btn { font: 500 12px var(--ff-sans); padding: 7px 12px; border-radius: var(--r-2); border: 1px solid var(--ink); background: var(--ink); color: var(--paper); cursor: pointer; }
|
||||
.body-preview { padding: 32px 24px; color: var(--fg-3); font: 400 13px var(--ff-mono); }
|
||||
</style></head>
|
||||
<body>
|
||||
<nav class="nav">
|
||||
<div class="brand"><img src="../assets/whynot-logo.png" alt=""><span>whynot</span><span class="org">/ control</span></div>
|
||||
<div class="links">
|
||||
<a class="active" href="#">Inbox</a>
|
||||
<a href="#">Prototypes</a>
|
||||
<a href="#">Signals</a>
|
||||
<a href="#">Betas</a>
|
||||
<a href="#">Decisions</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="search"><span>Search…</span><span class="kbd">⌘ K</span></div>
|
||||
<button class="btn">+ New idea</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="body-preview">// 56px height · 1px hairline · rgba(255,255,255,0.92) when scrolled</div>
|
||||
</body></html>
|
||||
104
designbook/preview/page-beta-invitation.html
Normal file
104
designbook/preview/page-beta-invitation.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Pages" name="Pages · Closed-beta invitation" subtitle="Invitation-only · seats, dates, accept / decline" viewport="1280x860" -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>You're invited · whynot closed beta</title>
|
||||
<link rel="icon" href="../assets/whynot-logo.png">
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
html, body { margin: 0; min-height: 100%; background: var(--paper); color: var(--fg-1); }
|
||||
.page { min-height: 100vh; display: flex; flex-direction: column; }
|
||||
|
||||
.nav { height: 60px; flex: none; display: flex; align-items: center; gap: 16px; padding: 0 40px; border-bottom: 1px solid var(--line); }
|
||||
.nav .brand { display: flex; align-items: center; gap: 10px; }
|
||||
.nav .brand img { width: 22px; height: 22px; }
|
||||
.nav .brand .nm { font: 500 15px var(--ff-sans); letter-spacing: -0.01em; }
|
||||
.nav .brand .slug { font: 400 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.nav .pill { margin-left: auto; font: 500 11px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); border: 1px solid var(--line); border-radius: 999px; padding: 6px 11px; }
|
||||
|
||||
.wrap {
|
||||
flex: 1; display: flex; align-items: center; justify-content: center;
|
||||
padding: 48px 24px;
|
||||
background:
|
||||
linear-gradient(to right, var(--line-soft) 1px, transparent 1px) 0 0 / 28px 28px,
|
||||
linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px) 0 0 / 28px 28px,
|
||||
var(--paper-2);
|
||||
}
|
||||
|
||||
.invite {
|
||||
width: 100%; max-width: 560px; background: var(--paper);
|
||||
border: 1px solid var(--line-strong); border-radius: var(--r-3);
|
||||
padding: 40px 44px 36px; position: relative;
|
||||
}
|
||||
.stamp {
|
||||
position: absolute; top: -14px; right: 28px;
|
||||
background: var(--hi); color: var(--hi-ink);
|
||||
font: 500 10px/1 var(--ff-mono); letter-spacing: 0.12em; text-transform: uppercase;
|
||||
padding: 7px 12px 5px; transform: rotate(-2deg);
|
||||
}
|
||||
.invite .eyebrow { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.invite h1 { font: 400 30px/1.2 var(--ff-sans); letter-spacing: -0.02em; margin: 12px 0 0; max-width: 18ch; }
|
||||
.invite .lede { font: 400 16px/1.6 var(--ff-sans); color: var(--fg-2); margin: 14px 0 0; max-width: 46ch; }
|
||||
|
||||
.specs { margin: 28px 0 0; border-top: 1px solid var(--line); }
|
||||
.spec { display: grid; grid-template-columns: 150px 1fr; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--line-soft); align-items: baseline; }
|
||||
.spec .k { font: 500 11px/1.4 var(--ff-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.spec .v { font: 400 14px/1.5 var(--ff-sans); color: var(--fg-1); }
|
||||
.spec .v .mono { font-family: var(--ff-mono); }
|
||||
|
||||
.actions { display: flex; align-items: center; gap: 12px; margin-top: 28px; }
|
||||
.btn { font: 500 14px var(--ff-sans); padding: 12px 20px; border-radius: var(--r-2); border: 1px solid var(--ink); background: var(--ink); color: var(--paper); cursor: pointer; }
|
||||
.btn:hover { background: var(--ink-2); }
|
||||
.btn.ghost { background: transparent; color: var(--fg-2); border-color: transparent; padding: 12px 10px; }
|
||||
.btn.ghost:hover { color: var(--fg-1); background: var(--paper-3); }
|
||||
.actions .seats { margin-left: auto; font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
|
||||
.note { margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line-soft); font: 400 12px/1.6 var(--ff-mono); color: var(--fg-3); }
|
||||
.note b { color: var(--fg-2); font-weight: 500; }
|
||||
|
||||
.footer { flex: none; padding: 18px 40px; border-top: 1px solid var(--line); display: flex; gap: 14px; font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
.footer .sp { margin-left: auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<nav class="nav">
|
||||
<div class="brand"><img src="../assets/whynot-logo.png" alt=""><span class="nm">whynot</span><span class="slug">/ betas</span></div>
|
||||
<span class="pill">Closed beta · invitation only</span>
|
||||
</nav>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="invite">
|
||||
<span class="stamp">Invitation · WNO-021</span>
|
||||
<span class="eyebrow">You’re invited</span>
|
||||
<h1>Concierge prototype triage</h1>
|
||||
<p class="lede">A one-hour call where we take one of your half-formed ideas and turn it into a testable prototype card — learning question, smallest useful test, and all.</p>
|
||||
|
||||
<div class="specs">
|
||||
<div class="spec"><span class="k">Learning question</span><span class="v">Will three founders pay a listed price for a single triage call?</span></div>
|
||||
<div class="spec"><span class="k">What you do</span><span class="v">Bring one idea. Leave with a prototype card and a next step.</span></div>
|
||||
<div class="spec"><span class="k">Seats</span><span class="v">5 · <span class="mono">2 remaining</span></span></div>
|
||||
<div class="spec"><span class="k">Window</span><span class="v"><span class="mono">2026-04-01 → 2026-04-14</span></span></div>
|
||||
<div class="spec"><span class="k">Cost</span><span class="v">Listed price. No refunds, no obligations after.</span></div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="btn">Accept invitation</button>
|
||||
<button class="btn ghost">Not now</button>
|
||||
<span class="seats">Expires in 6 days</span>
|
||||
</div>
|
||||
|
||||
<p class="note"><b>Invitation only.</b> This is a prototype, not a product — it may be parked after the beta regardless of how it goes. Accepting reserves a seat; it is not a commitment to continue.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<span>whynot · betas</span>
|
||||
<span>·</span>
|
||||
<span>BETA_MODEL.md</span>
|
||||
<span class="sp">try($idea) until success;</span>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
224
designbook/preview/page-landing-auth.html
Normal file
224
designbook/preview/page-landing-auth.html
Normal file
@@ -0,0 +1,224 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Pages" name="Pages · Landing — Login & Registration" subtitle="Public landing · log in / request access toggle" viewport="1280x820" -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>whynot — landing</title>
|
||||
<link rel="icon" href="../assets/whynot-logo.png">
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; background: var(--paper); color: var(--fg-1); }
|
||||
|
||||
/* faint engineering-graph backdrop, very subtle */
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
display: flex; flex-direction: column;
|
||||
}
|
||||
|
||||
/* ---- top nav ---- */
|
||||
.nav {
|
||||
height: 60px; flex: none;
|
||||
display: flex; align-items: center; gap: 24px;
|
||||
padding: 0 40px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.nav .brand { display: flex; align-items: center; gap: 10px; }
|
||||
.nav .brand img { width: 24px; height: 24px; }
|
||||
.nav .brand .nm { font: 500 15px var(--ff-sans); letter-spacing: -0.01em; }
|
||||
.nav .brand .slug { font: 400 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.nav .links { margin-left: auto; display: flex; align-items: center; gap: 24px; }
|
||||
.nav .links a { font: 500 13px var(--ff-sans); color: var(--fg-2); text-decoration: none; }
|
||||
.nav .links a:hover { color: var(--fg-1); }
|
||||
.nav .pill {
|
||||
font: 500 11px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase;
|
||||
color: var(--fg-3); border: 1px solid var(--line); border-radius: 999px; padding: 6px 11px;
|
||||
}
|
||||
|
||||
/* ---- hero split ---- */
|
||||
.hero {
|
||||
flex: 1; display: grid; grid-template-columns: 1.15fr 0.85fr;
|
||||
align-items: stretch;
|
||||
}
|
||||
.pitch {
|
||||
padding: 72px 56px 56px 40px;
|
||||
display: flex; flex-direction: column; gap: 24px;
|
||||
border-right: 1px solid var(--line);
|
||||
background:
|
||||
linear-gradient(to right, var(--line-soft) 1px, transparent 1px) 0 0 / 28px 28px,
|
||||
linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px) 0 0 / 28px 28px,
|
||||
var(--paper-2);
|
||||
}
|
||||
.eyebrow-lg { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.pitch h1 {
|
||||
font: 300 64px/0.98 var(--ff-sans); letter-spacing: -0.035em;
|
||||
margin: 4px 0 0; color: var(--ink);
|
||||
max-width: 13ch;
|
||||
}
|
||||
.pitch h1 .q { font-weight: 500; }
|
||||
.pitch .lede { font: 400 18px/1.55 var(--ff-sans); color: var(--fg-2); margin: 0; max-width: 42ch; }
|
||||
.codeline {
|
||||
font: 500 14px var(--ff-mono); color: var(--fg-1);
|
||||
background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-2);
|
||||
padding: 12px 16px; align-self: flex-start;
|
||||
}
|
||||
.codeline .c { color: var(--ink-4); }
|
||||
.codeline mark { background: var(--hi); color: var(--hi-ink); padding: 0 3px; }
|
||||
|
||||
.principles { margin-top: auto; display: flex; flex-direction: column; gap: 0; }
|
||||
.principles .p {
|
||||
display: grid; grid-template-columns: 28px 1fr; gap: 14px;
|
||||
padding: 16px 0; border-top: 1px solid var(--line);
|
||||
align-items: baseline;
|
||||
}
|
||||
.principles .p .k { font: 500 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.principles .p .v { font: 400 14px/1.5 var(--ff-sans); color: var(--fg-2); }
|
||||
.principles .p .v b { color: var(--fg-1); font-weight: 500; }
|
||||
|
||||
/* ---- auth panel ---- */
|
||||
.auth {
|
||||
padding: 72px 40px 56px 56px;
|
||||
display: flex; flex-direction: column;
|
||||
max-width: 480px;
|
||||
}
|
||||
.auth .tabs { display: flex; gap: 0; border-bottom: 1px solid var(--line); margin-bottom: 28px; }
|
||||
.auth .tab {
|
||||
font: 500 13px var(--ff-sans); color: var(--fg-3); background: none; border: 0;
|
||||
padding: 0 0 12px; margin-right: 28px; cursor: pointer;
|
||||
border-bottom: 2px solid transparent; margin-bottom: -1px;
|
||||
}
|
||||
.auth .tab.active { color: var(--fg-1); border-bottom-color: var(--ink); }
|
||||
|
||||
.form { display: flex; flex-direction: column; gap: 18px; }
|
||||
.form.hidden { display: none; }
|
||||
.field { display: flex; flex-direction: column; gap: 7px; }
|
||||
.field label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.field input, .field textarea {
|
||||
font: 400 14px var(--ff-sans); color: var(--fg-1);
|
||||
padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-1);
|
||||
background: var(--paper); outline: none; transition: border-color 120ms ease;
|
||||
}
|
||||
.field input:focus, .field textarea:focus { border-color: var(--ink); }
|
||||
.field input::placeholder, .field textarea::placeholder { color: var(--ink-5); }
|
||||
.field textarea { resize: none; min-height: 76px; font-family: var(--ff-sans); }
|
||||
.field .row { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.field .row a { font: 400 11px var(--ff-mono); color: var(--fg-3); text-decoration: none; }
|
||||
.field .row a:hover { color: var(--fg-1); text-decoration: underline; }
|
||||
|
||||
.btn {
|
||||
font: 500 14px var(--ff-sans); padding: 12px 18px; border-radius: var(--r-2);
|
||||
border: 1px solid var(--ink); background: var(--ink); color: var(--paper);
|
||||
cursor: pointer; transition: background 120ms ease; margin-top: 4px;
|
||||
}
|
||||
.btn:hover { background: var(--ink-2); }
|
||||
|
||||
.note {
|
||||
font: 400 12px/1.5 var(--ff-mono); color: var(--fg-3);
|
||||
margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line-soft);
|
||||
}
|
||||
.note b { color: var(--fg-2); font-weight: 500; }
|
||||
|
||||
.footer {
|
||||
flex: none; padding: 18px 40px; border-top: 1px solid var(--line);
|
||||
display: flex; align-items: center; gap: 16px;
|
||||
font: 400 11px var(--ff-mono); color: var(--fg-3); letter-spacing: 0.04em;
|
||||
}
|
||||
.footer .dot { width: 5px; height: 5px; border-radius: 999px; background: var(--ink-4); }
|
||||
.footer .sp { margin-left: auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
|
||||
<nav class="nav">
|
||||
<div class="brand">
|
||||
<img src="../assets/whynot-logo.png" alt="">
|
||||
<span class="nm">whynot</span>
|
||||
<span class="slug">/ prototypes</span>
|
||||
</div>
|
||||
<div class="links">
|
||||
<span class="pill">A1 · Incubating</span>
|
||||
<a href="#" onclick="show('login');return false;">Log in</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="hero">
|
||||
|
||||
<!-- left: pitch -->
|
||||
<section class="pitch">
|
||||
<span class="eyebrow-lg">Prototype & market-signal space</span>
|
||||
<h1>why<span class="q">?</span> why not<span class="q">!</span></h1>
|
||||
<p class="lede">A quiet workshop for discovering the weird and the useful — building, testing, and reviewing prototypes before they ever pretend to be products.</p>
|
||||
<div class="codeline"><span class="c">$</span> try(<mark>$idea</mark>) until success<span class="c">;</span></div>
|
||||
|
||||
<div class="principles">
|
||||
<div class="p"><span class="k">01</span><span class="v"><b>A prototype is a question made tangible.</b> Not a promise.</span></div>
|
||||
<div class="p"><span class="k">02</span><span class="v"><b>Signal beats enthusiasm.</b> Evidence, not vibes.</span></div>
|
||||
<div class="p"><span class="k">03</span><span class="v"><b>Capture is not commitment.</b> A good idea can still be parked.</span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- right: auth -->
|
||||
<section class="auth">
|
||||
<div class="tabs">
|
||||
<button class="tab active" id="tab-login" onclick="show('login')">Log in</button>
|
||||
<button class="tab" id="tab-register" onclick="show('register')">Request access</button>
|
||||
</div>
|
||||
|
||||
<form class="form" id="form-login" onsubmit="return false;">
|
||||
<div class="field">
|
||||
<label for="li-email">Email</label>
|
||||
<input id="li-email" type="email" placeholder="you@example.com" autocomplete="username">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="row">
|
||||
<label for="li-pw">Password</label>
|
||||
<a href="#" onclick="return false;">Forgot?</a>
|
||||
</div>
|
||||
<input id="li-pw" type="password" placeholder="••••••••" autocomplete="current-password">
|
||||
</div>
|
||||
<button class="btn" type="submit">Log in</button>
|
||||
<p class="note">Access is limited to current contributors and invited beta participants. <b>No public sign-ups.</b></p>
|
||||
</form>
|
||||
|
||||
<form class="form hidden" id="form-register" onsubmit="return false;">
|
||||
<div class="field">
|
||||
<label for="rg-name">Name</label>
|
||||
<input id="rg-name" type="text" placeholder="What should we call you?">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="rg-email">Email</label>
|
||||
<input id="rg-email" type="email" placeholder="you@example.com">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="rg-build">What would you want to build or test?</label>
|
||||
<textarea id="rg-build" placeholder="One sentence is plenty. The weirder the better."></textarea>
|
||||
</div>
|
||||
<button class="btn" type="submit">Request invite</button>
|
||||
<p class="note"><b>Closed beta. Invitation only.</b> Requests are read, not auto-approved — silence is also an answer.</p>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<span class="dot"></span>
|
||||
<span>whynot · 2026</span>
|
||||
<span>·</span>
|
||||
<span>Prereleases & prototypes only</span>
|
||||
<span class="sp">try($idea) until success;</span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function show(which) {
|
||||
var isLogin = which === 'login';
|
||||
document.getElementById('form-login').classList.toggle('hidden', !isLogin);
|
||||
document.getElementById('form-register').classList.toggle('hidden', isLogin);
|
||||
document.getElementById('tab-login').classList.toggle('active', isLogin);
|
||||
document.getElementById('tab-register').classList.toggle('active', !isLogin);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
158
designbook/preview/page-prototype-detail.html
Normal file
158
designbook/preview/page-prototype-detail.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Pages" name="Pages · Prototype detail" subtitle="Single prototype · pipeline, learning question, signal sidebar" viewport="1280x860" -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WNO-017 · Prototype</title>
|
||||
<link rel="icon" href="../assets/whynot-logo.png">
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
html, body { margin: 0; background: var(--paper); color: var(--fg-1); }
|
||||
a { color: inherit; }
|
||||
|
||||
.nav { height: 60px; display: flex; align-items: center; gap: 24px; padding: 0 40px; border-bottom: 1px solid var(--line); }
|
||||
.nav .brand { display: flex; align-items: center; gap: 10px; }
|
||||
.nav .brand img { width: 22px; height: 22px; }
|
||||
.nav .brand .nm { font: 500 15px var(--ff-sans); letter-spacing: -0.01em; }
|
||||
.nav .brand .slug { font: 400 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.nav .right { margin-left: auto; display: flex; align-items: center; gap: 16px; }
|
||||
.nav .search { font: 400 12px var(--ff-mono); color: var(--fg-3); border: 1px solid var(--line); border-radius: var(--r-1); padding: 6px 10px; min-width: 220px; display: flex; gap: 8px; }
|
||||
.nav .search .kbd { margin-left: auto; border: 1px solid var(--line); border-radius: 2px; padding: 0 5px; font-size: 10px; }
|
||||
|
||||
.app { display: grid; grid-template-columns: 220px 1fr; min-height: calc(100vh - 60px); }
|
||||
|
||||
/* left nav */
|
||||
.leftnav { display: flex; flex-direction: column; gap: 28px; padding: 28px 8px 24px 16px; border-right: 1px solid var(--line-soft); }
|
||||
.leftnav .section { display: flex; flex-direction: column; gap: 8px; }
|
||||
.leftnav .lbl { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); padding-left: 12px; opacity: 0.7; }
|
||||
.leftnav .items { display: flex; flex-direction: column; gap: 1px; }
|
||||
.leftnav .item { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-left: 2px solid transparent; color: var(--fg-3); font: 400 13px var(--ff-sans); text-decoration: none; }
|
||||
.leftnav .item .ic { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.5; fill: none; flex: none; }
|
||||
.leftnav .item .n { margin-left: auto; font: 400 11px var(--ff-mono); color: var(--ink-5); }
|
||||
.leftnav .item.active { color: var(--fg-1); font-weight: 500; border-left-color: var(--ink); }
|
||||
.leftnav .item.doc { font: 400 12px var(--ff-mono); }
|
||||
.leftnav .footer { margin-top: auto; display: flex; align-items: center; gap: 8px; padding: 0 12px; font: 400 11px var(--ff-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.leftnav .footer .dot { width: 5px; height: 5px; border-radius: 999px; background: var(--ink-4); }
|
||||
|
||||
/* main */
|
||||
.main { padding: 40px 56px 80px; max-width: 980px; }
|
||||
.crumb { font: 400 12px/1.5 var(--ff-mono); color: var(--fg-3); margin-bottom: 22px; display: flex; gap: 7px; }
|
||||
.crumb a { text-decoration: none; color: var(--fg-2); }
|
||||
.crumb .sep { color: var(--ink-5); }
|
||||
.crumb .cur { color: var(--fg-1); }
|
||||
|
||||
.head { display: flex; flex-direction: column; gap: 10px; margin-bottom: 36px; }
|
||||
.head .eyebrow { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.head .row { display: flex; align-items: flex-start; gap: 24px; }
|
||||
.head h1 { font: 400 32px/1.2 var(--ff-sans); letter-spacing: -0.02em; margin: 0; flex: 1; max-width: 22ch; }
|
||||
.head .actions { display: flex; gap: 8px; flex: none; padding-top: 4px; }
|
||||
.btn { font: 500 13px var(--ff-sans); padding: 9px 15px; border-radius: var(--r-2); border: 1px solid var(--line); background: var(--paper); color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
|
||||
.btn:hover { border-color: var(--ink); }
|
||||
.btn .ic { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.5; fill: none; }
|
||||
.btn.primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
|
||||
.btn.primary:hover { background: var(--ink-2); }
|
||||
|
||||
/* pipeline */
|
||||
.pipeline { display: grid; grid-template-columns: repeat(5, 1fr); margin: 0 0 40px; }
|
||||
.pstage { padding: 10px 12px 14px; border-top: 2px solid var(--line); display: flex; flex-direction: column; gap: 4px; position: relative; }
|
||||
.pstage.done { border-top-color: var(--ink); }
|
||||
.pstage.active { border-top-color: var(--hi-2); }
|
||||
.pstage .num { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.pstage.done .num, .pstage.active .num { color: var(--fg-1); }
|
||||
.pstage .nm { font: 500 13px/1.25 var(--ff-sans); color: var(--fg-1); }
|
||||
.pstage.pending .nm { color: var(--fg-3); }
|
||||
.pstage .meta { font: 400 11px/1.3 var(--ff-mono); color: var(--fg-3); }
|
||||
.pstage .arrow { position: absolute; top: -8px; right: -7px; font: 400 14px var(--ff-mono); color: var(--ink-5); }
|
||||
.pstage.done .arrow, .pstage.active .arrow { color: var(--ink); }
|
||||
|
||||
.body { display: grid; grid-template-columns: 1.4fr 1fr; gap: 48px; }
|
||||
.col { display: flex; flex-direction: column; gap: 24px; }
|
||||
.field { display: flex; flex-direction: column; gap: 7px; }
|
||||
.field .k { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.field .v { font: 400 15px/1.6 var(--ff-sans); color: var(--fg-1); max-width: 56ch; }
|
||||
|
||||
.aside { display: flex; flex-direction: column; gap: 20px; }
|
||||
.arow { display: flex; flex-direction: column; gap: 7px; }
|
||||
.arow .k { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.arow .v { font: 400 14px/1.5 var(--ff-sans); color: var(--fg-1); }
|
||||
.tag { align-self: flex-start; font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 10px; border-radius: 999px; background: var(--ink); color: var(--paper); }
|
||||
.dot { display: inline-flex; align-items: center; gap: 6px; font: 500 11px/1 var(--ff-mono); letter-spacing: 0.06em; color: var(--fg-2); }
|
||||
.dot .b { width: 8px; height: 8px; border-radius: 999px; background: var(--ink); }
|
||||
.mono { font-family: var(--ff-mono); }
|
||||
.caveat { border: 1px dashed var(--line-strong); border-radius: var(--r-2); padding: 16px; margin-top: 4px; }
|
||||
.caveat .k { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); display: block; margin-bottom: 8px; }
|
||||
.caveat .v { font: 400 13px/1.55 var(--ff-sans); color: var(--fg-2); margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="nav">
|
||||
<div class="brand"><img src="../assets/whynot-logo.png" alt=""><span class="nm">whynot</span><span class="slug">/ control</span></div>
|
||||
<div class="right">
|
||||
<div class="search"><span>Search…</span><span class="kbd">⌘ K</span></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="app">
|
||||
<nav class="leftnav">
|
||||
<div class="section">
|
||||
<span class="lbl">Work</span>
|
||||
<div class="items">
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg><span>Inbox</span><span class="n">7</span></a>
|
||||
<a class="item active"><svg class="ic" viewBox="0 0 24 24"><path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"/><path d="M6.453 15h11.094"/><path d="M8.5 2h7"/></svg><span>Prototypes</span><span class="n">4</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.5.5 0 0 1-.96 0L9.24 2.18a.5.5 0 0 0-.96 0l-2.35 8.36A2 2 0 0 1 4 12H2"/></svg><span>Signals</span><span class="n">12</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/><path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/></svg><span>Betas</span><span class="n">1</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg><span>Decisions</span><span class="n">3</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<span class="lbl">Control docs</span>
|
||||
<div class="items">
|
||||
<a class="item doc"><span>INTENT.md</span></a>
|
||||
<a class="item doc"><span>OPERATING_MODEL.md</span></a>
|
||||
<a class="item doc"><span>PROTOTYPE_PIPELINE.md</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer"><span class="dot"></span><span>A1 · Incubating</span></div>
|
||||
</nav>
|
||||
|
||||
<main class="main">
|
||||
<div class="crumb"><a href="#">whynot</a><span class="sep">/</span><a href="#">Prototypes</a><span class="sep">/</span><span class="cur">WNO-017</span></div>
|
||||
|
||||
<div class="head">
|
||||
<span class="eyebrow">WNO-017 · Prototype</span>
|
||||
<div class="row">
|
||||
<h1>A LEGO-brick mood board for engineers who don’t think in mood boards.</h1>
|
||||
<div class="actions">
|
||||
<button class="btn"><svg class="ic" viewBox="0 0 24 24"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>Park</button>
|
||||
<button class="btn primary"><svg class="ic" viewBox="0 0 24 24"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>Promote → Helix</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pipeline">
|
||||
<div class="pstage done"><span class="num">Stage 0</span><span class="nm">Raw idea</span><span class="meta">inbox/</span></div>
|
||||
<div class="pstage done"><span class="num">Stage 1</span><span class="nm">Triage</span><span class="meta">2026-02-15</span><span class="arrow">→</span></div>
|
||||
<div class="pstage done"><span class="num">Stage 2</span><span class="nm">Prototype card</span><span class="meta">prototypes/</span><span class="arrow">→</span></div>
|
||||
<div class="pstage done"><span class="num">Stage 3</span><span class="nm">Experiment</span><span class="meta">closed 2026-03-04</span><span class="arrow">→</span></div>
|
||||
<div class="pstage active"><span class="num">Stage 4</span><span class="nm">Signal review</span><span class="meta">in progress</span><span class="arrow">→</span></div>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div class="col">
|
||||
<div class="field"><span class="k">Learning question</span><span class="v">Will engineers attach metaphors to their tickets, and do those metaphors help anyone else read the work later?</span></div>
|
||||
<div class="field"><span class="k">Smallest useful test</span><span class="v">A Slack bot in three teams for two weeks. One command attaches a “brick” — a one-line metaphor — to any ticket.</span></div>
|
||||
<div class="field"><span class="k">Expected signal</span><span class="v">At least one team voluntarily keeps using the bricks after the two weeks, or references a brick in a review without being prompted.</span></div>
|
||||
<div class="field"><span class="k">Risks</span><span class="v">Cute but unused after a week. Or: engineers treat it as a chore rather than a shortcut.</span></div>
|
||||
</div>
|
||||
<aside class="aside">
|
||||
<div class="arow"><span class="k">Stage</span><span class="tag">Signal review</span></div>
|
||||
<div class="arow"><span class="k">Signal</span><span class="dot"><span class="b"></span>S3 · Strong</span></div>
|
||||
<div class="arow"><span class="k">Promotion target</span><span class="v mono">→ Helix</span></div>
|
||||
<div class="arow"><span class="k">Audience</span><span class="v">Engineering teams already writing terse tickets.</span></div>
|
||||
<div class="caveat"><span class="k">Caveat</span><p class="v">Strong signal is not a decision. Promotion to Helix still requires an explicit record in <span class="mono">DECISIONS.md</span>.</p></div>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
135
designbook/preview/page-signals-dashboard.html
Normal file
135
designbook/preview/page-signals-dashboard.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Pages" name="Pages · Signals dashboard" subtitle="Market-signal log · filter by strength · evidence rows" viewport="1280x860" -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Signals · whynot-control</title>
|
||||
<link rel="icon" href="../assets/whynot-logo.png">
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
html, body { margin: 0; background: var(--paper); color: var(--fg-1); }
|
||||
|
||||
.nav { height: 60px; display: flex; align-items: center; gap: 24px; padding: 0 40px; border-bottom: 1px solid var(--line); }
|
||||
.nav .brand { display: flex; align-items: center; gap: 10px; }
|
||||
.nav .brand img { width: 22px; height: 22px; }
|
||||
.nav .brand .nm { font: 500 15px var(--ff-sans); letter-spacing: -0.01em; }
|
||||
.nav .brand .slug { font: 400 12px var(--ff-mono); color: var(--fg-3); }
|
||||
.nav .right { margin-left: auto; display: flex; align-items: center; gap: 16px; }
|
||||
.nav .search { font: 400 12px var(--ff-mono); color: var(--fg-3); border: 1px solid var(--line); border-radius: var(--r-1); padding: 6px 10px; min-width: 220px; display: flex; gap: 8px; }
|
||||
.nav .search .kbd { margin-left: auto; border: 1px solid var(--line); border-radius: 2px; padding: 0 5px; font-size: 10px; }
|
||||
|
||||
.app { display: grid; grid-template-columns: 220px 1fr; min-height: calc(100vh - 60px); }
|
||||
|
||||
.leftnav { display: flex; flex-direction: column; gap: 28px; padding: 28px 8px 24px 16px; border-right: 1px solid var(--line-soft); }
|
||||
.leftnav .section { display: flex; flex-direction: column; gap: 8px; }
|
||||
.leftnav .lbl { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); padding-left: 12px; opacity: 0.7; }
|
||||
.leftnav .items { display: flex; flex-direction: column; gap: 1px; }
|
||||
.leftnav .item { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-left: 2px solid transparent; color: var(--fg-3); font: 400 13px var(--ff-sans); text-decoration: none; }
|
||||
.leftnav .item .ic { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.5; fill: none; flex: none; }
|
||||
.leftnav .item .n { margin-left: auto; font: 400 11px var(--ff-mono); color: var(--ink-5); }
|
||||
.leftnav .item.active { color: var(--fg-1); font-weight: 500; border-left-color: var(--ink); }
|
||||
.leftnav .item.doc { font: 400 12px var(--ff-mono); }
|
||||
.leftnav .footer { margin-top: auto; display: flex; align-items: center; gap: 8px; padding: 0 12px; font: 400 11px var(--ff-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.leftnav .footer .dot { width: 5px; height: 5px; border-radius: 999px; background: var(--ink-4); }
|
||||
|
||||
.main { padding: 40px 56px 80px; max-width: 1040px; }
|
||||
.head { display: flex; flex-direction: column; gap: 10px; margin-bottom: 32px; }
|
||||
.head .eyebrow { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.head .row { display: flex; align-items: flex-end; gap: 24px; }
|
||||
.head h1 { font: 400 32px/1.2 var(--ff-sans); letter-spacing: -0.02em; margin: 0; flex: 1; }
|
||||
.head .lede { font: 400 16px/1.6 var(--ff-sans); color: var(--fg-2); margin: 4px 0 0; max-width: 58ch; }
|
||||
.btn { font: 500 13px var(--ff-sans); padding: 9px 15px; border-radius: var(--r-2); border: 1px solid var(--ink); background: var(--ink); color: var(--paper); cursor: pointer; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
|
||||
.btn .ic { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.5; fill: none; }
|
||||
|
||||
/* distribution strip */
|
||||
.dist { display: flex; gap: 0; border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; margin-bottom: 28px; }
|
||||
.dist .cell { flex: 1; padding: 14px 16px; border-right: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 6px; }
|
||||
.dist .cell:last-child { border-right: 0; }
|
||||
.dist .cell .lv { display: inline-flex; align-items: center; gap: 6px; font: 500 10px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.dist .cell .lv .b { width: 8px; height: 8px; border-radius: 999px; }
|
||||
.dist .cell .ct { font: 300 28px/1 var(--ff-sans); color: var(--fg-1); }
|
||||
.b0 { background: var(--status-raw); } .b1 { background: var(--status-weak); } .b2 { background: var(--status-medium); } .b3 { background: var(--status-strong); } .b4 { background: var(--status-commercial); }
|
||||
|
||||
.filters { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
|
||||
.chip { font: 500 10px/1 var(--ff-mono); letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--fg-2); background: var(--paper); cursor: pointer; }
|
||||
.chip.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
|
||||
.filters .count { margin-left: auto; font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
|
||||
.rows { display: flex; flex-direction: column; }
|
||||
.srow { display: grid; grid-template-columns: 90px 90px 1fr; gap: 6px 24px; padding: 20px 0; border-bottom: 1px solid var(--line-soft); align-items: baseline; }
|
||||
.srow .id { font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
.srow .pr { font: 400 11px var(--ff-mono); color: var(--fg-2); }
|
||||
.srow .dot { display: inline-flex; align-items: center; gap: 6px; font: 500 11px/1 var(--ff-mono); letter-spacing: 0.06em; color: var(--fg-2); }
|
||||
.srow .dot .b { width: 8px; height: 8px; border-radius: 999px; }
|
||||
.srow .what { grid-column: 1 / -1; margin: 4px 0 0; font: 400 14px/1.55 var(--ff-sans); color: var(--fg-1); max-width: 64ch; }
|
||||
.srow .src { grid-column: 1 / -1; font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="nav">
|
||||
<div class="brand"><img src="../assets/whynot-logo.png" alt=""><span class="nm">whynot</span><span class="slug">/ control</span></div>
|
||||
<div class="right"><div class="search"><span>Search…</span><span class="kbd">⌘ K</span></div></div>
|
||||
</nav>
|
||||
|
||||
<div class="app">
|
||||
<nav class="leftnav">
|
||||
<div class="section">
|
||||
<span class="lbl">Work</span>
|
||||
<div class="items">
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg><span>Inbox</span><span class="n">7</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"/><path d="M6.453 15h11.094"/><path d="M8.5 2h7"/></svg><span>Prototypes</span><span class="n">4</span></a>
|
||||
<a class="item active"><svg class="ic" viewBox="0 0 24 24"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.5.5 0 0 1-.96 0L9.24 2.18a.5.5 0 0 0-.96 0l-2.35 8.36A2 2 0 0 1 4 12H2"/></svg><span>Signals</span><span class="n">12</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/><path d="M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/></svg><span>Betas</span><span class="n">1</span></a>
|
||||
<a class="item"><svg class="ic" viewBox="0 0 24 24"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg><span>Decisions</span><span class="n">3</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<span class="lbl">Control docs</span>
|
||||
<div class="items">
|
||||
<a class="item doc"><span>MARKET_SIGNAL.md</span></a>
|
||||
<a class="item doc"><span>OPERATING_MODEL.md</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer"><span class="dot"></span><span>A1 · Incubating</span></div>
|
||||
</nav>
|
||||
|
||||
<main class="main">
|
||||
<div class="head">
|
||||
<span class="eyebrow">whynot-control / signals</span>
|
||||
<div class="row">
|
||||
<h1>Signals</h1>
|
||||
<button class="btn"><svg class="ic" viewBox="0 0 24 24"><path d="M12 5v14"/><path d="M5 12h14"/></svg>Record signal</button>
|
||||
</div>
|
||||
<p class="lede">A signal is evidence, not a vibe. Record what happened, who did it, and how strong the evidence is. Lack of signal is also information.</p>
|
||||
</div>
|
||||
|
||||
<div class="dist">
|
||||
<div class="cell"><span class="lv"><span class="b b0"></span>S0</span><span class="ct">1</span></div>
|
||||
<div class="cell"><span class="lv"><span class="b b1"></span>S1</span><span class="ct">2</span></div>
|
||||
<div class="cell"><span class="lv"><span class="b b2"></span>S2</span><span class="ct">2</span></div>
|
||||
<div class="cell"><span class="lv"><span class="b b3"></span>S3</span><span class="ct">1</span></div>
|
||||
<div class="cell"><span class="lv"><span class="b b4"></span>S4</span><span class="ct">0</span></div>
|
||||
</div>
|
||||
|
||||
<div class="filters">
|
||||
<span class="chip active">All</span>
|
||||
<span class="chip">S0</span>
|
||||
<span class="chip">S1</span>
|
||||
<span class="chip">S2</span>
|
||||
<span class="chip">S3</span>
|
||||
<span class="chip">S4</span>
|
||||
<span class="count">6 of 6</span>
|
||||
</div>
|
||||
|
||||
<div class="rows">
|
||||
<div class="srow"><span class="id">SIG-031</span><span class="pr">WNO-017</span><span class="dot"><span class="b b3"></span>S3</span><p class="what">Two teams shipped public README sections labelled “brick: scope” after using the bot for a week.</p><span class="src">usage log · 2026-03-04</span></div>
|
||||
<div class="srow"><span class="id">SIG-030</span><span class="pr">WNO-017</span><span class="dot"><span class="b b2"></span>S2</span><p class="what">Three engineers DM’d asking for an export-to-Notion option.</p><span class="src">Slack · 2026-03-03</span></div>
|
||||
<div class="srow"><span class="id">SIG-029</span><span class="pr">WNO-014</span><span class="dot"><span class="b b1"></span>S1</span><p class="what">Landing page: 34 visits, 7 emails, 0 returns in week 1.</p><span class="src">Plausible · 2026-03-01</span></div>
|
||||
<div class="srow"><span class="id">SIG-028</span><span class="pr">WNO-021</span><span class="dot"><span class="b b2"></span>S2</span><p class="what">First triage call booked at listed price; second declined on price.</p><span class="src">Stripe / email · 2026-02-28</span></div>
|
||||
<div class="srow"><span class="id">SIG-027</span><span class="pr">WNO-021</span><span class="dot"><span class="b b1"></span>S1</span><p class="what">“Interesting but I’d want a free first one” ×2.</p><span class="src">interview · 2026-02-26</span></div>
|
||||
<div class="srow"><span class="id">SIG-026</span><span class="pr">WNO-024</span><span class="dot"><span class="b b0"></span>S0</span><p class="what">Static preview: 12 visits in 30 days, 0 returns.</p><span class="src">Plausible · 2026-02-24</span></div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
26
designbook/preview/spacing-elevation.html
Normal file
26
designbook/preview/spacing-elevation.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Spacing" name="Spacing · Elevation" subtitle="Mostly none · wireframe system" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Elevation</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper-2); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 22px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
||||
.cell { display: flex; flex-direction: column; align-items: center; gap: 12px; }
|
||||
.obj { width: 100%; height: 72px; background: var(--paper); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font: 500 11px var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.lbl { font: 500 11px var(--ff-mono); color: var(--fg-1); }
|
||||
.val { font: 400 10px var(--ff-mono); color: var(--fg-3); text-align: center; line-height: 1.4; }
|
||||
.s1 { box-shadow: 0 1px 0 var(--line); }
|
||||
.s2 { box-shadow: 0 1px 0 var(--line-strong); }
|
||||
.s3 { box-shadow: 0 4px 12px -6px rgba(10,10,10,.10); border-color: var(--border-soft); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Elevation — this is a wireframe system, prefer none</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><div class="obj">default</div><span class="lbl">--shadow-0</span><span class="val">none · everywhere</span></div>
|
||||
<div class="cell"><div class="obj s1">+1</div><span class="lbl">--shadow-1</span><span class="val">1px hairline · sticky nav</span></div>
|
||||
<div class="cell"><div class="obj s2">+2</div><span class="lbl">--shadow-2</span><span class="val">1px strong · sticky strong</span></div>
|
||||
<div class="cell"><div class="obj s3">float</div><span class="lbl">--shadow-3</span><span class="val">soft 4–12px · popover only</span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
24
designbook/preview/spacing-radii.html
Normal file
24
designbook/preview/spacing-radii.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Spacing" name="Spacing · Radii" subtitle="0 / 2 / 4 / 8 / pill" viewport="700x200" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Radii</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 16px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
|
||||
.cell { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
||||
.swatch { width: 80px; height: 60px; background: var(--paper); border: 1px solid var(--ink); }
|
||||
.lbl { font: 500 11px/1.2 var(--ff-mono); letter-spacing: 0.04em; color: var(--fg-1); text-align: center; }
|
||||
.val { font: 400 11px var(--ff-mono); color: var(--fg-3); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Radii — big things stay square</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><div class="swatch" style="border-radius:0"></div><span class="lbl">--r-0<br><span class="val">0 · documents</span></span></div>
|
||||
<div class="cell"><div class="swatch" style="border-radius:2px"></div><span class="lbl">--r-1<br><span class="val">2 · inputs, tags</span></span></div>
|
||||
<div class="cell"><div class="swatch" style="border-radius:4px"></div><span class="lbl">--r-2<br><span class="val">4 · buttons</span></span></div>
|
||||
<div class="cell"><div class="swatch" style="border-radius:8px"></div><span class="lbl">--r-3<br><span class="val">8 · cards, modals</span></span></div>
|
||||
<div class="cell"><div class="swatch" style="border-radius:999px"></div><span class="lbl">--r-pill<br><span class="val">∞ · label caps only</span></span></div>
|
||||
</div>
|
||||
</body></html>
|
||||
28
designbook/preview/spacing-scale.html
Normal file
28
designbook/preview/spacing-scale.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Spacing" name="Spacing · Scale" subtitle="4px base · 10 steps" viewport="700x280" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Spacing Scale</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 24px 32px; background: var(--paper); }
|
||||
.row-label { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 14px; }
|
||||
.scale { display: grid; grid-template-columns: 80px 1fr 90px; row-gap: 8px; column-gap: 16px; align-items: center; font-family: var(--ff-mono); font-size: 12px; }
|
||||
.name { color: var(--fg-1); }
|
||||
.bar { height: 12px; background: var(--ink); }
|
||||
.val { color: var(--fg-3); text-align: right; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row-label">Spacing — 4px base unit</div>
|
||||
<div class="scale">
|
||||
<span class="name">--sp-1</span><div class="bar" style="width:4px"></div><span class="val">4px</span>
|
||||
<span class="name">--sp-2</span><div class="bar" style="width:8px"></div><span class="val">8px</span>
|
||||
<span class="name">--sp-3</span><div class="bar" style="width:12px"></div><span class="val">12px</span>
|
||||
<span class="name">--sp-4</span><div class="bar" style="width:16px"></div><span class="val">16px</span>
|
||||
<span class="name">--sp-5</span><div class="bar" style="width:24px"></div><span class="val">24px</span>
|
||||
<span class="name">--sp-6</span><div class="bar" style="width:32px"></div><span class="val">32px</span>
|
||||
<span class="name">--sp-7</span><div class="bar" style="width:48px"></div><span class="val">48px</span>
|
||||
<span class="name">--sp-8</span><div class="bar" style="width:64px"></div><span class="val">64px</span>
|
||||
<span class="name">--sp-9</span><div class="bar" style="width:96px"></div><span class="val">96px</span>
|
||||
<span class="name">--sp-10</span><div class="bar" style="width:128px"></div><span class="val">128px</span>
|
||||
</div>
|
||||
</body></html>
|
||||
23
designbook/preview/type-body.html
Normal file
23
designbook/preview/type-body.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Type" name="Type · Body & Lead" subtitle="Lead 17/1.55 · Body 15/1.5" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Body & Lead</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
|
||||
.col .label { display: block; margin-bottom: 8px; }
|
||||
.col .spec { color: var(--fg-3); font-family: var(--ff-mono); font-size: 10px; letter-spacing: 0.04em; margin-top: 6px; display: block; }
|
||||
p { margin: 0; max-width: 56ch; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="col">
|
||||
<span class="label">Lead</span>
|
||||
<p class="lead">A prototype is a question made tangible. The purpose is not to prove an idea is brilliant — it is to learn what is useful, desirable, or irrelevant.</p>
|
||||
<span class="spec">.lead · system-sans 400 · 17 / 1.55 · fg-2</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Body</span>
|
||||
<p>Signals are evidence, not vibes. Weak signals are useful if clearly labelled. Contradictory signals should be preserved. A signal should be connected to a prototype, audience, or hypothesis. Lack of signal is also information.</p>
|
||||
<span class="spec">p · system-sans 400 · 15 / 1.5 · fg-1</span>
|
||||
</div>
|
||||
</body></html>
|
||||
23
designbook/preview/type-display.html
Normal file
23
designbook/preview/type-display.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Type" name="Type · Display" subtitle="PlexSans 300/400 · -.035em tracking" viewport="700x200" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Display Type</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 32px; background: var(--paper); }
|
||||
.row { display: flex; align-items: baseline; gap: 24px; margin-bottom: 18px; }
|
||||
.row .label { width: 80px; flex: none; }
|
||||
.row .spec { color: var(--fg-3); font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.04em; margin-left: auto; flex: none; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<span class="label">Display 1</span>
|
||||
<span class="display-1">try($idea)</span>
|
||||
<span class="spec">system-sans 300 · 96 / .95 · -.035em</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">Display 2</span>
|
||||
<span class="display-2">why? why not!</span>
|
||||
<span class="spec">system-sans 400 · 64 / 1.0 · -.02em</span>
|
||||
</div>
|
||||
</body></html>
|
||||
20
designbook/preview/type-headings.html
Normal file
20
designbook/preview/type-headings.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Type" name="Type · Headings" subtitle="H1–H5 · PlexSans 500 · tight tracking" viewport="700x320" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Headings</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); }
|
||||
.row { display: grid; grid-template-columns: 64px 1fr auto; align-items: baseline; gap: 24px; padding: 10px 0; border-bottom: 1px solid var(--border-soft); }
|
||||
.row:last-child { border: 0; }
|
||||
.row .label { color: var(--fg-3); font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }
|
||||
.row h1, .row h2, .row h3, .row h4, .row h5 { margin: 0; }
|
||||
.row .spec { color: var(--fg-3); font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.04em; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row"><span class="label">H1</span><h1>Prototype pipeline</h1><span class="spec">500 · 44 / 1.05</span></div>
|
||||
<div class="row"><span class="label">H2</span><h2>Stage 2 — Prototype card</h2><span class="spec">500 · 32 / 1.25</span></div>
|
||||
<div class="row"><span class="label">H3</span><h3>Learning question</h3><span class="spec">500 · 24 / 1.25</span></div>
|
||||
<div class="row"><span class="label">H4</span><h4>Smallest useful test</h4><span class="spec">500 · 20 / 1.25</span></div>
|
||||
<div class="row"><span class="label">H5</span><h5>Expected signal</h5><span class="spec">500 · 17 / 1.25</span></div>
|
||||
</body></html>
|
||||
42
designbook/preview/type-mono-eyebrows.html
Normal file
42
designbook/preview/type-mono-eyebrows.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Type" name="Type · Mono & Eyebrows" subtitle="PlexMono · uppercase · .08em tracking" viewport="700x220" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Mono & Eyebrows</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 28px 32px; background: var(--paper); }
|
||||
.group { display: flex; gap: 48px; align-items: flex-start; }
|
||||
.stack { display: flex; flex-direction: column; gap: 10px; }
|
||||
.stack h6 { margin: 0 0 4px; font: 500 11px/1.2 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
|
||||
.eyebrow-row { display: flex; gap: 10px; flex-wrap: wrap; }
|
||||
.specrow { display: flex; align-items: baseline; gap: 16px; }
|
||||
.specrow code { background: none; padding: 0; color: var(--fg-1); }
|
||||
.tag { font: 500 11px/1 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-2); padding: 5px 9px; border: 1px solid var(--border); border-radius: var(--r-pill); }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="group">
|
||||
<div class="stack" style="flex:1">
|
||||
<h6>Eyebrow labels</h6>
|
||||
<div class="eyebrow-row">
|
||||
<span class="eyebrow">PROTOTYPE</span>
|
||||
<span class="eyebrow">STAGE</span>
|
||||
<span class="eyebrow">SIGNAL · S2</span>
|
||||
<span class="eyebrow">IN BETA</span>
|
||||
<span class="eyebrow">PROMOTION TARGET</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stack" style="flex:1">
|
||||
<h6>Mono inline</h6>
|
||||
<div class="specrow"><code class="mono">whynot-control/INTENT.md</code></div>
|
||||
<div class="specrow"><code class="mono">stage: prototype-candidate</code></div>
|
||||
<div class="specrow"><code class="mono">→ Helix</code></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 28px; display: flex; gap: 10px; align-items: center;">
|
||||
<span class="tag">Raw Idea</span>
|
||||
<span class="tag">Prototype Candidate</span>
|
||||
<span class="tag">Experiment</span>
|
||||
<span class="tag">Promotion Candidate</span>
|
||||
<span class="tag">Parked</span>
|
||||
</div>
|
||||
</body></html>
|
||||
17
designbook/preview/type-serif-quote.html
Normal file
17
designbook/preview/type-serif-quote.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<!-- @dsCard group="Type" name="Type · Serif Quote" subtitle="PlexSerif italic · editorial moments" viewport="700x210" -->
|
||||
<html><head>
|
||||
<meta charset="utf-8"><title>Serif Quote</title>
|
||||
<link rel="stylesheet" href="../colors_and_type.css">
|
||||
<style>
|
||||
body { padding: 32px 36px; background: var(--paper); }
|
||||
blockquote { margin: 0; max-width: 60ch; padding-left: 16px; border-left: 1px solid var(--border-strong); }
|
||||
blockquote .q { font: 400 italic 22px/1.4 var(--ff-serif); color: var(--ink); margin: 0 0 12px; }
|
||||
blockquote cite { font: 500 11px/1.2 var(--ff-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); font-style: normal; }
|
||||
</style></head>
|
||||
<body>
|
||||
<blockquote>
|
||||
<p class="q">A prototype is a question made tangible. The purpose is not to prove an idea is brilliant. The purpose is to learn what is actually useful, desirable, feasible, or irrelevant.</p>
|
||||
<cite>— whynot-control / INTENT.md</cite>
|
||||
</blockquote>
|
||||
</body></html>
|
||||
Reference in New Issue
Block a user