Repaint to jet-black + atomic-tangerine skin, add consultant-special 2×2
Why: the default skin was too warm/neutral and the pyramid + venn never quite read the way they should. Also prepping for public sharing, so the example diagrams needed to drop the littlemight-specific copy. Changes: - New five-color palette: jet-black ink, atomic-tangerine accent, white-smoke paper, blue-slate muted, silver hairlines. Replaces warm-stone + rust across every variant + dark-mode tokens. - Default background is clean paper; dot grid + framed container are now opt-in variants (uncomment in template to enable). - New consultant-special quadrant variant (example-quadrant-consultant.html) — 2×2 scenario matrix with named cells, double-ended axes, one focal quadrant; house skin, not a separate visual language. - Pyramid redrawn as a true triangular silhouette with shared edges on one slope (stacked polygons on a single triangle outline, no kinks). - Venn redesigned: dark-fill triple-intersection with white text, circle labels moved inside non-overlap lobes, pair-overlap labels removed, legend dropped. - Example content genericized (content site / product timeline / content platform instead of littlemight-branded copy). - Screenshots regenerated at 2× DPI; added quadrant-consultant.png (14th diagram in the gallery). - README: hero-first opener, preserved Why-I-built-it section, UTM tags on littlemight + bestself links, palette description updated.
@@ -1,10 +1,20 @@
|
||||
# Diagram Design
|
||||
|
||||
**I wanted good-looking diagrams for my blog posts.**
|
||||
**Editorial diagrams your designer won't hate.**
|
||||
|
||||
I write at [littlemight.com](https://littlemight.com). Every time I needed a diagram — an architecture sketch, a flowchart, a pyramid of what matters most — I'd ask Claude and get back a generic rounded-box thing that looked nothing like the rest of the site. I'd either fight with Figma for 30 minutes or just skip the diagram.
|
||||

|
||||
|
||||
So I built a Claude Code skill for it. 13 types, editorial quality, matches your brand in 60 seconds by reading your website.
|
||||
14 types. One Claude Code skill. Your brand in 60 seconds — the skill reads your website and maps colors + fonts to every diagram.
|
||||
|
||||
No Figma. No generic rounded boxes. No 30-minute color-picking sessions.
|
||||
|
||||
---
|
||||
|
||||
## Why I built it
|
||||
|
||||
I write at [littlemight.com](https://littlemight.com?utm_source=diagram-design&utm_medium=readme&utm_campaign=github&utm_content=intro) (and run [BestSelf.co](https://bestself.co?utm_source=diagram-design&utm_medium=readme&utm_campaign=github&utm_content=intro) on the side). Every time I needed a diagram — an architecture sketch, a flowchart, a pyramid of what matters most — I'd ask Claude and get back a generic rounded-box thing that looked nothing like the rest of the site. I'd either fight with Figma for 30 minutes or just skip the diagram.
|
||||
|
||||
So I built a Claude Code skill for it. Fourteen types, editorial quality, matches your brand in 60 seconds by reading your website.
|
||||
|
||||
> *The highest-quality move is usually deletion.* Every node earns its place. The accent color is reserved for the 1–2 things the reader should look at first. Target density: 4/10.
|
||||
|
||||
@@ -12,7 +22,7 @@ So I built a Claude Code skill for it. 13 types, editorial quality, matches your
|
||||
|
||||
## What it makes
|
||||
|
||||
All 13 diagrams ship in three variants: minimal light, minimal dark, and full-editorial. Open any of them directly in a browser — no build step, no JS, no external images.
|
||||
All 14 diagrams ship in three variants: minimal light, minimal dark, and full-editorial. Open any of them directly in a browser — no build step, no JS, no external images.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -36,11 +46,13 @@ All 13 diagrams ship in three variants: minimal light, minimal dark, and full-ed
|
||||
<td align="center"><img src="docs/screenshots/venn.png" alt="Venn"><br><b>Venn</b><br><sub>Set overlap</sub></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="3"><img src="docs/screenshots/pyramid.png" alt="Pyramid" width="40%"><br><b>Pyramid / funnel</b><br><sub>Ranked hierarchy or conversion drop-off</sub></td>
|
||||
<td align="center"><img src="docs/screenshots/pyramid.png" alt="Pyramid"><br><b>Pyramid / funnel</b><br><sub>Ranked hierarchy or drop-off</sub></td>
|
||||
<td align="center"><img src="docs/screenshots/quadrant-consultant.png" alt="Consultant 2×2"><br><b>Consultant 2×2</b><br><sub>Scenario matrix · named cells</sub></td>
|
||||
<td align="center"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Browse the live gallery:** open [`assets/index.html`](assets/index.html) in your browser to flip through all 13 types with light / dark / full-editorial tabs.
|
||||
**Browse the live gallery:** open [`assets/index.html`](assets/index.html) in your browser to flip through all 14 diagrams with light / dark / full-editorial tabs.
|
||||
|
||||
---
|
||||
|
||||
@@ -75,7 +87,7 @@ Quicker to install — but the skill lives in the plugin cache, so edits to `ref
|
||||
|
||||
The whole point: ship editorial-quality diagrams in **your** colors and typography, not a generic template.
|
||||
|
||||
Out of the box, diagrams render in a neutral **stone + rust** palette (warm off-white paper, deep charcoal ink, rust-orange accent). Good enough to screenshot straight away. But 60 seconds of onboarding is better — the skill will pull your brand from your website and apply it across every diagram.
|
||||
Out of the box, diagrams render in a clean **jet-black + atomic-tangerine** palette (white-smoke paper, jet-black ink, atomic-tangerine accent, blue-slate muted, silver hairlines). Good enough to screenshot straight away. But 60 seconds of onboarding is better — the skill will pull your brand from your website and apply it across every diagram.
|
||||
|
||||
### The flow
|
||||
|
||||
@@ -111,7 +123,7 @@ Before writing tokens, the skill verifies WCAG AA contrast on `ink` over `paper`
|
||||
|
||||
### Manual override
|
||||
|
||||
Prefer to set tokens by hand? Open [`references/style-guide.md`](references/style-guide.md) and edit the table. Everything downstream reads from there — the 13 types, the annotation primitive, and the gallery all inherit semantic role names (`accent`, not `#b5523a`).
|
||||
Prefer to set tokens by hand? Open [`references/style-guide.md`](references/style-guide.md) and edit the table. Everything downstream reads from there — all 14 diagrams, the annotation primitive, and the gallery all inherit semantic role names (`accent`, not `#eb6c36`).
|
||||
|
||||
### First-run gate
|
||||
|
||||
@@ -126,7 +138,7 @@ See [`references/onboarding.md`](references/onboarding.md) for the full spec.
|
||||
## Quickstart
|
||||
|
||||
```bash
|
||||
# Open the gallery to see all 13 types
|
||||
# Open the gallery to see all 14 diagrams
|
||||
open ~/.claude/skills/diagram-design/assets/index.html
|
||||
|
||||
# In Claude Code, just ask:
|
||||
@@ -172,7 +184,8 @@ diagram-design/
|
||||
├── assets/
|
||||
│ ├── index.html — live gallery, tabbed
|
||||
│ ├── template*.html — scaffolds for new diagrams
|
||||
│ └── example-<type>.html — 3 variants × 13 types
|
||||
│ ├── example-<type>.html — 3 variants × 13 types
|
||||
│ └── example-quadrant-consultant.html — consultant-special 2×2 scenario matrix
|
||||
└── docs/screenshots/ — the images in this README
|
||||
```
|
||||
|
||||
@@ -189,7 +202,7 @@ The top-level `SKILL.md` is always in context. Everything else is pulled in only
|
||||
| "Onboard this skill to my site" | `SKILL.md` + `references/onboarding.md` + `references/style-guide.md` |
|
||||
| "Add an editorial callout to this diagram" | `SKILL.md` + `references/primitive-annotation.md` |
|
||||
| "Give me a hand-drawn version" | `SKILL.md` + `references/primitive-sketchy.md` |
|
||||
| Routine diagram-making (any of the 13 types) | Only `SKILL.md` + that one type's reference |
|
||||
| Routine diagram-making (any of the 14 diagrams) | Only `SKILL.md` + that one type's reference |
|
||||
|
||||
No matter how many types exist, Claude only reads the one you need. Add a new type tomorrow and nothing else changes.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Thirteen diagram types. One shared design system, complexity budget, and taste g
|
||||
|
||||
Open [`references/style-guide.md`](references/style-guide.md) and check the default tokens. If they're still the shipped defaults (paper `#faf7f2`, ink `#1c1917`, accent `#b5523a` rust), **pause and ask the user**:
|
||||
|
||||
> *"This is your first diagram in this project. The style guide is still at the default (neutral stone + rust). Do you want to customize it to match your brand first? Options: (a) run onboarding — I'll pull colors and fonts from your website, (b) paste your tokens manually, (c) proceed with the default for now."*
|
||||
> *"This is your first Schematic in this project. The style guide is still at the default (neutral stone + rust). Do you want to customize it to match your brand first? Options: (a) run onboarding — I'll pull colors and fonts from your website, (b) paste your tokens manually, (c) proceed with the default for now."*
|
||||
|
||||
Then branch:
|
||||
- **(a)** → follow [`references/onboarding.md`](references/onboarding.md) to fetch the site, extract palette + fonts, propose a diff, and write `style-guide.md`.
|
||||
@@ -39,11 +39,11 @@ Don't silently ship default-skinned diagrams into a branded project — that's t
|
||||
|
||||
From `.impeccable.md`: *"Confident restraint. Earn every element. One color accent, two families, a small spacing vocabulary. If removing it wouldn't hurt the page, remove it."*
|
||||
|
||||
Applied to diagrams:
|
||||
Applied to schematics:
|
||||
- Every node represents a distinct idea. Two nodes that always travel together are one node.
|
||||
- Every connection carries information. If the relationship is obvious from layout, remove the line.
|
||||
- Coral is **editorial, not a flag.** 1–2 focal nodes per diagram. Using it on 5 nodes erases the signal.
|
||||
- The diagram isn't done when everything is added. It's done when nothing can be removed.
|
||||
- The schematic isn't done when everything is added. It's done when nothing can be removed.
|
||||
|
||||
**Target density: 4/10.** Enough to be technically complete. Not so dense it needs a guide. Above 9 nodes, it's probably two diagrams.
|
||||
|
||||
@@ -94,7 +94,7 @@ Rules of thumb:
|
||||
|
||||
## 4. Universal Anti-patterns
|
||||
|
||||
These mark "AI slop" diagrams of any type:
|
||||
These mark "AI slop" schematics of any type:
|
||||
|
||||
| Anti-pattern | Why it fails |
|
||||
|---|---|
|
||||
@@ -115,7 +115,7 @@ Type-specific anti-patterns live in each `references/type-*.md`.
|
||||
|
||||
## 5. Design System
|
||||
|
||||
**The design system is skinnable.** All colors, typography, and tokens live in a single source of truth — [`references/style-guide.md`](references/style-guide.md). This file describes semantic roles (`paper`, `ink`, `muted`, `accent`, `link`, …). The default skin is littlemight.com (warm paper, ink, coral); to apply your own brand, either edit `style-guide.md` directly or run the URL-based flow described in [`references/onboarding.md`](references/onboarding.md).
|
||||
**The design system is skinnable.** All colors, typography, and tokens live in a single source of truth — [`references/style-guide.md`](references/style-guide.md). This file describes semantic roles (`paper`, `ink`, `muted`, `accent`, `link`, …). The default skin is a cool editorial palette (white-smoke paper, jet-black ink, atomic-tangerine accent, blue-slate muted, silver hairlines); to apply your own brand, either edit `style-guide.md` directly or run the URL-based flow described in [`references/onboarding.md`](references/onboarding.md).
|
||||
|
||||
> When specs below or in type references mention "ink", "accent", "muted", etc., look up the current hex value in `style-guide.md`.
|
||||
|
||||
@@ -169,35 +169,45 @@ Universal building blocks. Type-specialized primitives (lifeline, activation bar
|
||||
|
||||
### Background
|
||||
|
||||
**Default: clean paper, no dot pattern.** Single `<rect>` filled with `paper`. Don't wrap the diagram in a secondary container background — the diagram sits directly on the page.
|
||||
|
||||
```svg
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
```
|
||||
|
||||
**Optional: dotted paper variant.** When a long-form editorial diagram benefits from textured ground (essays, hero diagrams on a dedicated page), opt in by adding the `dots` pattern and a second rect:
|
||||
|
||||
```svg
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.6"/>
|
||||
```
|
||||
|
||||
Don't use the dot pattern when the diagram sits inside a product page, slide, or card — the texture compounds with surrounding chrome and reads as noise.
|
||||
|
||||
### Arrow markers (define all three, always)
|
||||
|
||||
```svg
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#52534e"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/>
|
||||
</marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#f7591f"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/>
|
||||
</marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/>
|
||||
</marker>
|
||||
```
|
||||
|
||||
| Arrow | Stroke | When |
|
||||
|---|---|---|
|
||||
| Default | muted `#52534e` | Internal, generic |
|
||||
| Accent | coral `#f7591f` | Primary / highlighted / headline |
|
||||
| Link-blue | `#1a70c7` | HTTP/API calls, external systems |
|
||||
| Default | muted `#4f5d75` | Internal, generic |
|
||||
| Accent | coral `#eb6c36` | Primary / highlighted / headline |
|
||||
| Link-blue | `#2e5aa8` | HTTP/API calls, external systems |
|
||||
| Dashed | `stroke-dasharray="5,4"` + any color | Optional, passive, return, async |
|
||||
|
||||
**Draw arrows before boxes** so z-order puts lines behind nodes.
|
||||
@@ -206,7 +216,7 @@ Universal building blocks. Type-specialized primitives (lifeline, activation bar
|
||||
|
||||
```svg
|
||||
<!-- 1. Opaque paper mask — prevents arrows bleeding through transparent fills -->
|
||||
<rect x="X" y="Y" width="W" height="H" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="X" y="Y" width="W" height="H" rx="6" fill="#f5f5f5"/>
|
||||
<!-- 2. Styled box -->
|
||||
<rect x="X" y="Y" width="W" height="H" rx="6" fill="FILL" stroke="STROKE" stroke-width="1"/>
|
||||
<!-- 3. Rectangular type tag (rx=2, NOT a pill) -->
|
||||
@@ -214,10 +224,10 @@ Universal building blocks. Type-specialized primitives (lifeline, activation bar
|
||||
<text x="X+22" y="Y+15" fill="STROKE@0.8" font-size="7" font-family="'Geist Mono', monospace"
|
||||
text-anchor="middle" letter-spacing="0.08em">API</text>
|
||||
<!-- 4. Node name (Geist sans — human-readable) -->
|
||||
<text x="CX" y="CY+2" fill="#0b0d0b" font-size="12" font-weight="600"
|
||||
<text x="CX" y="CY+2" fill="#2d3142" font-size="12" font-weight="600"
|
||||
font-family="'Geist', sans-serif" text-anchor="middle">Node Name</text>
|
||||
<!-- 5. Technical sublabel (Geist Mono) -->
|
||||
<text x="CX" y="CY+18" fill="#52534e" font-size="9"
|
||||
<text x="CX" y="CY+18" fill="#4f5d75" font-size="9"
|
||||
font-family="'Geist Mono', monospace" text-anchor="middle">tech:port</text>
|
||||
```
|
||||
|
||||
@@ -226,8 +236,8 @@ Universal building blocks. Type-specialized primitives (lifeline, activation bar
|
||||
Every arrow label needs an opaque rect behind it. Without one it bleeds through the line.
|
||||
|
||||
```svg
|
||||
<rect x="MID_X-18" y="ARROW_Y-12" width="36" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="MID_X" y="ARROW_Y-3" fill="#65655c" font-size="8"
|
||||
<rect x="MID_X-18" y="ARROW_Y-12" width="36" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="MID_X" y="ARROW_Y-3" fill="#7a8399" font-size="8"
|
||||
font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">WRITE</text>
|
||||
```
|
||||
|
||||
@@ -239,8 +249,8 @@ Rules: ≤14 characters, all-caps, centered on segment midpoint, 8–10px above
|
||||
|
||||
```svg
|
||||
<line x1="30" y1="LEGEND_Y-8" x2="VIEWBOX_W-30" y2="LEGEND_Y-8"
|
||||
stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="30" y="LEGEND_Y+8" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace"
|
||||
stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="30" y="LEGEND_Y+8" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace"
|
||||
letter-spacing="0.14em">LEGEND</text>
|
||||
<!-- Items — horizontal row, ~160px apart -->
|
||||
```
|
||||
@@ -291,7 +301,7 @@ If you exceed, split into two diagrams (overview + detail).
|
||||
### Page layout
|
||||
|
||||
1. **Header** — eyebrow (Geist Mono), title (Instrument Serif), optional subtitle (Geist muted).
|
||||
2. **Diagram container** — `#efeee5` bg, 1px `rgba(11,13,11,0.12)` border, 8px radius, `overflow-x: auto`.
|
||||
2. **Diagram container** — default: **clean, borderless**, no background — the SVG sits directly on the page paper. Optional *framed* variant (for card-heavy layouts or hero placements): `paper-2` bg + 1px `rule` border + 8px radius + `1.5rem` padding + `overflow-x: auto`.
|
||||
3. **Summary cards** — 2–3 col grid with *varied* widths (e.g., `1.1fr 1fr 0.9fr`).
|
||||
4. **Footer** — colophon in Geist Mono, muted, hairline top border.
|
||||
|
||||
@@ -314,7 +324,7 @@ Don't use 3 identical generic cards. Vary the treatment:
|
||||
|
||||
Rules:
|
||||
- `background: #ffffff` (not paper — slight lift without shadow)
|
||||
- `border: 1px solid rgba(11,13,11,0.12)`
|
||||
- `border: 1px solid rgba(45,49,66,0.12)`
|
||||
- `border-radius: 6px`, `padding: 1.25rem`
|
||||
- **No `box-shadow`**
|
||||
- Card dots: 7px, `border-radius: 50%` — ink / muted / coral / link / soft variants
|
||||
@@ -343,7 +353,7 @@ Run before producing any diagram.
|
||||
|
||||
**Technical:**
|
||||
- [ ] Arrows drawn before boxes?
|
||||
- [ ] Every arrow label has an opaque `fill="#f5f4ed"` rect behind it?
|
||||
- [ ] Every arrow label has an opaque `fill="#f5f5f5"` rect behind it?
|
||||
- [ ] Legend is a horizontal bottom strip, not floating?
|
||||
- [ ] No vertical `writing-mode` text?
|
||||
- [ ] `viewBox` expanded for the legend strip (~60px)?
|
||||
@@ -367,6 +377,7 @@ Every diagram ships in three variants (see `assets/`):
|
||||
| **Minimal light** (default) | `template.html`, `example-<type>.html` | Screenshot-ready. Diagram + title. Warm paper. |
|
||||
| **Minimal dark** | `template-dark.html`, `example-<type>-dark.html` | Dark mode sites, slides, high-contrast posts. |
|
||||
| **Full editorial** | `template-full.html`, `example-<type>-full.html` | Long-form posts where the diagram is the hero. |
|
||||
| **Consultant special** (quadrant only) | `example-quadrant-consultant.html` | BCG/McKinsey-style 2×2 scenario matrix. Clinical sans-serif, white bg, bold blue double-ended axes, named scenario cells. See [type-quadrant.md](references/type-quadrant.md#consultant-special-2x2-scenario-matrix). |
|
||||
|
||||
**Sketchy variant** (optional, applied to any of the above) — see [primitive-sketchy.md](references/primitive-sketchy.md). SVG turbulence filter wobbles strokes for a hand-drawn feel. Good for essays, not for technical docs.
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight.com · Architecture</title>
|
||||
<title>Content site · Architecture</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,106 +56,106 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">Architecture · Diagram Design</p>
|
||||
<h1>littlemight.com in production</h1>
|
||||
<h1>Content site in production</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#5ba8eb"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#6a95d8"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows first (behind boxes) -->
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#5ba8eb" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#6a95d8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="196" y="262" fill="#5ba8eb" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="196" y="262" fill="#6a95d8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="392" y="262" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="392" y="262" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="588" y="222" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="588" y="222" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="586" y="330" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="586" y="330" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
|
||||
<!-- Node: Reader -->
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#1c1a17"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(168,166,157,0.10)" stroke="#8e8c83" stroke-width="1"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#2d3142"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(191,192,192,0.10)" stroke="#8e98ac" stroke-width="1"/>
|
||||
<rect x="48" y="248" width="28" height="12" rx="2" fill="transparent" stroke="rgba(142,140,131,0.40)" stroke-width="0.8"/>
|
||||
<text x="62" y="257" fill="#8e8c83" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<text x="62" y="257" fill="#8e98ac" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Node: Cloudflare -->
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#1c1a17"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#8e8c83" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(241,239,231,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#2d3142"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#8e98ac" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(245,245,245,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Node: Astro (focal coral) -->
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#1c1a17"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(255,106,48,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#ff6a30" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(255,106,48,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#2d3142"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#f08a59" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(240,138,89,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Node: MDX Bundle -->
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#1c1a17"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#2d3142"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
|
||||
<!-- Node: Content CMS -->
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#1c1a17"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(168,166,157,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#a8a69d" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#2d3142"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(191,192,192,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#bfc0c0" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(168,166,157,0.10)" stroke="#8e8c83" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(191,192,192,0.10)" stroke="#8e98ac" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#5ba8eb" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#6a95d8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight.com · Architecture</title>
|
||||
<title>Content site · Architecture</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed; --color-paper-2: #efeee5;
|
||||
--color-ink: #0b0d0b; --color-muted: #52534e; --color-soft: #65655c;
|
||||
--color-rule: rgba(11,13,11,0.12);
|
||||
--color-accent: #f7591f; --color-accent-tint: rgba(247,89,31,0.08);
|
||||
--color-link: #1a70c7;
|
||||
--color-paper: #f5f5f5; --color-paper-2: #ececec;
|
||||
--color-ink: #2d3142; --color-muted: #4f5d75; --color-soft: #7a8399;
|
||||
--color-rule: rgba(45,49,66,0.12);
|
||||
--color-accent: #eb6c36; --color-accent-tint: rgba(235,108,54,0.08);
|
||||
--color-link: #2e5aa8;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -29,21 +29,21 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; letter-spacing: -0.005em; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<p class="header-eyebrow">Architecture · Diagram Design</p>
|
||||
<h1>littlemight.com in production</h1>
|
||||
<h1>Content site in production</h1>
|
||||
<p class="subtitle">The static-first stack: Cloudflare's edge absorbs most reads, Astro renders MDX on misses, content is checked into the repo.</p>
|
||||
</div>
|
||||
|
||||
@@ -51,101 +51,101 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows first (behind boxes) -->
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="196" y="262" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="196" y="262" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="392" y="262" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="392" y="262" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="588" y="222" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="588" y="222" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="586" y="330" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="586" y="330" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
|
||||
<!-- Node: Reader -->
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<rect x="48" y="248" width="28" height="12" rx="2" fill="transparent" stroke="rgba(101,101,92,0.40)" stroke-width="0.8"/>
|
||||
<text x="62" y="257" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<rect x="48" y="248" width="28" height="12" rx="2" fill="transparent" stroke="rgba(122,131,153,0.40)" stroke-width="0.8"/>
|
||||
<text x="62" y="257" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Node: Cloudflare -->
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(11,13,11,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(45,49,66,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Node: Astro (focal coral) -->
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(247,89,31,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(235,108,54,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Node: MDX Bundle -->
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
|
||||
<!-- Node: Content CMS -->
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(82,83,78,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#52534e" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(79,93,117,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -166,8 +166,8 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span>littlemight.com · architecture</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>content site · architecture</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight.com · Architecture</title>
|
||||
<title>Content site · Architecture</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,106 +56,106 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">Architecture · Diagram Design</p>
|
||||
<h1>littlemight.com in production</h1>
|
||||
<h1>Content site in production</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows first (behind boxes) -->
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="168" y1="272" x2="220" y2="272" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="364" y1="272" x2="416" y2="272" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="576" y1="256" x2="628" y2="212" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="576" y1="288" x2="628" y2="332" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="196" y="262" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
<rect x="172" y="252" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="196" y="262" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">HTTPS</text>
|
||||
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="392" y="262" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
<rect x="368" y="252" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="392" y="262" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SSR</text>
|
||||
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="588" y="222" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
<rect x="560" y="212" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="588" y="222" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">READ MDX</text>
|
||||
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="586" y="330" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
<rect x="560" y="320" width="52" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="586" y="330" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
|
||||
|
||||
<!-- Node: Reader -->
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<rect x="48" y="248" width="28" height="12" rx="2" fill="transparent" stroke="rgba(101,101,92,0.40)" stroke-width="0.8"/>
|
||||
<text x="62" y="257" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="40" y="240" width="128" height="64" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<rect x="48" y="248" width="28" height="12" rx="2" fill="transparent" stroke="rgba(122,131,153,0.40)" stroke-width="0.8"/>
|
||||
<text x="62" y="257" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="104" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="104" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Node: Cloudflare -->
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(11,13,11,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="220" y="240" width="144" height="64" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<rect x="228" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="244" y="257" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="356" y="300" fill="rgba(45,49,66,0.06)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<text x="292" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="292" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Node: Astro (focal coral) -->
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(247,89,31,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="416" y="240" width="160" height="64" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="424" y="248" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="440" y="257" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="568" y="300" fill="rgba(235,108,54,0.10)" font-size="32" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<text x="496" y="276" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="496" y="292" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Node: MDX Bundle -->
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="628" y="160" width="144" height="64" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="636" y="168" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="652" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BUN</text>
|
||||
<text x="700" y="196" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MDX Bundle</text>
|
||||
<text x="700" y="212" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/*.mdx</text>
|
||||
|
||||
<!-- Node: Content CMS -->
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(82,83,78,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#52534e" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="628" y="320" width="144" height="64" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<rect x="636" y="328" width="28" height="12" rx="2" fill="transparent" stroke="rgba(79,93,117,0.50)" stroke-width="0.8"/>
|
||||
<text x="650" y="337" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CMS</text>
|
||||
<text x="700" y="356" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Content CMS</text>
|
||||
<text x="700" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">assets · og images</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal / origin</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Backend / bundle</text>
|
||||
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
<rect x="340" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<text x="360" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Store</text>
|
||||
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
<rect x="436" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="456" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Cloud</text>
|
||||
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
<rect x="528" y="436" width="14" height="10" rx="2" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<text x="548" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">External</text>
|
||||
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="636" y1="442" x2="664" y2="442" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="672" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
<line x1="784" y1="442" x2="812" y2="442" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="820" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary flow</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight content model · ER</title>
|
||||
<title>Content platform · ER model</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,144 +56,144 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">ER · Diagram Design</p>
|
||||
<h1>littlemight content model</h1>
|
||||
<h1>Content platform · data model</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Relationship lines (drawn first) -->
|
||||
<!-- 1. Author — Article (1:N "writes") -->
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#a8a69d" stroke-width="1" />
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#bfc0c0" stroke-width="1" />
|
||||
<!-- 2. Article — ArticleTag (1:N) -->
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#a8a69d" stroke-width="1" />
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#bfc0c0" stroke-width="1" />
|
||||
<!-- 3. Tag — ArticleTag (1:N, vertical) -->
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#a8a69d" stroke-width="1" />
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#bfc0c0" stroke-width="1" />
|
||||
|
||||
<!-- Cardinality labels -->
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="272" y="242" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="272" y="242" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="386" y="242" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="386" y="242" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="652" y="326" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="652" y="326" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="768" y="334" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="768" y="334" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="880" y="262" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="880" y="262" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="880" y="278" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="880" y="278" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<!-- Relationship labels -->
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#1c1a17"/>
|
||||
<text x="332" y="230" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#2d3142"/>
|
||||
<text x="332" y="230" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#1c1a17"/>
|
||||
<text x="716" y="310" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#2d3142"/>
|
||||
<text x="716" y="310" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
|
||||
<!-- Entity: Author -->
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(241,239,231,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(241,239,231,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(245,245,245,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(245,245,245,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: Article (focal coral) -->
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(255,106,48,0.04)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(255,106,48,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(255,106,48,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(255,106,48,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(240,138,89,0.04)" stroke="#f08a59" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(240,138,89,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(240,138,89,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(240,138,89,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
|
||||
<!-- Entity: Tag -->
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(241,239,231,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(241,239,231,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(245,245,245,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(245,245,245,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: ArticleTag (join) -->
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(241,239,231,0.04)" stroke="#a8a69d" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(241,239,231,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(241,239,231,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(245,245,245,0.04)" stroke="#bfc0c0" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(245,245,245,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(245,245,245,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(255,106,48,0.04)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(240,138,89,0.04)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(241,239,231,0.04)" stroke="#a8a69d" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(245,245,245,0.04)" stroke="#bfc0c0" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
|
||||
<text x="372" y="444" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
<text x="372" y="444" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
|
||||
<text x="476" y="444" fill="#f1efe7" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
<text x="476" y="444" fill="#f5f5f5" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
|
||||
<text x="584" y="444" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
<text x="584" y="444" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight content model · ER</title>
|
||||
<title>Content platform · ER model</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,21 +20,21 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<p class="header-eyebrow">ER · Diagram Design</p>
|
||||
<h1>littlemight content model</h1>
|
||||
<h1>Content platform · data model</h1>
|
||||
<p class="subtitle">The four entities behind the site. Article is the aggregate root — everything else exists to describe or classify it. `#` marks primary keys, `→` marks foreign keys.</p>
|
||||
</div>
|
||||
|
||||
@@ -42,139 +42,139 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Relationship lines (drawn first) -->
|
||||
<!-- 1. Author — Article (1:N "writes") -->
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#4f5d75" stroke-width="1" />
|
||||
<!-- 2. Article — ArticleTag (1:N) -->
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#4f5d75" stroke-width="1" />
|
||||
<!-- 3. Tag — ArticleTag (1:N, vertical) -->
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#4f5d75" stroke-width="1" />
|
||||
|
||||
<!-- Cardinality labels -->
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="272" y="242" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="272" y="242" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="386" y="242" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="386" y="242" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="652" y="326" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="652" y="326" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="768" y="334" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="768" y="334" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="880" y="262" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="880" y="262" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="880" y="278" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="880" y="278" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<!-- Relationship labels -->
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#f5f4ed"/>
|
||||
<text x="332" y="230" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#f5f5f5"/>
|
||||
<text x="332" y="230" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#f5f4ed"/>
|
||||
<text x="716" y="310" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#f5f5f5"/>
|
||||
<text x="716" y="310" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
|
||||
<!-- Entity: Author -->
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(11,13,11,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(11,13,11,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(45,49,66,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(45,49,66,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: Article (focal coral) -->
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(247,89,31,0.04)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(247,89,31,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(247,89,31,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(247,89,31,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(235,108,54,0.04)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(235,108,54,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(235,108,54,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(235,108,54,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
|
||||
<!-- Entity: Tag -->
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(11,13,11,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(11,13,11,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(45,49,66,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(45,49,66,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: ArticleTag (join) -->
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(11,13,11,0.04)" stroke="#52534e" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(11,13,11,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(11,13,11,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(45,49,66,0.04)" stroke="#4f5d75" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(45,49,66,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(45,49,66,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(247,89,31,0.04)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(235,108,54,0.04)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.04)" stroke="#52534e" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.04)" stroke="#4f5d75" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
|
||||
<text x="372" y="444" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
<text x="372" y="444" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
|
||||
<text x="476" y="444" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
<text x="476" y="444" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
|
||||
<text x="584" y="444" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
<text x="584" y="444" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -195,8 +195,8 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span>littlemight content model · ER</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>Content platform · ER model</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight content model · ER</title>
|
||||
<title>Content platform · ER model</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,144 +56,144 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">ER · Diagram Design</p>
|
||||
<h1>littlemight content model</h1>
|
||||
<h1>Content platform · data model</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Relationship lines (drawn first) -->
|
||||
<!-- 1. Author — Article (1:N "writes") -->
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="260" y1="240" x2="400" y2="240" stroke="#4f5d75" stroke-width="1" />
|
||||
<!-- 2. Article — ArticleTag (1:N) -->
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="640" y1="320" x2="780" y2="328" stroke="#4f5d75" stroke-width="1" />
|
||||
<!-- 3. Tag — ArticleTag (1:N, vertical) -->
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#52534e" stroke-width="1" />
|
||||
<line x1="880" y1="248" x2="880" y2="280" stroke="#4f5d75" stroke-width="1" />
|
||||
|
||||
<!-- Cardinality labels -->
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="272" y="242" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="266" y="232" width="12" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="272" y="242" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="386" y="242" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="378" y="232" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="386" y="242" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="652" y="326" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="646" y="316" width="12" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="652" y="326" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="768" y="334" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="760" y="324" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="768" y="334" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="880" y="262" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
<rect x="872" y="252" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="880" y="262" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">1</text>
|
||||
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="880" y="278" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
<rect x="872" y="268" width="16" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="880" y="278" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="middle" font-weight="600">N</text>
|
||||
|
||||
<!-- Relationship labels -->
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#f5f4ed"/>
|
||||
<text x="332" y="230" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
<rect x="304" y="220" width="56" height="14" rx="2" fill="#f5f5f5"/>
|
||||
<text x="332" y="230" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">WRITES</text>
|
||||
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#f5f4ed"/>
|
||||
<text x="716" y="310" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
<rect x="688" y="300" width="56" height="14" rx="2" fill="#f5f5f5"/>
|
||||
<text x="716" y="310" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">TAGGED</text>
|
||||
|
||||
<!-- Entity: Author -->
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(11,13,11,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(11,13,11,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="60" y="160" width="200" height="160" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="60" y="160" width="200" height="40" rx="6" fill="rgba(45,49,66,0.04)" stroke="none"/>
|
||||
<rect x="60" y="192" width="200" height="8" fill="rgba(45,49,66,0.04)"/>
|
||||
<line x1="60" y1="200" x2="260" y2="200" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="76" y="176" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="76" y="192" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Author</text>
|
||||
<text x="76" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="220" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="76" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">handle</text>
|
||||
<text x="220" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="260" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="220" y="260" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="280" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">bio</text>
|
||||
<text x="220" y="280" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="76" y="300" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">site_url</text>
|
||||
<text x="220" y="300" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: Article (focal coral) -->
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(247,89,31,0.04)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(247,89,31,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(247,89,31,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(247,89,31,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
<rect x="400" y="120" width="240" height="240" rx="6" fill="rgba(235,108,54,0.04)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="400" y="120" width="240" height="40" rx="6" fill="rgba(235,108,54,0.10)" stroke="none"/>
|
||||
<rect x="400" y="152" width="240" height="8" fill="rgba(235,108,54,0.10)"/>
|
||||
<line x1="400" y1="160" x2="640" y2="160" stroke="rgba(235,108,54,0.40)" stroke-width="1"/>
|
||||
<text x="416" y="136" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY · AGGREGATE ROOT</text>
|
||||
<text x="416" y="152" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Article</text>
|
||||
<text x="416" y="180" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="600" y="180" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="200" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">title</text>
|
||||
<text x="600" y="200" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="600" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="416" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">body_mdx</text>
|
||||
<text x="600" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="416" y="260" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">published_at</text>
|
||||
<text x="600" y="260" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">timestamp</text>
|
||||
<text x="416" y="280" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ author_id</text>
|
||||
<text x="600" y="280" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="416" y="300" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">status</text>
|
||||
<text x="600" y="300" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">enum</text>
|
||||
<text x="416" y="320" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">og_image</text>
|
||||
<text x="600" y="320" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · url</text>
|
||||
|
||||
<!-- Entity: Tag -->
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(11,13,11,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(11,13,11,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<rect x="780" y="120" width="200" height="128" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="780" y="120" width="200" height="40" rx="6" fill="rgba(45,49,66,0.04)" stroke="none"/>
|
||||
<rect x="780" y="152" width="200" height="8" fill="rgba(45,49,66,0.04)"/>
|
||||
<line x1="780" y1="160" x2="980" y2="160" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="136" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">ENTITY</text>
|
||||
<text x="796" y="152" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">Tag</text>
|
||||
<text x="796" y="180" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace"># id</text>
|
||||
<text x="940" y="180" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="200" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">slug</text>
|
||||
<text x="940" y="200" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text · unique</text>
|
||||
<text x="796" y="220" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">name</text>
|
||||
<text x="940" y="220" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
<text x="796" y="240" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">description</text>
|
||||
<text x="940" y="240" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">text</text>
|
||||
|
||||
<!-- Entity: ArticleTag (join) -->
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(11,13,11,0.04)" stroke="#52534e" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(11,13,11,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(11,13,11,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<rect x="780" y="280" width="200" height="96" rx="6" fill="rgba(45,49,66,0.04)" stroke="#4f5d75" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="780" y="280" width="200" height="40" rx="6" fill="rgba(45,49,66,0.06)" stroke="none"/>
|
||||
<rect x="780" y="312" width="200" height="8" fill="rgba(45,49,66,0.06)"/>
|
||||
<line x1="780" y1="320" x2="980" y2="320" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<text x="796" y="296" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">JOIN</text>
|
||||
<text x="796" y="312" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif">ArticleTag</text>
|
||||
<text x="796" y="340" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ article_id</text>
|
||||
<text x="940" y="340" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
<text x="796" y="360" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace">→ tag_id</text>
|
||||
<text x="940" y="360" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end">uuid</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="404" x2="960" y2="404" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="420" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(247,89,31,0.04)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
<rect x="40" y="436" width="14" height="10" rx="2" fill="rgba(235,108,54,0.04)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Aggregate root</text>
|
||||
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
<rect x="180" y="436" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Entity</text>
|
||||
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(11,13,11,0.04)" stroke="#52534e" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
<rect x="268" y="436" width="14" height="10" rx="2" fill="rgba(45,49,66,0.04)" stroke="#4f5d75" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<text x="288" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Join table</text>
|
||||
|
||||
<text x="372" y="444" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
<text x="372" y="444" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">#</text>
|
||||
<text x="388" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary key</text>
|
||||
|
||||
<text x="476" y="444" fill="#0b0d0b" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
<text x="476" y="444" fill="#2d3142" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">→</text>
|
||||
<text x="492" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Foreign key</text>
|
||||
|
||||
<text x="584" y="444" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
<text x="584" y="444" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" font-weight="600">1 / N</text>
|
||||
<text x="616" y="444" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Cardinality</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,93 +61,93 @@
|
||||
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows (drawn first, behind nodes) -->
|
||||
<!-- Start → Step -->
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Step → Diamond 1 -->
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "NO" right -->
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "YES" down -->
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "NO" right -->
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "YES" down (coral — happy path) -->
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="656" y="239" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="656" y="239" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="500" y="307" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="500" y="307" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="656" y="375" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="656" y="375" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="500" y="443" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="500" y="443" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<!-- Start oval -->
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
|
||||
<!-- Rectangle: Step -->
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
|
||||
<!-- Diamond 1: Repeated >3 times? -->
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
|
||||
<!-- End oval: One-off -->
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
|
||||
<!-- Diamond 2: Reusable across projects? -->
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
|
||||
<!-- End oval: CLAUDE.md note -->
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
|
||||
<!-- End oval: Write a skill (coral focal) -->
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,93 +42,93 @@
|
||||
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows (drawn first, behind nodes) -->
|
||||
<!-- Start → Step -->
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Step → Diamond 1 -->
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "NO" right -->
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "YES" down -->
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "NO" right -->
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "YES" down (coral — happy path) -->
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="656" y="239" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="656" y="239" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="500" y="307" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="500" y="307" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="656" y="375" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="656" y="375" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="500" y="443" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="500" y="443" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<!-- Start oval -->
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
|
||||
<!-- Rectangle: Step -->
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
|
||||
<!-- Diamond 1: Repeated >3 times? -->
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
|
||||
<!-- End oval: One-off -->
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
|
||||
<!-- Diamond 2: Reusable across projects? -->
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
|
||||
<!-- End oval: CLAUDE.md note -->
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
|
||||
<!-- End oval: Write a skill (coral focal) -->
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>flowchart · should I write this as a skill?</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,93 +61,93 @@
|
||||
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Arrows (drawn first, behind nodes) -->
|
||||
<!-- Start → Step -->
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="88" x2="500" y2="120" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Step → Diamond 1 -->
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="168" x2="500" y2="192" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "NO" right -->
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="240" x2="720" y2="240" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 1 "YES" down -->
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="500" y1="288" x2="500" y2="328" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "NO" right -->
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="600" y1="376" x2="720" y2="376" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Diamond 2 "YES" down (coral — happy path) -->
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="424" x2="500" y2="464" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="656" y="239" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="230" width="24" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="656" y="239" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="500" y="307" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="298" width="32" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="500" y="307" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="656" y="375" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
<rect x="644" y="366" width="24" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="656" y="375" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">NO</text>
|
||||
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="500" y="443" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
<rect x="484" y="434" width="32" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="500" y="443" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">YES</text>
|
||||
|
||||
<!-- Start oval -->
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
<rect x="420" y="40" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="500" y="68" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">New workflow</text>
|
||||
|
||||
<!-- Rectangle: Step -->
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
<rect x="420" y="120" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="148" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Do it manually once</text>
|
||||
|
||||
<!-- Diamond 1: Repeated >3 times? -->
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
<polygon points="500,192 600,240 500,288 400,240" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="238" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Will you repeat</text>
|
||||
<text x="500" y="252" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">it >3 times?</text>
|
||||
|
||||
<!-- End oval: One-off -->
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
<rect x="720" y="216" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">One-off</text>
|
||||
<text x="800" y="254" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">keep manual</text>
|
||||
|
||||
<!-- Diamond 2: Reusable across projects? -->
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
<polygon points="500,328 600,376 500,424 400,376" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="500" y="374" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reusable across</text>
|
||||
<text x="500" y="388" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">projects?</text>
|
||||
|
||||
<!-- End oval: CLAUDE.md note -->
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
<rect x="720" y="352" width="160" height="48" rx="24" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="800" y="376" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md note</text>
|
||||
<text x="800" y="390" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">project-scoped</text>
|
||||
|
||||
<!-- End oval: Write a skill (coral focal) -->
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
<rect x="420" y="464" width="160" height="56" rx="28" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="500" y="492" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Write a skill</text>
|
||||
<text x="500" y="508" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">reusable + assets</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
<line x1="40" y1="540" x2="960" y2="540" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="556" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND · SHAPE CARRIES TYPE</text>
|
||||
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
<rect x="40" y="572" width="24" height="12" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="72" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Start / end (oval)</text>
|
||||
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
<rect x="220" y="572" width="24" height="12" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="252" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Step (rectangle)</text>
|
||||
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
<polygon points="412,578 424,572 436,578 424,584" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="448" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Decision (diamond)</text>
|
||||
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
<line x1="604" y1="580" x2="632" y2="580" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="640" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Happy path</text>
|
||||
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
<line x1="768" y1="580" x2="796" y2="580" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="804" y="582" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Branch</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,60 +61,60 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Direction column (left margin) -->
|
||||
<text x="60" y="68" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#a8a69d"/>
|
||||
<text x="60" y="416" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
<text x="60" y="68" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#bfc0c0"/>
|
||||
<text x="60" y="416" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
|
||||
<!-- Stack container hairlines (top + bottom edges) -->
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
|
||||
<!-- L5 — UI (top layer, lifted fill) -->
|
||||
<rect x="120" y="80" width="840" height="64" fill="#2a2723"/>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
<rect x="120" y="80" width="840" height="64" fill="#393e53"/>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
|
||||
<!-- L4 — Agent harness (FOCAL, coral tint + coral stroke) -->
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(255,106,48,0.12)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#ff6a30" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(240,138,89,0.12)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#f08a59" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
|
||||
<!-- L3 — Prompt layer -->
|
||||
<rect x="120" y="208" width="840" height="64" fill="#1c1a17"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
<rect x="120" y="208" width="840" height="64" fill="#2d3142"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
|
||||
<!-- L2 — SDK -->
|
||||
<rect x="120" y="272" width="840" height="64" fill="#221f1c"/>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
|
||||
<!-- L1 — Model -->
|
||||
<rect x="120" y="336" width="840" height="64" fill="#221f1c"/>
|
||||
<text x="140" y="372" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#a8a69d" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
<text x="140" y="372" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#bfc0c0" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
|
||||
<!-- Caption -->
|
||||
<text x="120" y="456" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
<text x="120" y="456" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,60 +42,60 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Direction column (left margin) -->
|
||||
<text x="60" y="68" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#52534e"/>
|
||||
<text x="60" y="416" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
<text x="60" y="68" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#4f5d75"/>
|
||||
<text x="60" y="416" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
|
||||
<!-- Stack container hairlines (top + bottom edges) -->
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
|
||||
<!-- L5 — UI (top layer, near-white fill) -->
|
||||
<rect x="120" y="80" width="840" height="64" fill="#ffffff"/>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
|
||||
<!-- L4 — Agent harness (FOCAL, coral tint + coral stroke) -->
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(247,89,31,0.08)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#f7591f" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(235,108,54,0.08)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#eb6c36" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
|
||||
<!-- L3 — Prompt layer -->
|
||||
<rect x="120" y="208" width="840" height="64" fill="#f5f4ed"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
<rect x="120" y="208" width="840" height="64" fill="#f5f5f5"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
|
||||
<!-- L2 — SDK -->
|
||||
<rect x="120" y="272" width="840" height="64" fill="#efeee5"/>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
<rect x="120" y="272" width="840" height="64" fill="#ececec"/>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
|
||||
<!-- L1 — Model -->
|
||||
<rect x="120" y="336" width="840" height="64" fill="#efeee5"/>
|
||||
<text x="140" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
<rect x="120" y="336" width="840" height="64" fill="#ececec"/>
|
||||
<text x="140" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
|
||||
<!-- Caption -->
|
||||
<text x="120" y="456" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
<text x="120" y="456" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>ai app stack · layer hierarchy</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,60 +61,60 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Direction column (left margin) -->
|
||||
<text x="60" y="68" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#52534e"/>
|
||||
<text x="60" y="416" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
<text x="60" y="68" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
|
||||
<line x1="80" y1="80" x2="80" y2="400" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<polygon points="76,80 84,80 80,72" fill="#4f5d75"/>
|
||||
<text x="60" y="416" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
|
||||
|
||||
<!-- Stack container hairlines (top + bottom edges) -->
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<line x1="120" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
|
||||
<!-- L5 — UI (top layer, near-white fill) -->
|
||||
<rect x="120" y="80" width="840" height="64" fill="#ffffff"/>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
<line x1="120" y1="144" x2="960" y2="144" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="116" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
|
||||
<text x="260" y="118" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
|
||||
<text x="940" y="118" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
|
||||
|
||||
<!-- L4 — Agent harness (FOCAL, coral tint + coral stroke) -->
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(247,89,31,0.08)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#f7591f" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
<rect x="120" y="144" width="840" height="64" fill="rgba(235,108,54,0.08)"/>
|
||||
<rect x="120" y="144" width="840" height="64" fill="none" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="140" y="180" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
|
||||
<text x="260" y="182" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
|
||||
<text x="940" y="182" fill="#eb6c36" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
|
||||
|
||||
<!-- L3 — Prompt layer -->
|
||||
<rect x="120" y="208" width="840" height="64" fill="#f5f4ed"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
<rect x="120" y="208" width="840" height="64" fill="#f5f5f5"/>
|
||||
<line x1="120" y1="272" x2="960" y2="272" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="244" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
|
||||
<text x="260" y="246" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
|
||||
<text x="940" y="246" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
|
||||
|
||||
<!-- L2 — SDK -->
|
||||
<rect x="120" y="272" width="840" height="64" fill="#efeee5"/>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
<rect x="120" y="272" width="840" height="64" fill="#ececec"/>
|
||||
<line x1="120" y1="336" x2="960" y2="336" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="140" y="308" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
|
||||
<text x="260" y="310" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
|
||||
<text x="940" y="310" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
|
||||
|
||||
<!-- L1 — Model -->
|
||||
<rect x="120" y="336" width="840" height="64" fill="#efeee5"/>
|
||||
<text x="140" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#52534e" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
<rect x="120" y="336" width="840" height="64" fill="#ececec"/>
|
||||
<text x="140" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
|
||||
<text x="260" y="374" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
|
||||
<text x="940" y="374" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
|
||||
|
||||
<!-- Caption -->
|
||||
<text x="120" y="456" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
<text x="120" y="456" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
|
||||
<text x="240" y="456" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,69 +61,69 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Level 1: ~/.claude/ (global) — outermost -->
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(241,239,231,0.015)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(245,245,245,0.015)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<!-- Level 2: ~/vault/ -->
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(241,239,231,0.02)" stroke="rgba(241,239,231,0.35)" stroke-width="1"/>
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(245,245,245,0.02)" stroke="rgba(245,245,245,0.35)" stroke-width="1"/>
|
||||
<!-- Level 3: /business -->
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(241,239,231,0.025)" stroke="rgba(241,239,231,0.45)" stroke-width="1"/>
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(245,245,245,0.025)" stroke="rgba(245,245,245,0.45)" stroke-width="1"/>
|
||||
<!-- Level 4: /marketing -->
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(241,239,231,0.03)" stroke="#a8a69d" stroke-width="1"/>
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(245,245,245,0.03)" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<!-- Level 5: /project — innermost, coral focal -->
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
|
||||
<!-- Level labels on paper-colored masks -->
|
||||
<rect x="56" y="52" width="188" height="16" fill="#1c1a17"/>
|
||||
<text x="64" y="64" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
<rect x="56" y="52" width="188" height="16" fill="#2d3142"/>
|
||||
<text x="64" y="64" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
|
||||
<rect x="88" y="88" width="148" height="16" fill="#1c1a17"/>
|
||||
<text x="96" y="100" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
<rect x="88" y="88" width="148" height="16" fill="#2d3142"/>
|
||||
<text x="96" y="100" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
|
||||
<rect x="120" y="124" width="96" height="16" fill="#1c1a17"/>
|
||||
<text x="128" y="136" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
<rect x="120" y="124" width="96" height="16" fill="#2d3142"/>
|
||||
<text x="128" y="136" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
|
||||
<rect x="152" y="160" width="108" height="16" fill="#1c1a17"/>
|
||||
<text x="160" y="172" fill="#f1efe7" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
<rect x="152" y="160" width="108" height="16" fill="#2d3142"/>
|
||||
<text x="160" y="172" fill="#f5f5f5" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
|
||||
<rect x="184" y="196" width="88" height="16" fill="#1c1a17"/>
|
||||
<text x="192" y="208" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
<rect x="184" y="196" width="88" height="16" fill="#2d3142"/>
|
||||
<text x="192" y="208" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
|
||||
<!-- File-icon glyphs (simple rect with folded corner) inside each level -->
|
||||
<g transform="translate(908, 408)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#1c1a17" stroke="rgba(241,239,231,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(241,239,231,0.35)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#2d3142" stroke="rgba(245,245,245,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(245,245,245,0.35)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(876, 372)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#1c1a17" stroke="rgba(241,239,231,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(241,239,231,0.40)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#2d3142" stroke="rgba(245,245,245,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(245,245,245,0.40)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(844, 336)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#1c1a17" stroke="rgba(241,239,231,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(241,239,231,0.50)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#2d3142" stroke="rgba(245,245,245,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(245,245,245,0.50)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(812, 300)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#1c1a17" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#2d3142" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- Innermost label — human readable -->
|
||||
<text x="500" y="248" fill="#f1efe7" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
<text x="500" y="248" fill="#f5f5f5" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
|
||||
<!-- Annotation top-right: italic callout with curved arrow -->
|
||||
<text x="904" y="36" fill="#f1efe7" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(241,239,231,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#f1efe7"/>
|
||||
<text x="904" y="36" fill="#f5f5f5" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(245,245,245,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#f5f5f5"/>
|
||||
|
||||
<!-- Annotation bottom-left: italic callout -->
|
||||
<text x="40" y="484" fill="#a8a69d" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
<text x="40" y="484" fill="#bfc0c0" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,69 +42,69 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Level 1: ~/.claude/ (global) — outermost -->
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(11,13,11,0.015)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(45,49,66,0.015)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<!-- Level 2: ~/vault/ -->
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(11,13,11,0.02)" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(45,49,66,0.02)" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
<!-- Level 3: /business -->
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(11,13,11,0.025)" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(45,49,66,0.025)" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
<!-- Level 4: /marketing -->
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(11,13,11,0.03)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(45,49,66,0.03)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<!-- Level 5: /project — innermost, coral focal -->
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(247,89,31,0.06)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(235,108,54,0.06)" stroke="#eb6c36" stroke-width="1"/>
|
||||
|
||||
<!-- Level labels on paper-2-colored masks (match diagram-container bg) -->
|
||||
<rect x="56" y="52" width="188" height="16" fill="#efeee5"/>
|
||||
<text x="64" y="64" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
<rect x="56" y="52" width="188" height="16" fill="#ececec"/>
|
||||
<text x="64" y="64" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
|
||||
<rect x="88" y="88" width="148" height="16" fill="#efeee5"/>
|
||||
<text x="96" y="100" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
<rect x="88" y="88" width="148" height="16" fill="#ececec"/>
|
||||
<text x="96" y="100" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
|
||||
<rect x="120" y="124" width="96" height="16" fill="#efeee5"/>
|
||||
<text x="128" y="136" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
<rect x="120" y="124" width="96" height="16" fill="#ececec"/>
|
||||
<text x="128" y="136" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
|
||||
<rect x="152" y="160" width="108" height="16" fill="#efeee5"/>
|
||||
<text x="160" y="172" fill="#0b0d0b" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
<rect x="152" y="160" width="108" height="16" fill="#ececec"/>
|
||||
<text x="160" y="172" fill="#2d3142" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
|
||||
<rect x="184" y="196" width="88" height="16" fill="#efeee5"/>
|
||||
<text x="192" y="208" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
<rect x="184" y="196" width="88" height="16" fill="#ececec"/>
|
||||
<text x="192" y="208" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
|
||||
<!-- File-icon glyphs inside each level -->
|
||||
<g transform="translate(908, 408)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#efeee5" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#ececec" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(876, 372)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#efeee5" stroke="rgba(11,13,11,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.40)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#ececec" stroke="rgba(45,49,66,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(844, 336)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#efeee5" stroke="rgba(11,13,11,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.50)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#ececec" stroke="rgba(45,49,66,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.50)" stroke-width="1"/>
|
||||
</g>
|
||||
<g transform="translate(812, 300)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#efeee5" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#ececec" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- Innermost label — human readable -->
|
||||
<text x="500" y="248" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
<text x="500" y="248" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
|
||||
<!-- Annotation top-right: italic callout with curved arrow -->
|
||||
<text x="904" y="36" fill="#0b0d0b" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(11,13,11,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#0b0d0b"/>
|
||||
<text x="904" y="36" fill="#2d3142" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#2d3142"/>
|
||||
|
||||
<!-- Annotation bottom-left: italic callout -->
|
||||
<text x="40" y="484" fill="#52534e" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
<text x="40" y="484" fill="#4f5d75" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>the claude.md hierarchy · nested containment</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,73 +61,73 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Level 1: ~/.claude/ (global) — outermost -->
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(11,13,11,0.015)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="40" y="60" width="920" height="380" rx="8" fill="rgba(45,49,66,0.015)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<!-- Level 2: ~/vault/ -->
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(11,13,11,0.02)" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<rect x="72" y="96" width="856" height="308" rx="8" fill="rgba(45,49,66,0.02)" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
<!-- Level 3: /business -->
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(11,13,11,0.025)" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<rect x="104" y="132" width="792" height="236" rx="8" fill="rgba(45,49,66,0.025)" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
<!-- Level 4: /marketing -->
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(11,13,11,0.03)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="136" y="168" width="728" height="164" rx="8" fill="rgba(45,49,66,0.03)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<!-- Level 5: /project — innermost, coral focal -->
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(247,89,31,0.06)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="168" y="204" width="664" height="92" rx="8" fill="rgba(235,108,54,0.06)" stroke="#eb6c36" stroke-width="1"/>
|
||||
|
||||
<!-- Level labels on paper-colored masks -->
|
||||
<rect x="56" y="52" width="188" height="16" fill="#f5f4ed"/>
|
||||
<text x="64" y="64" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
<rect x="56" y="52" width="188" height="16" fill="#f5f5f5"/>
|
||||
<text x="64" y="64" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/.claude/ (global)</text>
|
||||
|
||||
<rect x="88" y="88" width="148" height="16" fill="#f5f4ed"/>
|
||||
<text x="96" y="100" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
<rect x="88" y="88" width="148" height="16" fill="#f5f5f5"/>
|
||||
<text x="96" y="100" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">~/vault/ (notes)</text>
|
||||
|
||||
<rect x="120" y="124" width="96" height="16" fill="#f5f4ed"/>
|
||||
<text x="128" y="136" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
<rect x="120" y="124" width="96" height="16" fill="#f5f5f5"/>
|
||||
<text x="128" y="136" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/business</text>
|
||||
|
||||
<rect x="152" y="160" width="108" height="16" fill="#f5f4ed"/>
|
||||
<text x="160" y="172" fill="#0b0d0b" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
<rect x="152" y="160" width="108" height="16" fill="#f5f5f5"/>
|
||||
<text x="160" y="172" fill="#2d3142" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">/marketing</text>
|
||||
|
||||
<rect x="184" y="196" width="88" height="16" fill="#f5f4ed"/>
|
||||
<text x="192" y="208" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
<rect x="184" y="196" width="88" height="16" fill="#f5f5f5"/>
|
||||
<text x="192" y="208" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">/project</text>
|
||||
|
||||
<!-- File-icon glyphs (simple rect with folded corner) inside each level -->
|
||||
<!-- Glyph in level 1 (bottom-right area of outer ring) -->
|
||||
<g transform="translate(908, 408)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f4ed" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.35)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f5f5" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.35)" stroke-width="1"/>
|
||||
</g>
|
||||
<!-- Glyph in level 2 ring -->
|
||||
<g transform="translate(876, 372)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f4ed" stroke="rgba(11,13,11,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.40)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f5f5" stroke="rgba(45,49,66,0.40)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="1"/>
|
||||
</g>
|
||||
<!-- Glyph in level 3 ring -->
|
||||
<g transform="translate(844, 336)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f4ed" stroke="rgba(11,13,11,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(11,13,11,0.50)" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f5f5" stroke="rgba(45,49,66,0.50)" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="rgba(45,49,66,0.50)" stroke-width="1"/>
|
||||
</g>
|
||||
<!-- Glyph in level 4 ring -->
|
||||
<g transform="translate(812, 300)">
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f4ed" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M0 0 L16 0 L20 4 L20 20 L0 20 Z" fill="#f5f5f5" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M16 0 L16 4 L20 4" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- Innermost label — human readable -->
|
||||
<text x="500" y="248" fill="#0b0d0b" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
<text x="500" y="248" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CLAUDE.md</text>
|
||||
<text x="500" y="272" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">inherits every level above</text>
|
||||
|
||||
<!-- Annotation top-right: italic callout with curved arrow -->
|
||||
<text x="904" y="36" fill="#0b0d0b" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(11,13,11,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#0b0d0b"/>
|
||||
<text x="904" y="36" fill="#2d3142" font-size="14" font-style="italic" font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none" stroke="rgba(45,49,66,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#2d3142"/>
|
||||
|
||||
<!-- Annotation bottom-left: italic callout -->
|
||||
<text x="40" y="484" fill="#52534e" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
<text x="40" y="484" fill="#4f5d75" font-size="14" font-style="italic" font-family="'Instrument Serif', serif">structure IS the index</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,56 +61,56 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Left axis: direction of rarity -->
|
||||
<line x1="100" y1="112" x2="100" y2="320" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,112 104,112 100,100" fill="rgba(241,239,231,0.45)"/>
|
||||
<text x="80" y="216" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
<line x1="100" y1="40" x2="100" y2="320" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,40 104,40 100,28" fill="rgba(245,245,245,0.45)"/>
|
||||
<text x="80" y="216" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
|
||||
<!-- Base layer: Short posts -->
|
||||
<polygon points="240,280 760,280 820,344 180,344" fill="rgba(241,239,231,0.04)" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
<polygon points="244,280 756,280 820,344 180,344" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
|
||||
<!-- L3: Essays -->
|
||||
<polygon points="300,216 700,216 760,280 240,280" fill="rgba(241,239,231,0.04)" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
<polygon points="308,216 692,216 756,280 244,280" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
|
||||
<!-- L2: Long-form guides -->
|
||||
<polygon points="360,152 640,152 700,216 300,216" fill="rgba(241,239,231,0.04)" stroke="rgba(241,239,231,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
<polygon points="372,152 628,152 692,216 308,216" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (triangle, pointed) -->
|
||||
<polygon points="500,76 640,152 360,152" fill="rgba(255,106,48,0.10)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#ff6a30" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (true pyramid peak — single triangle, consistent slope with layers below) -->
|
||||
<polygon points="500,24 628,152 372,152" fill="rgba(240,138,89,0.10)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#f08a59" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
|
||||
<!-- Footnote under pyramid -->
|
||||
<text x="500" y="384" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
<text x="500" y="384" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(255,106,48,0.10)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(240,138,89,0.10)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
|
||||
<rect x="280" y="464" width="16" height="12" fill="rgba(241,239,231,0.04)" stroke="rgba(241,239,231,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
<rect x="280" y="464" width="16" height="12" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
|
||||
<text x="560" y="474" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
<text x="560" y="474" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,56 +42,56 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Left axis: direction of rarity -->
|
||||
<line x1="100" y1="112" x2="100" y2="320" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,112 104,112 100,100" fill="rgba(11,13,11,0.45)"/>
|
||||
<text x="80" y="216" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
<line x1="100" y1="40" x2="100" y2="320" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,40 104,40 100,28" fill="rgba(45,49,66,0.45)"/>
|
||||
<text x="80" y="216" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
|
||||
<!-- Base layer: Short posts -->
|
||||
<polygon points="240,280 760,280 820,344 180,344" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
<polygon points="244,280 756,280 820,344 180,344" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
|
||||
<!-- L3: Essays -->
|
||||
<polygon points="300,216 700,216 760,280 240,280" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
<polygon points="308,216 692,216 756,280 244,280" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
|
||||
<!-- L2: Long-form guides -->
|
||||
<polygon points="360,152 640,152 700,216 300,216" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
<polygon points="372,152 628,152 692,216 308,216" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (triangle, pointed) -->
|
||||
<polygon points="500,76 640,152 360,152" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#f7591f" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (true pyramid peak — single triangle, consistent slope with layers below) -->
|
||||
<polygon points="500,24 628,152 372,152" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#eb6c36" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
|
||||
<!-- Footnote under pyramid -->
|
||||
<text x="500" y="384" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
<text x="500" y="384" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
|
||||
<rect x="280" y="464" width="16" height="12" fill="#efeee5" stroke="rgba(11,13,11,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
<rect x="280" y="464" width="16" height="12" fill="#ececec" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
|
||||
<text x="560" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
<text x="560" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>content pyramid · what compounds</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,56 +61,56 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Left axis: direction of rarity -->
|
||||
<line x1="100" y1="112" x2="100" y2="320" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,112 104,112 100,100" fill="rgba(11,13,11,0.45)"/>
|
||||
<text x="80" y="216" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
<line x1="100" y1="40" x2="100" y2="320" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<polygon points="96,40 104,40 100,28" fill="rgba(45,49,66,0.45)"/>
|
||||
<text x="80" y="216" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="middle" transform="rotate(-90 80 216)">RARER · FEWER · COMPOUNDS ↑</text>
|
||||
|
||||
<!-- Base layer: Short posts -->
|
||||
<polygon points="240,280 760,280 820,344 180,344" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
<polygon points="244,280 756,280 820,344 180,344" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Short posts</text>
|
||||
<text x="500" y="324" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">daily · ~200 words</text>
|
||||
<text x="836" y="316" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~240/yr</text>
|
||||
|
||||
<!-- L3: Essays -->
|
||||
<polygon points="300,216 700,216 760,280 240,280" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
<polygon points="308,216 692,216 756,280 244,280" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="244" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Essays</text>
|
||||
<text x="500" y="260" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">weekly · 800–1,500 words</text>
|
||||
<text x="776" y="252" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~48/yr</text>
|
||||
|
||||
<!-- L2: Long-form guides -->
|
||||
<polygon points="360,152 640,152 700,216 300,216" fill="#efeee5" stroke="rgba(11,13,11,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#65655c" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
<polygon points="372,152 628,152 692,216 308,216" fill="#ececec" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
||||
<text x="500" y="180" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Long-form guides</text>
|
||||
<text x="500" y="196" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">quarterly · 4,000+ words</text>
|
||||
<text x="716" y="188" fill="#7a8399" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">~4/yr</text>
|
||||
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (triangle, pointed) -->
|
||||
<polygon points="500,76 640,152 360,152" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#f7591f" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
<!-- Apex: Flagship book — CORAL FOCAL (true pyramid peak — single triangle, consistent slope with layers below) -->
|
||||
<polygon points="500,24 628,152 372,152" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="500" y="120" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Flagship book</text>
|
||||
<text x="500" y="136" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">every 3–5 years</text>
|
||||
<text x="656" y="112" fill="#eb6c36" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.08em">the apex</text>
|
||||
|
||||
<!-- Footnote under pyramid -->
|
||||
<text x="500" y="384" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
<text x="500" y="384" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" text-anchor="middle" font-style="italic">The base funds the apex. The apex defines the base.</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="436" x2="960" y2="436" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="452" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
<rect x="40" y="464" width="16" height="12" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="64" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Apex — rarest, highest leverage</text>
|
||||
|
||||
<rect x="280" y="464" width="16" height="12" fill="#efeee5" stroke="rgba(11,13,11,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
<rect x="280" y="464" width="16" height="12" fill="#ececec" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
|
||||
<text x="304" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Supporting layer — the volume work</text>
|
||||
|
||||
<text x="560" y="474" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
<text x="560" y="474" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Layer width is honest: narrower = rarer shipping cadence.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Workplace 2030 · Remote work × AI automation</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f5f5;
|
||||
--color-paper-2: #ececec;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-soft: #7a8399;
|
||||
--color-rule: rgba(45,49,66,0.12);
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
}
|
||||
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
.header-eyebrow { font-family: var(--font-mono); font-size: 0.66rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.75rem; }
|
||||
h1 { font-family: var(--font-serif); font-size: clamp(1.75rem, 3vw + 1rem, 2.5rem); font-weight: 400; letter-spacing: -0.02em; line-height: 1.1; margin-bottom: 0.5rem; }
|
||||
.subtitle { font-size: 1rem; line-height: 1.55; color: var(--color-muted); max-width: 58ch; }
|
||||
|
||||
.diagram-container { background: transparent; border: none; padding: 0; overflow-x: auto; }
|
||||
svg { width: 100%; min-width: 900px; display: block; }
|
||||
|
||||
.cards { display: grid; grid-template-columns: 1.1fr 1fr 0.9fr; gap: 1rem; margin-top: 1.5rem; }
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); }
|
||||
.card-dot.muted { background: var(--color-muted); }
|
||||
.card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<p class="header-eyebrow">Quadrant · Consultant special</p>
|
||||
<h1>Workplace 2030 · Remote × AI automation</h1>
|
||||
<p class="subtitle">Four named futures, one matrix. Scenario planning in the consultant 2×2 form — two independent drivers, four equal-weight cells, one quadrant carrying the coral bet.</p>
|
||||
</div>
|
||||
|
||||
<div class="diagram-container">
|
||||
<svg viewBox="0 0 1000 660" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<!-- Double-ended axis markers -->
|
||||
<marker id="axis-end" markerWidth="9" markerHeight="7" refX="8" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 9 3.5, 0 7" fill="#2d3142"/>
|
||||
</marker>
|
||||
<marker id="axis-start" markerWidth="9" markerHeight="7" refX="1" refY="3.5" orient="auto">
|
||||
<polygon points="9 0, 0 3.5, 9 7" fill="#2d3142"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Clean paper background, no dot pattern -->
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
|
||||
<!-- Focal quadrant tint (TR) — coral at 3% -->
|
||||
<rect x="500" y="80" width="400" height="220" fill="rgba(235,108,54,0.04)"/>
|
||||
|
||||
<!-- Scenario cells — store treatment with hairline rule, slightly varied -->
|
||||
<!-- TL: Distributed humans -->
|
||||
<rect x="140" y="120" width="300" height="160" rx="6" fill="rgba(45,49,66,0.04)" stroke="rgba(79,93,117,0.28)" stroke-width="1"/>
|
||||
<text x="156" y="144" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.18em">01 · HIGH REMOTE / LOW AI</text>
|
||||
<text x="156" y="180" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Distributed humans</text>
|
||||
<text x="156" y="216" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Async-first, global hiring,</text>
|
||||
<text x="156" y="232" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Slack-heavy. Human-centric</text>
|
||||
<text x="156" y="248" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">workflows, low AI leverage.</text>
|
||||
|
||||
<!-- TR: Agent teams (FOCAL) -->
|
||||
<rect x="560" y="120" width="300" height="160" rx="6" fill="rgba(235,108,54,0.06)" stroke="#eb6c36" stroke-width="1.2"/>
|
||||
<text x="576" y="144" fill="#eb6c36" font-size="8" font-weight="600" font-family="'Geist Mono', monospace" letter-spacing="0.18em">02 · HIGH REMOTE / HIGH AI</text>
|
||||
<text x="576" y="180" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent teams <tspan fill="#eb6c36" font-size="13">●</tspan></text>
|
||||
<text x="576" y="216" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Humans orchestrate; AI</text>
|
||||
<text x="576" y="232" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">handles the routine layer.</text>
|
||||
<text x="576" y="248" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Small, high-leverage teams.</text>
|
||||
|
||||
<!-- BL: Office classic -->
|
||||
<rect x="140" y="320" width="300" height="160" rx="6" fill="rgba(45,49,66,0.04)" stroke="rgba(79,93,117,0.28)" stroke-width="1"/>
|
||||
<text x="156" y="344" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.18em">03 · LOW REMOTE / LOW AI</text>
|
||||
<text x="156" y="380" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Office classic</text>
|
||||
<text x="156" y="416" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Return-to-office mandates,</text>
|
||||
<text x="156" y="432" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">manual work. Techlash</text>
|
||||
<text x="156" y="448" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">prolongs the status quo.</text>
|
||||
|
||||
<!-- BR: In-person + AI -->
|
||||
<rect x="560" y="320" width="300" height="160" rx="6" fill="rgba(45,49,66,0.04)" stroke="rgba(79,93,117,0.28)" stroke-width="1"/>
|
||||
<text x="576" y="344" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.18em">04 · LOW REMOTE / HIGH AI</text>
|
||||
<text x="576" y="380" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">In-person + AI</text>
|
||||
<text x="576" y="416" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Smart offices, AI-augmented</text>
|
||||
<text x="576" y="432" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">staff. Physical presence is</text>
|
||||
<text x="576" y="448" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">the moat, AI is the lever.</text>
|
||||
|
||||
<!-- Axis cross — ink, heavier than standard quadrant, double-ended -->
|
||||
<line x1="80" y1="300" x2="920" y2="300"
|
||||
stroke="#2d3142" stroke-width="1.2"
|
||||
marker-start="url(#axis-start)" marker-end="url(#axis-end)"/>
|
||||
<line x1="500" y1="60" x2="500" y2="540"
|
||||
stroke="#2d3142" stroke-width="1.2"
|
||||
marker-start="url(#axis-start)" marker-end="url(#axis-end)"/>
|
||||
|
||||
<!-- Axis labels — driver name + range (eyebrow + sublabel) -->
|
||||
<!-- Top (vertical axis, maximum) -->
|
||||
<text x="508" y="40" fill="#2d3142" font-size="9" font-weight="600" font-family="'Geist Mono', monospace" letter-spacing="0.18em">↑ AI AUTOMATION</text>
|
||||
<text x="508" y="56" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace">high</text>
|
||||
<!-- Bottom (vertical axis, minimum) -->
|
||||
<text x="508" y="560" fill="#2d3142" font-size="9" font-weight="600" font-family="'Geist Mono', monospace" letter-spacing="0.18em">↓ AI AUTOMATION</text>
|
||||
<text x="508" y="576" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace">low</text>
|
||||
<!-- Left (horizontal axis, minimum) -->
|
||||
<text x="60" y="292" fill="#2d3142" font-size="9" font-weight="600" font-family="'Geist Mono', monospace" letter-spacing="0.18em">← REMOTE WORK</text>
|
||||
<text x="60" y="308" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace">low</text>
|
||||
<!-- Right (horizontal axis, maximum) -->
|
||||
<text x="940" y="292" fill="#2d3142" font-size="9" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">REMOTE WORK →</text>
|
||||
<text x="940" y="308" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end">high</text>
|
||||
|
||||
<!-- Legend — horizontal strip, placed BELOW the bottom axis labels (y=560/576) -->
|
||||
<line x1="40" y1="604" x2="960" y2="604" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<rect x="40" y="616" width="16" height="16" rx="3" fill="rgba(235,108,54,0.06)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="64" y="628" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Headline bet</text>
|
||||
<rect x="160" y="616" width="16" height="16" rx="3" fill="rgba(45,49,66,0.04)" stroke="rgba(79,93,117,0.28)" stroke-width="1"/>
|
||||
<text x="184" y="628" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Candidate future</text>
|
||||
<text x="304" y="628" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Every cell is named. The axes carry the range; the coral quadrant carries the commitment.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<p class="eyebrow">THE HEADLINE</p>
|
||||
<div class="card-header"><span class="card-dot coral"></span><h3>Name every future</h3></div>
|
||||
<p>Scenario planning fails when three of the four cells are placeholders. Forcing a name on each future — even the "won't happen" ones — surfaces the assumptions hiding in the axes.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><span class="card-dot ink"></span><h3>Variant rules</h3></div>
|
||||
<ul>
|
||||
<li>Double-ended arrows on both axes (spectrum, not flow)</li>
|
||||
<li>Named cells, not plotted items</li>
|
||||
<li>Driver name + range on each arrow tip</li>
|
||||
<li>Coral on one focal quadrant max</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><span class="card-dot muted"></span><h3>When to use</h3></div>
|
||||
<p>Reach for the consultant 2×2 for scenario planning, positioning frames, or strategy sessions where four named archetypes beat a plotted point cloud. If you're prioritising, use the standard quadrant instead.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span>workplace 2030 · remote × AI automation</span>
|
||||
<span>example · consultant special</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,72 +61,72 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Quadrant backgrounds (very subtle, only coral on DO FIRST) -->
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(255,106,48,0.03)"/>
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(240,138,89,0.03)"/>
|
||||
|
||||
<!-- Axis cross -->
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(241,239,231,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(241,239,231,0.45)" stroke-width="1"/>
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(245,245,245,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(245,245,245,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Axis end labels -->
|
||||
<text x="880" y="266" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
<text x="880" y="266" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
|
||||
<!-- Quadrant corner labels -->
|
||||
<text x="140" y="104" fill="#ff6a30" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
<text x="140" y="104" fill="#f08a59" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
|
||||
<!-- Items: TL (Do First) -->
|
||||
<!-- coral focal -->
|
||||
<circle cx="220" cy="140" r="6" fill="#ff6a30"/>
|
||||
<text x="232" y="144" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif">diagram-design</text>
|
||||
<circle cx="220" cy="140" r="6" fill="#f08a59"/>
|
||||
<text x="232" y="144" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif">Schematic skill v4</text>
|
||||
|
||||
<circle cx="320" cy="200" r="4" fill="#f1efe7"/>
|
||||
<text x="332" y="204" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
<circle cx="320" cy="200" r="4" fill="#f5f5f5"/>
|
||||
<text x="332" y="204" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
|
||||
<!-- Items: TR (Major Projects) -->
|
||||
<circle cx="620" cy="140" r="4" fill="#f1efe7"/>
|
||||
<text x="632" y="144" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
<circle cx="620" cy="140" r="4" fill="#f5f5f5"/>
|
||||
<text x="632" y="144" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
|
||||
<circle cx="760" cy="180" r="4" fill="#f1efe7"/>
|
||||
<text x="772" y="184" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
<circle cx="760" cy="180" r="4" fill="#f5f5f5"/>
|
||||
<text x="772" y="184" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
|
||||
<!-- Items: BL (Quick Wins) -->
|
||||
<circle cx="260" cy="320" r="4" fill="#f1efe7"/>
|
||||
<text x="272" y="324" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
<circle cx="260" cy="320" r="4" fill="#f5f5f5"/>
|
||||
<text x="272" y="324" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
|
||||
<circle cx="360" cy="380" r="4" fill="#f1efe7"/>
|
||||
<text x="372" y="384" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
<circle cx="360" cy="380" r="4" fill="#f5f5f5"/>
|
||||
<text x="372" y="384" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
|
||||
<!-- Items: BR (Avoid) -->
|
||||
<circle cx="640" cy="380" r="4" fill="#f1efe7"/>
|
||||
<text x="652" y="384" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
<circle cx="640" cy="380" r="4" fill="#f5f5f5"/>
|
||||
<text x="652" y="384" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
|
||||
<circle cx="780" cy="320" r="4" fill="#f1efe7"/>
|
||||
<text x="792" y="324" fill="#a8a69d" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
<circle cx="780" cy="320" r="4" fill="#f5f5f5"/>
|
||||
<text x="792" y="324" fill="#bfc0c0" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="#ff6a30"/>
|
||||
<text x="68" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
<circle cx="52" cy="488" r="6" fill="#f08a59"/>
|
||||
<text x="68" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
|
||||
<circle cx="192" cy="488" r="4" fill="#f1efe7"/>
|
||||
<text x="208" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
<circle cx="192" cy="488" r="4" fill="#f5f5f5"/>
|
||||
<text x="208" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
|
||||
<text x="336" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
<text x="336" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,72 +42,72 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Quadrant backgrounds (very subtle, only coral on DO FIRST) -->
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(247,89,31,0.03)"/>
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(235,108,54,0.03)"/>
|
||||
|
||||
<!-- Axis cross -->
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Axis end labels -->
|
||||
<text x="880" y="266" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
<text x="880" y="266" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
|
||||
<!-- Quadrant corner labels -->
|
||||
<text x="140" y="104" fill="#f7591f" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
<text x="140" y="104" fill="#eb6c36" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
|
||||
<!-- Items: TL (Do First) -->
|
||||
<!-- coral focal -->
|
||||
<circle cx="220" cy="140" r="6" fill="#f7591f"/>
|
||||
<text x="232" y="144" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif">diagram-design</text>
|
||||
<circle cx="220" cy="140" r="6" fill="#eb6c36"/>
|
||||
<text x="232" y="144" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif">Schematic skill v4</text>
|
||||
|
||||
<circle cx="320" cy="200" r="4" fill="#0b0d0b"/>
|
||||
<text x="332" y="204" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
<circle cx="320" cy="200" r="4" fill="#2d3142"/>
|
||||
<text x="332" y="204" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
|
||||
<!-- Items: TR (Major Projects) -->
|
||||
<circle cx="620" cy="140" r="4" fill="#0b0d0b"/>
|
||||
<text x="632" y="144" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
<circle cx="620" cy="140" r="4" fill="#2d3142"/>
|
||||
<text x="632" y="144" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
|
||||
<circle cx="760" cy="180" r="4" fill="#0b0d0b"/>
|
||||
<text x="772" y="184" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
<circle cx="760" cy="180" r="4" fill="#2d3142"/>
|
||||
<text x="772" y="184" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
|
||||
<!-- Items: BL (Quick Wins) -->
|
||||
<circle cx="260" cy="320" r="4" fill="#0b0d0b"/>
|
||||
<text x="272" y="324" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
<circle cx="260" cy="320" r="4" fill="#2d3142"/>
|
||||
<text x="272" y="324" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
|
||||
<circle cx="360" cy="380" r="4" fill="#0b0d0b"/>
|
||||
<text x="372" y="384" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
<circle cx="360" cy="380" r="4" fill="#2d3142"/>
|
||||
<text x="372" y="384" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
|
||||
<!-- Items: BR (Avoid) -->
|
||||
<circle cx="640" cy="380" r="4" fill="#0b0d0b"/>
|
||||
<text x="652" y="384" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
<circle cx="640" cy="380" r="4" fill="#2d3142"/>
|
||||
<text x="652" y="384" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
|
||||
<circle cx="780" cy="320" r="4" fill="#0b0d0b"/>
|
||||
<text x="792" y="324" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
<circle cx="780" cy="320" r="4" fill="#2d3142"/>
|
||||
<text x="792" y="324" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="#f7591f"/>
|
||||
<text x="68" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
<circle cx="52" cy="488" r="6" fill="#eb6c36"/>
|
||||
<text x="68" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
|
||||
<circle cx="192" cy="488" r="4" fill="#0b0d0b"/>
|
||||
<text x="208" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
<circle cx="192" cy="488" r="4" fill="#2d3142"/>
|
||||
<text x="208" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
|
||||
<text x="336" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
<text x="336" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>content ideas · impact × effort</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,72 +61,72 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Quadrant backgrounds (very subtle, only coral on DO FIRST) -->
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(247,89,31,0.03)"/>
|
||||
<rect x="120" y="80" width="380" height="170" fill="rgba(235,108,54,0.03)"/>
|
||||
|
||||
<!-- Axis cross -->
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(11,13,11,0.45)" stroke-width="1"/>
|
||||
<line x1="120" y1="250" x2="880" y2="250" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
<line x1="500" y1="80" x2="500" y2="420" stroke="rgba(45,49,66,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Axis end labels -->
|
||||
<text x="880" y="266" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
<text x="880" y="266" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">HIGH EFFORT →</text>
|
||||
<text x="120" y="266" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">← LOW EFFORT</text>
|
||||
<text x="512" y="80" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↑ HIGH IMPACT</text>
|
||||
<text x="512" y="432" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">↓ LOW IMPACT</text>
|
||||
|
||||
<!-- Quadrant corner labels -->
|
||||
<text x="140" y="104" fill="#f7591f" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
<text x="140" y="104" fill="#eb6c36" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em" font-weight="600">DO FIRST</text>
|
||||
<text x="860" y="104" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">MAJOR PROJECTS</text>
|
||||
<text x="140" y="412" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">QUICK WINS</text>
|
||||
<text x="860" y="412" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.18em">AVOID</text>
|
||||
|
||||
<!-- Items: TL (Do First) -->
|
||||
<!-- coral focal -->
|
||||
<circle cx="220" cy="140" r="6" fill="#f7591f"/>
|
||||
<text x="232" y="144" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif">diagram-design</text>
|
||||
<circle cx="220" cy="140" r="6" fill="#eb6c36"/>
|
||||
<text x="232" y="144" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif">Schematic skill v4</text>
|
||||
|
||||
<circle cx="320" cy="200" r="4" fill="#0b0d0b"/>
|
||||
<text x="332" y="204" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
<circle cx="320" cy="200" r="4" fill="#2d3142"/>
|
||||
<text x="332" y="204" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Update changelog</text>
|
||||
|
||||
<!-- Items: TR (Major Projects) -->
|
||||
<circle cx="620" cy="140" r="4" fill="#0b0d0b"/>
|
||||
<text x="632" y="144" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
<circle cx="620" cy="140" r="4" fill="#2d3142"/>
|
||||
<text x="632" y="144" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Design v4 refresh</text>
|
||||
|
||||
<circle cx="760" cy="180" r="4" fill="#0b0d0b"/>
|
||||
<text x="772" y="184" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
<circle cx="760" cy="180" r="4" fill="#2d3142"/>
|
||||
<text x="772" y="184" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">New publication</text>
|
||||
|
||||
<!-- Items: BL (Quick Wins) -->
|
||||
<circle cx="260" cy="320" r="4" fill="#0b0d0b"/>
|
||||
<text x="272" y="324" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
<circle cx="260" cy="320" r="4" fill="#2d3142"/>
|
||||
<text x="272" y="324" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Fix footer link</text>
|
||||
|
||||
<circle cx="360" cy="380" r="4" fill="#0b0d0b"/>
|
||||
<text x="372" y="384" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
<circle cx="360" cy="380" r="4" fill="#2d3142"/>
|
||||
<text x="372" y="384" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Update OG tags</text>
|
||||
|
||||
<!-- Items: BR (Avoid) -->
|
||||
<circle cx="640" cy="380" r="4" fill="#0b0d0b"/>
|
||||
<text x="652" y="384" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
<circle cx="640" cy="380" r="4" fill="#2d3142"/>
|
||||
<text x="652" y="384" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Rewrite build pipeline</text>
|
||||
|
||||
<circle cx="780" cy="320" r="4" fill="#0b0d0b"/>
|
||||
<text x="792" y="324" fill="#52534e" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
<circle cx="780" cy="320" r="4" fill="#2d3142"/>
|
||||
<text x="792" y="324" fill="#4f5d75" font-size="11" font-family="'Geist', sans-serif">Port to Nuxt</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="#f7591f"/>
|
||||
<text x="68" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
<circle cx="52" cy="488" r="6" fill="#eb6c36"/>
|
||||
<text x="68" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Start tomorrow</text>
|
||||
|
||||
<circle cx="192" cy="488" r="4" fill="#0b0d0b"/>
|
||||
<text x="208" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
<circle cx="192" cy="488" r="4" fill="#2d3142"/>
|
||||
<text x="208" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Candidate project</text>
|
||||
|
||||
<text x="336" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
<text x="336" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Position is the signal. Colour is reserved for the single action item.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -62,42 +62,42 @@
|
||||
<defs>
|
||||
<!-- Dot grid background -->
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
|
||||
<!-- Arrow markers -->
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/>
|
||||
</marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#f08a59"/>
|
||||
</marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#5ba8eb"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#6a95d8"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Background: paper + dot grid -->
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- =================================================================
|
||||
LIFELINES — dashed vertical lines from each actor, behind everything.
|
||||
Actor lifeline x-coords: 128, 352, 584, 800
|
||||
================================================================= -->
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(241,239,231,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(241,239,231,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(241,239,231,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(241,239,231,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(245,245,245,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(245,245,245,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(245,245,245,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(245,245,245,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTIVATION BARS — w=8 rects on lifelines showing control duration.
|
||||
Drawn before message arrows so arrows land on their edges.
|
||||
================================================================= -->
|
||||
<!-- Cloudflare activation: receives at y=176, responds at y=408 -->
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(241,239,231,0.06)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(245,245,245,0.06)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<!-- Astro activation: called at y=232, returns at y=352 -->
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(241,239,231,0.06)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(245,245,245,0.06)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE ARROWS — time flows top→down.
|
||||
@@ -105,50 +105,50 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1: Reader → Cloudflare (HTTPS request · link-blue) -->
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#5ba8eb" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#6a95d8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
|
||||
<!-- M2: Cloudflare → Astro (cache miss · muted) -->
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M3: Astro self-message (render MDX · muted U-loop) -->
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M4: Astro → Cloudflare (return HTML · muted dashed) -->
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M5: Cloudflare → Reader (primary success · coral) -->
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- M6: Reader → Analytics (async beacon · muted dashed) -->
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE LABELS — each with an opaque paper-colored mask.
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1 label -->
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="240" y="170" fill="#5ba8eb" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="240" y="170" fill="#6a95d8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
|
||||
<!-- M2 label -->
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="466" y="226" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="466" y="226" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
|
||||
<!-- M3 label (to the right of the self-loop) -->
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="668" y="302" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="668" y="302" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
|
||||
<!-- M4 label -->
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="468" y="346" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="468" y="346" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
|
||||
<!-- M5 label (coral · primary response) -->
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="240" y="402" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="240" y="402" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
|
||||
<!-- M6 label (placed between Astro and Analytics lifelines, a clear gap) -->
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="696" y="458" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="696" y="458" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTOR BOXES — drawn after arrows/labels.
|
||||
@@ -156,63 +156,63 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- Actor 1: Reader (external / soft) -->
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#1c1a17"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(168,166,157,0.10)" stroke="#8e8c83" stroke-width="1"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#2d3142"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(191,192,192,0.10)" stroke="#8e98ac" stroke-width="1"/>
|
||||
<rect x="64" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(142,140,131,0.40)" stroke-width="0.8"/>
|
||||
<text x="78" y="89" fill="#8e8c83" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<text x="78" y="89" fill="#8e98ac" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Actor 2: Cloudflare (cloud / muted) -->
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#1c1a17"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(241,239,231,0.03)" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#8e8c83" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#2d3142"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(245,245,245,0.03)" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#8e98ac" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Actor 3: Astro Origin (focal / coral) -->
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#1c1a17"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(255,106,48,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#ff6a30" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#2d3142"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#f08a59" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Actor 4: Analytics (optional / dashed) -->
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#1c1a17"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(241,239,231,0.02)" stroke="rgba(241,239,231,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#8e8c83" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#2d3142"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(245,245,245,0.02)" stroke="rgba(245,245,245,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#8e98ac" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
|
||||
<!-- =================================================================
|
||||
LEGEND — horizontal strip at the bottom.
|
||||
Separator at y=504, eyebrow at y=520, items at y=540–548.
|
||||
================================================================= -->
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<!-- Item 1: Actor swatch (coral focal) -->
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
|
||||
<!-- Item 2: Activation bar swatch -->
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(241,239,231,0.06)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(245,245,245,0.06)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
|
||||
<!-- Item 3: Request arrow (link-blue) -->
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#5ba8eb" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#6a95d8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<!-- Item 4: Return / async (muted dashed) -->
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
|
||||
<!-- Item 5: Primary response (coral) -->
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-paper-2: #efeee5;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-soft: #65655c;
|
||||
--color-rule: rgba(11,13,11,0.12);
|
||||
--color-rule-solid: rgba(135,139,134,0.25);
|
||||
--color-accent: #f7591f;
|
||||
--color-accent-tint: rgba(247,89,31,0.08);
|
||||
--color-link: #1a70c7;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-paper-2: #ececec;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-soft: #7a8399;
|
||||
--color-rule: rgba(45,49,66,0.12);
|
||||
--color-rule-solid: rgba(79,93,117,0.25);
|
||||
--color-accent: #eb6c36;
|
||||
--color-accent-tint: rgba(235,108,54,0.08);
|
||||
--color-link: #2e5aa8;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', 'Times New Roman', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, Menlo, monospace;
|
||||
@@ -107,7 +107,7 @@
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 0.875rem;
|
||||
padding-bottom: 0.875rem;
|
||||
border-bottom: 1px solid rgba(11,13,11,0.08);
|
||||
border-bottom: 1px solid rgba(45,49,66,0.08);
|
||||
}
|
||||
|
||||
.card-dot {
|
||||
@@ -151,14 +151,14 @@
|
||||
content: '—';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: rgba(11,13,11,0.25);
|
||||
color: rgba(45,49,66,0.25);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid rgba(11,13,11,0.10);
|
||||
border-top: 1px solid rgba(45,49,66,0.10);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.06em;
|
||||
@@ -178,7 +178,7 @@
|
||||
<div class="header">
|
||||
<p class="header-eyebrow">Sequence · Diagram Design</p>
|
||||
<h1>Article request, cold cache</h1>
|
||||
<p class="subtitle">How littlemight.com serves a reader when the requested slug isn't already sitting in Cloudflare's edge cache — origin render, beacon, and back in one round trip.</p>
|
||||
<p class="subtitle">How a content site serves a reader when the requested slug isn't already sitting in Cloudflare's edge cache — origin render, beacon, and back in one round trip.</p>
|
||||
</div>
|
||||
|
||||
<!-- Sequence Diagram -->
|
||||
@@ -187,42 +187,42 @@
|
||||
<defs>
|
||||
<!-- Dot grid background -->
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
|
||||
<!-- Arrow markers -->
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#52534e"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/>
|
||||
</marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#f7591f"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/>
|
||||
</marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Background: paper + dot grid -->
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- =================================================================
|
||||
LIFELINES — dashed vertical lines from each actor, behind everything.
|
||||
Actor lifeline x-coords: 128, 352, 584, 800
|
||||
================================================================= -->
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTIVATION BARS — w=8 rects on lifelines showing control duration.
|
||||
Drawn before message arrows so arrows land on their edges.
|
||||
================================================================= -->
|
||||
<!-- Cloudflare activation: receives at y=176, responds at y=408 -->
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<!-- Astro activation: called at y=232, returns at y=352 -->
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE ARROWS — time flows top→down.
|
||||
@@ -230,50 +230,50 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1: Reader → Cloudflare (HTTPS request · link-blue) -->
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
|
||||
<!-- M2: Cloudflare → Astro (cache miss · muted) -->
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M3: Astro self-message (render MDX · muted U-loop) -->
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M4: Astro → Cloudflare (return HTML · muted dashed) -->
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M5: Cloudflare → Reader (primary success · coral) -->
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- M6: Reader → Analytics (async beacon · muted dashed) -->
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE LABELS — each with an opaque paper-colored mask.
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1 label -->
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="240" y="170" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="240" y="170" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
|
||||
<!-- M2 label -->
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="466" y="226" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="466" y="226" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
|
||||
<!-- M3 label (to the right of the self-loop) -->
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="668" y="302" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="668" y="302" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
|
||||
<!-- M4 label -->
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="468" y="346" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="468" y="346" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
|
||||
<!-- M5 label (coral · primary response) -->
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="240" y="402" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="240" y="402" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
|
||||
<!-- M6 label (placed between Astro and Analytics lifelines, a clear gap) -->
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="696" y="458" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="696" y="458" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTOR BOXES — drawn after arrows/labels.
|
||||
@@ -281,63 +281,63 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- Actor 1: Reader (external / soft) -->
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<rect x="64" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(101,101,92,0.40)" stroke-width="0.8"/>
|
||||
<text x="78" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<rect x="64" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(122,131,153,0.40)" stroke-width="0.8"/>
|
||||
<text x="78" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Actor 2: Cloudflare (cloud / muted) -->
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Actor 3: Astro Origin (focal / coral) -->
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Actor 4: Analytics (optional / dashed) -->
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(11,13,11,0.02)" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(45,49,66,0.02)" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
|
||||
<!-- =================================================================
|
||||
LEGEND — horizontal strip at the bottom.
|
||||
Separator at y=504, eyebrow at y=520, items at y=540–548.
|
||||
================================================================= -->
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<!-- Item 1: Actor swatch (coral focal) -->
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
|
||||
<!-- Item 2: Activation bar swatch -->
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
|
||||
<!-- Item 3: Request arrow (link-blue) -->
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<!-- Item 4: Return / async (muted dashed) -->
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
|
||||
<!-- Item 5: Primary response (coral) -->
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
@@ -377,8 +377,8 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<span>littlemight.com · article request sequence</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>content site · article request sequence</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -62,42 +62,42 @@
|
||||
<defs>
|
||||
<!-- Dot grid background -->
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
|
||||
<!-- Arrow markers -->
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#52534e"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/>
|
||||
</marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#f7591f"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/>
|
||||
</marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- Background: paper + dot grid -->
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- =================================================================
|
||||
LIFELINES — dashed vertical lines from each actor, behind everything.
|
||||
Actor lifeline x-coords: 128, 352, 584, 800
|
||||
================================================================= -->
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="128" y1="128" x2="128" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="352" y1="128" x2="352" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="584" y1="128" x2="584" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="800" y1="128" x2="800" y2="488" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTIVATION BARS — w=8 rects on lifelines showing control duration.
|
||||
Drawn before message arrows so arrows land on their edges.
|
||||
================================================================= -->
|
||||
<!-- Cloudflare activation: receives at y=176, responds at y=408 -->
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<rect x="348" y="180" width="8" height="232" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<!-- Astro activation: called at y=232, returns at y=352 -->
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<rect x="580" y="236" width="8" height="120" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE ARROWS — time flows top→down.
|
||||
@@ -105,50 +105,50 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1: Reader → Cloudflare (HTTPS request · link-blue) -->
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<line x1="128" y1="176" x2="352" y2="176" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
|
||||
<!-- M2: Cloudflare → Astro (cache miss · muted) -->
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="352" y1="232" x2="580" y2="232" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M3: Astro self-message (render MDX · muted U-loop) -->
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<path d="M 588 284 L 624 284 L 624 316 L 588 316" fill="none" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M4: Astro → Cloudflare (return HTML · muted dashed) -->
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="580" y1="352" x2="356" y2="352" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- M5: Cloudflare → Reader (primary success · coral) -->
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="348" y1="408" x2="128" y2="408" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
|
||||
<!-- M6: Reader → Analytics (async beacon · muted dashed) -->
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="128" y1="464" x2="800" y2="464" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- =================================================================
|
||||
MESSAGE LABELS — each with an opaque paper-colored mask.
|
||||
================================================================= -->
|
||||
|
||||
<!-- M1 label -->
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="240" y="170" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
<rect x="188" y="160" width="104" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="240" y="170" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">GET /ARTICLES/SLUG</text>
|
||||
|
||||
<!-- M2 label -->
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="466" y="226" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
<rect x="416" y="216" width="100" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="466" y="226" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CACHE MISS · ORIGIN</text>
|
||||
|
||||
<!-- M3 label (to the right of the self-loop) -->
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="668" y="302" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
<rect x="632" y="292" width="72" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="668" y="302" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">RENDER MDX</text>
|
||||
|
||||
<!-- M4 label -->
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="468" y="346" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
<rect x="420" y="336" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="468" y="346" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · HTML + MAX-AGE</text>
|
||||
|
||||
<!-- M5 label (coral · primary response) -->
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="240" y="402" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
<rect x="192" y="392" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="240" y="402" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">200 · EDGE-CACHED</text>
|
||||
|
||||
<!-- M6 label (placed between Astro and Analytics lifelines, a clear gap) -->
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="696" y="458" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
<rect x="648" y="448" width="96" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="696" y="458" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PAGEVIEW BEACON</text>
|
||||
|
||||
<!-- =================================================================
|
||||
ACTOR BOXES — drawn after arrows/labels.
|
||||
@@ -156,63 +156,63 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- Actor 1: Reader (external / soft) -->
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<rect x="64" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(101,101,92,0.40)" stroke-width="0.8"/>
|
||||
<text x="78" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="56" y="72" width="144" height="56" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<rect x="64" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(122,131,153,0.40)" stroke-width="0.8"/>
|
||||
<text x="78" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<text x="128" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Reader</text>
|
||||
<text x="128" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser</text>
|
||||
|
||||
<!-- Actor 2: Cloudflare (cloud / muted) -->
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="280" y="72" width="144" height="56" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<rect x="288" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="304" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EDGE</text>
|
||||
<text x="352" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Cloudflare</text>
|
||||
<text x="352" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Pages · cache</text>
|
||||
|
||||
<!-- Actor 3: Astro Origin (focal / coral) -->
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="504" y="72" width="160" height="56" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="512" y="80" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="528" y="89" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORIG</text>
|
||||
<text x="584" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Astro Origin</text>
|
||||
<text x="584" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">SSR + MDX</text>
|
||||
|
||||
<!-- Actor 4: Analytics (optional / dashed) -->
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(11,13,11,0.02)" stroke="rgba(11,13,11,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="728" y="72" width="144" height="56" rx="6" fill="rgba(45,49,66,0.02)" stroke="rgba(45,49,66,0.22)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<rect x="736" y="80" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="750" y="89" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ASY</text>
|
||||
<text x="800" y="104" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Analytics</text>
|
||||
<text x="800" y="119" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Beacon · async</text>
|
||||
|
||||
<!-- =================================================================
|
||||
LEGEND — horizontal strip at the bottom.
|
||||
Separator at y=504, eyebrow at y=520, items at y=540–548.
|
||||
================================================================= -->
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="56" y1="504" x2="944" y2="504" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="56" y="520" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<!-- Item 1: Actor swatch (coral focal) -->
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
<rect x="56" y="540" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="76" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal actor</text>
|
||||
|
||||
<!-- Item 2: Activation bar swatch -->
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
<rect x="188" y="536" width="4" height="18" fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="200" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Activation</text>
|
||||
|
||||
<!-- Item 3: Request arrow (link-blue) -->
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
<line x1="308" y1="546" x2="336" y2="546" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="344" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">HTTP request</text>
|
||||
|
||||
<!-- Item 4: Return / async (muted dashed) -->
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
<line x1="476" y1="546" x2="504" y2="546" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Return / async</text>
|
||||
|
||||
<!-- Item 5: Primary response (coral) -->
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
<line x1="652" y1="546" x2="680" y2="546" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="688" y="548" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Primary response</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,84 +61,84 @@
|
||||
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Transitions (drawn first) -->
|
||||
<!-- Start → Draft -->
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Draft → In Review -->
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Published (coral — happy path) -->
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- Published → Archived (down) -->
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Archived → End (down) -->
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Draft (curved back up-and-left) -->
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Transition labels -->
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="196" y="194" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="196" y="194" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="312" y="194" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="312" y="194" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="530" y="194" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="530" y="194" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="640" y="274" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="640" y="274" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="640" y="426" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="640" y="426" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
|
||||
<!-- Reject label on curved path -->
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="316" y="102" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="316" y="102" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
|
||||
<!-- Start dot (filled ink) -->
|
||||
<circle cx="60" cy="200" r="6" fill="#f1efe7"/>
|
||||
<circle cx="60" cy="200" r="6" fill="#f5f5f5"/>
|
||||
|
||||
<!-- State: Draft -->
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
|
||||
<!-- State: In Review -->
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
|
||||
<!-- State: Published (focal coral) -->
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(255,106,48,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#ff6a30" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#f08a59" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
|
||||
<!-- State: Archived -->
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(168,166,157,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#a8a69d" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(191,192,192,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#bfc0c0" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
|
||||
<!-- End ring dot -->
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#f1efe7" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#f1efe7"/>
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#f5f5f5"/>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,84 +42,84 @@
|
||||
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Transitions (drawn first) -->
|
||||
<!-- Start → Draft -->
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Draft → In Review -->
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Published (coral — happy path) -->
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- Published → Archived (down) -->
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Archived → End (down) -->
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Draft (curved back up-and-left) -->
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Transition labels -->
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="196" y="194" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="196" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="312" y="194" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="312" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="530" y="194" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="530" y="194" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="640" y="274" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="640" y="274" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="640" y="426" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="640" y="426" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
|
||||
<!-- Reject label on curved path -->
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="316" y="102" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="316" y="102" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
|
||||
<!-- Start dot (filled ink) -->
|
||||
<circle cx="60" cy="200" r="6" fill="#0b0d0b"/>
|
||||
<circle cx="60" cy="200" r="6" fill="#2d3142"/>
|
||||
|
||||
<!-- State: Draft -->
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
|
||||
<!-- State: In Review -->
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
|
||||
<!-- State: Published (focal coral) -->
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
|
||||
<!-- State: Archived -->
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(82,83,78,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#52534e" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(79,93,117,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
|
||||
<!-- End ring dot -->
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#0b0d0b"/>
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#2d3142" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#2d3142"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>article lifecycle · state machine</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,84 +61,84 @@
|
||||
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Transitions (drawn first) -->
|
||||
<!-- Start → Draft -->
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="68" y1="200" x2="120" y2="200" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Draft → In Review -->
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="280" y1="200" x2="340" y2="200" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Published (coral — happy path) -->
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="500" y1="200" x2="560" y2="200" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- Published → Archived (down) -->
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="240" x2="640" y2="300" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- Archived → End (down) -->
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="400" x2="640" y2="432" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- In Review → Draft (curved back up-and-left) -->
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<path d="M 420 160 C 420 96, 200 96, 200 160" fill="none" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Transition labels -->
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="196" y="194" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
<rect x="172" y="184" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="196" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CREATE</text>
|
||||
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="312" y="194" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
<rect x="288" y="184" width="48" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="312" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">SUBMIT</text>
|
||||
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="530" y="194" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
<rect x="500" y="184" width="60" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="530" y="194" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">APPROVE</text>
|
||||
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="640" y="274" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
<rect x="612" y="264" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="640" y="274" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXPIRE</text>
|
||||
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="640" y="426" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
<rect x="620" y="416" width="40" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="640" y="426" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PURGE</text>
|
||||
|
||||
<!-- Reject label on curved path -->
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="316" y="102" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
<rect x="276" y="92" width="80" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="316" y="102" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">REJECT · REVISE</text>
|
||||
|
||||
<!-- Start dot (filled ink) -->
|
||||
<circle cx="60" cy="200" r="6" fill="#0b0d0b"/>
|
||||
<circle cx="60" cy="200" r="6" fill="#2d3142"/>
|
||||
|
||||
<!-- State: Draft -->
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
<rect x="120" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="128" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="148" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="200" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft</text>
|
||||
<text x="200" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">unpublished</text>
|
||||
|
||||
<!-- State: In Review -->
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
<rect x="340" y="160" width="160" height="80" rx="8" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="348" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="368" y="177" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="420" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">In Review</text>
|
||||
<text x="420" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">awaiting approval</text>
|
||||
|
||||
<!-- State: Published (focal coral) -->
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
<rect x="560" y="160" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="568" y="168" width="40" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="177" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="208" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Published</text>
|
||||
<text x="640" y="224" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">live on site</text>
|
||||
|
||||
<!-- State: Archived -->
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(82,83,78,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#52534e" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
<rect x="560" y="300" width="160" height="100" rx="8" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<rect x="568" y="308" width="40" height="12" rx="2" fill="transparent" stroke="rgba(79,93,117,0.50)" stroke-width="0.8"/>
|
||||
<text x="588" y="317" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STATE</text>
|
||||
<text x="640" y="348" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Archived</text>
|
||||
<text x="640" y="364" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">noindex · hidden</text>
|
||||
<text x="640" y="382" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">redirect retained</text>
|
||||
|
||||
<!-- End ring dot -->
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#0b0d0b"/>
|
||||
<circle cx="640" cy="440" r="8" fill="none" stroke="#2d3142" stroke-width="1"/>
|
||||
<circle cx="640" cy="440" r="5" fill="#2d3142"/>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,109 +61,109 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Lane dividers -->
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(241,239,231,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(241,239,231,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(241,239,231,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(245,245,245,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(245,245,245,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(245,245,245,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Actor column divider -->
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(241,239,231,0.22)" stroke-width="1"/>
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(245,245,245,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Lane labels -->
|
||||
<text x="60" y="124" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
<text x="60" y="124" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
|
||||
<!-- Arrows (drawn first) -->
|
||||
<!-- 1. Draft → Open PR (within Author) -->
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 2. Open PR → Review (Author → Reviewer handoff, diagonal down-right) -->
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 3. Review → Polish (Reviewer → Editor, vertical down) -->
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<!-- 4. Polish → Approve (within Editor) -->
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 5. Approve → Build (Editor → CI/CD, coral handoff) -->
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- 6. Build → Deploy (within CI/CD) -->
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="482" y="150" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="482" y="150" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#2a2723"/>
|
||||
<text x="574" y="238" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#393e53"/>
|
||||
<text x="574" y="238" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#1c1a17"/>
|
||||
<text x="752" y="318" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#2d3142"/>
|
||||
<text x="752" y="318" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
|
||||
<!-- Steps -->
|
||||
<!-- Author: Draft MDX -->
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
|
||||
<!-- Author: Open PR -->
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
|
||||
<!-- Reviewer: Review content -->
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
|
||||
<!-- Editor: Polish copy -->
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
|
||||
<!-- Editor: Approve merge -->
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
|
||||
<!-- CI/CD: Build -->
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
|
||||
<!-- CI/CD: Deploy (coral focal) -->
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#f1efe7" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#2a2723" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#393e53" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(255,106,48,0.08)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(240,138,89,0.08)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#a8a69d" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#bfc0c0" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#a8a69d" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#bfc0c0" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#ff6a30" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#f08a59" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,109 +42,109 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Lane dividers -->
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Actor column divider -->
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Lane labels -->
|
||||
<text x="60" y="124" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
<text x="60" y="124" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
|
||||
<!-- Arrows (drawn first) -->
|
||||
<!-- 1. Draft → Open PR (within Author) -->
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 2. Open PR → Review (Author → Reviewer handoff, diagonal down-right) -->
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 3. Review → Polish (Reviewer → Editor, vertical down) -->
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<!-- 4. Polish → Approve (within Editor) -->
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 5. Approve → Build (Editor → CI/CD, coral handoff) -->
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- 6. Build → Deploy (within CI/CD) -->
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="482" y="150" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="482" y="150" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#efeee5"/>
|
||||
<text x="574" y="238" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#ececec"/>
|
||||
<text x="574" y="238" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="752" y="318" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="752" y="318" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
|
||||
<!-- Steps -->
|
||||
<!-- Author: Draft MDX -->
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
|
||||
<!-- Author: Open PR -->
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
|
||||
<!-- Reviewer: Review content -->
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
|
||||
<!-- Editor: Polish copy -->
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
|
||||
<!-- Editor: Approve merge -->
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
|
||||
<!-- CI/CD: Build -->
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
|
||||
<!-- CI/CD: Deploy (coral focal) -->
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#52534e" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>publishing an article · swimlane</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,109 +61,109 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Lane dividers -->
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(11,13,11,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
<line x1="40" y1="160" x2="960" y2="160" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="240" x2="960" y2="240" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="320" x2="960" y2="320" stroke="rgba(45,49,66,0.10)" stroke-width="1"/>
|
||||
<line x1="40" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Actor column divider -->
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(11,13,11,0.22)" stroke-width="1"/>
|
||||
<line x1="160" y1="80" x2="160" y2="400" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
|
||||
|
||||
<!-- Lane labels -->
|
||||
<text x="60" y="124" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
<text x="60" y="124" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">AUTHOR</text>
|
||||
<text x="60" y="204" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">REVIEWER</text>
|
||||
<text x="60" y="284" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">EDITOR</text>
|
||||
<text x="60" y="364" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" letter-spacing="0.18em">CI / CD</text>
|
||||
|
||||
<!-- Arrows (drawn first) -->
|
||||
<!-- 1. Draft → Open PR (within Author) -->
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="300" y1="120" x2="340" y2="120" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 2. Open PR → Review (Author → Reviewer handoff, diagonal down-right) -->
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="460" y1="144" x2="500" y2="176" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 3. Review → Polish (Reviewer → Editor, vertical down) -->
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#52534e" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<line x1="570" y1="224" x2="570" y2="256" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
||||
<!-- 4. Polish → Approve (within Editor) -->
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="640" y1="280" x2="680" y2="280" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<!-- 5. Approve → Build (Editor → CI/CD, coral handoff) -->
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<line x1="750" y1="304" x2="720" y2="336" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<!-- 6. Build → Deploy (within CI/CD) -->
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="760" y1="360" x2="800" y2="360" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Arrow labels -->
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="482" y="150" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
<rect x="452" y="140" width="60" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="482" y="150" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">HANDOFF</text>
|
||||
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#efeee5"/>
|
||||
<text x="574" y="238" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
<rect x="548" y="228" width="52" height="12" rx="2" fill="#ececec"/>
|
||||
<text x="574" y="238" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">REVISE</text>
|
||||
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#f5f4ed"/>
|
||||
<text x="752" y="318" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
<rect x="712" y="308" width="80" height="12" rx="2" fill="#f5f5f5"/>
|
||||
<text x="752" y="318" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.12em">DEPLOY TRIGGER</text>
|
||||
|
||||
<!-- Steps -->
|
||||
<!-- Author: Draft MDX -->
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
<rect x="180" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="240" y="118" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Draft MDX</text>
|
||||
<text x="240" y="132" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">src/content/…</text>
|
||||
|
||||
<!-- Author: Open PR -->
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
<rect x="340" y="96" width="120" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="400" y="118" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Open PR</text>
|
||||
<text x="400" y="132" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">gh pr create</text>
|
||||
|
||||
<!-- Reviewer: Review content -->
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
<rect x="500" y="176" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="570" y="198" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Review content</text>
|
||||
<text x="570" y="212" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">fact-check · voice</text>
|
||||
|
||||
<!-- Editor: Polish copy -->
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
<rect x="500" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="570" y="278" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Polish copy</text>
|
||||
<text x="570" y="292" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">style · line edits</text>
|
||||
|
||||
<!-- Editor: Approve merge -->
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
<rect x="680" y="256" width="140" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="750" y="278" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Approve merge</text>
|
||||
<text x="750" y="292" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">squash · main</text>
|
||||
|
||||
<!-- CI/CD: Build -->
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
<rect x="680" y="336" width="80" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="720" y="358" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Build</text>
|
||||
<text x="720" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">astro build</text>
|
||||
|
||||
<!-- CI/CD: Deploy (coral focal) -->
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#0b0d0b" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
<rect x="800" y="336" width="120" height="48" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="860" y="358" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Deploy</text>
|
||||
<text x="860" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">cloudflare pages</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="428" x2="960" y2="428" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="444" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
<rect x="40" y="460" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="60" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Step</text>
|
||||
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
<rect x="132" y="460" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="152" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Focal outcome</text>
|
||||
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
<line x1="268" y1="466" x2="296" y2="466" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="304" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Within-lane step</text>
|
||||
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#52534e" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
<line x1="444" y1="466" x2="472" y2="466" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
||||
<text x="480" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Revision loop</text>
|
||||
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#f7591f" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
<line x1="608" y1="466" x2="636" y2="466" stroke="#eb6c36" stroke-width="1.4" marker-end="url(#arrow-accent)"/>
|
||||
<text x="644" y="468" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Critical handoff</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight milestones · Timeline</title>
|
||||
<title>Product milestones · Timeline</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,77 +56,77 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">Timeline · Diagram Design</p>
|
||||
<h1>littlemight, fourteen months</h1>
|
||||
<h1>Product launch · fourteen months</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Year markers (background) -->
|
||||
<text x="60" y="340" fill="rgba(241,239,231,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(241,239,231,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
<text x="60" y="340" fill="rgba(245,245,245,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(245,245,245,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
|
||||
<!-- Baseline -->
|
||||
<line x1="80" y1="240" x2="920" y2="240" stroke="rgba(150,146,138,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Year boundary tick (between 2025 and 2026) -->
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(241,239,231,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#8e8c83" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#8e98ac" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
|
||||
<!-- Start / end caps -->
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(241,239,231,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(241,239,231,0.20)" stroke-width="1"/>
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
|
||||
|
||||
<!-- Event 1: FEB 2025 · First post (below) -->
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#f1efe7"/>
|
||||
<text x="100" y="312" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#f5f5f5"/>
|
||||
<text x="100" y="312" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
|
||||
<!-- Event 2: APR 2025 · Design v1 (above) -->
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#f1efe7"/>
|
||||
<text x="240" y="156" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#f5f5f5"/>
|
||||
<text x="240" y="156" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
|
||||
<!-- Event 3: SEP 2025 · Design v2 (below) -->
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(241,239,231,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#f1efe7"/>
|
||||
<text x="500" y="312" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(245,245,245,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#f5f5f5"/>
|
||||
<text x="500" y="312" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
|
||||
<!-- Event 4: JAN 2026 · Design v3 (above, coral major) -->
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#ff6a30" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#ff6a30"/>
|
||||
<text x="740" y="128" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#f08a59" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#f08a59"/>
|
||||
<text x="740" y="128" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
|
||||
<!-- Event 5: APR 2026 · now · Diagram Design skill (below, coral) -->
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#ff6a30" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#ff6a30"/>
|
||||
<text x="900" y="312" fill="#ff6a30" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">diagram-design</text>
|
||||
<text x="900" y="344" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#f08a59" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#f08a59"/>
|
||||
<text x="900" y="312" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Schematic skill</text>
|
||||
<text x="900" y="344" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="408" r="4" fill="#f1efe7"/>
|
||||
<text x="68" y="412" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
<circle cx="52" cy="408" r="4" fill="#f5f5f5"/>
|
||||
<text x="68" y="412" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
|
||||
<circle cx="148" cy="408" r="6" fill="#ff6a30"/>
|
||||
<text x="164" y="412" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
<circle cx="148" cy="408" r="6" fill="#f08a59"/>
|
||||
<text x="164" y="412" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
|
||||
<text x="296" y="412" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
<text x="296" y="412" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight milestones · Timeline</title>
|
||||
<title>Product milestones · Timeline</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,94 +20,94 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<p class="header-eyebrow">Timeline · Diagram Design</p>
|
||||
<h1>littlemight, fourteen months</h1>
|
||||
<p class="subtitle">Five design moments from the first post to the current diagram-design overhaul. Spacing is proportional to calendar time — the five-month gap between v1 and v2 is genuinely wider on the page.</p>
|
||||
<h1>Product launch · fourteen months</h1>
|
||||
<p class="subtitle">Five design moments from the first post to the current schematic overhaul. Spacing is proportional to calendar time — the five-month gap between v1 and v2 is genuinely wider on the page.</p>
|
||||
</div>
|
||||
|
||||
<div class="diagram-container">
|
||||
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Year markers (background) -->
|
||||
<text x="60" y="340" fill="rgba(11,13,11,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(11,13,11,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
<text x="60" y="340" fill="rgba(45,49,66,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(45,49,66,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
|
||||
<!-- Baseline -->
|
||||
<line x1="80" y1="240" x2="920" y2="240" stroke="rgba(135,139,134,0.45)" stroke-width="1"/>
|
||||
<line x1="80" y1="240" x2="920" y2="240" stroke="rgba(79,93,117,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Year boundary tick (between 2025 and 2026) -->
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#65655c" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
|
||||
<!-- Start / end caps -->
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
|
||||
<!-- Event 1: FEB 2025 · First post (below) -->
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="100" y="312" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="100" y="312" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
|
||||
<!-- Event 2: APR 2025 · Design v1 (above) -->
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="240" y="156" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="240" y="156" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
|
||||
<!-- Event 3: SEP 2025 · Design v2 (below) -->
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="500" y="312" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="500" y="312" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
|
||||
<!-- Event 4: JAN 2026 · Design v3 (above, coral major) -->
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#f7591f" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#f7591f"/>
|
||||
<text x="740" y="128" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#eb6c36" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#eb6c36"/>
|
||||
<text x="740" y="128" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
|
||||
<!-- Event 5: APR 2026 · now · Diagram Design skill (below, coral) -->
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#f7591f" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#f7591f"/>
|
||||
<text x="900" y="312" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">diagram-design</text>
|
||||
<text x="900" y="344" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#eb6c36" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#eb6c36"/>
|
||||
<text x="900" y="312" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Schematic skill</text>
|
||||
<text x="900" y="344" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="408" r="4" fill="#0b0d0b"/>
|
||||
<text x="68" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
<circle cx="52" cy="408" r="4" fill="#2d3142"/>
|
||||
<text x="68" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
|
||||
<circle cx="148" cy="408" r="6" fill="#f7591f"/>
|
||||
<text x="164" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
<circle cx="148" cy="408" r="6" fill="#eb6c36"/>
|
||||
<text x="164" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
|
||||
<text x="296" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
<text x="296" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -128,8 +128,8 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span>littlemight · design lineage</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>product · design lineage</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>littlemight milestones · Timeline</title>
|
||||
<title>Product milestones · Timeline</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -56,77 +56,77 @@
|
||||
<body>
|
||||
<div class="frame">
|
||||
<p class="eyebrow">Timeline · Diagram Design</p>
|
||||
<h1>littlemight, fourteen months</h1>
|
||||
<h1>Product launch · fourteen months</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Year markers (background) -->
|
||||
<text x="60" y="340" fill="rgba(11,13,11,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(11,13,11,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
<text x="60" y="340" fill="rgba(45,49,66,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2025</text>
|
||||
<text x="700" y="340" fill="rgba(45,49,66,0.06)" font-size="72" font-weight="600" font-family="'Geist Mono', monospace">2026</text>
|
||||
|
||||
<!-- Baseline -->
|
||||
<line x1="80" y1="240" x2="920" y2="240" stroke="rgba(135,139,134,0.45)" stroke-width="1"/>
|
||||
<line x1="80" y1="240" x2="920" y2="240" stroke="rgba(79,93,117,0.45)" stroke-width="1"/>
|
||||
|
||||
<!-- Year boundary tick (between 2025 and 2026) -->
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#65655c" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
<line x1="680" y1="232" x2="680" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
<text x="680" y="260" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN '26</text>
|
||||
|
||||
<!-- Start / end caps -->
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(11,13,11,0.20)" stroke-width="1"/>
|
||||
<line x1="80" y1="232" x2="80" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
<line x1="920" y1="232" x2="920" y2="248" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
|
||||
|
||||
<!-- Event 1: FEB 2025 · First post (below) -->
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="100" y="312" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
<line x1="100" y1="240" x2="100" y2="296" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="100" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="100" y="312" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">FEB 2025</text>
|
||||
<text x="100" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">First post</text>
|
||||
|
||||
<!-- Event 2: APR 2025 · Design v1 (above) -->
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="240" y="156" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
<line x1="240" y1="184" x2="240" y2="240" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="240" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="240" y="156" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2025</text>
|
||||
<text x="240" y="172" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v1</text>
|
||||
|
||||
<!-- Event 3: SEP 2025 · Design v2 (below) -->
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#0b0d0b"/>
|
||||
<text x="500" y="312" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
<line x1="500" y1="240" x2="500" y2="296" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<circle cx="500" cy="240" r="4" fill="#2d3142"/>
|
||||
<text x="500" y="312" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">SEP 2025</text>
|
||||
<text x="500" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v2</text>
|
||||
<text x="500" y="344" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">typography pass</text>
|
||||
|
||||
<!-- Event 4: JAN 2026 · Design v3 (above, coral major) -->
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#f7591f" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#f7591f"/>
|
||||
<text x="740" y="128" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
<line x1="740" y1="160" x2="740" y2="240" stroke="#eb6c36" stroke-width="1"/>
|
||||
<circle cx="740" cy="240" r="6" fill="#eb6c36"/>
|
||||
<text x="740" y="128" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">JAN 2026</text>
|
||||
<text x="740" y="148" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design v3</text>
|
||||
<text x="740" y="164" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">complexity budget</text>
|
||||
|
||||
<!-- Event 5: APR 2026 · now · Diagram Design skill (below, coral) -->
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#f7591f" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#f7591f"/>
|
||||
<text x="900" y="312" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">diagram-design</text>
|
||||
<text x="900" y="344" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
<line x1="900" y1="240" x2="900" y2="296" stroke="#eb6c36" stroke-width="1"/>
|
||||
<circle cx="900" cy="240" r="6" fill="#eb6c36"/>
|
||||
<text x="900" y="312" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">APR 2026 · NOW</text>
|
||||
<text x="900" y="328" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Schematic skill</text>
|
||||
<text x="900" y="344" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">eight diagram types</text>
|
||||
|
||||
<!-- Legend -->
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="376" x2="960" y2="376" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="392" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="408" r="4" fill="#0b0d0b"/>
|
||||
<text x="68" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
<circle cx="52" cy="408" r="4" fill="#2d3142"/>
|
||||
<text x="68" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Event</text>
|
||||
|
||||
<circle cx="148" cy="408" r="6" fill="#f7591f"/>
|
||||
<text x="164" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
<circle cx="148" cy="408" r="6" fill="#eb6c36"/>
|
||||
<text x="164" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Major milestone</text>
|
||||
|
||||
<text x="296" y="412" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
<text x="296" y="412" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Spacing is proportional to real elapsed time.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,110 +61,110 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Tier tags (left margin) -->
|
||||
<text x="40" y="108" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
<text x="40" y="108" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
|
||||
<!-- Connectors drawn first (behind nodes) -->
|
||||
<!-- Root → Tier 1 bus -->
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
|
||||
<!-- Design → leaves -->
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
|
||||
<!-- Engineering → leaves -->
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
|
||||
<!-- Research → single leaf -->
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
|
||||
<!-- Root node: Skills (coral focal) -->
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(255,106,48,0.10)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(255,106,48,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#ff6a30" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(240,138,89,0.10)" stroke="#f08a59" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#f08a59" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
|
||||
<!-- Tier 1: Design -->
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="rgba(241,239,231,0.04)" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="rgba(245,245,245,0.04)" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
|
||||
<!-- Tier 1: Engineering -->
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="rgba(241,239,231,0.04)" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="rgba(245,245,245,0.04)" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
|
||||
<!-- Tier 1: Research -->
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="rgba(241,239,231,0.04)" stroke="#f1efe7" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(241,239,231,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#f1efe7" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="rgba(245,245,245,0.04)" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#f5f5f5" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
|
||||
<!-- Tier 2: polish -->
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
|
||||
<!-- Tier 2: critique -->
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
|
||||
<!-- Tier 2: review -->
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
|
||||
<!-- Tier 2: ship -->
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
|
||||
<!-- Tier 2: investigate -->
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#1c1a17"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#f1efe7" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#2d3142"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#f5f5f5" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(255,106,48,0.10)" stroke="#ff6a30" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(240,138,89,0.10)" stroke="#f08a59" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="rgba(241,239,231,0.04)" stroke="#f1efe7" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="rgba(245,245,245,0.04)" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(241,239,231,0.05)" stroke="#a8a69d" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(245,245,245,0.05)" stroke="#bfc0c0" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
|
||||
<text x="500" y="452" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
<text x="500" y="452" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,110 +42,110 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Tier tags (left margin) -->
|
||||
<text x="40" y="108" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
<text x="40" y="108" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
|
||||
<!-- Connectors drawn first (behind nodes) -->
|
||||
<!-- Root → Tier 1 bus -->
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Design → leaves -->
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Engineering → leaves -->
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Research → single leaf -->
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Root node: Skills (coral focal) -->
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
|
||||
<!-- Tier 1: Design -->
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
|
||||
<!-- Tier 1: Engineering -->
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
|
||||
<!-- Tier 1: Research -->
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
|
||||
<!-- Tier 2: polish -->
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
|
||||
<!-- Tier 2: critique -->
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
|
||||
<!-- Tier 2: review -->
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
|
||||
<!-- Tier 2: ship -->
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
|
||||
<!-- Tier 2: investigate -->
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
|
||||
<text x="500" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
<text x="500" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>claude code skill taxonomy</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,110 +61,110 @@
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Tier tags (left margin) -->
|
||||
<text x="40" y="108" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
<text x="40" y="108" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">TIER 0 · ROOT</text>
|
||||
<text x="40" y="224" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 1</text>
|
||||
<text x="40" y="324" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em" text-anchor="start">TIER 2</text>
|
||||
|
||||
<!-- Connectors drawn first (behind nodes) -->
|
||||
<!-- Root → Tier 1 bus -->
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 128 L 500 168 L 220 168 L 220 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 168 L 500 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 168 L 780 168 L 780 208" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Design → leaves -->
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 220 256 L 220 296 L 140 296 L 140 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 220 296 L 300 296 L 300 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Engineering → leaves -->
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 500 256 L 500 296 L 480 296 L 480 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<path d="M 500 296 L 660 296 L 660 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Research → single leaf -->
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<path d="M 780 256 L 780 296 L 840 296 L 840 336" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
|
||||
<!-- Root node: Skills (coral focal) -->
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="420" y="80" width="160" height="48" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="428" y="88" width="32" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="444" y="97" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ROOT</text>
|
||||
<text x="500" y="118" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Skills</text>
|
||||
|
||||
<!-- Tier 1: Design -->
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="140" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="148" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="162" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="220" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Design</text>
|
||||
<text x="220" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ui · visual · ux</text>
|
||||
|
||||
<!-- Tier 1: Engineering -->
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="420" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="428" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="442" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="500" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Engineering</text>
|
||||
<text x="500" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">ship · review · test</text>
|
||||
|
||||
<!-- Tier 1: Research -->
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="700" y="208" width="160" height="48" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="708" y="216" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="722" y="225" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CAT</text>
|
||||
<text x="780" y="240" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Research</text>
|
||||
<text x="780" y="252" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">investigate · analyze</text>
|
||||
|
||||
<!-- Tier 2: polish -->
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="60" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="140" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">polish</text>
|
||||
<text x="140" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">align · space · rhythm</text>
|
||||
|
||||
<!-- Tier 2: critique -->
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="220" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="300" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">critique</text>
|
||||
<text x="300" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">hierarchy · density</text>
|
||||
|
||||
<!-- Tier 2: review -->
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="400" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="480" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">review</text>
|
||||
<text x="480" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">pre-land diff · sql</text>
|
||||
|
||||
<!-- Tier 2: ship -->
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="580" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="660" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">ship</text>
|
||||
<text x="660" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">merge · deploy · verify</text>
|
||||
|
||||
<!-- Tier 2: investigate -->
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="760" y="336" width="160" height="48" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="840" y="360" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">investigate</text>
|
||||
<text x="840" y="372" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">root cause · evidence</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="412" x2="960" y2="412" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="428" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
<rect x="40" y="444" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="60" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Root · focal</text>
|
||||
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
<rect x="180" y="444" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="200" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Category branch</text>
|
||||
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
<rect x="340" y="444" width="14" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
<text x="360" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Leaf skill</text>
|
||||
|
||||
<text x="500" y="452" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
<text x="500" y="452" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Orthogonal connectors only. Coral marks the root — every branch descends from one idea.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17;
|
||||
--color-ink: #f1efe7;
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142;
|
||||
--color-ink: #f5f5f5;
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -61,7 +61,7 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
|
||||
</pattern>
|
||||
<clipPath id="clip-center">
|
||||
<circle cx="500" cy="180" r="140"/>
|
||||
@@ -71,59 +71,59 @@
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Three set circles (stroke + very-low-opacity tint; tints compound in overlaps) -->
|
||||
<!-- Desirable — top, ink -->
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(241,239,231,0.04)" stroke="#f1efe7" stroke-width="1"/>
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(245,245,245,0.04)" stroke="#f5f5f5" stroke-width="1"/>
|
||||
<!-- Feasible — bottom-left, muted -->
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(168,166,157,0.05)" stroke="#a8a69d" stroke-width="1"/>
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(191,192,192,0.05)" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<!-- Viable — bottom-right, soft -->
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(142,140,131,0.05)" stroke="#8e8c83" stroke-width="1"/>
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(142,140,131,0.05)" stroke="#8e98ac" stroke-width="1"/>
|
||||
|
||||
<!-- Coral focal tint on the all-three intersection -->
|
||||
<g clip-path="url(#clip-center)">
|
||||
<g clip-path="url(#clip-center-2)">
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(255,106,48,0.14)"/>
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(240,138,89,0.14)"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- Set labels -->
|
||||
<text x="500" y="20" fill="#f1efe7" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="36" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
<text x="500" y="20" fill="#f5f5f5" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="36" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
|
||||
<text x="152" y="400" fill="#a8a69d" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Feasible</text>
|
||||
<text x="152" y="416" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="start" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
<text x="152" y="400" fill="#bfc0c0" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Feasible</text>
|
||||
<text x="152" y="416" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="start" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
|
||||
<text x="848" y="400" fill="#8e8c83" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Viable</text>
|
||||
<text x="848" y="416" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
<text x="848" y="400" fill="#8e98ac" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Viable</text>
|
||||
<text x="848" y="416" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
|
||||
<!-- Pairwise intersection labels -->
|
||||
<text x="360" y="232" fill="#a8a69d" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Prototype</text>
|
||||
<text x="360" y="248" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">no business model</text>
|
||||
<text x="360" y="232" fill="#bfc0c0" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Prototype</text>
|
||||
<text x="360" y="248" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">no business model</text>
|
||||
|
||||
<text x="640" y="232" fill="#a8a69d" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Vaporware</text>
|
||||
<text x="640" y="248" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">can't build it</text>
|
||||
<text x="640" y="232" fill="#bfc0c0" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Vaporware</text>
|
||||
<text x="640" y="248" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">can't build it</text>
|
||||
|
||||
<text x="500" y="368" fill="#a8a69d" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Internal tool</text>
|
||||
<text x="500" y="384" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">nobody wants it</text>
|
||||
<text x="500" y="368" fill="#bfc0c0" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Internal tool</text>
|
||||
<text x="500" y="384" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">nobody wants it</text>
|
||||
|
||||
<!-- Focal: all-three center -->
|
||||
<text x="500" y="260" fill="#ff6a30" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="276" fill="#a8a69d" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
<text x="500" y="260" fill="#f08a59" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="276" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(241,239,231,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#a8a69d" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="none" stroke="#ff6a30" stroke-width="1.2"/>
|
||||
<text x="68" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">All three — ship it</text>
|
||||
<circle cx="52" cy="488" r="6" fill="none" stroke="#f08a59" stroke-width="1.2"/>
|
||||
<text x="68" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">All three — ship it</text>
|
||||
|
||||
<circle cx="192" cy="488" r="6" fill="none" stroke="#a8a69d" stroke-width="1"/>
|
||||
<text x="208" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif">Two of three — incomplete</text>
|
||||
<circle cx="192" cy="488" r="6" fill="none" stroke="#bfc0c0" stroke-width="1"/>
|
||||
<text x="208" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Two of three — incomplete</text>
|
||||
|
||||
<text x="380" y="492" fill="#a8a69d" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Coral marks the intersection that earns the work. The others name the traps.</text>
|
||||
<text x="380" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Coral marks the intersection that earns the work. The others name the traps.</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root { --color-paper:#f5f4ed; --color-paper-2:#efeee5; --color-ink:#0b0d0b; --color-muted:#52534e; --color-soft:#65655c; --color-rule:rgba(11,13,11,0.12); --color-accent:#f7591f; --color-link:#1a70c7; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
:root { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
|
||||
body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.header { margin-bottom: 2.5rem; }
|
||||
@@ -20,14 +20,14 @@
|
||||
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
||||
.card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
|
||||
.card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(11,13,11,0.08); }
|
||||
.card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
||||
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
|
||||
.card h3 { font-size: 0.875rem; font-weight: 600; }
|
||||
.card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
||||
.card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(11,13,11,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(11,13,11,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
|
||||
.footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -42,7 +42,7 @@
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<clipPath id="clip-center">
|
||||
<circle cx="500" cy="180" r="140"/>
|
||||
@@ -52,59 +52,59 @@
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
|
||||
<!-- Three set circles (stroke + very-low-opacity tint; tints compound in overlaps) -->
|
||||
<!-- Desirable — top, ink -->
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(11,13,11,0.04)" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(45,49,66,0.04)" stroke="#2d3142" stroke-width="1"/>
|
||||
<!-- Feasible — bottom-left, muted -->
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(82,83,78,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(79,93,117,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<!-- Viable — bottom-right, soft -->
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(101,101,92,0.05)" stroke="#65655c" stroke-width="1"/>
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(122,131,153,0.05)" stroke="#7a8399" stroke-width="1"/>
|
||||
|
||||
<!-- Coral focal tint on the all-three intersection -->
|
||||
<g clip-path="url(#clip-center)">
|
||||
<g clip-path="url(#clip-center-2)">
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(247,89,31,0.10)"/>
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(235,108,54,0.10)"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- Set labels -->
|
||||
<text x="500" y="20" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="36" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
<text x="500" y="20" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="36" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
|
||||
<text x="152" y="400" fill="#52534e" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Feasible</text>
|
||||
<text x="152" y="416" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="start" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
<text x="152" y="400" fill="#4f5d75" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Feasible</text>
|
||||
<text x="152" y="416" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="start" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
|
||||
<text x="848" y="400" fill="#65655c" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Viable</text>
|
||||
<text x="848" y="416" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
<text x="848" y="400" fill="#7a8399" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Viable</text>
|
||||
<text x="848" y="416" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
|
||||
<!-- Pairwise intersection labels -->
|
||||
<text x="360" y="232" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Prototype</text>
|
||||
<text x="360" y="248" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">no business model</text>
|
||||
<text x="360" y="232" fill="#4f5d75" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Prototype</text>
|
||||
<text x="360" y="248" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">no business model</text>
|
||||
|
||||
<text x="640" y="232" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Vaporware</text>
|
||||
<text x="640" y="248" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">can't build it</text>
|
||||
<text x="640" y="232" fill="#4f5d75" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Vaporware</text>
|
||||
<text x="640" y="248" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">can't build it</text>
|
||||
|
||||
<text x="500" y="368" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Internal tool</text>
|
||||
<text x="500" y="384" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">nobody wants it</text>
|
||||
<text x="500" y="368" fill="#4f5d75" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Internal tool</text>
|
||||
<text x="500" y="384" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">nobody wants it</text>
|
||||
|
||||
<!-- Focal: all-three center -->
|
||||
<text x="500" y="260" fill="#f7591f" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="276" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
<text x="500" y="260" fill="#eb6c36" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="276" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="none" stroke="#f7591f" stroke-width="1.2"/>
|
||||
<text x="68" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">All three — ship it</text>
|
||||
<circle cx="52" cy="488" r="6" fill="none" stroke="#eb6c36" stroke-width="1.2"/>
|
||||
<text x="68" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">All three — ship it</text>
|
||||
|
||||
<circle cx="192" cy="488" r="6" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<text x="208" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Two of three — incomplete</text>
|
||||
<circle cx="192" cy="488" r="6" fill="none" stroke="#4f5d75" stroke-width="1"/>
|
||||
<text x="208" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Two of three — incomplete</text>
|
||||
|
||||
<text x="380" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Coral marks the intersection that earns the work. The others name the traps.</text>
|
||||
<text x="380" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Coral marks the intersection that earns the work. The others name the traps.</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
<div class="footer">
|
||||
<span>good design · desirable × feasible × viable</span>
|
||||
<span>example · diagram-design</span>
|
||||
<span>example · schematic skill</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-accent: #eb6c36;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -58,79 +58,50 @@
|
||||
<p class="eyebrow">Venn · Diagram Design</p>
|
||||
<h1>Good design · Desirable × Feasible × Viable</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
</pattern>
|
||||
<!-- Clip to the all-three intersection (centroid region) for the coral tint -->
|
||||
<clipPath id="clip-center">
|
||||
<!-- Chained clips isolate the all-three intersection: clip to Desirable, then to Feasible, then fill via the third circle. -->
|
||||
<clipPath id="clip-desirable">
|
||||
<circle cx="500" cy="180" r="140"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip-center-2">
|
||||
<clipPath id="clip-feasible">
|
||||
<circle cx="428" cy="320" r="140"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
|
||||
<!-- Three set circles (stroke + very-low-opacity tint; tints compound in overlaps) -->
|
||||
<!-- Desirable — top, ink -->
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(11,13,11,0.04)" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<circle cx="500" cy="180" r="140" fill="rgba(45,49,66,0.04)" stroke="#2d3142" stroke-width="1"/>
|
||||
<!-- Feasible — bottom-left, muted -->
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(82,83,78,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<circle cx="428" cy="320" r="140" fill="rgba(79,93,117,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<!-- Viable — bottom-right, soft -->
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(101,101,92,0.05)" stroke="#65655c" stroke-width="1"/>
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(122,131,153,0.05)" stroke="#7a8399" stroke-width="1"/>
|
||||
|
||||
<!-- Coral focal tint on the all-three intersection -->
|
||||
<g clip-path="url(#clip-center)">
|
||||
<g clip-path="url(#clip-center-2)">
|
||||
<circle cx="572" cy="320" r="140" fill="rgba(247,89,31,0.10)"/>
|
||||
<!-- Focal: solid-ink triple intersection (dark fill for white text to read against) -->
|
||||
<g clip-path="url(#clip-desirable)">
|
||||
<g clip-path="url(#clip-feasible)">
|
||||
<circle cx="572" cy="320" r="140" fill="#2d3142"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- Set labels (outside circles, pinned to far side) -->
|
||||
<!-- Desirable -->
|
||||
<text x="500" y="20" fill="#0b0d0b" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="36" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
<!-- Set labels — positioned INSIDE each circle's non-overlapping lobe, so the diagram reads like a classic Venn -->
|
||||
<!-- Desirable — top lobe (centered inside top of Desirable circle) -->
|
||||
<text x="500" y="96" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Desirable</text>
|
||||
<text x="500" y="112" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">PEOPLE WANT IT</text>
|
||||
|
||||
<!-- Feasible -->
|
||||
<text x="152" y="400" fill="#52534e" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Feasible</text>
|
||||
<text x="152" y="416" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="start" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
<!-- Feasible — bottom-left lobe -->
|
||||
<text x="340" y="386" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Feasible</text>
|
||||
<text x="340" y="402" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">WE CAN BUILD IT</text>
|
||||
|
||||
<!-- Viable -->
|
||||
<text x="848" y="400" fill="#65655c" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Viable</text>
|
||||
<text x="848" y="416" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
<!-- Viable — bottom-right lobe -->
|
||||
<text x="660" y="386" fill="#2d3142" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Viable</text>
|
||||
<text x="660" y="402" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">BUSINESS SUSTAINS</text>
|
||||
|
||||
<!-- Pairwise intersection labels (inside overlap regions) -->
|
||||
<!-- Desirable ∩ Feasible (upper-left overlap): "Prototype" — between top and BL -->
|
||||
<text x="360" y="232" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Prototype</text>
|
||||
<text x="360" y="248" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">no business model</text>
|
||||
|
||||
<!-- Desirable ∩ Viable (upper-right overlap): "Vaporware" -->
|
||||
<text x="640" y="232" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Vaporware</text>
|
||||
<text x="640" y="248" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">can't build it</text>
|
||||
|
||||
<!-- Feasible ∩ Viable (lower overlap): "Internal tool" -->
|
||||
<text x="500" y="368" fill="#52534e" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Internal tool</text>
|
||||
<text x="500" y="384" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">nobody wants it</text>
|
||||
|
||||
<!-- Focal: all-three center -->
|
||||
<text x="500" y="260" fill="#f7591f" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="276" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
|
||||
<!-- Legend strip -->
|
||||
<line x1="40" y1="456" x2="960" y2="456" stroke="rgba(11,13,11,0.10)" stroke-width="0.8"/>
|
||||
<text x="40" y="472" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
|
||||
|
||||
<circle cx="52" cy="488" r="6" fill="none" stroke="#f7591f" stroke-width="1.2"/>
|
||||
<text x="68" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">All three — ship it</text>
|
||||
|
||||
<circle cx="192" cy="488" r="6" fill="none" stroke="#52534e" stroke-width="1"/>
|
||||
<text x="208" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif">Two of three — incomplete</text>
|
||||
|
||||
<text x="380" y="492" fill="#52534e" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">Coral marks the intersection that earns the work. The others name the traps.</text>
|
||||
<!-- Focal label: white text on the dark intersection -->
|
||||
<text x="500" y="268" fill="#ffffff" font-size="14" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Shippable</text>
|
||||
<text x="500" y="284" fill="rgba(245,245,245,0.75)" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.14em">THE SWEET SPOT</text>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #1c1a17; /* deep warm charcoal */
|
||||
--color-ink: #f1efe7; /* warm off-white */
|
||||
--color-muted: #a8a69d;
|
||||
--color-accent: #ff6a30;
|
||||
--color-paper: #2d3142; /* deep warm charcoal */
|
||||
--color-ink: #f5f5f5; /* warm off-white */
|
||||
--color-muted: #bfc0c0;
|
||||
--color-accent: #f08a59;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -60,16 +60,19 @@
|
||||
|
||||
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#6a95d8"/></marker>
|
||||
|
||||
<!-- OPTIONAL: dot-pattern background. Uncomment and add <rect fill="url(#dots)"/> after the paper rect to enable. -->
|
||||
<!--
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(241,239,231,0.08)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.08)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#a8a69d"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#ff6a30"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#5ba8eb"/></marker>
|
||||
-->
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#1c1a17"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.6"/>
|
||||
<rect width="100%" height="100%" fill="#2d3142"/>
|
||||
|
||||
<!-- Draw arrows first, then nodes. Replace with your content. -->
|
||||
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
|
||||
/* ── Tokens ─────────────────────────────────────────────────── */
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-paper-2: #efeee5;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-soft: #65655c;
|
||||
--color-rule: rgba(11,13,11,0.12);
|
||||
--color-rule-solid: rgba(135,139,134,0.25);
|
||||
--color-accent: #f7591f;
|
||||
--color-accent-tint: rgba(247,89,31,0.08);
|
||||
--color-link: #1a70c7;
|
||||
--color-paper: #f5f5f5;
|
||||
--color-paper-2: #ececec;
|
||||
--color-ink: #2d3142;
|
||||
--color-muted: #4f5d75;
|
||||
--color-soft: #7a8399;
|
||||
--color-rule: rgba(45,49,66,0.12);
|
||||
--color-rule-solid: rgba(79,93,117,0.25);
|
||||
--color-accent: #eb6c36;
|
||||
--color-accent-tint: rgba(235,108,54,0.08);
|
||||
--color-link: #2e5aa8;
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', 'Times New Roman', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, Menlo, monospace;
|
||||
@@ -67,12 +67,17 @@
|
||||
}
|
||||
|
||||
/* ── Diagram container ────────────────────────────────────────── */
|
||||
/* Default: clean, borderless — diagram sits directly on the page paper.
|
||||
For the framed/boxed variant, uncomment the background/border/padding below. */
|
||||
.diagram-container {
|
||||
background: var(--color-paper-2);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--color-rule);
|
||||
padding: 1.5rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
overflow-x: auto;
|
||||
/* background: var(--color-paper-2); */
|
||||
/* border: 1px solid var(--color-rule); */
|
||||
/* border-radius: 8px; */
|
||||
/* padding: 1.5rem; */
|
||||
}
|
||||
|
||||
svg { width: 100%; min-width: 900px; display: block; }
|
||||
@@ -98,7 +103,7 @@
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 0.875rem;
|
||||
padding-bottom: 0.875rem;
|
||||
border-bottom: 1px solid rgba(11,13,11,0.08);
|
||||
border-bottom: 1px solid rgba(45,49,66,0.08);
|
||||
}
|
||||
|
||||
.card-dot {
|
||||
@@ -137,7 +142,7 @@
|
||||
content: '—';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: rgba(11,13,11,0.25);
|
||||
color: rgba(45,49,66,0.25);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
@@ -145,7 +150,7 @@
|
||||
.footer {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid rgba(11,13,11,0.10);
|
||||
border-top: 1px solid rgba(45,49,66,0.10);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.06em;
|
||||
@@ -173,55 +178,57 @@
|
||||
<svg viewBox="0 0 1000 700" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
|
||||
<!-- Dot grid background (matches site .hero-terminal pattern) -->
|
||||
<!-- OPTIONAL: dot-pattern background. Uncomment the <pattern> below and the second <rect> in the bg section to enable. -->
|
||||
<!--
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
-->
|
||||
|
||||
<!-- Arrow: muted (default — generic / internal connections) -->
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#52534e"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/>
|
||||
</marker>
|
||||
|
||||
<!-- Arrow: coral (accent — primary / highlighted flows) -->
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#f7591f"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/>
|
||||
</marker>
|
||||
|
||||
<!-- Arrow: link-blue (#1a70c7 — HTTP/API / external calls) -->
|
||||
<!-- Arrow: link-blue (#2e5aa8 — HTTP/API / external calls) -->
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/>
|
||||
<polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/>
|
||||
</marker>
|
||||
|
||||
</defs>
|
||||
|
||||
<!-- Background: paper + dot grid -->
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.6"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<!-- <rect width="100%" height="100%" fill="url(#dots)" opacity="0.6"/> -->
|
||||
|
||||
<!-- =================================================================
|
||||
DRAW ARROWS FIRST — they paint behind boxes (SVG document order).
|
||||
================================================================= -->
|
||||
|
||||
<!-- HTTP/API arrow (link-blue) with label -->
|
||||
<line x1="130" y1="305" x2="195" y2="305" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="162" y="297" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">HTTPS</text>
|
||||
<line x1="130" y1="305" x2="195" y2="305" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="162" y="297" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">HTTPS</text>
|
||||
|
||||
<!-- Generic internal arrow -->
|
||||
<line x1="310" y1="305" x2="356" y2="305" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="310" y1="305" x2="356" y2="305" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Vertical arrow -->
|
||||
<line x1="253" y1="332" x2="253" y2="376" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<line x1="253" y1="332" x2="253" y2="376" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- Auth / security flow (dashed coral) -->
|
||||
<path d="M 80 140 L 80 200 Q 80 218 98 218 L 200 218 Q 218 218 218 236 L 218 276"
|
||||
fill="none" stroke="#f7591f" stroke-width="1.2" stroke-dasharray="5,4"
|
||||
fill="none" stroke="#eb6c36" stroke-width="1.2" stroke-dasharray="5,4"
|
||||
marker-end="url(#arrow-accent)"/>
|
||||
<text x="148" y="212" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">JWT</text>
|
||||
<text x="148" y="212" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">JWT</text>
|
||||
|
||||
<!-- Primary data flow (coral) -->
|
||||
<line x1="620" y1="305" x2="696" y2="305" stroke="#f7591f" stroke-width="1.2" marker-end="url(#arrow-accent)"/>
|
||||
<text x="655" y="297" fill="#f7591f" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">TLS</text>
|
||||
<line x1="620" y1="305" x2="696" y2="305" stroke="#eb6c36" stroke-width="1.2" marker-end="url(#arrow-accent)"/>
|
||||
<text x="655" y="297" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">TLS</text>
|
||||
|
||||
|
||||
<!-- =================================================================
|
||||
@@ -231,121 +238,121 @@
|
||||
================================================================= -->
|
||||
|
||||
<!-- ── External / User ──────────────────────────────────────── -->
|
||||
<rect x="30" y="278" width="100" height="54" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="30" y="278" width="100" height="54" rx="6" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<rect x="30" y="278" width="100" height="54" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="30" y="278" width="100" height="54" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<!-- Rectangular type tag (not rounded — brand rule) -->
|
||||
<rect x="38" y="284" width="26" height="12" rx="2" fill="transparent" stroke="rgba(101,101,92,0.4)" stroke-width="0.8"/>
|
||||
<text x="51" y="293" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<rect x="38" y="284" width="26" height="12" rx="2" fill="transparent" stroke="rgba(122,131,153,0.4)" stroke-width="0.8"/>
|
||||
<text x="51" y="293" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
|
||||
<!-- Main label -->
|
||||
<text x="80" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Users</text>
|
||||
<text x="80" y="323" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser / Mobile</text>
|
||||
<text x="80" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Users</text>
|
||||
<text x="80" y="323" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Browser / Mobile</text>
|
||||
|
||||
<!-- ── Security / Auth ──────────────────────────────────────── -->
|
||||
<rect x="30" y="78" width="100" height="56" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="30" y="78" width="100" height="56" rx="6" fill="rgba(247,89,31,0.06)" stroke="rgba(247,89,31,0.50)" stroke-width="1"/>
|
||||
<rect x="38" y="84" width="28" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.40)" stroke-width="0.8"/>
|
||||
<text x="52" y="93" fill="rgba(247,89,31,0.8)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">AUTH</text>
|
||||
<text x="80" y="110" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Auth Provider</text>
|
||||
<text x="80" y="125" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">OAuth 2.0</text>
|
||||
<rect x="30" y="78" width="100" height="56" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="30" y="78" width="100" height="56" rx="6" fill="rgba(235,108,54,0.06)" stroke="rgba(235,108,54,0.50)" stroke-width="1"/>
|
||||
<rect x="38" y="84" width="28" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.40)" stroke-width="0.8"/>
|
||||
<text x="52" y="93" fill="rgba(235,108,54,0.8)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">AUTH</text>
|
||||
<text x="80" y="110" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Auth Provider</text>
|
||||
<text x="80" y="125" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">OAuth 2.0</text>
|
||||
|
||||
<!-- ── Region boundary (dashed) ─────────────────────────────── -->
|
||||
<rect x="158" y="38" width="822" height="624" rx="8" fill="transparent" stroke="rgba(11,13,11,0.18)" stroke-width="1" stroke-dasharray="6,4"/>
|
||||
<text x="170" y="55" fill="#52534e" font-size="8" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.12em">AWS REGION · US-WEST-2</text>
|
||||
<rect x="158" y="38" width="822" height="624" rx="8" fill="transparent" stroke="rgba(45,49,66,0.18)" stroke-width="1" stroke-dasharray="6,4"/>
|
||||
<text x="170" y="55" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.12em">AWS REGION · US-WEST-2</text>
|
||||
|
||||
<!-- ── Cloud / CDN (with faded watermark numeral — slide card pattern) -->
|
||||
<rect x="198" y="278" width="112" height="54" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="198" y="278" width="112" height="54" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="198" y="278" width="112" height="54" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="198" y="278" width="112" height="54" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<!-- Faded mono watermark numeral (background) -->
|
||||
<text x="294" y="323" fill="rgba(11,13,11,0.06)" font-size="40" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<rect x="206" y="284" width="24" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="218" y="293" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CDN</text>
|
||||
<text x="254" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CloudFront</text>
|
||||
<text x="254" y="323" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">AWS CDN</text>
|
||||
<text x="294" y="323" fill="rgba(45,49,66,0.06)" font-size="40" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">01</text>
|
||||
<rect x="206" y="284" width="24" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="218" y="293" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">CDN</text>
|
||||
<text x="254" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">CloudFront</text>
|
||||
<text x="254" y="323" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">AWS CDN</text>
|
||||
|
||||
<!-- ── Cloud / Storage ───────────────────────────────────────── -->
|
||||
<rect x="198" y="378" width="112" height="102" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="198" y="378" width="112" height="102" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="294" y="468" fill="rgba(11,13,11,0.06)" font-size="40" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<rect x="206" y="384" width="22" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="217" y="393" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">S3</text>
|
||||
<text x="254" y="408" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">S3 Buckets</text>
|
||||
<text x="254" y="426" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">bucket-assets</text>
|
||||
<text x="254" y="440" fill="#52534e" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">bucket-uploads</text>
|
||||
<text x="254" y="466" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">OAI PROTECTED</text>
|
||||
<rect x="198" y="378" width="112" height="102" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="198" y="378" width="112" height="102" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="294" y="468" fill="rgba(45,49,66,0.06)" font-size="40" font-weight="600" font-family="'Geist Mono', monospace" text-anchor="end">02</text>
|
||||
<rect x="206" y="384" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="217" y="393" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">S3</text>
|
||||
<text x="254" y="408" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">S3 Buckets</text>
|
||||
<text x="254" y="426" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">bucket-assets</text>
|
||||
<text x="254" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">bucket-uploads</text>
|
||||
<text x="254" y="466" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">OAI PROTECTED</text>
|
||||
|
||||
<!-- ── Security group boundary ───────────────────────────────── -->
|
||||
<rect x="348" y="264" width="120" height="80" rx="6" fill="transparent" stroke="rgba(247,89,31,0.45)" stroke-width="1" stroke-dasharray="4,4"/>
|
||||
<text x="356" y="278" fill="rgba(247,89,31,0.7)" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.08em">SG · :443</text>
|
||||
<rect x="348" y="264" width="120" height="80" rx="6" fill="transparent" stroke="rgba(235,108,54,0.45)" stroke-width="1" stroke-dasharray="4,4"/>
|
||||
<text x="356" y="278" fill="rgba(235,108,54,0.7)" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.08em">SG · :443</text>
|
||||
|
||||
<!-- ── Load Balancer (inside security group) ──────────────────── -->
|
||||
<rect x="358" y="282" width="100" height="54" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="358" y="282" width="100" height="54" rx="6" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<rect x="366" y="288" width="22" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.22)" stroke-width="0.8"/>
|
||||
<text x="377" y="297" fill="#65655c" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">LB</text>
|
||||
<text x="408" y="311" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Load Balancer</text>
|
||||
<text x="408" y="326" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">HTTPS :443</text>
|
||||
<rect x="358" y="282" width="100" height="54" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="358" y="282" width="100" height="54" rx="6" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<rect x="366" y="288" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.22)" stroke-width="0.8"/>
|
||||
<text x="377" y="297" fill="#7a8399" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">LB</text>
|
||||
<text x="408" y="311" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Load Balancer</text>
|
||||
<text x="408" y="326" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">HTTPS :443</text>
|
||||
|
||||
<!-- ── Backend / API ─────────────────────────────────────────── -->
|
||||
<rect x="508" y="278" width="112" height="54" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="508" y="278" width="112" height="54" rx="6" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<rect x="516" y="284" width="26" height="12" rx="2" fill="transparent" stroke="rgba(11,13,11,0.40)" stroke-width="0.8"/>
|
||||
<text x="529" y="293" fill="#0b0d0b" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">API</text>
|
||||
<text x="564" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">API Server</text>
|
||||
<text x="564" y="323" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">FastAPI :8000</text>
|
||||
<rect x="508" y="278" width="112" height="54" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="508" y="278" width="112" height="54" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<rect x="516" y="284" width="26" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.40)" stroke-width="0.8"/>
|
||||
<text x="529" y="293" fill="#2d3142" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">API</text>
|
||||
<text x="564" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">API Server</text>
|
||||
<text x="564" y="323" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">FastAPI :8000</text>
|
||||
|
||||
<!-- ── Database ───────────────────────────────────────────────── -->
|
||||
<rect x="698" y="278" width="120" height="54" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="698" y="278" width="120" height="54" rx="6" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<rect x="706" y="284" width="22" height="12" rx="2" fill="transparent" stroke="rgba(82,83,78,0.50)" stroke-width="0.8"/>
|
||||
<text x="717" y="293" fill="#52534e" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DB</text>
|
||||
<text x="758" y="308" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Database</text>
|
||||
<text x="758" y="323" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">PostgreSQL</text>
|
||||
<rect x="698" y="278" width="120" height="54" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="698" y="278" width="120" height="54" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<rect x="706" y="284" width="22" height="12" rx="2" fill="transparent" stroke="rgba(79,93,117,0.50)" stroke-width="0.8"/>
|
||||
<text x="717" y="293" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DB</text>
|
||||
<text x="758" y="308" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Database</text>
|
||||
<text x="758" y="323" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">PostgreSQL</text>
|
||||
|
||||
<!-- ── Frontend / UI ─────────────────────────────────────────── -->
|
||||
<rect x="198" y="518" width="200" height="112" rx="6" fill="#f5f4ed"/>
|
||||
<rect x="198" y="518" width="200" height="112" rx="6" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<rect x="206" y="524" width="22" height="12" rx="2" fill="transparent" stroke="rgba(247,89,31,0.50)" stroke-width="0.8"/>
|
||||
<text x="217" y="533" fill="#f7591f" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">UI</text>
|
||||
<text x="298" y="550" fill="#0b0d0b" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Web App</text>
|
||||
<text x="298" y="567" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">React + TypeScript</text>
|
||||
<text x="298" y="581" fill="#52534e" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Astro SSG</text>
|
||||
<rect x="198" y="518" width="200" height="112" rx="6" fill="#f5f5f5"/>
|
||||
<rect x="198" y="518" width="200" height="112" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<rect x="206" y="524" width="22" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
|
||||
<text x="217" y="533" fill="#eb6c36" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">UI</text>
|
||||
<text x="298" y="550" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Web App</text>
|
||||
<text x="298" y="567" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">React + TypeScript</text>
|
||||
<text x="298" y="581" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">Astro SSG</text>
|
||||
<!-- Link-blue URL label -->
|
||||
<text x="298" y="614" fill="#1a70c7" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.04em">app.example.com</text>
|
||||
<text x="298" y="614" fill="#2e5aa8" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.04em">app.example.com</text>
|
||||
|
||||
|
||||
<!-- =================================================================
|
||||
LEGEND — OUTSIDE all boundary boxes.
|
||||
Region boundary ends at y=662 → legend starts at y=682.
|
||||
================================================================= -->
|
||||
<text x="510" y="544" fill="#0b0d0b" font-size="9" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.12em">LEGEND</text>
|
||||
<text x="510" y="544" fill="#2d3142" font-size="9" font-weight="500" font-family="'Geist Mono', monospace" letter-spacing="0.12em">LEGEND</text>
|
||||
|
||||
<rect x="510" y="558" width="14" height="10" rx="2" fill="rgba(247,89,31,0.08)" stroke="#f7591f" stroke-width="1"/>
|
||||
<text x="530" y="567" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Frontend / UI</text>
|
||||
<rect x="510" y="558" width="14" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
||||
<text x="530" y="567" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Frontend / UI</text>
|
||||
|
||||
<rect x="510" y="576" width="14" height="10" rx="2" fill="#ffffff" stroke="#0b0d0b" stroke-width="1"/>
|
||||
<text x="530" y="585" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Backend / API</text>
|
||||
<rect x="510" y="576" width="14" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
||||
<text x="530" y="585" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Backend / API</text>
|
||||
|
||||
<rect x="510" y="594" width="14" height="10" rx="2" fill="rgba(11,13,11,0.03)" stroke="rgba(11,13,11,0.30)" stroke-width="1"/>
|
||||
<text x="530" y="603" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Cloud / Service</text>
|
||||
<rect x="510" y="594" width="14" height="10" rx="2" fill="rgba(45,49,66,0.03)" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
|
||||
<text x="530" y="603" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Cloud / Service</text>
|
||||
|
||||
<rect x="510" y="612" width="14" height="10" rx="2" fill="rgba(11,13,11,0.05)" stroke="#52534e" stroke-width="1"/>
|
||||
<text x="530" y="621" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Database</text>
|
||||
<rect x="510" y="612" width="14" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
||||
<text x="530" y="621" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Database</text>
|
||||
|
||||
<rect x="510" y="630" width="14" height="10" rx="2" fill="rgba(82,83,78,0.10)" stroke="#65655c" stroke-width="1"/>
|
||||
<text x="530" y="639" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">External / User</text>
|
||||
<rect x="510" y="630" width="14" height="10" rx="2" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
||||
<text x="530" y="639" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">External / User</text>
|
||||
|
||||
<!-- Arrow types -->
|
||||
<line x1="510" y1="655" x2="524" y2="655" stroke="#1a70c7" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="530" y="659" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">HTTP / API call</text>
|
||||
<line x1="510" y1="655" x2="524" y2="655" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
||||
<text x="530" y="659" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">HTTP / API call</text>
|
||||
|
||||
<line x1="510" y1="671" x2="524" y2="671" stroke="#f7591f" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow-accent)"/>
|
||||
<text x="530" y="675" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Auth flow</text>
|
||||
<line x1="510" y1="671" x2="524" y2="671" stroke="#eb6c36" stroke-width="1.2" stroke-dasharray="4,3" marker-end="url(#arrow-accent)"/>
|
||||
<text x="530" y="675" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Auth flow</text>
|
||||
|
||||
<line x1="510" y1="687" x2="524" y2="687" stroke="#52534e" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="530" y="691" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Internal connection</text>
|
||||
<line x1="510" y1="687" x2="524" y2="687" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
||||
<text x="530" y="691" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Internal connection</text>
|
||||
|
||||
<rect x="510" y="698" width="14" height="10" rx="2" fill="transparent" stroke="rgba(247,89,31,0.45)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<text x="530" y="707" fill="#52534e" font-size="9" font-family="'Geist', sans-serif">Security group</text>
|
||||
<rect x="510" y="698" width="14" height="10" rx="2" fill="transparent" stroke="rgba(235,108,54,0.45)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<text x="530" y="707" fill="#4f5d75" font-size="9" font-family="'Geist', sans-serif">Security group</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
:root {
|
||||
--color-paper: #f5f4ed;
|
||||
--color-ink: #0b0d0b;
|
||||
--color-muted: #52534e;
|
||||
--color-accent: #f7591f;
|
||||
--color-paper: #f5f5f5; /* white-smoke */
|
||||
--color-ink: #2d3142; /* jet-black */
|
||||
--color-muted: #4f5d75; /* blue-slate */
|
||||
--color-accent: #eb6c36; /* atomic-tangerine */
|
||||
--font-sans: 'Geist', system-ui, sans-serif;
|
||||
--font-serif: 'Instrument Serif', serif;
|
||||
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
||||
@@ -60,16 +60,20 @@
|
||||
|
||||
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker>
|
||||
|
||||
<!-- OPTIONAL: dot-pattern background. Uncomment the <pattern> and the second <rect> below if you want the dotted paper look. -->
|
||||
<!--
|
||||
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(11,13,11,0.10)"/>
|
||||
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
|
||||
</pattern>
|
||||
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#52534e"/></marker>
|
||||
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f7591f"/></marker>
|
||||
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#1a70c7"/></marker>
|
||||
-->
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="#f5f4ed"/>
|
||||
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
|
||||
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
||||
<!-- <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/> -->
|
||||
|
||||
<!-- Draw arrows first, then nodes. Replace with your content. -->
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 144 KiB |
@@ -30,7 +30,7 @@ future diagrams use your tokens
|
||||
|
||||
Ask the skill:
|
||||
|
||||
> *"Onboard diagram-design to my site — `https://example.com`"*
|
||||
> *"Onboard Schematic to my site — `https://example.com`"*
|
||||
|
||||
Or run it with an explicit URL and the skill reads this file and executes the steps below.
|
||||
|
||||
@@ -68,7 +68,7 @@ Read the rendered `font-family` stack of:
|
||||
- `<body>` → `node-name` family
|
||||
- `<code>`, `<pre>`, or any mono-styled element → `sublabel` family
|
||||
|
||||
If the site has only one family, keep the diagram-design defaults for the missing roles (Instrument Serif for title, Geist Mono for mono). Don't force-pick a mono font that isn't on the site.
|
||||
If the site has only one family, keep the schematic defaults for the missing roles (Instrument Serif for title, Geist Mono for mono). Don't force-pick a mono font that isn't on the site.
|
||||
|
||||
---
|
||||
|
||||
@@ -92,7 +92,7 @@ Before writing, validate:
|
||||
|
||||
- **AA contrast**: `ink` on `paper` ≥ 4.5:1. `muted` on `paper` ≥ 4.5:1 for body text.
|
||||
- **Accent is the most saturated color**: not muted-ish, not near-grey.
|
||||
- **paper ≠ pure white**: if the site uses `#ffffff`, fall back to `#fafaf7` to preserve diagram-design's warm-neutral feel — or ask the user to confirm pure-white is intentional.
|
||||
- **paper ≠ pure white**: if the site uses `#ffffff`, fall back to `#fafaf7` to preserve Schematic's warm-neutral feel — or ask the user to confirm pure-white is intentional.
|
||||
|
||||
If any check fails, propose an adjusted value and explain why.
|
||||
|
||||
@@ -127,8 +127,8 @@ After onboarding, the user should:
|
||||
|
||||
## When onboarding fails
|
||||
|
||||
- **Site uses webfonts you can't replicate** (custom-hosted, paid): keep the diagram-design defaults for typography and skin only the colors.
|
||||
- **Brand has 6+ colors** and you can't identify a clear hierarchy: pick one as `accent`, demote the rest to `muted` variants or ignore them. The diagram grammar only uses 5–7 roles.
|
||||
- **Site uses webfonts you can't replicate** (custom-hosted, paid): keep the schematic defaults for typography and skin only the colors.
|
||||
- **Brand has 6+ colors** and you can't identify a clear hierarchy: pick one as `accent`, demote the rest to `muted` variants or ignore them. The schematic grammar only uses 5–7 roles.
|
||||
- **Site is dark-mode first**: flip the inversion — treat their dark paper as the default `paper`, and generate a light variant via inversion.
|
||||
- **Homepage is all imagery, no text**: ask for a blog or docs URL instead — text-heavy pages expose the type hierarchy.
|
||||
|
||||
@@ -136,4 +136,4 @@ After onboarding, the user should:
|
||||
|
||||
## Future: per-project skins
|
||||
|
||||
If the user wants multiple skins (one per project), duplicate `style-guide.md` as `style-guides/<project>.md` and add a header comment pointing the build to the active one. That's a v1.1 feature — for now, one skin per skill install.
|
||||
If the user wants multiple skins (one per project), duplicate `style-guide.md` as `style-guides/<project>.md` and add a header comment pointing the build to the active one. That's a v5.2 feature — for now, one skin per skill install.
|
||||
|
||||
@@ -6,13 +6,13 @@ Use for editorial asides — the "italic pointer" that marks a detail without co
|
||||
|
||||
```svg
|
||||
<!-- 1. Italic Instrument Serif text -->
|
||||
<text x="904" y="36" fill="#0b0d0b" font-size="14" font-style="italic"
|
||||
<text x="904" y="36" fill="#2d3142" font-size="14" font-style="italic"
|
||||
font-family="'Instrument Serif', serif" text-anchor="end">no imports, no configuration</text>
|
||||
<!-- 2. Dashed Bézier leader -->
|
||||
<path d="M 820 44 Q 700 84 520 216" fill="none"
|
||||
stroke="rgba(11,13,11,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
stroke="rgba(45,49,66,0.40)" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<!-- 3. Landing dot -->
|
||||
<circle cx="520" cy="216" r="2" fill="#0b0d0b"/>
|
||||
<circle cx="520" cy="216" r="2" fill="#2d3142"/>
|
||||
```
|
||||
|
||||
## Rules
|
||||
@@ -25,9 +25,9 @@ Use for editorial asides — the "italic pointer" that marks a detail without co
|
||||
|
||||
| Intent | Text | Leader |
|
||||
|---|---|---|
|
||||
| Neutral aside | ink `#0b0d0b` | `rgba(11,13,11,0.40)` |
|
||||
| Focal / accent | coral `#f7591f` | `rgba(247,89,31,0.50)` |
|
||||
| Tertiary (muted) | muted `#52534e` | `rgba(11,13,11,0.30)` |
|
||||
| Neutral aside | ink `#2d3142` | `rgba(45,49,66,0.40)` |
|
||||
| Focal / accent | coral `#eb6c36` | `rgba(235,108,54,0.50)` |
|
||||
| Tertiary (muted) | muted `#4f5d75` | `rgba(45,49,66,0.30)` |
|
||||
|
||||
## Anti-patterns
|
||||
- Solid arrow leader (reads as a flow arrow).
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Style Guide
|
||||
|
||||
**The single source of truth for colors, typography, and tokens.** Every diagram draws from this — not from hex values inlined in other reference files. If you want to change the visual skin of diagram-design, change this file.
|
||||
**The single source of truth for colors, typography, and tokens.** Every diagram draws from this — not from hex values inlined in other reference files. If you want to change the visual skin of Schematic, change this file.
|
||||
|
||||
Default skin is a neutral editorial palette — warm stone paper, deep charcoal ink, rust accent. It's designed to look good out of the box for any open-source user without matching any specific brand. Swap these values (or run [`onboarding.md`](onboarding.md)) and every new diagram inherits the new skin without touching any type-specific logic.
|
||||
Default skin is a cool editorial palette — white-smoke paper, jet-black ink, atomic-tangerine accent, blue-slate muted. It's designed to look good out of the box; swap these values (or run [`onboarding.md`](onboarding.md)) and every new diagram inherits the new skin without touching any type-specific logic.
|
||||
|
||||
To generate your own from a website URL, see [`onboarding.md`](onboarding.md).
|
||||
|
||||
@@ -16,18 +16,20 @@ Every token is referred to by **semantic role**, not by its hex value. Type refe
|
||||
|
||||
| Role | Purpose | Default (light) | Default (dark) |
|
||||
|---|---|---|---|
|
||||
| `paper` | Page background, default node fill | `#faf7f2` | `#1c1917` |
|
||||
| `paper-2` | Diagram container bg, secondary fill | `#f2ede4` | `#292524` |
|
||||
| `ink` | Primary text, primary stroke | `#1c1917` | `#faf7f2` |
|
||||
| `muted` | Secondary text, default arrow stroke | `#57534e` | `#a8a29e` |
|
||||
| `soft` | Sublabels, boundary labels | `#78716c` | `#8e8680` |
|
||||
| `rule` | Hairline borders | `rgba(28,25,23,0.12)` | `rgba(250,247,242,0.12)` |
|
||||
| `rule-solid` | Stronger borders, baselines | `rgba(120,113,108,0.25)` | `rgba(168,162,158,0.25)` |
|
||||
| `accent` | Focal / 1–2 max per diagram | `#b5523a` | `#d6724a` |
|
||||
| `accent-tint` | Fill for accent-bordered boxes | `rgba(181,82,58,0.08)` | `rgba(214,114,74,0.10)` |
|
||||
| `link` | HTTP/API calls, external arrows | `#2563eb` | `#60a5fa` |
|
||||
| `paper` | Page background, default node fill | `#f5f5f5` (white-smoke) | `#2d3142` (jet-black) |
|
||||
| `paper-2` | Diagram container bg, secondary fill | `#ececec` | `#393e53` |
|
||||
| `ink` | Primary text, primary stroke | `#2d3142` (jet-black) | `#f5f5f5` (white-smoke) |
|
||||
| `muted` | Secondary text, default arrow stroke | `#4f5d75` (blue-slate) | `#bfc0c0` (silver) |
|
||||
| `soft` | Sublabels, boundary labels | `#7a8399` | `#8e98ac` |
|
||||
| `rule` | Hairline borders | `rgba(45,49,66,0.12)` | `rgba(245,245,245,0.12)` |
|
||||
| `rule-solid` | Stronger borders, baselines | `#bfc0c0` (silver) | `rgba(191,192,192,0.25)` |
|
||||
| `accent` | Focal / 1–2 max per diagram | `#eb6c36` (atomic-tangerine) | `#f08a59` |
|
||||
| `accent-tint` | Fill for accent-bordered boxes | `rgba(235,108,54,0.08)` | `rgba(240,138,89,0.10)` |
|
||||
| `link` | HTTP/API calls, external arrows | `#2e5aa8` | `#6a95d8` |
|
||||
|
||||
> **Note:** The pre-baked example HTML files in `assets/` were built under an earlier skin. Regenerating them against the current `style-guide.md` is a v1.1 task. New diagrams the skill produces will use the tokens above.
|
||||
> **Brand palette source:** this skin maps to a five-color brand palette — `jet-black #2d3142`, `silver #bfc0c0`, `white-smoke #f5f5f5`, `atomic-tangerine #eb6c36`, `blue-slate #4f5d75`. The `soft`, `rule`, and `link` tokens are derived (lighter slate, ink-at-opacity, and a saturated variant in the blue-slate hue family) to cover roles the brand palette doesn't name directly.
|
||||
|
||||
> **Note:** The pre-baked example HTML files in `assets/` were built under an earlier skin. Regenerating them against the current `style-guide.md` is a v5.1 task. New diagrams the skill produces will use the tokens above.
|
||||
|
||||
### Inversion rule (light → dark)
|
||||
|
||||
@@ -101,4 +103,5 @@ Three options:
|
||||
- **No rainbow palette**: if your brand ships 8 colors, pick 3 (paper, ink, accent). The rest become `muted` variants.
|
||||
- **Serif + sans + mono**: three families, not more. If brand typography is all sans, keep Instrument Serif for `title` and `callout` anyway — the contrast is load-bearing.
|
||||
- **Paper is warm-neutral, not pure white**: pure white turns the design sterile. Pick a cream, bone, or light grey with a hint of warmth.
|
||||
- **Dot pattern survives**: the 22×22 dot pattern on the diagram background needs to sit at ~10% opacity of `ink` on `paper` — verify it's visible but quiet after a skin change.
|
||||
- **Dot pattern is optional, not default**: the 22×22 dot pattern is an opt-in "dotted paper" variant (good for long-form editorial hero diagrams). The default background is a clean `paper` fill, no pattern. When the pattern is enabled, it should sit at ~10% opacity of `ink` on `paper` — visible but quiet.
|
||||
- **Container is clean by default**: the diagram sits directly on the page paper, no secondary container background or border. A framed variant (`paper-2` bg + `rule` border + 8px radius + padding) is available as an opt-in for card-heavy layouts, but don't reach for it by default — the extra chrome fights the figure.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
1. **Index tag** on the far left (`L3`, `07`, `APPLICATION`) — Geist Mono 8–9px eyebrow.
|
||||
2. **Layer name** slightly right of center-left — Geist 14–16px 600.
|
||||
3. **Sublabel / note** on the far right — Geist Mono 9–10px muted.
|
||||
- Border between layers: 1px hairline `rgba(11,13,11,0.12)`. Outer silhouette 1px ink or muted.
|
||||
- Border between layers: 1px hairline `rgba(45,49,66,0.12)`. Outer silhouette 1px ink or muted.
|
||||
- Fills: either alternating subtle shades (paper / paper-2) OR all paper with hairline dividers. Pick one and hold it.
|
||||
- Direction indicator on the LEFT margin (outside the stack): small up/down arrow + Geist Mono label (`abstraction ↑`, `packets ↓`).
|
||||
- Coral on **one** focal layer (stroke + subtle tint fill) — the bottleneck, the pay-rent layer, the one under discussion.
|
||||
|
||||
@@ -18,3 +18,55 @@
|
||||
- `assets/example-quadrant.html` — minimal light
|
||||
- `assets/example-quadrant-dark.html` — minimal dark
|
||||
- `assets/example-quadrant-full.html` — full editorial
|
||||
- `assets/example-quadrant-consultant.html` — consultant special (see below)
|
||||
|
||||
---
|
||||
|
||||
## Consultant special (2×2 scenario matrix)
|
||||
|
||||
A **layout variant** of the standard quadrant — same house skin (warm paper, dot pattern, Instrument Serif title, Geist mono eyebrows, coral focal rule). The grammar shifts: axes hold a **range** rather than a measurement; cells hold **named scenarios** rather than positioned items.
|
||||
|
||||
**Use when:** you're framing four futures, archetypes, or strategic options across two independent drivers — classic scenario planning, positioning frames, or 2×2 strategy decks (BCG/McKinsey territory). The reader should come away with four named bets, not a point cloud.
|
||||
|
||||
**Do not use** for prioritization, density maps, or anything where the *position inside* a cell carries meaning — that's the standard quadrant above.
|
||||
|
||||
### What makes it the consultant variant
|
||||
|
||||
| Move | Standard quadrant | Consultant special |
|
||||
|---|---|---|
|
||||
| Axis arrows | single-ended (→ HIGH EFFORT) | **double-ended** (← LOW ↔ HIGH →) |
|
||||
| Cell content | small dots with labels | **named scenario + 1–3 line description** |
|
||||
| Quadrant corner | short tag (e.g. DO FIRST) | **numbered tag + axis combination** (`01 · HIGH / LOW`) |
|
||||
| Focal accent | coral on one *item* | coral on one *quadrant* — tinted bg + coral stroke + coral corner tag |
|
||||
| Axes | 1px muted ink | **1.2px ink** (slightly heavier — the axes carry more of the figure) |
|
||||
|
||||
Everything else — paper, dot pattern, typography, legend strip, 4px grid, complexity budget — is the house default. Don't invent new colors or fonts for this variant.
|
||||
|
||||
### Style tokens (in-house)
|
||||
|
||||
- **Paper / bg / pattern**: defaults from `style-guide.md` (`paper`, 22×22 dot pattern at 10% ink).
|
||||
- **Axis lines**: `ink` (`#2d3142`), `stroke-width: 1.2`, `marker-start` + `marker-end` both pointing outward.
|
||||
- **Focal quadrant tint**: `rgba(235,108,54,0.04)` full rect behind the focal cell.
|
||||
- **Focal cell**: `accent-tint` fill, `accent` stroke at 1.2px. Corner tag in `accent`, weight 600.
|
||||
- **Non-focal cells**: `store` treatment (`ink @ 0.04` fill, `muted @ 0.28` stroke).
|
||||
- **Cell title**: Geist sans, 16px, weight 600, `ink`.
|
||||
- **Cell description**: Geist sans, 11px, `muted`, 1–3 lines, left-aligned inside the cell.
|
||||
- **Corner tag**: Geist Mono, 8px, uppercase, tracked `0.18em`, `muted` (or `accent` on focal).
|
||||
- **Axis labels**: two-line — `↑ DRIVER NAME` in Geist Mono 9px weight 600 uppercase tracked, `range` sublabel in Geist Mono 9px regular `muted`.
|
||||
|
||||
### Layout conventions
|
||||
|
||||
- Four cells, equal size (240×160 or 280×180 are good defaults), arranged with a 40–60px gap from the axis cross.
|
||||
- Axis cross passes *between* the cells, not through them.
|
||||
- Arrow tips live ~20–40px outside the outermost cell edge; two-line axis labels beyond the tips.
|
||||
- Exactly one focal cell. Picking none makes it a placeholder template; picking two erases the signal.
|
||||
- Keep the legend strip + horizontal rule at the bottom — same as the standard quadrant. Legend swatches should show both "headline bet" (coral) and "candidate future" (neutral).
|
||||
|
||||
### Anti-patterns (variant-specific)
|
||||
|
||||
- Plain white background — the warm paper + dot pattern is load-bearing across the skill; dropping it to "look consultant" turns the diagram generic.
|
||||
- Sans-serif H1 — keep Instrument Serif for the page title. The title/diagram contrast is the house signature.
|
||||
- Unnamed cells ("Scenario 1/2/3/4") in a shipped diagram — OK as a blank template; not OK as a finished artifact.
|
||||
- Coral on more than one cell — same focal rule as everywhere else in the skill.
|
||||
- 3×3 or 2×3 grids — those are different diagrams, not this variant.
|
||||
- Positioning dots *inside* the cells — if position matters, use the standard quadrant.
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
## Lifeline primitive
|
||||
```svg
|
||||
<line x1="CX" y1="TOP" x2="CX" y2="BOTTOM"
|
||||
stroke="rgba(11,13,11,0.20)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
stroke="rgba(45,49,66,0.20)" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
```
|
||||
|
||||
## Activation bar primitive
|
||||
```svg
|
||||
<rect x="CX-4" y="TOP" width="8" height="H"
|
||||
fill="rgba(11,13,11,0.06)" stroke="#52534e" stroke-width="0.8"/>
|
||||
fill="rgba(45,49,66,0.06)" stroke="#4f5d75" stroke-width="0.8"/>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
## Layout conventions
|
||||
- **Prefer 2 or 3 circles.** Avoid 4+ (unreadable — use a matrix instead).
|
||||
- Circle stroke: 1px hairline, color per-set (ink, muted, soft).
|
||||
- Circle fill: very low-opacity tint — `rgba(11,13,11,0.04)` for ink set, `rgba(82,83,78,0.05)` for muted. Tints compound naturally in overlap regions.
|
||||
- Circle fill: very low-opacity tint — `rgba(45,49,66,0.04)` for ink set, `rgba(79,93,117,0.05)` for muted. Tints compound naturally in overlap regions.
|
||||
- Radii: equal when sets are comparable in size; proportional when sets are meaningfully different. Don't fake equal sizes for aesthetics.
|
||||
- **Set labels** placed outside the circle, NEVER crossing the stroke. Geist 12–14px 600 for the set name, optional Geist Mono 9px sublabel.
|
||||
- **Intersection labels** placed inside the overlap region, Geist 12px 600, centered. For small overlaps, use a leader line to a label in clear space.
|
||||
- **Coral accent** on the ONE focal intersection — the "sweet spot". Either coral label stroke OR clipPath-bounded coral fill tint (`rgba(247,89,31,0.10)`).
|
||||
- **Coral accent** on the ONE focal intersection — the "sweet spot". Either coral label stroke OR clipPath-bounded coral fill tint (`rgba(235,108,54,0.10)`).
|
||||
- Circle centers and radii divisible by 4.
|
||||
|
||||
## Anti-patterns
|
||||
|
||||