{title}
+{children}
+From ac6c5d24f0822cc77030dccc2c21a89ff311921f Mon Sep 17 00:00:00 2001
From: Joseph Dale Banares {card.subtitle}
@@ -229,6 +240,7 @@ function RouteDetail({ toggle }: { toggle: ReactNode }) {
const byId = new Map(draft.nodes.map((n) => [n.id, n]));
const edgeById = new Map(draft.edges.map((e) => [e.id, e]));
const title = (id: string) => byId.get(id)?.card.title ?? id;
+ const H = useHeading(0);
const header = (
No directed connections lead from one to the other. void }) {
+/** Without `onToggleMinimap` the bar has no minimap button. */
+export function ZoomBar({ minimapOn = false, onToggleMinimap }: { minimapOn?: boolean; onToggleMinimap?: () => void }) {
const { transform, zoomIn, zoomOut, fit } = useViewport();
return (
{title}
+ {n.title}
+
{n.items.map((item, j) => (
{card.title}
+
+
+
{!route ? (
+ {shown ? TRIES.find((t) => t.id === shown)!.desc : IDLE} +
+validate names each problem with a code and the allowed fixes. The agent repairs what is named.
+ >
+ ),
+ },
+ {
+ n: '04',
+ title: 'One file comes back.',
+ desc: (
+ <>
+ deliver lays the diagram out and writes one self-contained HTML viewer.
+ >
+ ),
+ },
+];
+
+const i = (n: number) => ({ '--i': n }) as CSSProperties;
+
+function Tool({ s, at, verb, children }: { s: number; at: number; verb: string; children: ReactNode }) {
+ return (
+
+
+ {verb}
+ {children}
+
+ );
+}
+function Out({ s, at, tone = '', children }: { s: number; at: number; tone?: string; children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
+const K = ({ children }: { children: string }) => "{children}";
+const S = ({ children }: { children: string }) => "{children}";
+
+// The diagram.json the agent writes, cut to the lines the repair touches: the edge that names a node that isn't there.
+function Json({ title }: { title: string }) {
+ const lines: { n: string; cls?: string; c: ReactNode }[] = [
+ { n: '1', c: '{' },
+ { n: '2', c: <> ": the edit lands where it points.
+ const pointer = repair.broken[0]?.trim().split(/\s+/)[2] ?? '';
+
+ return (
+
+
+
+
+
+
+
+ {STEPS.map((s, n) => (
+ -
+
+
+ ))}
+
+
+
+
+
+ ~/commerce-api
+
+
+
+
+ Make an architecture diagram of this repository, backed by evidence from the code.
+
+
+ .stackmap/commerce-api/diagram.json
+
+
+ {nodes.length} nodes · {edges.length} connections · {views?.length ?? 0} views
+
+
+ stackmap validate diagram.json
+
+ {repair.broken.map((line, n) => (
+
+ {line}
+
+ ))}
+
+ diagram.json {pointer} → "orders"
+
+
+ stackmap validate diagram.json
+
+ {repair.clean.map((line, n) => (
+
+ {line}
+
+ ))}
+
+ stackmap deliver diagram.json
+
+
+ delivered {receipt.file}
+
+
+ {` · sha256 ${short} · ${receipt.bytes} bytes`}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/site/components/landing/Install.tsx b/site/components/landing/Install.tsx
new file mode 100644
index 0000000..96eafef
--- /dev/null
+++ b/site/components/landing/Install.tsx
@@ -0,0 +1,76 @@
+import Link from 'next/link';
+import { BookOpen, Map } from 'lucide-react';
+import { LINKS } from '@/components/site/links';
+import { Lockup } from '@/components/site/Lockup';
+import { Cmd } from '@/components/ui/Cmd';
+import { CopyButton } from '@/components/ui/CopyButton';
+import { GitHubIcon, NpmIcon } from '@/components/ui/icons';
+
+export const ASK = 'Make an architecture diagram of this repository, backed by evidence from the code.';
+
+/** #install: the skill, the request to make, and the CLI on its own. */
+export function Install({ skill, cli }: { skill: string; cli: string }) {
+ return (
+
+
+
+
+
+
+
+ Every layer of your stack, on one map.
+
+ Interactive system diagrams your coding agent writes, as one offline HTML file.
+
+ -
+
+
+
Install the skill into your agent
+
+
+
+ -
+
+
+
Then ask
+
+ {ASK}
+
+
+
+
+
+
+
+ Or run the CLI on its own, with Node 22.12 or later: it turns any diagram.json into diagram.html beside
+ it.
+
+
+
+
+
+
+
+ );
+}
diff --git a/site/components/landing/KindCount.tsx b/site/components/landing/KindCount.tsx
deleted file mode 100644
index 74662a3..0000000
--- a/site/components/landing/KindCount.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-'use client';
-
-import { useEffect, useRef, useState } from 'react';
-import { HOLDS } from './kinds-geometry';
-
-/** The phone's "3 / 5 · one checkout, five ways", following the scroll while the scene scrubs. */
-export function KindCount({ rest, total }: { rest: number; total: number }) {
- const ref = useRef(null);
- const [kind, setKind] = useState(rest);
- useEffect(() => {
- const scene = ref.current?.closest('[data-scene]');
- if (!scene) return;
- const onScene = (e: Event) => {
- const pct = (e as CustomEvent).detail * 100;
- setKind(Math.max(0, HOLDS.findLastIndex(([a]) => pct >= a - 3.5)));
- };
- scene.addEventListener('scene', onScene);
- return () => scene.removeEventListener('scene', onScene);
- }, []);
- return (
-
- {kind + 1} / {total} · one checkout, five ways
-
- );
-}
diff --git a/site/components/landing/KindFlow.tsx b/site/components/landing/KindFlow.tsx
deleted file mode 100644
index f1b8b8d..0000000
--- a/site/components/landing/KindFlow.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-'use client';
-
-import { useCallback, useRef } from 'react';
-import { FlowLayer, type FlowClock } from '@stackmap/viewer/src/canvas/FlowLayer';
-import { holdTime, type KindFlow as Data } from './kinds-geometry';
-import { s } from './style';
-
-/** Kind k's pulses over its layer, playing one loop through its hold as the scene scrubs; hidden at rest. */
-export function KindFlow({ data, k }: { data: Data; k: number }) {
- const box = useRef(null);
- const { flow, origin, width, height } = data;
- const clock = useCallback(
- (draw) => {
- const scene = box.current?.closest('[data-scene]');
- if (!scene) return () => {};
- const onScene = (e: Event) => draw(holdTime((e as CustomEvent).detail, k, flow.period));
- scene.addEventListener('scene', onScene);
- return () => scene.removeEventListener('scene', onScene);
- },
- [k, flow.period],
- );
- return (
-
-
-
- );
-}
diff --git a/site/components/landing/KindPills.tsx b/site/components/landing/KindPills.tsx
deleted file mode 100644
index d36eaee..0000000
--- a/site/components/landing/KindPills.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-'use client';
-
-import { useEffect, useRef, useState } from 'react';
-import { DIAGRAM_KINDS, KIND_LABELS } from '@stackmap/core';
-import { HOLDS } from './kinds-geometry';
-
-/**
- * The kind pills. While the page scrubs they seek to that kind's hold and follow the scroll; at rest they
- * switch the shown kind in place (the scene's data-kind picks the layer, faces and slot positions).
- */
-export function KindPills({ rest }: { rest: number }) {
- const ref = useRef(null);
- const [kind, setKind] = useState(rest);
- useEffect(() => {
- const scene = ref.current?.closest('[data-scene]');
- if (!scene) return;
- const onScene = (e: Event) => {
- const pct = (e as CustomEvent).detail * 100;
- setKind(Math.max(0, HOLDS.findLastIndex(([a]) => pct >= a - 3.5)));
- };
- scene.addEventListener('scene', onScene);
- return () => scene.removeEventListener('scene', onScene);
- }, []);
- const pick = (k: number) => {
- const scene = ref.current?.closest('[data-scene]');
- const root = scene?.closest('.lp');
- if (!scene || !root) return;
- setKind(k);
- if (root.classList.contains('live')) {
- const [a, b] = HOLDS[k]!;
- root.dispatchEvent(new CustomEvent('seek', { detail: { id: scene.dataset.scene, p: (a + b) / 200 } }));
- } else scene.dataset.kind = DIAGRAM_KINDS[k];
- };
- return (
-
- {DIAGRAM_KINDS.map((k, i) => (
-
- ))}
-
- );
-}
diff --git a/site/components/landing/Kinds.tsx b/site/components/landing/Kinds.tsx
new file mode 100644
index 0000000..d387872
--- /dev/null
+++ b/site/components/landing/Kinds.tsx
@@ -0,0 +1,118 @@
+'use client';
+
+import Link from 'next/link';
+import { useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent } from 'react';
+import { ArrowRight } from 'lucide-react';
+import { DIAGRAM_KINDS, KIND_LABELS, type DiagramKind, type LaidOutDiagram } from '@stackmap/core';
+import { LiveScene } from '@/components/diagram/LiveScene';
+
+const ABOUT: Record = {
+ architecture: { def: 'Components and what they call.', layout: 'Laid out by ELK, left to right or top down.' },
+ dataflow: { def: 'Data moving through stages.', layout: 'Laid out by ELK, in stages.' },
+ workflow: { def: 'Steps across owner lanes.', layout: 'Lanes laid out by stackmap.' },
+ lifecycle: { def: 'The states of one thing.', layout: 'States in lanes, laid out by stackmap.' },
+ sequence: { def: 'Messages over time.', layout: 'Lifelines laid out by stackmap.' },
+};
+
+/**
+ * #kinds: one checkout drawn as each kind. A tab swaps the layer (the old one fades in 120 ms) and the new one plays
+ * the viewer's intro, then loops its flow while the stage is on screen. Arrow keys switch at once.
+ */
+export function Kinds({ checkout }: { checkout: Record }) {
+ const [at, setAt] = useState(0);
+ // How many times each kind has been brought on: a new count replays its intro.
+ const [plays, setPlays] = useState(() => DIAGRAM_KINDS.map(() => 0));
+ const [visible, setVisible] = useState(false);
+ const stage = useRef(null);
+ const tabs = useRef(null);
+ const marker = useRef(null);
+ const seen = useRef(false);
+
+ const show = (i: number, intro: boolean) => {
+ setAt(i);
+ if (intro) setPlays((p) => p.map((n, j) => (j === i ? n + 1 : n)));
+ };
+
+ useEffect(() => {
+ const el = stage.current;
+ if (!el) return;
+ const io = new IntersectionObserver(
+ ([e]) => {
+ if (!e) return;
+ setVisible(e.isIntersecting);
+ // The first time it's on screen, the shown kind plays its intro.
+ if (e.isIntersecting && !seen.current) {
+ seen.current = true;
+ setPlays((p) => p.map((n, j) => (j === 0 ? n + 1 : n)));
+ }
+ },
+ { threshold: 0.25 },
+ );
+ io.observe(el);
+ return () => io.disconnect();
+ }, []);
+
+ useLayoutEffect(() => {
+ const place = () => {
+ const tab = tabs.current?.querySelectorAll('[role="tab"]')[at];
+ const m = marker.current;
+ if (!tab || !m) return;
+ m.style.width = `${tab.offsetWidth}px`;
+ m.style.translate = `${tab.offsetLeft}px 0`;
+ };
+ place();
+ void document.fonts?.ready.then(place);
+ addEventListener('resize', place);
+ return () => removeEventListener('resize', place);
+ }, [at]);
+
+ const onKeyDown = (e: KeyboardEvent) => {
+ const last = DIAGRAM_KINDS.length - 1;
+ const to = { ArrowRight: at === last ? 0 : at + 1, ArrowLeft: at === 0 ? last : at - 1, Home: 0, End: last }[e.key];
+ if (to === undefined) return;
+ e.preventDefault();
+ show(to, false);
+ tabs.current?.querySelectorAll('[role="tab"]')[to]?.focus();
+ };
+
+ const kind = DIAGRAM_KINDS[at]!;
+ return (
+
+
+
+ {DIAGRAM_KINDS.map((k, i) => (
+
+ ))}
+
+
+ {DIAGRAM_KINDS.map((k, i) => (
+
+
+
+ ))}
+
+
+
+ {ABOUT[kind].def}
+ {ABOUT[kind].layout}
+
+
+ {KIND_LABELS[kind]} diagrams
+
+
+
+
+ );
+}
diff --git a/site/components/landing/KindsStage.tsx b/site/components/landing/KindsStage.tsx
deleted file mode 100644
index 979db59..0000000
--- a/site/components/landing/KindsStage.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { DIAGRAM_KINDS, type DiagramKind, type LaidOutDiagram } from '@stackmap/core';
-import { NodeCard } from '@stackmap/viewer/src/card/NodeCard';
-import { StepCard } from '@stackmap/viewer/src/card/StepCard';
-import { Still } from '@/components/diagram/Still';
-import { stillOf } from '@/lib/diagrams';
-import { KindFlow } from './KindFlow';
-import { kindsGeometry, kindsTweens, restingFlow, type Area } from './kinds-geometry';
-import { s } from './style';
-
-const px = (n: number) => `${Math.round(n * 10) / 10}px`;
-
-/**
- * One checkout, five ways: each kind's layer (its lanes, phases and connections) plus the card slots that
- * glide between kinds. At rest the scene's data-kind picks what shows; scrolling plays the tweens it carries,
- * and each kind's flow in its hold.
- */
-export function KindsStage({ checkout, area, root }: { checkout: Record; area: Area; root: string }) {
- const g = kindsGeometry(checkout, area);
- const at = (kind: DiagramKind) => `${root} [data-kind="${kind}"]`;
- const restRules = DIAGRAM_KINDS.flatMap((kind, k) => [
- `${at(kind)} .kl${k}, ${at(kind)} .kdef${k} {opacity:1}`,
- `${at(kind)} .kcam {transform:scale(${g.layers[k]!.cam})}`,
- `${at(kind)} .kn-col {transform:translateY(${-260 * k}px)}`,
- ...g.slots.map((faces, i) => {
- const f = faces[k];
- const r = (f ?? faces.find(Boolean)!).rect;
- return `${at(kind)} .ks${i} {left:${px(r.x)};top:${px(r.y)};width:${px(r.width)};height:${px(r.height)};opacity:${f ? 1 : 0}}${f ? `${at(kind)} .kf${i}_${k} {opacity:1}` : ''}`;
- }),
- ]);
- // Escaping `<` keeps the JSON from closing its script early.
- const timelines = JSON.stringify(kindsTweens(g)).replace(/
-
-
-
- {g.layers.map((l, k) => (
-
-
-
-
- ))}
- {g.slots.map((faces, i) => (
-
- {faces.map((f, k) =>
- f ? (
-
-
- {f.compact ? : }
-
-
- ) : null,
- )}
-
- ))}
-
-
- );
-}
diff --git a/site/components/landing/Landing.tsx b/site/components/landing/Landing.tsx
index 5a77901..f9fb528 100644
--- a/site/components/landing/Landing.tsx
+++ b/site/components/landing/Landing.tsx
@@ -1,56 +1,88 @@
+import Link from 'next/link';
+import { ArrowRight } from 'lucide-react';
import type { LaidOutDiagram } from '@stackmap/core';
-import { Agent } from './desktop/Agent';
-import { Features } from './desktop/Features';
-import { Files } from './desktop/Files';
-import { Hero } from './desktop/Hero';
-import { Install } from './desktop/Install';
-import { Kinds } from './desktop/Kinds';
-import { Unmapped } from './desktop/Unmapped';
-import { Viewer } from './desktop/Viewer';
-import { HashAnchors } from './HashAnchors';
-import { LandingMotion } from './LandingMotion';
-import { Agent as MAgent } from './mobile/Agent';
-import { Features as MFeatures } from './mobile/Features';
-import { Files as MFiles } from './mobile/Files';
-import { Hero as MHero } from './mobile/Hero';
-import { Install as MInstall } from './mobile/Install';
-import { Kinds as MKinds } from './mobile/Kinds';
-import { Unmapped as MUnmapped } from './mobile/Unmapped';
-import { Viewer as MViewer } from './mobile/Viewer';
-import './desktop.css';
-import './mobile.css';
-import './site.css';
+import { Cmd } from '@/components/ui/Cmd';
+import { EXAMPLES } from '@/lib/catalog';
+import { stillOf } from '@/lib/diagrams';
+import { SITE } from '@/lib/site-data';
+import { spell } from '@/lib/words';
+import { HeroDemo } from './HeroDemo';
+import { How } from './How';
+import { Install } from './Install';
+import { Kinds } from './Kinds';
+import { Proof } from './Proof';
+import { Reveals } from './Reveals';
+import './landing.css';
-/**
- * The landing: the canvas's desktop composition (1440 × 900 frames), and its phone composition below 768px.
- * Both render on the server as their resting frames; LandingMotion scrubs whichever one is on screen.
- */
+const rise = (d: number) => ({ ['--d' as string]: `${d}ms` });
+
+/** The landing, after the canvas's "Landing" boards: one responsive page, desktop 1440 down to a 320 phone. */
export function Landing({ demo, checkout }: { demo: LaidOutDiagram; checkout: Record }) {
return (
<>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Every layer of your stack, on one map.
+
+
+ Interactive system diagrams your coding agent writes, as one offline HTML file.
+
+
+
+
+ Read the docs
+
+
+
+
+ Works with Claude Code, Cursor, Codex and other coding agents.
+
+
+
+
+
+
+
+
+
+
+
+ How it works
+
+ Ask your agent. One file comes back.
+
+ The agent writes a small typed diagram.json. stackmap checks it, lays it out and delivers a viewer you can open anywhere.
+
+
+
+
+
+
+
+
+ Five kinds
+
+ One checkout, five ways to draw it.
+
+ Pick the kind that answers the question. Each has its own layout, and every one plays its flow.
+
+
+
+ {spell(EXAMPLES.length, true)} diagrams, from release pipelines to maps a coding agent wrote from one request.
+
+ See the examples
+
+
+
+
+
+
+
+
+
>
);
}
diff --git a/site/components/landing/LandingMotion.tsx b/site/components/landing/LandingMotion.tsx
deleted file mode 100644
index e4a4993..0000000
--- a/site/components/landing/LandingMotion.tsx
+++ /dev/null
@@ -1,188 +0,0 @@
-'use client';
-
-import { useGSAP } from '@gsap/react';
-import { gsap } from 'gsap';
-import { CustomEase } from 'gsap/CustomEase';
-import { ScrollTrigger } from 'gsap/ScrollTrigger';
-import { sceneExtras, sceneTimeline, type Tween } from './timeline';
-
-gsap.registerPlugin(useGSAP, ScrollTrigger, CustomEase);
-
-// Each pinned scene owns one GSAP timeline, scrubbed by ScrollTrigger through its pin (Motion rule 01).
-// All of it lives inside gsap.matchMedia: with reduced motion, on the other composition's widths, or
-// before any script runs, nothing is set and every scene stays the resting frame the server drew (rule 02).
-
-interface Route {
- el: SVGPathElement;
- a: number;
- b: number;
- head: SVGGElement | null;
- len: number;
- k0: number;
-}
-
-const clamp = (x: number) => (x < 0 ? 0 : x > 1 ? 1 : x);
-
-function routesOf(root: HTMLElement, owner: string): Route[] {
- return [...root.querySelectorAll(`[data-route="${owner}"]`)].map((el) => ({
- el,
- a: parseFloat(el.dataset.r0 ?? '0'),
- b: parseFloat(el.dataset.r1 ?? '1'),
- head: el.dataset.head ? el.parentElement!.querySelector(`[data-route-head="${el.dataset.head}"]`) : null,
- len: 0,
- k0: 0,
- }));
-}
-
-function measureRoute(r: Route) {
- r.len = r.el.getTotalLength();
- // A route entering at its frame's top starts drawn a little way in, so the line from the scene above carries on.
- const top = r.len > 0 && r.el.getPointAtLength(0).y < 2;
- r.k0 = top ? Math.min(0.5, Number(r.el.dataset.stub ?? 104) / r.len) : 0;
-}
-
-// The route through-line draws with its scene's progress, in the gutter, and its head rides the tip.
-function drawRoute(r: Route, p: number) {
- const k = Math.max(r.k0, clamp((p - r.a) / Math.max(0.0001, r.b - r.a)));
- r.el.style.strokeDashoffset = String(1 - k);
- if (r.head && r.len) {
- const at = r.el.getPointAtLength(k * r.len);
- r.head.setAttribute('transform', `translate(${at.x} ${at.y})`);
- r.head.style.opacity = k > 0.002 && k < 0.998 ? '1' : '0';
- }
-}
-
-function animate(root: HTMLElement, tweens: Tween[]) {
- const nav = document.querySelector('header[data-nav]');
- const nav0 = nav?.dataset.theme;
- root.classList.add('live');
- const mark = root.querySelector('[data-mark-route]');
- mark?.classList.remove('drawn');
- const progress = new Map();
- const triggers = new Map();
- const allRoutes: Route[] = [];
-
- for (const el of root.querySelectorAll('[data-scene]')) {
- const id = el.dataset.scene!;
- const stage = el.querySelector('[data-stage]')!;
- const frame = el.querySelector('[data-frame]')!;
- const fw = Number(el.dataset.fw) || 1440;
- const fh = Number(el.dataset.fh) || 900;
- const runway = parseFloat(el.dataset.runway ?? '0');
- const routes = routesOf(root, id);
- allRoutes.push(...routes);
- // The frame keeps its design size and scales to fit the window, centred in the pinned stage.
- const fit = () => Math.min(1, innerWidth / fw, innerHeight / fh);
- gsap.set([el, stage], { height: '100vh' });
- gsap.set(frame, { top: '50%', left: '50%', xPercent: -50, yPercent: -50, scale: fit });
- const tl = sceneTimeline(el, [...tweens, ...sceneExtras(el)]);
- const st = ScrollTrigger.create({
- trigger: el,
- pin: true,
- start: 'top top',
- end: () => `+=${runway * innerHeight}`,
- scrub: true,
- animation: tl,
- invalidateOnRefresh: true,
- onRefresh: () => gsap.set(frame, { scale: fit() }),
- onUpdate: (self) => {
- const p = self.progress;
- progress.set(id, p);
- for (const r of routes) drawRoute(r, p);
- // The mark's route draws once, never scrubbed (Motion rule 03).
- if (id === 'unmapped' && p >= 0.53) mark?.classList.add('drawn');
- el.dispatchEvent(new CustomEvent('scene', { detail: p }));
- },
- });
- triggers.set(id, st);
- progress.set(id, 0);
- }
-
- // Sections that don't pin (features, install) draw their stretch of the route as they pass.
- for (const el of root.querySelectorAll('[data-sec]')) {
- const routes = routesOf(root, el.dataset.sec!);
- allRoutes.push(...routes);
- ScrollTrigger.create({ trigger: el, start: 'top 78%', end: 'bottom 78%', onUpdate: (self) => routes.forEach((r) => drawRoute(r, self.progress)) });
- }
- const measureRoutes = () => allRoutes.forEach(measureRoute);
- measureRoutes();
- ScrollTrigger.addEventListener('refresh', measureRoutes);
-
- for (const el of root.querySelectorAll('[data-rv]')) {
- ScrollTrigger.create({ trigger: el, start: 'top 90%', once: true, onEnter: () => el.classList.add('in') });
- }
-
- // The nav takes the theme of the section under it; the viewer's light, and the files scene's, can cover it first.
- const themed = [...root.querySelectorAll('[data-theme-sec]')];
- const files = root.querySelector('[data-scene="files"]');
- const viewer = root.querySelector('[data-scene="viewer"]');
- const under = (el: HTMLElement | null) => {
- const r = el?.getBoundingClientRect();
- return !!r && r.top <= 40 && r.bottom > 40;
- };
- const navTheme = () => {
- if (!nav) return;
- let theme = themed.find(under)?.dataset.themeSec ?? root.dataset.theme ?? 'dark';
- if (under(files) && (progress.get('files') ?? 0) < Number(files!.dataset.lit ?? 0)) theme = 'light';
- if (under(viewer) && (progress.get('viewer') ?? 0) < 0.07) theme = 'dark';
- if (nav.dataset.theme !== theme) nav.dataset.theme = theme;
- };
- ScrollTrigger.create({ start: 0, end: 'max', onUpdate: navTheme, onRefresh: navTheme });
-
- // The kind pills ask for a point in a scene's pin.
- const onSeek = (e: Event) => {
- const { id, p } = (e as CustomEvent<{ id: string; p: number }>).detail;
- const st = triggers.get(id);
- if (st) scrollTo({ top: Math.round(st.start + (st.end - st.start) * p), behavior: 'smooth' });
- };
- root.addEventListener('seek', onSeek);
-
- // Hero parallax: the unmapped files drift against the pointer.
- const hero = root.querySelector('[data-scene="top"]');
- const heroFrame = hero?.querySelector('[data-frame]');
- const onPointer = (e: PointerEvent) => {
- const r = hero!.getBoundingClientRect();
- heroFrame!.style.setProperty('--mx', (((e.clientX - r.left) / r.width - 0.5) * 2).toFixed(3));
- heroFrame!.style.setProperty('--my', (((e.clientY - r.top) / r.height - 0.5) * 2).toFixed(3));
- };
- hero?.addEventListener('pointermove', onPointer);
-
- return () => {
- root.classList.remove('live');
- root.removeEventListener('seek', onSeek);
- hero?.removeEventListener('pointermove', onPointer);
- ScrollTrigger.removeEventListener('refresh', measureRoutes);
- for (const r of allRoutes) {
- r.el.style.strokeDashoffset = '';
- r.head?.removeAttribute('transform');
- }
- for (const el of root.querySelectorAll('[data-rv].in')) el.classList.remove('in');
- // At rest the mark is simply drawn.
- mark?.classList.add('drawn');
- if (nav && nav0) nav.dataset.theme = nav0;
- };
-}
-
-// Each composition's timelines load only once its widths match with motion allowed: the other one's,
-// or both under reduced motion, never download.
-const COMPOSITIONS = {
- desktop: { rootId: 'lp-d', media: '(min-width: 768px)', tweens: () => import('./desktop/timelines').then((m) => m.TWEENS) },
- phone: { rootId: 'lp-m', media: '(max-width: 767px)', tweens: () => import('./mobile/timelines').then((m) => m.TWEENS) },
-};
-
-/** Scrubs one composition, desktop or phone, while its widths match and motion is allowed. */
-export function LandingMotion({ composition }: { composition: keyof typeof COMPOSITIONS }) {
- const { rootId, media, tweens } = COMPOSITIONS[composition];
- useGSAP(() => {
- const root = document.getElementById(rootId);
- if (!root) return;
- root.querySelector('[data-mark-route]')?.classList.add('drawn');
- const mm = gsap.matchMedia();
- mm.add(`${media} and (prefers-reduced-motion: no-preference)`, (ctx) => {
- // Added to the context once loaded, so leaving the widths reverts it like any other; skipped if they already have.
- void tweens().then((t) => ctx.isReverted || ctx.add(() => animate(root, t)));
- });
- return () => mm.revert();
- }, [rootId, media, tweens]);
- return null;
-}
diff --git a/site/components/landing/LazyViewer.tsx b/site/components/landing/LazyViewer.tsx
deleted file mode 100644
index ea27a4f..0000000
--- a/site/components/landing/LazyViewer.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-'use client';
-
-import dynamic from 'next/dynamic';
-import { useEffect, useRef, useState } from 'react';
-import type { LaidOutDiagram } from '@stackmap/core';
-import type { StaticDiagram } from '@/lib/data/static-html';
-import { FitDiagram } from '@/components/diagram/FitDiagram';
-
-const LiveViewer = dynamic(() => import('@/components/examples/LiveViewer'), { ssr: false });
-
-/**
- * The real viewer, mounted once its box is on screen (and visible: the other composition's copy never mounts).
- * Until then, and without script, the same diagram at rest.
- */
-export function LazyViewer({ diagram, still, width, height }: { diagram: LaidOutDiagram; still: StaticDiagram; width: number; height: number }) {
- const box = useRef(null);
- const [mounted, setMounted] = useState(false);
- useEffect(() => {
- const el = box.current;
- if (!el) return;
- const io = new IntersectionObserver(
- ([e]) => {
- if (e?.isIntersecting && el.offsetParent !== null) {
- setMounted(true);
- io.disconnect();
- }
- },
- { rootMargin: '50% 0px' },
- );
- io.observe(el);
- return () => io.disconnect();
- }, []);
- return (
-
- {mounted ? : }
-
- );
-}
diff --git a/site/components/landing/Proof.tsx b/site/components/landing/Proof.tsx
new file mode 100644
index 0000000..f3cc4d9
--- /dev/null
+++ b/site/components/landing/Proof.tsx
@@ -0,0 +1,153 @@
+import type { CSSProperties, ReactNode } from 'react';
+import { Check, Link2 } from 'lucide-react';
+import type { NodeType } from '@stackmap/core';
+import { BrandIcon } from '@stackmap/viewer/src/icons/BrandIcon';
+import { TypeIcon } from '@stackmap/viewer/src/icons/TypeIcon';
+import type { Receipt } from '@/lib/data/receipt';
+
+const tint = (type: NodeType) =>
+ ({ '--f': `var(--sm-${type}-fill)`, '--b': `var(--sm-${type}-border)`, '--t': `var(--sm-${type}-tile)`, '--a': `var(--sm-${type}-accent)` }) as CSSProperties;
+
+// A card drawn as the viewer draws one, at the proof card's size.
+function MiniCard({ type, brand, title, subtitle }: { type: NodeType; brand?: string; title: string; subtitle: string }) {
+ return (
+
+ {brand ? : }
+
+ {title}
+ {subtitle}
+
+
+ );
+}
+
+function Card({ d, visual, title, children }: { d: number; visual: ReactNode; title: string; children: ReactNode }) {
+ return (
+
+
+ {title}
+ {children}
+
+ );
+}
+
+const K = ({ children }: { children: string }) => "{children}";
+const S = ({ children }: { children: string }) => "{children}";
+
+/** #trust: evidence, no coordinates, deterministic output, one shareable file. */
+export function Proof({ receipt }: { receipt: Receipt }) {
+ const line = (
+
+ $ stackmap deliver diagram.json
+
+ delivered · sha256 {receipt.sha256.slice(0, 12)}… · {receipt.bytes} bytes
+
+
+ );
+ return (
+
+
+
+ Built to be checked
+
+ Made to be checked, and easy to share.
+
+ Every card can cite its source, the same JSON always builds the same file, and that file opens anywhere.
+
+
+
+
+
+
+
+ Evidence
+ services/api/src/server.ts:12
+
+
+
+
+
+
+ Evidence
+ infra/orders/postgres.tf:12
+
+
+ >
+ }
+ >
+ A node can cite the file and line it came from. Select it and the inspector shows where.
+
+
+
+ {'{\n '}
+ id : orders
+ {',\n '}
+ type : database
+ {',\n '}
+ group : data
+ {',\n '}
+ card
+ {': { '}
+ title : Orders DB
+ {' }\n}'}
+
+ no x · no y · no width
+ >
+ }
+ >
+ The agent names nodes, connections, groups and views. ELK lays out architecture and dataflow; stackmap lays out lanes and lifelines.
+
+
+ {line}
+ {line}
+
+
+ Byte for byte
+
+ >
+ }
+ >
+ deliver is deterministic: the same diagram.json always gives the same diagram.html.
+
+
+
+
+
+ diagram.html#view=checkout&node=api&play=1
+
+
+
+ {['PNG', 'JPEG', 'WebP', 'SVG', 'Video'].map((f) => (
+
+ {f}
+
+ ))}
+
+ >
+ }
+ >
+ No server, no account, nothing to install to open it. The URL keeps the view, selection, route and playback.
+
+
+
+
+ );
+}
diff --git a/site/components/landing/Reveals.tsx b/site/components/landing/Reveals.tsx
new file mode 100644
index 0000000..12e26dc
--- /dev/null
+++ b/site/components/landing/Reveals.tsx
@@ -0,0 +1,33 @@
+'use client';
+
+import { useEffect } from 'react';
+import { gsap, ScrollTrigger } from '@/lib/motion';
+
+/**
+ * Content past the hero arrives once as it enters: a 12px rise and fade over 640 ms, 60 ms apart.
+ * Only with motion allowed; the server's markup is the resting frame, so nothing here is needed to read the page.
+ */
+export function Reveals() {
+ useEffect(() => {
+ const mm = gsap.matchMedia();
+ mm.add('(prefers-reduced-motion: no-preference)', () => {
+ const els = gsap.utils.toArray('[data-reveal]');
+ gsap.set(els, { autoAlpha: 0, y: 12 });
+ ScrollTrigger.batch(els, {
+ start: 'top 92%',
+ once: true,
+ onEnter: (batch) =>
+ gsap.to(batch, {
+ autoAlpha: 1,
+ y: 0,
+ stagger: 0.06,
+ duration: 0.64,
+ ease: 'stackmap.out',
+ clearProps: 'transform,opacity,visibility',
+ }),
+ });
+ });
+ return () => mm.revert();
+ }, []);
+ return null;
+}
diff --git a/site/components/landing/desktop.css b/site/components/landing/desktop.css
deleted file mode 100644
index e9a1da7..0000000
--- a/site/components/landing/desktop.css
+++ /dev/null
@@ -1,444 +0,0 @@
-/* Ported from the canvas board. Scoped to .lp-d; keyframes are prefixed so the two compositions never collide. */
-.lp-d {
- .mono {font-family:var(--font-mono)}
- .tnum {font-variant-numeric:tabular-nums}
- .ic {display:block;flex-shrink:0}
- .sr {position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
- .t-client {--f:var(--sm-client-fill);--b:var(--sm-client-border);--t:var(--sm-client-tile);--a:var(--sm-client-accent)}
- .t-service {--f:var(--sm-service-fill);--b:var(--sm-service-border);--t:var(--sm-service-tile);--a:var(--sm-service-accent)}
- .t-gateway {--f:var(--sm-gateway-fill);--b:var(--sm-gateway-border);--t:var(--sm-gateway-tile);--a:var(--sm-gateway-accent)}
- .t-database {--f:var(--sm-database-fill);--b:var(--sm-database-border);--t:var(--sm-database-tile);--a:var(--sm-database-accent)}
- .t-cache {--f:var(--sm-cache-fill);--b:var(--sm-cache-border);--t:var(--sm-cache-tile);--a:var(--sm-cache-accent)}
- .t-queue {--f:var(--sm-queue-fill);--b:var(--sm-queue-border);--t:var(--sm-queue-tile);--a:var(--sm-queue-accent)}
- .t-storage {--f:var(--sm-storage-fill);--b:var(--sm-storage-border);--t:var(--sm-storage-tile);--a:var(--sm-storage-accent)}
- .t-external {--f:var(--sm-external-fill);--b:var(--sm-external-border);--t:var(--sm-external-tile);--a:var(--sm-external-accent)}
- .t-security {--f:var(--sm-security-fill);--b:var(--sm-security-border);--t:var(--sm-security-tile);--a:var(--sm-security-accent)}
- .t-start {--f:var(--sm-start-fill);--b:var(--sm-start-border);--t:var(--sm-start-tile);--a:var(--sm-start-accent)}
- .t-active {--f:var(--sm-active-fill);--b:var(--sm-active-border);--t:var(--sm-active-tile);--a:var(--sm-active-accent)}
- .t-waiting {--f:var(--sm-waiting-fill);--b:var(--sm-waiting-border);--t:var(--sm-waiting-tile);--a:var(--sm-waiting-accent)}
- .t-decision {--f:var(--sm-decision-fill);--b:var(--sm-decision-border);--t:var(--sm-decision-tile);--a:var(--sm-decision-accent)}
- .t-success {--f:var(--sm-success-fill);--b:var(--sm-success-border);--t:var(--sm-success-tile);--a:var(--sm-success-accent)}
- .t-failure {--f:var(--sm-failure-fill);--b:var(--sm-failure-border);--t:var(--sm-failure-tile);--a:var(--sm-failure-accent)}
- .t-neutral {--f:var(--sm-neutral-fill);--b:var(--sm-neutral-border);--t:var(--sm-neutral-tile);--a:var(--sm-neutral-accent)}
- .ed[data-tint="client"] {--ec:var(--sm-client-accent);--ew:1.75px}
- .ed[data-tint="service"] {--ec:var(--sm-service-accent);--ew:1.75px}
- .ed[data-tint="gateway"] {--ec:var(--sm-gateway-accent);--ew:1.75px}
- .ed[data-tint="database"] {--ec:var(--sm-database-accent);--ew:1.75px}
- .ed[data-tint="cache"] {--ec:var(--sm-cache-accent);--ew:1.75px}
- .ed[data-tint="queue"] {--ec:var(--sm-queue-accent);--ew:1.75px}
- .ed[data-tint="storage"] {--ec:var(--sm-storage-accent);--ew:1.75px}
- .ed[data-tint="external"] {--ec:var(--sm-external-accent);--ew:1.75px}
- .ed[data-tint="security"] {--ec:var(--sm-security-accent);--ew:1.75px}
- .ed[data-tint="start"] {--ec:var(--sm-start-accent);--ew:1.75px}
- .ed[data-tint="active"] {--ec:var(--sm-active-accent);--ew:1.75px}
- .ed[data-tint="waiting"] {--ec:var(--sm-waiting-accent);--ew:1.75px}
- .ed[data-tint="decision"] {--ec:var(--sm-decision-accent);--ew:1.75px}
- .ed[data-tint="success"] {--ec:var(--sm-success-accent);--ew:1.75px}
- .ed[data-tint="failure"] {--ec:var(--sm-failure-accent);--ew:1.75px}
- .ed[data-tint="neutral"] {--ec:var(--sm-neutral-accent);--ew:1.75px}
- .dg {position:relative}
- .cw {position:absolute;display:block;border:0;padding:0;margin:0;background:transparent;text-align:left;font:inherit;color:var(--sm-text);border-radius:14px;outline:none;transition:opacity 150ms ease}
- .cw.cpt {border-radius:12px}
- button.cw {cursor:pointer}
- .nc, .scd {position:relative;display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden;background:var(--f);box-shadow:inset 0 0 0 1px var(--b)}
- .nc {border-radius:14px}
- .scd {border-radius:12px}
- .nc-h {display:flex;align-items:center;gap:12px;height:64px;padding:0 16px;flex-shrink:0}
- .nc .tile {width:36px;height:36px;flex-shrink:0;border-radius:10px;display:grid;place-items:center;background:var(--t);color:var(--a)}
- .nc-tx {display:flex;flex-direction:column;min-width:0}
- .nc .ct {font-size:13.5px;line-height:20px;font-weight:500;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc .cs {font-size:12px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc-rows {display:block;padding:8px 0;flex-shrink:0}
- .nc-row {display:flex;align-items:center;justify-content:space-between;gap:12px;height:28px;padding:0 16px;font-size:12px}
- .nc-k {color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc-v {max-width:55%;flex-shrink:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--sm-text)}
- .nc-stats {display:block;padding:0 12px;margin-bottom:12px;flex-shrink:0}
- .st-box {display:flex;flex-direction:column;overflow:hidden;border-radius:10px;background:var(--t);box-shadow:inset 0 0 0 1px var(--b)}
- .st-grid {display:grid;gap:6px;padding:6px;height:60px}
- .st {display:flex;flex-direction:column;justify-content:center;min-width:0;border-radius:8px;background:var(--sm-stage);padding:0 10px}
- .st-v {font-size:15px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .st-l {font-size:11px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .st-note {display:flex;align-items:center;gap:6px;height:30px;padding:0 12px;font-size:11.5px;color:var(--sm-text-muted)}
- .nc-foot {display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));align-items:center;gap:12px;height:40px;padding:0 16px;font-size:12px;color:var(--sm-text-muted);box-shadow:inset 0 1px 0 var(--b);flex-shrink:0}
- .nf-i {display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden}
- .nf-i.r {justify-content:flex-end}
- .nc-cta {display:block;height:48px;padding:0 12px;flex-shrink:0}
- .cta-in {display:flex;height:36px;align-items:center;justify-content:space-between;border-radius:8px;padding:0 12px;font-size:13px;font-weight:500;background:var(--t)}
- .cta-in .ic {color:var(--a)}
- .sc-h {display:flex;align-items:center;gap:10px;height:60px;padding:0 12px;flex-shrink:0}
- .scd .tile {width:28px;height:28px;flex-shrink:0;border-radius:8px;display:grid;place-items:center;background:var(--t);color:var(--a)}
- .scd .ct {font-size:13px;line-height:18px;font-weight:500;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .scd .cs {font-size:11.5px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .sc-tag {display:flex;align-items:flex-start;height:24px;padding:0 12px 0 50px;flex-shrink:0}
- .pill {display:inline-flex;align-items:center;height:18px;max-width:100%;padding:0 8px;border-radius:9999px;font-size:11px;font-weight:500;background:var(--t);color:var(--sm-text);white-space:nowrap;overflow:hidden}
- .scd.final {box-shadow:inset 0 0 0 1.5px var(--a),inset 0 0 0 3.5px var(--f),inset 0 0 0 4.5px var(--a)}
- [data-em="focus"] {outline:2px solid var(--a);outline-offset:3px}
- [data-em="dim"], [data-dim="true"], [data-dim="dim"] {opacity:.22}
- .cw:focus-visible {outline:2px solid var(--sm-text);outline-offset:3px}
- .hd {position:absolute;width:7px;height:7px;border-radius:9999px;background:var(--sm-stage);border:1.5px solid var(--a);pointer-events:none}
- .hin-v {left:50%;top:0;transform:translate(-50%, -50%)}
- .hout-v {left:50%;bottom:0;transform:translate(-50%, 50%)}
- .hin-h {top:50%;left:0;transform:translate(-50%, -50%)}
- .hout-h {top:50%;right:0;transform:translate(50%, -50%)}
- .hd.rh {transform:translate(-50%, -50%);transition:opacity 150ms ease}
- .eg, .pg {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .ed {--ec:var(--sm-edge);--ew:1.25px;transition:opacity 150ms ease}
- .ed .ln {fill:none;stroke:var(--ec);stroke-width:var(--ew);transition:stroke 150ms ease, stroke-width 150ms ease}
- .ed .ah {fill:var(--ec);stroke:none;transition:fill 150ms ease}
- .ed .ah.open {fill:none;stroke:var(--ec);stroke-width:1.25px;stroke-linejoin:round}
- .ed.k-async .ln {stroke-dasharray:5 4}
- .ed.k-return .ln {stroke-dasharray:1 4;stroke-linecap:round}
- .ed.tone-main {--ec:var(--sm-text);--ew:1.75px}
- .ed.tone-security {--ec:var(--sm-security-accent);--ew:1.5px}
- .ed.tone-error {--ec:var(--sm-failure-accent);--ew:1.5px}
- .lifeline {stroke:var(--sm-group-border);stroke-width:1;stroke-dasharray:4 4;transition:opacity 150ms ease}
- .act {fill:var(--a);fill-opacity:.16;stroke:var(--a);stroke-width:1;transition:opacity 150ms ease}
- .startmark line {stroke:var(--sm-start-accent);stroke-width:1.5}
- .startmark path, .startmark circle {fill:var(--sm-start-accent)}
- .elb {position:absolute;transform:translate(-50%, -50%);white-space:nowrap;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);padding:2px 8px;font-size:11px;line-height:1.5;color:var(--sm-text-muted);pointer-events:none;transition:opacity 150ms ease}
- .elt {position:absolute;transform:translate(-50%, -50%);white-space:nowrap;border-radius:4px;background:var(--sm-stage);padding:0 6px;font-size:11.5px;line-height:16px;color:var(--sm-text);pointer-events:none;transition:opacity 150ms ease}
- .fr {position:absolute;border:1px dashed var(--sm-group-border);border-radius:18px;background:var(--sm-group-fill)}
- .fr.cpt {border-radius:14px}
- .fr.onlane {background:transparent}
- .fr.sec {border-color:var(--sm-security-accent)}
- .fr.sec .ic {color:var(--sm-security-accent)}
- .fr-l {display:flex;align-items:center;gap:6px;padding:0 20px;font-size:12.5px;font-weight:500;color:var(--sm-text-muted)}
- .fr.cpt .fr-l {padding:0 12px;font-size:12px}
- .lane {position:absolute;border-radius:16px;background:var(--sm-group-fill);box-shadow:inset 0 0 0 1px var(--sm-panel-border)}
- .lane.exc {box-shadow:none;border:1px dashed var(--sm-group-border)}
- .lane-l {display:flex;align-items:flex-start;gap:6px;width:128px;padding:16px 16px 0;font-size:12.5px;line-height:18px;font-weight:500;color:var(--sm-text-muted);overflow-wrap:anywhere}
- .lane-l .ic {margin-top:2.5px}
- .ph-head {position:absolute;display:flex;align-items:flex-start;justify-content:center}
- .ph-head span {margin-top:6px;font-size:13px;font-weight:500;color:var(--sm-text)}
- .ph-head i {position:absolute;left:0;right:0;bottom:8px;height:1px;background:var(--sm-group-border)}
- .ph-band {position:absolute;border:1px dashed var(--sm-group-border);border-radius:18px;background:var(--sm-group-fill)}
- .ph-band span {display:flex;align-items:center;height:44px;padding:0 20px;font-size:12.5px;font-weight:500;color:var(--sm-text-muted)}
- .ph-band.c span {justify-content:center}
- .ph-time {position:absolute;border:1px dashed var(--sm-group-border);border-radius:14px;background:var(--sm-group-fill)}
- .ph-time span {display:flex;align-items:center;height:28px;padding:0 16px;font-size:12px;font-weight:500;color:var(--sm-text-muted)}
- .pnl {background:var(--sm-panel);box-shadow:var(--shadow-panel);border-radius:16px}
- .ib {width:36px;height:36px;border:0;border-radius:12px;background:transparent;color:var(--sm-text-muted);display:grid;place-items:center;cursor:pointer;transition:background-color 150ms ease, color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .ib:hover, .ib[aria-pressed="true"] {background:var(--sm-page);color:var(--sm-text)}
- .ib:active {transform:scale(0.96)}
- .ib:focus-visible, .pbtn:focus-visible, .lnk:focus-visible, .chip-b:focus-visible, .tab:focus-visible {outline:2px solid var(--sm-text);outline-offset:2px}
- .pbtn {display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px;padding:0 18px;border:0;border-radius:9999px;background:var(--sm-primary);color:var(--sm-primary-text);font-size:14px;font-weight:500;text-decoration:none;cursor:pointer;white-space:nowrap;transition:transform 120ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms ease}
- .pbtn:active {transform:scale(0.96)}
- .lnk {display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;border-radius:12px;color:var(--sm-text-muted);text-decoration:none;font-size:14px;transition:background-color 150ms ease, color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .lnk:active {transform:scale(0.97)}
- .lnk:hover {background:var(--sm-page);color:var(--sm-text)}
- .kbd {display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 6px;border-radius:6px;box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);font-size:12px;color:var(--sm-text-muted);background:var(--sm-panel)}
- .badge {display:inline-flex;align-items:center;height:24px;padding:0 10px;border-radius:9999px;box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-size:13px;color:var(--sm-text)}
- .grid-bg {background-image:radial-gradient(circle, var(--sm-grid) 1.5px, transparent 1.75px);background-size:24px 24px}
- .scn {position:relative;background:var(--sm-page)}
- .stage {position:relative;height:100%;overflow:clip}
- .frame {position:absolute;left:50%;top:0;transform:translateX(-50%);transform-origin:50% 50%}
- &.live [data-rv] {transition:opacity 700ms cubic-bezier(0.23, 1, 0.32, 1), translate 700ms cubic-bezier(0.23, 1, 0.32, 1)}
- &.live [data-rv]:not(.in) {opacity:0;translate:0 28px}
- &.live [data-rv="lines"] {opacity:1 !important;translate:none !important;transition:none}
- &.live [data-rv="lines"] .ml>span {display:inline-block;transition:translate 800ms cubic-bezier(0.23, 1, 0.32, 1)}
- &.live [data-rv="lines"]:not(.in) .ml>span {translate:0 108%}
- .ml {display:block;overflow:hidden;padding:0.06em 0.04em 0.14em;margin:-0.06em -0.04em -0.14em}
- &.live [data-route] {stroke-dasharray:1 1;stroke-dashoffset:1}
- .rhead {opacity:0;transition:opacity 200ms ease;pointer-events:none}
- .rh-halo {fill:var(--sm-text);fill-opacity:.14}
- .rh-core {fill:var(--sm-text)}
- .cmd {display:inline-flex;align-items:center;gap:12px;height:52px;padding:0 8px 0 18px;border-radius:14px}
- .cmd.big {height:60px;padding:0 10px 0 22px}
- .cmd-p {font-size:15px;color:var(--sm-text-muted)}
- .cmd-t {flex:1 1 auto;min-width:0;font-size:15px;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .cmd.big .cmd-t, .cmd.big .cmd-p {font-size:16px}
- .cp [data-i="check"] {display:none}
- .cp.done [data-i="copy"] {display:none}
- .cp.done [data-i="check"] {display:block;color:var(--sm-text)}
- .t-mega {font-size:200px;line-height:0.92;font-weight:600;letter-spacing:-0.05em}
- .t-hero {font-size:112px;line-height:0.94;font-weight:600;letter-spacing:-0.045em}
- .t-title {font-size:96px;line-height:1;font-weight:600;letter-spacing:-0.045em}
- .t-section {font-size:72px;line-height:1.02;font-weight:600;letter-spacing:-0.04em}
- .t-display {font-size:60px;line-height:70px;font-weight:600;letter-spacing:-0.03em}
- .t-lede {font-size:22px;line-height:1.4;font-weight:400;color:var(--sm-text-muted)}
- .acc {color:var(--site-accent)}
- .muted {color:var(--sm-text-muted)}
- h1, h2, h3, h4, p {margin:0}
- .hero-grid {position:absolute;inset:0;-webkit-mask-image:radial-gradient(closest-side, #000 55%, transparent 100%);mask-image:radial-gradient(closest-side, #000 55%, transparent 100%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:42% 46%;mask-position:42% 46%;-webkit-mask-size:1900px 1400px;mask-size:1900px 1400px;animation:gridgrow 1500ms cubic-bezier(0.23, 1, 0.32, 1) 850ms backwards}
- .par {position:absolute;inset:0;transition:transform 900ms cubic-bezier(0.23, 1, 0.32, 1)}
- .par0 {transform:translate(calc(var(--mx, 0) * -8px), calc(var(--my, 0) * -6px))}
- .par1 {transform:translate(calc(var(--mx, 0) * -16px), calc(var(--my, 0) * -12px))}
- .par2 {transform:translate(calc(var(--mx, 0) * -28px), calc(var(--my, 0) * -20px))}
- .chip {position:absolute;white-space:nowrap;padding:7px 12px;border-radius:9px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);font-size:15px;line-height:1.5;color:var(--sm-text-muted);animation-duration:11s, 900ms;animation-timing-function:ease-in-out, cubic-bezier(0.23, 1, 0.32, 1);animation-iteration-count:infinite, 1;animation-direction:alternate, normal;animation-fill-mode:none, backwards}
- .chip.dp0 {filter:blur(3px);opacity:.3}
- .chip.dp1 {filter:blur(1.4px);opacity:.55}
- .chip.dp2 {opacity:.85;color:var(--sm-text)}
- .chip.dr-a {animation-name:driftA, chipin}
- .chip.dr-b {animation-name:driftB, chipin}
- .chip.dr-c {animation-name:driftC, chipin}
- .chip:has(.ghost) {padding:0;background:none;box-shadow:none}
- .ghost {display:flex;align-items:center;gap:12px;width:280px;height:64px;padding:0 16px;border-radius:14px;background:var(--sm-external-fill);box-shadow:inset 0 0 0 1px var(--sm-external-border)}
- .g-tile {width:36px;height:36px;border-radius:10px;background:var(--sm-external-tile)}
- .g-lines {display:flex;flex-direction:column;gap:6px}
- .g-lines span {display:block;width:120px;height:8px;border-radius:4px;background:var(--sm-external-border)}
- .g-lines span+span {width:80px;height:6px;background:var(--sm-panel-border)}
- .h-content {position:absolute;inset:0}
- .hero-h {position:absolute;left:96px;top:250px;margin:0;font-size:112px;line-height:0.94;font-weight:600;letter-spacing:-0.045em;color:var(--sm-text);perspective:1600px;perspective-origin:40% 40%}
- .hl {display:block;white-space:nowrap}
- .hw {display:inline-block;animation:hdrop 1000ms linear backwards;transform-origin:50% 60%}
- .hacc {position:relative;display:inline-block;color:var(--site-accent);animation:acc 320ms cubic-bezier(0.23, 1, 0.32, 1) 2180ms backwards}
- .hacc .hw {color:inherit}
- .hglow {position:absolute;left:-18px;right:-18px;top:14px;bottom:4px;border-radius:28px;background:var(--site-accent);filter:blur(22px);opacity:0;pointer-events:none;z-index:-1;animation:hglow 900ms cubic-bezier(0.23, 1, 0.32, 1) 2180ms backwards}
- .h-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .h-route .rt {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .h-route .rt-in {stroke:url(#hr-fade);stroke-dasharray:1 1;animation:rdraw 650ms cubic-bezier(0.33, 1, 0.68, 1) 1480ms backwards}
- .h-route .ah {fill:var(--sm-text);animation:fadein 140ms linear 2100ms backwards}
- .h-route .hd2 {fill:var(--sm-stage);stroke:var(--sm-text);stroke-width:1.5;animation:fadein 200ms linear 2240ms backwards}
- .comet {position:absolute;left:0;top:0;width:7px;height:7px;border-radius:9999px;background:var(--sm-text);box-shadow:0 0 0 5px rgb(237 237 236 / 0.18), 0 0 18px 4px rgb(237 237 236 / 0.22);offset-path:path("M 56 0 V 402 Q 56 418 72 418 H 79");offset-rotate:0deg;offset-distance:100%;opacity:0;animation:comet 720ms cubic-bezier(0.5, 1, 0.89, 1) 1480ms backwards}
- .h-lede {position:absolute;left:96px;top:506px;width:600px;animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1250ms backwards}
- .h-cta {position:absolute;left:96px;top:600px;display:flex;align-items:center;gap:10px;animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1380ms backwards}
- .h-works {position:absolute;left:98px;top:686px;font-size:13px;color:var(--sm-text-muted);animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1520ms backwards}
- .h-bridge {display:none}
- &.live .h-bridge {display:inline;stroke-dasharray:1 1}
- .hero-chips {position:absolute;inset:0;transform-origin:720px 450px}
- .vx {position:absolute;left:720px;top:450px;width:0;height:0}
- .vring {position:absolute;left:0;top:0}
- .vchip {position:absolute;left:0;top:0;white-space:nowrap;padding:8px 14px;border-radius:9px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);line-height:1.5;color:var(--sm-text)}
- /* Decorative texture: the names are drawn, not text, so they carry no contrast duty. */
- .vchip[data-label]::before {content:attr(data-label)}
- .vghost {padding:0;background:none;box-shadow:none}
- .kline-wrap {position:absolute;inset:0;transform-origin:720px 450px}
- .kl {position:absolute;left:96px;margin:0;font-size:96px;line-height:1;font-weight:600;letter-spacing:-0.045em;color:var(--sm-text);white-space:nowrap;transition:color 300ms ease}
- .kw {display:inline-block}
- .kw>span {display:inline-block}
- .cdot {position:absolute;left:714px;top:444px;width:12px;height:12px;border-radius:9999px;background:var(--sm-edge);opacity:0}
- .shock {position:absolute;left:120px;top:-150px;width:1200px;height:1200px;border-radius:9999px;box-shadow:inset 0 0 0 1.5px var(--sm-text);opacity:0}
- .s2-grid {position:absolute;inset:0;opacity:0;-webkit-mask-image:radial-gradient(closest-side, #000 60%, transparent 100%);mask-image:radial-gradient(closest-side, #000 60%, transparent 100%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:2400px 2400px;mask-size:2400px 2400px}
- .mk {position:absolute;left:528px;top:258px;overflow:visible;opacity:0}
- .mk .bx {transform-box:fill-box;transform-origin:center}
- .mk-route {stroke-dasharray:100;stroke-dashoffset:0}
- &.live .mk-route {stroke-dashoffset:100;opacity:0;transition:stroke-dashoffset 640ms cubic-bezier(0.77, 0, 0.175, 1), opacity 1ms linear}
- &.live .mk-route.drawn {stroke-dashoffset:0;opacity:1}
- .mcard {opacity:0}
- .mcard .nc {border-radius:inherit}
- .mc-in {position:absolute;inset:0;display:flex;flex-direction:column}
- .mc-ov {position:absolute;inset:0;border-radius:inherit}
- .s2-edge {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .s2-edge .ln {fill:none;stroke:var(--sm-edge);stroke-width:1.25}
- .s2-edge .ah {fill:var(--sm-edge)}
- .s2-edge .lead {fill:none;stroke:var(--sm-database-accent);stroke-width:1.75}
- .s2-edge g {opacity:0}
- .selring {position:absolute;left:759px;top:413px;width:290px;height:74px;border-radius:17px;box-shadow:0 0 0 2px var(--sm-database-accent);opacity:0;pointer-events:none}
- .s2ev {position:absolute;left:768px;top:554px;display:flex;align-items:center;gap:10px;padding:9px 14px;border-radius:10px;opacity:0}
- .s2ev code {font-size:15px;color:var(--sm-text)}
- .s2ev .ic {color:var(--sm-database-accent)}
- .s2cap {position:absolute;left:0;right:0;text-align:center;opacity:0}
- .s2-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .s2-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .bigp {position:absolute;left:150px;top:282px;font-family:var(--font-mono);font-size:64px;line-height:1.3;color:var(--sm-text);transform-origin:0 0;opacity:0}
- .bigp-c {position:absolute;left:-58px;top:0;color:var(--sm-text-muted)}
- .ty {display:block;box-sizing:content-box;overflow:hidden;white-space:nowrap;border-right:0.08em solid transparent}
- .term {position:absolute;left:96px;top:112px;width:640px;height:428px;border-radius:16px;overflow:hidden}
- .term-h, .json-h {display:flex;align-items:center;height:48px;padding:0 22px;font-size:13px;color:var(--sm-text-muted);box-shadow:inset 0 -1px 0 var(--sm-panel-border)}
- .term-b {display:flex;flex-direction:column;padding:18px 22px;font-size:14.5px;line-height:25px;color:var(--sm-text-muted);white-space:pre}
- .term-b b {font-weight:600;color:var(--sm-text)}
- .tl-row {display:block;margin:0 -10px;padding:0 10px;border-radius:6px}
- .row-err {background:rgb(240 128 110 / 0.13)}
- .row-ok {background:rgb(166 217 122 / 0.12)}
- .row-del {background:rgb(143 166 242 / 0.12)}
- .t-ink {color:var(--sm-text)}
- .t-err {color:var(--sm-cache-accent)}
- .t-ok {color:var(--sm-service-accent)}
- .tp {display:block;color:var(--sm-text);white-space:pre-wrap;margin-bottom:14px}
- .tp .c {color:var(--sm-text-muted)}
- .json {position:absolute;left:768px;top:112px;width:576px;height:428px;border-radius:16px;background:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);overflow:hidden}
- .json-b {display:flex;flex-direction:column;padding:14px 22px;font-size:13px;line-height:19.5px;color:var(--sm-text-muted);white-space:pre}
- .j-s {color:var(--sm-text)}
- .j-t {color:var(--a)}
- .fixv {display:inline}
- .fx-bad {color:var(--sm-cache-accent);display:none}
- .fx-ok {color:var(--sm-text)}
- &.live .fx-bad, &.live .fx-ok {display:inline-block;overflow:hidden;vertical-align:bottom;white-space:pre}
- .fly {opacity:1}
- .steps {position:absolute;left:96px;top:716px;width:1248px;display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));gap:32px;margin:0;padding:0;list-style:none}
- .step {position:relative;padding-top:34px}
- .sdot {position:absolute;left:0;top:0;width:9px;height:9px;margin:-1px 0 0 -1px;border-radius:9999px;background:var(--sm-text);box-shadow:0 0 0 1.5px var(--sm-text);z-index:1}
- .s-n {display:block;font-size:12.5px;color:var(--sm-text-muted);margin-bottom:8px}
- .step h3 {font-size:22px;line-height:1.25;font-weight:600;letter-spacing:-0.02em;color:var(--sm-text)}
- .step p {margin-top:8px;font-size:14.5px;line-height:1.55;color:var(--sm-text-muted);max-width:280px}
- .s3-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .s3-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .s3-route .base {stroke:var(--sm-panel-border)}
- .lights {position:absolute;left:-2400px;right:-2400px;top:-1200px;bottom:-1200px;background:var(--sm-page);color:var(--sm-text);transition:background-color 200ms ease}
- .lights-in {position:absolute;left:2400px;top:1200px;width:1440px;height:900px}
- .vw {position:absolute;left:96px;top:84px;width:1248px;height:800px}
- .vw-head {position:absolute;left:0;top:0;right:0}
- .crumb {font-size:14px;line-height:21px;color:var(--sm-text-muted)}
- .vt {display:flex;align-items:center;gap:14px;margin-top:5px}
- .vt h2 {font-size:28px;line-height:36px;font-weight:600;letter-spacing:-0.025em}
- .vt .cnt {font-size:14px;color:var(--sm-text-muted)}
- .tabs {position:absolute;left:0;top:66px;display:flex;gap:26px;height:36px}
- .tab {position:relative;height:36px;padding:0;border:0;background:none;font-size:14.5px;color:var(--sm-text-muted);cursor:pointer;transition:color 150ms ease}
- .tab:hover, .tab[aria-selected="true"] {color:var(--sm-text)}
- .tab-ind {position:absolute;left:0;top:100px;height:2px;border-radius:2px;background:var(--sm-text);transition:translate 180ms cubic-bezier(0.77, 0, 0.175, 1), width 180ms cubic-bezier(0.77, 0, 0.175, 1)}
- .vw-rule {position:absolute;left:0;right:0;top:102px;height:1px;background:var(--sm-divider)}
- .vstage {position:absolute;left:0px;top:114px;width:932px;height:686px;border-radius:20px;background-color:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border)}
- .vstage>.grid-bg {position:absolute;inset:0;border-radius:20px}
- .vclip {position:absolute;left:0px;top:114px;width:932px;height:686px;clip-path:inset(0px round 20px);touch-action:none;cursor:grab}
- .vclip.drag {cursor:grabbing}
- .vcam {position:absolute;left:0;top:0;width:932px;height:686px;transform-origin:466px 343px}
- .plane-wrap {position:absolute;left:99px;top:-5px;width:734px;height:656px;perspective:2200px;perspective-origin:50% 20%}
- .plane {position:absolute;left:0;top:0;width:100%;height:100%;transform-style:preserve-3d;transform-origin:50% 45%}
- .plane-grid {position:absolute;left:-700px;right:-700px;top:-500px;bottom:-500px;opacity:0}
- .plane .dg {transform:scale(0.728);transform-origin:0 0;transform-style:preserve-3d}
- .plane .cw {transform-style:preserve-3d}
- .vchrome .pnl {position:absolute}
- .v-id {left:15px;top:129px;width:250px;height:64px;display:flex;align-items:center;gap:12px;padding:0 14px}
- .v-id .tile {width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:var(--sm-page);color:var(--sm-text)}
- .v-id b {display:block;font-size:14px;line-height:20px;font-weight:500}
- .v-id span span {display:block;font-size:12.5px;line-height:16px;color:var(--sm-text-muted)}
- .v-tools {left:15px;top:201px;height:52px;display:flex;align-items:center;gap:2px;padding:0 8px}
- .v-tools .sep {width:1px;height:20px;margin:0 4px;background:var(--sm-divider)}
- .v-zoom {left:15px;top:745px;height:40px;display:flex;align-items:center;gap:2px;padding:0 4px;border-radius:9999px}
- .v-zoom .ib {width:32px;height:32px;border-radius:9999px}
- .v-zoom .pct {min-width:48px;text-align:center;font-size:13px;font-variant-numeric:tabular-nums}
- .pop {position:absolute;z-index:5;left:15px;top:261px;width:300px;padding:12px;border-radius:16px}
- .pop input[type="search"] {width:100%;height:36px;padding:0 12px;border:0;border-radius:12px;background:var(--sm-page);color:var(--sm-text);font:inherit;font-size:14px;outline:none}
- .pop input[type="search"]:focus-visible {box-shadow:inset 0 0 0 2px var(--sm-text)}
- .pop .hint {margin-top:8px;font-size:12px;line-height:20px;color:var(--sm-text-muted)}
- .pop-t {font-size:12.5px;font-weight:500;color:var(--sm-text-muted);margin:2px 6px 6px}
- .lens-r {display:flex;align-items:center;gap:10px;height:32px;padding:0 6px;border-radius:8px;font-size:13px;cursor:pointer}
- .lens-r:hover {background:var(--sm-page)}
- .lens-r input {margin:0;accent-color:var(--sm-text)}
- .lens-r span:last-child {margin-left:auto}
- .dot {display:inline-block;width:8px;height:8px;border-radius:9999px;flex-shrink:0}
- .insp {position:absolute;left:948px;top:114px;width:300px;height:686px;border-radius:20px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);padding:20px;overflow:auto}
- .insp .cap {display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:500;color:var(--sm-text-muted)}
- .insp h3 {margin-top:4px;font-size:18px;line-height:1.5;font-weight:600;letter-spacing:-0.025em}
- .insp .sub {font-size:13px;line-height:1.5;color:var(--sm-text-muted)}
- .insp h4 {margin-top:24px;margin-bottom:10px;font-size:13px;font-weight:600}
- .insp ul {list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
- .insp li {display:flex;justify-content:space-between;align-items:center;gap:12px;font-size:13px}
- .lg-l {display:flex;align-items:center;gap:10px}
- .kv {display:flex;justify-content:space-between;gap:16px;font-size:13px;margin-bottom:8px}
- .kv span:first-child {color:var(--sm-text-muted)}
- .conn {display:flex;align-items:center;gap:8px;width:calc(100% + 16px);height:32px;margin:0 -8px;padding:0 8px;border:0;border-radius:8px;background:none;font-size:13px;text-align:left;cursor:pointer}
- .conn:hover {background:var(--sm-page)}
- .conn .muted {margin-left:auto;font-size:12px}
- .ev {display:block;font-family:var(--font-mono);font-size:12px;color:var(--sm-text);overflow-wrap:anywhere}
- .ev-n {margin-top:2px;font-size:12px;color:var(--sm-text-muted)}
- .i-row {display:flex;justify-content:space-between;align-items:center}
- .i-acts .ib {width:32px;height:32px}
- .tbtn {display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 12px;margin-top:14px;border:0;border-radius:10px;background:var(--sm-page);font-size:13px;cursor:pointer;transition:background-color 150ms ease, color 150ms ease}
- .tbtn[aria-pressed="true"] {background:var(--sm-primary);color:var(--sm-primary-text)}
- .caption {margin-top:12px;font-size:13px;line-height:1.5;color:var(--sm-text-muted)}
- .drop-title {position:absolute;left:0;right:0;top:108px;text-align:center;opacity:0;pointer-events:none}
- .v-route-dark {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .v-route-dark path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .v-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .v-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .dt-dark {display:none}
- &.live .dt-dark {display:block;opacity:1}
- .feat-sec {position:relative;height:880px;overflow:hidden;background:var(--sm-page);color:var(--sm-text)}
- .rline {position:absolute;top:0;bottom:0;left:calc(50% + var(--gl-off, -664px) - 0.75px);width:1.5px;background:var(--sm-text)}
- .feat-in {position:relative;max-width:1440px;margin:0 auto;padding:104px 96px 0}
- .feat-h {font-size:120px;line-height:0.95;font-weight:600;letter-spacing:-0.05em}
- .feat-lede {margin-top:28px;max-width:720px}
- .feat-g {display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));gap:0;margin-top:60px;box-shadow:inset 0 1px 0 var(--sm-divider)}
- .feat {position:relative;padding:28px 28px 32px 0;box-shadow:inset 0 -1px 0 var(--sm-divider)}
- .feat:nth-child(4n+2), .feat:nth-child(4n+3), .feat:nth-child(4n+4) {padding-left:28px;box-shadow:inset 0 -1px 0 var(--sm-divider), inset 1px 0 0 var(--sm-divider)}
- .feat-t {display:flex;align-items:center;gap:10px;font-size:20px;line-height:1.3;font-weight:600;letter-spacing:-0.02em}
- .feat-t .ic {color:var(--sm-text-muted)}
- .feat-t .kbd {margin-left:auto}
- .feat p {margin-top:12px;font-size:15px;line-height:1.55;color:var(--sm-text-muted)}
- .f-route {position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible;pointer-events:none}
- &.live .a-kd0 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd1 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd2 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd3 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd4 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- .kcam {position:absolute;inset:0;transform-origin:720px 640px}
- .kinds-h {position:absolute;left:96px;top:56px;height:260px;overflow:hidden;padding:0 12px 0 0}
- .kn-col {display:flex;flex-direction:column;transform:translateY(-520px)}
- &.live .kn-col {transform:none}
- .kn {display:block;height:260px;font-size:200px;line-height:260px;font-weight:600;letter-spacing:-0.05em;white-space:nowrap}
- .kdefs {position:absolute;left:100px;top:338px;height:32px}
- .kdef {position:absolute;left:0;top:0;white-space:nowrap;font-size:22px;line-height:1.4;color:var(--sm-text-muted);opacity:0}
- .kdef.on {opacity:1}
- .kpills {position:absolute;right:96px;top:330px;display:flex;gap:4px;padding:5px;border-radius:9999px}
- .kpill {height:36px;padding:0 14px;border:0;border-radius:9999px;background:transparent;color:var(--sm-text-muted);font-size:14px;cursor:pointer;transition:background-color 150ms ease, color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .kpill:active {transform:scale(0.97)}
- .kpill:hover {color:var(--sm-text)}
- .kpill[aria-pressed="true"] {background:var(--sm-primary);color:var(--sm-primary-text)}
- .kmore {position:absolute;right:96px;top:176px;font-size:14px}
- .klayer {position:absolute;transform-origin:0 0;opacity:0}
- .klayer.on {opacity:1}
- .kslot {position:absolute;opacity:1}
- .kface {position:absolute;inset:0;opacity:0;display:block}
- .kface.on {opacity:1}
- .kface .scd {width:176px;transform:scale(0.8261000000000001);transform-origin:0 0}
- .k-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .k-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .kface .scd {height:calc(100% / 0.8261000000000001)}
- .mm-e {fill:none;stroke:var(--sm-edge);stroke-width:1}
- .mm-c {fill-opacity:.55}
- .mm-lane {fill:var(--sm-group-fill);stroke:var(--sm-panel-border);stroke-width:1}
- .mm-fr {fill:none;stroke:var(--sm-group-border);stroke-width:1;stroke-dasharray:3 3}
- .file {position:absolute;left:900px;top:196px;width:332px;height:460px;perspective:1400px}
- .file-in {position:absolute;inset:0;transform-style:preserve-3d;transform:rotateY(180deg)}
- .face {position:absolute;inset:0;display:flex;flex-direction:column;gap:12px;padding:22px;border-radius:20px;background:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border), 0 40px 100px -40px rgb(0 0 0 / 0.6);-webkit-backface-visibility:hidden;backface-visibility:hidden}
- .face.back {transform:rotateY(180deg);background:var(--sm-panel)}
- .ff-t {font-size:20px;line-height:1.3;font-weight:600;letter-spacing:-0.02em}
- .ff-s {margin-top:-8px;font-size:13px;color:var(--sm-text-muted)}
- .ff-map {display:grid;place-items:center;flex:1}
- .fb-shot {height:268px;border-radius:12px;background-color:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);display:grid;place-items:center;overflow:hidden}
- .fb-n {margin-top:6px;font-size:20px;line-height:1.5}
- .fb-s {font-size:15px;line-height:1.5;color:var(--sm-text-muted)}
- .of-cap {position:absolute;left:0;right:0;top:112px;text-align:center;opacity:0}
- .fl-lights {position:absolute;left:-2400px;right:-2400px;top:-1200px;bottom:-1200px;display:none;background:var(--sm-page);color:var(--sm-text);pointer-events:none}
- &.live .fl-lights {display:block}
- .fl-in {position:absolute;left:2400px;top:1200px;width:1440px;height:900px}
- .of-h {position:absolute;left:96px;top:200px;font-size:104px;line-height:0.98;font-weight:600;letter-spacing:-0.05em}
- .of-list {position:absolute;left:100px;top:446px;display:flex;flex-direction:column;gap:14px;margin:0;padding:0;list-style:none;max-width:640px}
- .of-list li {display:flex;gap:14px;font-size:17px;line-height:1.5;color:var(--sm-text-muted)}
- .of-list .ic {margin-top:3px;color:var(--sm-text)}
- .of-more {position:absolute;left:96px;top:664px;display:flex;align-items:center;gap:20px}
- .of-more p {font-size:15px;line-height:1.5;color:var(--sm-text-muted);max-width:420px}
- .pill-l {display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 18px 0 20px;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);color:var(--sm-text);font-size:14px;font-weight:500;text-decoration:none;white-space:nowrap;transition:box-shadow 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .pill-l:hover {box-shadow:inset 0 0 0 1.5px var(--sm-text)}
- .pill-l:active {transform:scale(0.96)}
- .pill-l:focus-visible {outline:2px solid var(--sm-text);outline-offset:2px}
- .f-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .f-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .inst {position:relative;height:960px;overflow:hidden;background:var(--sm-page);color:var(--sm-text)}
- .inst-in {position:relative;max-width:1440px;margin:0 auto;padding:128px 96px 0}
- .ir-a {position:absolute;top:0;left:calc(50% + var(--gl-off, -664px) - 0.75px);width:calc(-1 * var(--gl-off, -664px) - 15.25px);height:48.75px;border-left:1.5px solid var(--sm-text);border-bottom:1.5px solid var(--sm-text);border-bottom-left-radius:16px}
- .ir-b {position:absolute;top:47.25px;left:calc(50% - 16px);width:16.75px;height:81.5px;border-top:1.5px solid var(--sm-text);border-right:1.5px solid var(--sm-text);border-top-right-radius:16px}
- .ir-d {position:absolute;top:124.5px;left:calc(50% - 4.5px);width:9px;height:9px;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1.5px var(--sm-text);z-index:2}
- .target {position:relative;width:920px;margin:0 auto;padding:56px 72px 48px;border-radius:28px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border), 0 40px 120px -40px rgb(0 0 0 / 0.5);text-align:center}
- .target img {display:block;margin:0 auto}
- .target h2 {margin-top:32px}
- .target .t-lede {margin:18px auto 0;max-width:620px}
- .ist {display:flex;flex-direction:column;gap:20px;margin-top:40px;text-align:left}
- .ist-row {display:grid;grid-template-columns:36px minmax(0, 1fr);gap:16px;align-items:start}
- .ist-n {display:grid;place-items:center;width:28px;height:28px;margin-top:4px;border-radius:9999px;box-shadow:inset 0 0 0 1.5px var(--sm-text-muted);font-size:13px;color:var(--sm-text)}
- .ist-row h3 {font-size:15px;font-weight:600;margin-bottom:10px}
- .ist-row .cmd {width:100%}
- .ist-row .cmd-t {overflow:hidden;text-overflow:ellipsis}
- .ask {padding:16px 20px;border-radius:14px;background:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-size:16px;line-height:1.55;color:var(--sm-text)}
- .ist-alt {margin-top:24px;padding-top:22px;box-shadow:inset 0 1px 0 var(--sm-divider);text-align:left;font-size:14px;color:var(--sm-text-muted)}
- .ist-alt .cmd {margin-top:12px;width:100%}
- .ilinks {display:flex;justify-content:center;gap:6px;margin-top:26px}
- @media (prefers-reduced-motion: reduce) {
- *, *::before, *::after {animation:none !important;transition:none !important}
- }
-}
-
-@keyframes gridgrow{0%{-webkit-mask-size:0px 0px;mask-size:0px 0px}100%{-webkit-mask-size:1900px 1400px;mask-size:1900px 1400px}}
-@keyframes driftA{0%{translate:0 0}100%{translate:26px -14px}}
-@keyframes driftB{0%{translate:0 0}100%{translate:-22px 16px}}
-@keyframes driftC{0%{translate:0 0}100%{translate:14px 22px}}
-@keyframes chipin{0%{opacity:0}}
-@keyframes hdrop{0%{opacity:0;transform:translate3d(var(--x), var(--y), var(--z));filter:blur(var(--bl));animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}22%{opacity:0.5;transform:translate3d(calc(var(--x) * 0.82), calc(var(--y) * 0.82), var(--z));filter:blur(var(--bl));animation-timing-function:cubic-bezier(0.55, 0, 1, 0.45)}70%{opacity:1;transform:translate3d(0px, 0px, 0px);filter:blur(0px);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}84%{transform:translate3d(0px, 0px, 18px);animation-timing-function:cubic-bezier(0.55, 0, 1, 0.45)}100%{opacity:1;transform:translate3d(0px, 0px, 0px);filter:blur(0px)}}
-@keyframes acc{0%{color:var(--sm-text)}100%{color:var(--brand-accent)}}
-@keyframes hglow{0%{opacity:0.42;transform:scale(0.96)}100%{opacity:0;transform:scale(1.08)}}
-@keyframes rdraw{0%{stroke-dashoffset:1}100%{stroke-dashoffset:0}}
-@keyframes fadein{0%{opacity:0}100%{opacity:1}}
-@keyframes comet{0%{offset-distance:0%;opacity:1}96%{opacity:1}100%{offset-distance:100%;opacity:0}}
-@keyframes rise{0%{opacity:0;translate:0 18px}100%{opacity:1;translate:0 0}}
-@keyframes spin{100%{rotate:360deg}}
diff --git a/site/components/landing/desktop/Agent.tsx b/site/components/landing/desktop/Agent.tsx
deleted file mode 100644
index d57a1a2..0000000
--- a/site/components/landing/desktop/Agent.tsx
+++ /dev/null
@@ -1,291 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Agent() {
- return (
- <>
-
-
-
- Ask your coding agent. It writes the JSON, stackmap checks it and delivers one file.
-
-
- ~/commerce-api
-
-
- › Make an architecture diagram of this repository, backed by evidence from the code.
-
-
- writing .stackmap/commerce-api/diagram.json
-
-
- stackmap · validate diagram.json
-
-
- error refs/unknown-node /edges/6/to
-
- Unknown node "orders-db"
- fix: use "orders"
-
- ✗ 1 error
-
-
- stackmap · validate diagram.json
-
-
- ✓ valid: no diagnostics
-
-
- stackmap · deliver diagram.json
-
-
- delivered .stackmap/commerce-api/diagram.html
-
-
- {' '}
- · sha256 {SITE.receipt.sha256.slice(0, 12)}… · {SITE.receipt.bytes} bytes
-
-
-
-
- diagram.json
-
- {'{'}
-
- {' '}
- "kind": "architecture",
-
-
- {' '}
- "title": "Commerce API",
-
- "nodes": [
-
- {' '}
- {'{'} "id": "storefront", "type": "client" {'}'},
-
-
- {' '}
- {'{'} "id": "edge", "type": "gateway" {'}'},
-
-
- {' '}
- {'{'} "id": "api", "type": "service",
-
- "evidence": [
-
- {' '}
- {'{'} "file": "services/api/src/server.ts", "line": 12 {'}'}] {'}'},
-
-
- {' '}
- {'{'} "id": "orders", "type": "database", "group":{' '}
- "data" {'}'},
-
-
- {' '}
- {'{'} "id": "events", "type": "queue" {'}'},
-
- …
- ],
- "edges": [
-
- {' '}
- {'{'} "id": "e-api-orders", "from": "api", "to":{' '}
-
- "orders-db"
- "orders"
- {' '}
- {'}'},
-
- …
- ]
- {'}'}
-
-
-
-
-
-
-
-
-
- Storefront
- Next.js
-
-
-
-
-
-
-
-
-
-
-
- Edge gateway
- Public routing
-
-
-
-
-
-
-
-
-
-
-
- shop-api
- REST API
-
-
-
-
-
-
-
-
-
-
-
- Orders DB
- PostgreSQL
-
-
-
-
-
-
- -
-
- 01
-
Ask.
- Ask your coding agent for a diagram of a codebase, a system, a process or a request.
-
- -
-
- 02
-
It writes JSON.
- A small typed diagram.json: nodes, connections, groups and views. No coordinates.
-
- -
-
- 03
-
stackmap checks it.
- validate names each problem with a code and the allowed fixes. The agent repairs what is named.
-
- -
-
- 04
-
One file comes back.
- deliver lays the diagram out and writes one self-contained HTML viewer.
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Features.tsx b/site/components/landing/desktop/Features.tsx
deleted file mode 100644
index aa7b7b3..0000000
--- a/site/components/landing/desktop/Features.tsx
+++ /dev/null
@@ -1,217 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Features() {
- return (
- <>
-
-
-
-
-
- Trace. Route.
- {' '}
-
-
- Play.
-
-
-
-
- The viewer above is the real thing, cut down to one diagram, and every control works. Here is what each one does.
-
-
-
-
-
- Explore
- Click
-
- Select a card for its details, connections and the file and line behind it.
-
-
-
-
- Trace
- T
-
- Keep a node’s upstream and downstream. Everything else dims; nothing moves.
-
-
-
-
- Route
- R
-
- Pick two nodes and every path between them lights up, hop by hop.
-
-
-
-
- Find
- /
-
- Search titles, ids and types. The lens dims the types you don’t need.
-
-
-
-
- Guided views
- F
-
- Tabs your agent defines, like Checkout path. Present steps through them full screen.
-
-
-
-
- Play
- P
-
- Pulses travel whatever you’re looking at: the diagram, a view, a trace or a route.
-
-
-
-
- Share
- ⌘C
-
- The URL keeps the view, selection, route and playback. Export PNG, JPEG, WebP, SVG or a video.
-
-
-
-
- Themes
-
- Dark and light, and every animation respects reduced motion.
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Files.tsx b/site/components/landing/desktop/Files.tsx
deleted file mode 100644
index 90058ca..0000000
--- a/site/components/landing/desktop/Files.tsx
+++ /dev/null
@@ -1,215 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Files() {
- return (
- <>
-
-
-
-
-
-
-
-
- One file.
-
- Opens anywhere.
-
-
- -
-
- No server, no account, nothing to install to open it.
-
- -
-
- The same JSON always gives the same file, byte for byte.
-
- -
-
- The URL keeps the view, the selection, the route and playback.
-
- -
-
- Export PNG, JPEG, WebP or SVG, or a short video of the flow.
-
-
-
-
- See the examples
-
-
- Sixteen diagrams, from release pipelines to maps a coding agent wrote from one request.
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Hero.tsx b/site/components/landing/desktop/Hero.tsx
deleted file mode 100644
index 4f6dffd..0000000
--- a/site/components/landing/desktop/Hero.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { BoardCopy } from '../BoardCopy';
-import { s } from '../style';
-import { LINKS } from '@/components/site/links';
-
-export function Hero() {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- Every
- {' '}
-
- layer
- {' '}
-
- of
- {' '}
-
- your
- {' '}
-
- stack,
-
-
-
-
-
-
- on
- {' '}
-
- one
- {' '}
-
- map.
-
-
-
-
- Interactive system diagrams your coding agent writes, as one offline HTML file.
-
- Works with Claude Code, Cursor, Codex and other coding agents.
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Install.tsx b/site/components/landing/desktop/Install.tsx
deleted file mode 100644
index 53230fb..0000000
--- a/site/components/landing/desktop/Install.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { BoardCopy } from '../BoardCopy';
-import { s } from '../style';
-
-export function Install() {
- return (
- <>
-
-
-
-
-
-
-
-
- Every layer of your stack,{' '}
-
- on one map.
-
-
- Interactive system diagrams your coding agent writes, as one offline HTML file.
-
-
- 1
-
- Install the skill into your agent
-
-
- {SITE.install.skill}
-
-
-
-
-
- 2
-
- Then ask
- Make an architecture diagram of this repository, backed by evidence from the code.
-
-
-
-
-
- Or run the CLI on its own, with Node 22.12 or later: it turns any diagram.json into{' '}
- diagram.html beside it.
-
-
-
- {SITE.install.cli}
-
-
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Kinds.tsx b/site/components/landing/desktop/Kinds.tsx
deleted file mode 100644
index f11626f..0000000
--- a/site/components/landing/desktop/Kinds.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { DIAGRAM_KINDS, KIND_LABELS, type LaidOutDiagram } from '@stackmap/core';
-import { KindPills } from '../KindPills';
-import { KindsStage } from '../KindsStage';
-import { s } from '../style';
-
-const REST = DIAGRAM_KINDS.indexOf('workflow');
-
-const LINES = ['Components and what they call.', 'Data moving through stages.', 'Steps across owner lanes.', 'The states of one thing.', 'Messages over time.'];
-
-/** #kinds: one checkout, five ways. At rest it shows the workflow, as the canvas does. */
-export function Kinds({ checkout }: { checkout: Record }) {
- return (
-
-
-
- Five kinds of diagram: architecture, dataflow, workflow, lifecycle and sequence.
-
-
-
-
-
-
-
-
- );
-}
diff --git a/site/components/landing/desktop/Unmapped.tsx b/site/components/landing/desktop/Unmapped.tsx
deleted file mode 100644
index b28742d..0000000
--- a/site/components/landing/desktop/Unmapped.tsx
+++ /dev/null
@@ -1,255 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Unmapped() {
- return (
- <>
-
-
-
-
-
-
- Every codebase has a shape. Nobody has drawn it.
-
-
-
-
-
-
- stackmap turns what your coding agent knows about a system into a diagram you can explore.
-
-
-
-
-
-
-
-
-
-
- shop-api
- REST API
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Orders DB
- PostgreSQL
-
-
-
-
-
-
-
-
-
- infra/orders/postgres.tf:12
-
-
- Every node can point back to the file and line it came from.
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/desktop/Viewer.tsx b/site/components/landing/desktop/Viewer.tsx
deleted file mode 100644
index ad87bc2..0000000
--- a/site/components/landing/desktop/Viewer.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import type { LaidOutDiagram } from '@stackmap/core';
-import { toScene } from '@stackmap/viewer/src/canvas/scene';
-import { Still } from '@/components/diagram/Still';
-import { stillOf } from '@/lib/diagrams';
-import { viewerTweens } from '../drops';
-import { LazyViewer } from '../LazyViewer';
-import { s } from '../style';
-import { TWEENS } from './timelines';
-
-// The plane the cards drop onto, inside the viewer's stage (the board's .plane-wrap).
-const PLANE = { width: 734, height: 656 };
-
-/** #viewer, "Lights on": the demo lands on a tilted map, flattens, and becomes the real viewer. */
-export function Viewer({ demo }: { demo: LaidOutDiagram }) {
- const { content } = toScene(demo);
- const k = Math.min(1, PLANE.width / content.width, PLANE.height / content.height);
- const timelines = JSON.stringify(viewerTweens(demo, TWEENS)).replace(/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/site/components/landing/desktop/timelines.ts b/site/components/landing/desktop/timelines.ts
deleted file mode 100644
index d3dc77c..0000000
--- a/site/components/landing/desktop/timelines.ts
+++ /dev/null
@@ -1,4081 +0,0 @@
-// Ported from the canvas board: every scroll timeline, as GSAP percentage keyframes over one 10 s scene.
-// Eases "cb:x1,y1,x2,y2" are the board's cubic-beziers (made into CustomEases at run time).
-import type { Tween } from '../timeline';
-
-export const TWEENS: Tween[] = [
- {
- "target": ".a-hero-out",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "filter": "blur(0px)"
- },
- "100%": {
- "opacity": "0",
- "transform": "translateY(-90px)",
- "filter": "blur(8px)",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-hero-chips",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1)"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0.72)",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-hbridge",
- "frames": {
- "0%": {
- "strokeDashoffset": "1"
- },
- "42%": {
- "strokeDashoffset": "1"
- },
- "78%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-hmarks",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "1"
- },
- "52%": {
- "opacity": "0"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vx",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1.35) rotate(-24deg)"
- },
- "7%": {
- "opacity": "1",
- "transform": "scale(1) rotate(0deg)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "26%": {
- "opacity": "1",
- "transform": "scale(1) rotate(0deg)",
- "filter": "blur(0px)"
- },
- "40%": {
- "opacity": "1",
- "transform": "scale(0) rotate(240deg)",
- "filter": "blur(10px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "41%": {
- "opacity": "0"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0) rotate(240deg)"
- }
- }
- },
- {
- "target": ".a-kw",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1)",
- "filter": "blur(0px)"
- },
- "27%": {
- "opacity": "1",
- "transform": "scale(1)",
- "filter": "blur(0px)"
- },
- "38%": {
- "opacity": "0",
- "transform": "scale(0.12)",
- "filter": "blur(14px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0.12)"
- }
- }
- },
- {
- "target": ".a-k1w0",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "2%": {
- "transform": "translateY(112%)"
- },
- "6.2%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w1",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "3.6%": {
- "transform": "translateY(112%)"
- },
- "7.8%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w2",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "5.2%": {
- "transform": "translateY(112%)"
- },
- "9.4%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w3",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "6.8%": {
- "transform": "translateY(112%)"
- },
- "11%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w4",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "8.4%": {
- "transform": "translateY(112%)"
- },
- "12.6%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w0",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "15%": {
- "transform": "translateY(112%)"
- },
- "19.2%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w1",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "16.6%": {
- "transform": "translateY(112%)"
- },
- "20.8%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w2",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "18.2%": {
- "transform": "translateY(112%)"
- },
- "22.4%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w3",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "19.8%": {
- "transform": "translateY(112%)"
- },
- "24%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1c",
- "frames": {
- "0%": {
- "color": "var(--sm-text)"
- },
- "15%": {
- "color": "var(--sm-text)"
- },
- "19%": {
- "color": "var(--sm-text-muted)"
- },
- "100%": {
- "color": "var(--sm-text-muted)"
- }
- }
- },
- {
- "target": ".a-cdot",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "29%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "31%": {
- "opacity": "1",
- "transform": "scale(1.9)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "33%": {
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "35.5%": {
- "transform": "scale(1.9)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "38%": {
- "transform": "scale(1)",
- "backgroundColor": "var(--sm-edge)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "41.5%": {
- "transform": "scale(0.5)",
- "backgroundColor": "var(--sm-text)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43.5%": {
- "opacity": "1",
- "transform": "scale(5)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "46%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0)"
- }
- }
- },
- {
- "target": ".a-shock",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0.02)"
- },
- "43%": {
- "opacity": "0",
- "transform": "scale(0.02)"
- },
- "43.5%": {
- "opacity": "0.7",
- "transform": "scale(0.02)"
- },
- "53%": {
- "opacity": "0",
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(1)"
- }
- }
- },
- {
- "target": ".a-s2grid",
- "frames": {
- "0%": {
- "opacity": "0",
- "WebkitMaskSize": "0px 0px",
- "maskSize": "0px 0px"
- },
- "43%": {
- "opacity": "1",
- "WebkitMaskSize": "0px 0px",
- "maskSize": "0px 0px"
- },
- "55%": {
- "opacity": "1",
- "WebkitMaskSize": "2400px 2400px",
- "maskSize": "2400px 2400px",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "WebkitMaskSize": "2400px 2400px",
- "maskSize": "2400px 2400px"
- }
- }
- },
- {
- "target": ".a-mk",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(1)"
- },
- "45%": {
- "opacity": "0"
- },
- "45.5%": {
- "opacity": "1",
- "transform": "scale(1)"
- },
- "64%": {
- "opacity": "1",
- "transform": "scale(1)"
- },
- "70%": {
- "opacity": "0",
- "transform": "scale(1.04)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mkdot",
- "frames": {
- "0%": {
- "transform": "scale(0.2)",
- "opacity": "0"
- },
- "45.5%": {
- "transform": "scale(0.2)",
- "opacity": "0"
- },
- "50%": {
- "transform": "scale(1)",
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "scale(1)",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mksrc",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0.9)"
- },
- "49%": {
- "opacity": "0",
- "transform": "scale(0.9)"
- },
- "52.5%": {
- "opacity": "1",
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "scale(1)"
- }
- }
- },
- {
- "target": ".a-mktgt",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(0.75px) scale(0.985)"
- },
- "58%": {
- "opacity": "0",
- "transform": "translateY(0.75px) scale(0.985)"
- },
- "62%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-s2e",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "77%": {
- "opacity": "0"
- },
- "77.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2eln",
- "frames": {
- "0%": {
- "strokeDashoffset": "1"
- },
- "77.5%": {
- "strokeDashoffset": "1"
- },
- "83%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.33,1,0.68,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-s2eah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "0"
- },
- "84%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2sel",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "86%": {
- "opacity": "0"
- },
- "88%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2lead",
- "frames": {
- "0%": {
- "strokeDashoffset": "1",
- "opacity": "1"
- },
- "88%": {
- "strokeDashoffset": "1"
- },
- "92%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.33,1,0.68,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-s2ev",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "91%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "94%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-s2cap1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "55%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "60%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "65%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "69%": {
- "opacity": "0",
- "transform": "translateY(-8px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-s2cap2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "93%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "97%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-mapi-box",
- "frames": {
- "0%": {
- "left": "552px",
- "top": "498px",
- "width": "144px",
- "height": "96px",
- "borderRadius": "28px",
- "opacity": "0"
- },
- "64%": {
- "left": "552px",
- "top": "498px",
- "width": "144px",
- "height": "96px",
- "borderRadius": "28px",
- "opacity": "0"
- },
- "64.5%": {
- "opacity": "1"
- },
- "74%": {
- "left": "396px",
- "top": "418px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "396px",
- "top": "418px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mapi-ov",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "68%": {
- "opacity": "1"
- },
- "76%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mapi-in",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "72%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mdb-box",
- "frames": {
- "0%": {
- "left": "744px",
- "top": "306px",
- "width": "144px",
- "height": "96px",
- "borderRadius": "28px",
- "opacity": "0"
- },
- "64%": {
- "left": "744px",
- "top": "306px",
- "width": "144px",
- "height": "96px",
- "borderRadius": "28px",
- "opacity": "0"
- },
- "64.5%": {
- "opacity": "1"
- },
- "74%": {
- "left": "764px",
- "top": "418px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "764px",
- "top": "418px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mdb-ov",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "68%": {
- "opacity": "1"
- },
- "76%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mdb-in",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "72%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-tr0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "37%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "39.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "41%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "43.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "44%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "46.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "45%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "47.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr4",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "47.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "49.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr5",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "49%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "51.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr6",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "53%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "55.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr7",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "56.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "58.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr8",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "61%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "63.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr9",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "64.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "66.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr10",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "65.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "67.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-jr0",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "41.2%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40.7%": {
- "opacity": "0"
- },
- "41.9%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "41.4%": {
- "opacity": "0"
- },
- "42.6%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "42.8%": {
- "opacity": "0"
- },
- "44%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "43.5%": {
- "opacity": "0"
- },
- "44.7%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr5",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "44.2%": {
- "opacity": "0"
- },
- "45.4%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr6",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "44.9%": {
- "opacity": "0"
- },
- "46.1%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr7",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "45.3%": {
- "opacity": "0"
- },
- "46.5%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr8",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "45.9%": {
- "opacity": "0"
- },
- "47.1%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr9",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "46.3%": {
- "opacity": "0"
- },
- "47.5%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr10",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "47%": {
- "opacity": "0"
- },
- "48.2%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr11",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "47.7%": {
- "opacity": "0"
- },
- "48.9%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr12",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "48.4%": {
- "opacity": "0"
- },
- "49.6%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr13",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "49.1%": {
- "opacity": "0"
- },
- "50.3%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr14",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "49.8%": {
- "opacity": "0"
- },
- "51%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr15",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "50.5%": {
- "opacity": "0"
- },
- "51.7%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr16",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "51.2%": {
- "opacity": "0"
- },
- "52.4%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-jr17",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "51.9%": {
- "opacity": "0"
- },
- "53.1%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-fly0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translate(694px, -342px) scale(0.32)"
- },
- "55%": {
- "opacity": "0",
- "transform": "translate(694px, -342px) scale(0.32)"
- },
- "60%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-fly1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translate(371px, -322px) scale(0.32)"
- },
- "56.6%": {
- "opacity": "0",
- "transform": "translate(371px, -322px) scale(0.32)"
- },
- "61.6%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-fly2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translate(49px, -303px) scale(0.32)"
- },
- "58.2%": {
- "opacity": "0",
- "transform": "translate(49px, -303px) scale(0.32)"
- },
- "63.2%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-fly3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translate(-274px, -244px) scale(0.32)"
- },
- "59.8%": {
- "opacity": "0",
- "transform": "translate(-274px, -244px) scale(0.32)"
- },
- "64.8%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-st0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "1%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "30%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-sd0",
- "frames": {
- "0%": {
- "backgroundColor": "var(--sm-text)"
- },
- "0.5%": {
- "backgroundColor": "var(--sm-text)"
- },
- "100%": {
- "backgroundColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-st1",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "29%": {
- "opacity": "0.42"
- },
- "31%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "50%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-sd1",
- "frames": {
- "0%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "29.5%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "30.5%": {
- "backgroundColor": "var(--sm-text)"
- },
- "100%": {
- "backgroundColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-st2",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "49%": {
- "opacity": "0.42"
- },
- "51%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "62%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-sd2",
- "frames": {
- "0%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "49.5%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "50.5%": {
- "backgroundColor": "var(--sm-text)"
- },
- "100%": {
- "backgroundColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-st3",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "61%": {
- "opacity": "0.42"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-sd3",
- "frames": {
- "0%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "61.5%": {
- "backgroundColor": "var(--sm-stage)"
- },
- "62.5%": {
- "backgroundColor": "var(--sm-text)"
- },
- "100%": {
- "backgroundColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-ty0",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "2%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "10%": {
- "width": "28ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(28)"
- },
- "10.4%": {
- "width": "28ch",
- "borderRightColor": "transparent"
- },
- "100%": {
- "width": "28ch",
- "borderRightColor": "transparent"
- }
- }
- },
- {
- "target": ".a-ty1",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "transparent"
- },
- "10.5%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "18.5%": {
- "width": "29ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(29)"
- },
- "18.9%": {
- "width": "29ch",
- "borderRightColor": "transparent"
- },
- "100%": {
- "width": "29ch",
- "borderRightColor": "transparent"
- }
- }
- },
- {
- "target": ".a-ty2",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "transparent"
- },
- "19%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "25%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(23)"
- },
- "25.4%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)"
- },
- "100%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-bigp",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- },
- "26.5%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- },
- "34%": {
- "opacity": "1",
- "transform": "translate(-6px, -95px) scale(0.2344)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "35.5%": {
- "opacity": "0",
- "transform": "translate(-6px, -95px) scale(0.2344)"
- },
- "100%": {
- "opacity": "0",
- "transform": "translate(-6px, -95px) scale(0.2344)"
- }
- }
- },
- {
- "target": ".a-tp",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "34.5%": {
- "opacity": "0"
- },
- "35.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-term",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(24px)"
- },
- "26%": {
- "opacity": "0",
- "transform": "translateY(24px)"
- },
- "32%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "44%": {
- "transform": "translateX(0px)"
- },
- "44.6%": {
- "transform": "translateX(-7px)"
- },
- "45.2%": {
- "transform": "translateX(6px)"
- },
- "45.8%": {
- "transform": "translateX(-4px)"
- },
- "46.4%": {
- "transform": "translateX(2px)"
- },
- "47%": {
- "transform": "translateX(0px)"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateX(0px)"
- }
- }
- },
- {
- "target": ".a-json",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(24px)"
- },
- "38%": {
- "opacity": "0",
- "transform": "translateY(24px)"
- },
- "42%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-fxbad",
- "frames": {
- "0%": {
- "opacity": "1",
- "maxWidth": "11ch"
- },
- "49.5%": {
- "opacity": "1",
- "maxWidth": "11ch"
- },
- "51.5%": {
- "opacity": "0",
- "maxWidth": "0ch",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0",
- "maxWidth": "0ch"
- }
- }
- },
- {
- "target": ".a-fxok",
- "frames": {
- "0%": {
- "opacity": "0",
- "maxWidth": "0ch"
- },
- "51%": {
- "opacity": "0",
- "maxWidth": "0ch"
- },
- "53%": {
- "opacity": "1",
- "maxWidth": "8ch",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "maxWidth": "8ch"
- }
- }
- },
- {
- "target": ".a-drop0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "13%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "14%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "17.2%": {
- "transform": "translateZ(0px)"
- },
- "18.2%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19.2%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade0",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "47%": {
- "opacity": "0"
- },
- "50.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "17.6%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "18.6%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "21.8%": {
- "transform": "translateZ(0px)"
- },
- "22.8%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "23.8%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "49.2%": {
- "opacity": "0"
- },
- "52.8%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "22.2%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "23.2%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "26.4%": {
- "transform": "translateZ(0px)"
- },
- "27.4%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "28.4%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "51.4%": {
- "opacity": "0"
- },
- "55%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "26.8%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "27.8%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "31%": {
- "transform": "translateZ(0px)"
- },
- "32%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "33%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "53.6%": {
- "opacity": "0"
- },
- "57.2%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop4",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "31.4%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "32.4%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "35.6%": {
- "transform": "translateZ(0px)"
- },
- "36.6%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "37.6%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "55.8%": {
- "opacity": "0"
- },
- "59.4%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop5",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "36%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "37%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "40.2%": {
- "transform": "translateZ(0px)"
- },
- "41.2%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "42.2%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade5",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "58%": {
- "opacity": "0"
- },
- "61.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ahin",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "61.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-frin",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "46%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".vcam .hd",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "58%": {
- "opacity": "0"
- },
- "61%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-lights",
- "frames": {
- "0%": {
- "clipPath": "circle(0px at 2456px 1304px)"
- },
- "13%": {
- "clipPath": "circle(3600px at 2456px 1304px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "clipPath": "circle(3600px at 2456px 1304px)"
- }
- }
- },
- {
- "target": ".a-plane",
- "frames": {
- "0%": {
- "transform": "rotateX(58deg) translateY(-20px) scale(0.92)"
- },
- "30%": {
- "transform": "rotateX(58deg) translateY(-20px) scale(0.92)"
- },
- "50%": {
- "transform": "rotateX(0deg) translateY(0px) scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "rotateX(0deg) translateY(0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-pgrid",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "6%": {
- "opacity": "0"
- },
- "14%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "50%": {
- "opacity": "1"
- },
- "58%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vclip",
- "frames": {
- "0%": {
- "clipPath": "inset(-900px round 20px)"
- },
- "52%": {
- "clipPath": "inset(-900px round 20px)"
- },
- "60%": {
- "clipPath": "inset(0px round 20px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "clipPath": "inset(0px round 20px)"
- }
- }
- },
- {
- "target": ".a-dtitle",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "46%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "53%": {
- "opacity": "0",
- "transform": "translateY(-20px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vstage",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "50%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-vhead",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "60%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "65%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "64%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "68%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "66%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "70%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "68%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "72%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vinsp",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateX(14px)"
- },
- "70%": {
- "opacity": "0",
- "transform": "translateX(14px)"
- },
- "76%": {
- "opacity": "1",
- "transform": "translateX(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateX(0px)"
- }
- }
- },
- {
- "target": ".a-ks0",
- "frames": {
- "0%": {
- "left": "340px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "340px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "300.3px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "300.3px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "495.3px",
- "top": "468.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "495.3px",
- "top": "468.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "506.9px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "506.9px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "558.1px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "558.1px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf0_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf0_1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "19%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf0_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf0_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf0_4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ks1",
- "frames": {
- "0%": {
- "left": "544.9px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "544.9px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "531.7px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "531.7px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "495.3px",
- "top": "570.6px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "495.3px",
- "top": "570.6px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "506.9px",
- "top": "588.8px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "506.9px",
- "top": "588.8px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "379.7px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "379.7px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf1_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf1_1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "19%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf1_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf1_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf1_4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ks2",
- "frames": {
- "0%": {
- "left": "749.7px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "749.7px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "763px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "763px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "693.6px",
- "top": "673px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "693.6px",
- "top": "673px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "705.1px",
- "top": "691.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "705.1px",
- "top": "691.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "705.1px",
- "top": "691.2px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "705.1px",
- "top": "691.2px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf2_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf2_1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "19%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf2_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf2_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-ks3",
- "frames": {
- "0%": {
- "left": "954.6px",
- "top": "532.6px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "954.6px",
- "top": "532.6px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "954.6px",
- "top": "532.6px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "954.6px",
- "top": "532.6px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "891.8px",
- "top": "570.6px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "891.8px",
- "top": "570.6px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "903.4px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "903.4px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "915px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "915px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf3_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf3_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf3_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf3_4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ks4",
- "frames": {
- "0%": {
- "left": "954.6px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "954.6px",
- "top": "615.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "994.3px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "994.3px",
- "top": "592.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "693.6px",
- "top": "468.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "693.6px",
- "top": "468.2px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "705.1px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "705.1px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "736.5px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "736.5px",
- "top": "486.3px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf4_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf4_1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "19%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf4_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf4_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf4_4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ks5",
- "frames": {
- "0%": {
- "left": "954.6px",
- "top": "697.8px",
- "height": "49.6px",
- "opacity": "1"
- },
- "16%": {
- "left": "954.6px",
- "top": "697.8px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "left": "994.3px",
- "top": "674.7px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "left": "994.3px",
- "top": "674.7px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "left": "693.6px",
- "top": "775.5px",
- "height": "69.4px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "left": "693.6px",
- "top": "775.5px",
- "height": "69.4px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "left": "705.1px",
- "top": "777.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "left": "705.1px",
- "top": "777.1px",
- "height": "49.6px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "left": "705.1px",
- "top": "777.1px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "705.1px",
- "top": "777.1px",
- "height": "49.6px",
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-kf5_0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1"
- },
- "20%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf5_1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "19%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf5_2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "39%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "60%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kf5_3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "59%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "80%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kl0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd0 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "3%": {
- "opacity": "0"
- },
- "3.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "20%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "39%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd1 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "26%": {
- "opacity": "0"
- },
- "26.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "59%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd2 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "46%": {
- "opacity": "0"
- },
- "46.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "79%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd3 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "66%": {
- "opacity": "0"
- },
- "66.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "80%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kd4 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "86%": {
- "opacity": "0"
- },
- "86.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kname",
- "frames": {
- "0%": {
- "transform": "translateY(0px)"
- },
- "16%": {
- "transform": "translateY(0px)"
- },
- "22%": {
- "transform": "translateY(-260px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "transform": "translateY(-260px)"
- },
- "42%": {
- "transform": "translateY(-520px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "transform": "translateY(-520px)"
- },
- "62%": {
- "transform": "translateY(-780px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "transform": "translateY(-780px)"
- },
- "82%": {
- "transform": "translateY(-1040px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "translateY(-1040px)"
- }
- }
- },
- {
- "target": ".a-kline0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "20%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "39%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "59%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "79%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "80%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kcam",
- "frames": {
- "0%": {
- "transform": "scale(1.3316)"
- },
- "16%": {
- "transform": "scale(1.3316)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "23%": {
- "transform": "scale(1.3316)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "transform": "scale(1.3316)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43%": {
- "transform": "scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "transform": "scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "63%": {
- "transform": "scale(1.0866)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "transform": "scale(1.0866)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "83%": {
- "transform": "scale(1.3316)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "scale(1.3316)",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-ofcap",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "30%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "36%": {
- "opacity": "0",
- "transform": "translateY(-10px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-file",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translate(-346px, 0px) scale(0.94)"
- },
- "16%": {
- "opacity": "1",
- "transform": "translate(-346px, 0px) scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "40%": {
- "opacity": "1",
- "transform": "translate(-346px, 0px) scale(1)"
- },
- "54%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-flights",
- "frames": {
- "0%": {
- "opacity": "1",
- "clipPath": "inset(calc(1200px - var(--by, 0px)) calc(2400px - var(--bx, 0px)) calc(1200px - var(--by, 0px)) calc(2400px - var(--bx, 0px)) round 0px)"
- },
- "16%": {
- "opacity": "1",
- "clipPath": "inset(1396px 2954px 1444px 2954px round 20px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "16.5%": {
- "opacity": "0",
- "clipPath": "inset(1396px 2954px 1444px 2954px round 20px)"
- },
- "100%": {
- "opacity": "0",
- "clipPath": "inset(1396px 2954px 1444px 2954px round 20px)"
- }
- }
- },
- {
- "target": ".a-filein",
- "frames": {
- "0%": {
- "transform": "rotateY(0deg)"
- },
- "20%": {
- "transform": "rotateY(0deg)"
- },
- "35%": {
- "transform": "rotateY(180deg)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "rotateY(180deg)"
- }
- }
- },
- {
- "target": ".a-ofh",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateX(-30px)"
- },
- "44%": {
- "opacity": "0",
- "transform": "translateX(-30px)"
- },
- "56%": {
- "opacity": "1",
- "transform": "translateX(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateX(0px)"
- }
- }
- },
- {
- "target": ".a-ofl0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "56%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "62%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "59%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "65%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "62%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "68%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "65%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "71%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofmore",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "76%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "84%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- }
-];
diff --git a/site/components/landing/drops.ts b/site/components/landing/drops.ts
deleted file mode 100644
index 2a8d8b9..0000000
--- a/site/components/landing/drops.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { LaidOutDiagram } from '@stackmap/core';
-import { toScene } from '@stackmap/viewer/src/canvas/scene';
-import type { Tween } from './timeline';
-
-/** The board has six drop beats; ranks past the last share it. */
-export const DROP_BEATS = 6;
-
-/**
- * "Cards drop onto the tilted map, layer by layer": a card's layer is its rank along the flow, so the
- * diagram lands from its entry points outward. Ranks come from the laid-out positions, not a list.
- */
-export function dropLayers(diagram: LaidOutDiagram): Map {
- const scene = toScene(diagram);
- const horizontal = scene.direction === 'RIGHT';
- const along = (id: string) => {
- const r = scene.cards.find((c) => c.node.id === id)!.rect;
- return horizontal ? r.x : r.y;
- };
- const ranks = [...new Set(scene.cards.map((c) => along(c.node.id)))].sort((a, b) => a - b);
- return new Map(scene.cards.map((c) => [c.node.id, Math.min(DROP_BEATS - 1, ranks.indexOf(along(c.node.id)))]));
-}
-
-const ENTER = 'cb:0.23,1,0.32,1';
-
-/**
- * The viewer scene's own timelines: each card takes the board's drop for its layer, connections fade in
- * after the map flattens, and the intro hands over to the real viewer by 76%.
- */
-export function viewerTweens(diagram: LaidOutDiagram, board: Tween[]): Tween[] {
- const drop = (layer: number) => board.find((t) => t.target === `.a-drop${layer}`)?.frames;
- const drops = [...dropLayers(diagram)].flatMap(([id, layer]) => {
- const frames = drop(layer);
- return frames ? [{ target: `.plane [data-card-id="${id}"]`, frames }] : [];
- });
- return [
- ...drops,
- { target: '.plane .sm-edges, .plane .sm-edge-label', frames: { '0%': { opacity: '0' }, '47%': { opacity: '0' }, '58%': { opacity: '1', ease: 'cb:0.33,1,0.68,1' }, '100%': { opacity: '1' } } },
- { target: '.vintro', frames: { '0%': { autoAlpha: '1' }, '76%': { autoAlpha: '1' }, '80%': { autoAlpha: '0', ease: ENTER }, '100%': { autoAlpha: '0' } } },
- { target: '.vreal', frames: { '0%': { autoAlpha: '0' }, '60%': { autoAlpha: '0' }, '76%': { autoAlpha: '1', ease: ENTER }, '100%': { autoAlpha: '1' } } },
- ];
-}
diff --git a/site/components/landing/kinds-geometry.ts b/site/components/landing/kinds-geometry.ts
deleted file mode 100644
index df26a58..0000000
--- a/site/components/landing/kinds-geometry.ts
+++ /dev/null
@@ -1,172 +0,0 @@
-import { DIAGRAM_KINDS, type DiagramKind, type LaidOutDiagram, type Rect } from '@stackmap/core';
-import { toScene, type SceneCard } from '@stackmap/viewer/src/canvas/scene';
-import { buildGraph } from '@stackmap/viewer/src/explore/graph';
-import { INITIAL } from '@stackmap/viewer/src/explore/state';
-import type { Flow } from '@stackmap/viewer/src/motion/flow';
-import { flowOf } from '@stackmap/viewer/src/motion/flowOf';
-import { SLOT_COUNT, SLOTS } from '@/lib/checkout';
-import type { Tween } from './timeline';
-
-/** The stage the kinds share, in frame pixels: its centre is the camera's origin. */
-export interface Area {
- cx: number;
- cy: number;
- width: number;
- height: number;
-}
-
-export interface KindLayer {
- kind: DiagramKind;
- diagram: LaidOutDiagram;
- /** the layer's box on the frame at the shared scale */
- left: number;
- top: number;
- /** the camera's zoom for this kind: its own fit, never past `maxCam` */
- cam: number;
-}
-
-export interface SlotFace {
- card: SceneCard;
- compact: boolean;
- /** where the card sits on the frame, at the shared scale */
- rect: Rect;
-}
-
-export interface KindsGeometry {
- scale: number;
- layers: KindLayer[];
- /** slots[i][k]: slot i's card in kind k, or null when that kind has no card there */
- slots: (SlotFace | null)[][];
-}
-
-/** "Every kind is laid out at one shared scale; a camera scales the stage to each kind's own fit." */
-export function kindsGeometry(checkout: Record, area: Area, maxCam = 1.35): KindsGeometry {
- const scenes = DIAGRAM_KINDS.map((kind) => {
- const diagram = checkout[kind];
- if (!diagram) throw new Error(`no checkout drawn as ${kind}`);
- return { kind, diagram, scene: toScene(diagram) };
- });
- const scale = Math.min(...scenes.map(({ scene: { content } }) => Math.min(area.width / content.width, area.height / content.height)));
- const layers = scenes.map(({ kind, diagram, scene: { content } }) => ({
- kind,
- diagram,
- left: area.cx - (content.width * scale) / 2,
- top: area.cy - (content.height * scale) / 2,
- cam: Math.min(maxCam, area.width / (content.width * scale), area.height / (content.height * scale)),
- }));
- const slots = Array.from({ length: SLOT_COUNT }, (_, i) =>
- scenes.map(({ kind, scene }, k) => {
- const id = SLOTS[kind][i];
- if (!id) return null;
- const card = scene.cards.find((c) => c.node.id === id);
- if (!card) throw new Error(`${kind} checkout has no node ${id}`);
- const { left, top } = layers[k]!;
- const r = card.rect;
- return {
- card,
- compact: scene.compact,
- rect: { x: left + (r.x - scene.content.x) * scale, y: top + (r.y - scene.content.y) * scale, width: r.width * scale, height: r.height * scale },
- };
- }),
- );
- return { scale, layers, slots };
-}
-
-/** Each kind's hold, in percent of the pin (Motion board, #kinds). Between holds everything moves. */
-export const HOLDS: [number, number][] = [
- [0, 16],
- [23, 36],
- [43, 56],
- [63, 76],
- [83, 100],
-];
-
-const MOVE = 'cb:0.77,0,0.175,1';
-const ENTER = 'cb:0.23,1,0.32,1';
-const px = (n: number) => `${Math.round(n * 10) / 10}px`;
-
-// Where a slot sits in a kind that leaves it empty: where it last was, or where it first will be.
-function standIn(faces: (SlotFace | null)[], k: number): SlotFace {
- for (let j = k - 1; j >= 0; j--) if (faces[j]) return faces[j]!;
- for (let j = k + 1; j < faces.length; j++) if (faces[j]) return faces[j]!;
- throw new Error('a slot with no card in any kind');
-}
-
-/** Held through each kind, moving between them on the in-out curve. */
-function holds(at: (k: number) => Record): Tween['frames'] {
- const frames: Tween['frames'] = {};
- HOLDS.forEach(([a, b], k) => {
- frames[`${a}%`] = { ...at(k), ...(k ? { ease: MOVE } : {}) };
- frames[`${b}%`] = at(k);
- });
- return frames;
-}
-
-/** Shown through kind k's hold, fading over `fade` percent either side; the first kind starts shown, the last stays. */
-function shownIn(k: number, fade: number): Tween['frames'] {
- const [a, b] = HOLDS[k]!;
- const last = k === HOLDS.length - 1;
- return {
- '0%': { opacity: k === 0 ? '1' : '0' },
- ...(k === 0 ? {} : { [`${a - fade}%`]: { opacity: '0' }, [`${a}%`]: { opacity: '1', ease: ENTER } }),
- [`${b}%`]: { opacity: '1' },
- ...(last ? {} : { [`${b + fade}%`]: { opacity: '0', ease: ENTER } }),
- '100%': { opacity: last ? '1' : '0' },
- };
-}
-
-/** The phone's kinds: whole diagrams crossfading in their holds, one layer each. */
-export function crossfadeTweens(count: number): Tween[] {
- return Array.from({ length: count }, (_, k) => ({ target: `.kl${k}`, frames: shownIn(k, 3) }));
-}
-
-/** The scene's generated timelines: slots glide between kinds, layers and faces cross over, the camera refits. */
-export function kindsTweens(g: KindsGeometry): Tween[] {
- const out: Tween[] = [];
- g.slots.forEach((faces, i) => {
- out.push({
- target: `.ks${i}`,
- frames: holds((k) => {
- const { x, y, width, height } = (faces[k] ?? standIn(faces, k)).rect;
- return { left: px(x), top: px(y), width: px(width), height: px(height), opacity: faces[k] ? '1' : '0' };
- }),
- });
- faces.forEach((f, k) => f && out.push({ target: `.kf${i}_${k}`, frames: shownIn(k, 4) }));
- });
- g.layers.forEach((_, k) => out.push({ target: `.kl${k}`, frames: shownIn(k, 3) }));
- out.push({ target: '.kcam', frames: holds((k) => ({ scale: String(Math.round(g.layers[k]!.cam * 1000) / 1000) })) });
- return out;
-}
-
-export interface KindFlow {
- flow: Flow;
- /** the drawn content's corner in diagram px, which the layer's still is cut to */
- origin: { x: number; y: number };
- width: number;
- height: number;
-}
-
-/**
- * The flow the viewer plays on a diagram left alone. `glows: false` lands each pulse on a ripple: where the
- * layer draws its own cards, a glow would sit over them rather than behind.
- */
-export function restingFlow(diagram: LaidOutDiagram, { glows = true } = {}): KindFlow {
- const scene = toScene(diagram);
- const { draft } = diagram;
- const graph = buildGraph(draft.nodes.map((n) => n.id), draft.edges, { timed: draft.kind === 'sequence' });
- const flow = flowOf(scene, graph, INITIAL, { active: false, nodes: new Map(), edges: new Map() });
- return {
- flow: glows ? flow : { ...flow, pulses: flow.pulses.map((p) => ({ ...p, glow: null })) },
- origin: { x: scene.content.x, y: scene.content.y },
- width: scene.bounds.width,
- height: scene.bounds.height,
- };
-}
-
-/** "Each hold scrubs one loop of that kind's flow": ms into kind k's loop at scene progress p, or null outside its hold. */
-export function holdTime(p: number, k: number, period: number): number | null {
- const [a, b] = HOLDS[k]!;
- const pct = p * 100;
- if (p <= 0 || pct < a || pct >= b) return null;
- return ((pct - a) / (b - a)) * period;
-}
diff --git a/site/components/landing/landing.css b/site/components/landing/landing.css
new file mode 100644
index 0000000..1abae8b
--- /dev/null
+++ b/site/components/landing/landing.css
@@ -0,0 +1,1084 @@
+/* The landing, after the canvas's Landing boards (desktop 1440, phone 390). Shared pieces live in app/site.css. */
+
+.nowrap {
+ white-space: nowrap;
+}
+.sec {
+ padding-top: 176px;
+}
+.sec-h {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ max-width: 760px;
+}
+.sec-h .t-lede {
+ max-width: 640px;
+}
+.hs-d code,
+.tc > p code {
+ font-family: var(--font-mono);
+ font-size: 0.92em;
+ color: var(--sm-text);
+}
+
+/* The hero rises on page load, without waiting for script: headline, lede, command, caption 60 ms apart, then the frame. */
+@keyframes rise {
+ from {
+ opacity: 0;
+ transform: translateY(12px);
+ }
+}
+@keyframes rise-frame {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+}
+@media (prefers-reduced-motion: no-preference) {
+ [data-rise] {
+ animation: rise 640ms cubic-bezier(0.23, 1, 0.32, 1) var(--d, 0ms) both;
+ }
+ [data-rise-frame] {
+ animation-name: rise-frame;
+ }
+}
+
+/* hero */
+.hero {
+ position: relative;
+ padding-top: 176px;
+}
+.hero-bg {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ height: 760px;
+ opacity: 0.8;
+ pointer-events: none;
+ -webkit-mask-image: radial-gradient(ellipse 58% 60% at 50% 34%, #000 18%, transparent 72%);
+ mask-image: radial-gradient(ellipse 58% 60% at 50% 34%, #000 18%, transparent 72%);
+}
+.hero .wrap {
+ position: relative;
+}
+.hero-copy {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ max-width: 880px;
+ margin: 0 auto;
+}
+.hero-lede {
+ max-width: 600px;
+ margin-top: 22px;
+}
+.hero-acts {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+ margin-top: 36px;
+}
+.hero-works {
+ margin-top: 18px;
+ font-size: 13px;
+ line-height: 20px;
+ color: var(--sm-text-muted);
+}
+.demo {
+ margin-top: 80px;
+}
+
+/* try it */
+.try {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ margin-top: 28px;
+}
+.try-g {
+ display: flex;
+ gap: 4px;
+ padding: 5px;
+ border-radius: 9999px;
+ max-width: 100%;
+ overflow-x: auto;
+ scrollbar-width: none;
+}
+.try-g::-webkit-scrollbar {
+ display: none;
+}
+.try-b {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ height: 40px;
+ padding: 0 14px 0 12px;
+ border: 0;
+ border-radius: 9999px;
+ background: transparent;
+ color: var(--sm-text-muted);
+ font-size: 14px;
+ white-space: nowrap;
+ cursor: pointer;
+ transition:
+ background-color 150ms ease,
+ color 150ms ease,
+ transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
+}
+.try-b > span:first-child {
+ display: grid;
+}
+.try-b:hover {
+ color: var(--sm-text);
+}
+.try-b:active {
+ transform: scale(0.96);
+}
+.try-b:focus-visible {
+ outline: 2px solid var(--sm-text);
+ outline-offset: 2px;
+}
+.try-b[aria-pressed='true'] {
+ background: var(--sm-primary);
+ color: var(--sm-primary-text);
+}
+.try-b .kbd {
+ height: 20px;
+ min-width: 20px;
+ font-size: 11.5px;
+ transition:
+ background-color 150ms ease,
+ color 150ms ease,
+ box-shadow 150ms ease;
+}
+.try-b[aria-pressed='true'] .kbd {
+ background: transparent;
+ color: var(--sm-primary-text);
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sm-primary-text) 35%, transparent);
+}
+.try-d {
+ min-height: 22px;
+ font-size: 14px;
+ line-height: 22px;
+ color: var(--sm-text-muted);
+ text-align: center;
+ text-wrap: balance;
+}
+
+/* how it works */
+.how .sec-h {
+ margin-bottom: 56px;
+}
+.how-pin,
+.how-stick {
+ position: relative;
+}
+.how-frame {
+ display: flex;
+ flex-direction: column;
+ gap: 36px;
+}
+.hsteps {
+ position: relative;
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 32px;
+}
+.hrail {
+ position: absolute;
+ left: 4px;
+ right: 0;
+ top: 4px;
+ height: 1px;
+ background: var(--sm-divider);
+}
+.hfill {
+ position: absolute;
+ inset: 0;
+ background: var(--sm-text);
+ transform-origin: 0 50%;
+}
+.hs {
+ position: relative;
+ transition: opacity 180ms ease;
+}
+.hs button {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 6px;
+ width: 100%;
+ padding: 26px 0 0;
+ border: 0;
+ background: none;
+ text-align: left;
+ cursor: pointer;
+ border-radius: 8px;
+}
+.how-pin:not([data-live]) .hs button {
+ cursor: default;
+}
+.hs button:focus-visible {
+ outline: 2px solid var(--sm-text);
+ outline-offset: 6px;
+}
+.hs-dot {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 9px;
+ height: 9px;
+ border-radius: 9999px;
+ background: var(--sm-page);
+ box-shadow: inset 0 0 0 1.5px var(--sm-group-border);
+ transition:
+ background-color 180ms ease,
+ box-shadow 180ms ease;
+}
+.hs[data-state='done'] .hs-dot,
+.hs[data-state='now'] .hs-dot {
+ background: var(--sm-text);
+ box-shadow: none;
+}
+.hs[data-state='now'] .hs-dot {
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--sm-text) 14%, transparent);
+}
+.hs[data-state='next'] {
+ opacity: 0.42;
+}
+.hs-n {
+ font-size: 12.5px;
+ line-height: 18px;
+ color: var(--sm-text-muted);
+}
+.hs-t {
+ font-size: 20px;
+ line-height: 28px;
+ font-weight: 600;
+ letter-spacing: -0.02em;
+ color: var(--sm-text);
+}
+.hs-d {
+ font-size: 14.5px;
+ line-height: 1.55;
+ color: var(--sm-text-muted);
+ max-width: 290px;
+ text-wrap: pretty;
+}
+.hpanel {
+ display: grid;
+ grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr);
+ height: clamp(440px, calc(100vh - 360px), 508px);
+ border-radius: 20px;
+ overflow: hidden;
+}
+.ses {
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+}
+.ses-h,
+.fp-h {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ height: 48px;
+ padding: 0 20px;
+ flex-shrink: 0;
+ font-size: 13px;
+ color: var(--sm-text-muted);
+ box-shadow: inset 0 -1px 0 var(--sm-panel-border);
+}
+.ses-b {
+ display: flex;
+ flex-direction: column;
+ gap: 1px;
+ padding: 16px 22px 18px;
+ font-size: 13px;
+ line-height: 21px;
+ color: var(--sm-text-muted);
+ overflow: hidden;
+}
+.tl {
+ display: block;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+ transition:
+ opacity 180ms ease,
+ transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
+}
+.tl .mono {
+ font-size: 12.5px;
+}
+.tl.ask {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 12px;
+ padding: 10px 12px;
+ border-radius: 10px;
+ background: var(--sm-stage);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ font-size: 14px;
+ line-height: 21px;
+ color: var(--sm-text);
+}
+.ask-p {
+ color: var(--brand-accent);
+ font-weight: 600;
+}
+.tl.tool {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 6px;
+ color: var(--sm-text);
+}
+.tl.tool b {
+ font-weight: 500;
+}
+.tl.tool .mono {
+ color: var(--sm-text-muted);
+}
+.tdot {
+ width: 6px;
+ height: 6px;
+ border-radius: 9999px;
+ background: var(--sm-service-accent);
+ flex-shrink: 0;
+}
+.tl.out {
+ padding-left: 14px;
+}
+.tl.t-err .mono {
+ color: var(--sm-failure-accent);
+}
+.tl.t-ok .mono {
+ color: var(--sm-success-accent);
+}
+.tl.t-ink .mono {
+ color: var(--sm-text);
+}
+.fp {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+ background: var(--sm-stage);
+ box-shadow: inset 1px 0 0 var(--sm-panel-border);
+}
+.fp-f {
+ display: none;
+ align-items: center;
+ gap: 8px;
+ color: var(--sm-text);
+}
+.fp-tag {
+ display: none;
+ margin-left: auto;
+ height: 22px;
+ align-items: center;
+ padding: 0 9px;
+ border-radius: 9999px;
+ font-size: 12px;
+ color: var(--sm-text-muted);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+}
+.hpanel:not([data-step='3']) .fp-f.f-json,
+.hpanel[data-step='3'] .fp-f.f-html,
+.hpanel[data-step='3'] .fp-tag {
+ display: inline-flex;
+}
+.fp-b {
+ position: relative;
+ flex: 1;
+ min-height: 0;
+}
+.fp-json,
+.fp-map {
+ position: absolute;
+ inset: 0;
+ transition: opacity 180ms ease;
+}
+.fp-json {
+ padding: 16px 16px 16px 8px;
+ overflow: hidden;
+}
+.json-v {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ font-family: var(--font-mono);
+ font-size: 12px;
+ line-height: 20px;
+ color: var(--sm-text-muted);
+}
+.jl {
+ display: flex;
+ gap: 12px;
+ white-space: pre;
+ border-radius: 4px;
+ transition:
+ opacity 180ms ease,
+ transform 180ms cubic-bezier(0.23, 1, 0.32, 1),
+ background-color 180ms ease;
+}
+.jn {
+ width: 22px;
+ flex-shrink: 0;
+ text-align: right;
+ color: var(--sm-group-border);
+}
+.jc {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.j-k,
+.j-p {
+ color: var(--sm-text);
+}
+.j-s {
+ color: var(--sm-database-accent);
+}
+.jl.bad,
+.jl.fix {
+ margin: 0 -6px;
+ padding: 0 6px;
+}
+.caret {
+ position: absolute;
+ left: 34px;
+ top: 2px;
+ width: 7px;
+ height: 16px;
+ border-radius: 1px;
+ background: var(--sm-text);
+ opacity: 0;
+ animation: blink 1.1s steps(1) infinite;
+}
+@keyframes blink {
+ 50% {
+ opacity: 0;
+ }
+}
+.hpanel:not([data-step='3']) .fp-map {
+ opacity: 0;
+ visibility: hidden;
+}
+.hpanel[data-step='3'] .fp-json {
+ opacity: 0;
+ visibility: hidden;
+}
+.hpanel[data-step='0'] .jl {
+ opacity: 0;
+}
+.hpanel[data-step='0'] .caret {
+ opacity: 1;
+}
+.hpanel[data-step='1'] .jl.fix,
+.hpanel[data-step='0'] .jl.fix {
+ display: none;
+}
+.hpanel[data-step='2'] .jl.bad,
+.hpanel[data-step='3'] .jl.bad {
+ background: color-mix(in srgb, var(--sm-failure-accent) 13%, transparent);
+ text-decoration: line-through;
+ text-decoration-color: color-mix(in srgb, var(--sm-failure-accent) 70%, transparent);
+}
+.hpanel[data-step='2'] .jl.bad .jn,
+.hpanel[data-step='3'] .jl.bad .jn {
+ color: var(--sm-failure-accent);
+}
+.hpanel[data-step='2'] .jl.fix,
+.hpanel[data-step='3'] .jl.fix {
+ background: color-mix(in srgb, var(--sm-success-accent) 13%, transparent);
+}
+.hpanel[data-step='2'] .jl.fix .jn,
+.hpanel[data-step='3'] .jl.fix .jn {
+ color: var(--sm-success-accent);
+}
+/* While pinned, each step adds its session lines 40 ms apart and dims the earlier ones; JSON lines stream 22 ms apart. */
+[data-live] .hpanel .tl {
+ transition-delay: calc(var(--i) * 40ms);
+}
+[data-live] .hpanel[data-step='0'] .tl[data-s='1'],
+[data-live] .hpanel[data-step='0'] .tl[data-s='2'],
+[data-live] .hpanel[data-step='0'] .tl[data-s='3'],
+[data-live] .hpanel[data-step='1'] .tl[data-s='2'],
+[data-live] .hpanel[data-step='1'] .tl[data-s='3'],
+[data-live] .hpanel[data-step='2'] .tl[data-s='3'] {
+ opacity: 0;
+ transform: translateY(4px);
+ transition-delay: 0ms;
+}
+[data-live] .hpanel[data-step='1'] .tl[data-s='0'],
+[data-live] .hpanel[data-step='2'] .tl[data-s='0'],
+[data-live] .hpanel[data-step='2'] .tl[data-s='1'],
+[data-live] .hpanel[data-step='3'] .tl[data-s='0'],
+[data-live] .hpanel[data-step='3'] .tl[data-s='1'],
+[data-live] .hpanel[data-step='3'] .tl[data-s='2'] {
+ opacity: 0.5;
+}
+[data-live] .hpanel .jl {
+ transition-delay: calc(var(--i) * 22ms);
+}
+
+/* kinds */
+.kinds .sec-h {
+ margin-bottom: 48px;
+}
+.k-tabs {
+ position: relative;
+ display: flex;
+ gap: 4px;
+ width: max-content;
+ max-width: 100%;
+ margin: 0 auto;
+ padding: 5px;
+ border-radius: 9999px;
+ overflow-x: auto;
+ scrollbar-width: none;
+}
+.k-tabs::-webkit-scrollbar {
+ display: none;
+}
+.k-ind {
+ position: absolute;
+ left: 0;
+ top: 5px;
+ height: 36px;
+ border-radius: 9999px;
+ background: var(--sm-primary);
+ transition:
+ translate 180ms cubic-bezier(0.77, 0, 0.175, 1),
+ width 180ms cubic-bezier(0.77, 0, 0.175, 1);
+}
+.k-tab {
+ position: relative;
+ z-index: 1;
+ height: 36px;
+ padding: 0 16px;
+ border: 0;
+ border-radius: 9999px;
+ background: transparent;
+ color: var(--sm-text-muted);
+ font-size: 14px;
+ white-space: nowrap;
+ cursor: pointer;
+ transition: color 150ms ease;
+}
+.k-tab:hover {
+ color: var(--sm-text);
+}
+.k-tab[aria-selected='true'] {
+ color: var(--sm-primary-text);
+}
+.k-tab:focus-visible {
+ outline: 2px solid var(--sm-text);
+ outline-offset: 2px;
+}
+.k-stage {
+ position: relative;
+ height: 548px;
+ margin-top: 24px;
+ border-radius: 20px;
+ background-color: var(--sm-stage);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ overflow: hidden;
+}
+.k-layer {
+ position: absolute;
+ inset: 0;
+ opacity: 0;
+ visibility: hidden;
+ transition:
+ opacity 120ms ease,
+ visibility 0ms linear 120ms;
+}
+.k-layer.on {
+ opacity: 1;
+ visibility: visible;
+ transition: opacity 120ms ease;
+}
+.k-foot {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 24px;
+ margin-top: 20px;
+}
+.k-cap {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+.k-def {
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 500;
+ color: var(--sm-text);
+}
+.k-lay {
+ font-size: 14px;
+ line-height: 22px;
+ color: var(--sm-text-muted);
+}
+.k-more {
+ flex-shrink: 0;
+ color: var(--sm-text);
+}
+.ex-band {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ margin-top: 64px;
+ padding: 28px 32px;
+ border-radius: 20px;
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+}
+.ex-band p {
+ font-size: 17px;
+ line-height: 26px;
+ color: var(--sm-text);
+ max-width: 560px;
+ text-wrap: pretty;
+}
+
+/* proof */
+.trust .sec-h {
+ margin-bottom: 48px;
+}
+.t-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(480px, 100%), 1fr));
+ gap: 16px;
+}
+.tc {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ padding: 24px 24px 28px;
+ border-radius: 20px;
+ background: var(--sm-panel);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+}
+.tc > p {
+ font-size: 15px;
+ line-height: 1.55;
+ color: var(--sm-text-muted);
+ max-width: 480px;
+ text-wrap: pretty;
+}
+.tc-v {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 12px;
+ height: 208px;
+ margin-bottom: 14px;
+ padding: 20px 22px;
+ border-radius: 14px;
+ background: var(--sm-stage);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ overflow: hidden;
+}
+.tv-row {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+.tc-card {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ width: 196px;
+ height: 64px;
+ flex-shrink: 0;
+ padding: 0 16px;
+ border-radius: 14px;
+ background: var(--f);
+ box-shadow: inset 0 0 0 1px var(--b);
+}
+.tc-card .tile {
+ display: grid;
+ place-items: center;
+ width: 36px;
+ height: 36px;
+ flex-shrink: 0;
+ border-radius: 10px;
+ background: var(--t);
+ color: var(--a);
+}
+.tc-tx {
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+}
+.tc-card .ct {
+ font-size: 13.5px;
+ line-height: 20px;
+ font-weight: 500;
+ color: var(--sm-text);
+}
+.tc-card .cs {
+ font-size: 12px;
+ line-height: 16px;
+ color: var(--sm-text-muted);
+}
+.tv-arrow {
+ flex: 1;
+ min-width: 24px;
+ height: 1px;
+ background: var(--sm-edge);
+ position: relative;
+}
+.tv-arrow::after {
+ content: '';
+ position: absolute;
+ right: -1px;
+ top: -3px;
+ border: 3.5px solid transparent;
+ border-left: 6px solid var(--sm-edge);
+ border-right: 0;
+}
+.tv-insp {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ min-width: 0;
+ padding: 10px 12px;
+ border-radius: 12px;
+ background: var(--sm-panel);
+ box-shadow: var(--shadow-panel);
+}
+.tv-h {
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--sm-text);
+}
+.ev-at {
+ display: block;
+ font-family: var(--font-mono);
+ font-size: 12px;
+ color: var(--sm-text);
+ overflow-wrap: anywhere;
+}
+.tc-v pre {
+ font-size: 12.5px;
+ line-height: 20px;
+ color: var(--sm-text-muted);
+ white-space: pre;
+}
+.tv-note {
+ font-size: 12px;
+ color: var(--sm-text-muted);
+}
+.rc {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ padding: 10px 12px;
+ border-radius: 10px;
+ background: var(--sm-panel);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ font-size: 12px;
+ line-height: 19px;
+ color: var(--sm-text);
+}
+.rc .t-dim {
+ color: var(--sm-text-muted);
+}
+.rc b {
+ font-weight: 500;
+ color: var(--sm-success-accent);
+}
+.tv-same {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 12.5px;
+ color: var(--sm-success-accent);
+}
+.tc-v:has(.tv-url) {
+ align-items: flex-start;
+ gap: 16px;
+}
+.tv-url {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ max-width: 100%;
+ height: 36px;
+ padding: 0 14px;
+ border-radius: 9999px;
+ background: var(--sm-panel);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ font-size: 12.5px;
+ color: var(--sm-text-muted);
+ white-space: nowrap;
+ overflow: hidden;
+}
+.tv-url b {
+ font-weight: 400;
+ color: var(--sm-text);
+}
+.tv-fmts {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+.pill-f {
+ display: inline-flex;
+ align-items: center;
+ height: 26px;
+ padding: 0 10px;
+ border-radius: 9999px;
+ font-size: 12.5px;
+ color: var(--sm-text);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+}
+
+/* install */
+.inst {
+ padding-bottom: 160px;
+}
+.target {
+ position: relative;
+ max-width: 920px;
+ margin: 0 auto;
+ padding: 56px 72px 48px;
+ border-radius: 28px;
+ background: var(--sm-panel);
+ box-shadow:
+ inset 0 0 0 1px var(--sm-panel-border),
+ 0 40px 120px -40px rgb(0 0 0 / 0.35);
+ text-align: center;
+}
+.t-lock {
+ display: flex;
+ justify-content: center;
+ margin-bottom: 28px;
+}
+.target .t-lede {
+ max-width: 560px;
+ margin: 14px auto 0;
+}
+.ist {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ margin-top: 40px;
+ text-align: left;
+}
+.ist-row {
+ display: grid;
+ grid-template-columns: 36px minmax(0, 1fr);
+ gap: 16px;
+ align-items: start;
+}
+.ist-n {
+ display: grid;
+ place-items: center;
+ width: 28px;
+ height: 28px;
+ margin-top: 4px;
+ border-radius: 9999px;
+ box-shadow: inset 0 0 0 1.5px var(--sm-text-muted);
+ font-size: 13px;
+ color: var(--sm-text);
+}
+.ist-row h3 {
+ margin: 6px 0 12px;
+ font-size: 16px;
+ font-weight: 500;
+}
+.ist-row .cmd,
+.ist-alt .cmd {
+ width: 100%;
+}
+.ask {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 12px 10px 12px 20px;
+ border-radius: 14px;
+ background: var(--sm-stage);
+ box-shadow: inset 0 0 0 1px var(--sm-panel-border);
+ font-size: 16px;
+ line-height: 1.55;
+ color: var(--sm-text);
+}
+.ask > button {
+ margin-left: auto;
+}
+.ist-alt {
+ margin-top: 24px;
+ padding-top: 22px;
+ box-shadow: inset 0 1px 0 var(--sm-divider);
+ text-align: left;
+ font-size: 14px;
+ line-height: 1.6;
+ color: var(--sm-text-muted);
+}
+.ist-alt .cmd {
+ margin-top: 12px;
+}
+.ist-alt code {
+ color: var(--sm-text);
+}
+.ilinks {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 6px;
+ margin-top: 26px;
+}
+
+/* tablet */
+@media (max-width: 1023px) {
+ .hsteps {
+ grid-template-columns: minmax(0, 1fr);
+ row-gap: 0;
+ }
+ .hrail {
+ left: 4px;
+ right: auto;
+ top: 6px;
+ bottom: 24px;
+ width: 1px;
+ height: auto;
+ }
+ .hs button {
+ padding: 0 0 24px 30px;
+ }
+ .hs-dot {
+ top: 6px;
+ }
+ .hs-d {
+ max-width: 560px;
+ }
+ .hpanel {
+ grid-template-columns: minmax(0, 1fr);
+ height: auto;
+ }
+ .fp {
+ display: none;
+ }
+}
+
+/* phone */
+@media (max-width: 767px) {
+ .sec {
+ padding-top: 112px;
+ }
+ .hero {
+ padding-top: 124px;
+ }
+ .hero-bg {
+ height: 560px;
+ }
+ .hero-acts {
+ flex-direction: column;
+ align-items: stretch;
+ width: 100%;
+ margin-top: 28px;
+ }
+ .hero-acts .cmd {
+ width: 100%;
+ padding-left: 14px;
+ }
+ .hero-acts .cmd-t,
+ .hero-acts .cmd-p {
+ font-size: 14px;
+ }
+ .hero-acts .pill-l {
+ justify-content: center;
+ }
+ .demo {
+ margin-top: 48px;
+ }
+ .try {
+ align-items: stretch;
+ }
+ .try-g {
+ justify-content: flex-start;
+ }
+ .hs-d {
+ max-width: none;
+ }
+ .ses-b {
+ padding: 16px;
+ }
+ .t-grid {
+ grid-template-columns: minmax(0, 1fr);
+ }
+ .tc-v {
+ height: auto;
+ min-height: 188px;
+ }
+ .tv-row {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 8px;
+ }
+ .tc-card {
+ width: 100%;
+ }
+ .tv-arrow {
+ display: none;
+ }
+ .tv-url span {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ .cmd.big .cmd-t,
+ .cmd.big .cmd-p {
+ font-size: 13.5px;
+ }
+ .ist-row .cmd-t,
+ .ist-alt .cmd-t {
+ font-size: 13px;
+ }
+ .k-stage {
+ height: 340px;
+ }
+ .k-foot {
+ flex-direction: column;
+ gap: 10px;
+ }
+ .ex-band {
+ flex-direction: column;
+ align-items: flex-start;
+ padding: 22px;
+ }
+ .target {
+ padding: 40px 20px 32px;
+ border-radius: 24px;
+ }
+ .ask {
+ font-size: 15px;
+ padding-left: 16px;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .hs,
+ .tl,
+ .jl,
+ .k-layer,
+ .k-ind,
+ .fp-json,
+ .fp-map {
+ transition: none;
+ }
+ .caret {
+ animation: none;
+ }
+}
diff --git a/site/components/landing/mobile.css b/site/components/landing/mobile.css
deleted file mode 100644
index 1245af9..0000000
--- a/site/components/landing/mobile.css
+++ /dev/null
@@ -1,378 +0,0 @@
-/* Ported from the canvas board. Scoped to .lp-m; keyframes are prefixed so the two compositions never collide. */
-.lp-m {
- .mono {font-family:var(--font-mono)}
- .tnum {font-variant-numeric:tabular-nums}
- .ic {display:block;flex-shrink:0}
- .sr {position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
- .t-client {--f:var(--sm-client-fill);--b:var(--sm-client-border);--t:var(--sm-client-tile);--a:var(--sm-client-accent)}
- .t-service {--f:var(--sm-service-fill);--b:var(--sm-service-border);--t:var(--sm-service-tile);--a:var(--sm-service-accent)}
- .t-gateway {--f:var(--sm-gateway-fill);--b:var(--sm-gateway-border);--t:var(--sm-gateway-tile);--a:var(--sm-gateway-accent)}
- .t-database {--f:var(--sm-database-fill);--b:var(--sm-database-border);--t:var(--sm-database-tile);--a:var(--sm-database-accent)}
- .t-cache {--f:var(--sm-cache-fill);--b:var(--sm-cache-border);--t:var(--sm-cache-tile);--a:var(--sm-cache-accent)}
- .t-queue {--f:var(--sm-queue-fill);--b:var(--sm-queue-border);--t:var(--sm-queue-tile);--a:var(--sm-queue-accent)}
- .t-storage {--f:var(--sm-storage-fill);--b:var(--sm-storage-border);--t:var(--sm-storage-tile);--a:var(--sm-storage-accent)}
- .t-external {--f:var(--sm-external-fill);--b:var(--sm-external-border);--t:var(--sm-external-tile);--a:var(--sm-external-accent)}
- .t-security {--f:var(--sm-security-fill);--b:var(--sm-security-border);--t:var(--sm-security-tile);--a:var(--sm-security-accent)}
- .t-start {--f:var(--sm-start-fill);--b:var(--sm-start-border);--t:var(--sm-start-tile);--a:var(--sm-start-accent)}
- .t-active {--f:var(--sm-active-fill);--b:var(--sm-active-border);--t:var(--sm-active-tile);--a:var(--sm-active-accent)}
- .t-waiting {--f:var(--sm-waiting-fill);--b:var(--sm-waiting-border);--t:var(--sm-waiting-tile);--a:var(--sm-waiting-accent)}
- .t-decision {--f:var(--sm-decision-fill);--b:var(--sm-decision-border);--t:var(--sm-decision-tile);--a:var(--sm-decision-accent)}
- .t-success {--f:var(--sm-success-fill);--b:var(--sm-success-border);--t:var(--sm-success-tile);--a:var(--sm-success-accent)}
- .t-failure {--f:var(--sm-failure-fill);--b:var(--sm-failure-border);--t:var(--sm-failure-tile);--a:var(--sm-failure-accent)}
- .t-neutral {--f:var(--sm-neutral-fill);--b:var(--sm-neutral-border);--t:var(--sm-neutral-tile);--a:var(--sm-neutral-accent)}
- .ed[data-tint="client"] {--ec:var(--sm-client-accent);--ew:1.75px}
- .ed[data-tint="service"] {--ec:var(--sm-service-accent);--ew:1.75px}
- .ed[data-tint="gateway"] {--ec:var(--sm-gateway-accent);--ew:1.75px}
- .ed[data-tint="database"] {--ec:var(--sm-database-accent);--ew:1.75px}
- .ed[data-tint="cache"] {--ec:var(--sm-cache-accent);--ew:1.75px}
- .ed[data-tint="queue"] {--ec:var(--sm-queue-accent);--ew:1.75px}
- .ed[data-tint="storage"] {--ec:var(--sm-storage-accent);--ew:1.75px}
- .ed[data-tint="external"] {--ec:var(--sm-external-accent);--ew:1.75px}
- .ed[data-tint="security"] {--ec:var(--sm-security-accent);--ew:1.75px}
- .ed[data-tint="start"] {--ec:var(--sm-start-accent);--ew:1.75px}
- .ed[data-tint="active"] {--ec:var(--sm-active-accent);--ew:1.75px}
- .ed[data-tint="waiting"] {--ec:var(--sm-waiting-accent);--ew:1.75px}
- .ed[data-tint="decision"] {--ec:var(--sm-decision-accent);--ew:1.75px}
- .ed[data-tint="success"] {--ec:var(--sm-success-accent);--ew:1.75px}
- .ed[data-tint="failure"] {--ec:var(--sm-failure-accent);--ew:1.75px}
- .ed[data-tint="neutral"] {--ec:var(--sm-neutral-accent);--ew:1.75px}
- .dg {position:relative}
- .cw {position:absolute;display:block;border:0;padding:0;margin:0;background:transparent;text-align:left;font:inherit;color:var(--sm-text);border-radius:14px;outline:none;transition:opacity 150ms ease}
- .cw.cpt {border-radius:12px}
- button.cw {cursor:pointer}
- .nc, .scd {position:relative;display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden;background:var(--f);box-shadow:inset 0 0 0 1px var(--b)}
- .nc {border-radius:14px}
- .scd {border-radius:12px}
- .nc-h {display:flex;align-items:center;gap:12px;height:64px;padding:0 16px;flex-shrink:0}
- .nc .tile {width:36px;height:36px;flex-shrink:0;border-radius:10px;display:grid;place-items:center;background:var(--t);color:var(--a)}
- .nc-tx {display:flex;flex-direction:column;min-width:0}
- .nc .ct {font-size:13.5px;line-height:20px;font-weight:500;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc .cs {font-size:12px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc-rows {display:block;padding:8px 0;flex-shrink:0}
- .nc-row {display:flex;align-items:center;justify-content:space-between;gap:12px;height:28px;padding:0 16px;font-size:12px}
- .nc-k {color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .nc-v {max-width:55%;flex-shrink:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--sm-text)}
- .nc-stats {display:block;padding:0 12px;margin-bottom:12px;flex-shrink:0}
- .st-box {display:flex;flex-direction:column;overflow:hidden;border-radius:10px;background:var(--t);box-shadow:inset 0 0 0 1px var(--b)}
- .st-grid {display:grid;gap:6px;padding:6px;height:60px}
- .st {display:flex;flex-direction:column;justify-content:center;min-width:0;border-radius:8px;background:var(--sm-stage);padding:0 10px}
- .st-v {font-size:15px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .st-l {font-size:11px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .st-note {display:flex;align-items:center;gap:6px;height:30px;padding:0 12px;font-size:11.5px;color:var(--sm-text-muted)}
- .nc-foot {display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));align-items:center;gap:12px;height:40px;padding:0 16px;font-size:12px;color:var(--sm-text-muted);box-shadow:inset 0 1px 0 var(--b);flex-shrink:0}
- .nf-i {display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden}
- .nf-i.r {justify-content:flex-end}
- .nc-cta {display:block;height:48px;padding:0 12px;flex-shrink:0}
- .cta-in {display:flex;height:36px;align-items:center;justify-content:space-between;border-radius:8px;padding:0 12px;font-size:13px;font-weight:500;background:var(--t)}
- .cta-in .ic {color:var(--a)}
- .sc-h {display:flex;align-items:center;gap:10px;height:60px;padding:0 12px;flex-shrink:0}
- .scd .tile {width:28px;height:28px;flex-shrink:0;border-radius:8px;display:grid;place-items:center;background:var(--t);color:var(--a)}
- .scd .ct {font-size:13px;line-height:18px;font-weight:500;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .scd .cs {font-size:11.5px;line-height:16px;color:var(--sm-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .sc-tag {display:flex;align-items:flex-start;height:24px;padding:0 12px 0 50px;flex-shrink:0}
- .pill {display:inline-flex;align-items:center;height:18px;max-width:100%;padding:0 8px;border-radius:9999px;font-size:11px;font-weight:500;background:var(--t);color:var(--sm-text);white-space:nowrap;overflow:hidden}
- .scd.final {box-shadow:inset 0 0 0 1.5px var(--a),inset 0 0 0 3.5px var(--f),inset 0 0 0 4.5px var(--a)}
- [data-em="focus"] {outline:2px solid var(--a);outline-offset:3px}
- [data-em="dim"], [data-dim="true"], [data-dim="dim"] {opacity:.22}
- .cw:focus-visible {outline:2px solid var(--sm-text);outline-offset:3px}
- .hd {position:absolute;width:7px;height:7px;border-radius:9999px;background:var(--sm-stage);border:1.5px solid var(--a);pointer-events:none}
- .hin-v {left:50%;top:0;transform:translate(-50%, -50%)}
- .hout-v {left:50%;bottom:0;transform:translate(-50%, 50%)}
- .hin-h {top:50%;left:0;transform:translate(-50%, -50%)}
- .hout-h {top:50%;right:0;transform:translate(50%, -50%)}
- .hd.rh {transform:translate(-50%, -50%);transition:opacity 150ms ease}
- .eg, .pg {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .ed {--ec:var(--sm-edge);--ew:1.25px;transition:opacity 150ms ease}
- .ed .ln {fill:none;stroke:var(--ec);stroke-width:var(--ew);transition:stroke 150ms ease, stroke-width 150ms ease}
- .ed .ah {fill:var(--ec);stroke:none;transition:fill 150ms ease}
- .ed .ah.open {fill:none;stroke:var(--ec);stroke-width:1.25px;stroke-linejoin:round}
- .ed.k-async .ln {stroke-dasharray:5 4}
- .ed.k-return .ln {stroke-dasharray:1 4;stroke-linecap:round}
- .ed.tone-main {--ec:var(--sm-text);--ew:1.75px}
- .ed.tone-security {--ec:var(--sm-security-accent);--ew:1.5px}
- .ed.tone-error {--ec:var(--sm-failure-accent);--ew:1.5px}
- .lifeline {stroke:var(--sm-group-border);stroke-width:1;stroke-dasharray:4 4;transition:opacity 150ms ease}
- .act {fill:var(--a);fill-opacity:.16;stroke:var(--a);stroke-width:1;transition:opacity 150ms ease}
- .startmark line {stroke:var(--sm-start-accent);stroke-width:1.5}
- .startmark path, .startmark circle {fill:var(--sm-start-accent)}
- .elb {position:absolute;transform:translate(-50%, -50%);white-space:nowrap;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);padding:2px 8px;font-size:11px;line-height:1.5;color:var(--sm-text-muted);pointer-events:none;transition:opacity 150ms ease}
- .elt {position:absolute;transform:translate(-50%, -50%);white-space:nowrap;border-radius:4px;background:var(--sm-stage);padding:0 6px;font-size:11.5px;line-height:16px;color:var(--sm-text);pointer-events:none;transition:opacity 150ms ease}
- .fr {position:absolute;border:1px dashed var(--sm-group-border);border-radius:18px;background:var(--sm-group-fill)}
- .fr.cpt {border-radius:14px}
- .fr.onlane {background:transparent}
- .fr.sec {border-color:var(--sm-security-accent)}
- .fr.sec .ic {color:var(--sm-security-accent)}
- .fr-l {display:flex;align-items:center;gap:6px;padding:0 20px;font-size:12.5px;font-weight:500;color:var(--sm-text-muted)}
- .fr.cpt .fr-l {padding:0 12px;font-size:12px}
- .lane {position:absolute;border-radius:16px;background:var(--sm-group-fill);box-shadow:inset 0 0 0 1px var(--sm-panel-border)}
- .lane.exc {box-shadow:none;border:1px dashed var(--sm-group-border)}
- .lane-l {display:flex;align-items:flex-start;gap:6px;width:128px;padding:16px 16px 0;font-size:12.5px;line-height:18px;font-weight:500;color:var(--sm-text-muted);overflow-wrap:anywhere}
- .lane-l .ic {margin-top:2.5px}
- .ph-head {position:absolute;display:flex;align-items:flex-start;justify-content:center}
- .ph-head span {margin-top:6px;font-size:13px;font-weight:500;color:var(--sm-text)}
- .ph-head i {position:absolute;left:0;right:0;bottom:8px;height:1px;background:var(--sm-group-border)}
- .ph-band {position:absolute;border:1px dashed var(--sm-group-border);border-radius:18px;background:var(--sm-group-fill)}
- .ph-band span {display:flex;align-items:center;height:44px;padding:0 20px;font-size:12.5px;font-weight:500;color:var(--sm-text-muted)}
- .ph-band.c span {justify-content:center}
- .ph-time {position:absolute;border:1px dashed var(--sm-group-border);border-radius:14px;background:var(--sm-group-fill)}
- .ph-time span {display:flex;align-items:center;height:28px;padding:0 16px;font-size:12px;font-weight:500;color:var(--sm-text-muted)}
- .pnl {background:var(--sm-panel);box-shadow:var(--shadow-panel);border-radius:16px}
- .ib {width:36px;height:36px;border:0;border-radius:12px;background:transparent;color:var(--sm-text-muted);display:grid;place-items:center;cursor:pointer;transition:background-color 150ms ease, color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .ib:hover, .ib[aria-pressed="true"] {background:var(--sm-page);color:var(--sm-text)}
- .ib:active {transform:scale(0.96)}
- .ib:focus-visible, .pbtn:focus-visible, .lnk:focus-visible, .chip-b:focus-visible, .tab:focus-visible {outline:2px solid var(--sm-text);outline-offset:2px}
- .pbtn {display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px;padding:0 18px;border:0;border-radius:9999px;background:var(--sm-primary);color:var(--sm-primary-text);font-size:14px;font-weight:500;text-decoration:none;cursor:pointer;white-space:nowrap;transition:transform 120ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms ease}
- .pbtn:active {transform:scale(0.96)}
- .lnk {display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;border-radius:12px;color:var(--sm-text-muted);text-decoration:none;font-size:14px;transition:background-color 150ms ease, color 150ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1)}
- .lnk:active {transform:scale(0.97)}
- .lnk:hover {background:var(--sm-page);color:var(--sm-text)}
- .kbd {display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 6px;border-radius:6px;box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);font-size:12px;color:var(--sm-text-muted);background:var(--sm-panel)}
- .badge {display:inline-flex;align-items:center;height:24px;padding:0 10px;border-radius:9999px;box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-size:13px;color:var(--sm-text)}
- .grid-bg {background-image:radial-gradient(circle, var(--sm-grid) 1.5px, transparent 1.75px);background-size:24px 24px}
- .scn {position:relative;background:var(--sm-page)}
- .stage {position:relative;height:100%;overflow:clip}
- .frame {position:absolute;left:50%;top:0;transform:translateX(-50%);transform-origin:50% 50%}
- &.live [data-rv] {transition:opacity 700ms cubic-bezier(0.23, 1, 0.32, 1), translate 700ms cubic-bezier(0.23, 1, 0.32, 1)}
- &.live [data-rv]:not(.in) {opacity:0;translate:0 28px}
- &.live [data-rv="lines"] {opacity:1 !important;translate:none !important;transition:none}
- &.live [data-rv="lines"] .ml>span {display:inline-block;transition:translate 800ms cubic-bezier(0.23, 1, 0.32, 1)}
- &.live [data-rv="lines"]:not(.in) .ml>span {translate:0 108%}
- .ml {display:block;overflow:hidden;padding:0.06em 0.04em 0.14em;margin:-0.06em -0.04em -0.14em}
- &.live [data-route] {stroke-dasharray:1 1;stroke-dashoffset:1}
- .rhead {opacity:0;transition:opacity 200ms ease;pointer-events:none}
- .rh-halo {fill:var(--sm-text);fill-opacity:.14}
- .rh-core {fill:var(--sm-text)}
- .cmd {display:inline-flex;align-items:center;gap:12px;height:52px;padding:0 8px 0 18px;border-radius:14px}
- .cmd.big {height:60px;padding:0 10px 0 22px}
- .cmd-p {font-size:15px;color:var(--sm-text-muted)}
- .cmd-t {flex:1 1 auto;min-width:0;font-size:15px;color:var(--sm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
- .cmd.big .cmd-t, .cmd.big .cmd-p {font-size:16px}
- .cp [data-i="check"] {display:none}
- .cp.done [data-i="copy"] {display:none}
- .cp.done [data-i="check"] {display:block;color:var(--sm-text)}
- .t-mega {font-size:200px;line-height:0.92;font-weight:600;letter-spacing:-0.05em}
- .t-hero {font-size:112px;line-height:0.94;font-weight:600;letter-spacing:-0.045em}
- .t-title {font-size:96px;line-height:1;font-weight:600;letter-spacing:-0.045em}
- .t-section {font-size:72px;line-height:1.02;font-weight:600;letter-spacing:-0.04em}
- .t-display {font-size:60px;line-height:70px;font-weight:600;letter-spacing:-0.03em}
- .t-lede {font-size:22px;line-height:1.4;font-weight:400;color:var(--sm-text-muted)}
- .acc {color:var(--site-accent)}
- .muted {color:var(--sm-text-muted)}
- h1, h2, h3, h4, p {margin:0}
- .hero-grid {position:absolute;inset:0;-webkit-mask-image:radial-gradient(closest-side, #000 50%, transparent 100%);mask-image:radial-gradient(closest-side, #000 50%, transparent 100%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:50% 38%;mask-position:50% 38%;-webkit-mask-size:760px 900px;mask-size:760px 900px;animation:gridgrow 1400ms cubic-bezier(0.23, 1, 0.32, 1) 850ms backwards}
- .par {position:absolute;inset:0}
- .chip {position:absolute;white-space:nowrap;padding:5px 9px;border-radius:8px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);font-size:12.5px;line-height:1.5;color:var(--sm-text-muted);animation-duration:11s, 900ms;animation-timing-function:ease-in-out, cubic-bezier(0.23, 1, 0.32, 1);animation-iteration-count:infinite, 1;animation-direction:alternate, normal;animation-fill-mode:none, backwards}
- .chip.dp0 {filter:blur(2.4px);opacity:.3}
- .chip.dp1 {filter:blur(1.2px);opacity:.55}
- .chip.dp2 {opacity:.85;color:var(--sm-text)}
- .chip.dr-a {animation-name:driftA, chipin}
- .chip.dr-b {animation-name:driftB, chipin}
- .chip.dr-c {animation-name:driftC, chipin}
- .h-content {position:absolute;inset:0}
- .hero-h {position:absolute;left:24px;top:158px;margin:0;font-size:52px;line-height:0.96;font-weight:600;letter-spacing:-0.045em;color:var(--sm-text);perspective:900px}
- .hl {display:block;white-space:nowrap}
- .hl3 {padding-left:16px}
- .hw {display:inline-block;animation:hdrop 1000ms linear backwards}
- .hacc {position:relative;display:inline-block;color:var(--site-accent);animation:acc 320ms cubic-bezier(0.23, 1, 0.32, 1) 2180ms backwards}
- .hacc .hw {color:inherit}
- .hglow {position:absolute;left:-12px;right:-12px;top:8px;bottom:2px;border-radius:20px;background:var(--site-accent);filter:blur(14px);opacity:0;pointer-events:none;z-index:-1;animation:hglow 900ms cubic-bezier(0.23, 1, 0.32, 1) 2180ms backwards}
- .h-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .h-route .rt {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .h-route .rt-in {stroke:url(#hr-fade-m);stroke-dasharray:1 1;animation:rdraw 650ms cubic-bezier(0.33, 1, 0.68, 1) 1480ms backwards}
- .h-route .ah {fill:var(--sm-text);animation:fadein 140ms linear 2100ms backwards}
- .h-route .hd2 {fill:var(--sm-stage);stroke:var(--sm-text);stroke-width:1.5;animation:fadein 200ms linear 2240ms backwards}
- .comet {position:absolute;left:0;top:0;width:6px;height:6px;border-radius:9999px;background:var(--sm-text);box-shadow:0 0 0 4px rgb(237 237 236 / 0.18), 0 0 14px 3px rgb(237 237 236 / 0.22);offset-path:path("M 10 0 V 275 Q 10 287 22 287 H 27");offset-rotate:0deg;offset-distance:100%;opacity:0;animation:comet 720ms cubic-bezier(0.5, 1, 0.89, 1) 1480ms backwards}
- .h-lede {position:absolute;left:24px;top:346px;width:340px;font-size:17px;line-height:1.45;color:var(--sm-text-muted);animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1250ms backwards}
- .h-cta {position:absolute;left:24px;top:444px;width:342px;display:flex;flex-direction:column;gap:10px;animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1380ms backwards}
- .h-cta .cmd {width:100%;height:50px;padding:0 6px 0 14px;gap:10px}
- .h-cta .cmd-t {font-size:13.5px}
- .h-links {display:flex;gap:4px;margin-left:-14px}
- .h-works {position:absolute;left:24px;top:578px;width:300px;font-size:13px;line-height:1.5;color:var(--sm-text-muted);animation:rise 900ms cubic-bezier(0.23, 1, 0.32, 1) 1520ms backwards}
- .h-bridge {display:none}
- &.live .h-bridge {display:inline;stroke-dasharray:1 1}
- .hero-chips {position:absolute;inset:0;transform-origin:195px 400px}
- .m-route {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .m-route path {fill:none;stroke:var(--sm-text);stroke-width:1.5}
- .vx {position:absolute;left:195px;top:420px;width:0;height:0}
- .vring {position:absolute;left:0;top:0}
- .vchip {position:absolute;left:0;top:0;white-space:nowrap;padding:6px 10px;border-radius:8px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-family:var(--font-mono);line-height:1.5;color:var(--sm-text)}
- /* Decorative texture: the names are drawn, not text, so they carry no contrast duty. */
- .vchip[data-label]::before {content:attr(data-label)}
- .kline-wrap {position:absolute;inset:0;transform-origin:195px 420px}
- .kl {position:absolute;left:24px;margin:0;font-size:44px;line-height:1;font-weight:600;letter-spacing:-0.045em;color:var(--sm-text)}
- .kl-l {display:block;white-space:nowrap}
- .kw {display:inline-block}
- .kw>span {display:inline-block}
- .cdot {position:absolute;left:189px;top:414px;width:12px;height:12px;border-radius:9999px;background:var(--sm-edge);opacity:0}
- .shock {position:absolute;left:-155px;top:70px;width:700px;height:700px;border-radius:9999px;box-shadow:inset 0 0 0 1.5px var(--sm-text);opacity:0}
- .s2-grid {position:absolute;inset:0;opacity:0;-webkit-mask-image:radial-gradient(closest-side, #000 60%, transparent 100%);mask-image:radial-gradient(closest-side, #000 60%, transparent 100%);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:1100px 1100px;mask-size:1100px 1100px}
- .mk {position:absolute;left:95px;top:250px;overflow:visible;opacity:0}
- .mk .bx {transform-box:fill-box;transform-origin:center}
- .mk-route {stroke-dasharray:100;stroke-dashoffset:0}
- &.live .mk-route {stroke-dashoffset:100;opacity:0;transition:stroke-dashoffset 640ms cubic-bezier(0.77, 0, 0.175, 1), opacity 1ms linear}
- &.live .mk-route.drawn {stroke-dashoffset:0;opacity:1}
- .mcard {opacity:0}
- .mcard .nc {border-radius:inherit}
- .mc-in {position:absolute;inset:0;display:flex;flex-direction:column}
- .mc-ov {position:absolute;inset:0;border-radius:inherit}
- .s2-edge {position:absolute;left:0;top:0;overflow:visible;pointer-events:none}
- .s2-edge .ln {fill:none;stroke:var(--sm-edge);stroke-width:1.25}
- .s2-edge .ah {fill:var(--sm-edge)}
- .s2-edge .lead {fill:none;stroke:var(--sm-database-accent);stroke-width:1.75}
- .s2-edge g {opacity:0}
- .selring {position:absolute;left:50px;top:415px;width:290px;height:74px;border-radius:17px;box-shadow:0 0 0 2px var(--sm-database-accent);opacity:0;pointer-events:none}
- .s2ev {position:absolute;left:55px;top:536px;display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:10px;opacity:0}
- .s2ev code {font-size:13px;color:var(--sm-text)}
- .s2ev .ic {color:var(--sm-database-accent)}
- .s2cap {position:absolute;left:24px;right:24px;font-size:17px;line-height:1.45;color:var(--sm-text-muted);opacity:0}
- .bigp {position:absolute;left:44px;top:150px;font-family:var(--font-mono);font-size:26px;line-height:1.35;color:var(--sm-text);transform-origin:0 0;opacity:0}
- .bigp-c {position:absolute;left:-22px;top:0;color:var(--sm-text-muted)}
- .ty {display:block;box-sizing:content-box;overflow:hidden;white-space:nowrap;border-right:0.08em solid transparent}
- .term {position:absolute;left:20px;top:84px;width:350px;height:392px;border-radius:16px;overflow:hidden}
- .term-h {display:flex;align-items:center;height:40px;padding:0 16px;font-size:12px;color:var(--sm-text-muted);box-shadow:inset 0 -1px 0 var(--sm-panel-border)}
- .term-b {display:flex;flex-direction:column;padding:14px 16px;font-size:12px;line-height:21px;color:var(--sm-text-muted);white-space:pre}
- .term-b b {font-weight:600;color:var(--sm-text)}
- .tl-row {display:block;margin:0 -8px;padding:0 8px;border-radius:5px}
- .row-err {background:rgb(240 128 110 / 0.13)}
- .row-ok {background:rgb(166 217 122 / 0.12)}
- .row-del {background:rgb(143 166 242 / 0.12)}
- .t-ink {color:var(--sm-text)}
- .t-err {color:var(--sm-cache-accent)}
- .t-ok {color:var(--sm-service-accent)}
- .tp {display:block;color:var(--sm-text);white-space:pre-wrap;margin-bottom:10px}
- .tp .c {color:var(--sm-text-muted)}
- .steps {position:absolute;left:20px;top:508px;width:350px;display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:22px 18px;margin:0;padding:0;list-style:none}
- .step {position:relative}
- .s-n {display:block;font-size:12px;color:var(--sm-text-muted);margin-bottom:6px}
- .step h3 {font-size:17px;line-height:1.25;font-weight:600;letter-spacing:-0.015em;color:var(--sm-text)}
- .step p {margin-top:6px;font-size:13px;line-height:1.5;color:var(--sm-text-muted)}
- .s3-base {stroke:var(--sm-panel-border) !important}
- .lights {position:absolute;left:-1000px;right:-1000px;top:-1000px;bottom:-1000px;background:var(--sm-page);color:var(--sm-text);transition:background-color 200ms ease}
- .lights-in {position:absolute;left:1000px;top:1000px;width:390px;height:844px}
- .vw {position:absolute;left:20px;top:76px;width:350px}
- .crumb {font-size:13px;line-height:20px;color:var(--sm-text-muted)}
- .vt {display:flex;align-items:center;gap:10px;margin-top:2px}
- .vt h2 {font-size:22px;line-height:30px;font-weight:600;letter-spacing:-0.025em}
- .vt .cnt {font-size:12.5px;color:var(--sm-text-muted)}
- .tabs {position:absolute;left:0;top:58px;display:flex;gap:20px;height:34px}
- .tab {height:34px;padding:0;border:0;background:none;font-size:14px;color:var(--sm-text-muted);cursor:pointer}
- .tab:hover, .tab[aria-selected="true"] {color:var(--sm-text)}
- .tab-ind {position:absolute;left:0;top:90px;height:2px;border-radius:2px;background:var(--sm-text);transition:translate 180ms cubic-bezier(0.77, 0, 0.175, 1), width 180ms cubic-bezier(0.77, 0, 0.175, 1)}
- .vw-rule {position:absolute;left:0;right:0;top:92px;height:1px;background:var(--sm-divider)}
- .vstage {position:absolute;left:20px;top:176px;width:350px;height:470px;border-radius:18px;background-color:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border)}
- .vstage>.grid-bg {position:absolute;inset:0;border-radius:18px}
- .vclip {position:absolute;left:20px;top:176px;width:350px;height:470px;clip-path:inset(0px round 18px);touch-action:none}
- .vcam {position:absolute;left:0;top:0;width:350px;height:470px;transform-origin:175px 235px}
- .plane-wrap {position:absolute;left:-4px;top:52px;width:359px;height:321px;perspective:1400px;perspective-origin:50% 20%}
- .plane {position:absolute;left:0;top:0;width:100%;height:100%;transform-style:preserve-3d;transform-origin:50% 45%}
- .plane-grid {position:absolute;left:-400px;right:-400px;top:-300px;bottom:-300px;opacity:0}
- .plane .dg {transform:scale(0.356);transform-origin:0 0;transform-style:preserve-3d}
- .plane .cw {transform-style:preserve-3d}
- .vchrome .pnl {position:absolute}
- .v-id {left:30px;top:186px;height:44px;display:flex;align-items:center;gap:10px;padding:0 12px 0 6px;border-radius:14px}
- .v-id .tile {width:32px;height:32px;border-radius:10px;display:grid;place-items:center;background:var(--sm-page);color:var(--sm-text)}
- .v-id b {font-size:13px;font-weight:500}
- .v-tools {left:232px;top:186px;height:44px;display:flex;align-items:center;gap:2px;padding:0 4px;border-radius:14px}
- .v-tools .ib {width:36px;height:36px}
- .v-zoom {left:30px;top:596px;height:40px;display:flex;align-items:center;gap:2px;padding:0 4px;border-radius:9999px}
- .v-zoom .ib {width:32px;height:32px;border-radius:9999px}
- .v-zoom .pct {min-width:44px;text-align:center;font-size:12.5px;font-variant-numeric:tabular-nums}
- .sheet {position:absolute;left:20px;top:658px;width:350px;height:166px;padding:14px 16px;border-radius:18px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);overflow:hidden}
- .sheet .cap {display:flex;align-items:center;gap:8px;font-size:12px;font-weight:500;color:var(--sm-text-muted)}
- .sheet h3 {margin-top:2px;font-size:16px;line-height:1.4;font-weight:600;letter-spacing:-0.02em}
- .sheet .sub {font-size:12.5px;line-height:1.5;color:var(--sm-text-muted)}
- .sheet .ev {display:block;margin-top:8px;font-family:var(--font-mono);font-size:11.5px;color:var(--sm-text)}
- .sheet .i-row {display:flex;justify-content:space-between;align-items:center}
- .sheet .ib {width:32px;height:32px}
- .dot {display:inline-block;width:8px;height:8px;border-radius:9999px;flex-shrink:0}
- .drop-title {position:absolute;left:24px;right:24px;top:96px;font-size:34px;line-height:1.05;font-weight:600;letter-spacing:-0.04em;opacity:0;pointer-events:none}
- .dt-dark {display:none}
- &.live .dt-dark {display:block;opacity:1}
- .feat-sec {position:relative;height:1040px;overflow:hidden;background:var(--sm-page);color:var(--sm-text)}
- .rline {position:absolute;top:0;bottom:0;left:calc(50% + var(--gl-off, -185px) - 0.75px);width:1.5px;background:var(--sm-text)}
- .feat-in {position:relative;padding:88px 24px 0}
- .feat-h {font-size:56px;line-height:0.98;font-weight:600;letter-spacing:-0.05em}
- .feat-lede {margin-top:20px;font-size:17px;line-height:1.45;color:var(--sm-text-muted)}
- .feat-g {display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));margin-top:40px;box-shadow:inset 0 1px 0 var(--sm-divider)}
- .feat {padding:20px 12px 22px 0;box-shadow:inset 0 -1px 0 var(--sm-divider)}
- .feat:nth-child(2n) {padding-left:16px;box-shadow:inset 0 -1px 0 var(--sm-divider), inset 1px 0 0 var(--sm-divider)}
- .feat-t {display:flex;align-items:center;gap:8px;font-size:16px;font-weight:600;letter-spacing:-0.015em}
- .feat-t .ic {color:var(--sm-text-muted)}
- .feat p {margin-top:8px;font-size:13.5px;line-height:1.5;color:var(--sm-text-muted)}
- &.live .a-kd0 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd1 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd2 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd3 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- &.live .a-kd4 .ed.k-async .ln {stroke-dasharray:5 4;animation:none}
- .kinds-h {position:absolute;left:24px;top:78px;height:78px;overflow:hidden}
- .kn-col {display:flex;flex-direction:column;transform:translateY(-156px)}
- &.live .kn-col {transform:none}
- .kn {display:block;height:78px;font-size:60px;line-height:78px;font-weight:600;letter-spacing:-0.05em;white-space:nowrap}
- .kdefs {position:absolute;left:24px;top:164px;height:24px}
- .kdef {position:absolute;left:0;top:0;white-space:nowrap;font-size:17px;line-height:1.4;color:var(--sm-text-muted);opacity:0}
- .kdef.on {opacity:1}
- .kcount {position:absolute;left:24px;top:204px;font-size:12.5px;color:var(--sm-text-muted)}
- .klayer {position:absolute;transform-origin:0 0;opacity:0}
- .klayer.on {opacity:1}
- .kmore {position:absolute;left:12px;top:782px;font-size:14px}
- .mm-e {fill:none;stroke:var(--sm-edge);stroke-width:1}
- .mm-c {fill-opacity:.55}
- .mm-lane {fill:var(--sm-group-fill);stroke:var(--sm-panel-border);stroke-width:1}
- .mm-fr {fill:none;stroke:var(--sm-group-border);stroke-width:1;stroke-dasharray:3 3}
- .file {position:absolute;left:58px;top:92px;width:274px;height:372px;perspective:1100px}
- .file-in {position:absolute;inset:0;transform-style:preserve-3d;transform:rotateY(180deg)}
- .face {position:absolute;inset:0;display:flex;flex-direction:column;gap:10px;padding:18px;border-radius:18px;background:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);-webkit-backface-visibility:hidden;backface-visibility:hidden}
- .face.back {transform:rotateY(180deg);background:var(--sm-panel)}
- .ff-t {font-size:17px;font-weight:600;letter-spacing:-0.02em}
- .ff-map {display:grid;place-items:center;flex:1}
- .fb-shot {height:214px;border-radius:12px;background-color:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);display:grid;place-items:center;overflow:hidden}
- .fb-n {margin-top:4px;font-size:17px}
- .fb-s {font-size:13.5px;line-height:1.45;color:var(--sm-text-muted)}
- .fl-lights {position:absolute;left:-1000px;right:-1000px;top:-1000px;bottom:-1000px;display:none;background:var(--sm-page);color:var(--sm-text);pointer-events:none}
- &.live .fl-lights {display:block}
- .fl-in {position:absolute;left:1000px;top:1000px;width:390px;height:844px}
- .of-h {position:absolute;left:24px;top:496px;font-size:48px;line-height:1;font-weight:600;letter-spacing:-0.05em}
- .of-list {position:absolute;left:24px;top:606px;right:20px;display:flex;flex-direction:column;gap:9px;margin:0;padding:0;list-style:none}
- .of-list li {display:flex;gap:10px;font-size:14px;line-height:1.45;color:var(--sm-text-muted)}
- .of-list .ic {margin-top:2px;color:var(--sm-text)}
- .of-more {position:absolute;left:24px;top:770px}
- .pill-l {display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 16px 0 18px;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);color:var(--sm-text);font-size:14px;font-weight:500;text-decoration:none}
- .inst {position:relative;height:1000px;overflow:hidden;background:var(--sm-page);color:var(--sm-text)}
- .inst-in {position:relative;padding:112px 20px 0}
- .ir-a {position:absolute;top:0;left:calc(50% + var(--gl-off, -185px) - 0.75px);width:calc(-1 * var(--gl-off, -185px) - 11.25px);height:40.75px;border-left:1.5px solid var(--sm-text);border-bottom:1.5px solid var(--sm-text);border-bottom-left-radius:12px}
- .ir-b {position:absolute;top:39.25px;left:calc(50% - 12px);width:12.75px;height:73.5px;border-top:1.5px solid var(--sm-text);border-right:1.5px solid var(--sm-text);border-top-right-radius:12px}
- .ir-d {position:absolute;top:108.5px;left:calc(50% - 4.5px);width:9px;height:9px;border-radius:9999px;background:var(--sm-panel);box-shadow:inset 0 0 0 1.5px var(--sm-text);z-index:2}
- .target {position:relative;padding:40px 22px 32px;border-radius:24px;background:var(--sm-panel);box-shadow:inset 0 0 0 1px var(--sm-panel-border);text-align:center}
- .target img {display:block;margin:0 auto}
- .target h2 {margin-top:24px;font-size:36px;line-height:1.08;font-weight:600;letter-spacing:-0.035em}
- .target .lede {margin-top:12px;font-size:16px;line-height:1.45;color:var(--sm-text-muted)}
- .ist {display:flex;flex-direction:column;gap:18px;margin-top:28px;text-align:left}
- .ist h3 {display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;margin-bottom:8px}
- .ist-n {display:grid;place-items:center;width:22px;height:22px;border-radius:9999px;box-shadow:inset 0 0 0 1.5px var(--sm-text-muted);font-size:11.5px}
- .ist .cmd, .ist-alt .cmd {display:flex;width:100%;height:48px;padding:0 4px 0 12px;gap:6px}
- .ist .cmd .ib, .ist-alt .cmd .ib {width:32px;height:32px;flex-shrink:0}
- .ist .cmd-t, .ist-alt .cmd-t {font-size:12.5px}
- .ist .cmd-p, .ist-alt .cmd-p {font-size:12.5px}
- .ask {padding:12px 14px;border-radius:12px;background:var(--sm-stage);box-shadow:inset 0 0 0 1px var(--sm-panel-border);font-size:14.5px;line-height:1.5}
- .ist-alt {margin-top:20px;padding-top:18px;box-shadow:inset 0 1px 0 var(--sm-divider);text-align:left;font-size:13px;line-height:1.5;color:var(--sm-text-muted)}
- .ist-alt .cmd {margin-top:10px;height:auto;min-height:48px;padding-top:8px;padding-bottom:8px}
- .ist-alt .cmd-t {white-space:normal;line-height:1.5}
- .ilinks {display:flex;flex-wrap:wrap;justify-content:center;gap:2px;margin-top:18px}
- @media (prefers-reduced-motion: reduce) {
- *, *::before, *::after {animation:none !important;transition:none !important}
- }
-}
-
-@keyframes gridgrow{0%{-webkit-mask-size:0px 0px;mask-size:0px 0px}100%{-webkit-mask-size:760px 900px;mask-size:760px 900px}}
-@keyframes driftA{0%{translate:0 0}100%{translate:14px -8px}}
-@keyframes driftB{0%{translate:0 0}100%{translate:-12px 9px}}
-@keyframes driftC{0%{translate:0 0}100%{translate:8px 12px}}
-@keyframes chipin{0%{opacity:0}}
-@keyframes hdrop{0%{opacity:0;transform:translate3d(var(--x), var(--y), var(--z));filter:blur(var(--bl));animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}22%{opacity:0.5;transform:translate3d(calc(var(--x) * 0.82), calc(var(--y) * 0.82), var(--z));filter:blur(var(--bl));animation-timing-function:cubic-bezier(0.55, 0, 1, 0.45)}70%{opacity:1;transform:translate3d(0px, 0px, 0px);filter:blur(0px);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}84%{transform:translate3d(0px, 0px, 12px);animation-timing-function:cubic-bezier(0.55, 0, 1, 0.45)}100%{opacity:1;transform:translate3d(0px, 0px, 0px);filter:blur(0px)}}
-@keyframes acc{0%{color:var(--sm-text)}100%{color:var(--brand-accent)}}
-@keyframes hglow{0%{opacity:0.42;transform:scale(0.96)}100%{opacity:0;transform:scale(1.08)}}
-@keyframes rdraw{0%{stroke-dashoffset:1}100%{stroke-dashoffset:0}}
-@keyframes fadein{0%{opacity:0}100%{opacity:1}}
-@keyframes comet{0%{offset-distance:0%;opacity:1}96%{opacity:1}100%{offset-distance:100%;opacity:0}}
-@keyframes rise{0%{opacity:0;translate:0 16px}100%{opacity:1;translate:0 0}}
-@keyframes spin{100%{rotate:360deg}}
diff --git a/site/components/landing/mobile/Agent.tsx b/site/components/landing/mobile/Agent.tsx
deleted file mode 100644
index 65ecd3e..0000000
--- a/site/components/landing/mobile/Agent.tsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Agent() {
- return (
- <>
-
-
-
- Ask your coding agent. It writes the JSON, stackmap checks it and delivers one file.
-
-
- ~/commerce-api
-
-
- › Make an architecture diagram of this repository, backed by evidence from the code.
-
-
- writing diagram.json
-
-
- stackmap · validate
-
-
- error refs/unknown-node
-
- Unknown node "orders-db"
- fix: use "orders"
-
- stackmap · validate
-
-
- ✓ valid: no diagnostics
-
-
- stackmap · deliver
-
-
- delivered diagram.html
-
-
-
-
-
- -
- 01
-
Ask.
- Your coding agent, for a codebase, system, process or request.
-
- -
- 02
-
It writes JSON.
- Nodes, connections, groups and views. No coordinates.
-
- -
- 03
-
stackmap checks it.
- Each problem comes with a code and the allowed fixes.
-
- -
- 04
-
One file comes back.
- deliver lays it out as one offline HTML viewer.
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Features.tsx b/site/components/landing/mobile/Features.tsx
deleted file mode 100644
index 6614148..0000000
--- a/site/components/landing/mobile/Features.tsx
+++ /dev/null
@@ -1,210 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Features() {
- return (
- <>
-
-
-
-
-
- Trace. Route.
-
-
-
- Play.
-
-
-
-
- The viewer above is the real thing, cut down to one diagram. Here is what each control does in the file your agent delivers.
-
-
-
-
-
- Explore
-
- A card’s details, connections and the file and line behind it.
-
-
-
-
- Trace
-
- Keep a node’s upstream and downstream; the rest dims.
-
-
-
-
- Route
-
- Every path between two nodes, lit hop by hop.
-
-
-
-
- Find
-
- Search titles, ids and types, or dim a type with the lens.
-
-
-
-
- Guided views
-
- Tabs your agent defines, presented full screen.
-
-
-
-
- Play
-
- Pulses travel whatever you’re looking at.
-
-
-
-
- Share
-
- The URL keeps the view. Export images or a video.
-
-
-
-
- Themes
-
- Dark and light. Reduced motion is respected.
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Files.tsx b/site/components/landing/mobile/Files.tsx
deleted file mode 100644
index f95e4f2..0000000
--- a/site/components/landing/mobile/Files.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Files() {
- return (
- <>
-
-
-
-
-
-
-
- One file.
-
- Opens anywhere.
-
-
- -
-
- No server, no account, nothing to install to open it.
-
- -
-
- The same JSON always gives the same file, byte for byte.
-
- -
-
- The URL keeps the view, the selection, the route and playback.
-
- -
-
- Export PNG, JPEG, WebP or SVG, or a short video of the flow.
-
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Hero.tsx b/site/components/landing/mobile/Hero.tsx
deleted file mode 100644
index a3b8221..0000000
--- a/site/components/landing/mobile/Hero.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { BoardCopy } from '../BoardCopy';
-import { s } from '../style';
-import { LINKS } from '@/components/site/links';
-
-export function Hero() {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- Every
- {' '}
-
- layer
-
-
-
-
- of
- {' '}
-
- your
- {' '}
-
- stack,
-
-
-
-
-
-
- on
- {' '}
-
- one
- {' '}
-
- map.
-
-
-
-
- Interactive system diagrams your coding agent writes, as one offline HTML file.
-
-
-
- {SITE.install.skill}
-
-
-
-
- Works with Claude Code, Cursor, Codex and other coding agents.
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Install.tsx b/site/components/landing/mobile/Install.tsx
deleted file mode 100644
index 0cce608..0000000
--- a/site/components/landing/mobile/Install.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { BoardCopy } from '../BoardCopy';
-
-export function Install() {
- return (
- <>
-
-
-
-
-
-
-
-
- Every layer of your stack, on one map.
-
- Interactive system diagrams your coding agent writes, as one offline HTML file.
-
-
-
- 1Install the skill
-
-
-
- {SITE.install.skill}
-
-
-
-
-
- 2Then ask
-
- Make an architecture diagram of this repository, backed by evidence from the code.
-
-
-
- Or run the CLI on its own, with Node 22.12 or later:
-
-
- {SITE.install.cli}
-
-
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Kinds.tsx b/site/components/landing/mobile/Kinds.tsx
deleted file mode 100644
index 4060b54..0000000
--- a/site/components/landing/mobile/Kinds.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { DIAGRAM_KINDS, KIND_LABELS, type LaidOutDiagram } from '@stackmap/core';
-import { toScene } from '@stackmap/viewer/src/canvas/scene';
-import { Still } from '@/components/diagram/Still';
-import { stillOf } from '@/lib/diagrams';
-import { KindCount } from '../KindCount';
-import { KindFlow } from '../KindFlow';
-import { crossfadeTweens, restingFlow } from '../kinds-geometry';
-import { s } from '../style';
-
-const REST = DIAGRAM_KINDS.indexOf('workflow');
-const LINES = ['Components and what they call.', 'Data moving through stages.', 'Steps across owner lanes.', 'The states of one thing.', 'Messages over time.'];
-// Where the diagrams sit on the 390 × 844 frame: each kind fits this box on its own, centred.
-const AREA = { cx: 195, cy: 510, width: 384, height: 300 };
-
-const px = (n: number) => `${Math.round(n * 10) / 10}px`;
-
-/** #kinds on a phone: the checkout's five diagrams crossfade whole, no cards gliding between them. */
-export function Kinds({ checkout }: { checkout: Record }) {
- const layers = DIAGRAM_KINDS.map((kind) => {
- const diagram = checkout[kind]!;
- const { content } = toScene(diagram);
- const k = Math.min(AREA.width / content.width, AREA.height / content.height);
- return { kind, diagram, k, left: AREA.cx - (content.width * k) / 2, top: AREA.cy - (content.height * k) / 2 };
- });
- const at = (kind: string) => `.lp-m [data-kind="${kind}"]`;
- const rest = DIAGRAM_KINDS.map((kind, k) => `${at(kind)} .kl${k}, ${at(kind)} .kdef${k} {opacity:1}\n${at(kind)} .kn-col {transform:translateY(${-78 * k}px)}`).join('\n');
- const timelines = JSON.stringify(crossfadeTweens(DIAGRAM_KINDS.length)).replace(/
-
-
-
-
- Five kinds of diagram: architecture, dataflow, workflow, lifecycle and sequence.
-
-
-
-
-
-
-
-
- );
-}
diff --git a/site/components/landing/mobile/Unmapped.tsx b/site/components/landing/mobile/Unmapped.tsx
deleted file mode 100644
index ac1c092..0000000
--- a/site/components/landing/mobile/Unmapped.tsx
+++ /dev/null
@@ -1,227 +0,0 @@
-import { SITE } from '@/lib/site-data';
-import { s } from '../style';
-
-export function Unmapped() {
- return (
- <>
-
-
-
-
-
-
- Every codebase has a shape. Nobody has drawn it.
-
-
-
-
-
-
- stackmap turns what your coding agent knows about a system into a diagram you can explore.
-
-
-
-
-
-
-
-
-
-
- shop-api
- REST API
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Orders DB
- PostgreSQL
-
-
-
-
-
-
-
-
-
- infra/orders/postgres.tf:12
-
-
- Every node can point back to the file and line it came from.
-
-
-
-
-
- >
- );
-}
diff --git a/site/components/landing/mobile/Viewer.tsx b/site/components/landing/mobile/Viewer.tsx
deleted file mode 100644
index 8ce142d..0000000
--- a/site/components/landing/mobile/Viewer.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import type { LaidOutDiagram } from '@stackmap/core';
-import { toScene } from '@stackmap/viewer/src/canvas/scene';
-import { Still } from '@/components/diagram/Still';
-import { stillOf } from '@/lib/diagrams';
-import { viewerTweens } from '../drops';
-import { LazyViewer } from '../LazyViewer';
-import { s } from '../style';
-import { TWEENS } from './timelines';
-
-// The phone's plane (the board's .plane-wrap) and the box the real viewer takes over.
-const PLANE = { width: 359, height: 321 };
-const VIEWER = { left: 20, top: 76, width: 350, height: 570 };
-
-/** #viewer on a phone: the same drop, flatten and hand-over, in one column. */
-export function Viewer({ demo }: { demo: LaidOutDiagram }) {
- const { content } = toScene(demo);
- const k = Math.min(1, PLANE.width / content.width, PLANE.height / content.height);
- const timelines = JSON.stringify(viewerTweens(demo, TWEENS)).replace(/ (
-
- );
- return (
-
-
-
-
- {route('h-viewer-d')}
-
-
-
- {route('h-viewer')}
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/site/components/landing/mobile/timelines.ts b/site/components/landing/mobile/timelines.ts
deleted file mode 100644
index b3bec4f..0000000
--- a/site/components/landing/mobile/timelines.ts
+++ /dev/null
@@ -1,2379 +0,0 @@
-// Ported from the canvas board: every scroll timeline, as GSAP percentage keyframes over one 10 s scene.
-// Eases "cb:x1,y1,x2,y2" are the board's cubic-beziers (made into CustomEases at run time).
-import type { Tween } from '../timeline';
-
-export const TWEENS: Tween[] = [
- {
- "target": ".a-hero-out",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "filter": "blur(0px)"
- },
- "100%": {
- "opacity": "0",
- "transform": "translateY(-60px)",
- "filter": "blur(6px)",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-hero-chips",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1)"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0.72)",
- "ease": "cb:0.77,0,0.175,1"
- }
- }
- },
- {
- "target": ".a-hbridge",
- "frames": {
- "0%": {
- "strokeDashoffset": "1"
- },
- "42%": {
- "strokeDashoffset": "1"
- },
- "78%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-hmarks",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "40%": {
- "opacity": "1"
- },
- "52%": {
- "opacity": "0"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vx",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1.35) rotate(-24deg)"
- },
- "7%": {
- "opacity": "1",
- "transform": "scale(1) rotate(0deg)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "26%": {
- "opacity": "1",
- "transform": "scale(1) rotate(0deg)",
- "filter": "blur(0px)"
- },
- "40%": {
- "opacity": "1",
- "transform": "scale(0) rotate(240deg)",
- "filter": "blur(10px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "41%": {
- "opacity": "0"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0) rotate(240deg)"
- }
- }
- },
- {
- "target": ".a-kw",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "scale(1)",
- "filter": "blur(0px)"
- },
- "27%": {
- "opacity": "1",
- "transform": "scale(1)",
- "filter": "blur(0px)"
- },
- "38%": {
- "opacity": "0",
- "transform": "scale(0.12)",
- "filter": "blur(12px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0.12)"
- }
- }
- },
- {
- "target": ".a-k1c",
- "frames": {
- "0%": {
- "color": "var(--sm-text)"
- },
- "15%": {
- "color": "var(--sm-text)"
- },
- "19%": {
- "color": "var(--sm-text-muted)"
- },
- "100%": {
- "color": "var(--sm-text-muted)"
- }
- }
- },
- {
- "target": ".a-cdot",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "29%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "31%": {
- "opacity": "1",
- "transform": "scale(1.9)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "33%": {
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "35.5%": {
- "transform": "scale(1.9)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "38%": {
- "transform": "scale(1)",
- "backgroundColor": "var(--sm-edge)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "41.5%": {
- "transform": "scale(0.5)",
- "backgroundColor": "var(--sm-text)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "43.5%": {
- "opacity": "1",
- "transform": "scale(5)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "46%": {
- "opacity": "0",
- "transform": "scale(0)"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(0)"
- }
- }
- },
- {
- "target": ".a-shock",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0.02)"
- },
- "43%": {
- "opacity": "0",
- "transform": "scale(0.02)"
- },
- "43.5%": {
- "opacity": "0.7",
- "transform": "scale(0.02)"
- },
- "53%": {
- "opacity": "0",
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0",
- "transform": "scale(1)"
- }
- }
- },
- {
- "target": ".a-s2grid",
- "frames": {
- "0%": {
- "opacity": "0",
- "WebkitMaskSize": "0px 0px",
- "maskSize": "0px 0px"
- },
- "43%": {
- "opacity": "1",
- "WebkitMaskSize": "0px 0px",
- "maskSize": "0px 0px"
- },
- "55%": {
- "opacity": "1",
- "WebkitMaskSize": "1100px 1100px",
- "maskSize": "1100px 1100px",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "WebkitMaskSize": "1100px 1100px",
- "maskSize": "1100px 1100px"
- }
- }
- },
- {
- "target": ".a-mk",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "45%": {
- "opacity": "0"
- },
- "45.5%": {
- "opacity": "1"
- },
- "64%": {
- "opacity": "1"
- },
- "70%": {
- "opacity": "0",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mkdot",
- "frames": {
- "0%": {
- "transform": "scale(0.2)",
- "opacity": "0"
- },
- "45.5%": {
- "transform": "scale(0.2)",
- "opacity": "0"
- },
- "50%": {
- "transform": "scale(1)",
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "scale(1)",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mksrc",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "scale(0.9)"
- },
- "49%": {
- "opacity": "0",
- "transform": "scale(0.9)"
- },
- "52.5%": {
- "opacity": "1",
- "transform": "scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "scale(1)"
- }
- }
- },
- {
- "target": ".a-mktgt",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(0.75px) scale(0.985)"
- },
- "58%": {
- "opacity": "0",
- "transform": "translateY(0.75px) scale(0.985)"
- },
- "62%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-s2e",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "77%": {
- "opacity": "0"
- },
- "77.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2eln",
- "frames": {
- "0%": {
- "strokeDashoffset": "1"
- },
- "77.5%": {
- "strokeDashoffset": "1"
- },
- "83%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.33,1,0.68,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-s2eah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "0"
- },
- "84%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2sel",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "86%": {
- "opacity": "0"
- },
- "88%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-s2lead",
- "frames": {
- "0%": {
- "strokeDashoffset": "1"
- },
- "88%": {
- "strokeDashoffset": "1"
- },
- "92%": {
- "strokeDashoffset": "0",
- "ease": "cb:0.33,1,0.68,1"
- },
- "100%": {
- "strokeDashoffset": "0"
- }
- }
- },
- {
- "target": ".a-s2ev",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "91%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "94%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-s2cap1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "55%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "60%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "65%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "69%": {
- "opacity": "0",
- "transform": "translateY(-8px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-s2cap2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "93%": {
- "opacity": "0",
- "transform": "translateY(12px)"
- },
- "97%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-k1w0",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "2%": {
- "transform": "translateY(112%)"
- },
- "6.2%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w1",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "3.6%": {
- "transform": "translateY(112%)"
- },
- "7.8%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w2",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "5.2%": {
- "transform": "translateY(112%)"
- },
- "9.4%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w3",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "6.8%": {
- "transform": "translateY(112%)"
- },
- "11%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k1w4",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "8.4%": {
- "transform": "translateY(112%)"
- },
- "12.6%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w0",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "15%": {
- "transform": "translateY(112%)"
- },
- "19.2%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w1",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "16.6%": {
- "transform": "translateY(112%)"
- },
- "20.8%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w2",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "18.2%": {
- "transform": "translateY(112%)"
- },
- "22.4%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-k2w3",
- "frames": {
- "0%": {
- "transform": "translateY(112%)"
- },
- "19.8%": {
- "transform": "translateY(112%)"
- },
- "24%": {
- "transform": "translateY(0%)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "transform": "translateY(0%)"
- }
- }
- },
- {
- "target": ".a-mapi-box",
- "frames": {
- "0%": {
- "left": "107.5px",
- "top": "375px",
- "width": "75px",
- "height": "50px",
- "borderRadius": "15px",
- "opacity": "0"
- },
- "64%": {
- "left": "107.5px",
- "top": "375px",
- "width": "75px",
- "height": "50px",
- "borderRadius": "15px",
- "opacity": "0"
- },
- "64.5%": {
- "opacity": "1"
- },
- "74%": {
- "left": "55px",
- "top": "300px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "55px",
- "top": "300px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mapi-ov",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "68%": {
- "opacity": "1"
- },
- "76%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mapi-in",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "72%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mdb-box",
- "frames": {
- "0%": {
- "left": "207.5px",
- "top": "275px",
- "width": "75px",
- "height": "50px",
- "borderRadius": "15px",
- "opacity": "0"
- },
- "64%": {
- "left": "207.5px",
- "top": "275px",
- "width": "75px",
- "height": "50px",
- "borderRadius": "15px",
- "opacity": "0"
- },
- "64.5%": {
- "opacity": "1"
- },
- "74%": {
- "left": "55px",
- "top": "420px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "left": "55px",
- "top": "420px",
- "width": "280px",
- "height": "64px",
- "borderRadius": "14px",
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-mdb-ov",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "68%": {
- "opacity": "1"
- },
- "76%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-mdb-in",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "72%": {
- "opacity": "0"
- },
- "79%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-tr0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "37%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "39.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "41%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "43.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "44%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "46.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "45%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "47.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr4",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "47.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "49.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr5",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "53%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "55.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr6",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "56.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "58.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr7",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "61%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "63.2%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-tr8",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "64.5%": {
- "opacity": "0",
- "transform": "translateY(8px)"
- },
- "66.7%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ty0",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "2%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "8%": {
- "width": "20ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(20)"
- },
- "8.4%": {
- "width": "20ch",
- "borderRightColor": "transparent"
- },
- "100%": {
- "width": "20ch",
- "borderRightColor": "transparent"
- }
- }
- },
- {
- "target": ".a-ty1",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "transparent"
- },
- "8.5%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "13%": {
- "width": "15ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(15)"
- },
- "13.4%": {
- "width": "15ch",
- "borderRightColor": "transparent"
- },
- "100%": {
- "width": "15ch",
- "borderRightColor": "transparent"
- }
- }
- },
- {
- "target": ".a-ty2",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "transparent"
- },
- "13.5%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "19.5%": {
- "width": "21ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(21)"
- },
- "19.9%": {
- "width": "21ch",
- "borderRightColor": "transparent"
- },
- "100%": {
- "width": "21ch",
- "borderRightColor": "transparent"
- }
- }
- },
- {
- "target": ".a-ty3",
- "frames": {
- "0%": {
- "width": "0ch",
- "borderRightColor": "transparent"
- },
- "20%": {
- "width": "0ch",
- "borderRightColor": "var(--sm-text)"
- },
- "26%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)",
- "ease": "steps(23)"
- },
- "26.4%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)"
- },
- "100%": {
- "width": "23ch",
- "borderRightColor": "var(--sm-text)"
- }
- }
- },
- {
- "target": ".a-st0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "1%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-st1",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "29%": {
- "opacity": "0.42"
- },
- "31%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-st2",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "49%": {
- "opacity": "0.42"
- },
- "51%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-st3",
- "frames": {
- "0%": {
- "opacity": "0.42"
- },
- "61%": {
- "opacity": "0.42"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-bigp",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- },
- "27%": {
- "opacity": "1",
- "transform": "translate(0px, 0px) scale(1)"
- },
- "34%": {
- "opacity": "1",
- "transform": "translate(-6px, -40px) scale(0.46)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "35.5%": {
- "opacity": "0",
- "transform": "translate(-6px, -40px) scale(0.46)"
- },
- "100%": {
- "opacity": "0",
- "transform": "translate(-6px, -40px) scale(0.46)"
- }
- }
- },
- {
- "target": ".a-tp",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "34.5%": {
- "opacity": "0"
- },
- "35.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-term",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(20px)"
- },
- "26%": {
- "opacity": "0",
- "transform": "translateY(20px)"
- },
- "32%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "44%": {
- "transform": "translateX(0px)"
- },
- "44.6%": {
- "transform": "translateX(-6px)"
- },
- "45.2%": {
- "transform": "translateX(5px)"
- },
- "45.8%": {
- "transform": "translateX(-3px)"
- },
- "46.4%": {
- "transform": "translateX(2px)"
- },
- "47%": {
- "transform": "translateX(0px)"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateX(0px)"
- }
- }
- },
- {
- "target": ".a-drop0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "13%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "14%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "17.2%": {
- "transform": "translateZ(0px)"
- },
- "18.2%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19.2%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade0",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "47%": {
- "opacity": "0"
- },
- "50.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "17.6%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "18.6%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "21.8%": {
- "transform": "translateZ(0px)"
- },
- "22.8%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "23.8%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "49.2%": {
- "opacity": "0"
- },
- "52.8%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "22.2%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "23.2%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "26.4%": {
- "transform": "translateZ(0px)"
- },
- "27.4%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "28.4%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "51.4%": {
- "opacity": "0"
- },
- "55%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "26.8%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "27.8%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "31%": {
- "transform": "translateZ(0px)"
- },
- "32%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "33%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "53.6%": {
- "opacity": "0"
- },
- "57.2%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop4",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "31.4%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "32.4%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "35.6%": {
- "transform": "translateZ(0px)"
- },
- "36.6%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "37.6%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "55.8%": {
- "opacity": "0"
- },
- "59.4%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-drop5",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "36%": {
- "opacity": "0",
- "transform": "translateZ(560px)"
- },
- "37%": {
- "opacity": "1",
- "ease": "cb:0.55,0,1,0.45"
- },
- "40.2%": {
- "transform": "translateZ(0px)"
- },
- "41.2%": {
- "transform": "translateZ(16px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "42.2%": {
- "opacity": "1",
- "transform": "translateZ(0px)",
- "ease": "cb:0.55,0,1,0.45"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateZ(0px)"
- }
- }
- },
- {
- "target": ".a-efade5",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "58%": {
- "opacity": "0"
- },
- "61.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-ahin",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "61.5%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-frin",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "46%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".vcam .hd",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "58%": {
- "opacity": "0"
- },
- "61%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-lights",
- "frames": {
- "0%": {
- "clipPath": "circle(0px at 1010px 1104px)"
- },
- "13%": {
- "clipPath": "circle(2400px at 1010px 1104px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "clipPath": "circle(2400px at 1010px 1104px)"
- }
- }
- },
- {
- "target": ".a-plane",
- "frames": {
- "0%": {
- "transform": "rotateX(58deg) translateY(-10px) scale(0.92)"
- },
- "30%": {
- "transform": "rotateX(58deg) translateY(-10px) scale(0.92)"
- },
- "50%": {
- "transform": "rotateX(0deg) translateY(0px) scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "rotateX(0deg) translateY(0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-pgrid",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "6%": {
- "opacity": "0"
- },
- "14%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "50%": {
- "opacity": "1"
- },
- "58%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vclip",
- "frames": {
- "0%": {
- "clipPath": "inset(-600px round 18px)"
- },
- "52%": {
- "clipPath": "inset(-600px round 18px)"
- },
- "60%": {
- "clipPath": "inset(0px round 18px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "clipPath": "inset(0px round 18px)"
- }
- }
- },
- {
- "target": ".a-dtitle",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "46%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- },
- "53%": {
- "opacity": "0",
- "transform": "translateY(-20px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-vstage",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "50%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-vhead",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "60%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "65%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "64%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "68%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "66%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "70%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vch2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "68%": {
- "opacity": "0",
- "transform": "translateY(-6px)"
- },
- "72%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-vinsp",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(14px)"
- },
- "70%": {
- "opacity": "0",
- "transform": "translateY(14px)"
- },
- "76%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-kl0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd0 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "3%": {
- "opacity": "0"
- },
- "3.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "20%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "39%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd1 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "26%": {
- "opacity": "0"
- },
- "26.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "59%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd2 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "46%": {
- "opacity": "0"
- },
- "46.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "79%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kd3 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "66%": {
- "opacity": "0"
- },
- "66.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kl4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "80%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kd4 .ah",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "86%": {
- "opacity": "0"
- },
- "86.6%": {
- "opacity": "1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-kname",
- "frames": {
- "0%": {
- "transform": "translateY(0px)"
- },
- "16%": {
- "transform": "translateY(0px)"
- },
- "22%": {
- "transform": "translateY(-78px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "36%": {
- "transform": "translateY(-78px)"
- },
- "42%": {
- "transform": "translateY(-156px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "56%": {
- "transform": "translateY(-156px)"
- },
- "62%": {
- "transform": "translateY(-234px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "76%": {
- "transform": "translateY(-234px)"
- },
- "82%": {
- "transform": "translateY(-312px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "translateY(-312px)"
- }
- }
- },
- {
- "target": ".a-kline0",
- "frames": {
- "0%": {
- "opacity": "1"
- },
- "16%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "19%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline1",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "20%": {
- "opacity": "0"
- },
- "23%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "36%": {
- "opacity": "1"
- },
- "39%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline2",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "40%": {
- "opacity": "0"
- },
- "43%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "56%": {
- "opacity": "1"
- },
- "59%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline3",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "60%": {
- "opacity": "0"
- },
- "63%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "76%": {
- "opacity": "1"
- },
- "79%": {
- "opacity": "0",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "0"
- }
- }
- },
- {
- "target": ".a-kline4",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "80%": {
- "opacity": "0"
- },
- "83%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- },
- {
- "target": ".a-file",
- "frames": {
- "0%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(0.94)"
- },
- "16%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px) scale(1)"
- }
- }
- },
- {
- "target": ".a-flights",
- "frames": {
- "0%": {
- "opacity": "1",
- "clipPath": "inset(calc(1000px - var(--by, 0px)) calc(1000px - var(--bx, 0px)) calc(1000px - var(--by, 0px)) calc(1000px - var(--bx, 0px)) round 0px)"
- },
- "16%": {
- "opacity": "1",
- "clipPath": "inset(1092px 1058px 1380px 1058px round 18px)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "16.5%": {
- "opacity": "0",
- "clipPath": "inset(1092px 1058px 1380px 1058px round 18px)"
- },
- "100%": {
- "opacity": "0",
- "clipPath": "inset(1092px 1058px 1380px 1058px round 18px)"
- }
- }
- },
- {
- "target": ".a-filein",
- "frames": {
- "0%": {
- "transform": "rotateY(0deg)"
- },
- "20%": {
- "transform": "rotateY(0deg)"
- },
- "35%": {
- "transform": "rotateY(180deg)",
- "ease": "cb:0.77,0,0.175,1"
- },
- "100%": {
- "transform": "rotateY(180deg)"
- }
- }
- },
- {
- "target": ".a-ofh",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(20px)"
- },
- "40%": {
- "opacity": "0",
- "transform": "translateY(20px)"
- },
- "52%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl0",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "54%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "60%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl1",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "57%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "63%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl2",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "60%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "66%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofl3",
- "frames": {
- "0%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "63%": {
- "opacity": "0",
- "transform": "translateY(10px)"
- },
- "69%": {
- "opacity": "1",
- "transform": "translateY(0px)",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1",
- "transform": "translateY(0px)"
- }
- }
- },
- {
- "target": ".a-ofmore",
- "frames": {
- "0%": {
- "opacity": "0"
- },
- "76%": {
- "opacity": "0"
- },
- "84%": {
- "opacity": "1",
- "ease": "cb:0.23,1,0.32,1"
- },
- "100%": {
- "opacity": "1"
- }
- }
- }
-];
diff --git a/site/components/landing/site.css b/site/components/landing/site.css
deleted file mode 100644
index 8e797aa..0000000
--- a/site/components/landing/site.css
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Site-owned additions to the ported boards: the root the boards' `.site` was, and where a board's
- hand-drawn stand-in became the real diagram or viewer. */
-
-.lp {
- position: relative;
- color: var(--sm-text);
- background: var(--sm-page);
- overflow-x: clip;
-}
-/* Declared per theme: a custom property resolves where it's declared, so one on the root would keep the root's border. */
-.lp,
-.lp [data-theme] {
- --shadow-panel: inset 0 0 0 1px var(--sm-panel-border), 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
-}
-.lp [data-theme] {
- /* The boards' theme classes also reset the colour; inherited text would keep the root's theme. */
- color: var(--sm-text);
-}
-.lp *,
-.lp *::before,
-.lp *::after {
- box-sizing: border-box;
-}
-/* Element resets sit in the base layer: unlayered, they'd beat the viewer's utility classes (its Export label). */
-@layer base {
- :where(.lp) button {
- font: inherit;
- color: inherit;
- }
- :where(.lp) a {
- color: inherit;
- }
-}
-.lp-m {
- display: none;
-}
-@media (max-width: 767px) {
- .lp-d {
- display: none;
- }
- .lp-m {
- display: block;
- }
-}
-
-/* #viewer: the intro plane only exists while the page scrubs; at rest the real viewer is the frame. */
-.lp .vintro {
- display: none;
-}
-.lp.live .vintro {
- display: block;
-}
-.lp .vreal {
- position: absolute;
- inset: 0;
- overflow: hidden;
- border-radius: 22px;
- background: var(--sm-page);
- box-shadow: var(--shadow-panel);
-}
-.lp .plane-dg {
- position: absolute;
- left: 50%;
- top: 0;
- transform-origin: 50% 0;
- transform-style: preserve-3d;
-}
-.lp .plane-dg div {
- transform-style: preserve-3d;
-}
-
-/* #kinds: the checkout's cards are the slots; the layers draw only lanes, phases, frames and connections. */
-.lp-d .klayer .sm-card {
- visibility: hidden;
-}
-.lp .kslot,
-.lp .klayer,
-.lp .kface,
-.lp .kcam,
-.lp .kn-col,
-.lp .kdef {
- transition:
- left 420ms cubic-bezier(0.77, 0, 0.175, 1),
- top 420ms cubic-bezier(0.77, 0, 0.175, 1),
- width 420ms cubic-bezier(0.77, 0, 0.175, 1),
- height 420ms cubic-bezier(0.77, 0, 0.175, 1),
- transform 420ms cubic-bezier(0.77, 0, 0.175, 1),
- opacity 240ms cubic-bezier(0.23, 1, 0.32, 1);
-}
-.lp.live .kslot,
-.lp.live .klayer,
-.lp.live .kface,
-.lp.live .kcam,
-.lp.live .kn-col,
-.lp.live .kdef {
- transition: none;
-}
-.lp .kface-in {
- transform-origin: 0 0;
-}
-.lp .kflow {
- position: absolute;
- top: 0;
- left: 0;
- pointer-events: none;
-}
-@media (prefers-reduced-motion: reduce) {
- .lp .kslot,
- .lp .klayer,
- .lp .kface,
- .lp .kcam,
- .lp .kn-col,
- .lp .kdef {
- transition: none;
- }
-}
diff --git a/site/components/landing/style.ts b/site/components/landing/style.ts
deleted file mode 100644
index 0d528d4..0000000
--- a/site/components/landing/style.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import type { CSSProperties } from 'react';
-
-/** Board markup sets custom properties (--x, --z…) inline, which CSSProperties doesn't type. */
-export const s = (style: Record) => style as CSSProperties;
diff --git a/site/components/landing/timeline.ts b/site/components/landing/timeline.ts
deleted file mode 100644
index 1736fd2..0000000
--- a/site/components/landing/timeline.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { gsap } from 'gsap';
-import { CustomEase } from 'gsap/CustomEase';
-
-/** One board timeline: GSAP percentage keyframes over a scene's 10 s, each frame's `ease` being the ease into it. */
-export interface Tween {
- target: string;
- frames: Record>;
-}
-
-/** Every scene's timeline runs 10 s; scroll through its pin maps onto that (Motion rule 01). */
-export const SCENE_SECONDS = 10;
-
-const eases = new Map();
-
-// The board's curves are cubic-beziers ("cb:x1,y1,x2,y2"); GSAP gets each as a CustomEase, made once.
-function ease(name: string | undefined): string | undefined {
- if (!name?.startsWith('cb:')) return name;
- let id = eases.get(name);
- if (!id) {
- const [x1, y1, x2, y2] = name.slice(3).split(',');
- id = `sm-${eases.size}`;
- CustomEase.create(id, `M0,0 C${x1},${y1} ${x2},${y2} 1,1`);
- eases.set(name, id);
- }
- return id;
-}
-
-const IDENTITY = { x: 0, y: 0, z: 0, scale: 1, rotation: 0, rotationX: 0, rotationY: 0 };
-
-/**
- * A CSS transform string as GSAP's own transform properties, which it animates on HTML and SVG alike
- * (it writes SVG transforms as attributes, where a CSS string doesn't parse). GSAP composes them as
- * translate, rotate, scale, the order nearly every board transform is already written in; a translate
- * the board writes after a rotateX moves in the tilted frame, so it's turned into the same move in world space.
- */
-export function transformVars(css: string): gsap.TweenVars {
- if (css.trim() === 'none') return { ...IDENTITY };
- const out: gsap.TweenVars = {};
- for (const [, fn, args] of css.matchAll(/(\w+)\(([^)]*)\)/g)) {
- const v = args!.split(',').map((a) => a.trim());
- const n = (i: number) => parseFloat(v[i] ?? '0');
- // A percentage moves by the element's own size: GSAP's xPercent and yPercent.
- const axis = (i: number, name: 'x' | 'y') => ((v[i] ?? '').endsWith('%') ? { [`${name}Percent`]: n(i) } : { [name]: n(i) });
- const tilt = ((Number(out.rotationX) || 0) * Math.PI) / 180;
- if (tilt && (fn === 'translateY' || fn === 'translateZ')) {
- const [y, z] = fn === 'translateY' ? [n(0), 0] : [0, n(0)];
- out.y = (Number(out.y) || 0) + y * Math.cos(tilt) - z * Math.sin(tilt);
- out.z = (Number(out.z) || 0) + y * Math.sin(tilt) + z * Math.cos(tilt);
- } else if (fn === 'translate') Object.assign(out, axis(0, 'x'), axis(1, 'y'));
- else if (fn === 'translateX') Object.assign(out, axis(0, 'x'));
- else if (fn === 'translateY') Object.assign(out, axis(0, 'y'));
- else if (fn === 'translateZ') out.z = n(0);
- else if (fn === 'scale') Object.assign(out, v.length > 1 ? { scaleX: n(0), scaleY: n(1) } : { scale: n(0) });
- else if (fn === 'rotate') out.rotation = n(0);
- else if (fn === 'rotateX') out.rotationX = n(0);
- else if (fn === 'rotateY') out.rotationY = n(0);
- }
- return out;
-}
-
-function keyframes(frames: Tween['frames']) {
- const out: Record = {};
- for (const [at, { ease: e, transform, ...props }] of Object.entries(frames)) {
- out[at] = { ...props, ...(transform ? transformVars(transform) : {}), ...(e ? { ease: ease(e) } : {}) };
- }
- return out;
-}
-
-/** The scene's timeline: every tween whose target is inside it, all starting at 0 and filling the 10 s. */
-export function sceneTimeline(scene: Element, tweens: Tween[]): gsap.core.Timeline {
- const tl = gsap.timeline({ paused: true, defaults: { ease: 'none' } });
- for (const t of tweens) {
- const targets = scene.querySelectorAll(t.target);
- if (!targets.length) continue;
- // SVG shapes transform about their own box, as the board's `transform-box: fill-box` has them.
- const svg = targets[0] instanceof SVGElement && (targets[0] as SVGElement).ownerSVGElement !== null;
- tl.to(targets, { keyframes: keyframes(t.frames), duration: SCENE_SECONDS, ease: 'none', ...(svg ? { transformOrigin: '50% 50%' } : {}) }, 0);
- }
- tl.set({}, {}, SCENE_SECONDS);
- return tl;
-}
-
-/** Timelines a scene computes from its own data (the kinds' slots, the viewer's drops), in a JSON script inside it. */
-export function sceneExtras(scene: Element): Tween[] {
- return [...scene.querySelectorAll('script[data-timelines]')].flatMap((s) => JSON.parse(s.textContent || '[]') as Tween[]);
-}
diff --git a/site/components/site/Footer.tsx b/site/components/site/Footer.tsx
index f65dd41..c94e4ff 100644
--- a/site/components/site/Footer.tsx
+++ b/site/components/site/Footer.tsx
@@ -4,33 +4,34 @@ import { LINKS, type SiteLink } from './links';
import { Lockup } from './Lockup';
const COLUMNS: { title: string; links: SiteLink[] }[] = [
- { title: 'Product', links: [LINKS.viewer, LINKS.kinds, LINKS.examples, LINKS.docs] },
+ { title: 'Product', links: [LINKS.how, LINKS.kinds, LINKS.examples, LINKS.docs] },
{ title: 'Reference', links: [LINKS.quickStart, LINKS.schema, LINKS.cli, LINKS.authoring] },
- { title: 'Project', links: [LINKS.github, LINKS.npm, LINKS.contributing, LINKS.security] },
+ { title: 'Project', links: [LINKS.github, LINKS.npm, LINKS.film, LINKS.contributing, LINKS.security] },
];
-const linkClass = 'text-sm text-fg-muted transition-colors duration-150 hover:text-fg';
-
function Item({ link }: { link: SiteLink }) {
- if (link.href.startsWith('/')) return {link.label};
- return {link.label};
+ if (link.href.startsWith('/')) return {link.label};
+ return (
+
+ {link.label}
+
+ );
}
-/** Always dark, on every page (the canvas's "lights off" ending). */
export function Footer() {
return (
-