OpenDesign's annual letter to its community: the year's story, what it learned, and where it's going next. Built as a decision-grade corporate strategy deck for community, contributors, investors.
9881cffProduce a single-file, letter-grade HTML deck in the Stripe Annual Letter
genre: a published letter you read, not a template you skim. Prose flows in
serif paragraphs; numbers live in inline data cards and giant display anchors.
The visual system, canvas contract, and navigation runtime are locked by
example.html. Start from example.html, replace content only — do not
rewrite the design or the script, and never introduce colors or fonts outside
this spec.
Adapted from the editorial-longform style (references/design-styles.md,
安静派 · 杂志编辑长文流 / Editorial Longform) of
huashu-design by
花叔 (alchaincyf), MIT licensed. Reference lineage: Stripe Annual Letter,
Amazon six-page narrative memos, Stripe Press.
<div id="stage"> fixed at 1920 × 1080 px, centered with
position: fixed; top: 50%; left: 50%.fit() function scales the stage to the viewport:
scale = min(innerWidth / 1920, innerHeight / 1080), applied as
translate(-50%, -50%) scale(s), re-run on resize. Letterboxed, never
cropped.vw/vh/% for type) —
the scaler owns responsiveness.<section class="slide"> directly inside #stage, with a
data-screen-label="01 刊头"-style label (1-indexed)..active. No .dark pages in this theme —
every page sits on cream paper; rhythm comes from density, not theme flips.←/↑/PageUp previous · →/↓/Space/PageDown next ·
Home/End first/last. Hash routing #/N (1-indexed) read on load and
hashchange, written via history.replaceState. Click: left third back,
rest forward. Fixed counter pill bottom-right, key-hint bottom-left.file:// inside
a sandboxed iframe.:root, keep the names — re-theme by changing values only)--paper: #FBFAF8; /* cream paper, every page */
--panel: #FFFFFF; /* data-card surface */
--ink: #232036; /* deep ink text */
--ink-70: rgba(35, 32, 54, 0.72); /* prose body */
--ink-45: rgba(35, 32, 54, 0.46); /* captions, chrome */
--hairline: rgba(35, 32, 54, 0.12); /* all rules */
--accent: #635BFF; /* Stripe purple — the ONLY accent */
--accent-soft: rgba(99, 91, 255, 0.08); /* tint panels, quote marks */
--serif: "Newsreader", "Source Serif 4", "Noto Serif SC", Georgia, serif;
--serif-text: "Source Serif 4", "Newsreader", "Noto Serif SC", Georgia, serif;
--sans: "Inter", "Noto Sans SC", -apple-system, sans-serif;
@import: Newsreader (display, incl. italic),
Source Serif 4 (prose), Noto Serif SC (CJK serif), Inter, Noto Sans SC..num class sets
font-variant-numeric: tabular-nums; every metric, year, and display
number uses it.var(--serif) (Newsreader/Noto Serif SC), weight 500–600 —
letters are set elegantly, not boldly; key words get class="hl" (accent),
never the whole heading.| Device | Spec |
|---|---|
| Prose measure | paragraphs max-width: 980px (≈65ch), serif 25–27px, line-height: 1.9, text-align: justify optional |
| Drop cap | first paragraph of the letter body: ::first-letter serif, ~3 lines tall, accent color |
| Inline data card | --panel bg, 1px hairline, 2–3px accent top rule, small-caps Inter label + large tabular serif numeral + one-line caption; floated beside or gridded next to prose |
| Display-number anchor | one giant tabular numeral 180–280px in accent, alone on the page with a one-line setup above and a footnote below |
| Minimal chart | inline SVG only: single purple line/area on hairline baseline, direct labels on data points, no grid mesh, no legend, no chartjunk |
| Quote page | oversized serif quote (60–76px, weight 500) with an accent-soft giant quotation mark, attribution in small-caps Inter |
| Signed closing | farewell prose + serif-italic signature block + key-hint capsule |
cover masthead page · contents letter outline rows · salutation prose
opening with drop cap · display-number anchor · prose+cards running text
with inline data cards · chart minimal SVG figure · quote full-page
citation · metrics-panorama data-card grid with footnote · closing
signature page.
<!-- 待用户提供 --> placeholder.example.html, retitle, swap token values only if the user has a
brand, then replace each section's content following the layout
enumeration. Keep letterhead/footer chrome and the script intact.#/N stay in sync; no overflow; prose stays inside the 980px measure;
numerals all tabular; grep for leftover placeholders.✦ ✓ → ·) only.Copy a source-pinned command for your client. You run it yourself.
Destination: .claude/skills/huashu-annual-letter · pinned to the source commit
# Run from your project root
git clone https://github.com/nexu-io/open-design.git .skillboard-tmp
git -C .skillboard-tmp checkout 9881cff70e02be86c2a58130af512011ba23d4af
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/plugins/_official/examples/huashu-annual-letter" ".claude/skills/"
rm -rf .skillboard-tmpReview the source before running. This copies files into your project; it is not a one-click install and does not verify runtime safety.
sudo apt update && sudo apt install -y gitnpm install -g @anthropic-ai/claude-code# Run from your project root
git clone https://github.com/nexu-io/open-design.git .skillboard-tmp
git -C .skillboard-tmp checkout 9881cff70e02be86c2a58130af512011ba23d4af
mkdir -p ".claude/skills"
cp -r ".skillboard-tmp/plugins/_official/examples/huashu-annual-letter" ".claude/skills/"
rm -rf .skillboard-tmpDestination: .claude/skills/huashu-annual-letter
Scanner static-checks@0.1.0 · commit 9881cff70e02. Static checks cannot prove runtime safety – review the source and the exact diff before installing. How checks work.
No static rules matched. This is not a safety guarantee.