A company update held in one dark panel, pairing a light heading and four supporting figures over a hairline rule with a bordered column that floats a live press contact card.
A company update held in one dark panel, pairing a light heading and four supporting figures over a hairline rule with a bordered column that floats a live press contact card.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/news39?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/news39?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/news39.tsx, the card31 person piece it floats in the right column (installed to components/beste/piece/card31.tsx), and the badge23 and button21 components it uses for the eyebrow and the actions.
The installed file exports news39Demo alongside the block: the exact props behind the preview above. Spread it to get a working announcement in one line.
import { News39, news39Demo } from "@/components/beste/block/news39";
export default function CompanyNewsPage() {
return <News39 {...news39Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Card31 } from "@/components/beste/piece/card31";
import { News39 } from "@/components/beste/block/news39";
export default function CompanyNewsPage() {
return (
<News39
badge={{ label: "Company news" }}
kicker="02 May 2026"
heading="We are profitable, and we are staying at eighteen people"
description="No second raise, no growth target we do not believe, and no plan to hire a sales team."
figures={[
{ value: "18", label: "people, nine of whom write code" },
{ value: "Q3 2025", label: "the quarter we stopped losing money" },
]}
buttons={[
{ label: "Read the full note", href: "/news/profitable" },
{ label: "See the company facts", href: "/about" },
]}
contactTitle="Writing about this?"
contactBody="Speak to a founder rather than to a communications team."
media={
<Card31
avatar={{ src: "/people/elena.jpg", alt: "Portrait of Elena Rourke" }}
name="Elena Rourke"
role="Co-founder, press contact"
status="Usually replies same day"
availability="free"
rows={[{ label: "Email", value: "press@example.com" }]}
/>
}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Eyebrow at the top of the panel, retoned for the dark surface |
kicker | string | – | Date line above the heading |
heading | string | – | Announcement heading |
description | string | – | Supporting paragraph, capped at max-w-xl |
figures | Figure[] | [] | Supporting numbers under a hairline |
buttons | ActionLink[] | [] | Actions, first solid and the rest outlined |
contactTitle | string | – | Heading under the press card |
contactBody | string | – | Paragraph under that heading |
media | ReactNode | – | Live asset in the right column, card31 in the demo |
className | string | – | Extra classes for the outer section |
type ActionLink = {
label: string;
href: string;
};
type Figure = {
value: string;
label: string;
};bg-foreground inside the normal page container, so it reads as an inverted card rather than a full-bleed band. Every text token inside is a fixed background value, since the surface is fixed.Badge23 is retoned inline with border-background/30 text-background/70, since the component's own tones assume a light surface.border-background/20 rather than border-border, which is close to invisible on an inverted surface.primary, later ones are outline plus an added border-background/30 so they read on the dark panel.figures accepts any string, so a value can be a count like "18" or a period like "Q3 2025". Because the mix is expected, the figures do not use tabular-nums.sm regardless of count, so four is the number the layout is tuned for.lg:grid-cols-5 split, three columns of copy against two of media. Below lg it stacks and the divider flips from lg:border-l to border-t.justify-center, so the card and contact copy stay centered against a copy column whose height varies with the number of figures.news38
A single announcement laid out like an article, with a standfirst, a full-bleed captioned photo band, a reading column, and a sticky rail carrying the key facts and related entries.
news21
Retro airport departure board style news ticker with character-by-character flip animation and auto-rotating headlines.
news9
Four-column news card grid with gradient overlays, category badges, and author info.
news11
Masonry-style news grid with large, medium, and small article cards. Dynamic sizing based on article importance.