Files
workbuddy_skills/open-design/design-templates/open-design-landing/example.html
T
admin 5afeb6b78a ④段整套同步(六节 + P/S/F/J + 模板)+ open-design 移到技能根
一、④段整套同步(用户选候选 A)
- 新增 `references/stage-proto-doc/assets/产品文档模板.html`(16 KB/247 行,从备份拷、转 LF)。
- ④段 SKILL.md 换成备份 15:28 那版,并按模板口径改齐:
  · 「产品文档框架」从「四块+一附录」改成**六节** —— 页面结构/功能清单/使用场景/操作流程/
    跨页与界面状态/待确认与偏离;与模板同构,⛔ 不从空白页重写结构。
  · 编号从 R/S/F 改成 **P 页面/S 场景/F 功能/J 二级功能**,各自唯一、按展示顺序通排。
  · 保留旧版有价值的要求:每项功能补齐 做什么/入口在哪/输入边界/异常与恢复;重点功能三处标红;
    横向流程图每步写清页面/功能/操作/完成判据。
  · 完成标准「七节」→「六节」,自查清单同步换掉「需求」那批条目,补模板与配图两条。
  · 路径 `designs/<项目>/` → `docs/pm/<项目>/ui/`(2 处)。
  · 补回本机那条「每份产出文档开头都要有一张图」的引用(指向主 skill,段内不复述)。
- 主 skill 同步:四段结构表④行、④段沿革、画图小节(④段画页面结构图 + 用户路径)。

二、open-design 移到技能根(用户选候选 A)
- `git mv product-planning/references/stage-delivery/assets/open-design → open-design/`(4178 文件)。
- `.gitignore` 白名单加 `!/open-design/` —— 否则移出去就不再纳入版本控制。
- 引用改 11 处:路径形态 `assets/open-design/...` → `<技能根>/open-design/...`;
  「随段携带的自带件」改称「同根技能」;「路径怎么找」那条改成自带件(段内相对路径)与
  同根技能(`<技能根>/<技能名>/`)两类分开写。
- open-design 自己的 ATTRIBUTION.md 两处同步(它现在与 oil-ui-pro 同层)。
- 副作用(有益):命名闸门读数由 2063 降到 225 —— 此前它把 open-design 里 919 个第三方 md
  当成规则一起扫了;现在只扫本包 23 个 md。已确认④段的 H1 与 4a/4b/4c 子步仍在检查范围内。

三、验收
- check_naming.py --ws E:/ProgramData/AIProject/contentm_agent = 通过 225 / 失败 0 / 提示 27。
- 活文件里 `assets/open-design` 残留 0;工作区 CRLF 文件 0。
2026-10-15 21:17:28 +08:00

