Visual
Striped wordmark
SVG wordmark with horizontal stripes.
npx -y github:anwarlemu/agentcard-brand-cli#release add striped-wordmarkUsage
Use across the bottom of SiteFooter on blue. Supports short uppercase words.
- More than one per page
- Long words or sentences
- On a white ground
- Set in a font instead of the bars
Example
import { StripedWordmark } from "@/components/visuals/striped-wordmark";
import { Surface } from "@/lib/surface";
export function Site() {
return (
<div className="grid gap-6">
<Surface ground="blue" className="overflow-hidden rounded-panel">
<StripedWordmark />
</Surface>
<Surface ground="blue" className="overflow-hidden rounded-panel">
<StripedWordmark text="VAULT" />
</Surface>
</div>
);
}Source
import * as React from "react";
import { cn } from "@/lib/utils";
// The footer's giant word (agentcard.sh, .v7-foot-glyphs): one letter per cell between vertical rules, each letter drawn
// in horizontal bars like type on a tube, the same lines as the logomark's hand. Every glyph is a 16 by 11 grid; a run
// of lit squares in a row becomes one bar, 6 units tall in a 10 unit row, so the stripes show the ground between them.
// The bars are paper and fade a little toward the foot. It is SVG, so it scales with the width it is given (the
// footer's full width) instead of stepping on the type scale. Letters A to Z; anything else is an empty cell.
const GLYPHS: Record<string, string[]> = {
A: ["....########....", "...##########...", "..####....####..", ".####......####.", ".###........###.", ".###........###.", ".##############.", ".##############.", ".###........###.", ".###........###.", ".###........###."],
B: [".###########....", ".#############..", ".###.......####.", ".###........###.", ".###.......####.", ".############...", ".#############..", ".###.......####.", ".###........###.", ".#############..", ".###########...."],
C: ["....#########...", "..#############.", ".####.......###.", ".###............", ".###............", ".###............", ".###............", ".###............", ".####.......###.", "..#############.", "....#########..."],
D: [".##########.....", ".#############..", ".###......#####.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###......#####.", ".#############..", ".##########....."],
E: [".##############.", ".##############.", ".###............", ".###............", ".###............", ".###########....", ".###########....", ".###............", ".###............", ".##############.", ".##############."],
F: [".##############.", ".##############.", ".###............", ".###............", ".###............", ".###########....", ".###########....", ".###............", ".###............", ".###............", ".###............"],
G: ["....#########...", "..#############.", ".####.......###.", ".###............", ".###............", ".###....#######.", ".###....#######.", ".###........###.", ".####.......###.", "..#############.", "....#########..."],
H: [".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".##############.", ".##############.", ".###........###.", ".###........###.", ".###........###.", ".###........###."],
I: ["....########....", "....########....", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......", "....########....", "....########...."],
J: ["......#########.", "......#########.", "............###.", "............###.", "............###.", "............###.", "............###.", ".###........###.", ".####......####.", "..############..", "....########...."],
K: [".###.......####.", ".###......####..", ".###.....####...", ".###....####....", ".###...####.....", ".#########......", ".##########.....", ".###....####....", ".###.....####...", ".###......####..", ".###.......####."],
L: [".###............", ".###............", ".###............", ".###............", ".###............", ".###............", ".###............", ".###............", ".###............", ".##############.", ".##############."],
M: [".####......####.", ".#####....#####.", ".######..######.", ".###.######.###.", ".###..####..###.", ".###...##...###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###."],
N: [".###........###.", ".####.......###.", ".#####......###.", ".######.....###.", ".###.###....###.", ".###..###...###.", ".###...###..###.", ".###....###.###.", ".###.....######.", ".###......#####.", ".###.......####."],
O: ["....########....", "..############..", ".####......####.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".####......####.", "..############..", "....########...."],
P: [".###########....", ".#############..", ".###.......####.", ".###........###.", ".###.......####.", ".#############..", ".###########....", ".###............", ".###............", ".###............", ".###............"],
Q: ["....########....", "..############..", ".####......####.", ".###........###.", ".###........###.", ".###........###.", ".###....###.###.", ".###.....######.", ".####.....####..", "..#############.", "....#######.###."],
R: [".###########....", ".#############..", ".###.......####.", ".###........###.", ".###.......####.", ".#############..", ".###########....", ".###...####.....", ".###....####....", ".###.....####...", ".###......####.."],
S: ["...###########..", ".##############.", ".####...........", ".###............", ".#####..........", "..###########...", "...###########..", "..........#####.", "............###.", ".##############.", "..###########..."],
T: [".##############.", ".##############.", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......", "......####......"],
U: [".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".####......####.", "..############..", "....########...."],
V: [".###........###.", ".###........###.", ".###........###.", ".####......####.", "..###......###..", "..####....####..", "...###....###...", "...####..####...", "....###..###....", ".....######.....", "......####......"],
W: [".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###........###.", ".###...##...###.", ".###..####..###.", ".###.######.###.", ".######..######.", ".#####....#####.", ".####......####."],
X: [".###........###.", ".####......####.", "..####....####..", "...####..####...", "....########....", ".....######.....", "....########....", "...####..####...", "..####....####..", ".####......####.", ".###........###."],
Y: [".###........###.", ".####......####.", "..####....####..", "...####..####...", "....########....", ".....######.....", "......####......", "......####......", "......####......", "......####......", "......####......"],
Z: [".##############.", ".##############.", "..........####..", ".........####...", "........####....", ".......####.....", "......####......", ".....####.......", "....####........", ".##############.", ".##############."],
};
const COLS = 16;
const ROWS = 11;
function BarGlyph({ rows }: { rows?: string[] }) {
const bars: { x: number; y: number; w: number }[] = [];
rows?.forEach((row, y) => {
for (const run of row.matchAll(/#+/g)) bars.push({ x: run.index ?? 0, y, w: run[0].length });
});
return (
<svg
viewBox={`0 0 ${COLS * 10} ${ROWS * 10}`}
aria-hidden
className="-mb-0.5 block h-auto w-full fill-paper [mask-image:linear-gradient(var(--ds-color-black)_45%,color-mix(in_srgb,var(--ds-color-black)_55%,transparent))]"
>
{bars.map((b) => (
<rect key={`${b.x}-${b.y}`} x={b.x * 10} y={b.y * 10 + 2} width={b.w * 10} height={6} />
))}
</svg>
);
}
function StripedWordmark({ text = "AGENTCARD", label, className, style, ...props }: Omit<React.ComponentProps<"div">, "children"> & { text?: string; label?: string }) {
const letters = [...text.toUpperCase()];
return (
<div
role="img"
aria-label={label ?? text}
data-slot="striped-wordmark"
className={cn("grid w-full", className)}
style={{ gridTemplateColumns: `repeat(${letters.length}, minmax(0, 1fr))`, ...style }}
{...props}
>
{letters.map((letter, i) => (
<div
key={i}
className="grid items-end border-l border-line-on-brand-strong px-[clamp(--spacing(0.75),0.8vw,--spacing(3.5))] pt-[clamp(--spacing(5),3vw,--spacing(12))] pb-[clamp(0rem,calc((87.5rem-100vw)*0.145),--spacing(19))] first:border-l-0"
>
<BarGlyph rows={GLYPHS[letter]} />
</div>
))}
</div>
);
}
export { StripedWordmark };Reference: agentcard-website src/components/v7/site-footer.tsx (BarGlyph, .v7-foot-glyphs); src/app/globals.css:5085; agentcard.sh / (computed).