DesignBlocs UI Library

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
Preview
Open ↗
Leader Profile — previewLoading

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;