Files
free666799 c7e422d7a2 feat(plugins): unify all 56 official deck seeds with the Open Design product narrative (#4357)
* feat(plugins): unify all 56 official deck seeds with the Open Design product narrative

Apply the same canonical 10-section story used for the community slides
batch (sourced from the homepage structure doc + README) to every official
deck plugin seed that ships an example.html: cover, why, three claims,
numbers board (60K+ stars / 300+ contributors / 217+ plugins / 129 design
systems / 21 agents), 5-step workflow, multimodal outputs, capabilities,
agent ecosystem, testimonial, and CTA with GitHub/Discord/X links.

Scenario decks keep their framing with Open Design as the subject:
weekly-report/weekly-update become OD growth reports, course-module a
getting-started tutorial, testing-safety-alert the local-data-security
story, xhs-* decks OD-themed xiaohongshu notes, ib-pitch-book an investor
narrative, presenter-mode-reveal keeps its presenter-mode demo.
open-design-landing-deck only gets its numbers aligned to the canonical
figures. Skipped (no example.html seed): guizang-ppt, html-ppt, replit-deck.

Content-only edits: CSS tokens, layouts, decorations, animations, keyboard
nav, hash routing and functional JS untouched. zh 13 decks / en 43 decks
per existing typography. All 56 verified: script syntax, cover screenshot,
no fictional brand residue.

* fix(decks): wire dead Download/closing CTAs to real destinations

Review follow-up for #4145: primary Download CTAs now point to
https://open-design.ai/ (the canonical download landing), and the
remaining href="#" closing links (Star on GitHub / Discord / X /
See All Agents) point to the repo, Discord invite, and X profile.
Also split the landing-deck primary CTA off the repo-root URL so the
primary and secondary actions no longer share a destination.

* style(official-decks): anti-slop visual pass across the official deck seeds

Restyle/polish sweep over all 55 official example decks (taste-skill +
impeccable + gsap-skills guidelines):

- A-class seeds (AI-slop look: default Inter, purple-blue gradients,
  uniform rounded shadow cards) fully restyled with distinct typographic
  systems, locked single accents, and off-white/off-black grounds.
- B-class seeds (clear style family, e.g. the zhangzara-* craft set)
  kept their family signature and received polish only: spacing rhythm,
  contrast to WCAG AA, hairline discipline, reduced-motion guards.
- Motion limited to transform/opacity with prefers-reduced-motion
  guards; signature ease cubic-bezier(.16,1,.3,1).
- Content is unchanged: all copy, numbers (60K+ stars, 217+ plugins,
  129 design systems, 21 agents, -80% cost), links, slide counts and
  the deck engine scripts are byte-identical to the previous seeds.
- html-ppt-zhangzara-pin-and-paper already met every rule (craft fonts,
  single ink accent, static content) and is intentionally untouched.

* i18n(official-decks): translate all Chinese deck seeds to English

All official slide seeds are now English-only per template policy.
15 decks translated (~12,000 CJK chars): presenter-mode-reveal,
testing-safety-alert, xhs-pastel-card, tech-sharing,
obsidian-claude-gradient, knowledge-arch-blueprint, xhs-white-editorial,
hermes-cyber-terminal, xhs-post, dir-key-nav-minimal,
graphify-dark-graph, ppt-keynote, guizang-editorial,
swiss-international, open-slide-canvas.

- Layout, engine scripts, slide counts, stats (60K+/300+/217+/129/21/
  -80%) and links unchanged; only content language changed.
- CJK-specific Google Fonts (Noto Sans/Serif SC, ZCOOL KuaiLe, Songti)
  replaced with Latin families matching each deck's voice (Inter,
  IBM Plex Sans, Nunito, Patrick Hand, Georgia, Noto Serif).
- The xhs-* social decks keep their Xiaohongshu aesthetic with native
  English social copy.
- Overflow from longer English copy fixed with minor per-element type
  sizing; every deck screenshot-verified; zero CJK characters remain
  across all 56 official deck seeds.

* fix(xhs-pastel-card): restore absolute positioning of topbar/footer chrome

The content-layer rule '.slide > *:not(.xp-blob){position:relative}'
(specificity 0,3,0) overrode the absolutely-positioned .xp-topbar and
.xp-footer (0,2,0), dropping both into the flex flow: the chip overlapped
the headline, left:90px turned into a 90px rightward shift that pushed
the page number off-canvas, and bottom:40px lifted the footer into the
body copy on every slide. Excluding the two chrome elements from the
content-layer rule restores the intended layout; verified per-slide
screenshots across all 8 slides.