3133 lines
108 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>OpenDesign — Designing intelligence with skills, taste, and your own agent.</title>
<meta name='description' content='OpenDesign is the open-source alternative to Claude Design. 12 coding-agent CLIs · 31 composable skills · 72 brand-grade design systems. Local-first, web-deployable, BYOK at every layer.' />
<link rel='preconnect' href='https://fonts.googleapis.com' />
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin />
<link href='https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700;800;900&family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,500;0,600;1,400;1,500;1,600;1,700&family=JetBrains+Mono:wght@400;500&display=swap' rel='stylesheet' />
<style>/*
* Atelier Zero — canonical landing-page stylesheet.
*
* This file is the SINGLE SOURCE OF TRUTH for the open-design-landing
* skill's visual system. It is consumed by:
*
* 1. `scripts/compose.ts` — inlined into the standalone HTML output.
* 2. `example.html` — the pre-rendered known-good demo.
*
* If you change tokens, layout, motion, or component styles, edit them
* here. The `@import` at top loads the four Google fonts the system
* requires (Inter Tight, Inter, Playfair Display, JetBrains Mono).
*
* Tokens, grid posture, and motion language are defined by
* `design-systems/atelier-zero/DESIGN.md`. Do not invent new colors or
* typefaces here; either extend the design system first.
*/
@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700;800;900&family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,500;0,600;1,400;1,500;1,600;1,700&family=JetBrains+Mono:wght@400;500&display=swap');
:root {
--paper: #efe7d2;
--paper-warm: #ece4cf;
--paper-dark: #ddd2b6;
--ink: #15140f;
--ink-soft: #2a2620;
--ink-mute: #5a5448;
--ink-faint: #8b8676;
--coral: #ed6f5c;
--coral-soft: #f08e7c;
--mustard: #e9b94a;
--olive: #6e7448;
--bone: #f7f1de;
--line: rgba(21, 20, 15, 0.16);
--line-soft: rgba(21, 20, 15, 0.08);
--line-faint: rgba(21, 20, 15, 0.05);
--shadow: 0 30px 60px -30px rgba(21, 20, 15, 0.18);
--serif: 'Playfair Display', 'Times New Roman', serif;
--sans: 'Inter Tight', 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
--body: 'Inter', -apple-system, system-ui, sans-serif;
--mono: 'JetBrains Mono', 'SF Mono', Menlo, monospace;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--paper); color: var(--ink); }
body {
font-family: var(--body);
font-size: 16px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
position: relative;
}
/* paper texture overlay across the whole page */
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
background-image:
radial-gradient(circle at 12% 18%, rgba(106, 92, 56, 0.07) 0, transparent 28%),
radial-gradient(circle at 88% 72%, rgba(106, 92, 56, 0.06) 0, transparent 32%),
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.18 0 0 0 0 0.16 0 0 0 0 0.12 0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
background-size: auto, auto, 240px 240px;
mix-blend-mode: multiply;
opacity: 0.92;
}
.shell { position: relative; z-index: 2; }
.container {
max-width: 1360px;
padding: 0 64px;
margin: 0 auto;
position: relative;
}
.container.wide { max-width: 1480px; }
/* fixed side rails — rotated brand text on the right edge */
.side-rail {
position: fixed;
top: 0;
bottom: 0;
width: 36px;
z-index: 3;
pointer-events: none;
display: flex;
align-items: center;
justify-content: center;
}
.side-rail.right { right: 0; border-left: 1px solid var(--line-faint); }
.side-rail.left { left: 0; border-right: 1px solid var(--line-faint); }
.side-rail .rail-text {
font-family: var(--sans);
font-size: 10px;
font-weight: 600;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
white-space: nowrap;
}
.side-rail.right .rail-text { transform: rotate(180deg); }
.side-rail.left .rail-text { writing-mode: vertical-rl; transform: none; }
/* top metadata strip */
.topbar {
border-bottom: 1px solid var(--line);
padding: 10px 0;
background: var(--paper);
position: relative;
z-index: 4;
}
.topbar-inner {
display: flex;
justify-content: space-between;
align-items: center;
gap: 24px;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.topbar-inner b { color: var(--ink); font-weight: 600; }
.topbar-inner .coral { color: var(--coral); }
.topbar-inner > span { white-space: nowrap; }
.topbar-inner .mid { display: inline-flex; gap: 26px; }
.topbar-inner .mid > span { white-space: nowrap; }
.topbar-inner .right { display: inline-flex; gap: 18px; align-items: center; }
.topbar-inner .right > span,
.topbar-inner .right > a { white-space: nowrap; }
.topbar-link {
color: inherit;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: color 160ms ease, border-color 160ms ease;
}
.topbar-link:hover { color: var(--coral); border-bottom-color: var(--coral); }
.topbar .pulse {
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
margin-right: 6px;
animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.35; }
}
/* nav */
/*
* Headroom-style sticky header.
*
* The element is always `position: sticky`, so the browser docks it to the
* top of the viewport once the topbar has scrolled away. The
* `<Header />` client island then toggles the `is-hidden` modifier based
* on scroll direction, which animates the bar in and out via `transform`.
*
* When the user is at the very top of the page, the topbar is still
* visible above the nav and `position: sticky` simply leaves the nav in
* its natural flow position — exactly the brief.
*/
.nav {
padding: 22px 0;
position: sticky;
top: 0;
z-index: 50;
background: var(--paper);
transform: translateY(0);
transition: transform 360ms cubic-bezier(0.22, 0.61, 0.36, 1),
box-shadow 220ms ease,
border-color 220ms ease;
border-bottom: 1px solid transparent;
will-change: transform;
}
/*
* Subtle visual cue once we leave the top of the page. We can't tell from
* CSS alone whether the bar is "stuck"; the deadband + class toggle in
* <Header /> approximates it well enough for our purpose. We rely on the
* `is-hidden` toggle to flicker the border while moving and a steady
* border once docked.
*/
.nav.is-hidden {
transform: translateY(-100%);
pointer-events: none;
box-shadow: none;
}
.nav-inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
}
@media (min-width: 1081px) {
/* Header spans the full viewport width (overriding the shared .container
* max-width) so the brand sits near the left edge and the side actions
* near the right edge, rather than aligned to the 1360px content column. */
.nav .nav-inner {
max-width: none;
/* Clear the fixed 46px decorative side-rails (plus breathing room) so
* the brand and side actions never collide with the edge lines. */
padding-left: 60px;
padding-right: 60px;
}
/* Three-zone header: the brand and side clusters take equal flexible
* width on either side, so the centered nav sits on (or very near) the
* bar's midline regardless of how wide the action cluster is — without the
* overlap an absolutely-centered nav causes at mid widths. The brand stays
* left-aligned in its column and the side actions stay right-aligned in
* theirs. */
.nav-inner > .brand {
flex: 1 1 0;
min-width: 0;
justify-content: flex-start;
}
.nav-inner > .nav-side {
flex: 1 1 0;
min-width: 0;
justify-content: flex-end;
}
.nav-inner > nav[data-nav-primary] {
flex: 0 0 auto;
display: flex;
justify-content: center;
}
/* Scale the header chrome up a step so the bar reads as substantial across
* the now-full-width layout, rather than small elements floating in extra
* whitespace. Desktop-only; sizes return to base below 1081px. Selectors
* are deliberately one level more specific than the base rules below
* (which appear later in source) so these win without !important. */
.nav .nav-inner .brand-logo { height: 44px; }
.nav-inner .nav-links { gap: 44px; }
.nav-inner .nav-links a { font-size: 16px; }
.nav-inner .nav-side { gap: 14px; }
.nav-inner .nav-side .nav-cta.ghost { font-size: 13px; }
.nav-inner .nav-side .locale-trigger { font-size: 13px; }
.nav-inner .nav-side .nav-amr img { width: 68px; height: auto; }
}
.brand {
display: inline-flex;
align-items: center;
gap: 14px;
font-family: var(--sans);
font-weight: 700;
letter-spacing: -0.01em;
color: var(--ink);
text-decoration: none;
font-size: 18px;
/*
* Pin the brand so it never participates in flex-shrink. `.nav-inner` is a
* `justify-content: space-between` flex row; in locales whose nav labels are
* longer (de/ru/pt-BR…) the link list widens the row past the container and
* the browser shrinks every shrinkable child proportionally — including the
* logo, which is why the wordmark looked smaller in some languages. The nav
* links absorb the squeeze instead (they already tighten/collapse to the
* hamburger at the 1180/1080 breakpoints below).
*/
flex-shrink: 0;
}
.brand-mark {
width: 36px; height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1.5px solid var(--ink);
border-radius: 50%;
font-family: var(--serif);
font-style: italic;
font-size: 17px;
color: var(--ink);
background: transparent;
}
.brand-meta {
font-family: var(--sans);
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
line-height: 1.3;
margin-left: 4px;
border-left: 1px solid var(--line);
padding-left: 14px;
}
.brand-meta b { display: block; color: var(--ink); font-weight: 600; }
.nav-links {
display: flex;
gap: 38px;
list-style: none;
}
.nav-links a {
color: var(--ink);
text-decoration: none;
font-family: var(--sans);
font-size: 14px;
font-weight: 500;
transition: color 0.18s ease;
position: relative;
}
.nav-links a:hover { color: var(--coral); }
.nav-links a .num {
font-size: 9px;
color: var(--ink-faint);
position: absolute;
top: -7px;
right: -16px;
letter-spacing: 0.04em;
}
.nav-side {
display: inline-flex;
align-items: center;
gap: 18px;
}
.nav-cta {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 9px 16px;
border-radius: 999px;
background: var(--ink);
color: var(--paper);
font-family: var(--sans);
font-size: 13px;
font-weight: 500;
text-decoration: none;
white-space: nowrap;
flex-shrink: 0;
}
.nav-cta [data-github-stars],
.nav-cta [data-github-version] {
font-variant-numeric: tabular-nums;
}
.nav-cta::after {
content: '★';
color: var(--mustard);
font-size: 11px;
}
.status-dot {
width: 28px; height: 28px;
border-radius: 50%;
border: 1px solid var(--line);
display: inline-flex;
align-items: center;
justify-content: center;
}
.status-dot::after {
content: '';
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
}
/* ---------- typography primitives ---------- */
.label {
font-family: var(--sans);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--coral);
display: inline-flex;
align-items: center;
gap: 12px;
}
.label::before {
content: '';
width: 18px;
height: 1px;
background: var(--coral);
display: inline-block;
}
.label .ix {
color: var(--ink-faint);
font-weight: 500;
margin-left: 4px;
}
.display {
font-family: var(--sans);
font-weight: 800;
letter-spacing: -0.028em;
color: var(--ink);
line-height: 1.0;
}
.display em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
letter-spacing: -0.018em;
}
.display .dot { color: var(--coral); }
.lead {
font-family: var(--body);
font-size: 16px;
line-height: 1.55;
color: var(--ink-soft);
max-width: 36ch;
}
.meta {
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.coord {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.04em;
color: var(--ink-faint);
}
.roman {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
color: var(--coral);
}
/* buttons */
.btn {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 14px 22px;
border-radius: 999px;
font-family: var(--sans);
font-size: 14px;
font-weight: 500;
letter-spacing: -0.005em;
text-decoration: none;
border: 1px solid transparent;
transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
cursor: pointer;
white-space: nowrap;
}
.btn-primary {
background: var(--coral);
color: #fff;
box-shadow: 0 14px 26px -16px rgba(237, 111, 92, 1);
}
.btn-primary:hover { transform: translateY(-1px); background: #e25e4a; }
.btn-ghost {
background: transparent;
color: var(--ink);
border-color: rgba(21, 20, 15, 0.2);
}
.btn-ghost:hover { background: rgba(21, 20, 15, 0.04); }
.btn .arrow {
width: 16px; height: 16px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.btn .arrow svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.6; }
/* helper used inline in headlines */
.code-inline {
font-family: var(--mono);
font-size: 14px;
background: var(--bone);
padding: 1px 6px;
border-radius: 4px;
}
/* ---------- HERO ---------- */
.hero {
position: relative;
padding: 0;
min-height: calc(100vh - 140px);
display: flex;
flex-direction: column;
align-items: stretch;
border-bottom: 1px solid var(--line);
}
.hero > .container { flex: 0 0 auto; }
.hero > .container.hero-grid { flex: 1 1 auto; }
.hero::before {
content: '';
position: absolute;
left: 50%;
top: 0;
bottom: 0;
width: 1px;
background: var(--line-soft);
z-index: 0;
display: none;
}
.hero-grid {
display: grid;
grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
gap: 36px;
align-items: stretch;
width: 100%;
position: relative;
}
.hero-copy {
padding: 4vh 0 4vh;
display: flex;
flex-direction: column;
position: relative;
}
.hero-copy .label { margin-bottom: 28px; }
.hero-copy .lead { margin-bottom: 30px; max-width: 38ch; font-size: 16px; }
.hero h1 {
font-size: clamp(44px, 5vw, 78px);
line-height: 1.0;
margin-bottom: 28px;
}
.hero-actions {
display: inline-flex;
align-items: center;
gap: 14px;
margin-bottom: 38px;
}
.hero-stats {
display: flex;
align-items: center;
gap: 22px;
flex-wrap: nowrap;
margin-bottom: 28px;
}
.hero-stats .stat { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
.hero-stats .stat .ring {
width: 34px; height: 34px;
border-radius: 50%;
border: 1px dashed var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
}
.hero-stats .stat .ring.solid { border-style: solid; }
.hero-stats .stat .ring.coral { border-color: var(--coral); color: var(--coral); }
.hero-stats .stat-label {
font-family: var(--sans);
font-size: 11px;
line-height: 1.25;
color: var(--ink-soft);
letter-spacing: 0.04em;
text-transform: uppercase;
}
.hero-stats .stat-label b { display: block; font-weight: 700; color: var(--ink); font-size: 12px; }
.hero-foot {
margin-top: auto;
padding-top: 22px;
border-top: 1px solid var(--line);
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
}
.hero-foot .meta { line-height: 1.4; }
.hero-art {
position: relative;
height: calc(100vh - 160px);
max-height: 860px;
margin-left: auto;
margin-right: -12px;
width: 100%;
overflow: visible;
}
.hero-art img {
width: 100%; height: 100%;
object-fit: contain;
object-position: right center;
display: block;
}
/* image annotations */
.annot {
position: absolute;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
line-height: 1.4;
white-space: nowrap;
}
.annot.has-line::before {
content: '';
position: absolute;
background: var(--ink-faint);
}
.annot-tl { top: 14px; left: 14px; }
.annot-tr { top: 14px; right: 14px; text-align: right; }
.annot-bl { bottom: 14px; left: 14px; }
.annot-br { bottom: 14px; right: 14px; text-align: right; }
.annot.coord { font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; text-transform: none; }
.hero-art .index {
position: absolute;
right: 12px;
top: 36%;
font-family: var(--sans);
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.16em;
color: var(--ink-faint);
text-transform: uppercase;
background: rgba(239, 231, 210, 0.7);
padding: 10px 12px;
border: 1px solid var(--line-soft);
border-radius: 6px;
backdrop-filter: blur(2px);
}
.hero-art .index span { display: block; line-height: 1.6; }
.hero-art .index span .n { color: var(--coral); margin-right: 6px; font-weight: 700; }
.hero-art .index span.on { color: var(--ink); font-weight: 700; }
.hero-art .index span.on .n { color: var(--coral); }
.hero-art .corner {
position: absolute;
width: 22px; height: 22px;
border-color: var(--ink-faint);
border-style: solid;
border-width: 0;
}
.hero-art .corner.tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.hero-art .corner.tr { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.hero-art .corner.bl { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; }
.hero-art .corner.br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
/* ---------- common section header ---------- */
section { position: relative; padding: 130px 0; }
section.tight { padding: 90px 0; }
.sec-rule {
border-top: 1px solid var(--line);
padding-top: 18px;
margin-bottom: 48px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.sec-rule .roman {
font-family: var(--serif);
font-style: italic;
color: var(--coral);
font-size: 14px;
letter-spacing: 0.05em;
text-transform: none;
}
.sec-rule .meta-grp { display: inline-flex; gap: 26px; }
.sec-rule .dot-mark { color: var(--coral); }
.section-header { margin-bottom: 70px; }
.section-header .label { margin-bottom: 32px; }
.section-header h2 {
font-size: clamp(40px, 4.6vw, 66px);
max-width: 22ch;
}
.section-header .lead { margin-top: 22px; }
/* ---------- WIRE / GLOBAL TICKER ----------
*
* Slim editorial strip between the hero and the About section. Two
* counter-scrolling marquees (cities → and contributors ←) signal that
* the project is global and community-driven, without disrupting the
* existing roman-numeral section count. Pure CSS animation; the track
* content is duplicated in markup so the loop wraps seamlessly.
*/
.wire {
border-bottom: 1px solid var(--line);
padding: 26px 0 28px;
background: var(--paper);
position: relative;
overflow: hidden;
}
.wire-inner {
display: grid;
grid-template-columns: minmax(180px, 220px) minmax(0, 1fr);
gap: 32px;
align-items: center;
}
.wire-left {
display: inline-flex;
align-items: center;
gap: 14px;
border-right: 1px solid var(--line);
padding-right: 24px;
min-height: 56px;
}
.wire-mark {
width: 22px;
height: 22px;
border-radius: 50%;
border: 1px solid var(--line);
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.wire-pulse {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
animation: pulse 2.4s ease-in-out infinite;
}
.wire-title {
font-family: var(--sans);
font-size: 11px;
line-height: 1.4;
display: flex;
flex-direction: column;
gap: 3px;
}
.wire-title b {
color: var(--ink);
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.wire-title span {
color: var(--ink-faint);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.wire-rows {
display: grid;
gap: 8px;
min-width: 0;
}
.wire-row {
overflow: hidden;
mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
-webkit-mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
}
.marquee-track {
display: inline-flex;
align-items: center;
gap: 36px;
width: max-content;
white-space: nowrap;
animation: marquee-x 52s linear infinite;
will-change: transform;
}
.wire-row.reverse .marquee-track {
animation-direction: reverse;
animation-duration: 64s;
}
.wire-row:hover .marquee-track {
animation-play-state: paused;
}
@keyframes marquee-x {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.wire-item {
display: inline-flex;
align-items: baseline;
gap: 8px;
font-family: var(--sans);
font-size: 12px;
letter-spacing: 0.04em;
color: var(--ink-mute);
text-decoration: none;
flex-shrink: 0;
}
.wire-item .wire-dot {
color: var(--coral);
font-size: 16px;
line-height: 0;
position: relative;
top: -1px;
margin-right: 2px;
}
.wire-item .wire-coord {
font-family: var(--mono);
font-size: 10.5px;
color: var(--ink-faint);
letter-spacing: 0;
}
.wire-item .wire-name {
text-transform: uppercase;
letter-spacing: 0.18em;
color: var(--ink);
font-weight: 500;
}
.wire-item .wire-handle {
font-family: var(--mono);
color: var(--ink);
font-size: 11.5px;
font-weight: 500;
}
.wire-item .wire-role {
text-transform: uppercase;
letter-spacing: 0.16em;
color: var(--coral);
font-size: 10px;
}
.wire-item.is-link {
transition: color 160ms ease;
}
.wire-item.is-link:hover .wire-handle {
color: var(--coral);
}
@media (prefers-reduced-motion: reduce) {
.marquee-track { animation: none; }
}
/* ---------- ABOUT ---------- */
.about-grid {
display: grid;
grid-template-columns: 1.05fr 1fr;
gap: 80px;
align-items: center;
}
.about h2 {
font-size: clamp(44px, 5.4vw, 78px);
margin: 30px 0 36px;
}
.about .label { margin-bottom: 28px; }
.about .lead { margin-bottom: 36px; max-width: 42ch; font-size: 17px; }
.about .footer-row {
display: flex;
align-items: center;
gap: 20px;
margin-top: 56px;
color: var(--ink-faint);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.about .footer-row .mark {
width: 30px; height: 30px;
border-radius: 50%;
border: 1px solid var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--serif);
font-style: italic;
font-size: 14px;
color: var(--ink);
}
.about .stamp {
margin-left: auto;
display: inline-flex;
flex-direction: column;
align-items: flex-end;
line-height: 1.4;
}
.about .stamp span:first-child { color: var(--coral); }
.about-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 620px;
margin-left: auto;
}
.about-art img { width: 100%; height: 100%; object-fit: contain; }
.about-side-note {
position: absolute;
right: -8px;
top: 26px;
text-align: right;
font-family: var(--sans);
font-size: 10.5px;
line-height: 1.55;
color: var(--ink-faint);
letter-spacing: 0.04em;
max-width: 16ch;
}
.about-side-note b {
display: block;
color: var(--coral);
width: 36px;
height: 1px;
background: var(--coral);
margin: 0 0 10px auto;
}
.about-caption {
position: absolute;
right: 18px;
bottom: 4px;
font-family: var(--sans);
font-size: 9.5px;
color: var(--ink-faint);
text-align: right;
letter-spacing: 0.06em;
line-height: 1.45;
}
.about-caption b { color: var(--ink); display: block; }
/* ---------- CAPABILITIES ---------- */
.capabilities-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 70px;
align-items: center;
}
.capabilities-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 600px;
}
.capabilities-art img { width: 100%; height: 100%; object-fit: contain; }
.capabilities-art .ribbon {
position: absolute;
right: -42px;
top: 50%;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
}
.capabilities-art .ribbon b { color: var(--coral); }
.capabilities-art .corner { position: absolute; width: 22px; height: 22px; border-color: var(--ink-faint); border-style: solid; border-width: 0; }
.capabilities-art .corner.tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.capabilities-art .corner.br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
.capabilities-copy h2 { font-size: clamp(40px, 4.8vw, 64px); margin: 22px 0 30px; }
.cards {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
margin-top: 22px;
}
.card {
padding: 28px 26px 32px;
background: var(--bone);
border-radius: 18px;
box-shadow: var(--shadow), inset 0 0 0 1px rgba(21, 20, 15, 0.06);
position: relative;
overflow: hidden;
transition: transform 0.2s ease;
}
.card:hover { transform: translateY(-3px); }
.card .num {
font-family: var(--serif);
font-style: italic;
font-size: 22px;
font-weight: 500;
color: var(--coral);
letter-spacing: 0.04em;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: baseline;
}
.card .num .tag {
font-family: var(--sans);
font-size: 9.5px;
color: var(--ink-faint);
letter-spacing: 0.18em;
text-transform: uppercase;
font-style: normal;
font-weight: 500;
}
.card .icon {
width: 28px;
height: 28px;
margin-bottom: 16px;
color: var(--ink);
}
.card h3 {
font-family: var(--sans);
font-size: 22px;
font-weight: 700;
line-height: 1.05;
letter-spacing: -0.014em;
margin-bottom: 14px;
}
.card p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
max-width: 24ch;
}
.card .arrow-mark {
position: absolute;
right: 22px;
bottom: 22px;
width: 28px; height: 28px;
border: 1px solid var(--line);
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--ink);
transition: all 0.18s ease;
}
.card:hover .arrow-mark { background: var(--coral); border-color: var(--coral); color: #fff; }
.card .arrow-mark svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 1.6; }
/* ---------- LABS ---------- */
.labs-head {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 60px;
align-items: end;
margin-bottom: 48px;
}
.labs-head h2 { font-size: clamp(40px, 4.8vw, 68px); }
.pills {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: flex-end;
}
.pill {
padding: 9px 18px;
border-radius: 999px;
border: 1px solid var(--line);
font-family: var(--sans);
font-size: 13px;
color: var(--ink-soft);
background: transparent;
cursor: pointer;
transition: all 0.18s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.pill:hover { background: rgba(21, 20, 15, 0.04); }
.pill.active {
background: var(--coral);
border-color: var(--coral);
color: #fff;
}
.pill .count {
font-size: 10px;
color: var(--ink-faint);
border-left: 1px solid var(--line);
padding-left: 8px;
}
.pill.active .count { color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.3); }
.labs-meta {
display: flex;
align-items: flex-start;
justify-content: flex-end;
gap: 22px;
margin-bottom: 30px;
}
.labs-meta .ring {
width: 38px; height: 38px;
border-radius: 50%;
border: 1px dashed var(--ink);
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--sans);
font-size: 11px;
font-weight: 700;
}
.labs-meta .meta-text {
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
line-height: 1.55;
color: var(--ink-faint);
max-width: 28ch;
}
.labs-meta .meta-text b { display: block; color: var(--ink); }
.labs-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 22px;
}
.lab {
display: flex;
flex-direction: column;
}
.lab-img {
aspect-ratio: 4 / 5;
background: var(--bone);
border-radius: 14px;
overflow: hidden;
margin-bottom: 18px;
box-shadow: var(--shadow);
position: relative;
}
.lab-img img { width: 100%; height: 100%; object-fit: cover; }
.lab-img .badge {
position: absolute;
top: 12px;
left: 12px;
background: rgba(239, 231, 210, 0.9);
color: var(--ink);
padding: 4px 9px;
border-radius: 4px;
font-family: var(--sans);
font-size: 9.5px;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.lab .num-row {
font-family: var(--sans);
font-size: 10.5px;
color: var(--ink-faint);
letter-spacing: 0.14em;
margin-bottom: 8px;
display: flex;
justify-content: space-between;
text-transform: uppercase;
}
.lab h4 {
font-family: var(--sans);
font-size: 18px;
font-weight: 700;
letter-spacing: -0.014em;
margin-bottom: 8px;
}
.lab p {
font-family: var(--body);
font-size: 13px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 14px;
}
.lab .arrow-mark {
width: 28px; height: 28px;
border: 1px solid var(--line);
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--ink);
margin-top: auto;
align-self: flex-start;
}
.lab .arrow-mark svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 1.6; }
.labs-foot {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 50px;
border-top: 1px dashed var(--line);
padding-top: 22px;
}
.progress {
display: flex;
align-items: center;
gap: 8px;
}
.progress span {
width: 26px; height: 2px;
background: var(--line);
border-radius: 2px;
}
.progress span.on { background: var(--coral); }
/* ---------- METHOD ---------- */
.method-head {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 60px;
align-items: start;
margin-bottom: 80px;
}
.method-head h2 { font-size: clamp(44px, 5.2vw, 76px); }
.method-head .right {
display: flex;
align-items: flex-start;
gap: 14px;
padding-top: 14px;
}
.method-head .plus {
color: var(--coral);
font-size: 24px;
line-height: 1;
font-family: var(--sans);
}
.method-head .right p {
font-family: var(--sans);
font-size: 13px;
color: var(--ink-soft);
max-width: 22ch;
line-height: 1.55;
}
.method-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 50px;
position: relative;
}
.method-grid::before {
content: '';
position: absolute;
top: 60px;
left: 50px;
right: 50px;
height: 1px;
background: var(--line-soft);
}
.method-step { position: relative; }
.method-step .num {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
font-size: 78px;
color: var(--coral);
line-height: 0.85;
margin-bottom: 24px;
letter-spacing: -0.02em;
background: var(--paper);
display: inline-block;
padding-right: 12px;
position: relative;
z-index: 1;
}
.method-step h4 {
font-family: var(--sans);
font-size: 30px;
font-weight: 800;
letter-spacing: -0.022em;
margin-bottom: 18px;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 18px;
}
.method-step h4 .arrow-r {
color: var(--ink-faint);
font-size: 22px;
line-height: 1;
}
.method-step:last-child h4 .arrow-r { display: none; }
.method-step p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 24px;
max-width: 24ch;
}
.method-step .img {
aspect-ratio: 1 / 1;
background: var(--bone);
border-radius: 12px;
overflow: hidden;
box-shadow: var(--shadow);
}
.method-step .img img { width: 100%; height: 100%; object-fit: cover; }
.method-foot {
margin-top: 80px;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px dashed var(--line);
padding-top: 24px;
}
.method-foot .left,
.method-foot .right {
font-family: var(--sans);
font-size: 11px;
color: var(--ink-faint);
letter-spacing: 0.18em;
text-transform: uppercase;
}
.method-foot .left {
display: inline-flex;
align-items: center;
gap: 12px;
}
.method-foot .left .ring {
width: 20px; height: 20px;
border: 1px dashed var(--ink-faint);
border-radius: 50%;
}
.method-foot .right b { color: var(--ink); }
/* ---------- WORK ---------- */
.work {
background: #15140f;
color: var(--paper);
border-radius: 32px;
margin: 0 64px;
overflow: hidden;
position: relative;
padding: 110px 64px;
}
.work::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background-image:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n2'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 0.95 0 0 0 0 0.85 0 0 0 0.05 0'/></filter><rect width='100%' height='100%' filter='url(%23n2)'/></svg>");
background-size: 240px 240px;
opacity: 0.6;
mix-blend-mode: screen;
}
.work-rule {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid rgba(247, 241, 222, 0.16);
padding-top: 16px;
margin-bottom: 60px;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: rgba(247, 241, 222, 0.55);
}
.work-rule .roman { color: var(--coral); font-family: var(--serif); font-style: italic; font-size: 14px; letter-spacing: 0.04em; text-transform: none; }
.work-grid {
display: grid;
grid-template-columns: 1fr 1.05fr 0.85fr;
gap: 48px;
align-items: center;
position: relative;
}
.work .label { color: var(--coral); }
.work .label::before { background: var(--coral); }
.work-copy h2 {
font-family: var(--sans);
font-weight: 800;
font-size: clamp(40px, 5vw, 66px);
line-height: 1.0;
letter-spacing: -0.024em;
margin: 28px 0 36px;
color: var(--paper);
}
.work-copy h2 em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
}
.work-copy h2 .dot { color: var(--coral); }
.work-link {
display: inline-flex;
align-items: center;
gap: 18px;
color: var(--paper);
font-family: var(--sans);
font-size: 14px;
text-decoration: none;
border-bottom: 2px solid var(--coral);
padding-bottom: 12px;
width: fit-content;
}
.work-link::after { content: '↗'; color: var(--coral); }
.work-card {
background: var(--paper);
color: var(--ink);
border-radius: 18px;
padding: 32px 30px;
position: relative;
transform: rotate(-1.2deg);
text-decoration: none;
display: block;
transition: transform 280ms ease, box-shadow 280ms ease;
}
.work-card:hover {
transform: rotate(-1.2deg) translateY(-4px);
box-shadow: var(--shadow);
}
.work-card.alt {
transform: rotate(2.4deg) translateY(20px);
padding: 28px 26px;
}
.work-card.alt:hover {
transform: rotate(2.4deg) translateY(16px);
box-shadow: var(--shadow);
}
.work-card .label-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 22px;
}
.work-card .small-label {
font-family: var(--sans);
font-size: 10.5px;
color: var(--coral);
letter-spacing: 0.18em;
text-transform: uppercase;
font-weight: 600;
}
.work-card .index {
font-family: var(--mono);
font-size: 11px;
color: var(--ink-faint);
letter-spacing: 0.04em;
}
.work-card h3 {
font-family: var(--sans);
font-size: clamp(26px, 2.4vw, 38px);
font-weight: 800;
letter-spacing: -0.022em;
line-height: 1.05;
margin-bottom: 14px;
}
.work-card p {
font-family: var(--body);
font-size: 14px;
color: var(--ink-mute);
line-height: 1.55;
margin-bottom: 22px;
max-width: 28ch;
}
.work-card .img {
aspect-ratio: 4 / 3;
background: var(--bone);
border-radius: 12px;
overflow: hidden;
margin-bottom: 22px;
}
.work-card .img img { width: 100%; height: 100%; object-fit: cover; }
.work-card .meta-row {
display: flex;
justify-content: space-between;
color: var(--ink-faint);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
border-top: 1px solid var(--line);
padding-top: 14px;
}
.work-card .year { color: var(--coral); font-weight: 600; }
.work-arrows {
position: absolute;
right: 64px;
bottom: 64px;
display: inline-flex;
align-items: center;
gap: 10px;
}
.work-arrows .nav-btn {
width: 46px; height: 46px;
border-radius: 50%;
border: 1px solid rgba(247, 241, 222, 0.2);
background: transparent;
color: var(--paper);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.work-arrows .nav-btn.active { background: var(--coral); border-color: var(--coral); }
/* ---------- TESTIMONIAL / COLLABORATORS ---------- */
.testimonial-grid {
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: 80px;
align-items: center;
}
.testimonial-copy h2 {
font-family: var(--sans);
font-size: clamp(36px, 4vw, 54px);
font-weight: 700;
letter-spacing: -0.022em;
line-height: 1.12;
margin-bottom: 36px;
}
.testimonial-copy h2 em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
}
.author {
display: flex;
align-items: center;
gap: 18px;
margin-top: 22px;
}
.author .avatar {
width: 50px; height: 50px;
border-radius: 50%;
background: var(--ink);
overflow: hidden;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--paper);
font-family: var(--serif);
font-style: italic;
font-size: 24px;
}
.author p {
font-family: var(--sans);
font-size: 14px;
color: var(--ink);
font-weight: 600;
}
.author p span {
display: block;
color: var(--ink-mute);
font-weight: 400;
}
.divider {
border-top: 1px solid var(--line);
margin: 60px 0 32px;
}
.partners-text {
font-family: var(--body);
font-size: 14px;
color: var(--ink-mute);
margin-bottom: 26px;
max-width: 38ch;
}
.partners {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 22px;
align-items: end;
}
.partner {
display: flex;
flex-direction: column;
gap: 10px;
text-decoration: none;
color: inherit;
cursor: pointer;
transition: transform 220ms ease;
}
.partner:hover { transform: translateY(-2px); }
.partner:hover .glyph { color: var(--coral); }
.partner:hover span { color: var(--coral); }
.partner .glyph {
height: 32px;
display: flex;
align-items: center;
color: var(--ink);
transition: color 220ms ease;
}
.partner .glyph svg { height: 100%; width: auto; max-width: 90px; }
.partner span {
font-family: var(--sans);
font-size: 13px;
color: var(--ink);
letter-spacing: -0.005em;
font-weight: 600;
transition: color 220ms ease;
}
.partner small {
font-family: var(--sans);
font-size: 10px;
color: var(--ink-faint);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.read-more {
margin-top: 56px;
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--sans);
font-size: 13px;
color: var(--ink);
text-decoration: none;
letter-spacing: 0.04em;
border-bottom: 1px solid var(--coral);
padding-bottom: 6px;
}
.read-more::after { content: '→'; color: var(--coral); }
.testimonial-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 560px;
}
.testimonial-art img { width: 100%; height: 100%; object-fit: contain; }
/* ---------- AMR band ---------- */
.amr-band {
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
overflow: hidden;
}
.amr-band-inner {
max-width: 860px;
margin: 0 auto;
padding: 18px 0 0;
text-align: center;
}
.amr-band-kicker {
display: inline-block;
font-family: var(--sans);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-faint);
}
.amr-band-title {
font-family: var(--sans);
font-size: clamp(30px, 5vw, 52px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.08;
margin: 16px auto 0;
max-width: 720px;
color: var(--ink);
}
.amr-band-lead {
font-family: var(--sans);
font-size: 15px;
line-height: 1.6;
color: var(--ink-mute);
margin: 16px auto 0;
max-width: 620px;
}
.amr-band-chips {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 10px;
list-style: none;
margin: 24px 0 0;
padding: 0;
}
.amr-band-chip {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 7px 16px 7px 13px;
border: 1px solid var(--line);
border-radius: 999px;
font-family: var(--sans);
font-size: 13px;
font-weight: 500;
color: var(--ink-soft);
background: color-mix(in srgb, var(--paper) 60%, transparent);
}
.amr-band-chip-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent, var(--ink-soft));
flex: none;
}
.amr-band-logos {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 28px;
list-style: none;
margin: 30px 0 0;
padding: 0;
}
.amr-band-logos li {
display: inline-flex;
align-items: center;
}
.amr-band-logo {
/* <img>-loaded SVGs can't inherit page color; they paint in their own
default ink (near-black). Opacity softens the row. */
width: 26px;
height: 26px;
display: block;
opacity: 0.74;
transition: opacity 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.amr-band-logos li:hover .amr-band-logo {
opacity: 1;
}
.amr-band-more {
font-family: var(--sans);
font-size: 26px;
font-weight: 600;
line-height: 1;
letter-spacing: 0.05em;
color: var(--ink-faint);
transform: translateY(-4px);
}
.amr-band-actions {
display: flex;
justify-content: center;
margin-top: 30px;
}
.amr-band-cta {
/* Reuse the dark .nav-cta pill; add the trailing arrow the nav CTAs use. */
padding: 11px 22px;
font-size: 14px;
}
.amr-band-cta::after {
content: '→';
color: var(--paper);
font-size: 13px;
margin-left: 7px;
}
/* ---------- CTA ---------- */
.cta-grid {
display: grid;
grid-template-columns: 1.05fr 1fr;
gap: 50px;
align-items: center;
}
.cta h2 {
font-size: clamp(54px, 6.6vw, 100px);
margin: 32px 0 32px;
}
.cta .lead { margin-bottom: 36px; max-width: 36ch; font-size: 16px; }
.cta-actions {
display: inline-flex;
align-items: center;
gap: 14px;
margin-bottom: 32px;
}
.email-pill {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 14px 18px 14px 22px;
border-radius: 999px;
border: 1px solid var(--line);
font-family: var(--sans);
font-size: 14px;
color: var(--ink);
text-decoration: none;
}
.email-pill .arrow-circle {
width: 22px; height: 22px;
border-radius: 50%;
background: var(--ink);
color: var(--paper);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.cta-foot {
display: flex;
gap: 28px;
align-items: center;
margin-top: 32px;
padding-top: 22px;
border-top: 1px solid var(--line);
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-faint);
}
.cta-foot .stamp { color: var(--coral); font-weight: 600; }
.cta-art {
position: relative;
aspect-ratio: 1 / 1;
max-width: 620px;
margin-left: auto;
}
.cta-art img { width: 100%; height: 100%; object-fit: contain; }
.cta-art .index {
position: absolute;
right: 8px;
top: 24px;
font-family: var(--serif);
font-style: italic;
font-size: 28px;
color: var(--ink-faint);
}
.cta-art .ribbon {
position: absolute;
left: -32px;
top: 50%;
font-family: var(--sans);
font-size: 10.5px;
letter-spacing: 0.42em;
text-transform: uppercase;
color: var(--ink-faint);
writing-mode: vertical-rl;
transform: rotate(180deg);
}
/* ---------- FOOTER ---------- */
footer {
border-top: 1px solid var(--line);
padding: 60px 0 30px;
margin-top: 60px;
}
.foot-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
gap: 40px;
margin-bottom: 60px;
}
.foot-brand .brand { margin-bottom: 18px; }
.foot-brand p {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-mute);
line-height: 1.55;
max-width: 38ch;
}
.foot-brand p .inline-link,
.inline-link {
color: var(--ink);
text-decoration: none;
border-bottom: 1px solid var(--line);
transition: color 160ms ease, border-color 160ms ease;
}
.inline-link:hover {
color: var(--coral);
border-bottom-color: var(--coral);
}
.method-repo-link {
color: inherit;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: color 160ms ease, border-color 160ms ease;
}
.method-repo-link:hover {
color: var(--coral);
border-bottom-color: var(--coral);
}
.library-link {
text-decoration: none;
border-bottom: 1px solid transparent;
transition: border-color 160ms ease;
}
.library-link:hover { border-bottom-color: var(--coral); }
.foot-col h5 {
font-family: var(--sans);
font-size: 11px;
color: var(--ink);
letter-spacing: 0.18em;
text-transform: uppercase;
margin-bottom: 18px;
font-weight: 700;
}
.foot-col ul { list-style: none; }
.foot-col li { margin-bottom: 10px; }
.foot-col a {
font-family: var(--body);
font-size: 13.5px;
color: var(--ink-soft);
text-decoration: none;
}
.foot-col a:hover { color: var(--coral); }
.foot-bottom {
border-top: 1px solid var(--line);
padding-top: 22px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: var(--sans);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--ink-faint);
}
.foot-bottom .right { display: inline-flex; gap: 24px; align-items: center; }
.foot-bottom .pulse {
width: 6px; height: 6px;
border-radius: 50%;
background: var(--coral);
display: inline-block;
margin-right: 6px;
vertical-align: middle;
}
.foot-mega {
margin-top: 60px;
padding-top: 0;
padding-bottom: 12px;
border-top: 1px solid var(--line);
overflow-x: hidden;
overflow-y: visible;
}
.foot-mega .word {
font-family: var(--sans);
font-weight: 900;
font-size: clamp(70px, 13vw, 200px);
letter-spacing: -0.04em;
line-height: 1.05;
color: var(--ink);
white-space: nowrap;
margin-top: 30px;
padding-bottom: 0.18em;
}
.foot-mega .word em {
font-family: var(--serif);
font-style: italic;
font-weight: 500;
color: var(--coral);
}
/* ---------- scroll-reveal motion ----------
*
* Content is visible by default. Once the observer is successfully bound,
* `.reveal-ready` opts unrevealed elements into the hidden start state. If
* JavaScript is disabled or setup fails, the complete page remains visible.
*
* Uses `translate` / `scale` longhand properties (not `transform`) so
* that elements like `.work-card` keep their static `transform: rotate()`
* intact while still translating in.
*/
[data-reveal] {
opacity: 1;
translate: 0 0;
scale: 1;
transition:
opacity 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms),
translate 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms),
scale 900ms cubic-bezier(0.22, 1, 0.36, 1) var(--reveal-delay, 0ms);
will-change: auto;
}
.reveal-ready [data-reveal]:not([data-revealed='true']) {
opacity: 0;
translate: 0 28px;
will-change: opacity, translate, scale;
}
.reveal-ready [data-reveal='left']:not([data-revealed='true']) { translate: -36px 0; }
.reveal-ready [data-reveal='right']:not([data-revealed='true']) { translate: 36px 0; }
.reveal-ready [data-reveal='scale']:not([data-revealed='true']) { translate: 0 0; scale: 0.96; }
.reveal-ready [data-reveal='rise-lg']:not([data-revealed='true']) { translate: 0 64px; scale: 0.985; }
[data-reveal][data-revealed='true'] {
opacity: 1;
translate: 0 0;
scale: 1;
}
/* stagger primitives — set --reveal-delay on grid children so siblings
* appear in sequence rather than all at once. */
.cards > .card[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.cards > .card[data-reveal]:nth-child(2) { --reveal-delay: 90ms; }
.cards > .card[data-reveal]:nth-child(3) { --reveal-delay: 180ms; }
.cards > .card[data-reveal]:nth-child(4) { --reveal-delay: 270ms; }
.labs-grid > .lab[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.labs-grid > .lab[data-reveal]:nth-child(2) { --reveal-delay: 90ms; }
.labs-grid > .lab[data-reveal]:nth-child(3) { --reveal-delay: 180ms; }
.labs-grid > .lab[data-reveal]:nth-child(4) { --reveal-delay: 270ms; }
.labs-grid > .lab[data-reveal]:nth-child(5) { --reveal-delay: 360ms; }
.method-grid > .method-step[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.method-grid > .method-step[data-reveal]:nth-child(2) { --reveal-delay: 110ms; }
.method-grid > .method-step[data-reveal]:nth-child(3) { --reveal-delay: 220ms; }
.method-grid > .method-step[data-reveal]:nth-child(4) { --reveal-delay: 330ms; }
.partners > .partner[data-reveal]:nth-child(1) { --reveal-delay: 0ms; }
.partners > .partner[data-reveal]:nth-child(2) { --reveal-delay: 70ms; }
.partners > .partner[data-reveal]:nth-child(3) { --reveal-delay: 140ms; }
.partners > .partner[data-reveal]:nth-child(4) { --reveal-delay: 210ms; }
.partners > .partner[data-reveal]:nth-child(5) { --reveal-delay: 280ms; }
.partners > .partner[data-reveal]:nth-child(6) { --reveal-delay: 350ms; }
/* hero copy — let label, headline, lead, actions, stats arrive in sequence
* so the headline isn't waiting on a single block-level reveal. */
.hero-copy > [data-reveal]:nth-of-type(1) { --reveal-delay: 0ms; }
.hero-copy > [data-reveal]:nth-of-type(2) { --reveal-delay: 80ms; }
.hero-copy > [data-reveal]:nth-of-type(3) { --reveal-delay: 160ms; }
.hero-copy > [data-reveal]:nth-of-type(4) { --reveal-delay: 240ms; }
.hero-copy > [data-reveal]:nth-of-type(5) { --reveal-delay: 320ms; }
.hero-copy > [data-reveal]:nth-of-type(6) { --reveal-delay: 400ms; }
@media (prefers-reduced-motion: reduce) {
[data-reveal] {
opacity: 1 !important;
translate: 0 0 !important;
scale: 1 !important;
transition: none !important;
}
/* Skip the slide-in on the sticky header for users who prefer no motion;
* the show/hide still toggles, just instantly. */
.nav { transition: none !important; }
}
/* responsive */
@media (max-width: 1280px) {
.container { padding: 0 44px; }
.work { margin: 0 44px; padding: 90px 44px; }
.side-rail { display: none; }
}
/* hide topbar mid text early — between 1200 and 1280 it crowds even with nowrap */
@media (max-width: 1200px) {
.topbar-inner .mid { display: none; }
}
/* nav: between 1080 and 1180 the brand tail + 5 nav links + 2 CTAs + dot
* crowd the row. Drop the brand sub-meta first, then tighten link spacing,
* so the Star CTA never has to compress. */
/* nav: tighten the simplified static nav (this template has no hamburger /
* dropdown machinery — the app Header carries that). Matches the app's
* desktop-tighten band that ends at the ≤1280px hamburger breakpoint. */
@media (max-width: 1280px) {
.nav-inner { gap: 18px; }
.brand-meta { display: none; }
.nav-links { gap: 28px; }
}
@media (max-width: 1080px) {
.container { padding: 0 32px; }
.hero h1 { font-size: clamp(36px, 4.6vw, 54px); }
.section-header h2 { font-size: clamp(32px, 4vw, 50px); }
.labs-grid { grid-template-columns: repeat(5, 1fr); gap: 14px; }
.partners { grid-template-columns: repeat(3, 1fr); gap: 18px; row-gap: 28px; }
.foot-grid { grid-template-columns: 2fr 1fr 1fr; }
.foot-grid .foot-col:nth-child(4),
.foot-grid .foot-col:nth-child(5) { display: none; }
}
@media (max-width: 880px) {
.container { padding: 0 24px; }
.hero-grid, .about-grid, .capabilities-grid, .testimonial-grid, .cta-grid {
grid-template-columns: 1fr;
gap: 50px;
}
.labs-head, .method-head { grid-template-columns: 1fr; }
.labs-grid { grid-template-columns: repeat(2, 1fr); }
.method-grid { grid-template-columns: repeat(2, 1fr); gap: 36px; }
.method-grid::before { display: none; }
.work { margin: 0 12px; padding: 60px 24px; }
.work-grid { grid-template-columns: 1fr; }
.partners { grid-template-columns: repeat(3, 1fr); gap: 18px; }
.nav-links, .brand-meta, .nav-cta { display: none; }
/* wire — stack the field label above the marquee rows */
.wire-inner { grid-template-columns: 1fr; gap: 14px; }
.wire-left {
border-right: none;
border-bottom: 1px solid var(--line);
padding-right: 0;
padding-bottom: 12px;
min-height: 0;
}
}
@media (max-width: 560px) {
.container { padding: 0 16px; }
.hero h1 { font-size: 38px; }
.labs-grid { grid-template-columns: 1fr; }
.cards { grid-template-columns: 1fr; }
.pills { justify-content: flex-start; }
section { padding: 80px 0; }
.topbar-inner { font-size: 9px; }
}
.code-inline {
font-family: var(--mono);
font-size: 14px;
background: var(--bone);
padding: 1px 6px;
border-radius: 4px;
}
.code-inline.sm { font-size: 12px; padding: 0 4px; }
/* ====== NEWSLETTER ====== */
.newsletter {
padding: 80px 0;
border-top: 1px solid var(--ink);
}
.newsletter-card {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
gap: 48px;
align-items: center;
}
.newsletter-title {
font-family: var(--serif);
font-size: clamp(28px, 4vw, 44px);
line-height: 1.05;
margin: 12px 0 14px;
color: var(--ink);
}
.newsletter-form {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.newsletter-input {
flex: 1 1 220px;
min-width: 0;
padding: 14px 16px;
font-family: var(--body);
font-size: 15px;
color: var(--ink);
background: var(--paper-warm);
border: 1px solid var(--ink);
border-radius: 2px;
}
.newsletter-input:focus-visible {
outline: 2px solid var(--coral);
outline-offset: 1px;
}
.newsletter-submit {
flex: 0 0 auto;
}
.newsletter-submit:disabled {
opacity: 0.55;
cursor: progress;
}
.newsletter-msg {
flex: 1 0 100%;
margin: 4px 0 0;
min-height: 1.2em;
font-size: 13px;
color: var(--ink-mute);
}
.newsletter-form.is-success .newsletter-input,
.newsletter-form.is-success .newsletter-submit {
display: none;
}
.newsletter-form.is-success .newsletter-msg {
color: var(--ink);
font-weight: 600;
}
/* Bottom-right popup */
.newsletter-popup {
position: fixed;
right: 24px;
bottom: 24px;
z-index: 90;
width: min(360px, calc(100vw - 48px));
padding: 22px 22px 20px;
background: var(--paper);
border: 1px solid var(--ink);
border-radius: 4px;
box-shadow: 0 18px 48px rgba(21, 20, 15, 0.22);
opacity: 0;
transform: translateY(12px);
transition: opacity 0.28s ease, transform 0.28s ease;
}
.newsletter-popup.is-visible {
opacity: 1;
transform: translateY(0);
}
.newsletter-popup__title {
font-family: var(--serif);
font-size: 22px;
line-height: 1.1;
margin: 10px 0 8px;
color: var(--ink);
}
.newsletter-popup__lead {
font-size: 13.5px;
line-height: 1.5;
color: var(--ink-mute);
margin: 0 0 14px;
}
.newsletter-popup__close {
position: absolute;
top: 8px;
right: 10px;
width: 28px;
height: 28px;
font-size: 22px;
line-height: 1;
color: var(--ink-faint);
background: transparent;
border: 0;
cursor: pointer;
}
.newsletter-popup__close:hover {
color: var(--ink);
}
.newsletter-popup .newsletter-input {
flex: 1 1 100%;
}
.newsletter-popup .newsletter-submit {
flex: 1 1 100%;
justify-content: center;
}
@media (prefers-reduced-motion: reduce) {
.newsletter-popup {
transition: none;
}
}
@media (max-width: 860px) {
.newsletter-card {
grid-template-columns: 1fr;
gap: 24px;
}
}
</style>
</head>
<body>
<div class='side-rail right' data-od-id='rail-right'>
<span class='rail-text'>OpenDesign — Vol. 01 · Issue Nº 26 · Apache-2.0</span>
</div>
<div class='side-rail left' data-od-id='rail-left'>
<span class='rail-text'>Skills · Systems · Agents · BYOK · Local-first</span>
</div>
<div class='shell'>
<div class='topbar' data-od-id='topbar'>
<div class='container topbar-inner'>
<span><b>OD / 2026</b> &nbsp;·&nbsp; Vol. 01 / Issue Nº 26</span>
<span class='mid'>
<span>Filed under <b class='coral'>Design · Intelligence</b></span>
<span>Apache-2.0 · Made on Earth</span>
</span>
<span class='right'>
<a class='topbar-link' href='https://github.com/nexu-io/open-design/releases' target='_blank' rel='noreferrer noopener'><span class='pulse'></span>Live · v0.3.0</a>
<span><b>EN</b> · DE · 中文 · 日本語</span>
</span>
</div>
</div>
<header class='nav' data-od-id='nav'>
<div class='container nav-inner'>
<a href='#top' class='brand'>
<span class='brand-mark'>Ø</span>
<span>OpenDesign</span>
<span class='brand-meta'><b>Studio Nº 01</b>Berlin / Open / Earth</span>
</a>
<nav>
<ul class='nav-links'>
<li><a href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener'>Skills<span class='num'>31</span></a></li>
<li><a href='https://github.com/nexu-io/open-design/tree/main/design-systems' target='_blank' rel='noreferrer noopener'>Systems<span class='num'>72</span></a></li>
<li><a href='#agents'>Agents<span class='num'>12</span></a></li>
<li><a href='#labs'>Labs<span class='num'>05</span></a></li>
<li><a href='#contact'>Contact</a></li>
</ul>
</nav>
<div class='nav-side'>
<a class='nav-cta ghost' href='https://github.com/nexu-io/open-design/releases' target='_blank' rel='noreferrer noopener'>Download</a>
<a class='nav-cta' href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'>Star · 0K</a>
<span class='status-dot' aria-hidden='true'></span>
</div>
</div>
</header>
<section class='hero' id='top' data-od-id='hero'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>I.</span>
<span class='meta-grp'>
<span>Hero / Cover Plate</span>
<span class='dot-mark'>•</span>
<span>OpenDesign / Volume 01</span>
</span>
<span>001 / 008</span>
</div>
</div>
<div class='container hero-grid'>
<div class='hero-copy'>
<span class='label' data-reveal>Open-source design studio <span class='ix'>· Nº 01</span></span>
<h1 class='display' data-reveal>Designing <em>intelligence</em> with skills, <em>taste,</em> and <em>code</em><span class='dot'>.</span></h1>
<p class='lead' data-reveal>The open-source alternative to Anthropic&rsquo;s Claude Design. 12 coding agents — Claude, Codex, Cursor, Gemini and friends — drive 31 composable skills and 72 brand-grade design systems. Generate web pages, slide decks, mobile prototypes, images, even short videos — all running on your own laptop.</p>
<div class='hero-actions' data-reveal>
<a class='btn btn-primary' href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'>
Star us on GitHub
<span class='arrow'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></span>
</a>
<a class='btn btn-ghost' href='https://github.com/nexu-io/open-design/releases' target='_blank' rel='noreferrer noopener'>
Download desktop
<span class='arrow'><svg viewBox='0 0 24 24'><circle cx='12' cy='12' r='9'/><path d='M9 12h6M12 9v6'/></svg></span>
</a>
</div>
<div class='hero-stats' data-reveal>
<div class='stat'>
<span class='ring solid'>31</span>
<span class='stat-label'><b>skills</b>shippable</span>
</div>
<div class='stat'>
<span class='ring'>72</span>
<span class='stat-label'><b>systems</b>portable</span>
</div>
<div class='stat'>
<span class='ring coral'>12</span>
<span class='stat-label'><b>CLIs</b>BYO agent</span>
</div>
</div>
<div class='hero-foot' data-reveal>
<span class='meta'>↳ &nbsp; pnpm tools-dev &nbsp; · &nbsp; 3 commands to start</span>
<span class='coord'>52.5200° N · 13.4050° E</span>
</div>
</div>
<div class='hero-art' data-reveal='scale'>
<span class='corner tl'></span>
<span class='corner tr'></span>
<span class='corner bl'></span>
<span class='corner br'></span>
<span class='annot annot-tl coord'>FIG. 01 / OD-26</span>
<span class='annot annot-tr'>Plate Nº 08</span>
<span class='annot annot-bl coord'>SHA · a1b2c3d</span>
<span class='annot annot-br'>Composed in&nbsp;<span style='color:var(--coral);'>OpenDesign</span></span>
<img src='./assets/hero.png' alt='' />
<div class='index'>
<span><span class='n'>01</span>Detect</span>
<span class='on'><span class='n'>02</span>Discover</span>
<span><span class='n'>03</span>Direct</span>
<span><span class='n'>04</span>Deliver</span>
</div>
</div>
</div>
</section>
<section class='wire' data-od-id='wire' aria-label='Global wire — cities and contributors'>
<div class='container wire-inner'>
<div class='wire-left'>
<span class='wire-mark' aria-hidden='true'><span class='wire-pulse'></span></span>
<span class='wire-title'>
<b>From the field</b>
<span>Open · 23 cities · 6 contributors</span>
</span>
</div>
<div class='wire-rows'>
<div class='wire-row'>
<div class='marquee-track' aria-hidden='true'>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>52.52°N</span><span class='wire-name'>Berlin</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>35.68°N</span><span class='wire-name'>Tokyo</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>31.23°N</span><span class='wire-name'>Shanghai</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>39.90°N</span><span class='wire-name'>Beijing</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>25.03°N</span><span class='wire-name'>Taipei</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>1.35°N</span><span class='wire-name'>Singapore</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>12.97°N</span><span class='wire-name'>Bangalore</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>25.20°N</span><span class='wire-name'>Dubai</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>6.52°N</span><span class='wire-name'>Lagos</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>1.29°S</span><span class='wire-name'>Nairobi</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>33.92°S</span><span class='wire-name'>Cape Town</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>38.72°N</span><span class='wire-name'>Lisbon</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>40.42°N</span><span class='wire-name'>Madrid</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>48.86°N</span><span class='wire-name'>Paris</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>51.51°N</span><span class='wire-name'>London</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>52.37°N</span><span class='wire-name'>Amsterdam</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>59.33°N</span><span class='wire-name'>Stockholm</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>43.65°N</span><span class='wire-name'>Toronto</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>40.71°N</span><span class='wire-name'>New York</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>37.77°N</span><span class='wire-name'>San Francisco</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>19.43°N</span><span class='wire-name'>Mexico City</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>23.55°S</span><span class='wire-name'>São Paulo</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>33.87°S</span><span class='wire-name'>Sydney</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>52.52°N</span><span class='wire-name'>Berlin</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>35.68°N</span><span class='wire-name'>Tokyo</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>31.23°N</span><span class='wire-name'>Shanghai</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>39.90°N</span><span class='wire-name'>Beijing</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>25.03°N</span><span class='wire-name'>Taipei</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>1.35°N</span><span class='wire-name'>Singapore</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>12.97°N</span><span class='wire-name'>Bangalore</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>25.20°N</span><span class='wire-name'>Dubai</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>6.52°N</span><span class='wire-name'>Lagos</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>1.29°S</span><span class='wire-name'>Nairobi</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>33.92°S</span><span class='wire-name'>Cape Town</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>38.72°N</span><span class='wire-name'>Lisbon</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>40.42°N</span><span class='wire-name'>Madrid</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>48.86°N</span><span class='wire-name'>Paris</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>51.51°N</span><span class='wire-name'>London</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>52.37°N</span><span class='wire-name'>Amsterdam</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>59.33°N</span><span class='wire-name'>Stockholm</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>43.65°N</span><span class='wire-name'>Toronto</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>40.71°N</span><span class='wire-name'>New York</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>37.77°N</span><span class='wire-name'>San Francisco</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>19.43°N</span><span class='wire-name'>Mexico City</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>23.55°S</span><span class='wire-name'>São Paulo</span></span>
<span class='wire-item'><span class='wire-dot'>·</span><span class='wire-coord'>33.87°S</span><span class='wire-name'>Sydney</span></span>
</div>
</div>
<div class='wire-row reverse'>
<div class='marquee-track'>
<a class='wire-item is-link' href='https://github.com/tw93' target='_blank' rel='noreferrer noopener' aria-label='Open tw93 on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@tw93</span><span class='wire-role'>kami</span></a>
<a class='wire-item is-link' href='https://github.com/op7418' target='_blank' rel='noreferrer noopener' aria-label='Open op7418 on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@op7418</span><span class='wire-role'>guizang</span></a>
<a class='wire-item is-link' href='https://github.com/alchaincyf' target='_blank' rel='noreferrer noopener' aria-label='Open alchaincyf on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@alchaincyf</span><span class='wire-role'>huashu</span></a>
<a class='wire-item is-link' href='https://github.com/multica-ai' target='_blank' rel='noreferrer noopener' aria-label='Open multica-ai on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@multica-ai</span><span class='wire-role'>daemon</span></a>
<a class='wire-item is-link' href='https://github.com/OpenCoworkAI' target='_blank' rel='noreferrer noopener' aria-label='Open OpenCoworkAI on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@OpenCoworkAI</span><span class='wire-role'>codesign</span></a>
<a class='wire-item is-link' href='https://github.com/nexu-io' target='_blank' rel='noreferrer noopener' aria-label='Open nexu-io on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@nexu-io</span><span class='wire-role'>studio</span></a>
<a class='wire-item is-link' href='https://github.com/nexu-io/open-design/graphs/contributors' target='_blank' rel='noreferrer noopener' aria-label='Open you on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@you</span><span class='wire-role'>be next</span></a>
<a class='wire-item is-link' href='https://github.com/tw93' target='_blank' rel='noreferrer noopener' aria-label='Open tw93 on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@tw93</span><span class='wire-role'>kami</span></a>
<a class='wire-item is-link' href='https://github.com/op7418' target='_blank' rel='noreferrer noopener' aria-label='Open op7418 on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@op7418</span><span class='wire-role'>guizang</span></a>
<a class='wire-item is-link' href='https://github.com/alchaincyf' target='_blank' rel='noreferrer noopener' aria-label='Open alchaincyf on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@alchaincyf</span><span class='wire-role'>huashu</span></a>
<a class='wire-item is-link' href='https://github.com/multica-ai' target='_blank' rel='noreferrer noopener' aria-label='Open multica-ai on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@multica-ai</span><span class='wire-role'>daemon</span></a>
<a class='wire-item is-link' href='https://github.com/OpenCoworkAI' target='_blank' rel='noreferrer noopener' aria-label='Open OpenCoworkAI on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@OpenCoworkAI</span><span class='wire-role'>codesign</span></a>
<a class='wire-item is-link' href='https://github.com/nexu-io' target='_blank' rel='noreferrer noopener' aria-label='Open nexu-io on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@nexu-io</span><span class='wire-role'>studio</span></a>
<a class='wire-item is-link' href='https://github.com/nexu-io/open-design/graphs/contributors' target='_blank' rel='noreferrer noopener' aria-label='Open you on GitHub'><span class='wire-dot'>·</span><span class='wire-handle'>@you</span><span class='wire-role'>be next</span></a>
</div>
</div>
</div>
</div>
</section>
<section class='about' data-od-id='about'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>II.</span>
<span class='meta-grp'>
<span>About / Manifesto</span>
<span class='dot-mark'>•</span>
<span>OpenDesign / Volume 01</span>
</span>
<span>002 / 008</span>
</div>
<div class='about-grid'>
<div class='about-copy' data-reveal>
<span class='label'>About the studio <span class='ix'>· Nº 02</span></span>
<h2 class='display'>We treat <em>your agent</em> as a creative <em>collaborator,</em> not a black box<span class='dot'>.</span></h2>
<p class='lead'>The strongest coding agents already live on your laptop. We don't ship one — we wire them into a skill-driven design workflow that runs locally with <code class='code-inline'>pnpm tools-dev</code>, deploys the web layer to Vercel, and stays BYOK at every layer.</p>
<a class='btn btn-ghost' href='https://github.com/nexu-io/open-design/tree/main/apps/daemon' target='_blank' rel='noreferrer noopener'>
Read our approach
<span class='arrow'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></span>
</a>
<div class='footer-row'>
<span class='mark'>Ø</span>
<span>Research · Design · Engineering · Repeat</span>
<span class='stamp'>
<span>Studio practice</span>
<span style='color: var(--ink);'>Est. MMXXVI</span>
</span>
</div>
</div>
<div class='about-art' data-reveal='right'>
<img src='./assets/about.png' alt='' />
<div class='about-side-note'>
<b></b>
From model behavior<br/>to visual taste, we<br/>prototype the full<br/>stack of creative<br/>systems.
</div>
<div class='about-caption'>
<b>Studies in form · perception · machine imagination.</b>
(OpenDesign, MMXXVI)
</div>
</div>
</div>
</div>
</section>
<section class='capabilities' id='agents' data-od-id='capabilities'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>III.</span>
<span class='meta-grp'>
<span>Capabilities · Skills · Systems</span>
<span class='dot-mark'>•</span>
<span>4 surfaces / 1 loop</span>
</span>
<span>003 / 008</span>
</div>
<div class='capabilities-grid'>
<div class='capabilities-art' data-reveal='left'>
<span class='corner tl'></span>
<span class='corner br'></span>
<img src='./assets/capabilities.png' alt='' />
<div class='ribbon'><b>OPENDESIGN</b> &nbsp;·&nbsp; CAPABILITIES MATRIX &nbsp;·&nbsp; OD/26</div>
</div>
<div class='capabilities-copy' data-reveal>
<span class='label'>Capabilities <span class='ix'>· Nº 03</span></span>
<h2 class='display'>Skills, systems, and surfaces <em>for creative</em> intelligence<span class='dot'>.</span></h2>
<p class='lead'>We blend human taste with whichever agent you already trust to ship interfaces, decks, and editorial pages that feel intentional, expressive, and alive.</p>
<div class='cards'>
<div class='card' data-reveal>
<div class='num'>01<span class='tag'>Skills</span></div>
<svg class='icon' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5'>
<circle cx='9' cy='9' r='5'/><path d='M14 14l5 5'/>
</svg>
<h3>Skills,<br/>not plugins</h3>
<p>31 file-based <code class='code-inline sm'>SKILL.md</code> bundles. Drop a folder in, restart the daemon, it appears.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener' aria-label='Learn more about Skills'>
<svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg>
</a>
</div>
<div class='card' data-reveal>
<div class='num'>02<span class='tag'>Systems</span></div>
<svg class='icon' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5'>
<rect x='3.5' y='3.5' width='8' height='8'/><rect x='12.5' y='3.5' width='8' height='8'/><rect x='3.5' y='12.5' width='8' height='8'/><rect x='12.5' y='12.5' width='8' height='8'/>
</svg>
<h3>Design Systems<br/>as Markdown</h3>
<p>72 portable <code class='code-inline sm'>DESIGN.md</code> systems — Linear, Vercel, Stripe, Apple, Cursor, Figma…</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/design-systems' target='_blank' rel='noreferrer noopener' aria-label='Learn more about Systems'>
<svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg>
</a>
</div>
<div class='card' data-reveal>
<div class='num'>03<span class='tag'>Adapters</span></div>
<svg class='icon' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5'>
<circle cx='8' cy='12' r='4.5'/><circle cx='16' cy='12' r='4.5'/>
</svg>
<h3>12 Agent<br/>Adapters</h3>
<p>Claude · Codex · Gemini · Cursor · Copilot · OpenCode · Devin · Hermes · Pi · Kimi · Kiro · Qwen — auto-detected on $PATH.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/apps/daemon' target='_blank' rel='noreferrer noopener' aria-label='Learn more about Adapters'>
<svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg>
</a>
</div>
<div class='card' data-reveal>
<div class='num'>04<span class='tag'>BYOK</span></div>
<svg class='icon' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5'>
<path d='M5 8h14v8H5z'/><path d='M9 12h6M12 9v6'/>
</svg>
<h3>BYOK<br/>at every layer</h3>
<p>OpenAI-compatible proxy. DeepSeek, Groq, OpenRouter, your self-hosted vLLM — paste a baseUrl + key, ship.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener' aria-label='Learn more about BYOK'>
<svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg>
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<section class='labs' id='labs' data-od-id='labs'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>IV.</span>
<span class='meta-grp'>
<span>Labs / Skills Catalog</span>
<span class='dot-mark'>•</span>
<span>05 of 31 ongoing</span>
</span>
<span>004 / 008</span>
</div>
<div class='labs-head'>
<div data-reveal>
<span class='label'>Labs <span class='ix'>· Nº 04</span></span>
<h2 class='display' style='margin-top:30px;'>A living archive of <em>experiments</em> in skills, decks, and machine-made form<span class='dot'>.</span></h2>
</div>
<div class='pills' data-reveal='right'>
<button class='pill active'>All<span class='count'>31</span></button>
<button class='pill'>Prototype<span class='count'>27</span></button>
<button class='pill'>Deck<span class='count'>04</span></button>
<button class='pill'>Mobile<span class='count'>03</span></button>
<button class='pill'>Office<span class='count'>08</span></button>
</div>
</div>
<div class='labs-meta'>
<span class='ring'>05</span>
<div class='meta-text'>
<b>Ongoing experiments</b>
documenting ideas in flux<br/>building intelligence<br/>through making
</div>
</div>
<div class='labs-grid'>
<div class='lab' data-reveal>
<div class='lab-img'><span class='badge'>Deck</span><img src='./assets/lab-1.png' alt='' /></div>
<div class='num-row'><span>Nº 01</span><span>2026</span></div>
<h4>Magazine Decks</h4>
<p>Editorial-grade slide decks with <code class='code-inline sm'>guizang-ppt</code>. Magazine layout, WebGL hero.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/skills/guizang-ppt' target='_blank' rel='noreferrer noopener' aria-label='Open Magazine Decks'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></a>
</div>
<div class='lab' data-reveal>
<div class='lab-img'><span class='badge'>Media</span><img src='./assets/lab-2.png' alt='' /></div>
<div class='num-row'><span>Nº 02</span><span>2026</span></div>
<h4>Synthetic Matter</h4>
<p>Gpt-image-2 + Seedance + HyperFrames. Image, video, audio — same chat surface as code.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/skills/hyperframes' target='_blank' rel='noreferrer noopener' aria-label='Open Synthetic Matter'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></a>
</div>
<div class='lab' data-reveal>
<div class='lab-img'><span class='badge'>Loop</span><img src='./assets/lab-3.png' alt='' /></div>
<div class='num-row'><span>Nº 03</span><span>2026</span></div>
<h4>Prompt Choreography</h4>
<p>When unresolved choices would materially change the result, a focused question form keeps the next iteration on track.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/skills/design-brief' target='_blank' rel='noreferrer noopener' aria-label='Open Prompt Choreography'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></a>
</div>
<div class='lab' data-reveal>
<div class='lab-img'><span class='badge'>Critique</span><img src='./assets/lab-4.png' alt='' /></div>
<div class='num-row'><span>Nº 04</span><span>2026</span></div>
<h4>Visual Reasoning</h4>
<p>5-dim self-critique gates every artifact: philosophy · hierarchy · execution · specificity · restraint.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/skills/critique' target='_blank' rel='noreferrer noopener' aria-label='Open Visual Reasoning'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></a>
</div>
<div class='lab' data-reveal>
<div class='lab-img'><span class='badge'>Runtime</span><img src='./assets/lab-5.png' alt='' /></div>
<div class='num-row'><span>Nº 05</span><span>2026</span></div>
<h4>Soft Systems</h4>
<p>Sandboxed iframe preview. Streaming todos. Real-cwd filesystem. Adaptive loops between human and machine.</p>
<a class='arrow-mark' href='https://github.com/nexu-io/open-design/tree/main/apps/daemon' target='_blank' rel='noreferrer noopener' aria-label='Open Soft Systems'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></a>
</div>
</div>
<div class='labs-foot'>
<div class='progress'>
<span class='on'></span><span class='on'></span><span class='on'></span><span class='on'></span><span class='on'></span><span></span><span></span><span></span>
</div>
<span class='meta'>05 / 31 SKILLS &nbsp;·&nbsp; <a class='library-link' href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener' style='color:var(--coral);'>VIEW FULL LIBRARY →</a></span>
</div>
</div>
</section>
<section class='method' data-od-id='method'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>V.</span>
<span class='meta-grp'>
<span>Method / Loop</span>
<span class='dot-mark'>•</span>
<span>04 stages, iterative</span>
</span>
<span>005 / 008</span>
</div>
<div class='method-head'>
<div data-reveal>
<span class='label'>Method <span class='ix'>· Nº 05</span></span>
<h2 class='display' style='margin-top:30px;'>From <em>signals</em> to systems<span class='dot'>.</span></h2>
</div>
<div class='right' data-reveal='right'>
<span class='plus'>+</span>
<p>Every stage is iterative, visual, and research-driven — composable files, not opaque prompts.</p>
</div>
</div>
<div class='method-grid'>
<div class='method-step' data-reveal>
<div class='num'>01</div>
<h4>Detect <span class='arrow-r'>→</span></h4>
<p>The daemon scans your $PATH for 12 coding agents and auto-loads 31 skills + 72 systems on boot.</p>
<div class='img'><img src='./assets/method-1.png' alt='' /></div>
</div>
<div class='method-step' data-reveal>
<div class='num'>02</div>
<h4>Discover <span class='arrow-r'>→</span></h4>
<p>Clarify only when it matters — focused questions for unresolved surface, audience, tone, scale, or brand context.</p>
<div class='img'><img src='./assets/method-2.png' alt='' /></div>
</div>
<div class='method-step' data-reveal>
<div class='num'>03</div>
<h4>Direct <span class='arrow-r'>→</span></h4>
<p>Pick one of 5 deterministic visual directions. Palette in OKLch, font stack, layout posture cues.</p>
<div class='img'><img src='./assets/method-3.png' alt='' /></div>
</div>
<div class='method-step' data-reveal>
<div class='num'>04</div>
<h4>Deliver</h4>
<p>The agent writes to disk, you preview in a sandboxed iframe, export HTML / PDF / PPTX / ZIP / Markdown.</p>
<div class='img'><img src='./assets/method-4.png' alt='' /></div>
</div>
</div>
<div class='method-foot'>
<div class='left'>
<span class='ring'></span>
<span>Skills inform everything. Files make it real.</span>
</div>
<div class='right'><a class='method-repo-link' href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'><b>github.com/nexu-io/open-design</b></a> &nbsp;·&nbsp; Apache-2.0</div>
</div>
</div>
</section>
<section class='tight' data-od-id='work'>
<div class='work'>
<div class='work-rule'>
<span class='roman'>VI.</span>
<span style='display:inline-flex;gap:24px;'>
<span>Selected Work · 2026 Catalog</span>
<span style='color:var(--coral);'>•</span>
<span>Edited by OpenDesign</span>
</span>
<span>006 / 008</span>
</div>
<div class='work-grid'>
<div class='work-copy' data-reveal>
<span class='label'>Selected work</span>
<h2>Skills that turn briefs into <em>memorable</em> shippable <em>artifacts</em><span class='dot'>.</span></h2>
<a class='work-link' href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener'>View all 31 skills</a>
</div>
<a class='work-card' data-reveal href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener'>
<div class='label-row'>
<span class='small-label'>Featured skill</span>
<span class='index'>01 / 31</span>
</div>
<h3>guizang-ppt</h3>
<p>Magazine-style web PPT for product launches and pitch decks. Bundled verbatim, original LICENSE preserved.</p>
<div class='img'><img src='./assets/work-1.png' alt='' /></div>
<div class='meta-row'>
<span class='year'>2026 · DECK</span>
<span>DEFAULT</span>
</div>
</a>
<a class='work-card alt' data-reveal href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener'>
<div class='label-row'>
<span class='small-label'>Companion system</span>
<span class='index'>04 / 72</span>
</div>
<h3>kami</h3>
<p>An editorial paper system. Warm parchment canvas, ink-blue accent, serif-led hierarchy — multilingual by design (EN · zh-CN · ja).</p>
<div class='img'><img src='./assets/work-2.png' alt='' /></div>
<div class='meta-row'>
<span class='year'>2026 · PAPER</span>
<span>SYSTEM</span>
</div>
</a>
</div>
<div class='work-arrows'>
<button class='nav-btn'><svg width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.6'><path d='M14 6l-6 6 6 6'/></svg></button>
<button class='nav-btn active'><svg width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.6'><path d='M10 6l6 6-6 6'/></svg></button>
</div>
</div>
</section>
<section class='testimonial' data-od-id='testimonial'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>VII.</span>
<span class='meta-grp'>
<span>Collaborators / Lineage</span>
<span class='dot-mark'>•</span>
<span>Standing on shoulders</span>
</span>
<span>007 / 008</span>
</div>
<div class='testimonial-grid'>
<div class='testimonial-copy' data-reveal>
<span class='label'>Collaborators <span class='ix'>· Nº 06</span></span>
<h2 style='margin-top:30px;'>&ldquo;OpenDesign helped us turn vague <em>AI ideas</em> into a visual system that felt <em>sharp, believable,</em> and genuinely new.&rdquo;</h2>
<div class='author'>
<span class='avatar'>m</span>
<p>Mina Kovac<br/><span>Creative Director · North Form</span></p>
</div>
<div class='divider'></div>
<p class='partners-text'>Standing on the shoulders of teams shipping open-source design culture.</p>
<div class='partners'>
<a class='partner' data-reveal href='https://github.com/alchaincyf/huashu-design' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<path d='M5 24L20 6L35 24M12 18h16'/>
</svg>
</div>
<span>huashu-design</span>
<small>Philosophy</small>
</a>
<a class='partner' data-reveal href='https://github.com/op7418/guizang-ppt-skill' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<path d='M8 24L20 6L24 22L36 4'/>
</svg>
</div>
<span>guizang-ppt</span>
<small>Decks</small>
</a>
<a class='partner' data-reveal href='https://github.com/multica-ai/multica' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<rect x='6' y='6' width='4' height='18'/><rect x='14' y='6' width='4' height='18'/><rect x='22' y='6' width='4' height='18'/><rect x='30' y='6' width='4' height='18'/>
</svg>
</div>
<span>multica-ai</span>
<small>Daemon</small>
</a>
<a class='partner' data-reveal href='https://github.com/OpenCoworkAI/open-codesign' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<circle cx='15' cy='15' r='9'/><path d='M15 6v18M6 15h18'/>
</svg>
</div>
<span>open-codesign</span>
<small>UX</small>
</a>
<a class='partner' data-reveal href='https://devin.ai/terminal' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<path d='M5 8l9 7-9 7M20 24h18'/>
</svg>
</div>
<span>Devin CLI</span>
<small>Terminal</small>
</a>
<a class='partner' data-reveal href='https://github.com/heygen-com/hyperframes' target='_blank' rel='noreferrer noopener'>
<div class='glyph'>
<svg viewBox='0 0 80 30' fill='none' stroke='currentColor' stroke-width='2'>
<rect x='4' y='5' width='22' height='18'/><rect x='14' y='9' width='22' height='18'/>
</svg>
</div>
<span>hyperframes</span>
<small>Frames</small>
</a>
</div>
<a class='read-more' href='/solutions/'>Read more stories</a>
</div>
<div class='testimonial-art' data-reveal='right'>
<img src='./assets/testimonial.png' alt='' />
</div>
</div>
</div>
</section>
<!-- AMR band: OpenDesign AMR ships SOTA frontier models out of the box.
Static monochrome vendor-logo row + ellipsis, sits under the testimonial. -->
<section class='amr-band' data-od-id='amr-band' data-reveal>
<div class='container'>
<div class='amr-band-inner'>
<span class='amr-band-kicker'>OpenDesign AMR · Design Agent</span>
<h2 class='amr-band-title'>The world&rsquo;s top Agents and LLMs, powering OpenDesign</h2>
<p class='amr-band-lead'>Top up once and reach GPT, Claude, Gemini, DeepSeek and more. AMR auto-routes each step to the right frontier model — billed by real token usage, with your wallet balance and request log in one console.</p>
<ul class='amr-band-chips' aria-label='OpenDesign AMR · Design Agent'>
<li class='amr-band-chip'><span class='amr-band-chip-dot' aria-hidden='true'></span>20+ flagship models</li>
<li class='amr-band-chip'><span class='amr-band-chip-dot' aria-hidden='true'></span>Zero setup</li>
<li class='amr-band-chip'><span class='amr-band-chip-dot' aria-hidden='true'></span>SOTA Harness For Design</li>
<li class='amr-band-chip'><span class='amr-band-chip-dot' aria-hidden='true'></span>Real token-based billing</li>
</ul>
<ul class='amr-band-logos' aria-label='Built-in frontier models'>
<li><img class='amr-band-logo' src='./assets/agents/openai.svg' alt='OpenAI' title='OpenAI' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/anthropic.svg' alt='Anthropic' title='Anthropic' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/gemini.svg' alt='Google Gemini' title='Google Gemini' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/deepseek.svg' alt='DeepSeek' title='DeepSeek' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/zhipu.svg' alt='Zhipu GLM' title='Zhipu GLM' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/moonshot.svg' alt='Moonshot Kimi' title='Moonshot Kimi' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/qwen.svg' alt='Qwen' title='Qwen' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/minimax.svg' alt='MiniMax' title='MiniMax' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/xiaomi.svg' alt='Xiaomi MiMo' title='Xiaomi MiMo' width='26' height='26' loading='lazy' /></li>
<li><img class='amr-band-logo' src='./assets/agents/xai.svg' alt='xAI' title='xAI' width='26' height='26' loading='lazy' /></li>
<li class='amr-band-more' aria-label='and more'>&hellip;</li>
</ul>
<div class='amr-band-actions'>
<a class='nav-cta amr-band-cta' href='https://open-design.ai/amr/'>Explore AMR</a>
</div>
</div>
</div>
</section>
<section class='cta' id='contact' data-od-id='cta'>
<div class='container'>
<div class='sec-rule'>
<span class='roman'>VIII.</span>
<span class='meta-grp'>
<span>Contact / Conversation</span>
<span class='dot-mark'>•</span>
<span>Three commands to ship</span>
</span>
<span>008 / 008</span>
</div>
<div class='cta-grid'>
<div data-reveal>
<span class='label'>Start a conversation <span class='ix'>· Nº 07</span></span>
<h2 class='display'>Let's build something <em>open</em> and <em>visually</em> unforgettable<span class='dot'>.</span></h2>
<p class='lead'>Star us on GitHub, drop into the issues, or run <code class='code-inline'>pnpm tools-dev</code> tonight. Three commands and the loop is yours.</p>
<div class='cta-actions'>
<a class='btn btn-primary' href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'>
Star on GitHub
<span class='arrow'><svg viewBox='0 0 24 24'><path d='M5 19L19 5M19 5H8M19 5v11'/></svg></span>
</a>
<a class='email-pill' href='https://github.com/nexu-io/open-design/issues' target='_blank' rel='noreferrer noopener'>
Open an issue
<span class='arrow-circle'>→</span>
</a>
</div>
<div class='cta-foot'>
<span class='stamp'>● Live</span>
<span>v0.3.0 / Apache-2.0</span>
<span style='margin-left:auto;'>52.5200° N · 13.4050° E</span>
</div>
</div>
<div class='cta-art' data-reveal='right'>
<img src='./assets/cta.png' alt='' />
<div class='index'>Nº 08</div>
<div class='ribbon'>OPENDESIGN &nbsp;·&nbsp; FIN.</div>
</div>
</div>
</div>
</section>
<!-- ====== NEWSLETTER ====== -->
<section class='newsletter' id='newsletter' data-od-id='newsletter'>
<div class='container'>
<div class='newsletter-card' data-reveal>
<div class='newsletter-copy'>
<span class='label'>Stay updated</span>
<h2 class='newsletter-title'>The OpenDesign newsletter</h2>
<p class='lead'>New templates, design-system drops, ambassador work, and product updates — straight to your inbox.</p>
</div>
<form class='newsletter-form' data-newsletter-form data-source='landing' data-success='You’re in. Watch your inbox.' data-error='Something went wrong. Try again.'>
<input class='newsletter-input' type='email' name='email' required autocomplete='email' placeholder='[email protected]' aria-label='[email protected]' data-newsletter-email />
<button class='btn btn-primary newsletter-submit' type='submit'>Subscribe</button>
<p class='newsletter-msg' data-newsletter-msg aria-live='polite'></p>
</form>
</div>
</div>
</section>
<!-- ====== NEWSLETTER POPUP (hidden until JS shows it) ====== -->
<aside class='newsletter-popup' data-newsletter-popup hidden role='dialog' aria-label='The OpenDesign newsletter'>
<button class='newsletter-popup__close' type='button' data-newsletter-dismiss aria-label='Close'>×</button>
<span class='label'>Stay updated</span>
<h3 class='newsletter-popup__title'>The OpenDesign newsletter</h3>
<p class='newsletter-popup__lead'>New templates, design-system drops, ambassador work, and product updates — straight to your inbox.</p>
<form class='newsletter-form' data-newsletter-form data-source='landing' data-success='You’re in. Watch your inbox.' data-error='Something went wrong. Try again.'>
<input class='newsletter-input' type='email' name='email' required autocomplete='email' placeholder='[email protected]' aria-label='[email protected]' data-newsletter-email />
<button class='btn btn-primary newsletter-submit' type='submit'>Subscribe</button>
<p class='newsletter-msg' data-newsletter-msg aria-live='polite'></p>
</form>
</aside>
<footer data-od-id='footer'>
<div class='container'>
<div class='foot-grid'>
<div class='foot-brand'>
<a href='#top' class='brand'>
<span class='brand-mark'>Ø</span>
<span>OpenDesign</span>
</a>
<p style='margin-top:18px;'>The open-source alternative to Claude Design. Built on the shoulders of <a class='inline-link' href='https://github.com/alchaincyf/huashu-design' target='_blank' rel='noreferrer noopener'>huashu-design</a>, <a class='inline-link' href='https://github.com/op7418/guizang-ppt-skill' target='_blank' rel='noreferrer noopener'>guizang-ppt</a>, <a class='inline-link' href='https://github.com/multica-ai/multica' target='_blank' rel='noreferrer noopener'>multica-ai</a>, and <a class='inline-link' href='https://github.com/OpenCoworkAI/open-codesign' target='_blank' rel='noreferrer noopener'>open-codesign</a>.</p>
<a class='foot-cta' href='https://github.com/nexu-io/open-design/releases' target='_blank' rel='noreferrer noopener'>Download desktop<span class='meta'>macOS · v0.3.0</span></a>
</div>
<div class='foot-col'>
<h5>Studio</h5>
<ul>
<li><a href='#agents'>Capabilities</a></li>
<li><a href='#labs'>Labs</a></li>
<li><a href='https://github.com/nexu-io/open-design/tree/main/apps/daemon' target='_blank' rel='noreferrer noopener'>Method</a></li>
<li><a href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'>Manifesto</a></li>
</ul>
</div>
<div class='foot-col'>
<h5>Library</h5>
<ul>
<li><a href='https://github.com/nexu-io/open-design/tree/main/skills' target='_blank' rel='noreferrer noopener'>31 Skills</a></li>
<li><a href='https://github.com/nexu-io/open-design/tree/main/design-systems' target='_blank' rel='noreferrer noopener'>72 Systems</a></li>
<li><a href='https://github.com/nexu-io/open-design/tree/main/design-systems' target='_blank' rel='noreferrer noopener'>5 Directions</a></li>
<li><a href='https://github.com/nexu-io/open-design/tree/main/skills/hyperframes' target='_blank' rel='noreferrer noopener'>5 Frames</a></li>
</ul>
</div>
<div class='foot-col'>
<h5>Connect</h5>
<ul>
<li><a href='https://github.com/nexu-io/open-design' target='_blank' rel='noreferrer noopener'>GitHub</a></li>
<li><a href='https://github.com/nexu-io/open-design/issues' target='_blank' rel='noreferrer noopener'>Issues</a></li>
<li><a href='https://github.com/nexu-io/open-design/graphs/contributors' target='_blank' rel='noreferrer noopener'>Contributors</a></li>
<li><a href='https://github.com/nexu-io/open-design/releases' target='_blank' rel='noreferrer noopener'>Releases</a></li>
</ul>
</div>
<div class='foot-col'>
<h5>Docs</h5>
<ul>
<li><a href='https://github.com/nexu-io/open-design/blob/main/QUICKSTART.md' target='_blank' rel='noreferrer noopener'>Quickstart</a></li>
<li><a href='https://github.com/nexu-io/open-design/blob/main/docs/architecture.md' target='_blank' rel='noreferrer noopener'>Architecture</a></li>
<li><a href='https://github.com/nexu-io/open-design/blob/main/docs/skills-protocol.md' target='_blank' rel='noreferrer noopener'>Skill Protocol</a></li>
<li><a href='https://github.com/nexu-io/open-design/blob/main/docs/roadmap.md' target='_blank' rel='noreferrer noopener'>Roadmap</a></li>
</ul>
</div>
</div>
<div class='foot-bottom'>
<span><span class='pulse'></span>● <b style='color:var(--ink);'>OpenDesign</b> · Apache-2.0 · 2026 / Vol. 01 / Issue Nº 26</span>
<span class='right'>
<span>Berlin / Open / Earth</span>
<span>52.5200° N · 13.4050° E</span>
<span style='color:var(--coral);'>♥ MMXXVI</span>
</span>
</div>
<div class='foot-mega'>
<div class='word' data-reveal='rise-lg'>Open <em>Design</em>.</div>
</div>
</div>
</footer>
</div>
<script>
/*
* Scroll-reveal observer.
* Watches every [data-reveal] element and flips data-revealed='true'
* when it first enters the viewport, triggering the CSS transition.
*/
(function () {
var elements = document.querySelectorAll('[data-reveal]:not([data-revealed])');
if (!elements.length) return;
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches || !('IntersectionObserver' in window)) {
for (var i = 0; i < elements.length; i++) elements[i].dataset.revealed = 'true';
return;
}
var observer;
try {
observer = new IntersectionObserver(function (entries) {
for (var i = 0; i < entries.length; i++) {
if (!entries[i].isIntersecting) continue;
entries[i].target.dataset.revealed = 'true';
observer.unobserve(entries[i].target);
}
}, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
for (var j = 0; j < elements.length; j++) observer.observe(elements[j]);
document.documentElement.classList.add('reveal-ready');
} catch (error) {
if (observer) observer.disconnect();
document.documentElement.classList.remove('reveal-ready');
console.error('Reveal animation initialization failed', error);
}
})();
/*
* Headroom-style sticky header.
* Hides the nav on downward scroll, re-pins it on upward scroll, and
* always keeps it visible near the top of the page.
*/
(function () {
var nav = document.querySelector('header.nav');
if (!nav) return;
var SHOW_TOP = 100;
var DELTA = 6;
var lastY = window.scrollY || 0;
function onScroll() {
var y = window.scrollY || 0;
var d = y - lastY;
if (y <= SHOW_TOP) {
nav.classList.remove('is-hidden');
} else if (d > DELTA) {
nav.classList.add('is-hidden');
} else if (d < -DELTA) {
nav.classList.remove('is-hidden');
}
lastY = y;
}
window.addEventListener('scroll', onScroll, { passive: true });
})();
</script>
<script>
/*
* GitHub star count — pulls live count and replaces the placeholder
* text in the nav CTA. Failures fall back silently.
*/
(function () {
var cta = document.querySelector('a.nav-cta:not(.ghost)');
if (!cta) return;
function format(n) {
if (!isFinite(n) || n <= 0) return '0';
if (n < 1000) return String(n);
var k = (n / 1000).toFixed(1).replace(/\.0$/, '');
return k + 'K';
}
fetch('https://api.github.com/repos/nexu-io/open-design', {
headers: { Accept: 'application/vnd.github+json' }
})
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (data) {
if (!data || typeof data.stargazers_count !== 'number') return;
cta.textContent = 'Star · ' + format(data.stargazers_count);
cta.setAttribute('aria-label', 'Star on GitHub — ' + format(data.stargazers_count) + ' stars');
})
.catch(function () { /* leave placeholder on failure */ });
})();
</script>
<script>
/*
* Newsletter signup. Wires both the in-page
* section form and the bottom-right popup to POST /subscribe, and
* reveals the popup after 50% scroll or a 10s fallback (whichever is
* first), suppressed once dismissed or subscribed.
*/
(function () {
var STORAGE_KEY = 'od-newsletter-dismissed';
var locale = (document.documentElement.getAttribute('lang') || 'en').toLowerCase();
function track(area, result) {
if (window.__odTrack)
window.__odTrack('newsletter_signup', { page_name: 'landing_home', area: area, result: result, locale: locale });
}
function dismissed() {
try {
return window.localStorage.getItem(STORAGE_KEY) === '1';
} catch (e) {
return false;
}
}
function setDismissed() {
try {
window.localStorage.setItem(STORAGE_KEY, '1');
} catch (e) {
/* private mode — popup will just reappear next visit */
}
}
function wireForm(form, area) {
var input = form.querySelector('[data-newsletter-email]');
var msg = form.querySelector('[data-newsletter-msg]');
var submit = form.querySelector('.newsletter-submit');
var successText = form.getAttribute('data-success') || '';
var errorText = form.getAttribute('data-error') || '';
form.addEventListener('submit', function (ev) {
ev.preventDefault();
var email = (input && input.value ? input.value : '').trim();
if (!email) return;
if (submit) submit.disabled = true;
if (msg) msg.textContent = '';
fetch('/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: email, source: form.getAttribute('data-source') || 'landing' })
})
.then(function (r) { return r.ok ? r.json() : Promise.reject(new Error('http error')); })
.then(function (data) {
if (!data || data.ok !== true) throw new Error('rejected');
form.classList.add('is-success');
if (msg) msg.textContent = successText;
if (input) input.value = '';
setDismissed();
track(area, 'success');
})
.catch(function () {
if (msg) msg.textContent = errorText;
if (submit) submit.disabled = false;
track(area, 'error');
});
});
}
var forms = document.querySelectorAll('[data-newsletter-form]');
for (var i = 0; i < forms.length; i++) {
var popupParent = forms[i].closest('[data-newsletter-popup]');
wireForm(forms[i], popupParent ? 'popup' : 'section');
}
var popup = document.querySelector('[data-newsletter-popup]');
if (popup && !dismissed()) {
var close = function () {
popup.hidden = true;
setDismissed();
};
var dismissBtns = popup.querySelectorAll('[data-newsletter-dismiss]');
for (var j = 0; j < dismissBtns.length; j++) dismissBtns[j].addEventListener('click', close);
document.addEventListener('keydown', function (ev) {
if (ev.key === 'Escape' && !popup.hidden) close();
});
var reveal = function () {
if (dismissed()) return;
popup.hidden = false;
popup.classList.add('is-visible');
track('popup', 'view');
};
var shown = false;
var showOnce = function () {
if (shown) return;
shown = true;
reveal();
};
var onScroll = function () {
if (window.scrollY > window.innerHeight * 0.5) {
window.removeEventListener('scroll', onScroll);
showOnce();
}
};
window.addEventListener('scroll', onScroll, { passive: true });
window.setTimeout(showOnce, 10000);
}
})();
</script>
</body>
</html>