Add the Northline template family: Purple Pop and Citrus Split

Purple Pop (cream page, purple pills, asterisk and dome decor, opt-in
logo) and Citrus Split (grey split panel, halftone chevrons, icon
contacts, logo in the measured slot) are rebuilt from the Canva PDFs on
the engine with A4/Letter support, GST slots and zero audit errors. Adds
static DM Sans, Jost and Poppins 800 as look-alikes for the commercial
fonts. The picker now lists ten templates.
This commit is contained in:
2026-10-04 09:56:56 +05:30
parent 06976df55c
commit 5ea62a9be8
36 changed files with 3033 additions and 56 deletions
+6 -3
View File
@@ -25,13 +25,16 @@ export interface CircledIconProps extends ContactIconProps {
ring: number;
/** The icon's share of the diameter, 0..1. */
glyph?: number;
/** A filled disc with the glyph knocked out in `glyphColor` (default white) instead of a ring. */
solid?: boolean;
glyphColor?: string;
}
/**
* An icon inside a ring (Slate Band's footer): one static Svg, ring and glyph together. The glyph sits in a
* translated and scaled static group (verified to work as a static child, unlike inside a render prop).
*/
export function CircledIcon({ name, size, color, ring, glyph = 0.5 }: CircledIconProps) {
export function CircledIcon({ name, size, color, ring, glyph = 0.5, solid = false, glyphColor = "#FFFFFF" }: CircledIconProps) {
const icon = ICONS[name];
const [minX, minY, vw, vh] = icon.viewBox.split(" ").map(Number);
const scale = (size * glyph) / Math.max(vw, vh);
@@ -39,10 +42,10 @@ export function CircledIcon({ name, size, color, ring, glyph = 0.5 }: CircledIco
const oy = (size - vh * scale) / 2 - minY * scale;
return (
<Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
<Circle cx={size / 2} cy={size / 2} r={size / 2 - ring / 2} stroke={color} strokeWidth={ring} fill="none" />
{solid ? <Circle cx={size / 2} cy={size / 2} r={size / 2} fill={color} /> : <Circle cx={size / 2} cy={size / 2} r={size / 2 - ring / 2} stroke={color} strokeWidth={ring} fill="none" />}
<G transform={`translate(${ox} ${oy}) scale(${scale})`}>
{icon.paths.map((d, i) => (
<Path key={i} d={d} fill={color} />
<Path key={i} d={d} fill={solid ? glyphColor : color} />
))}
</G>
</Svg>