File size: 2,264 Bytes
092334a c14ceee 092334a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | // ---------------------------------------------------------------------------
// shell/Brand.tsx — the Loopable lockup: the mark, plus the wordmark on request.
//
// ⚠ THIS COMPONENT DRAWS NOTHING. It POINTS at the generated artifact, and that
// is the entire point of the file.
//
// The mark's one source of truth is `_brandmark.loopable_svg()` in
// platform (wave-10 I24: an open loop of continuously tapering weight,
// monotone #6E56CF). `platform/static/loopable-mark.svg` and
// `web/public/favicon.svg` are GENERATED from it, and that file's own header
// says: "Never redraw a third copy."
//
// It was redrawn anyway. Shell.tsx carried a hand-typed TWO-CONCENTRIC-RINGS
// mark (the wave-9 geometry, blue + green) under a comment asserting it was
// "identical to app.py `_loopable_svg` and public/favicon.svg — one mark, three
// painters". I24 replaced the geometry upstream and the copy did not follow, so
// the standalone shell has been painting LAST WAVE'S BRAND while claiming
// parity in a comment. A comment claiming parity is not parity; consuming the
// artifact is. Hence <img>, not <svg>.
//
// BASE_URL rather than a leading slash: `vite.config.ts` sets `base: "./"` so
// the bundle works served from any sub-path, and an absolute `/favicon.svg`
// would quietly reach outside that sub-path for the one asset that carries the
// brand.
// ---------------------------------------------------------------------------
const MARK_SRC = `${import.meta.env.BASE_URL}favicon.svg`;
export function Mark({ size }: { size: number }) {
return (
<img
className="lp-mark"
src={MARK_SRC}
width={size}
height={size}
// Decorative: the wordmark beside it already says "Loopable", and a
// screen reader announcing the product name twice is noise.
alt=""
aria-hidden="true"
draggable={false}
/>
);
}
/** Mark + wordmark, side by side — the wave-9 I5 lockup, the same object on the
* login card and in the nav so the two doors read as one product. */
export function Brand({ size, className }: { size: number; className?: string }) {
return (
<div className={className}>
<Mark size={size} />
<span className="lp-wordmark">Loopable</span>
</div>
);
}
|