Skip to content

Corporate page

Written for an evaluator and a procurement reviewer at the same time.

Businessintermediatecorporateenterpriseb2bprocurement

Live preview

Open the full page
full widthLive preview — open it in a new tab for the full-height version.
Open the preview in a new tab

Source

This exact file renders the preview above.

import ProductSwitcherNavigation from '@/components/blocks/navigation/product-switcher'
import EnterpriseHeader from '@/components/blocks/headers/enterprise'
import GridCellLogos from '@/components/blocks/sections/logos/grid-cells'
import VersusTableComparison from '@/components/blocks/sections/comparison/versus-table'
import MigrationPathComparison from '@/components/blocks/sections/comparison/migration-path'
import DividedStatsBand from '@/components/blocks/sections/stats/divided-band'
import HiringTeam from '@/components/blocks/sections/team/hiring'
import RoutedContactCards from '@/components/blocks/sections/contact/routed-cards'
import MegaFooter from '@/components/blocks/footers/mega'

/**
 * Corporate page
 *
 * Written for two readers at once: an evaluator who wants the comparison, and
 * a procurement reviewer who wants the assurances. The routed contact cards
 * near the end exist because those two readers need different inboxes.
 */
export default function CorporatePattern() {
  return (
    <>
      <ProductSwitcherNavigation />
      <main>
        <EnterpriseHeader />
        <GridCellLogos />
        <VersusTableComparison />
        <DividedStatsBand />
        <MigrationPathComparison />
        <HiringTeam />
        <RoutedContactCards />
      </main>
      <MegaFooter />
    </>
  )
}

components/patterns/corporate.tsx

import ProductSwitcherNavigation from '@/components/blocks/navigation/product-switcher'
import EnterpriseHeader from '@/components/blocks/headers/enterprise'
import GridCellLogos from '@/components/blocks/sections/logos/grid-cells'
import VersusTableComparison from '@/components/blocks/sections/comparison/versus-table'
import MigrationPathComparison from '@/components/blocks/sections/comparison/migration-path'
import DividedStatsBand from '@/components/blocks/sections/stats/divided-band'
import HiringTeam from '@/components/blocks/sections/team/hiring'
import RoutedContactCards from '@/components/blocks/sections/contact/routed-cards'
import MegaFooter from '@/components/blocks/footers/mega'

/**
 * Corporate page
 *
 * Written for two readers at once: an evaluator who wants the comparison, and
 * a procurement reviewer who wants the assurances. The routed contact cards
 * near the end exist because those two readers need different inboxes.
 */
export default function CorporatePattern() {
  return (
    <>
      <ProductSwitcherNavigation />
      <main>
        <EnterpriseHeader />
        <GridCellLogos />
        <VersusTableComparison />
        <DividedStatsBand />
        <MigrationPathComparison />
        <HiringTeam />
        <RoutedContactCards />
      </main>
      <MegaFooter />
    </>
  )
}

components/blocks/headers/enterprise.tsx

import Link from 'next/link'
import { ArrowRight, Lock, ShieldCheck, FileCheck2 } from 'lucide-react'
import { ButtonLink } from '@/components/ui/button'
import { Container } from '@/components/ui/layout'

/**
 * Enterprise header
 *
 * Two actions of equal weight — "talk to sales" and "read the security brief"
 * — because enterprise buyers arrive with two different jobs. The assurance
 * strip below carries the certifications that would otherwise be buried three
 * clicks deep.
 */
const assurances = [
  { icon: ShieldCheck, label: 'SOC 2 Type II', detail: 'Audited annually' },
  { icon: Lock, label: 'SSO & SCIM', detail: 'Okta, Entra, Google' },
  { icon: FileCheck2, label: 'DPA available', detail: 'EU and UK residency' },
]

export default function EnterpriseHeader() {
  return (
    <header className="border-b border-line bg-canvas">
      <Container className="py-section">
        <div className="grid gap-10 lg:grid-cols-[1.15fr_1fr] lg:items-center lg:gap-16">
          <div>
            <p className="label-caps text-ink-subtle">For organisations</p>
            <h1 className="display-type mt-4 text-3xl leading-tight font-semibold text-ink-strong sm:text-4xl lg:text-5xl">
              A design system your security review will actually pass.
            </h1>
            <p className="mt-5 max-w-xl text-md text-ink-muted">
              Self-hosted, no telemetry, no third-party runtime. Everything ships as source you own
              and can audit.
            </p>
            <div className="mt-8 flex flex-wrap gap-3">
              <ButtonLink
                href="/forms/sales-inquiry"
                size="lg"
                trailingIcon={<ArrowRight className="size-4" />}
              >
                Talk to sales
              </ButtonLink>
              <ButtonLink href="/docs/installation" size="lg" variant="outline">
                Read the technical brief
              </ButtonLink>
            </div>
          </div>

          <dl className="flex flex-col divide-y divide-[var(--color-border-subtle)] rounded-xl border border-line bg-surface">
            {assurances.map((item) => {
              const Icon = item.icon
              return (
                <div key={item.label} className="flex items-start gap-3.5 p-5">
                  <span className="mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-md bg-accent-soft text-accent-soft-ink">
                    <Icon className="size-4.5" aria-hidden="true" />
                  </span>
                  <div>
                    <dt className="text-sm font-semibold text-ink-strong">{item.label}</dt>
                    <dd className="mt-0.5 text-xs text-ink-muted">{item.detail}</dd>
                  </div>
                </div>
              )
            })}
          </dl>
        </div>
      </Container>

      <div className="border-t border-line bg-surface-sunken">
        <Container className="flex flex-wrap items-center justify-between gap-3 py-4">
          <p className="text-sm text-ink-muted">
            Procurement questions? We answer security questionnaires in five working days.
          </p>
          <Link
            href="/forms/quote-request"
            className="text-sm font-medium text-accent underline underline-offset-4"
          >
            Request a quote
          </Link>
        </Container>
      </div>
    </header>
  )
}

