We are building the surface care teams live in all day. Small teams, long horizons, and work you can point at a year from now.
42 people, 9 countries
Four-day summer weeks, a real budget for craft, and quiet hours the whole company keeps.
Nothing here fits, but you think you belong with us?
Send an open applicationA light editorial careers section with a monospace eyebrow over a hairline rule, a two-column heading, and a sticky culture photo with a gradient caption beside team filter pills and hairline job rows showing location, contract type, and a hover arrow.
Careers section with a monospace eyebrow over a hairline rule and a two-column heading, then a sticky culture photo beside a filterable role list: team pills carrying live counts above hairline rows that pair the job title and team with location, contract type, and a hover arrow.
Free block
This block is free. No license or account is required: install it with the CLI and use it in unlimited projects.
Radix flavor
npx shadcn add "https://ui.beste.co/r/careers51"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/careers51"This installs the block to components/beste/block/careers51.tsx plus the badge23 and button21 components it uses for the eyebrow and the closing action.
The installed file exports careers51Demo alongside the block: the exact props behind the preview above. Spread it to get a working careers list in one line.
import { Careers51, careers51Demo } from "@/components/beste/block/careers51";
export default function CareersPage() {
return <Careers51 {...careers51Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Careers51 } from "@/components/beste/block/careers51";
export default function CareersPage() {
return (
<Careers51
badge={{ label: "Careers" }}
heading="Open roles"
description="Small teams, long horizons, and work you can point at a year from now."
allLabel="All roles"
media={{
image: { src: "/images/studio.jpg", alt: "The team around a laptop" },
title: "42 people, 9 countries",
description: "Four-day summer weeks and a real budget for craft.",
}}
items={[
{
title: "Senior Product Designer",
team: "Design",
location: "Remote, Europe",
type: "Full-time",
href: "/careers/senior-product-designer",
},
{
title: "Backend Engineer",
team: "Engineering",
location: "Berlin, hybrid",
type: "Full-time",
href: "/careers/backend-engineer",
},
]}
footnote={{
label: "Nothing here fits?",
button: { label: "Send an open application", href: "/careers/open" },
}}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string } | – | Monospace eyebrow above the hairline rule, rendered via Badge23 |
heading | string | – | Section heading in the left column |
description | string | – | Supporting paragraph, right-aligned from md up |
media | Media | – | Sticky photo column on the left, with an optional caption over a gradient |
allLabel | string | – | Label of the first filter pill, the one that clears the team filter |
items | Role[] | [] | Job rows, and the source of the team filter list |
footnote | { label: string; button: ActionLink } | – | Closing line and outline button under the list |
className | string | – | Extra classes for the outer <section> |
type ActionLink = { label: string; href: string };
type Media = {
image: { src: string; alt: string };
title?: string;
description?: string;
};
type Role = {
title: string;
team: string;
location: string;
type: string;
href: string;
};items[].team through a Set, so a team appears exactly once and in first-seen order, and each pill's count is recomputed from items on every render.useState holding the active team string. The empty string is the "everything" state, which is why allLabel sits on a pill whose value is "" and why its count is always items.length.lg:sticky lg:top-24 lg:self-start, so on desktop the photo stays in place while a long role list scrolls past it; below lg it collapses into a h-64 band above the list, sm:h-80.media.title or media.description is set. Without either, the gradient scrim is skipped too and the image shows clean.next/link wrapping the whole row, so the entire strip is the hit target. The arrow's hover nudge and the title's colour change are driven from a single named group (group/careers51) on that link.careers50
Centered careers intro with eyebrow, highlighted heading and supporting copy above a three-image gallery — one wide frame beside two portraits.
careers58
A careers section: a serif heading that settles in word by word, an intro, a pill action and a photograph drifting inside its frame on the left, beside ruled open roles with serif titles and small-caps type and place that lift an arrow on hover, and a note on how applications are answered.
careers57
A short roles list where the pay band sits on the row rather than behind an application, with a written empty state for when nothing is open and a speculative line underneath.