* feat(deck-seeds): expand the three sampler decks to full 10-page examples

deck-guizang-editorial, deck-swiss-international, and
deck-open-slide-canvas shipped as 1-2 page style samplers while every
other official seed carries a full 8-11 page example. Each is now a
10-page deck built from its own SKILL.md layout vocabulary:

- guizang-editorial: one page per L01-L10 layout, single Ink/Monocle
  palette per the 5-pick-1 rule, ink/paper reversal for rhythm.
- swiss-international: 10 of the 22 locked layouts (statement, cards,
  six-cell grid, timeline, duo compare, loop diagram, why-now, closing
  manifesto), Klein Blue as the single accent; SKILL.md example_desc
  updated from the stale two-page wording.
- open-slide-canvas: ten free-composition 1920x1080 canvases (asymmetric
  split, oversized numerals, positioned-block flow, editorial quote,
  comparison spread) with keyboard + hash navigation per its own
  convention.

Content follows the English-only OD narrative with canonical stats and
links; every page screenshot-verified; zero CJK; single-file with
Google Fonts as the only external resource.

* fix(decks): wire the two remaining dead closing-slide CTAs

Review follow-up for #4145 (nettee, looper reviewer):

- 8-bit-orbit: the closing 'Download Open Design' / 'Star on GitHub'
  pixel buttons were plain <button> elements with no click handling;
  converted to anchors targeting https://open-design.ai/ and the
  GitHub repo, keeping the .pixel-btn skin.
- retro-windows: the closing copy promised download/star actions but
  the action row was the old unwired Restart / Contact / End Session
  set; replaced with Download Open Design / Star on GitHub /
  Join Discord anchors in the same .btn-retro skin.

* fix(decks): wire remaining button-skinned dead CTAs across deck seeds

Review follow-up for #4145 (looper reviewer round 3). Converts every
remaining action-copy control that carried button/chip skin but no
href into a real anchor with the canonical targets, keeping each
deck's skin:

- zhangzara-long-table: closing .pill chips (GitHub / Download) and the
  cover 'Star on GitHub' pill
- zhangzara-raw-grid: closing .label arrow Download + the two
  .s10-rb-block tiles (macOS-Windows / Star on GitHub)
- zhangzara-peoples-platform: GET STARTED slide DOWNLOAD block
- obsidian-claude-gradient: all four .oc-pill chips on the CTA slide
- zhangzara-biennale-yellow / sakura-chroma / cobalt-grid colophon
  ftag labels, zhangzara-pink-script 'Star on GitHub' tile, and
  ib-pitch-book 'Download Open Design' stamp (same pattern, found by
  a repo-wide sweep for the regression class)

* fix(decks): wire zhangzara-coral closing-slide social icons to anchors

* feat(plugins): unify guizang-ppt (magazine-web-ppt) deck default with the Open Design product narrative in English

The deck-mode default seed (magazine-web-ppt, dir guizang-ppt) was the one
official deck the narrative+i18n pass missed, because its content lives in
assets/example-slides.html + assets/template.html rather than example.html.

- Rewrite the 9-slide example deck to the English Open Design product narrative
  (60K+ stars / 300+ contributors / 217+ plugins / 129 design systems / 21
  agents / -80% cost), preserving the magazine editorial layout vocabulary and
  hitting all 8 layout categories. English titles use the Playfair .h-hero-en
  family; copy follows anti-slop craft (no decorative em-dashes, real labelled
  metrics, tight hierarchy).
