Merge nucleic/warm-velvet-dingo-rmhb into main

Mirrored from corpo 969f1a3.
This commit is contained in:
2026-08-10 02:59:21 -07:00
parent 93a3e6241a
commit 58763d192d
+315 -61
View File
@@ -78,29 +78,69 @@ const canonical = new URL('/', Astro.site);
<main> <main>
<section class="hero" aria-labelledby="hero-heading"> <section class="hero" aria-labelledby="hero-heading">
<!-- Headline and card share one wrapper so they sit on a single flex line <!-- The copy and technology stack share a flex line that can break. Grid
that can break. Grid alone cannot: a headline too wide for its columns alone cannot do that safely: enlarged headline text keeps its area and
keeps its area and simply prints over whatever occupies the next one. --> simply prints over the technology column instead of stepping above it. -->
<div class="hero-lead"> <div class="hero-lead">
<h1 id="hero-heading" class="statement" aria-label="Research that runs."> <div class="hero-copy">
<span class="line line-research"><span class="word">Research</span></span> <h1 id="hero-heading" class="statement" aria-label="Research that runs.">
<span class="line line-runs"><span class="word"><span class="that">that</span> <span class="runs">runs.</span></span></span> <span class="line line-research"><span class="word">Research</span></span>
</h1> <span class="line line-runs"><span class="word"><span class="that">that</span> <span class="runs">runs.</span></span></span>
</h1>
<a class="product-card" href="https://nucleic.blakeslee.xyz"> <p class="mission">
<span class="card-index">01 / Flagship system</span> We engineer infrastructure that keeps intelligence forever online and forever
<span class="product-name">Nucleic <span aria-hidden="true">↗</span></span> active — immortal by design.
<span class="product-description"> </p>
Where agents live — persisted, orchestrated, observed. </div>
</span>
<span class="card-rule" aria-hidden="true"></span> <div class="technology-stack" data-technology-stack>
</a> <div class="technology-stage">
<div class="technology-panel">
<div class="technology-cards">
<a
id="technology-nucleic"
class="product-card is-active"
data-technology-card
href="https://nucleic.blakeslee.xyz"
>
<span class="card-index">01 / Flagship system</span>
<span class="product-name">Nucleic <span aria-hidden="true">↗</span></span>
<span class="product-description">
Where agents live — persisted, orchestrated, observed.
</span>
<span class="card-rule" aria-hidden="true"></span>
</a>
<a
id="technology-naros-nash"
class="product-card product-card-next"
data-technology-card
href="https://version.blakeslee.xyz/blakeslee-research?q=na&sort=recentupdate"
>
<span class="card-index">02 / Agent foundation</span>
<span class="product-name">narOS + nash <span aria-hidden="true">↗</span></span>
<span class="product-description">
The agent OS and shell — ready on turn zero, watching every command.
</span>
<span class="card-rule" aria-hidden="true"></span>
</a>
</div>
<div class="technology-index" aria-label="Choose a technology">
<button type="button" class="is-active" data-technology-jump="0" aria-label="Show Nucleic" aria-pressed="true">01</button>
<span aria-hidden="true">/</span>
<button type="button" data-technology-jump="1" aria-label="Show narOS and nash" aria-pressed="false">02</button>
</div>
</div>
</div>
<div class="technology-steps" aria-hidden="true">
<span data-technology-step="0"></span>
<span data-technology-step="1"></span>
</div>
</div>
</div> </div>
<p class="mission">
We engineer infrastructure that keeps intelligence forever online and forever
active — immortal by design.
</p>
</section> </section>
</main> </main>
@@ -410,6 +450,7 @@ const canonical = new URL('/', Astro.site);
} }
.card-index, .card-index,
.technology-index,
.footer { .footer {
font-family: 'JetBrains Mono', monospace; font-family: 'JetBrains Mono', monospace;
font-size: 0.78rem; font-size: 0.78rem;
@@ -436,10 +477,7 @@ const canonical = new URL('/', Astro.site);
--hero-span-4: calc(var(--hero-col) * 4 + 3 * var(--hero-gap)); --hero-span-4: calc(var(--hero-col) * 4 + 3 * var(--hero-gap));
display: grid; display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr)); min-height: 100%;
column-gap: var(--hero-gap);
row-gap: clamp(1.9rem, 4.4vh, 4rem);
min-height: 0;
align-content: center; align-content: center;
padding: clamp(1.75rem, 4.5vh, 4.5rem) 0 clamp(1.5rem, 3vh, 3rem); padding: clamp(1.75rem, 4.5vh, 4.5rem) 0 clamp(1.5rem, 3vh, 3rem);
} }
@@ -451,13 +489,63 @@ const canonical = new URL('/', Astro.site);
headline's minimum width outgrows its share, the line breaks, and the card headline's minimum width outgrows its share, the line breaks, and the card
steps down instead of being printed over. */ steps down instead of being printed over. */
.hero-lead { .hero-lead {
grid-column: 1 / -1;
grid-row: 1;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: flex-end; align-items: flex-end;
column-gap: var(--hero-gap); column-gap: var(--hero-gap);
row-gap: clamp(1.5rem, 3vh, 2.5rem); row-gap: clamp(2.75rem, 7vh, 6rem);
}
.hero-lead.has-scroll-stack {
position: relative;
min-height: clamp(68rem, 185svh, 108rem);
align-items: stretch;
}
.hero-copy {
display: grid;
flex: 1 1 var(--hero-span-8);
align-self: flex-end;
gap: clamp(1.9rem, 4.4vh, 4rem);
}
.has-scroll-stack .hero-copy {
position: sticky;
top: 50svh;
align-self: flex-start;
transform: translateY(-50%);
}
/* Enlarged type and middle-width windows can make the flex line wrap before the
phone breakpoint. The script detects that actual wrap from geometry; once it
happens, the story becomes one column so its two sticky elements never occupy
the same band of the viewport. */
.hero-lead.is-stacked-stack {
display: block;
min-height: 0;
}
.is-stacked-stack .hero-copy {
position: relative;
top: auto;
transform: none;
}
.is-stacked-stack .technology-stack {
width: min(100%, 28rem);
min-width: 0;
min-height: 135svh;
margin-top: clamp(3.25rem, 9vh, 6rem);
margin-left: auto;
}
.is-stacked-stack .technology-stage {
top: clamp(8.5rem, 28svh, 14rem);
transform: none;
}
.is-stacked-stack .technology-cards {
min-height: 11.9rem;
} }
.statement { .statement {
@@ -470,15 +558,6 @@ const canonical = new URL('/', Astro.site);
--optical-inset: 0.078em; --optical-inset: 0.078em;
display: grid; display: grid;
/* Flex sizes the border box, so the basis has to give back what the negative
margin takes or the card lands inside the eight columns. The half-pixel keeps
sub-pixel rounding in the two calc()s from ever summing past the hero width and
breaking the line at normal size; flex-grow hands it straight back. */
flex: 1 1 calc(var(--hero-span-8) + var(--optical-inset) - 0.5px);
/* Fills the row the way a stretched grid item did, so on the narrow desktop
widths where the card is the taller of the two, the headline's own rows keep
the extra height instead of collapsing to the card's baseline. */
align-self: stretch;
justify-items: start; justify-items: start;
margin: 0 0 0 calc(-1 * var(--optical-inset)); margin: 0 0 0 calc(-1 * var(--optical-inset));
font-size: clamp(3.2rem, min(9vw, 18vh), 8.25rem); font-size: clamp(3.2rem, min(9vw, 18vh), 8.25rem);
@@ -618,8 +697,6 @@ const canonical = new URL('/', Astro.site);
} }
.mission { .mission {
grid-column: 1 / span 4;
grid-row: 2;
max-width: 29rem; max-width: 29rem;
margin: 0; margin: 0;
color: var(--secondary); color: var(--secondary);
@@ -629,19 +706,76 @@ const canonical = new URL('/', Astro.site);
animation: fade-up 700ms 850ms ease-out forwards; animation: fade-up 700ms 850ms ease-out forwards;
} }
.technology-stack {
position: relative;
flex: 0 1 var(--hero-span-4);
align-self: flex-end;
min-width: min(100%, 18rem);
}
.has-scroll-stack .technology-stack {
align-self: stretch;
}
.technology-stage {
position: relative;
z-index: 1;
}
.is-scroll-stack .technology-stage {
position: sticky;
top: 50svh;
transform: translateY(-50%);
}
.technology-panel {
opacity: 0;
animation: fade-up 700ms 980ms ease-out forwards;
}
.technology-cards {
display: grid;
gap: clamp(1.5rem, 3vh, 2.25rem);
}
.is-scroll-stack .technology-cards {
min-height: 11.6rem;
}
.product-card { .product-card {
position: relative; position: relative;
display: grid; display: grid;
/* Never grows, so the half-pixel the headline gives up comes back to the headline
alone and the card starts exactly on the ninth column line. */
flex: 0 1 var(--hero-span-4);
grid-template-columns: 1fr; grid-template-columns: 1fr;
align-content: start;
gap: 0.55rem; gap: 0.55rem;
padding: 1.15rem 0 1.05rem; padding: 1.15rem 0 1.05rem;
border-top: 1px solid var(--line); border-top: 1px solid var(--line);
text-decoration: none; text-decoration: none;
}
.is-scroll-stack .product-card {
grid-area: 1 / 1;
opacity: 0; opacity: 0;
animation: fade-up 700ms 980ms ease-out forwards; visibility: hidden;
pointer-events: none;
transform: translate3d(0, -1.5rem, 0) scale(0.985);
transition:
opacity 320ms ease,
visibility 0s linear 320ms,
transform 420ms cubic-bezier(0.2, 0.75, 0.2, 1);
}
.is-scroll-stack .product-card-next {
transform: translate3d(0, 1.5rem, 0) scale(0.985);
}
.is-scroll-stack .product-card.is-active {
z-index: 1;
opacity: 1;
visibility: visible;
pointer-events: auto;
transform: translate3d(0, 0, 0) scale(1);
transition-delay: 80ms, 0s, 0s;
} }
.product-card::after { .product-card::after {
@@ -680,6 +814,54 @@ const canonical = new URL('/', Astro.site);
line-height: 1.45; line-height: 1.45;
} }
.technology-index {
display: none;
align-items: center;
justify-content: flex-end;
gap: 0.45rem;
margin-top: 0.75rem;
color: var(--muted);
}
.is-scroll-stack .technology-index {
display: flex;
}
.technology-index button {
appearance: none;
border: 0;
padding: 0.3rem;
color: inherit;
background: transparent;
font: inherit;
letter-spacing: inherit;
line-height: inherit;
cursor: pointer;
transition: color 220ms ease;
}
.technology-index button:hover,
.technology-index button:focus-visible,
.technology-index button.is-active {
color: var(--pine);
}
.technology-index button:focus-visible {
outline-offset: 1px;
}
.technology-steps {
position: absolute;
inset: 0;
display: none;
grid-template-rows: repeat(2, minmax(0, 1fr));
pointer-events: none;
}
.is-scroll-stack .technology-steps {
display: grid;
}
.footer { .footer {
padding-top: 1rem; padding-top: 1rem;
border-top: 1px solid var(--line); border-top: 1px solid var(--line);
@@ -797,8 +979,6 @@ const canonical = new URL('/', Astro.site);
} }
.hero { .hero {
grid-template-columns: 1fr;
row-gap: clamp(1.75rem, 5vh, 3rem);
padding-top: clamp(2.5rem, 8vh, 5rem); padding-top: clamp(2.5rem, 8vh, 5rem);
} }
@@ -810,34 +990,49 @@ const canonical = new URL('/', Astro.site);
margin-left: 1.2em; margin-left: 1.2em;
} }
/* One column, so there is nothing for the headline to collide with and no need
for the flex line. Dissolving the wrapper puts all three back on the hero grid,
where explicit rows keep the phone order the design has always had — the DOM
carries the card first because that is where it reads on the desktop layout. */
.hero-lead { .hero-lead {
display: contents; display: block;
} }
.statement, .hero-lead.has-scroll-stack {
.mission, min-height: 0;
.product-card {
grid-column: 1;
} }
.statement { .hero-copy,
grid-row: 1; .has-scroll-stack .hero-copy {
position: relative;
top: auto;
display: grid;
gap: clamp(1.75rem, 5vh, 3rem);
transform: none;
} }
.mission { .mission {
grid-row: 2;
max-width: 25rem; max-width: 25rem;
} }
/* Stacked, the card is a separate thought from the hero copy rather than the .technology-stack {
column beside it, so it wants more air above than the hero's row rhythm gives. */ width: 100%;
.product-card { min-width: 0;
grid-row: 3; margin-top: clamp(3.25rem, 9vh, 6rem);
margin-top: clamp(0.75rem, 3.5vh, 2.25rem); }
.hero-lead.is-stacked-stack .technology-stack {
width: 100%;
margin-left: 0;
}
.has-scroll-stack .technology-stack {
min-height: 135svh;
}
.is-scroll-stack .technology-stage {
top: clamp(8.5rem, 28svh, 14rem);
transform: none;
}
.is-scroll-stack .technology-cards {
min-height: 11.9rem;
} }
/* One line each: side by side these two need ~360px of tracking-heavy mono, which /* One line each: side by side these two need ~360px of tracking-heavy mono, which
@@ -959,6 +1154,7 @@ const canonical = new URL('/', Astro.site);
.masthead, .masthead,
.line, .line,
.mission, .mission,
.technology-panel,
.product-card, .product-card,
.footer { .footer {
opacity: 1; opacity: 1;
@@ -966,3 +1162,61 @@ const canonical = new URL('/', Astro.site);
} }
} }
</style> </style>
<script>
const technologyStack = document.querySelector<HTMLElement>('[data-technology-stack]');
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
if (technologyStack && 'IntersectionObserver' in window && !reducedMotion.matches) {
const heroLead = technologyStack.closest<HTMLElement>('.hero-lead');
const heroCopy = heroLead?.querySelector<HTMLElement>('.hero-copy');
const cards = [...technologyStack.querySelectorAll<HTMLAnchorElement>('[data-technology-card]')];
const steps = [...technologyStack.querySelectorAll<HTMLElement>('[data-technology-step]')];
const jumps = [...technologyStack.querySelectorAll<HTMLButtonElement>('[data-technology-jump]')];
heroLead?.classList.add('has-scroll-stack');
if (heroLead && heroCopy) {
const stackWrappedBelow = technologyStack.offsetLeft <= heroCopy.offsetLeft + 1;
heroLead.classList.toggle('is-stacked-stack', stackWrappedBelow);
}
technologyStack.classList.add('is-scroll-stack');
const activateTechnology = (index: number) => {
cards.forEach((card, cardIndex) => {
const isActive = cardIndex === index;
card.classList.toggle('is-active', isActive);
card.toggleAttribute('inert', !isActive);
card.setAttribute('aria-hidden', String(!isActive));
});
jumps.forEach((jump, jumpIndex) => {
const isActive = jumpIndex === index;
jump.classList.toggle('is-active', isActive);
jump.setAttribute('aria-pressed', String(isActive));
});
};
activateTechnology(0);
const stepObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const index = Number((entry.target as HTMLElement).dataset.technologyStep);
if (Number.isInteger(index)) activateTechnology(index);
});
},
{ rootMargin: '-45% 0px -45% 0px' },
);
steps.forEach((step) => stepObserver.observe(step));
jumps.forEach((jump) => {
jump.addEventListener('click', () => {
const index = Number(jump.dataset.technologyJump);
if (!Number.isInteger(index) || !steps[index]) return;
activateTechnology(index);
steps[index].scrollIntoView({ behavior: 'smooth', block: 'center' });
});
});
}
</script>