# Contact Departments and Offices

> Contact section in two intro-column rows: department cards with mailto and tel links, then office cards with street addresses. Built from Section, Card and DescriptionList with Orbcore sample details.

A shadcn/ui block from the [@01orbital](https://01orbital.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/01orbital/contact-offices-01).

- Page, with a live preview: https://shadcn.exchange/r/01orbital/contact-offices-01
- Screenshot: https://shadcn.exchange/shot/01orbital/contact-offices-01/light.png
- Registry item: https://01orbital.dev/r/contact-offices-01.json
- Categories: contact
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/01orbital/contact-offices-01.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `card`, `@01orbital/description-list`, `@01orbital/features`, `@01orbital/heading`, `@01orbital/section`

## Files

### `blocks/contact/contact-offices-01/index.tsx`

```tsx
import {
  DescriptionList,
  DescriptionListDetails,
  DescriptionListItem,
  DescriptionListTerm,
} from "@/components/editorial/description-list"
import {
  Feature,
  FeatureGroup,
} from "@/components/editorial/features"
import { Heading } from "@/components/editorial/heading"
import {
  Section,
  SectionColumns,
  SectionContent,
  SectionDescription,
  SectionHeader,
  SectionTitleGroup,
} from "@/components/editorial/section"
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"

// The copy: change text here, not in the markup.
const COPY = {
  title: "Get in touch",
  body: "One address per question, so the right people read it first. Replies come within one working day.",
  emailTerm: "Email",
  phoneTerm: "Phone number",
} as const

const LOCATIONS = {
  title: "Locations",
  body: "Four studios in four time zones. Visits are by appointment; write to the studio first.",
} as const

const DEPARTMENTS = [
  {
    name: "Collaborate",
    email: "collaborate@orbcore.example",
    phone: "+1 (555) 905-2345",
  },
  { name: "Press", email: "press@orbcore.example", phone: "+1 (555) 905-3456" },
  {
    name: "Join our team",
    email: "careers@orbcore.example",
    phone: "+1 (555) 905-4567",
  },
  {
    name: "Say hello",
    email: "hello@orbcore.example",
    phone: "+1 (555) 905-5678",
  },
] as const

const OFFICES = [
  { name: "Portland", address: ["301 Meridian Way", "Portland, OR 97209"] },
  { name: "Austin", address: ["1450 Halo Street", "Austin, TX 78702"] },
  { name: "Halifax", address: ["62 Eclipse Avenue", "Halifax, NS B3J 1A1"] },
  { name: "Edinburgh", address: ["9 Starling Close", "Edinburgh EH1 2AB"] },
] as const

// A tel: link carries only the digits and the leading plus.
const tel = (phone: string) => `tel:${phone.replace(/[^\d+]/g, "")}`

export default function ContactOffices01() {
  return (
    <Section>
      <SectionContent>
        <section>
          <SectionColumns variant="intro">
            <SectionHeader size="sm">
              <SectionTitleGroup>
                <Heading>{COPY.title}</Heading>
              </SectionTitleGroup>
              <SectionDescription>{COPY.body}</SectionDescription>
            </SectionHeader>
            <FeatureGroup cols={2} gap="sm" className="@sm:grid-cols-2">
              {DEPARTMENTS.map((department) => (
                <Feature key={department.name}>
                  <Card>
                    <CardHeader>
                      <CardTitle role="heading" aria-level={3}>
                        {department.name}
                      </CardTitle>
                    </CardHeader>
                    <CardContent>
                      <DescriptionList className="gap-1">
                        <DescriptionListItem className="justify-start">
                          <DescriptionListTerm className="sr-only">
                            {COPY.emailTerm}
                          </DescriptionListTerm>
                          <DescriptionListDetails>
                            <a
                              href={`mailto:${department.email}`}
                              className="font-semibold underline-offset-4 hover:underline"
                            >
                              {department.email}
                            </a>
                          </DescriptionListDetails>
                        </DescriptionListItem>
                        <DescriptionListItem className="justify-start">
                          <DescriptionListTerm className="sr-only">
                            {COPY.phoneTerm}
                          </DescriptionListTerm>
                          <DescriptionListDetails className="text-muted-foreground">
                            <a
                              href={tel(department.phone)}
                              className="underline-offset-4 hover:underline"
                            >
                              {department.phone}
                            </a>
                          </DescriptionListDetails>
                        </DescriptionListItem>
                      </DescriptionList>
                    </CardContent>
                  </Card>
                </Feature>
              ))}
            </FeatureGroup>
          </SectionColumns>
        </section>
        <section>
          <SectionColumns variant="intro">
            <SectionHeader size="sm">
              <SectionTitleGroup>
                <Heading>{LOCATIONS.title}</Heading>
              </SectionTitleGroup>
              <SectionDescription>{LOCATIONS.body}</SectionDescription>
            </SectionHeader>
            <FeatureGroup cols={2} gap="sm" className="@sm:grid-cols-2">
              {OFFICES.map((office) => (
                <Feature key={office.name}>
                  <Card>
                    <CardHeader>
                      <CardTitle role="heading" aria-level={3}>
                        {office.name}
                      </CardTitle>
                    </CardHeader>
                    <CardContent>
                      <address className="grid gap-1 text-sm/6 text-muted-foreground not-italic">
                        {office.address.map((line) => (
                          <p key={line}>{line}</p>
                        ))}
                      </address>
                    </CardContent>
                  </Card>
                </Feature>
              ))}
            </FeatureGroup>
          </SectionColumns>
        </section>
      </SectionContent>
    </Section>
  )
}
```
