mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-07 23:09:34 +08:00
- Introduced comprehensive design documentation and JSON configurations for multiple design systems, including Agentic, Airtable, Ant, Apple, Application, Arc, and Artistic. - Each design system includes detailed guidelines on visual themes, color palettes, typography, spacing, layout, components, and interaction principles. - Enhanced the overall design framework to support diverse user interfaces and improve consistency across applications. This update significantly enriches the design resources available for developers, enabling them to create visually cohesive and user-friendly applications.
489 lines
21 KiB
HTML
489 lines
21 KiB
HTML
<!doctype html>
|
|
<!--
|
|
OD replit-deck seed.
|
|
|
|
Single-file horizontal-swipe HTML deck in the style of Replit Slides's
|
|
landing-page template gallery (replit.com/slides). One deck picks ONE
|
|
theme via `<body data-theme="...">`. All 8 themes ship as tokens below;
|
|
never override per-slide.
|
|
|
|
Themes:
|
|
helix Modern minimal · light grey + ink + electric blue
|
|
holm Editorial serif · cream + ink + deep chestnut
|
|
vance Gallery · black/cream bars + cream serif
|
|
bevel Y2K editorial · black + Y2K display type
|
|
world-dark Finance dark · deep green + mint + neon yellow
|
|
world-mint Finance light · mint + deep green + neon yellow
|
|
atlas Museum · black + ivory + vermilion + serif
|
|
bluehouse Consumer · deep navy + peach/coral gradient cards
|
|
|
|
DO NOT rewrite the `<script>` at the bottom. It reuses the five-rule
|
|
pattern from `skills/simple-deck` that solves:
|
|
1. real-scroller detection (the deck root is the scroller, not window —
|
|
inside the daemon's iframe, window.scroll* is a different surface)
|
|
2. dual listeners (keydown fires on window AND document; without
|
|
deduping, one press advances two slides)
|
|
3. auto-focus (iframe must grab focus on load, or keyboard nav dies
|
|
silently until the user clicks inside the deck)
|
|
4. no `scrollIntoView` (it yanks the parent page if the iframe is
|
|
embedded — we compute offsets manually instead)
|
|
5. position persistence (reloading the iframe would reset to slide 1;
|
|
we persist the current slide index in localStorage, keyed by
|
|
pathname — so two decks on the same origin don't steal each
|
|
other's position)
|
|
See `skills/simple-deck/assets/template.html` for the derivation.
|
|
Rewriting the script reintroduces all five bugs in the daemon preview.
|
|
-->
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>[REPLACE] Deck title · subtitle</title>
|
|
<style>
|
|
/* ─── font stacks (system-only; no external fonts) ─────────────── */
|
|
:root {
|
|
--font-sans: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', system-ui, sans-serif;
|
|
--font-sans-display: -apple-system, BlinkMacSystemFont, 'Inter Display', 'Inter', 'Segoe UI', system-ui, sans-serif;
|
|
--font-serif: 'Iowan Old Style', 'Charter', 'Palatino', Georgia, 'Times New Roman', serif;
|
|
--font-serif-display: 'GT Super', 'Tiempos Headline', 'Iowan Old Style', Georgia, serif;
|
|
--font-mono: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, monospace;
|
|
}
|
|
|
|
/* ─── theme: helix (slide-1/4/5 — modern minimal) ─────────────── */
|
|
body[data-theme="helix"] {
|
|
--bg: #fafafa;
|
|
--surface: #ffffff;
|
|
--fg: #19191c;
|
|
--muted: #6e6e73;
|
|
--border: #e4e4e7;
|
|
--accent: #5889fe;
|
|
--accent-soft: color-mix(in oklch, #5889fe 14%, transparent);
|
|
--font-display: var(--font-sans-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 600;
|
|
--display-tracking: -0.02em;
|
|
}
|
|
|
|
/* ─── theme: holm (slide-2 — editorial serif memo) ────────────── */
|
|
body[data-theme="holm"] {
|
|
--bg: #e4dfd7;
|
|
--surface: #eee9e0;
|
|
--fg: #0f0f0e;
|
|
--muted: #7c7e84;
|
|
--border: #c7c1b7;
|
|
--accent: #52311d;
|
|
--accent-soft: color-mix(in oklch, #52311d 14%, transparent);
|
|
--font-display: var(--font-serif-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 500;
|
|
--display-tracking: -0.015em;
|
|
}
|
|
|
|
/* ─── theme: vance (slide-3/7 — gallery catalog) ──────────────── */
|
|
body[data-theme="vance"] {
|
|
--bg: #f1ede2;
|
|
--surface: #e7e2d4;
|
|
--fg: #171815;
|
|
--muted: #6e6b62;
|
|
--border: #d6d2c5;
|
|
--accent: #171815;
|
|
--accent-soft: color-mix(in oklch, #171815 8%, transparent);
|
|
--bar: #0a0a0a; /* top/bottom gallery bar */
|
|
--bar-fg: #f1ede2;
|
|
--font-display: var(--font-serif-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 400;
|
|
--display-tracking: -0.01em;
|
|
}
|
|
|
|
/* ─── theme: bevel (slide-6/13 — Y2K editorial) ───────────────── */
|
|
body[data-theme="bevel"] {
|
|
--bg: #0d0d0b;
|
|
--surface: #18181a;
|
|
--fg: #eae6dd;
|
|
--muted: #a29e95;
|
|
--border: #2a2a28;
|
|
--accent: #c8ff00; /* neon outline only — sparingly */
|
|
--accent-soft: color-mix(in oklch, #c8ff00 10%, transparent);
|
|
--font-display: 'Antonio', 'Bebas Neue', Impact, var(--font-sans-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 700;
|
|
--display-tracking: 0;
|
|
}
|
|
|
|
/* ─── theme: world-dark (slide-8/10 — finance dark) ───────────── */
|
|
body[data-theme="world-dark"] {
|
|
--bg: #0d3a2b;
|
|
--surface: #124736;
|
|
--fg: #bcd6cd;
|
|
--muted: #789f91;
|
|
--border: #1d4c3c;
|
|
--accent: #e8f615;
|
|
--accent-soft: color-mix(in oklch, #e8f615 18%, transparent);
|
|
--font-display: var(--font-sans-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 500;
|
|
--display-tracking: -0.015em;
|
|
}
|
|
|
|
/* ─── theme: world-mint (slide-9 — finance light sibling) ─────── */
|
|
body[data-theme="world-mint"] {
|
|
--bg: #bcd6cd;
|
|
--surface: #c8e0d6;
|
|
--fg: #0d3a2b;
|
|
--muted: #527567;
|
|
--border: #9abbac;
|
|
--accent: #e8f615;
|
|
--accent-soft: color-mix(in oklch, #e8f615 22%, transparent);
|
|
--font-display: var(--font-sans-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 500;
|
|
--display-tracking: -0.015em;
|
|
}
|
|
|
|
/* ─── theme: atlas (slide-11 — museum chapter) ────────────────── */
|
|
body[data-theme="atlas"] {
|
|
--bg: #111010;
|
|
--surface: #1a1918;
|
|
--fg: #e7e6e2;
|
|
--muted: #827d78;
|
|
--border: #2a2826;
|
|
--accent: #de3f40;
|
|
--accent-soft: color-mix(in oklch, #de3f40 14%, transparent);
|
|
--font-display: var(--font-serif-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 500;
|
|
--display-tracking: -0.02em;
|
|
}
|
|
|
|
/* ─── theme: bluehouse (slide-12 — consumer card) ─────────────── */
|
|
body[data-theme="bluehouse"] {
|
|
--bg: #0b1524;
|
|
--surface: #10203a;
|
|
--fg: #ffffff;
|
|
--muted: #8ea0b8;
|
|
--border: #1a2c46;
|
|
--accent: #fb675d; /* coral */
|
|
--accent-2: #ff8f68; /* peach */
|
|
--accent-soft: color-mix(in oklch, #fb675d 18%, transparent);
|
|
--card-peach: #e0af99;
|
|
--card-lavender: #c7cff0;
|
|
--font-display: var(--font-sans-display);
|
|
--font-body: var(--font-sans);
|
|
--display-weight: 700;
|
|
--display-tracking: -0.025em;
|
|
}
|
|
|
|
/* ─── reset / base ────────────────────────────────────────────── */
|
|
*, *::before, *::after { box-sizing: border-box; }
|
|
html, body { margin: 0; height: 100%; }
|
|
body {
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
font-family: var(--font-body);
|
|
font-size: 18px;
|
|
line-height: 1.5;
|
|
-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; }
|
|
p { text-wrap: pretty; margin: 0; }
|
|
h1, h2, h3 { text-wrap: balance; margin: 0; font-weight: var(--display-weight); letter-spacing: var(--display-tracking); }
|
|
|
|
/* ─── slide surface ───────────────────────────────────────────── */
|
|
.slide {
|
|
flex: 0 0 100vw;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
scroll-snap-align: start;
|
|
padding: clamp(48px, 6vw, 96px) clamp(56px, 7vw, 112px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.slide.center { align-items: center; justify-content: center; text-align: center; }
|
|
|
|
/* ─── meta bar (top thin row: brand · meta · page) ────────────── */
|
|
.meta-bar {
|
|
position: absolute;
|
|
top: clamp(32px, 4vw, 56px);
|
|
left: clamp(56px, 7vw, 112px);
|
|
right: clamp(56px, 7vw, 112px);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
body[data-theme="vance"] .meta-bar { color: var(--bar-fg); }
|
|
|
|
/* ─── typography primitives ──────────────────────────────────── */
|
|
.eyebrow {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
.eyebrow.accent { color: var(--accent); }
|
|
.h-hero { font-family: var(--font-display); font-size: clamp(56px, 8.5vw, 128px); line-height: 1.02; }
|
|
.h-xl { font-family: var(--font-display); font-size: clamp(40px, 5vw, 76px); line-height: 1.08; }
|
|
.h-lg { font-family: var(--font-display); font-size: clamp(28px, 3vw, 44px); line-height: 1.14; }
|
|
.h-md { font-family: var(--font-display); font-size: clamp(20px, 1.6vw, 24px); line-height: 1.25; }
|
|
.lead { font-size: clamp(16px, 1.2vw, 19px); color: var(--muted); max-width: 56ch; }
|
|
|
|
/* Big numeric display — for kpi rows, used by helix / world / atlas */
|
|
.num { font-family: var(--font-display); font-size: clamp(48px, 5.5vw, 84px); line-height: 1; letter-spacing: -0.03em; }
|
|
.num-label { font-size: 15px; color: var(--muted); margin-bottom: 8px; }
|
|
.num-delta { font-family: var(--font-mono); font-size: 13px; color: var(--accent); margin-top: 8px; letter-spacing: 0.02em; }
|
|
|
|
/* ─── layout primitives ──────────────────────────────────────── */
|
|
.hstack { display: flex; gap: var(--gap, 24px); align-items: flex-start; }
|
|
.vstack { display: flex; flex-direction: column; gap: var(--gap, 16px); }
|
|
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 3vw, 48px); }
|
|
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 4vw, 64px); align-items: center; }
|
|
.grid-6 { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(32px, 4vw, 56px); row-gap: clamp(48px, 5vw, 80px); }
|
|
.divider { height: 1px; background: var(--border); margin: clamp(16px, 2vw, 32px) 0; }
|
|
|
|
/* ─── surface cards ──────────────────────────────────────────── */
|
|
.card {
|
|
background: var(--surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: 16px;
|
|
padding: clamp(20px, 2vw, 32px);
|
|
}
|
|
|
|
/* ─── vance gallery bars ─────────────────────────────────────── */
|
|
body[data-theme="vance"] .slide { padding-top: 0; padding-bottom: 0; }
|
|
body[data-theme="vance"] .vance-top {
|
|
background: var(--bar);
|
|
color: var(--bar-fg);
|
|
padding: clamp(32px, 4vw, 64px) clamp(56px, 7vw, 112px);
|
|
margin-left: calc(-1 * clamp(56px, 7vw, 112px));
|
|
margin-right: calc(-1 * clamp(56px, 7vw, 112px));
|
|
}
|
|
|
|
/* ─── bevel dashed frames ────────────────────────────────────── */
|
|
body[data-theme="bevel"] .bevel-frame {
|
|
border: 1px dashed var(--accent);
|
|
padding: clamp(16px, 2vw, 28px);
|
|
position: relative;
|
|
}
|
|
body[data-theme="bevel"] .bevel-frame::before,
|
|
body[data-theme="bevel"] .bevel-frame::after {
|
|
content: "";
|
|
position: absolute;
|
|
width: 8px; height: 8px;
|
|
background: var(--accent);
|
|
border-radius: 50%;
|
|
}
|
|
body[data-theme="bevel"] .bevel-frame::before { top: -4px; left: -4px; }
|
|
body[data-theme="bevel"] .bevel-frame::after { bottom: -4px; right: -4px; }
|
|
|
|
/* ─── world yellow square marker ─────────────────────────────── */
|
|
body[data-theme="world-dark"] .world-marker,
|
|
body[data-theme="world-mint"] .world-marker {
|
|
display: inline-block;
|
|
width: 14px; height: 14px;
|
|
background: var(--accent);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* ─── atlas chapter dot ──────────────────────────────────────── */
|
|
body[data-theme="atlas"] .atlas-dot {
|
|
display: inline-block;
|
|
width: 10px; height: 10px;
|
|
border-radius: 50%;
|
|
background: var(--accent);
|
|
margin-right: 12px;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* ─── bluehouse gradient card ────────────────────────────────── */
|
|
body[data-theme="bluehouse"] .bh-card {
|
|
border-radius: 24px;
|
|
padding: clamp(28px, 3vw, 48px);
|
|
aspect-ratio: 4 / 3;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
body[data-theme="bluehouse"] .bh-card.peach {
|
|
background: var(--card-peach);
|
|
color: #1a0e08;
|
|
}
|
|
body[data-theme="bluehouse"] .bh-card.coral {
|
|
background: linear-gradient(135deg, var(--accent-2), var(--accent));
|
|
color: #ffffff;
|
|
}
|
|
body[data-theme="bluehouse"] .bh-card.lavender {
|
|
background: linear-gradient(180deg, var(--card-lavender), #8faad8);
|
|
color: #0b1524;
|
|
}
|
|
|
|
/* ─── deck chrome (counter, progress, hint) ──────────────────── */
|
|
.deck-counter {
|
|
position: fixed;
|
|
bottom: 24px; right: 32px;
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
padding: 6px 12px;
|
|
background: color-mix(in oklch, var(--bg) 92%, transparent);
|
|
border: 1px solid var(--border);
|
|
letter-spacing: 0.08em;
|
|
color: var(--muted);
|
|
z-index: 10;
|
|
}
|
|
.deck-hint {
|
|
position: fixed;
|
|
bottom: 24px; left: 32px;
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
letter-spacing: 0.04em;
|
|
z-index: 10;
|
|
}
|
|
.deck-progress {
|
|
position: fixed;
|
|
top: 0; left: 0;
|
|
height: 2px;
|
|
background: var(--accent);
|
|
width: 0;
|
|
z-index: 10;
|
|
transition: width 0.18s ease;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body data-theme="helix">
|
|
<!--
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Set data-theme on <body> above ONCE. Never override per-slide. │
|
|
│ Paste layouts from references/layouts.md between this comment │
|
|
│ and the chrome divs below. │
|
|
│ │
|
|
│ Every slide needs: │
|
|
│ • class="slide" + optional "center" │
|
|
│ • data-screen-label="NN Name" │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
-->
|
|
|
|
<section class="slide center" data-screen-label="01 Cover">
|
|
<div class="meta-bar">
|
|
<span>[REPLACE] brand · context</span>
|
|
<span>[REPLACE] page / total</span>
|
|
</div>
|
|
<div>
|
|
<p class="eyebrow" style="margin-bottom: 24px;">[REPLACE] Eyebrow · season / no.</p>
|
|
<h1 class="h-hero">[REPLACE] The cover headline.</h1>
|
|
<p class="lead" style="margin-top: 24px;">[REPLACE] One subhead — concrete, not corporate.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="slide" data-screen-label="02 Body">
|
|
<div class="meta-bar">
|
|
<span>[REPLACE] brand · section</span>
|
|
<span>02</span>
|
|
</div>
|
|
<div style="margin-top: auto; margin-bottom: auto;">
|
|
<p class="eyebrow" style="margin-bottom: 24px;">[REPLACE] Section eyebrow</p>
|
|
<h2 class="h-xl" style="max-width: 16ch;">[REPLACE] Body-slide headline.</h2>
|
|
<p class="lead" style="margin-top: 20px;">[REPLACE] Two sentences explaining the idea. No more.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="slide center" data-screen-label="03 Closing">
|
|
<div class="meta-bar">
|
|
<span>[REPLACE] brand</span>
|
|
<span>[REPLACE] end</span>
|
|
</div>
|
|
<div>
|
|
<p class="eyebrow" style="margin-bottom: 24px;">[REPLACE] Eyebrow</p>
|
|
<h2 class="h-hero">[REPLACE] The take-away.</h2>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- chrome (do not move) -->
|
|
<div class="deck-progress" id="deck-progress" aria-hidden></div>
|
|
<div class="deck-counter" id="deck-counter">1 / 3</div>
|
|
<div class="deck-hint">← / → · scroll · swipe</div>
|
|
|
|
<script>
|
|
/*
|
|
Five hard rules for deck nav inside an iframe.
|
|
Verified by skills/simple-deck — do not rewrite.
|
|
|
|
1. Detect the real scroller — body OR documentElement.
|
|
2. Listen for scroll on BOTH window and document, capture phase.
|
|
3. Listen for keydown on BOTH window and document, capture phase.
|
|
4. Auto-focus body so arrow keys work without an upfront click.
|
|
5. Never use Element.scrollIntoView — yanks host page.
|
|
*/
|
|
(function () {
|
|
var slides = document.querySelectorAll('.slide');
|
|
var counter = document.getElementById('deck-counter');
|
|
var progress = document.getElementById('deck-progress');
|
|
var KEY = 'od-deck-pos:' + (location.pathname || '/');
|
|
var active = 0;
|
|
|
|
function scroller() {
|
|
if (document.body.scrollWidth > document.body.clientWidth + 1) return document.body;
|
|
return document.scrollingElement || document.documentElement;
|
|
}
|
|
function setActive(i) {
|
|
active = i;
|
|
if (counter) counter.textContent = (i + 1) + ' / ' + slides.length;
|
|
if (progress) progress.style.width = (((i + 1) / slides.length) * 100) + '%';
|
|
try { localStorage.setItem(KEY, String(i)); } catch (_) {}
|
|
}
|
|
function go(i) {
|
|
var next = Math.max(0, Math.min(slides.length - 1, i));
|
|
setActive(next);
|
|
scroller().scrollTo({ left: next * window.innerWidth, behavior: 'smooth' });
|
|
}
|
|
function syncFromScroll() {
|
|
var i = Math.round(scroller().scrollLeft / window.innerWidth);
|
|
if (i !== active && i >= 0 && i < slides.length) setActive(i);
|
|
}
|
|
function onKey(e) {
|
|
var t = e.target;
|
|
if (t && (t.tagName === 'INPUT' || t.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); }
|
|
}
|
|
|
|
window.addEventListener('keydown', onKey, true);
|
|
document.addEventListener('keydown', onKey, true);
|
|
document.addEventListener('scroll', syncFromScroll, { passive: true, capture: true });
|
|
window.addEventListener('scroll', syncFromScroll, { passive: true });
|
|
|
|
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();
|
|
|
|
try {
|
|
var saved = parseInt(localStorage.getItem(KEY) || '0', 10);
|
|
if (!isNaN(saved) && saved >= 0 && saved < slides.length) {
|
|
setActive(saved);
|
|
scroller().scrollTo({ left: saved * window.innerWidth, behavior: 'instant' });
|
|
} else {
|
|
setActive(0);
|
|
}
|
|
} catch (_) { setActive(0); }
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|