mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-06 22:31:53 +08:00
* 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>
270 lines
11 KiB
HTML
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>
|