// Mission 001 v2 — panels: masthead, telemetry strip, route card, candidates, feed, scrubber, share card
const { useState: useSt, useEffect: useEff } = React;
function useClock() {
// Real elapsed time since mission declaration (MD.t0). Not a simulation.
const [now, setNow] = useSt(Date.now());
useEff(() => { const id = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(id); }, []);
const s = Math.max(0, Math.floor((now - MD.t0) / 1000));
const p = (n) => String(n).padStart(2, "0");
return `T+${p(Math.floor(s / 86400))}:${p(Math.floor(s / 3600) % 24)}:${p(Math.floor(s / 60) % 60)}:${p(s % 60)}`;
}
const Masthead = ({ st, onShare }) => {
const clock = useClock();
return (
);
};
const StatusStrip = ({ st }) => {
const dest = st.dest ? MD.DEST_NAMES[st.dest] : null;
return (
STAGE · DAY {String(st.day).padStart(2, "0")}
{st.stageLabel}
{st.statusLine.toLowerCase()}
BEST DESTINATION
{dest ? dest.short.toUpperCase() : "UNDER EVALUATION"}
{dest ? dest.full : (st.destNote || "scanning for candidates")}
ROUTE CONFIDENCE
{st.conf == null ? "——" : st.conf + "%"}
{st.confDelta != null && st.confDelta !== 0 && (
0 ? "up" : "down"}>{st.confDelta > 0 ? "▲ +" : "▼ "}{st.confDelta}
)}
{st.hops == null ? "no route yet" : st.complete ? "route closed — target reached" :
st.hopsPrev ? {st.hopsPrev} → {st.hops} steps in best route : `${st.hops} steps in best route`}
LAST UPDATE
{st.lastUpdate.t} {st.lastUpdate.txt}
);
};
const RouteCard = ({ st }) => {
const dest = st.dest ? MD.DEST_NAMES[st.dest] : null;
return (
CURRENT BEST ROUTE
{dest ? (
{dest.full}
{st.conf}%
{st.confDelta != null && st.confDelta !== 0 && (
0 ? "up" : "down"}>{st.confDelta > 0 ? "▲ +" : "▼ "}{st.confDelta} today
)}
{st.route.steps.map((s, i) => (
{String(i + 1).padStart(2, "0")}
{s.txt} {s.sub}
))}
) : (
NO ROUTE SELECTED{st.key === "declared" ? "the agent is scoring destinations from public sources — it has no view of anyone's network" : "candidates found — ranking routes by expected value"}
)}
);
};
const Candidates = ({ st }) => (
CANDIDATE DESTINATIONS
{st.candidates.length === 0 ? (
SCANNINGfirst discovery sprint in progress — candidates appear here when scored
) : (
{st.candidates.map((c, i) => (
{String(i + 1).padStart(2, "0")}
{c.short}
{c.state}
{c.prob}%
))}
)}
);
const Feed = ({ st, limit = 4 }) => (
RECENT DISCOVERIES
{st.log.slice(0, limit).map((l, i) => (
{l.t}
{l.txt} {l.delta && {l.delta} }
))}
{st.deadEnds.length > 0 && (
DEAD ENDS
{st.deadEnds.map((d, i) => (
✕ {d.txt}
))}
)}
);
const NextAction = ({ st }) => (
{st.complete ? "OUTCOME" : "NEXT ACTION"}
{st.nextAction}
);
const Scrubber = ({ stage, setStage }) => {
useEff(() => {
const onKey = (e) => {
if (e.key === "ArrowRight") setStage(Math.min(stage + 1, MD.STAGES.length - 1));
if (e.key === "ArrowLeft") setStage(Math.max(stage - 1, 0));
};
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, [stage, setStage]);
return (
MISSION TIMELINE
{MD.STAGES.map((s, i) => (
setStage(i)} aria-label={`${s.tick} ${s.tickLabel}`}>
{s.tick}
{s.tickLabel}
))}
◂ ▸ REPLAY
);
};
// 1200×630 social share card, scaled to fit the viewport
const ShareCard = ({ st, stage, onClose }) => {
const [scale, setScale] = useSt(1);
useEff(() => {
const fit = () => setScale(Math.min((window.innerWidth - 64) / 1200, (window.innerHeight - 140) / 630, 1));
fit();
window.addEventListener("resize", fit);
return () => window.removeEventListener("resize", fit);
}, []);
const dest = st.dest ? MD.DEST_NAMES[st.dest] : null;
return (
screenshot this card · click anywhere to close
e.stopPropagation()}>
{MD.brand} · {MD.mission} · DAY {String(st.day).padStart(2, "0")}
“{MD.objective}”
STAGE
{st.stageLabel}
BEST DESTINATION
{dest ? dest.short.toUpperCase() : "UNDER EVALUATION"}
ROUTE CONFIDENCE
{st.conf == null ? "——" : st.conf + "%"}
{st.statusLine.toUpperCase()} — PUBLIC EXPERIMENT · EVERY NUMBER REGISTERED BEFORE ACTING
);
};
Object.assign(window, { Masthead, StatusStrip, RouteCard, Candidates, Feed, NextAction, Scrubber, ShareCard, useClock });