Vier cijfers in een bento-raster: één groot vlak op --primary (label, groot getal, toelichting, schuine arcering naar de hoek), een groeikaart met staafjes, een klein telvlak en een beoordelingsvlak met glyph. Smal stapelt alles; breed 6 kolommen × 2.
Marktaandeel
64%
Toonaangevend in cloud-infrastructuur voor snelgroeiende start-ups.
Groei
+240%
12
Awards
4,9 / 5,0
Beoordelingen van klanten
blocks/stats/stats-bento.tsx
/**
* StatsBento — vier cijfers in een bento-raster: één groot vlak op --primary
* (label, groot getal, toelichting, met een schuine arcering die naar de
* hoek uitvloeit), een groeikaart met een rij staafjes, een klein telvlak en
* een beoordelingsvlak met glyph. Smal stapelt alles; breed 6 kolommen × 2.
*
* Geoogst uit 21st.dev Stats Bento (uilayout): de repeating-linear-gradient
* met #808080 → --primary-foreground op lage dekking, vaste teksten
* ('Market Share 64%', 'G2 Peer Reviews') → props, size-10/★ → glyph-slot.
* Statisch; de staafjes zijn hoogtes in % (geen animatie).
*/
import type * as React from "react";
export interface StatsBentoProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
/** Het grote vlak. */
main: { label: string; value: string; text?: string };
/** De groeikaart: getal + staafjes (0–100). */
trend?: { label: string; value: string; bars?: readonly number[] };
/** Het kleine telvlak. */
count?: { value: string; label: string };
/** Het beoordelingsvlak. */
rating?: { value: string; label: string; glyph?: React.ReactNode };
}
export function StatsBento({ main, trend, count, rating, className, ...rest }: StatsBentoProps) {
return (
<section {...rest} className={["fp-bento", className].filter(Boolean).join(" ")}>
<div className="fp-bento__vlak fp-bento__vlak--hoofd">
<span className="fp-bento__arcering" aria-hidden="true" />
<div>
<span className="fp-bento__label fp-bento__label--pil">{main.label}</span>
<p className="fp-bento__groot">{main.value}</p>
</div>
{main.text && <p className="fp-bento__tekst">{main.text}</p>}
</div>
{trend && (
<div className="fp-bento__vlak fp-bento__vlak--trend">
<div>
<p className="fp-bento__label">{trend.label}</p>
<p className="fp-bento__getal">{trend.value}</p>
</div>
{trend.bars && (
<div className="fp-bento__staafjes" aria-hidden="true">
{trend.bars.map((h, i) => (
<i key={i} style={{ ["--h" as string]: `${Math.max(0, Math.min(100, h))}%` } as React.CSSProperties} />
))}
</div>
)}
</div>
)}
{count && (
<div className="fp-bento__vlak fp-bento__vlak--tel">
<p className="fp-bento__getal">{count.value}</p>
<p className="fp-bento__label">{count.label}</p>
</div>
)}
{rating && (
<div className="fp-bento__vlak fp-bento__vlak--score">
<span className="fp-bento__glyph" aria-hidden="true">{rating.glyph ?? "★"}</span>
<div>
<p className="fp-bento__score">{rating.value}</p>
<p className="fp-bento__label fp-bento__label--klein">{rating.label}</p>
</div>
</div>
)}
</section>
);
}
blocks/stats/stats.css
/** StatsBento — importeren in de app-root (registry-site: app/globals.css). */
.fp-bento { display: grid; grid-template-columns: 1fr; gap: 1rem; width: 100%; max-width: 72rem; margin: 0 auto; box-sizing: border-box; color: var(--foreground); }
@media (min-width: 48rem) {
.fp-bento { grid-template-columns: repeat(6, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); }
.fp-bento__vlak--hoofd { grid-column: span 3; grid-row: span 2; }
.fp-bento__vlak--trend { grid-column: span 3; }
.fp-bento__vlak--tel { grid-column: span 1; }
.fp-bento__vlak--score { grid-column: span 2; }
}
.fp-bento__vlak { position: relative; overflow: hidden; box-sizing: border-box; border-radius: var(--radius-lg); }
.fp-bento__vlak--hoofd { display: flex; flex-direction: column; justify-content: space-between; gap: 2rem; padding: 2.5rem; background: var(--primary); color: var(--primary-foreground); }
/* Schuine arcering die naar de rechterbovenhoek uitvloeit. */
.fp-bento__arcering {
position: absolute; inset: 0; pointer-events: none; opacity: 0.3;
background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--primary-foreground) 50%, transparent) 0 1px, transparent 1px 10px);
-webkit-mask-image: radial-gradient(ellipse 80% 50% at 100% 0%, black 70%, transparent 110%); mask-image: radial-gradient(ellipse 80% 50% at 100% 0%, black 70%, transparent 110%);
}
.fp-bento__label { margin: 0 0 0.25rem; font: inherit; font-size: var(--text-label); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-foreground); }
.fp-bento__label--pil { display: inline-block; margin: 0 0 1.5rem; padding: 0.25rem 0.75rem; border-radius: 999px; font-size: var(--text-label); background: color-mix(in srgb, var(--primary-foreground) 10%, transparent); color: color-mix(in srgb, var(--primary-foreground) 60%, transparent); }
.fp-bento__label--klein { margin: 0.25rem 0 0; letter-spacing: 0; text-transform: none; }
.fp-bento__groot { position: relative; margin: 0; font: inherit; font-size: var(--text-display); line-height: 1; letter-spacing: -0.04em; }
.fp-bento__tekst { position: relative; margin: 0; max-width: 20rem; font: inherit; font-size: var(--text-body-sm); line-height: 1.5; color: color-mix(in srgb, var(--primary-foreground) 60%, transparent); }
.fp-bento__vlak--trend { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 2rem; background: var(--muted); border: 1px solid var(--border); }
.fp-bento__getal { margin: 0; font: inherit; font-size: var(--text-data); line-height: 1.1; letter-spacing: -0.02em; }
.fp-bento__staafjes { display: flex; align-items: flex-end; gap: 0.25rem; height: 2rem; }
.fp-bento__staafjes i { display: block; width: 0.375rem; height: var(--h, 50%); border-radius: 999px; background: var(--foreground); }
.fp-bento__vlak--tel { display: flex; flex-direction: column; justify-content: center; text-align: center; padding: 1.5rem; background: var(--card); color: var(--card-foreground, var(--foreground)); border: 1px solid var(--border); }
.fp-bento__vlak--tel .fp-bento__getal { font-size: var(--text-data); }
.fp-bento__vlak--score { display: flex; align-items: center; gap: 1rem; padding: 1.5rem; background: var(--muted); }
.fp-bento__glyph { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 2.5rem; height: 2.5rem; border-radius: 50%; background: var(--background); color: var(--foreground); font-size: var(--text-h3); font-weight: 600; box-shadow: var(--shadow-overlay); }
.fp-bento__score { margin: 0; font: inherit; font-size: var(--text-body-sm); line-height: 1; }