Leader Profile
One person given a page rather than a card: a ruled section heading, then name and particulars, a tall 4:5 portrait, and the writing beside it with its first line set as a statement.
- Team
- No dependencies
- MIT
- Google Sans Flex · SIL Open Font License 1.1
Copy the code
The whole component, in one file. Yours from the moment you paste it.
Install it
Straight into a project with a shadcn setup — no account, no limit.
npx shadcn@latest add https://designblocs.com/r/leader-profile.json Hand it to an agent
A prompt for Claude Code, Cursor or v0 that adapts the component to your codebase rather than pasting it in raw.
src/components/ui-library/blocks/LeaderProfile.tsx
/**
* LeaderProfile — one person, given a page rather than a card.
*
* A ruled section heading, then three columns: who they are on the left with a
* definition list of their particulars, a tall 4:5 portrait in the middle, and
* the writing on the right with its first line set as a statement. It is the
* shape you want when a company has one founder worth introducing properly,
* instead of a grid of headshots.
*
* The portrait is a plain `<img>` and the component ships no image: pass `src`,
* or leave it and the frame stands as a flat colour, which is what it does
* while a real photograph is being commissioned.
*
* SELF-CONTAINED: imports React and nothing else. Note in particular that the
* heading's size, weight and tracking are declared here rather than inherited
* from a host's `--section-heading-*` variables — a component that reads
* variables it does not define renders at the wrong size in someone else's
* project, silently.
*/
export interface LeaderDetail {
term: string;
value: string;
}
export interface LeaderProfileProps {
/** The section's own heading, above the rule. */
heading?: string;
/** The small label over the name — "Founder / CEO". */
eyebrow?: string;
name?: string;
details?: LeaderDetail[];
/** The opening line, set larger than the rest. */
lead?: string;
/** Paragraphs after the lead. */
body?: string[];
portrait?: { src: string; alt: string };
}
const DEFAULTS = {
heading: "Our Leadership",
eyebrow: "Founder / CEO",
name: "Durga Das",
details: [
{ term: "Role", value: "Founder & Chief Executive Officer" },
{ term: "Focus", value: "Water technology and scalable systems" },
] as LeaderDetail[],
lead: "Building new possibilities for how the world accesses water.",
body: [
"As Founder and CEO, Durga Das leads the company’s work to translate advanced water technology into dependable systems for people, organisations, and communities.",
"Her approach brings long-term vision together with practical execution — shaping technology around the places and people it is intended to serve.",
],
portrait: undefined as { src: string; alt: string } | undefined,
};
const STYLES = `
[data-block="LeaderProfile"],
[data-block="LeaderProfile"] :is(h2, h3, p, dt, dd) {
font-family: "Google Sans Flex", "Inter Variable", Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
}
[data-block="LeaderProfile"] {
--lp-ink: #10171c;
--lp-body: rgb(16 23 28 / 64%);
--lp-muted: rgb(16 23 28 / 50%);
--lp-rule: rgb(16 23 28 / 22%);
--lp-ground: #fff;
--lp-frame: #cad8d4;
--lp-gutter: 48px;
/* Declared, not inherited — see the note at the top of the file. */
--lp-heading: clamp(40px, 3.4vw, 64px);
position: relative;
isolation: isolate;
overflow: hidden;
padding: 168px var(--lp-gutter) 0;
color: var(--lp-ink);
background: var(--lp-ground);
}
[data-block="LeaderProfile"][data-tone="dark"] {
--lp-ink: #f4f8fa;
--lp-body: rgb(244 248 250 / 68%);
--lp-muted: rgb(244 248 250 / 52%);
--lp-rule: rgb(244 248 250 / 24%);
--lp-ground: #0b1114;
--lp-frame: #1b2a2d;
}
[data-block="LeaderProfile"] .lp-head {
padding-bottom: 40px;
border-bottom: 1px solid var(--lp-rule);
}
[data-block="LeaderProfile"] .lp-head h2 {
margin: 0;
font-size: var(--lp-heading);
font-weight: 400;
line-height: 0.98;
letter-spacing: -0.045em;
}
[data-block="LeaderProfile"] .lp-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
padding-top: 34px;
}
[data-block="LeaderProfile"] .lp-identity,
[data-block="LeaderProfile"] .lp-content {
min-width: 0;
padding-top: 2px;
}
[data-block="LeaderProfile"] .lp-identity {
display: flex;
flex-direction: column;
align-items: flex-start;
}
[data-block="LeaderProfile"] .lp-eyebrow {
margin: 0 0 12px;
color: var(--lp-muted);
font-size: 13px;
font-weight: 500;
line-height: 1.2;
letter-spacing: 0.01em;
text-transform: uppercase;
}
[data-block="LeaderProfile"] .lp-name {
max-width: 9ch;
margin: 0;
font-size: clamp(34px, 2.6vw, 50px);
font-weight: 400;
line-height: 0.98;
letter-spacing: -0.04em;
}
[data-block="LeaderProfile"] .lp-details {
width: 100%;
max-width: 430px;
margin: 48px 0 0;
border-top: 1px solid var(--lp-rule);
}
[data-block="LeaderProfile"] .lp-details > div {
display: grid;
grid-template-columns: 72px minmax(0, 1fr);
align-items: center;
min-height: 64px;
border-bottom: 1px solid var(--lp-rule);
}
[data-block="LeaderProfile"] .lp-details dt {
color: var(--lp-muted);
font-size: 13px;
font-weight: 500;
line-height: 1.2;
letter-spacing: 0.01em;
text-transform: uppercase;
}
[data-block="LeaderProfile"] .lp-details dd {
margin: 0;
font-size: 16px;
line-height: 1.3;
letter-spacing: -0.015em;
}
[data-block="LeaderProfile"] .lp-portrait {
position: relative;
min-width: 0;
margin: 0;
overflow: hidden;
aspect-ratio: 4 / 5;
align-self: start;
background: var(--lp-frame);
}
[data-block="LeaderProfile"] .lp-portrait img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center top;
}
[data-block="LeaderProfile"] .lp-content {
display: flex;
flex-direction: column;
padding-right: clamp(0px, 1.2vw, 22px);
}
[data-block="LeaderProfile"] .lp-copy {
max-width: 590px;
color: var(--lp-body);
font-size: clamp(16px, 1.08vw, 19px);
line-height: 1.42;
letter-spacing: -0.018em;
}
[data-block="LeaderProfile"] .lp-copy p { margin: 0 0 24px; }
[data-block="LeaderProfile"] .lp-lead {
color: var(--lp-ink);
font-size: clamp(23px, 1.75vw, 32px);
font-weight: 400;
line-height: 1.12;
letter-spacing: -0.035em;
}
@media (max-width: 1100px) {
[data-block="LeaderProfile"] .lp-grid {
grid-template-columns: minmax(0, 0.85fr) minmax(420px, 1.15fr);
}
[data-block="LeaderProfile"] .lp-identity {
grid-column: 1 / -1;
padding-bottom: 28px;
}
[data-block="LeaderProfile"] .lp-eyebrow { width: 100%; }
[data-block="LeaderProfile"] .lp-content { padding-right: 12px; }
}
@media (max-width: 767px) {
[data-block="LeaderProfile"] {
--lp-gutter: 20px;
--lp-heading: clamp(25px, 7.8vw, 42px);
padding-top: 142px;
}
[data-block="LeaderProfile"] .lp-head { padding-bottom: 30px; }
[data-block="LeaderProfile"] .lp-grid {
display: flex;
flex-direction: column;
gap: 44px;
padding-top: 28px;
}
[data-block="LeaderProfile"] .lp-identity { padding-bottom: 0; }
/* The column flex made "align-self: start" collapse the portrait along the
cross axis, taking its aspect-ratio height to zero with it. */
[data-block="LeaderProfile"] .lp-portrait { width: 100%; align-self: stretch; }
[data-block="LeaderProfile"] .lp-content { padding-right: 0; }
[data-block="LeaderProfile"] .lp-copy { font-size: 17px; }
[data-block="LeaderProfile"] .lp-details { width: 100%; margin-top: 64px; }
}
`;
export function LeaderProfile(props: LeaderProfileProps & { tone?: "light" | "dark" }) {
const p = { ...DEFAULTS, ...props };
return (
<section data-block="LeaderProfile" data-tone={props.tone ?? "light"} aria-labelledby="leader-profile-title">
<style dangerouslySetInnerHTML={{ __html: STYLES }} />
<header className="lp-head">
<h2 id="leader-profile-title">{p.heading}</h2>
</header>
<div className="lp-grid">
<header className="lp-identity">
<p className="lp-eyebrow">{p.eyebrow}</p>
<h3 className="lp-name">{p.name}</h3>
<dl className="lp-details">
{p.details.map((detail) => (
<div key={detail.term}>
<dt>{detail.term}</dt>
<dd>{detail.value}</dd>
</div>
))}
</dl>
</header>
<figure className="lp-portrait">
{p.portrait && <img src={p.portrait.src} alt={p.portrait.alt} loading="lazy" decoding="async" />}
</figure>
<div className="lp-content">
<div className="lp-copy">
<p className="lp-lead">{p.lead}</p>
{p.body.map((paragraph) => (
<p key={paragraph.slice(0, 32)}>{paragraph}</p>
))}
</div>
</div>
</div>
</section>
);
}
/* A named export as well as the default, so a project that takes this file can
import it either way. */
export default LeaderProfile;