/** * The one panel chrome (milestone 39): a white hairline-bordered card with a * prominent title and a one-line description under it. Every panel on every * page is one of these, so the pages agree by construction rather than by * copying a `panel` style object around. * * The title is an `h2` because a card is a section of the page's outline; a * page that needs a different level passes `as`. */ import { useId } from "react"; import * as stylex from "@stylexjs/stylex"; import { colors, metrics } from "./tokens.stylex"; export const cardStyles = stylex.create({ card: { minWidth: 0, borderRadius: metrics.radius, borderWidth: 1, borderStyle: "solid", borderColor: colors.border, backgroundColor: colors.surfaceRaised, padding: metrics.cardPadding, }, head: { marginBottom: "1.25rem", }, /** * The card's title is the loudest text on the page after the stat numerals: * the references (Pi-hole, NextDNS) both lead each panel with a heading the * eye lands on first. Kept in one place so no heading reset outranks it. */ title: { margin: 0, fontSize: "1.4rem", lineHeight: 1.2, fontWeight: 650, letterSpacing: "-0.015em", color: colors.text, textWrap: "balance", }, description: { margin: 0, marginTop: "0.25rem", fontSize: "0.875rem", lineHeight: "1.25rem", color: colors.textMuted, textWrap: "pretty", }, }); export default function Card({ title, description, as: Heading = "h2", style, children, }: { title: string; /** One sentence saying what the panel shows; every card carries one (the decision record's card head). */ description: string; as?: "h2" | "h3"; /** Extra styles for the card box itself: a grid placement, a clipped list variant. */ style?: stylex.StyleXStyles; children: React.ReactNode; }) { const titleId = useId(); return (
{title}

{description}

{children}
); }