Files

66 lines
1.9 KiB
TypeScript
Raw Permalink Normal View History

/**
* The SchoolCompare mark.
*
* Five bars: a cohort, with one school picked out. It is the same object as
* the distribution strip inside a school row, at a different size — the logo
* teaches the chart and the chart reinforces the logo.
*
* Built from opacity steps over `currentColor` rather than fixed greys, so it
* inverts cleanly on any ground without a second artwork. The highlighted bar
* is the only element that takes the brand hue.
*
* This is the single source for the mark. The favicon and the generated icons
* derive from the same geometry (see BARS) — previously the header and the
* favicon had drifted into two different logos.
*/
/** x, y, width, height, and whether this bar is the highlighted school. */
export const BARS: ReadonlyArray<[number, number, number, number, boolean]> = [
[2, 26, 6, 12, false],
[10, 16, 6, 22, false],
[18, 8, 6, 30, false],
[26, 14, 6, 24, true],
[34, 28, 4, 10, false],
];
const COHORT_OPACITY = [0.22, 0.38, 0.55, 1, 0.22];
interface LogoMarkProps {
className?: string;
/** Rendered size in px. Defaults to inheriting via CSS. */
size?: number;
/** Colour of the highlighted bar. Defaults to the brand token. */
accent?: string;
title?: string;
}
export function LogoMark({ className, size, accent = 'var(--brand)', title }: LogoMarkProps) {
return (
<svg
className={className}
width={size}
height={size}
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role={title ? 'img' : undefined}
aria-hidden={title ? undefined : true}
aria-label={title}
>
{title ? <title>{title}</title> : null}
{BARS.map(([x, y, w, h, isSchool], i) => (
<rect
key={x}
x={x}
y={y}
width={w}
height={h}
rx={1}
fill={isSchool ? accent : 'currentColor'}
opacity={isSchool ? 1 : COHORT_OPACITY[i]}
/>
))}
</svg>
);
}