ncei hero
This commit is contained in:
1 parent
2b509386eb
commit
00edb9dfc2
3 files changed
+109
-20
No files matched your search
@@ -5,14 +5,57 @@ const { lang } = Astro.props;
|
||||
const ui = t(lang);
|
||||
const s = ui.verifier.soon;
|
||||
const n = s.notify;
|
||||
|
||||
/* The background: a relief of thin ridge lines, computed once at build time. Each line is a row
|
||||
of smooth value noise, lifted most on the right where the page is quiet and nearly flat under
|
||||
the text on the left. Rows are drawn back to front and filled with night, so a nearer ridge
|
||||
hides the one behind it. Colour runs through the logo blues, deep at the back to cyan in front. */
|
||||
const W = 1600, H = 1000, rows = 46, steps = 160;
|
||||
const hash = (x: number, y: number) => {
|
||||
const h = Math.sin(x * 127.1 + y * 311.7) * 43758.5453;
|
||||
return h - Math.floor(h);
|
||||
};
|
||||
const smooth = (t: number) => t * t * (3 - 2 * t);
|
||||
const value = (x: number, y: number) => {
|
||||
const xi = Math.floor(x), yi = Math.floor(y), xf = smooth(x - xi), yf = smooth(y - yi);
|
||||
const a = hash(xi, yi), b = hash(xi + 1, yi), c = hash(xi, yi + 1), d = hash(xi + 1, yi + 1);
|
||||
return a + (b - a) * xf + (c - a) * yf + (a - b - c + d) * xf * yf;
|
||||
};
|
||||
const fbm = (x: number, y: number) => value(x, y) * 0.6 + value(x * 2.1 + 5, y * 2.1) * 0.28 + value(x * 4.3 + 9, y * 4.3) * 0.12;
|
||||
const ridges = Array.from({ length: rows }, (_, r) => {
|
||||
const depth = r / (rows - 1);
|
||||
const base = H * 0.22 + depth * H * 0.78;
|
||||
const pts = Array.from({ length: steps + 1 }, (_, i) => {
|
||||
const x = (i / steps) * W;
|
||||
const u = x / W;
|
||||
const envelope = Math.exp(-((u - 0.7) ** 2) / 0.045) * (0.35 + 0.65 * Math.sin(depth * Math.PI));
|
||||
const lift = Math.max(0, fbm(u * 5.5, r * 0.22) - 0.3) * 480 * envelope;
|
||||
return `${x.toFixed(1)},${(base - lift).toFixed(1)}`;
|
||||
});
|
||||
return {
|
||||
d: `M${pts.join(' L')} L${W},${H} L0,${H} Z`,
|
||||
mix: Math.round(depth * 100),
|
||||
alpha: (0.35 + depth * 0.5).toFixed(2),
|
||||
};
|
||||
});
|
||||
---
|
||||
<section class="shero night" aria-labelledby="shero-title">
|
||||
<div class="shero__media" aria-hidden="true">
|
||||
<svg class="shero__relief" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMax slice" xmlns="http://www.w3.org/2000/svg">
|
||||
{ridges.map((r) => (
|
||||
<path d={r.d} style={`--mix: ${r.mix}%; --alpha: ${r.alpha}`} />
|
||||
))}
|
||||
</svg>
|
||||
<div class="shero__overlay"></div>
|
||||
</div>
|
||||
|
||||
<div class="container shero__inner">
|
||||
<!-- First in the document, last on screen: the product name, set across the full width. -->
|
||||
<h1 id="shero-title" class="shero__name">{s.title[0].replace(/\.$/, '')}<span class="visually-hidden">. {s.title[1]}</span></h1>
|
||||
|
||||
<div class="shero__text">
|
||||
<p class="eyebrow">{s.eyebrow}</p>
|
||||
<h1 id="shero-title" class="display shero__title">
|
||||
{s.title.map((line, i) => <span class:list={['line', { 'line--muted': i > 0 }]}>{line}</span>)}
|
||||
</h1>
|
||||
<p class="shero__soon" aria-hidden="true">{s.title[1]}</p>
|
||||
<p class="shero__lead">{s.lead}</p>
|
||||
</div>
|
||||
|
||||
@@ -52,31 +95,71 @@ const n = s.notify;
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.line { display: block; }
|
||||
.line--muted { color: var(--ink-muted); }
|
||||
.shero {
|
||||
position: relative;
|
||||
/* Runs up under the floating header, as the home hero does, so the bar takes the night tone. */
|
||||
margin-top: calc(-1 * var(--header-height));
|
||||
overflow: hidden;
|
||||
}
|
||||
.shero__media { position: absolute; inset: 0; animation: shero-settle var(--dur-hero) var(--ease) both; transform-origin: 60% 50%; }
|
||||
.shero__relief { width: 100%; height: 100%; display: block; }
|
||||
.shero__relief path {
|
||||
fill: var(--night);
|
||||
stroke: color-mix(in oklab, var(--logo-deep), var(--logo-cyan) var(--mix));
|
||||
stroke-opacity: var(--alpha);
|
||||
stroke-width: 1;
|
||||
vector-effect: non-scaling-stroke;
|
||||
}
|
||||
/* Darker on the left, where the type sits. */
|
||||
.shero__overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to right, rgb(14 16 15 / 0.7), rgb(14 16 15 / 0) 60%);
|
||||
}
|
||||
|
||||
.shero__inner {
|
||||
position: relative;
|
||||
display: grid;
|
||||
gap: var(--space-8);
|
||||
padding-block: var(--space-9) var(--space-7);
|
||||
min-height: calc(100svh - var(--header-height));
|
||||
padding-top: calc(var(--header-height) + var(--space-7));
|
||||
min-height: 100svh;
|
||||
align-content: end;
|
||||
}
|
||||
.shero__text { display: grid; gap: var(--space-5); justify-items: start; }
|
||||
.shero__title { text-wrap: balance; }
|
||||
.shero__text { display: grid; gap: var(--space-4); justify-items: start; }
|
||||
.shero__soon {
|
||||
font-size: var(--step-h2);
|
||||
letter-spacing: var(--track-h2);
|
||||
line-height: var(--leading-h2);
|
||||
font-weight: var(--weight-medium);
|
||||
}
|
||||
.shero__lead { max-width: 26em; color: var(--ink-muted); }
|
||||
|
||||
/* Fade the headline in line by line: the page's one load moment. */
|
||||
.shero__title .line, .shero__lead, .signup, .readout {
|
||||
/* The name: one word across the container, its lower edge cut by the section. */
|
||||
.shero__name {
|
||||
order: 9;
|
||||
font-size: var(--step-giant);
|
||||
font-weight: var(--weight-medium);
|
||||
letter-spacing: var(--track-display);
|
||||
line-height: 0.8;
|
||||
white-space: nowrap;
|
||||
margin-bottom: -0.1em;
|
||||
margin-left: -0.05em;
|
||||
}
|
||||
|
||||
/* The one load moment: the image settles, then the type arrives line by line. */
|
||||
@keyframes shero-settle { from { transform: scale(1.045); } to { transform: none; } }
|
||||
.shero__soon, .shero__lead, .signup, .readout, .shero__name {
|
||||
opacity: 0;
|
||||
animation: shero-in var(--dur-slow) var(--ease) forwards;
|
||||
}
|
||||
.shero__title .line:nth-child(1) { animation-delay: 120ms; }
|
||||
.shero__title .line:nth-child(2) { animation-delay: 280ms; }
|
||||
.shero__lead { animation-delay: 440ms; }
|
||||
.signup, .readout { animation-delay: 600ms; }
|
||||
.shero__name { animation-duration: 900ms; animation-delay: 200ms; }
|
||||
.shero__soon { animation-delay: 500ms; }
|
||||
.shero__lead { animation-delay: 640ms; }
|
||||
.signup, .readout { animation-delay: 780ms; }
|
||||
@keyframes shero-in { to { opacity: 1; } }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.shero__title .line, .shero__lead, .signup, .readout { animation: none; opacity: 1; }
|
||||
.shero__media { animation: none; }
|
||||
.shero__soon, .shero__lead, .signup, .readout, .shero__name { animation: none; opacity: 1; }
|
||||
}
|
||||
|
||||
/* Sign-up: a framed instrument panel. */
|
||||
@@ -85,6 +168,7 @@ const n = s.notify;
|
||||
display: grid;
|
||||
gap: var(--space-5);
|
||||
padding: var(--space-6);
|
||||
background: var(--glass-on-night);
|
||||
align-content: start;
|
||||
justify-items: start;
|
||||
}
|
||||
@@ -126,6 +210,7 @@ const n = s.notify;
|
||||
letter-spacing: var(--track-caps);
|
||||
text-transform: uppercase;
|
||||
line-height: var(--leading-small);
|
||||
background: var(--glass-on-night);
|
||||
}
|
||||
.readout__cell {
|
||||
display: grid;
|
||||
@@ -142,17 +227,19 @@ const n = s.notify;
|
||||
.signup { padding: var(--space-5); }
|
||||
}
|
||||
|
||||
/* Wide: headline across seven columns, sign-up across four beside it, the strip along the foot. */
|
||||
/* Wide: the line and lead on the left, sign-up on the right, the strip, then the name. */
|
||||
@media (min-width: 64rem) {
|
||||
.shero__inner {
|
||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||
column-gap: var(--gap);
|
||||
row-gap: var(--space-9);
|
||||
row-gap: var(--space-6);
|
||||
align-items: end;
|
||||
}
|
||||
.shero__text { grid-column: 1 / span 7; }
|
||||
.signup { padding: var(--space-5) var(--space-6); gap: var(--space-4); }
|
||||
.shero__text { grid-column: 1 / span 6; }
|
||||
.signup { grid-column: 9 / span 4; }
|
||||
.readout { grid-column: 1 / -1; grid-template-columns: 1fr 2fr 2fr 2fr; }
|
||||
.shero__name { grid-column: 1 / -1; margin-top: var(--space-4); }
|
||||
.readout__cell { grid-template-columns: 1fr; gap: var(--space-1); padding: var(--space-4) var(--space-5); }
|
||||
.readout__cell + .readout__cell { border-top: 0; border-left: var(--hairline) solid var(--line-on-night); }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user