1717 lines
97 KiB
HTML
1717 lines
97 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Nucleic — mission control for a fleet of coding agents</title>
|
||
<meta name="description" content="Nucleic runs Claude Code, Codex, and Grok Build — or any ACP-compatible agent — in parallel, each isolated and observed down to the edit, with one Mac cockpit to watch, approve, and merge their work. Work from your iPhone, too." />
|
||
<meta property="og:title" content="Nucleic — mission control for a fleet of coding agents" />
|
||
<meta property="og:description" content="Run a fleet of coding agents. Stay in command." />
|
||
<meta name="theme-color" content="#faf7f3" />
|
||
|
||
<!-- atom mark, reused as favicon -->
|
||
<link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><g fill='none' stroke-width='7'><ellipse cx='50' cy='50' rx='17' ry='40' transform='rotate(80 50 50)' stroke='%237AA7DD'/><ellipse cx='50' cy='50' rx='17' ry='40' transform='rotate(20 50 50)' stroke='%23DF619B'/><ellipse cx='50' cy='50' rx='17' ry='40' transform='rotate(140 50 50)' stroke='%23C5826F'/></g></svg>" />
|
||
|
||
<!-- Self-hosted fonts (latin subset). The woff2 binaries live in fonts/ and are
|
||
preloaded so they download in parallel with the HTML; @font-face is inlined
|
||
(no render-blocking stylesheet) and the page never contacts Google. -->
|
||
<link rel="preload" href="fonts/space-grotesk.woff2" as="font" type="font/woff2" crossorigin />
|
||
<link rel="preload" href="fonts/jetbrains-mono.woff2" as="font" type="font/woff2" crossorigin />
|
||
<style>
|
||
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/space-grotesk.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
||
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;src:url(fonts/jetbrains-mono.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
||
</style>
|
||
|
||
<style>
|
||
:root{
|
||
--ink:#181520; /* warm near-black */
|
||
--ink-soft:#5b5560; /* muted body text */
|
||
--ink-faint:#8b8590; /* captions */
|
||
--paper:#faf7f3; /* warm off-white */
|
||
--panel:#fffdfb;
|
||
--panel-2:#f3ede6;
|
||
--line:#e6ded4;
|
||
--line-2:#efe9e1;
|
||
|
||
--blue:#5e9bd8;
|
||
--pink:#db5f97;
|
||
--magenta:#c264ad;
|
||
--rust:#c47e69;
|
||
--green:#5fa775;
|
||
--amber:#d7a23f;
|
||
|
||
--sans:"Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||
--mono:"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
||
--maxw:1080px;
|
||
}
|
||
|
||
*{box-sizing:border-box}
|
||
html{scroll-behavior:smooth}
|
||
body{
|
||
margin:0;
|
||
overflow-x:clip;
|
||
font-family:var(--sans);
|
||
color:var(--ink);
|
||
background:var(--paper);
|
||
/* faint graph-paper dotting — instrument, not glow */
|
||
background-image:radial-gradient(var(--line) 1px, transparent 1px);
|
||
background-size:26px 26px;
|
||
background-position:-13px -13px;
|
||
-webkit-font-smoothing:antialiased;
|
||
line-height:1.5;
|
||
}
|
||
a{color:inherit}
|
||
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
|
||
|
||
.mono{font-family:var(--mono)}
|
||
.kicker{
|
||
font-family:var(--mono);
|
||
font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
|
||
color:var(--ink-faint);
|
||
}
|
||
|
||
/* ---------- selection ----------
|
||
Chrome that isn't prose — buttons, the brand lockup, eyebrow labels,
|
||
badges/pills, agent chips, decorative index numbers, and ornamental
|
||
separators — has no text worth selecting; only the page's actual copy
|
||
(headlines, paragraphs, captions) stays selectable. The cockpit and
|
||
iPhone mocks scope their own user-select:none below. */
|
||
.btn,.brand,.kicker,.hero-badge,.ach,.card .no,.beta,.dotsep{
|
||
-webkit-user-select:none;user-select:none;
|
||
}
|
||
|
||
/* ---------- top bar ---------- */
|
||
header{
|
||
position:sticky;top:0;z-index:20;
|
||
backdrop-filter:saturate(1.1) blur(8px);
|
||
background:color-mix(in srgb, var(--paper) 82%, transparent);
|
||
border-bottom:1px solid var(--line-2);
|
||
}
|
||
.bar{display:flex;align-items:center;justify-content:space-between;height:62px}
|
||
.brand{display:flex;align-items:center;gap:11px;font-weight:600;letter-spacing:-.01em;font-size:17px}
|
||
.brand .mk{width:26px;height:26px;display:block}
|
||
.tag{
|
||
font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
|
||
color:var(--ink-faint);border:1px solid var(--line);border-radius:999px;padding:3px 8px;
|
||
}
|
||
.nav{display:flex;align-items:center;gap:22px;font-size:14px;color:var(--ink-soft)}
|
||
.nav a{text-decoration:none}
|
||
.nav .lk:hover{color:var(--ink)}
|
||
/* Top-bar download stays hidden until the hero's download scrolls out of view */
|
||
#nav-dl{opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-6px);transition:opacity .2s ease, transform .2s ease, visibility .2s ease}
|
||
#nav-dl.show{opacity:1;visibility:visible;pointer-events:auto;transform:none}
|
||
.btn{
|
||
font-family:var(--sans);font-size:14px;font-weight:500;
|
||
text-decoration:none;cursor:pointer;border:0;
|
||
padding:9px 16px;border-radius:10px;
|
||
color:#fff;background:var(--ink);
|
||
transition:transform .12s ease, opacity .12s ease;
|
||
white-space:nowrap;-webkit-tap-highlight-color:transparent;
|
||
}
|
||
.btn:link,.btn:visited,.btn:hover,.btn:focus,.btn:active{color:#fff}
|
||
.btn:hover{opacity:.9;transform:translateY(-1px)}
|
||
.btn.ghost,.btn.ghost:link,.btn.ghost:visited{background:transparent;color:var(--ink);border:1px solid var(--line)}
|
||
|
||
/* ---------- download split button ----------
|
||
Primary half downloads the default (beta) build; the chevron opens a small
|
||
menu to pick a channel — canary lives here, obvious but a notch down the
|
||
hierarchy from the headline "Download" action. */
|
||
.dl{display:inline-flex;position:relative;vertical-align:top}
|
||
/* No hover lift on the split control — the two halves would rise separately. */
|
||
.dl .btn{border-radius:10px 0 0 10px}
|
||
.dl .btn:hover{transform:none}
|
||
.dl-toggle{
|
||
font-family:var(--sans);display:flex;align-items:center;justify-content:center;
|
||
width:38px;padding:0;border:0;cursor:pointer;color:#fff;background:var(--ink);
|
||
border-radius:0 10px 10px 0;border-left:1px solid color-mix(in srgb,#fff 22%, var(--ink));
|
||
transition:opacity .12s ease;-webkit-tap-highlight-color:transparent;
|
||
}
|
||
.dl-toggle:hover{opacity:.9}
|
||
.dl-toggle svg{width:15px;height:15px;transition:transform .2s ease}
|
||
.dl.open .dl-toggle svg{transform:rotate(180deg)}
|
||
.dl-menu{
|
||
position:absolute;top:calc(100% + 8px);left:0;z-index:40;width:250px;max-width:78vw;
|
||
background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:6px;
|
||
box-shadow:0 20px 44px -24px rgba(24,21,32,.55);text-align:left;
|
||
opacity:0;visibility:hidden;transform:translateY(-6px);
|
||
transition:opacity .16s ease, transform .16s ease, visibility .16s ease;
|
||
}
|
||
.dl-menu.right{left:auto;right:0}
|
||
.dl-menu.center{left:50%;right:auto;transform:translate(-50%,-6px)}
|
||
.dl.open .dl-menu{opacity:1;visibility:visible;transform:none}
|
||
.dl.open .dl-menu.center{transform:translateX(-50%)}
|
||
.dl-opt{display:block;text-decoration:none;color:var(--ink);border-radius:8px;padding:9px 11px}
|
||
.dl-opt:hover,.dl-opt:focus-visible{background:var(--panel-2);outline:none}
|
||
.dl-opt .t{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;letter-spacing:-.01em}
|
||
.dl-opt .d{margin:3px 0 0;font-size:12px;color:var(--ink-soft);line-height:1.45}
|
||
.dl-lbl{font-family:var(--mono);font-size:9px;letter-spacing:.12em;text-transform:uppercase;border-radius:999px;padding:2px 6px;border:1px solid transparent;font-weight:400}
|
||
.dl-lbl.beta{color:var(--magenta);border-color:color-mix(in srgb,var(--magenta) 35%,transparent)}
|
||
.dl-lbl.canary{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 45%,transparent)}
|
||
@media (max-width:720px){ .nav .lk{display:none} #nav-dl{display:none} .brand .tag{display:none} .bar{gap:12px} }
|
||
|
||
/* ---------- hero ---------- */
|
||
.hero{padding:74px 0 40px}
|
||
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center}
|
||
h1{
|
||
font-size:clamp(34px,5.4vw,60px);line-height:1.02;letter-spacing:-.03em;
|
||
font-weight:600;margin:18px 0 0;
|
||
}
|
||
h1 .em{
|
||
background:linear-gradient(100deg,var(--rust),var(--pink) 45%,var(--magenta) 70%,var(--blue));
|
||
-webkit-background-clip:text;background-clip:text;color:transparent;
|
||
}
|
||
.sub{margin:22px 0 0;font-size:18px;color:var(--ink-soft);max-width:40ch}
|
||
.cta-row{display:flex;align-items:center;gap:14px;margin-top:30px;flex-wrap:wrap}
|
||
.cta-note{font-family:var(--mono);font-size:12px;color:var(--ink-faint)}
|
||
.hero-badge{
|
||
display:inline-block;
|
||
font-size:12.5px;font-weight:500;color:var(--ink);line-height:1.3;
|
||
background:color-mix(in srgb,var(--blue) 12%, var(--panel));
|
||
border:1px solid color-mix(in srgb,var(--blue) 40%, var(--line));
|
||
border-radius:999px;padding:6px 13px;margin:0 0 6px;
|
||
}
|
||
|
||
/* atom visual */
|
||
.atom-wrap{display:flex;justify-content:center;align-items:center;min-width:0}
|
||
.atom{width:100%;max-width:420px;height:auto;overflow:visible}
|
||
.hero-grid>*{min-width:0}
|
||
@media (max-width:820px){
|
||
.hero{padding:48px 0 32px}
|
||
.hero-grid{grid-template-columns:1fr;gap:30px}
|
||
.atom{max-width:230px}
|
||
}
|
||
.ring{fill:none;stroke-width:5;opacity:.92}
|
||
.node{filter:drop-shadow(0 1px 3px rgba(0,0,0,.18))}
|
||
.nucleus{fill:var(--ink)}
|
||
@keyframes spin{to{transform:rotate(360deg)}}
|
||
.sys{transform-origin:200px 200px;animation:spin 90s linear infinite}
|
||
@media (prefers-reduced-motion:reduce){
|
||
.sys{animation:none}
|
||
.dot{display:none}
|
||
}
|
||
|
||
/* ---------- premise band ---------- */
|
||
.band{border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);background:color-mix(in srgb,var(--panel) 60%, transparent)}
|
||
.band .wrap{padding:34px 24px;display:flex;gap:40px;align-items:baseline;flex-wrap:wrap}
|
||
.band h2{font-size:clamp(20px,2.6vw,27px);font-weight:500;letter-spacing:-.02em;margin:0;max-width:24ch}
|
||
.band p{margin:0;color:var(--ink-soft);font-size:15.5px;max-width:46ch}
|
||
.band .lede{color:var(--ink)}
|
||
|
||
/* ---------- cockpit mock (faithful web port — see website/cockpit.html) ---------- */
|
||
/* top padding matches the band's top gap (.agents bottom padding) so the
|
||
premise band has equal breathing room above and below */
|
||
.showcase{padding:48px 0 10px}
|
||
/* ===== Nucleic cockpit — scoped, light (warm-paper), Control-tab active ==== */
|
||
.nuc-cockpit{
|
||
/* Surfaces — the app's actual LIGHT appearance (AppTheme.swift sRGB values) */
|
||
--bg:#f7f7fa; /* background srgb(.97,.97,.98) */
|
||
--sidebar:#ebecf0; /* sidebar srgb(.92,.925,.94) */
|
||
--surface:#ffffff; /* surface — cards / tiles / pills (white) */
|
||
--tile:#ffffff; /* StatCard / QuotaCard / streak all use surface (white) */
|
||
--field:#eeeef1; /* composer field — .quaternary fill */
|
||
--hair:rgba(0,0,0,.10);/* hairline NSColor(white:0, alpha:.10) */
|
||
--hair-2:rgba(0,0,0,.06);
|
||
--sel:#d4d7df; /* selected-row highlight — softened for marketing; app srgb(.83,.84,.875) */
|
||
|
||
/* Text — primaryText srgb(.24,.24,.27) + secondary/tertiary label tiers */
|
||
--tx:#3d3d45;
|
||
--tx2:#70707a;
|
||
--tx3:#a2a2ab;
|
||
|
||
/* Categorical palette — app standard palette, LIGHT (vivid base) values */
|
||
--lav:#7352d1; /* Control-project accent (violet) (.45,.32,.82) */
|
||
--teal:#0a8580; /* default accent (.04,.52,.50) */
|
||
--blue:#338cf2; /* running / active (.20,.55,.95) */
|
||
--amber:#ffa626; /* attention / waiting (1,.65,.15) */
|
||
--green:#4dcc73; /* success / running container (.30,.80,.45) */
|
||
--red:#eb5757; /* danger (.92,.34,.34) */
|
||
--frozen:#42a3f5; /* iced streak-freeze blue (.26,.64,.96) */
|
||
--gold:#cc9117; /* orchestra gold (.80,.57,.09) */
|
||
--usagebar:#6b99a3;/* AppTheme.usageBar light (.42,.60,.64) */
|
||
|
||
/* Activity grid shades — activityBase green over a secondary-15% empty cell */
|
||
--c-l0:#dcdce1;
|
||
--c-l1:rgba(77,204,115,.4);
|
||
--c-l2:rgba(77,204,115,.7);
|
||
--c-l3:rgba(77,204,115,.88);
|
||
--c-l4:#4dcc73;
|
||
|
||
--mono:"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
||
|
||
font-family:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "Space Grotesk", Arial, sans-serif;
|
||
color:var(--tx);
|
||
background:var(--bg);
|
||
border:1px solid var(--hair);
|
||
border-radius:14px;
|
||
overflow:hidden;
|
||
box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
|
||
0 30px 70px -40px rgba(40,30,50,.40);
|
||
font-size:13px;
|
||
line-height:1.45;
|
||
/* It's an illustrative chrome, not real content — keep its text unselectable. */
|
||
-webkit-user-select:none;
|
||
user-select:none;
|
||
}
|
||
.nuc-cockpit, .nuc-cockpit *{cursor:default}
|
||
.nuc-cockpit *{box-sizing:border-box}
|
||
.nuc-cockpit svg{display:block}
|
||
|
||
/* ---- title bar (window toolbar: lights, then the toolbar buttons) ---- */
|
||
.nuc-cockpit .nuc-titlebar{
|
||
display:flex;align-items:center;gap:12px;
|
||
padding:10px 14px;background:#e9eaef;border-bottom:1px solid var(--hair);
|
||
}
|
||
.nuc-cockpit .nuc-lights{display:flex;gap:8px}
|
||
.nuc-cockpit .nuc-lights i{width:11px;height:11px;border-radius:50%;display:block}
|
||
.nuc-cockpit .nuc-lights i:nth-child(1){background:#ec6a5e}
|
||
.nuc-cockpit .nuc-lights i:nth-child(2){background:#f4bd4f}
|
||
.nuc-cockpit .nuc-lights i:nth-child(3){background:#61c454}
|
||
/* Toggle Sidebar · Home · Add Project — the three window-toolbar buttons */
|
||
.nuc-cockpit .nuc-tbar{display:flex;align-items:center;gap:15px;margin-left:5px}
|
||
.nuc-cockpit .nuc-tbtn{color:#54545d;display:flex}
|
||
.nuc-cockpit .nuc-tbtn svg{width:16px;height:16px}
|
||
.nuc-cockpit .nuc-wtitle{margin-left:22px;font-weight:600;letter-spacing:-.01em;color:var(--tx)}
|
||
|
||
/* ---- two-column body ----
|
||
Height is bounded (default 780px, override via `--nuc-h`) and each pane scrolls
|
||
internally — mirroring the real app (HomeView is a ScrollView with a pinned chat
|
||
bar; the sidebar is a List). So the cockpit fits a hero slot and adapts to height
|
||
changes instead of growing to its content. On mobile it falls back to natural
|
||
height (the page scrolls — see the media query at the end). */
|
||
/* Default sized so the selected chat + the one below it stay visible in the sidebar. */
|
||
.nuc-cockpit{--nuc-h:780px}
|
||
.nuc-cockpit .nuc-body{display:grid;grid-template-columns:286px 1fr;height:var(--nuc-h)}
|
||
/* hide the internal scrollbars so the panes read as a clean app window */
|
||
.nuc-cockpit .nuc-side,.nuc-cockpit .nuc-scroll{scrollbar-width:none}
|
||
.nuc-cockpit .nuc-side::-webkit-scrollbar,.nuc-cockpit .nuc-scroll::-webkit-scrollbar{width:0;height:0}
|
||
|
||
/* =========================== SIDEBAR ===================================== */
|
||
/* Column-edge inset matches the app's safeAreaPadding(5)+row padding(8)=13. */
|
||
.nuc-cockpit .nuc-side{
|
||
background:var(--sidebar);border-right:1px solid var(--hair);
|
||
padding:10px 13px;display:flex;flex-direction:column;overflow:hidden;min-height:0;
|
||
}
|
||
/* The sidebar scroll is locked (overflow:hidden) so it reads as a fixed app pane;
|
||
its children must NOT flex-shrink, or an overflowing column would squash the
|
||
switcher/sections (the switcher's overflow:hidden then clips them). */
|
||
.nuc-cockpit .nuc-side > *{flex-shrink:0}
|
||
|
||
/* mode switcher — bordered segmented control spanning the column
|
||
(SidebarModeSwitcher: equal maxWidth-infinity segments, 3pt inset pill) */
|
||
.nuc-cockpit .nuc-switch{
|
||
display:flex;gap:2px;padding:3px;overflow:hidden;
|
||
background:var(--surface);border:1px solid var(--hair);border-radius:9px;margin-bottom:6px;
|
||
}
|
||
.nuc-cockpit .nuc-seg{
|
||
flex:1 1 0;min-width:0;overflow:hidden;
|
||
display:flex;align-items:center;justify-content:center;gap:4px;
|
||
padding:5px 6px;border-radius:6px;font-size:11px;font-weight:600;
|
||
color:var(--tx2);white-space:nowrap;
|
||
}
|
||
.nuc-cockpit .nuc-seg svg{width:13px;height:13px;flex:none}
|
||
.nuc-cockpit .nuc-seg.on{background:rgba(0,0,0,.08);color:var(--tx)}
|
||
|
||
/* pane header — accent atom glyph + status summary + trailing control + rule */
|
||
.nuc-cockpit .nuc-pane-head{display:flex;flex-direction:column}
|
||
.nuc-cockpit .nuc-pane-row{display:flex;align-items:flex-start;gap:8px;padding:9px 0}
|
||
.nuc-cockpit .nuc-pane-row .nuc-acc{color:var(--lav);flex:none;margin-top:1px}
|
||
.nuc-cockpit .nuc-pane-row .nuc-sum{font-size:11px;color:var(--tx2);flex:1;min-width:0;line-height:1.35}
|
||
.nuc-cockpit .nuc-relall{
|
||
font-size:10.5px;color:var(--tx2);display:inline-flex;align-items:center;gap:4px;
|
||
flex:none;white-space:nowrap;margin-top:1px;
|
||
}
|
||
.nuc-cockpit .nuc-rule{height:1px;background:var(--hair);margin:0 0 10px}
|
||
|
||
/* section titles + pane body */
|
||
.nuc-cockpit .nuc-pane-body{display:flex;flex-direction:column;gap:14px;padding:0 0 4px}
|
||
.nuc-cockpit .nuc-sec-t{
|
||
font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;font-weight:700;color:var(--tx2);
|
||
margin-bottom:3px;
|
||
}
|
||
|
||
/* container identity row */
|
||
.nuc-cockpit .nuc-crow{display:flex;align-items:center;gap:8px;padding:3px 0}
|
||
.nuc-cockpit .nuc-dot{width:8px;height:8px;border-radius:50%;flex:none}
|
||
.nuc-cockpit .nuc-dot.green{background:var(--green)}
|
||
.nuc-cockpit .nuc-dot.amber{background:var(--amber)}
|
||
.nuc-cockpit .nuc-dot.blue{background:var(--blue)}
|
||
.nuc-cockpit .nuc-ct{flex:1;min-width:0}
|
||
.nuc-cockpit .nuc-ct .nm{font-size:12.5px;color:var(--tx);line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nuc-cockpit .nuc-ct .sub{font-size:10px;color:var(--tx2);font-family:var(--mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
|
||
.nuc-cockpit .nuc-trail{font-size:10px;color:var(--tx2);flex:none;white-space:nowrap}
|
||
|
||
/* resource meters (CPU / RAM) */
|
||
.nuc-cockpit .nuc-meter{display:flex;align-items:center;gap:8px;padding:2px 0}
|
||
.nuc-cockpit .nuc-meter .k{width:28px;font-size:10px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-meter .trk{flex:1;height:5px;border-radius:3px;background:rgba(24,21,32,.10);overflow:hidden}
|
||
.nuc-cockpit .nuc-meter .trk i{display:block;height:100%;border-radius:3px}
|
||
.nuc-cockpit .nuc-meter .pct{width:34px;text-align:right;font-size:10px;color:var(--tx2);font-family:var(--mono)}
|
||
|
||
/* autoship / activity info rows */
|
||
.nuc-cockpit .nuc-irow{display:flex;align-items:center;gap:7px;padding:4px 0}
|
||
.nuc-cockpit .nuc-irow .gl{width:13px;flex:none;display:flex;justify-content:center}
|
||
.nuc-cockpit .nuc-irow .gl svg{width:11px;height:11px}
|
||
.nuc-cockpit .nuc-irow .it{flex:1;min-width:0}
|
||
.nuc-cockpit .nuc-irow .it .t{font-size:12px;color:var(--tx);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nuc-cockpit .nuc-irow .it .s{font-size:10px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
|
||
.nuc-cockpit .nuc-irow .when{font-size:10px;color:var(--tx3);flex:none;font-family:var(--mono)}
|
||
|
||
/* file-lock rows (waiter indented) */
|
||
.nuc-cockpit .nuc-lrow{display:flex;align-items:center;gap:7px;padding:4px 0}
|
||
.nuc-cockpit .nuc-lrow.wait{padding-left:16px}
|
||
.nuc-cockpit .nuc-lrow .gl{width:9px;flex:none;display:flex;justify-content:center}
|
||
.nuc-cockpit .nuc-lrow .gl svg{width:11px;height:11px}
|
||
.nuc-cockpit .nuc-lrow .it{flex:1;min-width:0}
|
||
.nuc-cockpit .nuc-lrow .it .t{font-size:12px;color:var(--tx)}
|
||
.nuc-cockpit .nuc-lrow .it .s{font-size:10px;color:var(--tx2);margin-top:1px}
|
||
.nuc-cockpit .nuc-release{font-size:10.5px;color:var(--lav);flex:none}
|
||
|
||
.nuc-cockpit .tint-lav{color:var(--lav)} .nuc-cockpit .tint-amber{color:var(--amber)}
|
||
.nuc-cockpit .tint-green{color:var(--green)} .nuc-cockpit .tint-blue{color:var(--blue)}
|
||
.nuc-cockpit .tint-tx2{color:var(--tx2)} .nuc-cockpit .tint-red{color:var(--red)}
|
||
|
||
/* ---- project tree below the Control pane (always-present session list) ---- */
|
||
.nuc-cockpit .nuc-tree{margin-top:16px;display:flex;flex-direction:column}
|
||
.nuc-cockpit .nuc-proj{display:flex;align-items:center;gap:5px;padding:6px 0 5px}
|
||
.nuc-cockpit .nuc-proj .pname{font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--tx)}
|
||
.nuc-cockpit .nuc-proj svg{width:12px;height:12px;flex:none}
|
||
.nuc-cockpit .nuc-proj .lav{color:var(--lav)}
|
||
.nuc-cockpit .nuc-proj .chev{color:var(--tx3)}
|
||
.nuc-cockpit .nuc-proj .sp{flex:1}
|
||
.nuc-cockpit .nuc-proj .integrate{color:var(--lav);width:15px;height:15px}
|
||
|
||
/* session row (SessionRow): leading status dot, title + status line, trailing meta */
|
||
.nuc-cockpit .nuc-srow{display:flex;align-items:center;gap:7px;margin:0 -7px;padding:6px 7px;border-radius:6px}
|
||
.nuc-cockpit .nuc-srow.sel{background:var(--sel)}
|
||
.nuc-cockpit .nuc-srow .sdot{width:8px;height:8px;border-radius:50%;flex:none}
|
||
.nuc-cockpit .nuc-srow .sglyph{width:9px;flex:none;display:flex;justify-content:center}
|
||
.nuc-cockpit .nuc-srow .sglyph svg{width:10px;height:10px}
|
||
.nuc-cockpit .nuc-srow .sc{flex:1;min-width:0}
|
||
.nuc-cockpit .nuc-srow .st{font-size:12.5px;color:var(--tx);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nuc-cockpit .nuc-srow .st.unseen{font-weight:600}
|
||
.nuc-cockpit .nuc-srow .ss{display:flex;align-items:center;gap:4px;margin-top:1px;font-size:10.5px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-srow .ss .b{display:inline-flex}
|
||
.nuc-cockpit .nuc-srow .ss svg{width:9px;height:9px}
|
||
.nuc-cockpit .nuc-srow .diff{font-size:10px;font-family:var(--mono);color:var(--tx2);flex:none}
|
||
.nuc-cockpit .nuc-srow .udot{width:7px;height:7px;border-radius:50%;background:var(--lav);flex:none}
|
||
.nuc-cockpit .nuc-srow .pause{flex:none;color:var(--amber)}
|
||
|
||
/* =========================== MAIN / HOME ================================= */
|
||
.nuc-cockpit .nuc-main{display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--bg)}
|
||
/* overflow-x:hidden (not just overflow-y:auto, which the browser promotes to
|
||
overflow-x:auto) so a child can never raise a stray horizontal scrollbar. */
|
||
.nuc-cockpit .nuc-scroll{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:18px 24px}
|
||
|
||
/* greeting + streak */
|
||
.nuc-cockpit .nuc-hi{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}
|
||
.nuc-cockpit .nuc-hi h1{margin:0;font-size:26px;font-weight:700;letter-spacing:-.02em;color:var(--tx)}
|
||
.nuc-cockpit .nuc-hi .greet{margin:4px 0 0;font-size:13px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-streak{
|
||
display:inline-flex;align-items:center;gap:8px;flex:none;
|
||
background:var(--surface);border:1px solid var(--hair);border-radius:12px;padding:7px 13px;
|
||
}
|
||
.nuc-cockpit .nuc-streak .bolt{color:var(--frozen)}
|
||
.nuc-cockpit .nuc-streak .n{font-size:15px;font-weight:600;color:var(--tx)}
|
||
.nuc-cockpit .nuc-streak .lbl{font-size:15px;font-weight:600;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-streak .fz{display:inline-flex;align-items:center;gap:3px;color:var(--frozen);font-size:12.5px;font-weight:600}
|
||
|
||
/* activity + usage row (side-by-side, equal columns like the dashboard HStack) */
|
||
.nuc-cockpit .nuc-dash{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:16px;align-items:start}
|
||
/* min-width:0 lets each track honour its 1fr share. Without it the activity
|
||
grid (a nowrap flex row) imposes its full content as the column's min-content,
|
||
blowing the track wide on narrow widths and squashing the usage card. */
|
||
.nuc-cockpit .nuc-dash>*{min-width:0}
|
||
.nuc-cockpit .nuc-h{font-size:14px;font-weight:600;color:var(--tx);margin:0 0 8px}
|
||
.nuc-cockpit .nuc-h .ic{color:var(--tx2);margin-right:6px;vertical-align:-2px;display:inline-block}
|
||
|
||
/* activity grid (GitHub-style) — sized to its column by the scoped script.
|
||
overflow:hidden clips any sub-pixel rounding so the row can't overflow. */
|
||
.nuc-cockpit .nuc-grid{display:flex;gap:3px;flex-wrap:nowrap;overflow:hidden}
|
||
.nuc-cockpit .nuc-grid .col{display:flex;flex-direction:column;gap:3px}
|
||
.nuc-cockpit .nuc-grid i{width:14px;height:14px;border-radius:3px;background:var(--c-l0);display:block}
|
||
.nuc-cockpit .nuc-grid i.l1{background:var(--c-l1)} .nuc-cockpit .nuc-grid i.l2{background:var(--c-l2)}
|
||
.nuc-cockpit .nuc-grid i.l3{background:var(--c-l3)} .nuc-cockpit .nuc-grid i.l4{background:var(--c-l4)}
|
||
.nuc-cockpit .nuc-grid i.fz{background:var(--frozen)}
|
||
.nuc-cockpit .nuc-legend{display:flex;align-items:center;gap:5px;margin-top:10px;font-size:10.5px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-legend i{width:11px;height:11px;border-radius:2px;display:block}
|
||
.nuc-cockpit .nuc-legend .gap{width:8px}
|
||
|
||
/* usage card */
|
||
.nuc-cockpit .nuc-card{background:var(--surface);border:1px solid var(--hair);border-radius:12px;padding:14px}
|
||
.nuc-cockpit .nuc-uwin{margin-top:11px}
|
||
.nuc-cockpit .nuc-uwin:first-of-type{margin-top:0}
|
||
.nuc-cockpit .nuc-uwin .top{display:flex;align-items:center;gap:6px}
|
||
.nuc-cockpit .nuc-uwin .top .ulbl{font-size:13px;color:var(--tx);flex:1}
|
||
.nuc-cockpit .nuc-uwin .top .ic{color:var(--tx2)}
|
||
.nuc-cockpit .nuc-uwin .top .up{font-size:13px;font-weight:600;font-family:var(--mono)}
|
||
.nuc-cockpit .nuc-ubar{height:6px;border-radius:4px;background:rgba(24,21,32,.10);overflow:hidden;margin-top:6px}
|
||
.nuc-cockpit .nuc-ubar i{display:block;height:100%;border-radius:4px}
|
||
.nuc-cockpit .nuc-ucap{font-size:10.5px;color:var(--tx2);margin-top:5px}
|
||
|
||
/* stat cards */
|
||
.nuc-cockpit .nuc-tiles{display:grid;grid-template-columns:repeat(5,1fr);gap:11px;margin-top:16px}
|
||
.nuc-cockpit .nuc-tile{background:var(--tile);border:1px solid var(--hair);border-radius:12px;padding:10px 13px}
|
||
.nuc-cockpit .nuc-tile .ic{color:var(--tx2)}
|
||
.nuc-cockpit .nuc-tile .n{font-size:20px;font-weight:600;letter-spacing:-.01em;margin-top:6px;color:var(--tx);font-variant-numeric:tabular-nums}
|
||
.nuc-cockpit .nuc-tile .l{font-size:11px;color:var(--tx2);margin-top:1px}
|
||
|
||
/* to-do */
|
||
.nuc-cockpit .nuc-todo-h{display:flex;align-items:center;justify-content:space-between;margin-top:16px}
|
||
.nuc-cockpit .nuc-todo-h .h{font-size:14px;font-weight:600;color:var(--tx)}
|
||
.nuc-cockpit .nuc-todo-h .act{display:flex;gap:16px;font-size:12px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-todo-h .act .add{color:var(--lav)}
|
||
.nuc-cockpit .nuc-todo-h .act .triaged{display:inline-flex;align-items:center;gap:4px;color:var(--lav)}
|
||
.nuc-cockpit .nuc-todo-h .act .triaged svg{width:13px;height:13px}
|
||
|
||
/* to-do inbox grouped by project: header (folder + name + count) over a card
|
||
of idea rows; each triaged row leads with a severity badge (TodoGroupView) */
|
||
.nuc-cockpit .nuc-tg{margin-top:11px}
|
||
.nuc-cockpit .nuc-tg-head{display:flex;align-items:center;gap:6px;margin-bottom:5px}
|
||
.nuc-cockpit .nuc-tg-head svg{width:13px;height:13px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-tg-head .pn{font-size:13px;font-weight:600;color:var(--tx)}
|
||
.nuc-cockpit .nuc-tg-head .cnt{font-size:10px;font-family:var(--mono);color:var(--tx2);background:rgba(0,0,0,.06);border-radius:999px;padding:1px 7px}
|
||
.nuc-cockpit .nuc-tg-card{background:var(--surface);border:1px solid var(--hair);border-radius:12px;overflow:hidden}
|
||
.nuc-cockpit .nuc-todo-row{display:flex;align-items:center;gap:10px;padding:9px 13px}
|
||
.nuc-cockpit .nuc-todo-row .ico{flex:1;min-width:0}
|
||
.nuc-cockpit .nuc-todo-row .ico .t{font-size:13px;color:var(--tx)}
|
||
.nuc-cockpit .nuc-todo-div{height:1px;background:var(--hair);margin:0 13px}
|
||
|
||
/* triage badge — classic/urgency labels (Critical/High/Medium/Low): a hued
|
||
dot in a tinted capsule, the word in secondary (TriageBadge, encouraging=off) */
|
||
.nuc-cockpit .tri{display:inline-flex;align-items:center;gap:5px;flex:none;font-size:10.5px;font-weight:600;color:var(--tx2);padding:3px 8px;border-radius:999px;white-space:nowrap}
|
||
.nuc-cockpit .tri .d{width:7px;height:7px;border-radius:50%;flex:none}
|
||
.nuc-cockpit .tri-crit{background:color-mix(in srgb,var(--red) 14%,transparent);border:1px solid color-mix(in srgb,var(--red) 35%,transparent)}
|
||
.nuc-cockpit .tri-crit .d{background:var(--red)}
|
||
.nuc-cockpit .tri-high{background:color-mix(in srgb,#f1872f 14%,transparent);border:1px solid color-mix(in srgb,#f1872f 35%,transparent)}
|
||
.nuc-cockpit .tri-high .d{background:#f1872f}
|
||
.nuc-cockpit .tri-med{background:color-mix(in srgb,#e3b324 16%,transparent);border:1px solid color-mix(in srgb,#e3b324 40%,transparent)}
|
||
.nuc-cockpit .tri-med .d{background:#e3b324}
|
||
.nuc-cockpit .tri-low{background:color-mix(in srgb,#9a9aa2 16%,transparent);border:1px solid color-mix(in srgb,#9a9aa2 40%,transparent)}
|
||
.nuc-cockpit .tri-low .d{background:#9a9aa2}
|
||
|
||
.nuc-cockpit .nuc-dispatch{
|
||
display:inline-flex;align-items:center;gap:6px;flex:none;
|
||
background:var(--lav);color:#fff;border-radius:8px;padding:6px 11px;font-size:12px;font-weight:600;
|
||
}
|
||
|
||
/* ---- chat bar (composer) ---- */
|
||
.nuc-cockpit .nuc-divider{height:1px;background:var(--hair)}
|
||
.nuc-cockpit .nuc-chatbar{padding:9px 14px 10px;display:flex;flex-direction:column;gap:7px;flex:none}
|
||
/* wrap (not clip) the chip/status row when the composer narrows */
|
||
.nuc-cockpit .nuc-chiprow{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:12.5px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-chip{display:inline-flex;align-items:center;gap:5px;background:var(--surface);border:1px solid var(--hair);border-radius:7px;padding:4px 9px;color:var(--tx)}
|
||
.nuc-cockpit .nuc-chip svg{width:12px;height:12px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-chip .chev{color:var(--tx3)}
|
||
.nuc-cockpit .nuc-statuspill{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-statuspill .dot{width:7px;height:7px;border-radius:50%;background:var(--green)}
|
||
.nuc-cockpit .nuc-field{
|
||
display:flex;align-items:center;gap:10px;
|
||
background:var(--field);border-radius:9px;padding:9px 12px;
|
||
/* persistent lavender ring — the Nucleic Control cue (HomeView composer) */
|
||
box-shadow:0 0 0 1px color-mix(in srgb,var(--lav) 55%, transparent);
|
||
}
|
||
.nuc-cockpit .nuc-field .ph{flex:1;color:var(--tx3);font-size:13px}
|
||
.nuc-cockpit .nuc-field .send{color:var(--tx2)}
|
||
.nuc-cockpit .nuc-ctrls{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
|
||
.nuc-cockpit .nuc-pill{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--hair);border-radius:7px;padding:4px 9px;font-size:12px;color:var(--tx2)}
|
||
.nuc-cockpit .nuc-pill svg{width:12px;height:12px}
|
||
.nuc-cockpit .nuc-pill.accent{color:var(--lav);border-color:color-mix(in srgb,var(--lav) 45%,transparent)}
|
||
.nuc-cockpit .nuc-pill.right{margin-left:auto}
|
||
.nuc-cockpit .nuc-pill .chev{color:var(--tx3)}
|
||
|
||
/* ---- responsive ---- */
|
||
@media (max-width:860px){
|
||
/* single column: drop the sidebar and let the window grow to its natural height —
|
||
the page scrolls, so no internal scroll/clip is wanted here */
|
||
.nuc-cockpit .nuc-body{grid-template-columns:1fr;height:auto}
|
||
.nuc-cockpit .nuc-side{display:none}
|
||
.nuc-cockpit .nuc-scroll{overflow:visible}
|
||
}
|
||
@media (max-width:680px){
|
||
.nuc-cockpit .nuc-dash{grid-template-columns:1fr;gap:16px}
|
||
.nuc-cockpit .nuc-tiles{grid-template-columns:repeat(3,1fr)}
|
||
.nuc-cockpit .nuc-tile:nth-child(4),.nuc-cockpit .nuc-tile:nth-child(5){display:none}
|
||
.nuc-cockpit .nuc-grid i{width:13px;height:13px}
|
||
}
|
||
|
||
/* ===== iPhone app surface (data-nuc-ios) — shown in place of the Mac cockpit on
|
||
mobile. Faithful web port of the iOS app's Home tab (ios/NucleicRemote); scoped
|
||
under .nuc-ios with its own variables. Standalone source: cockpit-mobile.html. = */
|
||
.nuc-ios{
|
||
/* Surfaces — iOS light system colors (UX_IOS / Theme.swift CardBackground) */
|
||
--bg:#ffffff; /* systemBackground — the Home ScrollView */
|
||
--card:#f2f2f7; /* secondarySystemBackground — .card() surfaces */
|
||
--field:#ffffff; /* .roundedBorder text field fill */
|
||
--hair:rgba(0,0,0,.07); /* Color.primary.opacity(.06) card hairline */
|
||
--field-hair:rgba(0,0,0,.16);
|
||
--tabbar:rgba(249,249,249,.94);
|
||
|
||
/* Text — iOS semantic label tiers (light) */
|
||
--label:#000000; /* UIColor.label */
|
||
--label2:rgba(60,60,67,.6); /* secondaryLabel */
|
||
--label3:rgba(60,60,67,.3); /* tertiaryLabel */
|
||
--tab-off:#999a9f; /* unselected tab item */
|
||
|
||
/* Palette.swift — the mobile categorical palette (exact sRGB) */
|
||
--accent:#0a8580; /* deep teal — Palette.accent (.04,.52,.50) */
|
||
--active:#338cf2; /* blue — running (.20,.55,.95) */
|
||
--attention:#ffa626;/* amber — awaiting approval (1,.65,.15) */
|
||
--success:#4dcc73; /* green — finished/done (.30,.80,.45) */
|
||
--paused:#9e7ded; /* purple — interrupted (.62,.49,.93) */
|
||
--danger:#eb5757; /* red — error / badge (.92,.34,.34) */
|
||
--frozen:#42a3f5; /* iced streak-freeze blue (.26,.64,.96) */
|
||
--orchestra:#e6a829;/* orchestra gold (.90,.66,.16) */
|
||
|
||
/* ActivityGrid shades — Palette.activity(intensity): success.opacity(i),
|
||
empty = secondary.opacity(.15) */
|
||
--a0:#e3e3e8;
|
||
--a1:rgba(77,204,115,.4);
|
||
--a2:rgba(77,204,115,.65);
|
||
--a3:rgba(77,204,115,.82);
|
||
--a4:#4dcc73;
|
||
|
||
--mono:"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
||
|
||
/* surface geometry — a borderless app card (no device frame); sizes to its
|
||
content with scrolling locked (the page scrolls); fits any viewport (max-width:100%) */
|
||
--w:360px;
|
||
|
||
font-family:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, "Space Grotesk", Arial, sans-serif;
|
||
color:var(--label);
|
||
display:flex;justify-content:center;
|
||
/* illustrative chrome — keep its text unselectable */
|
||
-webkit-user-select:none;user-select:none;
|
||
}
|
||
.nuc-ios *{box-sizing:border-box}
|
||
.nuc-ios svg{display:block}
|
||
|
||
/* ---- borderless app surface (framed like the desktop cockpit — no device
|
||
bezel, status bar, Dynamic Island, or home indicator; this already renders
|
||
on a phone) ------------------------------------------------------------- */
|
||
.nuc-ios .ios-phone{
|
||
position:relative;
|
||
width:var(--w);max-width:100%; /* height: natural (content-sized) */
|
||
display:flex;flex-direction:column;
|
||
background:var(--bg);
|
||
border:1px solid var(--hair);
|
||
border-radius:16px;overflow:hidden;
|
||
box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
|
||
0 30px 70px -40px rgba(40,30,50,.40);
|
||
}
|
||
|
||
/* ---- Home content (no title bar — content starts at the top; scrolling locked,
|
||
the surface sizes to its content and the page scrolls) --------------------- */
|
||
.nuc-ios .ios-content{
|
||
padding:22px 16px 120px; /* bottom room for the chip + tab bar */
|
||
display:flex;flex-direction:column;gap:22px;
|
||
}
|
||
|
||
/* greeting + streak (HomeView header HStack) */
|
||
.nuc-ios .ios-hi{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
|
||
.nuc-ios .ios-hi h1{margin:0;font-size:27px;font-weight:700;letter-spacing:-.02em;line-height:1.05}
|
||
.nuc-ios .ios-hi .sub{margin:5px 0 0;font-size:14px;color:var(--label2)}
|
||
.nuc-ios .ios-streak{
|
||
flex:none;display:inline-flex;align-items:center;gap:7px;
|
||
background:var(--card);border-radius:999px;padding:7px 11px;
|
||
}
|
||
.nuc-ios .ios-streak .bolt{color:var(--frozen);filter:drop-shadow(0 0 4px rgba(66,163,245,.5))}
|
||
.nuc-ios .ios-streak .col{display:flex;flex-direction:column;line-height:1}
|
||
.nuc-ios .ios-streak .n{font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}
|
||
.nuc-ios .ios-streak .lbl{font-size:10px;color:var(--label2);margin-top:2px}
|
||
.nuc-ios .ios-streak .fz{display:inline-flex;align-items:center;gap:2px;color:var(--frozen);font-size:12px;font-weight:600}
|
||
.nuc-ios .ios-streak .fz svg{width:12px;height:12px}
|
||
|
||
/* StatCard row — five across, like HomeView.statCards (tight at phone width,
|
||
exactly as the app is; labels wrap like SwiftUI Text, value never wraps) */
|
||
.nuc-ios .ios-stats{display:flex;gap:7px;align-items:stretch}
|
||
.nuc-ios .ios-stat{
|
||
flex:1 1 0;min-width:0;
|
||
background:var(--card);border:1px solid var(--hair);border-radius:13px;
|
||
padding:8px 7px;display:flex;flex-direction:column;gap:3px;
|
||
}
|
||
.nuc-ios .ios-stat .ic{color:var(--accent)}
|
||
.nuc-ios .ios-stat .ic svg{width:15px;height:15px}
|
||
.nuc-ios .ios-stat .n{font-size:15px;font-weight:600;font-family:var(--mono);letter-spacing:-.03em;white-space:nowrap}
|
||
.nuc-ios .ios-stat .l{font-size:9.5px;line-height:1.12;color:var(--label2);overflow-wrap:break-word}
|
||
|
||
/* a .card() block (CardBackground modifier) */
|
||
.nuc-ios .ios-card{background:var(--card);border:1px solid var(--hair);border-radius:14px;padding:14px}
|
||
.nuc-ios .ios-card-h{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
|
||
.nuc-ios .ios-card-h .h{font-size:16px;font-weight:600;letter-spacing:-.01em}
|
||
.nuc-ios .ios-card-h .cnt{font-size:15px;color:var(--label2);font-variant-numeric:tabular-nums}
|
||
|
||
/* ActivityGrid (no legend on iOS — just the grid) */
|
||
.nuc-ios .ios-grid{display:flex;gap:3px;flex-wrap:nowrap;overflow:hidden}
|
||
.nuc-ios .ios-grid .col{display:flex;flex-direction:column;gap:3px}
|
||
.nuc-ios .ios-grid i{width:13px;height:13px;border-radius:2px;background:var(--a0);display:block}
|
||
.nuc-ios .ios-grid i.l1{background:var(--a1)} .nuc-ios .ios-grid i.l2{background:var(--a2)}
|
||
.nuc-ios .ios-grid i.l3{background:var(--a3)} .nuc-ios .ios-grid i.l4{background:var(--a4)}
|
||
.nuc-ios .ios-grid i.fz{background:var(--frozen)}
|
||
|
||
/* SessionRow */
|
||
.nuc-ios .ios-srow{display:flex;align-items:center;gap:12px;padding:3px 0}
|
||
.nuc-ios .ios-srow .sym{width:24px;flex:none;display:flex;justify-content:center}
|
||
.nuc-ios .ios-srow .sym svg{width:21px;height:21px}
|
||
.nuc-ios .ios-srow .sc{flex:1;min-width:0}
|
||
.nuc-ios .ios-srow .st{font-size:16px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nuc-ios .ios-srow .sp{font-size:12px;color:var(--label2);margin-top:1px}
|
||
.nuc-ios .ios-srow .diff{font-size:12px;font-family:var(--mono);color:var(--label2);flex:none}
|
||
|
||
/* QuickTodos */
|
||
.nuc-ios .ios-capture{display:flex;align-items:center;gap:10px;margin-bottom:10px}
|
||
.nuc-ios .ios-input{
|
||
flex:1;min-width:0;background:var(--field);border:1px solid var(--field-hair);border-radius:8px;
|
||
padding:8px 11px;font-size:14px;color:var(--label3);
|
||
}
|
||
.nuc-ios .ios-addbtn{color:var(--accent);flex:none;display:flex}
|
||
.nuc-ios .ios-addbtn svg{width:24px;height:24px}
|
||
.nuc-ios .ios-todo{display:flex;align-items:center;gap:10px;padding:6px 0}
|
||
.nuc-ios .ios-todo .box{color:var(--label3);flex:none;display:flex}
|
||
.nuc-ios .ios-todo .box svg{width:18px;height:18px}
|
||
.nuc-ios .ios-todo .tt{flex:1;min-width:0;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.nuc-ios .ios-todo .pn{font-size:11px;color:var(--label2);flex:none}
|
||
|
||
/* StartChatComposer */
|
||
.nuc-ios .ios-comp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:10px}
|
||
.nuc-ios .ios-menu{display:inline-flex;align-items:center;gap:5px;font-size:14px;color:var(--label)}
|
||
.nuc-ios .ios-menu svg{width:15px;height:15px;color:var(--label2)}
|
||
.nuc-ios .ios-tint{display:inline-flex;align-items:center;gap:4px;font-size:13px;color:var(--accent);font-weight:500}
|
||
.nuc-ios .ios-tint svg{width:14px;height:14px}
|
||
.nuc-ios .ios-tint .badge{color:var(--label3);font-weight:400}
|
||
.nuc-ios .ios-auto{
|
||
display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--label2);
|
||
border:1px solid var(--field-hair);border-radius:8px;padding:5px 9px;font-weight:500;
|
||
}
|
||
.nuc-ios .ios-auto svg{width:14px;height:14px}
|
||
.nuc-ios .ios-comp-field{display:flex;align-items:flex-end;gap:8px}
|
||
.nuc-ios .ios-comp-field .ios-input{padding:10px 12px;font-size:15px}
|
||
.nuc-ios .ios-send{color:var(--accent);flex:none;display:flex}
|
||
.nuc-ios .ios-send svg{width:30px;height:30px}
|
||
|
||
/* ConnectionChip — floating, pinned above the tab bar */
|
||
.nuc-ios .ios-chip{
|
||
position:absolute;left:50%;bottom:72px;transform:translateX(-50%);z-index:5;
|
||
display:inline-flex;align-items:center;gap:6px;
|
||
background:rgba(255,255,255,.74);
|
||
-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
|
||
border:1px solid var(--hair);border-radius:999px;padding:6px 12px;
|
||
font-size:13px;font-weight:500;color:var(--label);
|
||
box-shadow:0 6px 18px -10px rgba(0,0,0,.35);
|
||
}
|
||
.nuc-ios .ios-chip .dot{width:8px;height:8px;border-radius:50%;background:#34c759}
|
||
|
||
/* ---- tab bar (RootView TabView) ------------------------------------------- */
|
||
.nuc-ios .ios-tabbar{
|
||
position:absolute;left:0;right:0;bottom:0;z-index:4;
|
||
display:flex;align-items:center;padding:6px 6px;height:60px;
|
||
background:var(--tabbar);
|
||
-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
|
||
border-top:1px solid var(--hair);
|
||
}
|
||
.nuc-ios .ios-tab{
|
||
flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
|
||
color:var(--tab-off);position:relative;
|
||
}
|
||
.nuc-ios .ios-tab svg{width:25px;height:25px}
|
||
.nuc-ios .ios-tab .tl{font-size:10px;font-weight:500;letter-spacing:.01em}
|
||
.nuc-ios .ios-tab.on{color:var(--accent)}
|
||
.nuc-ios .ios-tab .tbadge{
|
||
position:absolute;top:-3px;left:calc(50% + 7px);
|
||
min-width:16px;height:16px;padding:0 4px;border-radius:999px;
|
||
background:var(--danger);color:#fff;font-size:10px;font-weight:700;
|
||
display:flex;align-items:center;justify-content:center;font-variant-numeric:tabular-nums;
|
||
}
|
||
|
||
/* ===== device swap: desktop shows the Mac cockpit, mobile shows the iPhone app.
|
||
860px matches the cockpit's own sidebar-drop breakpoint. ==================== */
|
||
.nuc-ios{display:none} /* hide the phone on desktop (overrides display:flex above) */
|
||
.showcase .cap-mobile{display:none} /* phone caption hidden on desktop */
|
||
@media (max-width:860px){
|
||
.showcase .nuc-cockpit{display:none} /* hide the Mac window… */
|
||
.nuc-ios{display:flex} /* …and show the phone instead */
|
||
.showcase .cap-desktop{display:none}
|
||
.showcase .cap-mobile{display:inline}
|
||
}
|
||
|
||
/* ---------- supported agents ---------- */
|
||
.agents{padding:6px 0 48px}
|
||
.agents .ak{text-align:center}
|
||
.agent-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:9px;margin-top:16px}
|
||
.ach{font-size:14px;border:1px solid var(--line);background:var(--panel);border-radius:999px;padding:7px 14px;color:var(--ink);white-space:nowrap;text-align:center}
|
||
.ach.any{background:transparent;color:var(--ink-faint);border-style:dashed}
|
||
.agent-any{text-align:center;margin-top:14px}
|
||
/* On phones, lay pills out 3 equal columns per line: the middle pill (and its
|
||
centered text) lands on the page's center axis, and a leftover row centers too. */
|
||
@media (max-width:600px){
|
||
.agent-chips{gap:8px}
|
||
.agent-chips .ach{flex:0 0 calc((100% - 16px)/3);font-size:12px;padding:7px 8px}
|
||
}
|
||
|
||
/* ---------- features ---------- */
|
||
.features{padding:52px 0 24px}
|
||
.sechead{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:30px;flex-wrap:wrap}
|
||
.sechead h2{font-size:clamp(24px,3.4vw,34px);font-weight:600;letter-spacing:-.025em;margin:8px 0 0;max-width:18ch}
|
||
.sechead p{margin:0;color:var(--ink-soft);max-width:34ch;font-size:15px}
|
||
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line-2);border:1px solid var(--line-2);border-radius:14px;overflow:hidden}
|
||
@media (max-width:860px){.grid{grid-template-columns:repeat(2,1fr)}}
|
||
@media (max-width:560px){.grid{grid-template-columns:1fr}}
|
||
.card{background:var(--panel);padding:24px 22px 26px;position:relative;transition:background .15s ease}
|
||
.card:hover{background:var(--panel-2)}
|
||
.card .no{font-family:var(--mono);font-size:11px;color:var(--ink-faint)}
|
||
.card .accent{position:absolute;top:24px;right:22px;width:22px;height:22px}
|
||
.card h3{font-size:17px;font-weight:600;letter-spacing:-.01em;margin:16px 0 7px}
|
||
.card p{margin:0;color:var(--ink-soft);font-size:14px;line-height:1.55}
|
||
.card .beta{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--magenta);border:1px solid color-mix(in srgb,var(--magenta) 35%,transparent);border-radius:999px;padding:2px 6px;margin-left:8px;vertical-align:middle}
|
||
.card .gold{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 45%,transparent)}
|
||
|
||
/* ---------- native to Apple ---------- */
|
||
.native{padding:34px 0 10px}
|
||
.native .head{max-width:52ch;margin:0 0 28px}
|
||
.native .head h2{font-size:clamp(24px,3.4vw,34px);font-weight:600;letter-spacing:-.025em;margin:8px 0 12px}
|
||
.native .head h2 .em{
|
||
background:linear-gradient(100deg,var(--rust),var(--pink) 45%,var(--magenta) 70%,var(--blue));
|
||
-webkit-background-clip:text;background-clip:text;color:transparent;
|
||
}
|
||
.native .head p{margin:0;color:var(--ink-soft);font-size:15.5px;max-width:50ch}
|
||
.native-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
|
||
@media (max-width:760px){.native-grid{grid-template-columns:1fr}}
|
||
.ncard{border:1px solid var(--line);border-radius:14px;background:var(--panel);padding:22px 20px}
|
||
.ncard .ic{width:24px;height:24px;display:block;margin-bottom:14px}
|
||
.ncard h3{font-size:16px;font-weight:600;letter-spacing:-.01em;margin:0 0 6px}
|
||
.ncard p{margin:0;color:var(--ink-soft);font-size:13.5px;line-height:1.55}
|
||
.native .foot-note{margin:22px 0 0;font-family:var(--mono);font-size:12px;color:var(--ink-faint);text-align:center}
|
||
|
||
/* ---------- trust line (inside the access card) ---------- */
|
||
.panel-trust{max-width:80ch;margin:22px auto 0;font-size:12.5px;color:var(--ink-soft);letter-spacing:.01em;line-height:1.6}
|
||
|
||
/* ---------- access / footer ---------- */
|
||
.access{padding:88px 0}
|
||
.access .panel{
|
||
border:1px solid var(--line);border-radius:18px;background:
|
||
radial-gradient(120% 140% at 0% 0%, color-mix(in srgb,var(--blue) 9%,transparent), transparent 42%),
|
||
radial-gradient(120% 140% at 100% 100%, color-mix(in srgb,var(--pink) 9%,transparent), transparent 42%),
|
||
var(--panel);
|
||
padding:48px 40px;text-align:center;
|
||
}
|
||
.access h2{font-size:clamp(26px,3.8vw,38px);font-weight:600;letter-spacing:-.025em;margin:10px 0 0}
|
||
.access p{color:var(--ink-soft);margin:14px auto 0;max-width:40ch;font-size:15.5px}
|
||
.access .cta-row{justify-content:center}
|
||
|
||
footer{border-top:1px solid var(--line-2);padding:30px 0 50px}
|
||
.foot{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;color:var(--ink-faint);font-size:13px}
|
||
.foot .mono{font-size:12px}
|
||
.foot-end{display:flex;flex-direction:column;align-items:flex-end;gap:4px;text-align:right}
|
||
.foot-links{display:flex;gap:18px;flex-wrap:wrap}
|
||
.foot-links a{text-decoration:none;color:var(--ink-soft)}
|
||
.foot-links a:hover{color:var(--ink)}
|
||
@media (max-width:720px){
|
||
/* Left-align the footer: Nucleic + Privacy/Terms stay on one line,
|
||
the copyright/Made-with stack drops to its own line under the brand. */
|
||
.foot{justify-content:flex-start}
|
||
.foot-end{flex-basis:100%;align-items:flex-start;text-align:left}
|
||
}
|
||
.dotsep{color:var(--line)}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<script>
|
||
// Keep refresh anchored to the top. The browser's automatic scroll
|
||
// restoration can land mid-page on reload (the cockpit mockup's inner
|
||
// scroll panel + late layout shifts from the grid-building script), and
|
||
// there are no in-page hash links that need restoration — so disable it
|
||
// and pin to the top on load (honoring an explicit #hash if one is ever used).
|
||
if ("scrollRestoration" in history) history.scrollRestoration = "manual";
|
||
window.addEventListener("pageshow", function () {
|
||
if (!location.hash) window.scrollTo(0, 0);
|
||
});
|
||
</script>
|
||
|
||
<!-- ===== top bar ===== -->
|
||
<header>
|
||
<div class="wrap bar">
|
||
<div class="brand">
|
||
<svg class="mk" viewBox="0 0 100 100" aria-hidden="true">
|
||
<g fill="none" stroke-width="7">
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(80 50 50)" stroke="#7AA7DD"/>
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(20 50 50)" stroke="#DF619B"/>
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(140 50 50)" stroke="#C5826F"/>
|
||
</g>
|
||
</svg>
|
||
Nucleic
|
||
<span class="tag">Beta</span>
|
||
</div>
|
||
<nav class="nav">
|
||
<div id="nav-dl" class="dl">
|
||
<a class="btn" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">Download for Apple Silicon</a>
|
||
<button class="dl-toggle" type="button" aria-label="Choose a version" aria-haspopup="true" aria-expanded="false">
|
||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg>
|
||
</button>
|
||
<div class="dl-menu right" role="menu">
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Beta <span class="dl-lbl beta">Recommended</span></span>
|
||
<span class="d">The public beta — best for everyday use.</span>
|
||
</a>
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/canary/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Canary <span class="dl-lbl canary">Bleeding edge</span></span>
|
||
<span class="d">The newest builds, shipped continuously. Expect rough edges.</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ===== hero ===== -->
|
||
<section class="hero">
|
||
<div class="wrap hero-grid">
|
||
<div>
|
||
<span class="hero-badge">Built for macOS 27</span>
|
||
<h1>Run a fleet of<br/>coding agents.<br/><span class="em">Stay in command.</span></h1>
|
||
<p class="sub">Nucleic runs Claude Code, Codex, and Grok Build — or any ACP-compatible agent — in parallel, each isolated and observed down to the edit, with one Mac cockpit to watch, approve, and merge their work.</p>
|
||
<div class="cta-row">
|
||
<div class="dl">
|
||
<a id="hero-dl" class="btn" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">Download for Apple Silicon</a>
|
||
<button class="dl-toggle" type="button" aria-label="Choose a version" aria-haspopup="true" aria-expanded="false">
|
||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg>
|
||
</button>
|
||
<div class="dl-menu" role="menu">
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Beta <span class="dl-lbl beta">Recommended</span></span>
|
||
<span class="d">The public beta — best for everyday use.</span>
|
||
</a>
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/canary/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Canary <span class="dl-lbl canary">Bleeding edge</span></span>
|
||
<span class="d">The newest builds, shipped continuously. Expect rough edges.</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cta-row"><span class="cta-note">No account required · private by design · runs offline</span></div>
|
||
</div>
|
||
|
||
<div class="atom-wrap">
|
||
<!-- the brand atom: agents (nodes) orbiting one nucleus of control -->
|
||
<svg class="atom" viewBox="0 0 400 400" xmlns:xlink="http://www.w3.org/1999/xlink" role="img" aria-label="Coding agents orbiting one point of control">
|
||
<defs>
|
||
<!-- Motion paths start at the local origin (0,0); each dot's cx/cy
|
||
offsets it onto the orbit (200,200 centre, 140×58 ellipse).
|
||
Keeping the dot's static cx/cy equal to the path's t=0 point
|
||
means there is no jump before SMIL produces its first sample on
|
||
load — otherwise a cx/cy-less dot paints at (0,0) and, after the
|
||
group's rotate() about (200,200), flashes in the upper-right. -->
|
||
<path id="oA" d="M 0,0 a 140,58 0 1,0 280,0 a 140,58 0 1,0 -280,0"/>
|
||
<path id="oB" d="M 0,0 a 140,58 0 1,0 280,0 a 140,58 0 1,0 -280,0"/>
|
||
<path id="oC" d="M 0,0 a 140,58 0 1,0 280,0 a 140,58 0 1,0 -280,0"/>
|
||
</defs>
|
||
|
||
<g class="sys">
|
||
<!-- blue orbit -->
|
||
<g transform="rotate(80 200 200)">
|
||
<ellipse class="ring" cx="200" cy="200" rx="140" ry="58" stroke="#5e9bd8"/>
|
||
<circle class="node dot" cx="60" cy="200" r="8" fill="#5e9bd8">
|
||
<animateMotion dur="13s" repeatCount="indefinite"><mpath xlink:href="#oA" href="#oA"/></animateMotion>
|
||
</circle>
|
||
</g>
|
||
<!-- pink orbit -->
|
||
<g transform="rotate(20 200 200)">
|
||
<ellipse class="ring" cx="200" cy="200" rx="140" ry="58" stroke="#db5f97"/>
|
||
<circle class="node dot" cx="60" cy="200" r="8" fill="#db5f97">
|
||
<animateMotion dur="17s" begin="-6s" repeatCount="indefinite"><mpath xlink:href="#oB" href="#oB"/></animateMotion>
|
||
</circle>
|
||
</g>
|
||
<!-- rust orbit -->
|
||
<g transform="rotate(140 200 200)">
|
||
<ellipse class="ring" cx="200" cy="200" rx="140" ry="58" stroke="#c47e69"/>
|
||
<circle class="node dot" cx="60" cy="200" r="8" fill="#c47e69">
|
||
<animateMotion dur="21s" begin="-3s" repeatCount="indefinite"><mpath xlink:href="#oC" href="#oC"/></animateMotion>
|
||
</circle>
|
||
</g>
|
||
</g>
|
||
|
||
<circle class="nucleus" cx="200" cy="200" r="9"/>
|
||
<circle cx="200" cy="200" r="16" fill="none" stroke="#181520" stroke-width="1.5" opacity=".25"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== supported agents ===== -->
|
||
<section class="agents">
|
||
<div class="wrap">
|
||
<div class="kicker ak">Supported agents</div>
|
||
<div class="agent-chips">
|
||
<span class="ach">Claude Code</span>
|
||
<span class="ach">Codex</span>
|
||
<span class="ach">Grok Build</span>
|
||
<span class="ach">OpenCode</span>
|
||
<span class="ach">Hermes Agent</span>
|
||
<span class="ach">Cursor Agent</span>
|
||
<span class="ach">OpenClaw</span>
|
||
</div>
|
||
<div class="agent-any"><span class="ach any">+ any ACP-compatible agent</span></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== premise ===== -->
|
||
<section class="band" id="how">
|
||
<div class="wrap">
|
||
<h2 class="lede">Agents got fast. <em>You</em> became the bottleneck.</h2>
|
||
<p>One agent per terminal means you babysit one task at a time. Run several by hand and they collide — same files, same branch, same working dir.</p>
|
||
<p>Nucleic gives every session its own real git worktree and branch. <strong>Infinite agents, zero collisions</strong> — each reviewed and merged, automatically.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== app window mock (faithful to the real UI) ===== -->
|
||
<section class="showcase">
|
||
<div class="wrap">
|
||
<div class="nuc-cockpit" aria-label="The Nucleic cockpit — home dashboard with the Control panel open">
|
||
|
||
<!-- title bar -->
|
||
<div class="nuc-titlebar">
|
||
<span class="nuc-lights"><i></i><i></i><i></i></span>
|
||
<span class="nuc-tbar">
|
||
<!-- Toggle Sidebar (sidebar.leading) -->
|
||
<span class="nuc-tbtn" title="Toggle Sidebar"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><rect x="3" y="4.5" width="18" height="15" rx="2.5"/><path d="M9 4.5v15"/></svg></span>
|
||
<!-- Home (house) — back to the dashboard -->
|
||
<span class="nuc-tbtn" title="Home"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 11.5 12 4l8.5 7.5"/><path d="M5.5 10v9h13v-9"/></svg></span>
|
||
<!-- Add Project (folder.badge.plus) -->
|
||
<span class="nuc-tbtn" title="Add Project"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M12 10.5v5M9.5 13h5"/></svg></span>
|
||
</span>
|
||
<span class="nuc-wtitle">Nucleic</span>
|
||
</div>
|
||
|
||
<div class="nuc-body">
|
||
|
||
<!-- ===================== SIDEBAR (Control tab active) ================== -->
|
||
<aside class="nuc-side">
|
||
|
||
<!-- mode switcher -->
|
||
<div class="nuc-switch">
|
||
<span class="nuc-seg">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 1.8"/></svg>
|
||
Recents
|
||
</span>
|
||
<span class="nuc-seg">
|
||
<!-- sparkles (Apple Intelligence) — enlarged so the stars read clearly -->
|
||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.5 1.8c.45 4.3 1.7 5.55 6 6-4.3.45-5.55 1.7-6 6-.45-4.3-1.7-5.55-6-6 4.3-.45 5.55-1.7 6-6z"/><path d="M18.5 12.5c.25 2.35.95 3.05 3.3 3.3-2.35.25-3.05.95-3.3 3.3-.25-2.35-.95-3.05-3.3-3.3 2.35-.25 3.05-.95 3.3-3.3z"/></svg>
|
||
Queue
|
||
</span>
|
||
<span class="nuc-seg on">
|
||
<!-- atom — the Control glyph, same mark Control projects carry -->
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="1.7" fill="currentColor" stroke="none"/><ellipse cx="12" cy="12" rx="10" ry="4.2"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(120 12 12)"/></svg>
|
||
Control
|
||
</span>
|
||
</div>
|
||
|
||
<!-- pane header: atom accent + one-line health rollup + Release All -->
|
||
<div class="nuc-pane-head">
|
||
<div class="nuc-pane-row">
|
||
<svg class="nuc-acc" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="1.7" fill="currentColor" stroke="none"/><ellipse cx="12" cy="12" rx="10" ry="4.2"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(120 12 12)"/></svg>
|
||
<span class="nuc-sum">Container running · 2 holding 1 file · 1 shipping</span>
|
||
<span class="nuc-relall">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V7a4 4 0 0 1 7-2.6"/></svg>
|
||
Release All
|
||
</span>
|
||
</div>
|
||
<div class="nuc-rule"></div>
|
||
</div>
|
||
|
||
<div class="nuc-pane-body">
|
||
|
||
<!-- Container -->
|
||
<div>
|
||
<div class="nuc-sec-t">Container</div>
|
||
<div class="nuc-crow">
|
||
<span class="nuc-dot green"></span>
|
||
<span class="nuc-ct"><div class="nm">Shared</div><div class="sub">nucleic-control-shared</div></span>
|
||
<span class="nuc-trail">4 active</span>
|
||
</div>
|
||
<div class="nuc-meter"><span class="k">CPU</span><span class="trk"><i style="width:23%;background:var(--green)"></i></span><span class="pct">23%</span></div>
|
||
<div class="nuc-meter"><span class="k">RAM</span><span class="trk"><i style="width:16%;background:var(--green)"></i></span><span class="pct">16%</span></div>
|
||
</div>
|
||
|
||
<!-- Autoship -->
|
||
<div>
|
||
<div class="nuc-sec-t">Autoship</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-tx2"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M3 7l9-4 9 4-9 4-9-4z"/><path d="M3 7v10l9 4 9-4V7M12 11v10"/></svg></span>
|
||
<span class="it"><div class="t">Refine composer glow</div><div class="s">Armed → nucleic/trunk</div></span>
|
||
</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-amber"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 1.8"/></svg></span>
|
||
<span class="it"><div class="t">Display version info</div><div class="s">Next to ship → nucleic/trunk</div></span>
|
||
</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-lav"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M7 4v7a5 5 0 0 0 5 5h5"/><circle cx="7" cy="4" r="2"/><circle cx="17" cy="16" r="2"/></svg></span>
|
||
<span class="it"><div class="t">Generate concept content</div><div class="s">Merging → nucleic/trunk…</div></span>
|
||
</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-green"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 2.6l2.1 1.6 2.6.1.8 2.5 2.2 1.5-.9 2.5.9 2.5-2.2 1.5-.8 2.5-2.6.1L12 21.4l-2.1-1.6-2.6-.1-.8-2.5-2.2-1.5.9-2.5-.9-2.5 2.2-1.5.8-2.5 2.6-.1z"/><path d="M9 12l2 2 4-4"/></svg></span>
|
||
<span class="it"><div class="t">Image file review</div><div class="s">Shipped → nucleic/trunk · 4f3bf3e</div></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- File locks -->
|
||
<div>
|
||
<div class="nuc-sec-t">File locks</div>
|
||
<div class="nuc-lrow">
|
||
<span class="gl tint-green"><svg viewBox="0 0 24 24" fill="currentColor"><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4" fill="none" stroke="currentColor" stroke-width="2"/></svg></span>
|
||
<span class="it"><div class="t">AppTheme.swift</div><div class="s">Refine composer glow</div></span>
|
||
<span class="nuc-release">Release</span>
|
||
</div>
|
||
<div class="nuc-lrow wait">
|
||
<span class="gl tint-amber"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M6 3h12M6 21h12"/><path d="M8 3c0 4 8 5.5 8 9s-8 5-8 9M16 3c0 4-8 5.5-8 9s8 5 8 9"/></svg></span>
|
||
<span class="it"><div class="t">AppTheme.swift</div><div class="s">Tune sidebar accents</div></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Activity (git-interceptor feed) -->
|
||
<div>
|
||
<div class="nuc-sec-t">Activity</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-tx2"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M7 4v7a5 5 0 0 0 5 5h5"/><circle cx="7" cy="4" r="2"/><circle cx="17" cy="16" r="2"/></svg></span>
|
||
<span class="it"><div class="t">Merge → nucleic/trunk</div><div class="s">Generate concept content</div></span>
|
||
<span class="when">2m</span>
|
||
</div>
|
||
<div class="nuc-irow">
|
||
<span class="gl tint-tx2"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="3"/><path d="M3 12h6M15 12h6"/></svg></span>
|
||
<span class="it"><div class="t">Commit · 3 files</div><div class="s">Image file review</div></span>
|
||
<span class="when">8m</span>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- project tree: the always-present per-project chat list below the pane -->
|
||
<div class="nuc-tree">
|
||
<div class="nuc-proj">
|
||
<span class="pname">nucleic</span>
|
||
<!-- atom (Control) + infinity (nvrsion) badges + open chevron -->
|
||
<svg class="lav" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="1.7" fill="currentColor" stroke="none"/><ellipse cx="12" cy="12" rx="10" ry="4.2"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(60 12 12)"/><ellipse cx="12" cy="12" rx="10" ry="4.2" transform="rotate(120 12 12)"/></svg>
|
||
<svg class="lav" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12c0-2 1.5-3.4 3.5-3.4S12 10 12 12s1.5 3.4 3.5 3.4S19 14 19 12s-1.5-3.4-3.5-3.4S12 10 12 12s-1.5 3.4-3.5 3.4S5 14 5 12z"/></svg>
|
||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M9 6l6 6-6 6"/></svg>
|
||
<span class="sp"></span>
|
||
<!-- nvrsion "Integrate" (promote trunk → branch) -->
|
||
<svg class="integrate" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M5 4h14M12 8v12M12 8l-4 4M12 8l4 4"/></svg>
|
||
</div>
|
||
|
||
<div class="nuc-srow sel">
|
||
<span class="sdot" style="background:var(--blue)"></span>
|
||
<span class="sc">
|
||
<div class="st">Refine composer glow</div>
|
||
<div class="ss">Working<span class="b" style="color:var(--lav)"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg></span></div>
|
||
</span>
|
||
<span class="diff">+124 −18</span>
|
||
</div>
|
||
|
||
<div class="nuc-srow">
|
||
<span class="sdot" style="background:var(--blue)"></span>
|
||
<span class="sc">
|
||
<div class="st">Generate concept content</div>
|
||
<div class="ss">Working<span class="b" style="color:var(--lav)"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg></span><span class="b" style="color:var(--gold)"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M9 17.5V6l9-1.8v10" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="6.5" cy="17.5" r="2.5"/><circle cx="15.5" cy="15.7" r="2.5"/></svg></span></div>
|
||
</span>
|
||
<span class="diff">+312 −87</span>
|
||
</div>
|
||
|
||
<div class="nuc-srow">
|
||
<span class="sdot" style="background:var(--amber)"></span>
|
||
<span class="sc">
|
||
<div class="st">Display version info</div>
|
||
<div class="ss">Awaiting approval</div>
|
||
</span>
|
||
<span class="pause"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="M10 9.5v5M14 9.5v5"/></svg></span>
|
||
</div>
|
||
|
||
<div class="nuc-srow">
|
||
<span class="sdot" style="background:var(--green)"></span>
|
||
<span class="sc">
|
||
<div class="st unseen">Image file review</div>
|
||
<div class="ss">Done<span class="b" style="color:var(--lav)"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg></span></div>
|
||
</span>
|
||
<span class="diff">+40 −5</span>
|
||
<span class="udot"></span>
|
||
</div>
|
||
|
||
<div class="nuc-srow">
|
||
<span class="sglyph" style="color:var(--amber)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M6 3h12M6 21h12"/><path d="M8 3c0 4 8 5.5 8 9s-8 5-8 9M16 3c0 4-8 5.5-8 9s8 5 8 9"/></svg></span>
|
||
<span class="sc">
|
||
<div class="st">Tune sidebar accents</div>
|
||
<div class="ss">Waiting for access</div>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ===================== MAIN / HOME DASHBOARD ======================== -->
|
||
<div class="nuc-main">
|
||
<div class="nuc-scroll">
|
||
|
||
<!-- greeting + streak -->
|
||
<div class="nuc-hi">
|
||
<div>
|
||
<h1>Hi, Andrew</h1>
|
||
<p class="greet">21 active of 21 chats across 4 projects.</p>
|
||
</div>
|
||
<span class="nuc-streak">
|
||
<svg class="bolt" width="17" height="17" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>
|
||
<span class="n">15</span><span class="lbl">day streak</span>
|
||
<span class="fz">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path d="M12 2v20M3.5 7l17 10M20.5 7l-17 10"/><path d="M12 6l2.2-2.2M12 6 9.8 3.8M12 18l2.2 2.2M12 18l-2.2 2.2"/></svg>
|
||
1
|
||
</span>
|
||
</span>
|
||
</div>
|
||
|
||
<!-- activity grid + usage -->
|
||
<div class="nuc-dash">
|
||
<div>
|
||
<div class="nuc-h">Activity</div>
|
||
<div class="nuc-grid" aria-hidden="true"><!-- cells injected by the scoped script --></div>
|
||
<div class="nuc-legend">
|
||
<span>Less</span>
|
||
<i style="background:var(--c-l0)"></i><i style="background:var(--c-l1)"></i><i style="background:var(--c-l2)"></i><i style="background:var(--c-l3)"></i><i style="background:var(--c-l4)"></i>
|
||
<span>More</span>
|
||
<span class="gap"></span>
|
||
<i style="background:var(--frozen)"></i><span>Frozen</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nuc-card">
|
||
<div class="nuc-h"><svg class="ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M4 15a8 8 0 1 1 16 0"/><path d="M12 14l4-3.5"/></svg>Usage</div>
|
||
<div class="nuc-uwin">
|
||
<div class="top">
|
||
<svg class="ic" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 1.8"/></svg>
|
||
<span class="ulbl">5-hour limit</span>
|
||
<span class="up" style="color:var(--usagebar)">41%</span>
|
||
</div>
|
||
<div class="nuc-ubar"><i style="width:41%;background:var(--usagebar)"></i></div>
|
||
<div class="nuc-ucap">Resets in 2h 14m</div>
|
||
</div>
|
||
<div class="nuc-uwin">
|
||
<div class="top">
|
||
<svg class="ic" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3.5" y="5" width="17" height="15" rx="2"/><path d="M3.5 9h17M8 3v4M16 3v4"/></svg>
|
||
<span class="ulbl">Weekly limit</span>
|
||
<span class="up" style="color:var(--amber)">78%</span>
|
||
</div>
|
||
<div class="nuc-ubar"><i style="width:78%;background:var(--amber)"></i></div>
|
||
<div class="nuc-ucap">Resets Sunday</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- stat cards -->
|
||
<div class="nuc-tiles">
|
||
<div class="nuc-tile"><svg class="ic" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg><div class="n">4</div><div class="l">Projects</div></div>
|
||
<div class="nuc-tile"><svg class="ic" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M4 5h16v10H9l-4 4z"/></svg><div class="n">21</div><div class="l">Chats</div></div>
|
||
<div class="nuc-tile"><svg class="ic" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg><div class="n">21</div><div class="l">Active</div></div>
|
||
<div class="nuc-tile"><svg class="ic" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M21 3 10 14M21 3l-7 18-4-7-7-4z"/></svg><div class="n">749</div><div class="l">Messages</div></div>
|
||
<div class="nuc-tile"><svg class="ic" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M4 7h16M4 12h16M4 17h11"/></svg><div class="n">1.7B</div><div class="l">Tokens</div></div>
|
||
</div>
|
||
|
||
<!-- to-do — grouped by project, triaged (urgency labels) -->
|
||
<div class="nuc-todo-h">
|
||
<span class="h">To-Do</span>
|
||
<span class="act">
|
||
<span class="triaged"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8.5 12.2l2.4 2.4 4.6-4.8"/></svg>Triaged</span>
|
||
<span class="add">+ Add idea</span>
|
||
</span>
|
||
</div>
|
||
|
||
<div class="nuc-tg">
|
||
<div class="nuc-tg-head">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>
|
||
<span class="pn">nucleic</span><span class="cnt">2</span>
|
||
</div>
|
||
<div class="nuc-tg-card">
|
||
<div class="nuc-todo-row">
|
||
<span class="tri tri-crit"><span class="d"></span>Critical</span>
|
||
<span class="ico"><div class="t">Enable multi-account support with project-specific locks.</div></span>
|
||
<span class="nuc-dispatch"><svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M21 3 3 10.5l7 2.5 2.5 7z"/></svg>Dispatch</span>
|
||
</div>
|
||
<div class="nuc-todo-div"></div>
|
||
<div class="nuc-todo-row">
|
||
<span class="tri tri-high"><span class="d"></span>High</span>
|
||
<span class="ico"><div class="t">Add fade-in swipe animation to LLM-generated elements.</div></span>
|
||
<span class="nuc-dispatch"><svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M21 3 3 10.5l7 2.5 2.5 7z"/></svg>Dispatch</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nuc-tg">
|
||
<div class="nuc-tg-head">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>
|
||
<span class="pn">website</span><span class="cnt">1</span>
|
||
</div>
|
||
<div class="nuc-tg-card">
|
||
<div class="nuc-todo-row">
|
||
<span class="tri tri-med"><span class="d"></span>Medium</span>
|
||
<span class="ico"><div class="t">Tighten hero spacing at the mobile breakpoint.</div></span>
|
||
<span class="nuc-dispatch"><svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M21 3 3 10.5l7 2.5 2.5 7z"/></svg>Dispatch</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- chat bar -->
|
||
<div class="nuc-divider"></div>
|
||
<div class="nuc-chatbar">
|
||
<div class="nuc-chiprow">
|
||
<span class="nuc-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>nucleic<span class="chev">▾</span></span>
|
||
<span class="nuc-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="6" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="9" r="2"/><path d="M6 8v8M8 6h6a4 4 0 0 1 4 4v.5"/></svg>dev<span class="chev">▾</span></span>
|
||
<span class="nuc-statuspill"><span class="dot"></span>All providers operational</span>
|
||
</div>
|
||
<div class="nuc-field">
|
||
<span class="ph">Start a new chat…</span>
|
||
<svg class="send" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M5 12h13M13 6l6 6-6 6"/></svg>
|
||
</div>
|
||
<div class="nuc-ctrls">
|
||
<!-- Auto is locked on for Control projects (lavender) -->
|
||
<span class="nuc-pill accent"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>Auto</span>
|
||
<span class="nuc-pill accent"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M3 7l9-4 9 4-9 4-9-4z"/><path d="M3 7v10l9 4 9-4V7"/></svg>Ship</span>
|
||
<span class="nuc-pill right">Model: Opus 4.8 <span style="color:var(--tx3)">1M</span><span class="chev">▾</span></span>
|
||
<span class="nuc-pill">Effort: xhigh<span class="chev">▾</span></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<!-- ===== iPhone app surface — shown in place of the Mac cockpit on mobile (data-nuc-ios) ===== -->
|
||
<div class="nuc-ios" aria-label="The Nucleic iPhone app — Home tab">
|
||
<div class="ios-phone">
|
||
|
||
<!-- Home content (HomeView) -->
|
||
<div class="ios-content">
|
||
|
||
<!-- greeting + StreakBadge -->
|
||
<div class="ios-hi">
|
||
<div>
|
||
<h1>Good morning</h1>
|
||
<p class="sub">2 active of 5 chats · 2 projects</p>
|
||
</div>
|
||
<span class="ios-streak">
|
||
<svg class="bolt" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>
|
||
<span class="col"><span class="n">15</span><span class="lbl">day streak</span></span>
|
||
<span class="fz">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path d="M12 2v20M3.5 7l17 10M20.5 7l-17 10"/><path d="M12 6l2.2-2.2M12 6 9.8 3.8M12 18l2.2 2.2M12 18l-2.2 2.2"/></svg>
|
||
1
|
||
</span>
|
||
</span>
|
||
</div>
|
||
|
||
<!-- five StatCards -->
|
||
<div class="ios-stats">
|
||
<div class="ios-stat">
|
||
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span>
|
||
<span class="n">2</span><span class="l">Projects</span>
|
||
</div>
|
||
<div class="ios-stat">
|
||
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="M12 3a9 9 0 0 0 0 18z" fill="currentColor" stroke="none"/></svg></span>
|
||
<span class="n">1</span><span class="l">In progress</span>
|
||
</div>
|
||
<div class="ios-stat">
|
||
<span class="ic"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg></span>
|
||
<span class="n">2</span><span class="l">Active</span>
|
||
</div>
|
||
<div class="ios-stat">
|
||
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"><path d="M21 3 10 14M21 3l-7 18-4-7-7-4z"/></svg></span>
|
||
<span class="n">142</span><span class="l">Messages</span>
|
||
</div>
|
||
<div class="ios-stat">
|
||
<span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path d="M4 8h7M4 12h11M4 16h6"/></svg></span>
|
||
<span class="n">1.3M</span><span class="l">Tokens</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Activity card -->
|
||
<div class="ios-card">
|
||
<div class="ios-card-h"><span class="h">Activity</span></div>
|
||
<div class="ios-grid" aria-hidden="true"><!-- cells injected by the scoped script --></div>
|
||
</div>
|
||
|
||
<!-- In progress card -->
|
||
<div class="ios-card">
|
||
<div class="ios-card-h"><span class="h">In progress</span><span class="cnt">1</span></div>
|
||
<div class="ios-srow">
|
||
<span class="sym" style="color:var(--active)">
|
||
<!-- circle.lefthalf.filled (running) -->
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="M12 3a9 9 0 0 0 0 18z" fill="currentColor" stroke="none"/></svg>
|
||
</span>
|
||
<span class="sc"><div class="st">flaky-tests</div><div class="sp">nucleic</div></span>
|
||
<span class="diff">+88/−12</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- To-dos card (QuickTodos) -->
|
||
<div class="ios-card">
|
||
<div class="ios-card-h"><span class="h">To-dos</span><span class="cnt">3</span></div>
|
||
<div class="ios-capture">
|
||
<span class="ios-input">Capture an idea…</span>
|
||
<span class="ios-addbtn"><svg viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="10"/><path d="M12 8v8M8 12h8" fill="none" stroke="#fff" stroke-width="1.8" stroke-linecap="round"/></svg></span>
|
||
</div>
|
||
<div class="ios-todo">
|
||
<span class="box"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/></svg></span>
|
||
<span class="tt">Dark mode in settings</span>
|
||
<span class="pn">website</span>
|
||
</div>
|
||
<div class="ios-todo">
|
||
<span class="box"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/></svg></span>
|
||
<span class="tt">Sync server memory leak</span>
|
||
<span class="pn">nucleic</span>
|
||
</div>
|
||
<div class="ios-todo">
|
||
<span class="box"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/></svg></span>
|
||
<span class="tt">Write release notes</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- New chat composer (StartChatComposer) -->
|
||
<div class="ios-card">
|
||
<div class="ios-card-h"><span class="h">New chat</span></div>
|
||
<div class="ios-comp-row">
|
||
<span class="ios-menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>nucleic</span>
|
||
<span class="ios-auto"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/><path d="M3 3l18 18"/></svg>Auto</span>
|
||
</div>
|
||
<div class="ios-comp-row">
|
||
<span class="ios-tint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="8.5" y="8.5" width="7" height="7" rx="1"/><path d="M9 1.5v2.5M15 1.5v2.5M9 20v2.5M15 20v2.5M1.5 9H4M1.5 15H4M20 9h2.5M20 15h2.5"/></svg>Default model</span>
|
||
<span class="ios-tint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"><path d="M4 6h10M18 6h2M4 12h2M10 12h10M4 18h8M16 18h4"/><circle cx="16" cy="6" r="2.2" fill="#fff"/><circle cx="8" cy="12" r="2.2" fill="#fff"/><circle cx="14" cy="18" r="2.2" fill="#fff"/></svg>high</span>
|
||
</div>
|
||
<div class="ios-comp-field">
|
||
<span class="ios-input">Describe a task…</span>
|
||
<span class="ios-send"><svg viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="11"/><path d="M12 17V8M8 11l4-4 4 4" fill="none" stroke="#fff" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- ConnectionChip -->
|
||
<span class="ios-chip"><span class="dot"></span>Connected · LAN</span>
|
||
|
||
<!-- tab bar -->
|
||
<nav class="ios-tabbar">
|
||
<span class="ios-tab on">
|
||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 11.2 12 4l9 7.2V20a1.4 1.4 0 0 1-1.4 1.4h-4.1V15h-3v6.4H4.4A1.4 1.4 0 0 1 3 20z"/></svg>
|
||
<span class="tl">Home</span>
|
||
</span>
|
||
<span class="ios-tab">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"><path d="M4 9.5 12 6l8 3.5-8 3.5z"/><path d="M5 13l7 3 7-3M5 16.5l7 3 7-3"/></svg>
|
||
<span class="tl">Sessions</span>
|
||
<span class="tbadge">2</span>
|
||
</span>
|
||
<span class="ios-tab">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M3 7a2 2 0 0 1 2-2h3.5l2 2H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>
|
||
<span class="tl">Projects</span>
|
||
</span>
|
||
<span class="ios-tab">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6l1.6 1.6L8.5 4.7M11 6h9M4 12l1.6 1.6L8.5 10.7M11 12h9M4 18l1.6 1.6L8.5 16.7M11 18h9"/></svg>
|
||
<span class="tl">To-dos</span>
|
||
</span>
|
||
<span class="ios-tab">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="3.2"/><path d="M12 2.5v3M12 18.5v3M2.5 12h3M18.5 12h3M5.2 5.2l2.1 2.1M16.7 16.7l2.1 2.1M18.8 5.2l-2.1 2.1M7.3 16.7l-2.1 2.1"/></svg>
|
||
<span class="tl">Settings</span>
|
||
</span>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
<!-- ===== end iPhone app surface ===== -->
|
||
|
||
<div class="cta-row" style="justify-content:center;margin-top:16px"><span class="cta-note cap-desktop">The Nucleic cockpit — Control panel open over the project's chats. Illustrative.</span><span class="cta-note cap-mobile">Nucleic on your iPhone — watch, steer, and ship from anywhere. Illustrative.</span></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== features ===== -->
|
||
<section class="features" id="features">
|
||
<div class="wrap">
|
||
<div class="sechead">
|
||
<div>
|
||
<div class="kicker">What it does</div>
|
||
<h2>Built for running agents in parallel, safely.</h2>
|
||
</div>
|
||
<p>Isolation, attention, and trust — the three hard parts of a fleet, each solved by design.</p>
|
||
</div>
|
||
|
||
<div class="grid">
|
||
<div class="card">
|
||
<span class="no">01</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--green)" stroke-width="2"><path d="M12 3v12M7 10l5 5 5-5"/><path d="M5 19h14"/></svg>
|
||
<h3>Autoship</h3>
|
||
<p>Finished work merges itself — queued per branch, conflict-aware, never mid-task. On Nucleic Control projects.</p>
|
||
</div>
|
||
<div class="card">
|
||
<span class="no">02</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--blue)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7 3v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z"/><path d="m9 12 2 2 4-4"/></svg>
|
||
<h3>Nucleic Control</h3>
|
||
<p>Nucleic clones and sandboxes your repo and watches git directly, so agents stay contained and unattended work runs where Nucleic is in command.</p>
|
||
</div>
|
||
<div class="card">
|
||
<span class="no">03</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--magenta)" stroke-width="2"><path d="M6 4v16M6 8c8 0 4 8 12 8"/><circle cx="6" cy="4" r="1.8"/><circle cx="18" cy="16" r="1.8"/></svg>
|
||
<h3>nvrsion<span class="beta">Beta</span></h3>
|
||
<p>Version control purpose-built for agentic coding. Many agents commit to one shared trunk in real time — no branches to juggle, so shipping keeps pace with the work.</p>
|
||
</div>
|
||
<div class="card">
|
||
<span class="no">04</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--amber)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72Z"/><path d="m14 7 3 3"/><path d="M5 6v4"/><path d="M19 14v4"/><path d="M10 2v2"/><path d="M7 8H3"/><path d="M21 16h-4"/><path d="M11 3H9"/></svg>
|
||
<h3>Orchestra</h3>
|
||
<p>Grant standing consent and one agent spins up its own parallel subagents — maximum thoroughness, no wall of prompts.</p>
|
||
</div>
|
||
<div class="card">
|
||
<span class="no">05</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--pink)" stroke-width="2"><rect x="7" y="3" width="10" height="18" rx="2"/><path d="M11 18h2"/></svg>
|
||
<h3>Work from your iPhone</h3>
|
||
<p>The cockpit, projected to your pocket — watch sessions, answer approvals, send input, and steer work from your iPhone, end-to-end encrypted.</p>
|
||
</div>
|
||
<div class="card">
|
||
<span class="no">06</span>
|
||
<svg class="accent" viewBox="0 0 24 24" fill="none" stroke="var(--rust)" stroke-width="2"><rect x="2.5" y="6" width="6" height="12" rx="1.4"/><rect x="9" y="6" width="6" height="12" rx="1.4"/><rect x="15.5" y="6" width="6" height="12" rx="1.4"/></svg>
|
||
<h3>Agent-agnostic</h3>
|
||
<p>Claude Code, Codex, and Grok Build behind one approval flow — plus any agent that speaks ACP, the open Agent Client Protocol.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== native to Apple ===== -->
|
||
<section class="native" id="native">
|
||
<div class="wrap">
|
||
<div class="head">
|
||
<div class="kicker">Native to Apple platforms</div>
|
||
<h2>A first-class citizen on <span class="em">Apple platforms</span>.</h2>
|
||
<p>No Electron. No web wrapper. Nucleic is a real Mac app — 100% Swift and SwiftUI — with a native iPhone remote alongside it. It looks, feels, and performs like it belongs on your machine.</p>
|
||
</div>
|
||
<div class="native-grid">
|
||
<div class="ncard">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="var(--blue)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="6.5" y="6.5" width="11" height="11" rx="2"/><path d="M9.5 3v3.5M14.5 3v3.5M9.5 17.5V21M14.5 17.5V21M3 9.5h3.5M3 14.5h3.5M17.5 9.5H21M17.5 14.5H21"/></svg>
|
||
<h3>Pure Swift & SwiftUI</h3>
|
||
<p>Built in Swift 6.4 and SwiftUI, top to bottom — so it runs featherweight: minimal CPU, memory, and battery, even with a full fleet of agents going.</p>
|
||
</div>
|
||
<div class="ncard">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="var(--magenta)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5l1.7 4.4 4.4 1.7-4.4 1.7L12 15.7l-1.7-4.4L5.9 9.6l4.4-1.7z"/><path d="M18.6 15.4l.65 1.75 1.75.65-1.75.65-.65 1.75-.65-1.75-1.75-.65 1.75-.65z"/></svg>
|
||
<h3>On-device intelligence</h3>
|
||
<p>Apple Intelligence runs local tasks — classifying turns, summarizing tool calls, auto-triaging your idea inbox — privately, right on your Mac.</p>
|
||
</div>
|
||
<div class="ncard">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="var(--green)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l8 4.5v9L12 21l-8-4.5v-9z"/><path d="M12 12l8-4.5M12 12v9M12 12L4 7.5"/></svg>
|
||
<h3>Native sandboxing</h3>
|
||
<p>Sandboxed agents run in Apple's containerization framework — real, lightweight VMs, with no extra daemons.</p>
|
||
</div>
|
||
</div>
|
||
<p class="foot-note">macOS 27 (public beta) on Apple Silicon <span class="dotsep">·</span> native iPhone remote <span class="dotsep">·</span> signed & notarized</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== access ===== -->
|
||
<section class="access" id="access">
|
||
<div class="wrap">
|
||
<div class="panel">
|
||
<div class="kicker">Open beta</div>
|
||
<h2>Be first in the cockpit.</h2>
|
||
<p>Nucleic is in open beta. Requires macOS 27 on Apple Silicon.</p>
|
||
<div class="cta-row">
|
||
<div class="dl">
|
||
<a class="btn" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">Download for Apple Silicon</a>
|
||
<button class="dl-toggle" type="button" aria-label="Choose a version" aria-haspopup="true" aria-expanded="false">
|
||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg>
|
||
</button>
|
||
<div class="dl-menu center" role="menu">
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/beta/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Beta <span class="dl-lbl beta">Recommended</span></span>
|
||
<span class="d">The public beta — best for everyday use.</span>
|
||
</a>
|
||
<a class="dl-opt" role="menuitem" href="https://updates.nucleic.blakeslee.xyz/canary/latest" target="_blank" rel="noopener noreferrer">
|
||
<span class="t">Canary <span class="dl-lbl canary">Bleeding edge</span></span>
|
||
<span class="d">The newest builds, shipped continuously. Expect rough edges.</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="panel-trust mono"><strong style="color:var(--ink);font-weight:600">No account required</strong> <span class="dotsep">·</span> private by design <span class="dotsep">·</span> local-first <span class="dotsep">·</span> end-to-end encrypted</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer>
|
||
<div class="wrap foot">
|
||
<div class="brand" style="font-size:15px">
|
||
<svg class="mk" viewBox="0 0 100 100" aria-hidden="true">
|
||
<g fill="none" stroke-width="7">
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(80 50 50)" stroke="#7AA7DD"/>
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(20 50 50)" stroke="#DF619B"/>
|
||
<ellipse cx="50" cy="50" rx="17" ry="40" transform="rotate(140 50 50)" stroke="#C5826F"/>
|
||
</g>
|
||
</svg>
|
||
Nucleic
|
||
</div>
|
||
<div class="foot-links">
|
||
<a href="/privacy.html">Privacy</a>
|
||
<a href="/terms.html">Terms</a>
|
||
</div>
|
||
<div class="foot-end">
|
||
<div class="mono">© 2026 Andrew Blakeslee Moore</div>
|
||
<div class="mono">Made with Nucleic</div>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- Hidden frame: starts the download in the background — no new tab, no navigation.
|
||
Falls back to target="_blank" on the links if JavaScript is unavailable. -->
|
||
<iframe id="dl-frame" title="Download" aria-hidden="true" tabindex="-1" style="position:absolute;width:0;height:0;border:0;left:-9999px"></iframe>
|
||
<script>
|
||
(function () {
|
||
// Start any channel download (beta or canary) in the hidden frame — no new tab.
|
||
var frame = document.getElementById("dl-frame");
|
||
Array.prototype.forEach.call(
|
||
document.querySelectorAll('a[href^="https://updates.nucleic.blakeslee.xyz/"]'),
|
||
function (a) {
|
||
a.addEventListener("click", function (e) {
|
||
e.preventDefault();
|
||
frame.src = a.getAttribute("href");
|
||
// Collapse the version menu once a choice is made.
|
||
var dl = a.closest(".dl");
|
||
if (dl) closeMenu(dl);
|
||
});
|
||
}
|
||
);
|
||
|
||
// ---- version split-button menus (chevron) ----
|
||
function closeMenu(dl) {
|
||
dl.classList.remove("open");
|
||
var t = dl.querySelector(".dl-toggle");
|
||
if (t) t.setAttribute("aria-expanded", "false");
|
||
}
|
||
function closeAll(except) {
|
||
document.querySelectorAll(".dl.open").forEach(function (dl) {
|
||
if (dl !== except) closeMenu(dl);
|
||
});
|
||
}
|
||
document.querySelectorAll(".dl-toggle").forEach(function (toggle) {
|
||
toggle.addEventListener("click", function (e) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
var dl = toggle.closest(".dl");
|
||
var willOpen = !dl.classList.contains("open");
|
||
closeAll(dl);
|
||
dl.classList.toggle("open", willOpen);
|
||
toggle.setAttribute("aria-expanded", willOpen ? "true" : "false");
|
||
});
|
||
});
|
||
// Click outside or Escape closes any open menu.
|
||
document.addEventListener("click", function (e) {
|
||
if (!e.target.closest(".dl")) closeAll(null);
|
||
});
|
||
document.addEventListener("keydown", function (e) {
|
||
if (e.key === "Escape") closeAll(null);
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
<script>
|
||
// Reveal the top-bar "Download for Apple Silicon" button only once the hero's
|
||
// own download button has scrolled out of view above the viewport.
|
||
(function () {
|
||
var navBtn = document.getElementById("nav-dl");
|
||
var heroBtn = document.getElementById("hero-dl");
|
||
if (!navBtn || !heroBtn) return;
|
||
if (!("IntersectionObserver" in window)) { navBtn.classList.add("show"); return; }
|
||
var io = new IntersectionObserver(function (entries) {
|
||
navBtn.classList.toggle("show", !entries[0].isIntersecting);
|
||
}, { threshold: 0 });
|
||
io.observe(heroBtn);
|
||
})();
|
||
</script>
|
||
|
||
<script data-nuc>
|
||
(function () {
|
||
// Fill each activity grid with as many whole weekly columns as its column
|
||
// width allows — mirroring the app's GeometryReader (weeks = width/(cell+gap)).
|
||
// Deterministic (seeded) so the pattern is stable; recent weeks (right) trend
|
||
// busier, with two streak-freeze cells in blue.
|
||
function build(grid) {
|
||
// Clear prior columns *before* measuring: a stale nowrap flex row can skew
|
||
// the cell probe, and rebuilding from empty keeps the count honest on resize.
|
||
grid.textContent = '';
|
||
var probe = document.createElement('i');
|
||
grid.appendChild(probe);
|
||
var cell = probe.getBoundingClientRect().width || 14;
|
||
grid.removeChild(probe);
|
||
var gap = 3, rows = 7;
|
||
// Fit only as many columns as actually fit — never a hard minimum. Forcing a
|
||
// count wider than the column is what overflowed the dashboard cell, blew out
|
||
// the 1fr/1fr grid, and cut elements off when narrowing then widening again.
|
||
var avail = grid.clientWidth || grid.parentElement.clientWidth || 0;
|
||
var weeks = Math.max(1, Math.floor((avail + gap) / (cell + gap)));
|
||
var seed = 20260629;
|
||
function rnd() { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; }
|
||
var frozen = {};
|
||
frozen[(weeks - 9) + ',2'] = 1;
|
||
frozen[(weeks - 4) + ',4'] = 1;
|
||
for (var c = 0; c < weeks; c++) {
|
||
var col = document.createElement('div');
|
||
col.className = 'col';
|
||
var recency = c / (weeks - 1);
|
||
for (var r = 0; r < rows; r++) {
|
||
var i = document.createElement('i');
|
||
if (frozen[c + ',' + r]) {
|
||
i.className = 'fz';
|
||
} else {
|
||
var p = rnd() * 0.55 + recency * 0.6;
|
||
var lvl = p < 0.28 ? 0 : p < 0.5 ? 1 : p < 0.72 ? 2 : p < 0.9 ? 3 : 4;
|
||
if (lvl) i.className = 'l' + lvl;
|
||
}
|
||
col.appendChild(i);
|
||
}
|
||
grid.appendChild(col);
|
||
}
|
||
}
|
||
function fill() { document.querySelectorAll('.nuc-cockpit .nuc-grid').forEach(build); }
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fill);
|
||
else fill();
|
||
var t; window.addEventListener('resize', function () { clearTimeout(t); t = setTimeout(fill, 150); });
|
||
})();
|
||
</script>
|
||
|
||
<!-- ===== iPhone app surface: paint its activity grid (data-nuc-ios) ===== -->
|
||
<script data-nuc-ios>
|
||
(function () {
|
||
// Paint the activity grid ONCE with a fixed column count sized to the 360px
|
||
// card — no live width measuring and no resize rebuild, so it never reflows or
|
||
// "jumps" on load. Deterministic (seeded); recent weeks (right) trend busier,
|
||
// with two streak-freeze cells in the iced blue. The grid's overflow:hidden
|
||
// clips the rightmost column gracefully on phones narrower than the card.
|
||
var COLS = 19, ROWS = 7;
|
||
function build(grid) {
|
||
grid.textContent = '';
|
||
var seed = 20260629;
|
||
function rnd() { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; }
|
||
var frozen = {};
|
||
frozen[(COLS - 7) + ',2'] = 1;
|
||
frozen[(COLS - 3) + ',5'] = 1;
|
||
for (var c = 0; c < COLS; c++) {
|
||
var col = document.createElement('div');
|
||
col.className = 'col';
|
||
var recency = c / (COLS - 1);
|
||
for (var r = 0; r < ROWS; r++) {
|
||
var i = document.createElement('i');
|
||
if (frozen[c + ',' + r]) {
|
||
i.className = 'fz';
|
||
} else {
|
||
var p = rnd() * 0.55 + recency * 0.6;
|
||
var lvl = p < 0.3 ? 0 : p < 0.52 ? 1 : p < 0.73 ? 2 : p < 0.9 ? 3 : 4;
|
||
if (lvl) i.className = 'l' + lvl;
|
||
}
|
||
col.appendChild(i);
|
||
}
|
||
grid.appendChild(col);
|
||
}
|
||
}
|
||
function fill() { document.querySelectorAll('.nuc-ios .ios-grid').forEach(build); }
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fill);
|
||
else fill();
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|