| // --------------------------------------------------------------------------- | |
| // 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> | |
| ); | |
| } | |