Skip to content

Commit 90e2a1d

Browse files
committed
Landing: Pharos engraving hero; drop og.png
The Lighthouse of Alexandria plate becomes the hero backdrop — the beam sweeps from the tower down to the small ship steering by its light at bottom-left. The wordmark moves to the top-left over the dark sky and the headline block to the bottom-right, so both sit on quiet areas of the plate. A light uniform scrim plus two corner shields keep the type crisp while the beam and the ship stay in view; the plate is monochrome warm sepia already, so it ships unfiltered. Replaces the constellation canvas. og.png and its meta tags go — the twitter card drops to summary.
1 parent aaca165 commit 90e2a1d

4 files changed

Lines changed: 36 additions & 120 deletions

File tree

frontend/landing/index.html

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,9 @@
1414
<meta property="og:description" content="Literature, code, experiments, and the write-up, in one place. Open source and model-agnostic, on your keys." />
1515
<meta property="og:url" content="https://openscience.sh" />
1616
<meta property="og:site_name" content="OpenScience" />
17-
<meta property="og:image" content="https://openscience.sh/og.png" />
18-
<meta property="og:image:secure_url" content="https://openscience.sh/og.png" />
19-
<meta property="og:image:type" content="image/png" />
20-
<meta property="og:image:width" content="1200" />
21-
<meta property="og:image:height" content="630" />
22-
<meta property="og:image:alt" content="OpenScience. The open-source AI workbench for scientific research." />
23-
<meta name="twitter:card" content="summary_large_image" />
17+
<meta name="twitter:card" content="summary" />
2418
<meta name="twitter:title" content="OpenScience. The open-source AI workbench for scientific research." />
2519
<meta name="twitter:description" content="Literature, code, experiments, and the write-up, in one place. On any model, with your keys." />
26-
<meta name="twitter:image" content="https://openscience.sh/og.png" />
27-
<meta name="twitter:image:alt" content="OpenScience. The open-source AI workbench for scientific research." />
2820
<meta name="twitter:site" content="@SynScience" />
2921

3022
<link rel="preconnect" href="https://fonts.googleapis.com" />

frontend/landing/public/og.png

-518 KB
Binary file not shown.
619 KB
Loading

frontend/landing/src/pages/Landing.tsx

Lines changed: 35 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useMemo, useRef, useState } from "react";
22
import workspaceShot from "@/assets/workspace.png";
33
import modelPickerShot from "@/assets/model-picker.png";
4+
import heroPlate from "@/assets/hero.webp";
45

