UI Library
Principles grid
A two-column grid of bordered term-and-description cards, with a section header above it. Built on a real <dl>, so each term is announced together with its description.
Featuresgriddefinition-listaccessible
Preview
How we work
A few principles that constrain what we build.
Not slogans: actual limits on what we will and will not ship.
- Amanah
- User data is held in trust. Collect only what a feature needs, never sell it, and deletion is real deletion.
- Sidq
- Marketing claims match the implementation. No dark patterns. AI outputs are disclosed.
- Adl
- Transparent, proportionate pricing. Safety features are never paywalled. Cancellation is frictionless.
- Ihsan
- Quality over feature count. Performance and reliability come first.
apps/site/blocks/components/principles-grid.tsx
interface Principle {
term: string;
description: string;
}
const DEFAULT_PRINCIPLES: Principle[] = [
{
term: 'Amanah',
description:
'User data is held in trust. Collect only what a feature needs, never sell it, and deletion is real deletion.',
},
{
term: 'Sidq',
description:
'Marketing claims match the implementation. No dark patterns. AI outputs are disclosed.',
},
{
term: 'Adl',
description:
'Transparent, proportionate pricing. Safety features are never paywalled. Cancellation is frictionless.',
},
{
term: 'Ihsan',
description: 'Quality over feature count. Performance and reliability come first.',
},
];
export function PrinciplesGrid({
eyebrow = 'How we work',
title = 'A few principles that constrain what we build.',
intro = 'Not slogans: actual limits on what we will and will not ship.',
principles = DEFAULT_PRINCIPLES,
}: {
eyebrow?: string;
title?: string;
intro?: string;
principles?: Principle[];
}) {
return (
<section className="border-b border-border/60">
<div className="mx-auto max-w-6xl px-4 py-20 sm:px-6">
<div className="mb-12 max-w-2xl space-y-3">
<div className="text-xs font-medium uppercase tracking-widest text-primary">{eyebrow}</div>
<h2 className="text-2xl font-semibold tracking-tight sm:text-3xl">{title}</h2>
<p className="text-sm text-muted-foreground sm:text-base">{intro}</p>
</div>
{/* A definition list, not a div soup: each card is genuinely a term and
its description, so screen readers announce the pairing. */}
<dl className="grid gap-6 sm:grid-cols-2">
{principles.map((principle) => (
<div key={principle.term} className="rounded-lg border border-border/70 bg-card p-5">
<dt className="text-sm font-semibold">{principle.term}</dt>
<dd className="mt-1.5 text-sm text-muted-foreground">{principle.description}</dd>
</div>
))}
</dl>
</div>
</section>
);
}
Dependencies
None. This block is self-contained — plain React and Tailwind utility classes. Paste the file and it renders.
Colours come from CSS variables (--background, --primary, --border) using the shadcn/ui token names, so the block adopts your palette rather than importing ours.