- Translate template.html (title, hint, all CSS/JS comments), SKILL.md,
  references/*.md, open-design.json, and the design-templates README to English.
- Keep magazine-web-ppt name, mode=deck, default_for=deck intact.
- Both synced copies (plugins/_official + design-templates) updated identically.

---------

Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com>
2026-06-16 08:41:04 +00:00

270 lines
11 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Open Design · The open-source, local, agent-driven design platform</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;1,9..144,400&family=Geist+Mono:wght@400;500&display=swap');
/* warm editorial: Fraunces display serif, paper ground, burnt-orange accent */
:root {
--bg: #faf7f2;
--fg: #211d18;
--muted: #5d564c;
--faint: #6f6859;
--accent: #b3431b;
--accent-bright: #e8703d;
--line: rgba(33, 29, 24, 0.14);
--line-strong: rgba(33, 29, 24, 0.32);
--surface: #fffdfa;
--serif: 'Fraunces', Georgia, 'Times New Roman', serif;
--sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
--mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
--ease: cubic-bezier(.16, 1, .3, 1);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
background: var(--bg);
color: var(--fg);
font: 18px/1.55 var(--sans);
-webkit-font-smoothing: antialiased;
display: flex;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
body::-webkit-scrollbar { display: none; }
.slide {
flex: 0 0 100vw;
height: 100vh;
scroll-snap-align: start;
padding: 88px 104px;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.slide + .slide { border-left: 1px solid var(--line); }
/* entrance: transform + opacity only, staggered, ease-out */
@keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
.slide > * { animation: rise .7s var(--ease) both; }
.slide > *:nth-child(2) { animation-delay: .07s; }
.slide > *:nth-child(3) { animation-delay: .14s; }
@media (prefers-reduced-motion: reduce) { .slide > * { animation: none; } }
.eyebrow {
font-family: var(--mono);
font-size: 11.5px;
font-weight: 500;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 30px;
}
.slide h1 {
font-family: var(--serif);
font-weight: 500;
font-size: clamp(56px, 8.5vw, 124px);
line-height: 1.0;
letter-spacing: -0.015em;
margin: 0 0 26px;
max-width: 16ch;
text-wrap: balance;
}
.slide h2 {
font-family: var(--serif);
font-weight: 500;
font-size: clamp(36px, 4.4vw, 58px);
line-height: 1.08;
letter-spacing: -0.01em;
margin: 0 0 24px;
max-width: 22ch;
text-wrap: balance;
}
.slide .body { font-size: 20px; line-height: 1.6; color: var(--muted); max-width: 56ch; }
/* cover stays on paper; a thick accent rule is its signature */
.slide.cover::before {
content: '';
position: absolute;
top: 88px;
left: 104px;
width: 72px;
height: 6px;
background: var(--accent);
}
.slide.cover h1 { font-size: clamp(64px, 10vw, 148px); }
/* single deliberate inversion: the closing CTA slide */
.slide.title { background: var(--fg); color: var(--bg); }
.slide.title .eyebrow { color: var(--accent-bright); }
.slide.title .body { color: rgba(250, 247, 242, 0.72); }
/* the closing line is a full sentence, not a wordmark: step the scale down so it can't clip at 720p */
.slide.title h1 { font-size: clamp(46px, 6.8vw, 100px); max-width: 18ch; }
.slide.big-stat .number {
font-family: var(--serif);
font-weight: 500;
font-size: clamp(140px, 24vw, 300px);
line-height: 0.85;
letter-spacing: -0.02em;
color: var(--accent);
margin-bottom: 28px;
}
.slide.big-stat .caption {
font-size: 22px;
color: var(--muted);
max-width: 26ch;
border-top: 1px solid var(--line-strong);
padding-top: 18px;
}
.quote-mark {
font-family: var(--serif);
font-weight: 500;
font-size: 96px;
line-height: 0.6;
color: var(--accent);
margin-bottom: 18px;
}
.quote-text {
font-family: var(--serif);
font-style: italic;
font-weight: 400;
font-size: clamp(30px, 3.6vw, 46px);
line-height: 1.25;
letter-spacing: -0.005em;
max-width: 26ch;
margin: 0 0 34px;
}
.quote-author { font-family: var(--mono); font-size: 13px; letter-spacing: 0.03em; color: var(--faint); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; margin-top: 48px; }
.grid-3 .pt { border-top: 1px solid var(--line-strong); padding-top: 18px; }
.grid-3 .pt .h { font-family: var(--serif); font-size: 20px; font-weight: 600; letter-spacing: -0.005em; margin: 0 0 10px; }
.grid-3 .pt .p { color: var(--muted); margin: 0; font-size: 15.5px; line-height: 1.55; }
.counter {
position: fixed;
bottom: 26px;
right: 32px;
font-family: var(--mono);
font-size: 11.5px;
letter-spacing: 0.05em;
font-variant-numeric: tabular-nums;
color: var(--muted);
background: var(--surface);
padding: 5px 12px;
border: 1px solid var(--line);
}
/* chip ground matches .counter so the hint stays legible on the inverted CTA slide */
.hint {
position: fixed;
bottom: 26px;
left: 32px;
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.04em;
color: var(--muted);
background: var(--surface);
padding: 5px 12px;
border: 1px solid var(--line);
}
@media print { .slide { page-break-after: always; border-left: none; } }
</style>
</head>
<body>
<section class="slide cover" data-od-id="slide-1">
<div class="eyebrow">Apache-2.0 · Runs Locally · BYOK · No Sign-up</div>
<h1>Open Design</h1>
<p class="body">The open-source, local, agent-driven design platform. From idea to prototypes, web pages, slides, and HTML video — on your own machine.</p>
</section>
<section class="slide" data-od-id="slide-2">
<div class="eyebrow">Problem</div>
<h2>Frontier AI design is locked in the cloud.</h2>
<p class="body">In April 2026, Claude Design proved for the first time that an LLM can truly design — not write about design, but produce real design artifacts. Yet it is closed-source, paid, and cloud-only: locked to one model, with no agent choice, no self-hosting, no BYOK. Open Design sets that capability free.</p>
</section>
<section class="slide big-stat" data-od-id="slide-3">
<div class="number">60K+</div>
<div class="caption">GitHub Stars — open source under Apache-2.0.</div>
</section>
<section class="slide" data-od-id="slide-4">
<div class="eyebrow">Why Open Design</div>
<h2>Three ideas, one platform.</h2>
<div class="grid-3">
<div class="pt"><h3 class="h">Desktop-native</h3><p class="p">Design happens on the desktop. Local files, Figma exports, and code repos are directly readable; agents get full terminal power.</p></div>
<div class="pt"><h3 class="h">Plug in agents, don't rebuild them</h3><p class="p">Claude Code, Codex, and Cursor on your machine are already powerful. Open Design wires them into a complete design workflow.</p></div>
<div class="pt"><h3 class="h">It learns your taste</h3><p class="p">Every choice becomes design systems, preferences, and memory, so the next generation lands closer to what you want.</p></div>
</div>
</section>
<section class="slide" data-od-id="slide-5">
<div class="quote-mark">"</div>
<p class="quote-text">Compared to Claude Design, our monthly bill dropped from $500 to ~$73 — over 80% less.</p>
<p class="quote-author">— Engineering manager</p>
</section>
<section class="slide title" data-od-id="slide-6">
<div class="eyebrow">Open · Local · Agent-native</div>
<h1>Frontier AI design, back on every creator's desk.</h1>
<p class="body">Download Open Design (macOS / Windows) · Star on GitHub — github.com/nexu-io/open-design</p>
</section>
<div class="counter" id="counter">1 / 6</div>
<div class="hint">← / → to navigate</div>
<script>
const slides = document.querySelectorAll('.slide');
const counter = document.getElementById('counter');
let active = 0;
// Detect the real scroller — when body has `display: flex` + `overflow-x: auto`
// the scroller can be body OR documentElement depending on the host (in
// particular, the OD srcdoc iframe). Pick whichever actually overflows.
function scroller() {
if (document.body.scrollWidth > document.body.clientWidth + 1) return document.body;
return document.scrollingElement || document.documentElement;
}
function go(i) {
const next = Math.max(0, Math.min(slides.length - 1, i));
active = next;
counter.textContent = (next + 1) + ' / ' + slides.length;
scroller().scrollTo({ left: next * window.innerWidth, behavior: 'smooth' });
}
function syncFromScroll() {
const i = Math.round(scroller().scrollLeft / window.innerWidth);
if (i !== active && i >= 0 && i < slides.length) {
active = i;
counter.textContent = (i + 1) + ' / ' + slides.length;
}
}
function onKey(e) {
if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) return;
if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown') { e.preventDefault(); go(active + 1); }
else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); go(active - 1); }
else if (e.key === 'Home') { e.preventDefault(); go(0); }
else if (e.key === 'End') { e.preventDefault(); go(slides.length - 1); }
}
// Listen on both window and document in capture phase so the handler
// fires regardless of which element holds focus inside the iframe.
window.addEventListener('keydown', onKey, true);
document.addEventListener('keydown', onKey, true);
// And listen for scroll on both surfaces — same reason.
document.addEventListener('scroll', syncFromScroll, { passive: true, capture: true });
window.addEventListener('scroll', syncFromScroll, { passive: true });
// Auto-focus body so arrow keys work without a click.
document.body.setAttribute('tabindex', '-1');
document.body.style.outline = 'none';
function focusDeck() { try { window.focus(); document.body.focus({ preventScroll: true }); } catch (_) {} }
document.addEventListener('mousedown', focusDeck);
window.addEventListener('load', focusDeck);
focusDeck();
</script>
</body>
</html>