56
/* OpenScience. CMU Concrete, warm dark, coral accents.
67
Same design family as the Atlas landing page.
@@ -259,100 +260,25 @@ function Section({
259260
);
260261
}
261262

262-
/* --------------------------- Hero constellation ------------------------- */
263-
/* A slow, drifting field of faint points joined into a constellation.
264-
Cream nodes, a few coral. Pure canvas, no library. */
265-
266-
function Constellation() {
267-
const ref = useRef<HTMLCanvasElement>(null);
268-
useEffect(() => {
269-
const canvas = ref.current;
270-
if (!canvas) return;
271-
const ctx = canvas.getContext("2d");
272-
if (!ctx) return;
273-
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
274-
const dpr = Math.min(window.devicePixelRatio || 1, 2);
275-
let raf = 0;
276-
let w = 0;
277-
let h = 0;
278-
type Pt = { x: number; y: number; vx: number; vy: number; r: number; hot: boolean };
279-
let pts: Pt[] = [];
280-
281-
const resize = () => {
282-
const rect = canvas.getBoundingClientRect();
283-
w = rect.width;
284-
h = rect.height;
285-
canvas.width = Math.round(w * dpr);
286-
canvas.height = Math.round(h * dpr);
287-
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
288-
const count = Math.min(120, Math.max(50, Math.floor((w * h) / 15000)));
289-
pts = Array.from({ length: count }, () => ({
290-
x: Math.random() * w,
291-
y: Math.random() * h,
292-
vx: (Math.random() - 0.5) * 0.14,
293-
vy: (Math.random() - 0.5) * 0.14,
294-
r: Math.random() < 0.14 ? 1.7 : 1.05,
295-
hot: Math.random() < 0.055,
296-
}));
297-
};
298-
299-
const LINK = 120;
300-
const draw = () => {
301-
ctx.clearRect(0, 0, w, h);
302-
for (let i = 0; i < pts.length; i++) {
303-
const a = pts[i];
304-
for (let j = i + 1; j < pts.length; j++) {
305-
const b = pts[j];
306-
const dx = a.x - b.x;
307-
const dy = a.y - b.y;
308-
const d2 = dx * dx + dy * dy;
309-
if (d2 < LINK * LINK) {
310-
const t = 1 - Math.sqrt(d2) / LINK;
311-
ctx.strokeStyle = `hsla(42, 32%, 88%, ${(t * 0.13).toFixed(3)})`;
312-
ctx.lineWidth = 0.6;
313-
ctx.beginPath();
314-
ctx.moveTo(a.x, a.y);
315-
ctx.lineTo(b.x, b.y);
316-
ctx.stroke();
317-
}
318-
}
319-
}
320-
for (const p of pts) {
321-
ctx.beginPath();
322-
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
323-
ctx.fillStyle = p.hot ? "hsla(14, 70%, 64%, 0.75)" : "hsla(42, 32%, 88%, 0.4)";
324-
ctx.fill();
325-
}
326-
};
327-
328-
const step = () => {
329-
for (const p of pts) {
330-
p.x += p.vx;
331-
p.y += p.vy;
332-
if (p.x < -8) p.x = w + 8;
333-
if (p.x > w + 8) p.x = -8;
334-
if (p.y < -8) p.y = h + 8;
335-
if (p.y > h + 8) p.y = -8;
336-
}
337-
draw();
338-
raf = window.requestAnimationFrame(step);
339-
};
340-
341-
resize();
342-
draw();
343-
if (!reduced) raf = window.requestAnimationFrame(step);
344-
const onResize = () => {
345-
resize();
346-
draw();
347-
};
348-
window.addEventListener("resize", onResize);
349-
return () => {
350-
window.cancelAnimationFrame(raf);
351-
window.removeEventListener("resize", onResize);
352-
};
353-
}, []);
354-
return <canvas ref={ref} className="absolute inset-0 w-full h-full" aria-hidden />;
355-
}
263+
/* ----------------------------- Hero plate ------------------------------- */
264+
/* The Pharos of Alexandria engraving — the beam sweeps from the tower at the
265+
right down to a small ship steering by its light at bottom-left. The plate
266+
is already monochrome warm sepia, the same hue family as the site's cream,
267+
so it ships unfiltered. Anchored right; on wide viewports the background
268+
color fills the left edge and the veil blends the seam. */
269+
270+
const HERO_NOISE =
271+
"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E\")";
272+
273+
/* Veil: a light uniform scrim softens the plate; a soft top-left shield sits
274+
under the wordmark and a bottom-right shield under the copy, so the beam
275+
and the ship at bottom-left stay in view. */
276+
const HERO_VEIL = [
277+
"linear-gradient(hsl(30 14% 7% / 0.2), hsl(30 14% 7% / 0.2))",
278+
"radial-gradient(ellipse 55% 45% at 5% 6%, hsl(30 14% 7% / 0.8) 0%, hsl(30 14% 7% / 0.4) 55%, transparent 85%)",
279+
"radial-gradient(ellipse 85% 75% at 96% 94%, hsl(var(--background)) 0%, hsl(30 14% 7% / 0.84) 38%, hsl(30 14% 7% / 0.28) 66%, transparent 90%)",
280+
"linear-gradient(180deg, hsl(28 18% 4% / 0.5) 0%, transparent 15%)",
281+
].join(", ");
356282

357283
/* ------------------------------ Hero ----------------------------------- */
358284

