
Web Prototype Taste Soft
- 169 installs
- 83.7k repo stars
- Updated August 5, 2026
- nexu-io/open-design
Create soft, approachable web prototypes for onboarding flows, wellness apps, or consumer SaaS where warmth and reduced visual friction must be tested with real users.
About
Generates soft-taste web prototypes emphasizing gentle color, rounded forms, and calm typography. Ideal for validating emotional design fit in consumer or onboarding experiences before implementation.
- Soft visual palette
- Approachable UI tone
- Consumer-friendly layouts
- Rapid HTML mocks
- User-test ready
Web Prototype Taste Soft by the numbers
- 169 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #979 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/nexu-io/open-design --skill web-prototype-taste-softAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 169 |
|---|---|
| repo stars | ★ 83.7k |
| Last updated | August 5, 2026 |
| Repository | nexu-io/open-design ↗ |
What it does
Create soft, approachable web prototypes for onboarding flows, wellness apps, or consumer SaaS where warmth and reduced visual friction must be tested with real users.
Files
Web Prototype — Soft Premium
For briefs that ask for "Apple-like", "Linear-tier", "premium consumer", "calm SaaS", or "$150k agency" finish. The aesthetic is soft, weighty, and obsessive about nested architecture.
Source
Distilled from Leonxlnx/taste-skill — skills/soft-skill/SKILL.md ("Vanguard UI Architect") with the haptic micro-aesthetics, double-bezel architecture, and motion choreography rules. See example.html in this directory for a fully-realized template.
Hard rules
- Canvas: silver-grey or warm cream (
#F2F2F0or#FDFBF7). Not pure white. - Type pairing: display in Geist / Plus Jakarta Sans / Cabinet Grotesk at heavy weight, body in the same family, monospace meta in Geist Mono.
- Display:
clamp(48px, 7vw, 96px),letter-spacing: -0.035em,line-height: 0.96. Heavy weight (700+). - Squircle radii:
border-radius: 28px–40px(rounded-[2rem]torounded-[2.5rem]) on major surfaces. - Double-bezel mandatory: every important card is a wrapper (
p-1.5, hairline border, soft outer shadow) containing an inner core with its own background and a concentric smaller radius (e.g., outer2rem, innercalc(2rem - 0.375rem)). - CTA = button-in-button: primary CTAs are full pills (
rounded-full px-6 py-3); the trailing arrow lives inside its own circular wrapper flush-right. - Ambient depth: one slow-drifting radial mesh blob behind hero,
opacity ≤ 0.18,pointer-events: none, fixed. - Eyebrow tag above each section header: pill, uppercase mono,
letter-spacing: 0.2em,text-[10px].
Banned
- Inter, Roboto, Helvetica, Open Sans.
- Generic 1px solid gray borders (use
border-black/5/ring-1 ring-black/5). shadow-md,shadow-lg, hard drop shadows. Only diffuse, wide-spread, low-opacity (0 20px 40px -15px rgba(0,0,0,0.05)).- Edge-to-edge sticky navbars glued to the top. Use a floating glass pill (
mt-6 mx-auto w-max rounded-full). - Linear or
ease-in-outtransitions. Usecubic-bezier(0.32, 0.72, 0, 1)or spring physics. h-screen(usemin-h-[100dvh]).- Animating
width/height/top/left. Onlytransformandopacity. - Pure black
#000. Use Zinc-950 / Off-Black.
Required components
- Floating-pill navbar with backdrop-blur-2xl.
- Asymmetric hero: massive heavy display, eyebrow tag, body lede
max-w-[52ch], two CTAs (primary pill with button-in-button arrow + ghost). - Bento grid using the double-bezel pattern; at least one wide card and one tall card.
- Feature row with z-axis cascade or split image module.
- Marquee strip of customer logos, slow infinite translation (
-100% / 20s), pause on hover. - Closing band on a soft inverted surface (deep zinc / espresso).
- Footer: monospace meta, hairline above.
Motion
- All transitions:
transition: transform 700ms cubic-bezier(0.32,0.72,0,1)minimum. - Hover on CTAs: outer pill scales
0.98on:active, inner trailing-icon circle translates(+1px, -1px)andscale(1.05). - Scroll entry:
translateY(16px) blur(8px) opacity(0)→translateY(0) blur(0) opacity(1).IntersectionObserveronly. - Marquee:
transform: translateX(-50%)over30s linearinfinite, applied to a duplicated track. - Hero mesh blob: 24s+ keyframe drift, opacity-only or transform-only.
Pre-flight
- [ ] Floating pill nav with
backdrop-blur+ hairline ring - [ ] At least one card uses the double-bezel (outer shell + inner core, concentric radii)
- [ ] Primary CTA uses button-in-button trailing icon
- [ ] Section padding ≥
py-24 - [ ] No banned fonts; display weight ≥ 700
- [ ] Hero uses
min-h-[100dvh], never100vh - [ ] All transitions use custom cubic-bezier or spring; no
linear/ease-in-out - [ ] Mobile: layout collapses to single column under 768px, all rotations + overlaps removed
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Halcyon — calmer infrastructure for AI agents</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--canvas: #F2F2F0;
--canvas-2: #E8E8E5;
--ink: #0A0A0A;
--ink-2: #18181B; /* zinc-900 */
--muted: #57575A;
--hairline: rgba(10,10,10,0.08);
--hairline-strong: rgba(10,10,10,0.12);
--innerlight: rgba(255,255,255,0.65);
--accent: #1F4D3F; /* deep sage */
--accent-glow: #5A8C7A;
--sans: 'Plus Jakarta Sans', 'Geist', 'Cabinet Grotesk', system-ui, sans-serif;
--mono: 'JetBrains Mono', 'Geist Mono', ui-monospace, monospace;
--ease: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.16, 1.16, 0.3, 1);
--shell-radius: 2.25rem;
--core-radius: calc(2.25rem - 0.4rem);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
background: var(--canvas);
color: var(--ink);
font-family: var(--sans);
font-size: 16px;
line-height: 1.5;
letter-spacing: -0.005em;
-webkit-font-smoothing: antialiased;
overflow-x: hidden;
}
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 28px; }
/* ============ AMBIENT MESH (fixed, pointer-events-none) ============ */
.mesh {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
overflow: hidden;
}
.mesh::before, .mesh::after {
content: ''; position: absolute; border-radius: 50%; filter: blur(90px);
opacity: 0.18; will-change: transform;
}
.mesh::before {
width: 720px; height: 720px;
background: radial-gradient(circle at 30% 30%, var(--accent-glow), transparent 60%);
top: -180px; left: -160px;
animation: drift1 28s var(--ease) infinite alternate;
}
.mesh::after {
width: 560px; height: 560px;
background: radial-gradient(circle at 60% 60%, #C9B79A, transparent 60%);
top: 120px; right: -140px;
animation: drift2 36s var(--ease) infinite alternate;
}
@keyframes drift1 { from { transform: translate3d(0,0,0); } to { transform: translate3d(80px, 60px, 0); } }
@keyframes drift2 { from { transform: translate3d(0,0,0); } to { transform: translate3d(-60px, 40px, 0); } }
@media (prefers-reduced-motion: reduce) { .mesh::before, .mesh::after { animation: none; } }
main, header, footer { position: relative; z-index: 1; }
/* ============ FLOATING PILL NAV ============ */
.nav-shell {
position: sticky; top: 24px; z-index: 50;
margin: 24px auto 0;
padding: 6px;
width: max-content; max-width: calc(100% - 56px);
border-radius: 999px;
background: rgba(255,255,255,0.42);
backdrop-filter: saturate(160%) blur(22px);
-webkit-backdrop-filter: saturate(160%) blur(22px);
box-shadow:
0 1px 0 rgba(255,255,255,0.45) inset,
0 0 0 1px rgba(10,10,10,0.05),
0 12px 36px -18px rgba(10,10,10,0.18);
}
.nav {
display: flex; align-items: center; gap: 18px;
padding: 6px 8px 6px 18px;
border-radius: 999px;
background: rgba(255,255,255,0.55);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
}
.nav .brand { font-weight: 700; font-size: 16px; letter-spacing: -0.02em; display: inline-flex; align-items: center; gap: 8px; }
.nav .brand-mark {
width: 22px; height: 22px; border-radius: 8px;
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-glow) 100%);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.35), 0 1px 2px rgba(10,10,10,0.18);
}
.nav ul { list-style: none; display: flex; gap: 6px; margin: 0; padding: 0; }
.nav ul a {
display: inline-block; padding: 9px 14px; border-radius: 999px;
color: var(--ink); text-decoration: none; font-size: 13px; font-weight: 500;
transition: background 300ms var(--ease);
}
.nav ul a:hover { background: rgba(10,10,10,0.05); }
.pill {
display: inline-flex; align-items: center; gap: 6px;
padding: 7px 7px 7px 16px;
border-radius: 999px;
background: var(--ink); color: var(--canvas);
font: 600 13px/1 var(--sans); cursor: pointer; border: none;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
transition: transform 300ms var(--ease);
}
.pill .icon-wrap {
width: 26px; height: 26px; border-radius: 999px;
background: rgba(255,255,255,0.14);
display: inline-flex; align-items: center; justify-content: center;
transition: transform 360ms var(--ease-spring), background 300ms var(--ease);
}
.pill:hover .icon-wrap { transform: translate(2px, -1px) scale(1.06); background: rgba(255,255,255,0.22); }
.pill:active { transform: scale(0.98); }
.pill svg { width: 12px; height: 12px; stroke: currentColor; fill: none; }
/* ============ HERO ============ */
.hero {
min-height: 100dvh;
padding: 96px 0 120px;
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: 48px;
align-items: center;
}
.eyebrow {
display: inline-flex; align-items: center; gap: 8px;
padding: 6px 12px; border-radius: 999px;
background: rgba(255,255,255,0.6);
box-shadow: inset 0 0 0 1px var(--hairline);
font-family: var(--mono); font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
color: var(--muted);
}
.eyebrow .dot { width: 6px; height: 6px; border-radius: 999px; background: var(--accent); box-shadow: 0 0 0 4px rgba(31,77,63,0.18); }
.hero h1 {
font-size: clamp(48px, 7vw, 92px);
font-weight: 700;
line-height: 0.96;
letter-spacing: -0.038em;
margin: 22px 0 28px;
max-width: 14ch;
}
.hero h1 .soft { color: var(--muted); font-weight: 500; }
.hero p.lede {
color: var(--muted);
font-size: 18px;
max-width: 52ch;
margin: 0 0 34px;
line-height: 1.55;
}
.hero .actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.ghost {
display: inline-flex; align-items: center; gap: 8px;
padding: 11px 18px; border-radius: 999px;
background: rgba(255,255,255,0.5);
box-shadow: inset 0 0 0 1px var(--hairline-strong);
font: 500 13.5px/1 var(--sans); color: var(--ink); cursor: pointer; border: none;
transition: background 300ms var(--ease), transform 300ms var(--ease);
}
.ghost:hover { background: rgba(255,255,255,0.85); }
.ghost:active { transform: scale(0.98); }
/* ============ HERO PREVIEW (DOUBLE-BEZEL CARD) ============ */
.hero-preview {
position: relative;
padding: 10px;
border-radius: var(--shell-radius);
background: rgba(255,255,255,0.45);
box-shadow:
inset 0 1px 0 var(--innerlight),
0 0 0 1px var(--hairline),
0 30px 60px -28px rgba(10,10,10,0.22),
0 12px 24px -16px rgba(10,10,10,0.10);
}
.hero-preview .core {
position: relative;
border-radius: var(--core-radius);
background: linear-gradient(180deg, #FAFAF7 0%, #EFEFEB 100%);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), inset 0 0 0 1px var(--hairline);
padding: 22px;
overflow: hidden;
}
.preview-bar {
display: flex; gap: 6px; margin-bottom: 18px;
}
.preview-bar span { width: 10px; height: 10px; border-radius: 999px; background: rgba(10,10,10,0.10); }
.preview-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pv-cell {
border-radius: 16px;
background: rgba(255,255,255,0.8);
box-shadow: inset 0 0 0 1px var(--hairline), inset 0 1px 0 rgba(255,255,255,0.8);
padding: 14px;
}
.pv-cell.span2 { grid-column: span 2; }
.pv-cell h4 { margin: 0 0 6px; font-size: 12px; font-weight: 600; letter-spacing: -0.01em; }
.pv-cell p { margin: 0; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.pv-cell .meta { font-family: var(--mono); font-size: 9.5px; color: var(--muted); letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 6px; }
.pv-cell .num { font-size: 26px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; margin-top: 4px; }
.pv-cell .num small { font-size: 12px; color: var(--muted); margin-left: 4px; font-weight: 500; }
.ring {
width: 38px; height: 38px; border-radius: 999px;
background: conic-gradient(var(--accent) 0 67%, rgba(10,10,10,0.08) 67% 100%);
mask: radial-gradient(circle 14px, transparent 12px, black 13px);
-webkit-mask: radial-gradient(circle 14px, transparent 12px, black 13px);
margin-top: 6px;
}
.pv-cell .row { display: flex; align-items: center; gap: 10px; }
.pulse {
width: 8px; height: 8px; border-radius: 999px; background: var(--accent);
box-shadow: 0 0 0 0 rgba(31,77,63,0.4);
animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(31,77,63,0.4); }
70% { box-shadow: 0 0 0 10px rgba(31,77,63,0); }
100% { box-shadow: 0 0 0 0 rgba(31,77,63,0); }
}
/* ============ SECTION DEFAULTS ============ */
section.block { padding: 112px 0; position: relative; }
.section-head { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: end; margin-bottom: 56px; }
.section-head h2 {
font-size: clamp(38px, 5vw, 64px);
font-weight: 700;
letter-spacing: -0.035em;
line-height: 1;
margin: 16px 0 0;
max-width: 14ch;
}
.section-head p { color: var(--muted); font-size: 16.5px; max-width: 46ch; margin: 0; line-height: 1.55; }
/* ============ BENTO (double-bezel cards) ============ */
.bento { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; }
.b-card {
padding: 8px;
border-radius: var(--shell-radius);
background: rgba(255,255,255,0.5);
box-shadow:
inset 0 1px 0 var(--innerlight),
0 0 0 1px var(--hairline),
0 24px 48px -28px rgba(10,10,10,0.18);
transition: transform 600ms var(--ease), box-shadow 600ms var(--ease);
}
.b-card:hover {
transform: translateY(-3px);
box-shadow:
inset 0 1px 0 var(--innerlight),
0 0 0 1px var(--hairline),
0 30px 70px -22px rgba(10,10,10,0.22);
}
.b-card .core {
border-radius: var(--core-radius);
background: #FCFCFA;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), inset 0 0 0 1px var(--hairline);
padding: 32px;
height: 100%;
display: flex; flex-direction: column;
}
.b-card.dark .core {
background: linear-gradient(180deg, #1A1A1A 0%, #0F0F0F 100%);
color: #ECECEA;
}
.b-card.dark .core .meta { color: rgba(255,255,255,0.55); }
.b-card.dark .core p { color: rgba(255,255,255,0.6); }
.b-card .meta { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin-bottom: 18px; }
.b-card h3 { font-size: 24px; font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; margin: 0 0 10px; }
.b-card.dark h3 { color: #FFFFFF; }
.b-card p { font-size: 14px; color: var(--muted); margin: 0; line-height: 1.55; max-width: 36ch; }
.span-3 { grid-column: span 3; }
.span-2 { grid-column: span 2; }
.span-4 { grid-column: span 4; }
.span-6 { grid-column: span 6; }
.row-2 { grid-row: span 2; }
.stat { display: flex; align-items: baseline; gap: 8px; margin-top: 24px; }
.stat .big { font-size: 56px; font-weight: 700; letter-spacing: -0.04em; line-height: 1; }
.stat .unit { font-family: var(--mono); font-size: 12px; color: var(--muted); letter-spacing: 0.12em; text-transform: uppercase; }
.codeblock {
margin-top: auto; padding: 18px;
border-radius: 18px;
background: #0E0E0E; color: #ECECEA;
font-family: var(--mono); font-size: 12px; line-height: 1.65;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.05);
overflow: hidden;
}
.codeblock .k { color: #5A8C7A; }
.codeblock .s { color: #C9B79A; }
.codeblock .c { color: rgba(236,236,234,0.4); }
/* ============ MARQUEE ============ */
.marquee {
padding: 56px 0;
overflow: hidden;
mask-image: linear-gradient(90deg, transparent, black 12%, black 88%, transparent);
-webkit-mask-image: linear-gradient(90deg, transparent, black 12%, black 88%, transparent);
}
.marquee-track {
display: flex; gap: 64px; width: max-content;
animation: track 32s linear infinite;
will-change: transform;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes track { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.marquee-item {
font-weight: 700; font-size: 22px; letter-spacing: -0.02em; color: var(--ink);
opacity: 0.55;
white-space: nowrap;
}
.marquee-item em { font-style: normal; color: var(--muted); margin: 0 12px; }
/* ============ CLOSING (inverted soft surface) ============ */
.closing {
padding: 112px 0;
margin: 56px 28px 28px;
border-radius: 40px;
background: linear-gradient(180deg, #131313 0%, #050505 100%);
color: #F2F2F0;
position: relative; overflow: hidden;
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.08),
0 30px 80px -40px rgba(10,10,10,0.6);
}
.closing::before {
content: ''; position: absolute; inset: 0;
background: radial-gradient(700px 360px at 30% 0%, rgba(90,140,122,0.32), transparent 70%);
pointer-events: none;
}
.closing-inner { position: relative; max-width: 1040px; padding: 0 32px; margin: 0 auto; text-align: center; }
.closing h2 { font-size: clamp(40px, 5.5vw, 76px); font-weight: 700; letter-spacing: -0.035em; line-height: 1; margin: 0 0 18px; max-width: 18ch; margin-inline: auto; }
.closing p { color: rgba(242,242,240,0.65); font-size: 17px; margin: 0 auto 32px; max-width: 48ch; line-height: 1.55; }
.closing .pill { background: var(--canvas); color: var(--ink); }
.closing .pill .icon-wrap { background: rgba(10,10,10,0.08); }
/* ============ FOOTER ============ */
footer {
padding: 36px 28px 28px;
font-family: var(--mono); font-size: 11px; color: var(--muted);
letter-spacing: 0.06em;
}
footer .row { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; max-width: 1240px; margin: 0 auto; padding: 0 28px; }
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--ink); }
/* ============ RESPONSIVE COLLAPSE ============ */
@media (max-width: 980px) {
.hero { grid-template-columns: 1fr; padding-top: 64px; padding-bottom: 80px; }
.nav ul { display: none; }
.section-head { grid-template-columns: 1fr; gap: 18px; }
.bento { grid-template-columns: 1fr; }
.span-3, .span-2, .span-4, .span-6 { grid-column: span 1; }
.row-2 { grid-row: auto; }
.closing { margin: 28px 16px; padding: 80px 0; }
}
/* ============ MOTION ENTRY ============ */
.reveal { opacity: 0; transform: translateY(18px); filter: blur(6px); transition: opacity 800ms var(--ease), transform 800ms var(--ease), filter 800ms var(--ease); }
.reveal.is-in { opacity: 1; transform: none; filter: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; filter: none; transition: none; } }
</style>
</head>
<body>
<div class="mesh" aria-hidden="true"></div>
<div class="nav-shell" data-od-id="topnav">
<header class="nav">
<span class="brand"><span class="brand-mark"></span>Halcyon</span>
<ul>
<li><a href="#bento">Platform</a></li>
<li><a href="#metrics">Metrics</a></li>
<li><a href="#docs">Docs</a></li>
<li><a href="#changelog">Changelog</a></li>
</ul>
<button class="pill">
<span>Get started</span>
<span class="icon-wrap"><svg viewBox="0 0 12 12" stroke-width="1.6"><path d="M2.5 6h7M6 2.5L9.5 6 6 9.5"/></svg></span>
</button>
</header>
</div>
<main>
<section class="wrap hero reveal" data-od-id="hero">
<div class="hero-copy">
<span class="eyebrow"><span class="dot"></span>Series A · 2026 · Bordeaux</span>
<h1>Calmer infrastructure for the agents <span class="soft">already running your business.</span></h1>
<p class="lede">Halcyon is a runtime for long-running AI agents that need stable identity, predictable cost, and an audit trail you can hand to legal. We replace the YAML scaffolding teams keep rebuilding from scratch.</p>
<div class="actions">
<button class="pill">
<span>Open the console</span>
<span class="icon-wrap"><svg viewBox="0 0 12 12" stroke-width="1.6"><path d="M2.5 6h7M6 2.5L9.5 6 6 9.5"/></svg></span>
</button>
<button class="ghost">
Read the runtime spec
</button>
</div>
</div>
<aside class="hero-preview" data-od-id="hero-preview">
<div class="core">
<div class="preview-bar"><span></span><span></span><span></span></div>
<div class="preview-grid">
<div class="pv-cell span2">
<div class="meta">runtime · live</div>
<div class="row" style="justify-content: space-between;">
<div>
<h4 style="font-size: 14px;">research-agent / tier-3</h4>
<div class="row" style="margin-top: 4px;"><span class="pulse"></span><p style="margin:0; font-size: 11px;">healthy · 7d 14h uptime</p></div>
</div>
<div class="ring" aria-hidden="true"></div>
</div>
</div>
<div class="pv-cell">
<div class="meta">spend / 24h</div>
<div class="num">$47.18<small>USD</small></div>
</div>
<div class="pv-cell">
<div class="meta">tasks / 24h</div>
<div class="num">1,284<small>ok</small></div>
</div>
<div class="pv-cell span2">
<div class="meta">audit · last entry</div>
<p style="font-size: 11.5px; line-height: 1.6;">
<code style="font-family: var(--mono); color: var(--accent);">04:12:09</code> · ticket <code style="font-family: var(--mono);">PRD-4731</code> dispatched to <b>research-agent/tier-3</b> by <b>quentin.albrecht</b>. Resolved in 41.7s.
</p>
</div>
</div>
</div>
</aside>
</section>
<section class="block reveal" id="bento">
<div class="wrap">
<div class="section-head">
<span class="eyebrow"><span class="dot"></span>02 · platform</span>
<p>Five primitives. No agent framework lock-in. Bring your own model, your own tools, your own sandbox — keep the runtime, the policies, and the bill in one place.</p>
</div>
<div class="section-head" style="margin-bottom: 56px;">
<h2>The runtime is the boring part. We're <em style="font-weight:500; color: var(--muted); font-style: normal;">obsessed</em> with the boring part.</h2>
<span></span>
</div>
<div class="bento">
<div class="b-card span-3 row-2">
<div class="core">
<div class="meta">01 · identity</div>
<h3>Stable identities, not session tokens.</h3>
<p>Every agent gets a long-lived identity with revocable credentials, scoped policies, and a portable memory layer that survives model swaps. Rotate keys without re-onboarding the agent.</p>
<div class="codeblock">
<span class="c">// stable across model swaps</span><br>
<span class="k">agent</span>.identity = {<br>
id: <span class="s">"agent_q7_research"</span>,<br>
policy: <span class="s">"tier-3:read-only"</span>,<br>
memory: halcyon.memory(<span class="s">"q7"</span>),<br>
};
</div>
</div>
</div>
<div class="b-card span-3">
<div class="core">
<div class="meta">02 · spend</div>
<h3>One bill. One cap. One alarm.</h3>
<p>Set budgets per agent, per workspace, per provider. Halcyon throttles before the bill becomes a Slack post-mortem.</p>
<div class="stat"><span class="big">$0.018</span><span class="unit">avg / task</span></div>
</div>
</div>
<div class="b-card span-3 dark">
<div class="core">
<div class="meta">03 · audit</div>
<h3>An audit log shaped like an audit log.</h3>
<p>Append-only. Cryptographically chained. Streams to your SIEM. Every tool call, every prompt, every model swap, every refund — in one place legal can actually subpoena.</p>
</div>
</div>
<div class="b-card span-2">
<div class="core">
<div class="meta">04 · sandbox</div>
<h3>Real sandboxes.</h3>
<p>Firecracker microVMs per task. Boots in 110ms.</p>
</div>
</div>
<div class="b-card span-2">
<div class="core">
<div class="meta">05 · routing</div>
<h3>Model-agnostic routing.</h3>
<p>Cheapest model that passes your eval. Updated nightly.</p>
</div>
</div>
<div class="b-card span-2">
<div class="core">
<div class="meta">06 · ergonomics</div>
<h3>Three SDKs. Two CLIs.</h3>
<p>Python, TypeScript, Go. <code style="font-family: var(--mono); color: var(--accent);">halcyon</code> & <code style="font-family: var(--mono); color: var(--accent);">hl</code>.</p>
</div>
</div>
</div>
</div>
</section>
<section class="marquee reveal">
<div class="marquee-track">
<span class="marquee-item">Anthropic<em>·</em>Stripe<em>·</em>Linear<em>·</em>Vercel<em>·</em>Cursor<em>·</em>Brex<em>·</em>Ramp<em>·</em>Replicate<em>·</em>Hex<em>·</em>Notion<em>·</em></span>
<span class="marquee-item" aria-hidden="true">Anthropic<em>·</em>Stripe<em>·</em>Linear<em>·</em>Vercel<em>·</em>Cursor<em>·</em>Brex<em>·</em>Ramp<em>·</em>Replicate<em>·</em>Hex<em>·</em>Notion<em>·</em></span>
</div>
</section>
<section class="closing reveal" data-od-id="closing">
<div class="closing-inner">
<h2>Less duct tape between the model and the bill.</h2>
<p>14-day evaluation, then choose pay-as-you-go or annual. We'll send a real engineer for setup. No SDR funnel.</p>
<button class="pill">
<span>Talk to an engineer</span>
<span class="icon-wrap"><svg viewBox="0 0 12 12" stroke-width="1.6"><path d="M2.5 6h7M6 2.5L9.5 6 6 9.5"/></svg></span>
</button>
</div>
</section>
</main>
<footer>
<div class="row">
<span>Halcyon Runtime · SOC 2 · ISO 27001 · v2026.05</span>
<span><a href="#">Docs</a> · <a href="#">Changelog</a> · <a href="#">Status</a> · <a href="#">Privacy</a> · <a href="#">Contact</a></span>
</div>
</footer>
<script>
const io = new IntersectionObserver((entries) => {
for (const e of entries) {
if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); }
}
}, { threshold: 0.1, rootMargin: '0px 0px -10% 0px' });
document.querySelectorAll('.reveal').forEach((el) => io.observe(el));
</script>
</body>
</html>