import type { CSSProperties } from "react"; import { MARK, MARK_VIEWBOX, type MarkTone } from "../lib/brand"; // A palette whose slots are any CSS colour — a hex, or a `var()` expression // such as the export header's `var(--brand-mark, var(--brand))`, which is why // this is not lib/brand.ts's hex-only IconPalette. export type BrandMarkPalette = Readonly>; // THE RING ON DARK. On the dark base the tile has no edge: a site's ink tile // is the ink page itself (#0c0a08 on #0c0a08), and the parent's slate barely // clears it. So on dark — `.dark` on , tokens.css's `@custom-variant // dark` — the tile gets a 1px ring OUTSIDE it, in the palette's own dim // (`--mark-ring`, set from `palette.dim` below), so the ring reads as part of // the mark. Light is untouched. // - A box-shadow, so it takes no layout: the mark's size and the header's // alignment are the same on every base. // - `rounded-[21.875%]` is the ground's corner (MARK_GROUND_RX / MARK_VIEWBOX, // 112 of 512; BrandMark.test.ts holds the two equal), so the ring follows // the tile's own curve. // - `overflow-visible`: an clips its content by default, and with a // border-radius that clip would be a second anti-aliased edge laid over // the ground's own rounded corner. // FORCED COLOURS (Windows High Contrast, release 11): the reader's palette // replaces the page on every base, and its Canvas may be as dark as the tile // (a black high-contrast theme), while the ring is only drawn on dark — and an // engine that forces `box-shadow: none` there drops even that. So under // `@media (forced-colors: active)`, on every base, the tile gets a 1px OUTLINE // in the system `CanvasText`, outside it and following the same corner (an // outline follows border-radius). An keeps its own colours there // (Chromium's UA sheet gives it `forced-color-adjust: preserve-parent-color`, // which also keeps the dark ring; the outline is painted over the same pixel // ring), so the outline is the one part drawn in the reader's colours. // Outside forced colours the two classes match nothing: every other mode // renders as before. // Complete literal class strings — Tailwind v4 only sees whole literals. export const BRAND_MARK_RING_CLASS = "rounded-[21.875%] overflow-visible dark:shadow-[0_0_0_1px_var(--mark-ring)] " + "forced-colors:outline forced-colors:outline-[color:CanvasText]"; // The Found-line mark, inline — drawn from the same MARK shape list as // markSvg (the icon files), so the two cannot drift. Decorative: the text // beside it names the link. Colours go through `style`, not a `fill="var()"` // attribute, because a presentation attribute does not resolve custom // properties everywhere a style declaration does. Size it with `className` // (e.g. `size-7`) or `size`. Every use draws the tile, so every use rings on // dark; the icon files (markSvg) never do. export function BrandMark({ palette, size, className, style, }: { palette: BrandMarkPalette; size?: number; className?: string; style?: CSSProperties; }) { return ( ); }