@@ -389,46 +315,44 @@ function Hero() {
389315
return (
390316
<section className="relative h-screen min-h-[680px] w-full bg-background overflow-hidden grain">
391317
<div ref={backdrop} className="absolute inset-0 will-change-transform" aria-hidden>
392-
<div className="absolute inset-0 graticule opacity-[0.05]" />
393318
<div
394-
className="absolute inset-0"
395-
style={{
396-
maskImage: "linear-gradient(to bottom, black 55%, transparent 96%)",
397-
WebkitMaskImage: "linear-gradient(to bottom, black 55%, transparent 96%)",
398-
}}
399-
>
400-
<Constellation />
401-
</div>
319+
className="absolute inset-0 bg-background bg-no-repeat [background-position:62%_14%] [background-size:cover] sm:[background-position:right_center] sm:[background-size:auto_114%]"
320+
style={{ backgroundImage: `url(${heroPlate})` }}
321+
/>
322+
<div
323+
className="absolute inset-0 opacity-[0.32] mix-blend-overlay"
324+
style={{ backgroundImage: HERO_NOISE }}
325+
/>
326+
<div className="absolute inset-0" style={{ background: HERO_VEIL }} />
402327
</div>
403328

404329
<div
405330
className="pointer-events-none absolute inset-x-0 bottom-0 z-[5]"
406331
style={{
407-
height: "56%",
408-
background:
409-
"linear-gradient(to top, hsl(var(--background)) 0%, hsl(var(--background) / 0.9) 18%, hsl(var(--background) / 0.55) 46%, hsl(var(--background) / 0) 100%)",
332+
height: "16%",
333+
background: "linear-gradient(to top, hsl(var(--background)) 0%, hsl(var(--background) / 0) 100%)",
410334
}}
411335
/>
412336

413337
<div className="absolute inset-0 z-10 mx-auto flex h-full max-w-[1400px] flex-col px-6 sm:px-10">
414-
<div className="hero-text rise self-end text-right mt-[9vh]" style={{ animationDelay: "120ms" }}>
338+
<div className="hero-text rise self-start mt-[9vh]" style={{ animationDelay: "120ms" }}>
415339
<div className="text-[clamp(40px,6.4vw,96px)] leading-[0.9] tracking-[-0.04em]">openscience</div>
416-
<div className="mt-3 text-[13px] tracking-[0.04em] text-foreground/50">by Synthetic Sciences</div>
340+
<div className="mt-3 text-[13px] tracking-[0.04em] text-foreground/55">by Synthetic Sciences</div>
417341
</div>
418342

419-
<div ref={copy} className="hero-text mt-auto mb-[7vh] max-w-[820px]">
343+
<div ref={copy} className="hero-text mt-auto mb-[7vh] self-end text-right max-w-[820px]">
420344
<div className="rise" style={{ animationDelay: "260ms" }}>
421345
<h1 className="text-balance text-[clamp(34px,4.6vw,62px)] leading-[1.04] tracking-[-0.024em] text-foreground">
422346
The open-source AI workbench for scientists.
423347
</h1>
424348
</div>
425349
<div className="rise" style={{ animationDelay: "420ms" }}>
426-
<p className={`mt-6 max-w-[54ch] ${P_BIG} text-foreground/80`}>
350+
<p className={`mt-6 ml-auto max-w-[44ch] ${P_BIG} text-foreground/85`}>
427351
One environment for the whole loop: literature, code, experiments, figures,
428352
and the write-up. In your browser, on any model, with your keys.
429353
</p>
430354
</div>
431-
<div className="rise mt-9 flex flex-wrap items-center gap-3 [text-shadow:none]" style={{ animationDelay: "580ms" }}>
355+
<div className="rise mt-9 flex flex-wrap items-center justify-end gap-3 [text-shadow:none]" style={{ animationDelay: "580ms" }}>
432356
<Cta href="#install">Install OpenScience</Cta>
433357
<Cta href={GITHUB} variant="ghost" arrow={false} external>
434358
<svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden>

0 commit comments

Comments
 (0)