components/blocks/sections/comparison/versus-table.tsx

import { Check, Minus, X } from 'lucide-react'
import { Container } from '@/components/ui/layout'
import { Badge } from '@/components/ui/badge'
import { Table } from '@/components/ui/table'

/**
 * Competitive comparison table
 *
 * A three-way comparison against approaches rather than named competitors —
 * which keeps the section honest and stops it ageing badly. Every cell is
 * icon + hidden text, so the answer is never conveyed by a glyph alone.
 */
interface Row {
  id: string
  criterion: string
  foundry: 'yes' | 'no' | 'partial'
  library: 'yes' | 'no' | 'partial'
  scratch: 'yes' | 'no' | 'partial'
}

const rows: Row[] = [
  {
    id: 'r1',
    criterion: 'You own and can edit the source',
    foundry: 'yes',
    library: 'no',
    scratch: 'yes',
  },
  {
    id: 'r2',
    criterion: 'Accessible patterns out of the box',
    foundry: 'yes',
    library: 'yes',
    scratch: 'no',
  },
  {
    id: 'r3',
    criterion: 'No runtime styling dependency',
    foundry: 'yes',
    library: 'partial',
    scratch: 'yes',
  },
  {
    id: 'r4',
    criterion: 'Complete page patterns included',
    foundry: 'yes',
    library: 'no',
    scratch: 'no',
  },
  {
    id: 'r5',
    criterion: 'Upgrades arrive automatically',
    foundry: 'no',
    library: 'yes',
    scratch: 'no',
  },
  { id: 'r6', criterion: 'Time to first screen', foundry: 'yes', library: 'yes', scratch: 'no' },
]

function Answer({ value }: { value: Row['foundry'] }) {
  if (value === 'yes') {
    return (
      <>
        <Check className="mx-auto size-4 text-success" aria-hidden="true" />
        <span className="sr-only">Yes</span>
      </>
    )
  }
  if (value === 'partial') {
    return (
      <>
        <Minus className="mx-auto size-4 text-warning" aria-hidden="true" />
        <span className="sr-only">Partly</span>
      </>
    )
  }
  return (
    <>
      <X className="mx-auto size-4 text-ink-subtle" aria-hidden="true" />
      <span className="sr-only">No</span>
    </>
  )
}

export default function VersusTableComparison() {
  return (
    <section className="border-b border-line bg-canvas py-section">
      <Container>
        <div className="max-w-2xl">
          <h2 className="display-type text-2xl font-semibold text-ink-strong sm:text-3xl">
            Three ways to get a component set.
          </h2>
          <p className="mt-3 text-md text-ink-muted">
            Compared against approaches rather than named products, so the table stays true as the
            market changes.
          </p>
        </div>

        <div className="mt-10">
          <Table
            caption="Foundry compared with an installed component library and building from scratch"
            rows={rows}
            rowKey={(row) => row.id}
            columns={[
              {
                key: 'criterion',
                header: 'Criterion',
                width: '46%',
                cell: (row) => <span className="text-ink">{row.criterion}</span>,
              },
              {
                key: 'foundry',
                header: (
                  <span className="flex items-center justify-center gap-2">
                    Foundry{' '}
                    <Badge size="sm" tone="accent">
                      This
                    </Badge>
                  </span>
                ),
                align: 'center',
                cell: (row) => <Answer value={row.foundry} />,
              },
              {
                key: 'library',
                header: 'Installed library',
                align: 'center',
                cell: (row) => <Answer value={row.library} />,
              },
              {
                key: 'scratch',
                header: 'From scratch',
                align: 'center',
                cell: (row) => <Answer value={row.scratch} />,
              },
            ]}
          />
        </div>

        <p className="mt-4 text-xs text-ink-subtle">
          Foundry deliberately does not upgrade automatically. Owning the source means owning the
          changes.
        </p>
      </Container>
    </section>
  )
}

Demo source — adapt to your project. Foundry is not published as a package.

Usage

The routed contact cards near the end exist because the two readers this page serves need different inboxes.

  • Put the assurances in the hero. Burying compliance three clicks deep costs deals.
  • Include a comparison row you lose; it is what makes the rest credible.

Variants and states

Every entry below is a genuine difference in behaviour or layout, and every one of them is visible in the preview above.

  • Workspace switcher navigation
  • Assurance-led hero
  • Competitive and migration comparisons
  • Routed contact cards

Accessibility

Comparison tables
Every cell pairs an icon with hidden text, so no answer depends on a glyph.
Named routes
Each contact card states its purpose and response time as text.

Foundry implements published ARIA patterns and is tested against them. No WCAG certification is claimed — see the accessibility documentation for what is and is not covered.