:root {
  --navy: #11273d;
  --navy-deep: #0a1d2d;
  --gold: #c7a56d;
  --gold-soft: #d9bf87;
  /* Gold at 37deg darkened until it clears 4.5:1 on white, paper AND stone.
     --gold is a FILL and a colour for dark grounds only; --gold-ink is the
     text colour on any light surface. */
  --gold-ink: #7b5e2f;
  --paper: #f4f1eb;
  --paper-strong: #ebe2d7;
  --stone: #e5dfd3;
  --text: #1f2a32;
  --muted: #59656f;
  --muted-light: #7a8a96;
  --line: rgba(17, 39, 61, 0.08);
  --line-dark: rgba(17, 39, 61, 0.16);
  --white: #ffffff;
  --shadow: 0 8px 24px rgba(13, 29, 45, 0.08);
  --shadow-lg: 0 16px 48px rgba(13, 29, 45, 0.12);

  /* ── Type: three roles, three faces ──────────────────────────────────────
     One family doing display, body and annotation is what made the old
     setting read as generic. Each face now does the job it was drawn for.

     Display  Archivo   — a grotesque with squared bowls and a short, dense
                          cap height. Holds the engineered bearing the system
                          asks for, and stays rigid at 3.5rem where a
                          geometric sans goes soft.
     Text     Public Sans — a Franklin-derived reading face. Bigger x-height
                          and narrower set than the display face, so long bios
                          and 345 Perspectives posts stay comfortable at 16px.
     Mono     IBM Plex Mono — the annotation voice. Diegetic only: docket
                          lines, reference labels, plate citations, eyebrows.
                          Never decoration (see DESIGN.md).

     Archivo and Public Sans share American-grotesque roots, so they set
     together without clashing; hierarchy comes from weight and tracking, not
     from a fight between two personalities. */
  --font-display: "Archivo", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-text: "Public Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Comfortable reading measure. `ch` is the width of "0", which in Public
     Sans runs ~24% wider than the average lowercase letter — so this value is
     NOT a character count. Measured on the rendered page, 60ch lands at ~74
     real characters, inside the 65-75 band where long-form reading holds up.
     Verify by measurement, not arithmetic, if the text face ever changes. */
  --measure: 60ch;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  font-size: 1rem;
  margin: 0;
  font-family: var(--font-text);
  background: var(--white);
  color: var(--text);
  line-height: 1.65;
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  display: block;
  max-width: 100%;
}

.container {
  width: min(1200px, calc(100% - 40px));
  margin: 0 auto;
}

.section-shell {
  padding: 90px 0;
}

.topbar {
  background: var(--navy-deep);
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.topbar-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  height: 18px;
}

.topbar a {
  color: var(--white);
}

/* The sticky header changes height on scroll, which removes 82px of flow.
   Scroll anchoring would compensate by moving scrollY, re-triggering the
   toggle and producing a blink. */
html,
body { overflow-anchor: none; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(255, 255, 255, 0.98);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(10px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
}

/* ---- Compact header on scroll -------------------------------------------
   .is-stuck is toggled by header-scroll.js past 60px. The utility bar
   collapses away and the brand + nav row halves in height, so the header
   goes from ~142px to ~60px while staying fully usable.
   Remove the two `transition` declarations below for an instant snap. */
.topbar {
  /* Decorative navy strip: the address/phone/email that used to sit here read
     oddly above the masthead and all of it is in the footer. */
  height: 18px;
  overflow: hidden;
  /* No transition: animating height/min-height/width thrashes layout on every
     frame of the scroll. The header snaps between its two sizes instead. */
}


.site-header.is-stuck .topbar {
  height: 0;
}

.site-header.is-stuck .nav-wrap {
  min-height: 60px;
}

.site-header.is-stuck .brand img {
  height: 40px;
}

/* Two marks, one shown at a time: the full logo with its tagline, and a
   wordmark-only version for the compacted header, where the tagline is too
   small to read. CSS cannot swap an <img src>, so both ship and the class
   toggles which is displayed — keeping the swap in the stylesheet alongside
   the rest of the .is-stuck sizing, as header-scroll.js intends. The compact
   mark is loading="lazy" and display:none until needed, so it is not fetched
   unless the visitor actually scrolls. */
.brand-logo-compact { display: none; }

.site-header.is-stuck .brand-logo-full { display: none; }

.site-header.is-stuck .brand-logo-compact { display: block; }

.site-header.is-stuck {
  box-shadow: 0 6px 20px rgba(0, 48, 73, 0.1);
}

/* The topbar is decorative once collapsed — keep it out of the tab order */
.site-header.is-stuck .topbar a {
  visibility: hidden;
}

@media (max-width: 980px) {
  .site-header.is-stuck .nav-wrap {
    min-height: 56px;
  }

  .site-header.is-stuck .brand img {
    height: 36px;
  }

  /* No mark swap on mobile. The wordmark-only version exists so the tagline
     does not shrink to an illegible smudge in the compacted desktop header,
     but the mobile header is already short and the logo already small, so
     swapping it mid-scroll just reads as the logo flickering. */
  .site-header.is-stuck .brand-logo-full { display: block; }

  .site-header.is-stuck .brand-logo-compact { display: none; }
}

.nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  /* 60px mark + 14px of air top and bottom. Tied to .brand img's height:
     change one and change the other. */
  min-height: 88px;
}

.brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

/* Sized by HEIGHT, not width: the height is what sets the masthead's optical
   weight against the nav row, and the mark's 1142x325 ratio then fixes the
   width at ~211px. The intrinsic width/height attributes stay on the <img>
   so the box is reserved before the file decodes (no layout shift). */
.brand img {
  height: 60px;
  width: auto;
}

.main-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 30px;
  margin-left: auto;
  margin-right: 18px;
  font-family: var(--font-display);
  font-size: 0.925rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--navy);
}

.main-nav > a,
.nav-dropdown > button {
  position: relative;
  display: inline-block;
}

.nav-dropdown > button {
  display: inline-flex;
  align-items: center;
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  cursor: pointer;
}

.nav-dropdown > button::before {
  content: "";
  display: inline-block;
  width: 0.42rem;
  height: 0.42rem;
  margin-left: 0.55rem;
  order: 2;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15rem) rotate(45deg);
}

.main-nav > a::after,
.nav-dropdown > button::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -8px;
  width: 100%;
  height: 2px;
  background: var(--gold);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.main-nav > a:hover::after,
.main-nav > a:focus-visible::after,
.nav-dropdown:hover > button::after,
.nav-dropdown:focus-within > button::after {
  opacity: 1;
}

.nav-dropdown {
  position: relative;
}

/* Hover bridge.
   The menu opens 18px below the trigger, and that gap belongs to neither the
   button nor the menu — so a pointer moving straight down toward the menu
   left .nav-dropdown, :hover went false, and the menu closed out from under
   it. This transparent strip spans the gap and is a child of .nav-dropdown,
   so the pointer never leaves the hover target in transit.

   It exists only while the menu is open (display:none otherwise), so it can
   never swallow clicks meant for the hero beneath the header. min-width
   matches the menu's so a diagonal path to the menu's outer edges is covered
   too. */
.nav-dropdown::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  min-width: 210px;
  height: 22px;              /* the 18px gap + slack */
  display: none;
}

.nav-dropdown:hover::after,
.nav-dropdown:focus-within::after {
  display: block;
}

.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 18px);
  left: 50%;
  z-index: 40;
  display: grid;
  min-width: 210px;
  padding: 10px;
  background: var(--white);
  border: 1px solid var(--line-dark);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

.nav-dropdown-menu a {
  padding: 10px 12px;
  white-space: nowrap;
}

.nav-dropdown-menu a:hover,
.nav-dropdown-menu a:focus-visible {
  background: var(--paper);
  color: var(--navy-deep);
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 22px;
  border: 2px solid transparent;
  font-family: var(--font-display);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: all 0.3s ease;
  cursor: pointer;
}

.button-primary {
  background: var(--gold);
  color: var(--navy-deep);
  border-color: var(--gold);
}

.button-primary:hover,
.button-primary:focus-visible {
  background: var(--gold-soft);
  box-shadow: 0 4px 12px rgba(199, 165, 109, 0.3);
  transform: translateY(-2px);
}

.button-secondary {
  background: transparent;
  color: var(--navy);
  border-color: var(--navy);
}

/* Buttons sitting side by side (Careers / Industries CTAs). Keeps a gap when
   they wrap onto separate lines on narrow screens. */
.button + .button {
  margin-left: 12px;
}

@media (max-width: 560px) {
  .button + .button {
    margin-left: 0;
    margin-top: 12px;
  }
}

/* On a dark panel the secondary button needs light strokes, not navy ones */
.section-shell[style*="--navy"] .button-secondary {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.6);
}

.section-shell[style*="--navy"] .button-secondary:hover {
  background: var(--white);
  color: var(--navy);
  border-color: var(--white);
}

.button-secondary:hover,
.button-secondary:focus-visible {
  background: var(--navy);
  color: var(--white);
  box-shadow: 0 4px 12px rgba(17, 39, 61, 0.2);
  transform: translateY(-2px);
}

.hero {
  /* photo removed; stops are opaque now that nothing sits behind them */
  background: linear-gradient(135deg, var(--navy-deep) 0%, var(--navy) 100%);
  min-height: 750px;
  display: flex;
  align-items: center;
  position: relative;
  padding: 0 20px;
}

.hero::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: radial-gradient(circle at top right, rgba(199, 165, 109, 0.08) 0%, transparent 50%);
  pointer-events: none;
}

.hero-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
  min-height: 750px;
  position: relative;
  z-index: 1;
  /* Mirrors .container, which every .hero-inner also carries. It has to be
     restated rather than inherited: both selectors are single-class, this
     rule comes later in the file, so a plain `width: 100%` here silently beat
     .container's 1200px cap and pinned the copy to .hero's 20px padding edge
     instead of the 120px gutter the logo and body content sit on.
     It cannot be dropped either -- .hero-inner is a flex item of .hero, so
     `width: auto` would shrink-to-fit instead of filling the gutter. */
  width: min(1200px, calc(100% - 40px));
  margin-inline: auto;
  padding: 60px 0;
}

.hero-copy {
  max-width: 680px;
  color: var(--white);
  padding: 40px 0;
  flex: 1;
}

.hero-panel {
  flex: 0 0 320px;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(199, 165, 109, 0.2);
  border-radius: 6px;
  padding: 32px 24px;
  color: rgba(255, 255, 255, 0.95);
}

.panel-header {
  margin-bottom: 28px;
  border-bottom: 1px solid rgba(199, 165, 109, 0.3);
  padding-bottom: 16px;
}

.panel-kicker {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 8px;
}

.panel-header h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.8rem;
  line-height: 1.1;
  margin: 0;
  color: var(--white);
}

.panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.panel-list li {
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(199, 165, 109, 0.15);
}

.panel-list li:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.panel-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 6px;
}

.panel-list strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--white);
}

.eyebrow,
.card-kicker {
  margin: 0 0 18px;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
}

/* Light grounds are the default (705 uses vs 373 on dark); base --gold and
   --gold-soft both fail AA on white/paper/stone, so text uses --gold-ink and
   dark containers opt back in below. */
.eyebrow,
.card-kicker {
  color: var(--gold-ink);
}

.hero .eyebrow,
.hero .card-kicker,
.archive-hero .eyebrow,
.archive-hero .card-kicker,
.stats-bar .eyebrow,
.site-footer .eyebrow,
.contact-directory .eyebrow,
.contact-directory .card-kicker,
.culture-cta-inner .eyebrow,
.culture-cta-inner .card-kicker,
.section-shell[style*="--navy"] .eyebrow,
.section-shell[style*="--navy"] .card-kicker {
  color: var(--gold-soft);
}

.accent {
  color: var(--gold-ink);
}

.hero .accent,
.stats-bar .accent,
.site-footer .accent,
.contact-directory .accent,
.culture-cta-inner .accent,
.section-shell[style*="--navy"] .accent {
  color: var(--gold-soft);
}

.hero-copy h1,
.intro-grid h2,
.section-title-wrap h2,
.purpose-copy h2,
.news-card h3,
.site-footer h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0;
}

.hero-copy h1 {
  font-size: clamp(2.6rem, 5vw, 4.2rem);
  line-height: 1;
  color: var(--white);
  max-width: 620px;
  font-weight: 700;
}

.lead {
  margin: 20px 0 0;
  font-size: clamp(1.2rem, 2vw, 1.8rem);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.96);
}

.lede-body {
  margin: 18px 0 0;
  max-width: 510px;
  color: rgba(255, 255, 255, 0.88);
  font-size: 1.05rem;
  line-height: 1.6;
}

.hero-actions {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 32px;
}

.stats-bar {
  background: linear-gradient(90deg, var(--navy-deep) 0%, var(--navy) 100%);
  padding: 48px 0;
  color: var(--white);
  border-top: 1px solid rgba(199, 165, 109, 0.2);
  border-bottom: 1px solid rgba(199, 165, 109, 0.2);
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
  text-align: center;
}

.stats-grid > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.stats-grid strong {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.4rem;
  line-height: 1;
  color: var(--gold);
  display: block;
}

.stats-grid span {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.8);
  font-weight: 500;
}

.section-title-wrap {
  margin-bottom: 32px;
}

.section-title-wrap h2,
.purpose-copy h2,
.intro-grid h2,
.news-card h3 {
  color: var(--navy);
}

.intro-grid h2,
.section-title-wrap h2,
.purpose-copy h2 {
  font-size: clamp(2.2rem, 3.8vw, 3.4rem);
}

.intro-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: center;
}

.intro-grid p:last-child {
  margin: 0;
  color: var(--muted);
  font-size: 1.06rem;
  line-height: 1.7;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
}

.service-card {
  display: flex;
  background: var(--white);
  border: 1px solid var(--line-dark);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: all 0.3s ease;
  border-radius: 6px;
}

.service-card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-4px);
  border-color: rgba(199, 165, 109, 0.3);
}

.service-media {
  position: relative;
  width: 36%;
  min-height: 100%;
}

.service-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.service-copy {
  flex: 1;
  padding: 32px 28px;
  display: flex;
  flex-direction: column;
}

.card-kicker {
  color: var(--gold-ink);
  margin-bottom: 12px;
  font-size: 0.75rem;
}

.service-copy h3 {
  font-size: 1.2rem;
  letter-spacing: -0.008em;
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.15;
  flex-grow: 1;
}

.text-link {
  display: inline-flex;
  align-items: center;
  margin-top: auto;
  margin-top: 12px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-ink);
  transition: all 0.3s ease;
  position: relative;
}

.text-link::after {
  content: "→";
  display: inline-block;
  margin-left: 6px;
  transition: transform 0.3s ease;
}

.text-link:hover::after,
.text-link:focus-visible::after {
  transform: translateX(4px);
}

.purpose {
  background: linear-gradient(180deg, var(--white) 0%, var(--paper) 100%);
  border-top: 1px solid var(--line-dark);
  border-bottom: 1px solid var(--line-dark);
}

.purpose-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 48px;
  align-items: center;
}

.purpose-copy {
  max-width: 620px;
}

.purpose-copy p {
  margin: 16px 0 0;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.7;
}

.purpose-copy p:last-of-type {
  margin-bottom: 24px;
}

.feature-list {
  list-style: none;
  margin: 24px 0;
  padding: 0;
}

.feature-list li {
  position: relative;
  padding-left: 24px;
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 1.02rem;
  line-height: 1.6;
}

.feature-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--gold);
  font-weight: 700;
  font-size: 1.1em;
}

.purpose-image-wrap {
  display: flex;
  justify-content: center;
}

.purpose-image-wrap img {
  width: min(100%, 480px);
  height: auto;
  box-shadow: var(--shadow-lg);
  border-radius: 6px;
}

.news {
  background: var(--white);
  border-top: 1px solid var(--line-dark);
}

.title-inline {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 40px;
}

.title-inline .text-link {
  color: var(--navy);
  white-space: nowrap;
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.news-card {
  background: var(--white);
  border: 1px solid var(--line-dark);
  padding: 28px;
  border-radius: 6px;
  transition: all 0.3s ease;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
}

.news-card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-4px);
  border-color: rgba(199, 165, 109, 0.3);
}

.tag {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-ink);
  background: rgba(199, 165, 109, 0.08);
  padding: 4px 8px;
  border-radius: 3px;
  width: fit-content;
}

.news-card h3 {
  font-size: clamp(1.5rem, 2vw, 1.8rem);
  margin-bottom: 12px;
  color: var(--navy);
  flex-grow: 1;
}

.news-card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.6;
}

/* Compact masthead used by interior content pages.

   Keyed on a CLASS, not on [style]. It used to be .hero--masthead, meaning "a
   hero that sets its own inline background" — but that selector matches ANY
   style attribute, including one written by script. hero.js writes --px/--py
   on the landing hero for the pointer parallax, so the first mouse move over
   the landing page made it match this whole block: the !important background
   replaced the flat navy, and min-height/h1/lead all jumped to masthead
   sizing. The background visibly changed under the cursor. */
.hero--masthead {
  min-height: 440px;
  background: linear-gradient(110deg, var(--navy-deep), var(--navy)) !important;
}

.hero--masthead .hero-inner {
  min-height: 440px;
  padding: 75px 0;
}

.hero--masthead .hero-inner > div {
  max-width: 850px;
}

.hero--masthead h1 {
  max-width: 820px;
  margin: 0 0 22px;
  color: var(--white);
  font-size: clamp(2.2rem, 3.8vw, 3.4rem);
  line-height: 1.0;
  letter-spacing: -.032em;
}

.hero--masthead .lead {
  max-width: 720px;
  margin: 0;
  color: rgba(255,255,255,.78);
  font-size: clamp(1rem, 1.6vw, 1.24rem);
}

/* Contact page */
.contact-intro {
  overflow: hidden;
  background: var(--paper);
}

.contact-intro-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(420px, 1.1fr);
  min-height: 600px;
  align-items: stretch;
}

.contact-intro-copy {
  align-self: center;
  max-width: 570px;
  padding: 90px 70px 90px 0;
}

.contact-intro-copy h1 {
  margin: 0 0 24px;
  color: var(--navy-deep);
  font-size: clamp(2.2rem, 3.8vw, 3.4rem);
  line-height: 0.98;
  letter-spacing: -0.034em;
}

.contact-intro-copy > p:last-child {
  max-width: 520px;
  margin: 0;
  color: var(--muted);
  font-size: 1.08rem;
}

.contact-intro-image {
  width: calc(100% + max(20px, (100vw - 1200px) / 2));
  background: linear-gradient(90deg, rgba(17, 39, 61, 0.08), transparent 35%),
    url("media/images/generated/content-led/contact-consultation.webp") center/cover no-repeat;
}

.contact-directory {
  background: var(--navy-deep);
  color: var(--white);
  padding: 0;
}

.inquiry-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.inquiry-grid article {
  min-height: 245px;
  padding: 40px 30px;
  border-left: 1px solid rgba(255,255,255,.12);
}

.inquiry-grid article:last-child {
  border-right: 1px solid rgba(255,255,255,.12);
}

.inquiry-grid span {
  color: var(--gold-soft);
  font-size: .72rem;
  letter-spacing: .15em;
}

.inquiry-grid h2 {
  margin: 42px 0 16px;
  color: var(--white);
  font-size: 1.18rem;
}

.inquiry-grid a,
.inquiry-grid p {
  display: block;
  margin: 4px 0;
  color: rgba(255,255,255,.72);
  font-size: .9rem;
}

.inquiry-grid a:hover { color: var(--gold-soft); }

.contact-form-section { padding: 110px 0; }

.contact-form-grid {
  display: grid;
  grid-template-columns: .75fr 1.25fr;
  gap: clamp(50px, 8vw, 120px);
}

.contact-form-grid h2 {
  margin: 0 0 24px;
  color: var(--navy-deep);
  font-size: clamp(2.2rem, 3.8vw, 3.4rem);
  line-height: .95;
}

.contact-form-note { color: var(--muted); }
.contact-form .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.contact-form .form-group { margin-bottom: 26px; }
.contact-form .form-group label {
  margin-bottom: 9px;
  color: var(--navy-deep);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.contact-form .form-group input,
.contact-form .form-group select,
.contact-form .form-group textarea {
  border: 0;
  border-bottom: 1px solid var(--line-dark);
  border-radius: 0;
  padding: 12px 2px;
  background: transparent;
}
.contact-form .form-group input:focus,
.contact-form .form-group select:focus,
.contact-form .form-group textarea:focus {
  border-color: var(--gold);
  box-shadow: none;
}
.contact-form .form-group textarea { min-height: 110px; }
.contact-form .button { min-width: 150px; }

.contact-location { height: 480px; background: var(--stone); }
.contact-location iframe { width: 100%; height: 100%; border: 0; filter: grayscale(.15) saturate(.8); }

.culture-cta {
  position: relative;
  padding: 105px 0;
  background: linear-gradient(90deg, rgba(10,29,45,.96), rgba(10,29,45,.7)),
    url("media/images/generated/content-led/collaborative-culture.webp") 70% center/cover;
  color: var(--white);
}
.culture-cta-inner { max-width: 720px; margin-left: max(20px, calc((100vw - 1200px) / 2)); }
.culture-cta h2 { margin: 0 0 18px; color: var(--white); font-size: clamp(2rem, 3.4vw, 3rem); }
.culture-cta p:not(.eyebrow) { margin: 0 0 28px; color: rgba(255,255,255,.78); }

.site-footer {
  background: var(--navy-deep);
  color: rgba(255, 255, 255, 0.8);
  padding: 48px 0 32px;
  border-top: 1px solid rgba(199, 165, 109, 0.2);
}

.footer-grid {
  display: grid;
  /* wider than 1.1fr: the brand column now carries the two award cards, and
     at 1.1fr they wrapped one-per-line instead of sitting side by side */
  grid-template-columns: 1.35fr 2fr;
  gap: 36px;
  align-items: start;
  margin-bottom: 32px;
}

.footer-brand-block img {
  width: 200px;
  filter: brightness(0) invert(1);
  opacity: 0.95;
}

.footer-links {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}

.footer-label {
  margin: 0 0 12px;
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.footer-links a,
.footer-bottom p {
  display: block;
  margin: 0;
  color: rgba(255, 255, 255, 0.58);
  font-size: inherit;
}

.footer-bottom a {
  display: inline;
  color: rgba(255, 255, 255, 0.78);
  font-size: inherit;
  text-decoration: none;
  transition: color 0.3s ease;
}

.footer-links a:hover,
.footer-bottom a:hover {
  color: var(--gold-soft);
}

/* ══ drafting plate ════════════════════════════════════════════════════════
   The landing hero's annotated blueprint, as a reusable piece. The landing
   page keeps its own copy in hero.css because that version is animated by
   hero.js; this one is static and lives here so any page loading styles.css
   can carry a plate. Deliberately NOT named .hero__* — index.html loads both
   stylesheets and the two must not collide.
   ══════════════════════════════════════════════════════════════════════════ */
.plate {
  display: block;
  width: 100%;
  height: auto;
  /* callout labels sit outside the viewBox's drawing area */
  overflow: visible;
}

html:not(.no-js) .hero[data-image-gated]:not(.is-image-ready),
html:not(.no-js) .hero[data-image-gated]:not(.is-image-ready) *,
html:not(.no-js) .hero[data-image-gated]:not(.is-image-ready) *::before,
html:not(.no-js) .hero[data-image-gated]:not(.is-image-ready) *::after {
  animation-play-state: paused !important;
}

.no-js .hero[data-image-gated],
.no-js .hero[data-image-gated] *,
.hero[data-image-gated].is-image-error,
.hero[data-image-gated].is-image-error * {
  animation: none !important;
  transition: none !important;
}

.no-js .hero[data-image-gated] .sig-stroke {
  stroke-dashoffset: 0;
}

.no-js .hero[data-image-gated] .interior-hero-grid,
.no-js .hero[data-image-gated] .interior-hero-glow {
  opacity: 1;
}

.hero[data-image-gated].is-image-error .hero__stat {
  opacity: 1;
}

.plate-drawing { opacity: 0.93; }

.plate-reg {
  fill: none;
  stroke: rgba(199, 165, 109, 0.5);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.plate-docket-dot { fill: var(--gold); }

.plate-docket-text {
  fill: var(--gold);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.13em;
}

.plate-lead {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1.15;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.plate-anchor { fill: var(--gold); }

.plate-ref {
  fill: var(--gold);
  font-family: var(--font-mono);
  font-size: 21px;
  font-style: italic;
}

.plate-reflabel {
  fill: rgba(255, 255, 255, 0.62);
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.plate-caption {
  margin: 18px 0 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
  line-height: 1.7;
}

/* ── the plate draws itself in ─────────────────────────────────────────────
   Same sequence as the landing hero (hero.css), which this is the portable
   copy of: registration marks and docket first, then each callout inks its
   leader line and drops its anchor, then the reference letter and label fade
   up behind it.

   Two gates, as on the landing page. Nothing here runs until plate.js adds
   .is-plated, which it does only once the drawing itself has decoded — the
   annotation must never point into an empty box. --len is the leader's true
   measured length, also written by plate.js; the fallback 300 only covers the
   frame before it lands.

   Fails visible in both directions: .no-js (the class is on <html> in source
   and removed by the inline head script) and reduced motion both skip
   straight to the finished plate.                                           */
.plate-wrap .plate-lead {
  stroke-dasharray: var(--len, 300);
  stroke-dashoffset: var(--len, 300);
}

.plate-wrap .plate-anchor,
.plate-wrap .plate-ref,
.plate-wrap .plate-reflabel,
.plate-wrap .plate-reg,
.plate-wrap .plate-docket-text,
.plate-wrap .plate-docket-dot,
.plate-wrap .plate-caption { opacity: 0; }

.plate-wrap.is-plated .plate-reg {
  animation: plateFade 500ms ease-out 260ms forwards;
}

.plate-wrap.is-plated .plate-docket-text,
.plate-wrap.is-plated .plate-docket-dot {
  animation: plateFade 620ms ease-out 240ms forwards;
}

.plate-wrap.is-plated .plate-caption {
  animation: plateFade 700ms ease-out 1500ms forwards;
}

.plate-wrap.is-plated .plate-lead {
  animation: plateDraw 620ms cubic-bezier(0.45, 0.05, 0.25, 1) both;
}

.plate-wrap.is-plated .plate-anchor,
.plate-wrap.is-plated .plate-ref,
.plate-wrap.is-plated .plate-reflabel {
  animation: plateFade 420ms ease-out both;
}

/* callouts, staggered 140ms apart; letters trail their own line by 540ms */
.plate-wrap.is-plated [data-call="1"] .plate-lead,
.plate-wrap.is-plated [data-call="1"] .plate-anchor { animation-delay: 1020ms; }
.plate-wrap.is-plated [data-call="2"] .plate-lead,
.plate-wrap.is-plated [data-call="2"] .plate-anchor { animation-delay: 1160ms; }
.plate-wrap.is-plated [data-call="3"] .plate-lead,
.plate-wrap.is-plated [data-call="3"] .plate-anchor { animation-delay: 1300ms; }
.plate-wrap.is-plated [data-call="4"] .plate-lead,
.plate-wrap.is-plated [data-call="4"] .plate-anchor { animation-delay: 1440ms; }
.plate-wrap.is-plated [data-call="5"] .plate-lead,
.plate-wrap.is-plated [data-call="5"] .plate-anchor { animation-delay: 1580ms; }

.plate-wrap.is-plated [data-call="1"] .plate-ref,
.plate-wrap.is-plated [data-call="1"] .plate-reflabel { animation-delay: 1560ms; }
.plate-wrap.is-plated [data-call="2"] .plate-ref,
.plate-wrap.is-plated [data-call="2"] .plate-reflabel { animation-delay: 1700ms; }
.plate-wrap.is-plated [data-call="3"] .plate-ref,
.plate-wrap.is-plated [data-call="3"] .plate-reflabel { animation-delay: 1840ms; }
.plate-wrap.is-plated [data-call="4"] .plate-ref,
.plate-wrap.is-plated [data-call="4"] .plate-reflabel { animation-delay: 1980ms; }
.plate-wrap.is-plated [data-call="5"] .plate-ref,
.plate-wrap.is-plated [data-call="5"] .plate-reflabel { animation-delay: 2120ms; }

@keyframes plateFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes plateDraw { to { stroke-dashoffset: 0; } }

/* Fails visible: a finished plate, never a half-drawn one. */
.no-js .plate-wrap .plate-lead { stroke-dashoffset: 0; }

.no-js .plate-wrap .plate-anchor,
.no-js .plate-wrap .plate-ref,
.no-js .plate-wrap .plate-reflabel,
.no-js .plate-wrap .plate-reg,
.no-js .plate-wrap .plate-docket-text,
.no-js .plate-wrap .plate-docket-dot,
.no-js .plate-wrap .plate-caption { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .plate-wrap .plate-lead {
    animation: none;
    stroke-dashoffset: 0;
  }

  html:not(.force-motion) .plate-wrap .plate-anchor,
  html:not(.force-motion) .plate-wrap .plate-ref,
  html:not(.force-motion) .plate-wrap .plate-reflabel,
  html:not(.force-motion) .plate-wrap .plate-reg,
  html:not(.force-motion) .plate-wrap .plate-docket-text,
  html:not(.force-motion) .plate-wrap .plate-docket-dot,
  html:not(.force-motion) .plate-wrap .plate-caption {
    animation: none;
    opacity: 1;
  }
}

/* The plate replaces the plain <img>, so the art column sizes to it. */
.art-hero-art .plate-wrap {
  /* concrete width: the art column is width:auto, so a percentage here would
     be circular and collapse the plate */
  width: 560px;
  max-width: 100%;
}

@media (max-width: 980px) {
  .art-hero-art .plate-wrap { width: 100%; }
}

/* ── footer recognition badges ─────────────────────────────────────────────
   Left column of the footer: the Best Law Firms shield sits beside the logo
   (it is tall and narrow, so it fills the space the logo leaves), and the two
   wide cards run underneath. The marks are the originals as their issuers
   publish them, on their own light grounds — which is why they must opt out
   of .footer-brand-block img's knockout filter below. */
.footer-brand-row {
  display: flex;
  align-items: center;
  gap: 26px;
}

/* .footer-brand-block img paints the Reising logo white with
   `brightness(0) invert(1)`. Every badge in this column inherits that at equal
   specificity and comes out a flat white silhouette, red and all, so the
   badges reset it explicitly. */
.footer-badges img,
.footer-brand-row .badge-tall {
  filter: none;
  opacity: 1;
  display: block;
  width: auto;
}

.footer-badges {
  margin-top: 24px;
}

.footer-badges ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 14px 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-badges li {
  display: flex;
  align-items: center;
  height: 64px;
}

.footer-badges .badge-wide { height: 64px; }
.footer-brand-row .badge-tall { height: 78px; }

@media (max-width: 560px) {
  .footer-brand-row { gap: 20px; }
  .footer-badges { margin-top: 20px; }
  .footer-badges ul { gap: 12px 14px; }
  .footer-badges li { height: 52px; }
  .footer-badges .badge-wide { height: 52px; }
  .footer-brand-row .badge-tall { height: 62px; }
}

/* Bottom bar: address | phone · email | copyright.
   Inherits the .container gutter — no width override, or the address would
   sit flush against the viewport edge. */
.footer-bottom {
  margin-top: 40px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-start;
  gap: 8px 44px;
  font-size: 0.8125rem;
  line-height: 1.7;
  letter-spacing: 0.01em;
}

/* Keep the phone and email on one line — the separator must never be
   orphaned onto a line of its own. */
.footer-contact {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.footer-sep {
  padding: 0 10px;
  color: rgba(255, 255, 255, 0.55);
}

.footer-bottom .footer-legal {
  margin-left: auto;
}

/* ── collapsible mobile menu ───────────────────────────────────────────────
   header-scroll.js injects .nav-toggle and marks the header .has-nav-toggle.
   Everything that hides the nav is scoped to that class, so a JS failure
   leaves the old wrapped layout with every link still on screen. */
.nav-toggle { display: none; }

@media (max-width: 980px) {
  .nav-toggle {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    margin-left: auto;
    padding: 0 9px;
    appearance: none;
    border: 1px solid var(--line-dark);
    background: none;
    cursor: pointer;
  }

  .nav-toggle span {
    display: block;
    height: 2px;
    background: var(--navy);
    transition: transform 0.25s ease, opacity 0.2s ease;
  }

  .site-header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .site-header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
  .site-header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* The masthead was ~135px on a phone: an 18px strip, a 60px mark with 20px
     of padding either side, and the nav wrapped onto a second row. The strip
     goes, the mark halves, and the nav moves into the panel. */
  .topbar { display: none; }

  .nav-wrap {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 12px;
    min-height: 0;
    padding: 9px 0;
  }

  .brand img { height: 40px; }

  .site-header.has-nav-toggle .main-nav { display: none; }

  .site-header.has-nav-toggle.nav-open .main-nav {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    order: 3;
    width: 100%;
    margin: 0;
    padding-bottom: 8px;
    border-top: 1px solid var(--line);
  }

  .site-header.has-nav-toggle.nav-open .main-nav > a,
  .site-header.has-nav-toggle.nav-open .nav-dropdown > button {
    display: block;
    width: 100%;
    padding: 13px 0 12px;
    border-bottom: 1px solid var(--line);
    text-align: left;
  }

  /* Touch has no hover, so the submenus are laid out inline and indented
     rather than waiting for a state the device cannot produce. */
  .site-header.has-nav-toggle.nav-open .nav-dropdown-menu {
    position: static;
    display: block;
    min-width: 0;
    padding: 0 0 6px 16px;
    border: 0;
    background: none;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }

  .site-header.has-nav-toggle.nav-open .nav-dropdown-menu a {
    /* the menu is display:block here, so the links need to stack themselves */
    display: block;
    padding: 10px 0;
    font-weight: 500;
    color: var(--muted);
    white-space: normal;
  }

  /* The gold underline and the chevron both signal a hover-opened menu; in the
     panel the submenu is already laid out, so neither has anything to say. */
  .site-header.has-nav-toggle.nav-open .nav-dropdown > button::after,
  .site-header.has-nav-toggle.nav-open .nav-dropdown > button::before { display: none; }

  .main-nav {
    order: 3;
    width: 100%;
    flex-wrap: wrap;
    gap: 14px 22px;
    margin: 0;
  }

  /* A closed dropdown still takes part in layout, so its box was creating
     ~22px of phantom horizontal scroll — a strip of white space with nothing
     in it, on every page.

     Neither centring nor left-pinning fixes it: once the nav wraps, the
     Services trigger starts at x=254 of a 390px viewport, so a 152px menu
     overflows whichever of its own edges you anchor. Anchoring the menu's
     RIGHT edge to the trigger's right edge makes it grow inward, away from
     the viewport edge, which is the only direction with room. */
  .nav-dropdown-menu {
    top: calc(100% + 10px);
    left: auto;
    right: 0;
    transform: translate(0, 8px);
    min-width: 0;
    width: max-content;
    max-width: calc(100vw - 40px);
  }

  .nav-dropdown:hover .nav-dropdown-menu,
  .nav-dropdown:focus-within .nav-dropdown-menu {
    transform: translate(0, 0);
  }

  /* The hover bridge is centred on the same axis; match it. */
  .nav-dropdown::after {
    left: auto;
    right: 0;
    transform: none;
    min-width: 0;
  }

  .hero-inner {
    flex-direction: column;
    gap: 32px;
  }

  .hero-panel {
    width: 100%;
    max-width: 400px;
  }

  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .card-grid,
  .intro-grid,
  .purpose-grid,
  .news-grid,
  .footer-grid,
  .footer-bottom {
    display: block;
  }

  .footer-bottom p {
    margin-bottom: 10px;
  }

  .footer-bottom p:last-child {
    margin-bottom: 0;
  }

  .footer-bottom .footer-legal {
    margin-left: 0;
  }

  .service-card {
    flex-direction: column;
  }

  .service-media {
    width: 100%;
    min-height: 240px;
  }

  .footer-links {
    /* the footer grid is display:block here, so its 36px column gap no longer
       separates the links from the badges stacked above them */
    margin-top: 40px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .contact-intro-grid,
  .contact-form-grid { grid-template-columns: 1fr; }
  .contact-intro-copy { padding: 70px 0; }
  .contact-intro-image { width: 100%; min-height: 420px; }
  .inquiry-grid { grid-template-columns: repeat(2, 1fr); }
  .inquiry-grid article:nth-child(3) { border-top: 1px solid rgba(255,255,255,.12); }
  .inquiry-grid article:nth-child(4) { border-top: 1px solid rgba(255,255,255,.12); }
}

@media (max-width: 640px) {
  .topbar-inner {
    flex-direction: column;
    justify-content: center;
    text-align: center;
    padding: 10px 0;
    gap: 6px;
  }

  .button {
    width: 100%;
  }

  .main-nav {
    align-items: stretch;
  }

  .main-nav > a,
  .nav-dropdown > button {
    padding: 6px 0;
  }

  .hero {
    min-height: 600px;
  }

  .hero-inner {
    min-height: 600px;
    gap: 24px;
  }

  .hero-copy {
    padding: 20px 0;
  }

  .hero-panel {
    padding: 24px 18px;
  }

  .hero-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .stats-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .hero-copy h1 {
    font-size: clamp(1.9rem, 4vw, 2.6rem);
  }

  .title-inline {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .purpose-grid {
    gap: 32px;
  }

  .footer-links {
    grid-template-columns: 1fr;
  }

  .news-grid {
    grid-template-columns: 1fr;
  }

  .contact-intro-copy h1 { font-size: 3.5rem; }
  .contact-intro-image { min-height: 300px; }
  .inquiry-grid { grid-template-columns: 1fr; }
  .inquiry-grid article { min-height: 190px; border-right: 1px solid rgba(255,255,255,.12); border-top: 1px solid rgba(255,255,255,.12); }
  .contact-form-section { padding: 75px 0; }
  .contact-form .form-row { grid-template-columns: 1fr; gap: 0; }
  .contact-location { height: 360px; }
  .culture-cta { padding: 75px 0; }
  .culture-cta-inner { margin-left: auto; }
}


/* ── browser surfaces ─────────────────────────────────────────────────────
   Selection, focus ring, caret, scrollbar and underline offset ship with
   browser defaults that belong to no design system. Theme them from the
   palette. */
::selection {
  background: var(--gold-soft);
  color: var(--navy-deep);
}

:root {
  accent-color: var(--gold-ink);
  caret-color: var(--navy);
  scrollbar-color: var(--gold) var(--paper-strong);
}

a {
  text-underline-offset: 0.18em;
}

:focus-visible {
  outline: 3px solid var(--gold-ink);
  outline-offset: 2px;
}

.hero :focus-visible,
.stats-bar :focus-visible,
.site-footer :focus-visible,
.topbar :focus-visible {
  outline-color: var(--gold-soft);
}


/* ══ Carry the hero's drafting language into the body ═════════════════════
   The eyebrow becomes the same mono docket label used over the patent plate,
   with a short gold rule above it. One visual language top to bottom. */
.eyebrow,
.card-kicker {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  position: relative;
  padding-top: 16px;
}

.eyebrow::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 34px;
  height: 2px;
  background: var(--gold);
}

/* Section headings sit on a measure so they cannot run to five lines */
.section-title-wrap h2,
.intro-grid h2,
.purpose-copy h2 {
  max-width: 20ch;
  text-wrap: balance;
}

/* Service card: the h3 is now a short label, the sentence is body copy */
.service-desc {
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 0.98rem;
  line-height: 1.65;
}


/* ══ practice bar ═════════════════════════════════════════════════════════
   Four practice areas, directly under the hero. Deliberately NOT styled as a
   stats strip: the hero already carries the numbers, and setting words like
   "Patents" in big figure type is what made the old band read as broken.
   Light paper ground so it separates the navy hero from the white body. */
.practice-bar {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.practice-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.practice-item {
  padding: 30px 28px 30px 0;
  border-left: 1px solid var(--line-dark);
  padding-left: 28px;
}

.practice-item:first-child {
  border-left: 0;
  padding-left: 0;
}

.practice-name {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.012em;
  line-height: 1.2;
  color: var(--navy);
}

/* the same gold tick that marks section eyebrows, tying the band to the
   drafting language rather than leaving it as a plain row */
.practice-name::before {
  content: "";
  display: block;
  width: 26px;
  height: 2px;
  background: var(--gold);
  margin-bottom: 12px;
}

.practice-desc {
  margin: 0;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
}

@media (max-width: 860px) {
  .practice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .practice-item:nth-child(3) { border-left: 0; padding-left: 0; }
  .practice-item { padding-block: 24px; }
}

@media (max-width: 520px) {
  .practice-grid { grid-template-columns: minmax(0, 1fr); }
  .practice-item { border-left: 0; padding-left: 0; padding-block: 20px; }
  .practice-item + .practice-item { border-top: 1px solid var(--line-dark); }
}


.culture-cta::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--navy-deep);
  animation: heroPhotoVeil 760ms cubic-bezier(0.16, 1, 0.3, 1) 40ms both;
}

@keyframes heroPhotoVeil {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* keep the copy above the veil */
.culture-cta .container,
.culture-cta-inner {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .culture-cta::after { animation: none; opacity: 0; }
}


/* ══ interior hero drafting grid ══════════════════════════════════════════
   The landing hero carries the blueprint language via its own .hero__grid
   element. Interior heroes had a photo; with that removed they were flat
   navy, so they get the same grid as a pseudo-element instead. Scoped to
   .hero--masthead, which only interior pages carry, so the landing hero is
   untouched. */
.professionals-hero::after,
.content-hero::after,
.archive-hero::after,
.industry-detail-hero::after,
.hero--masthead::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right,  rgba(199, 165, 109, 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.05) 1px, transparent 1px),
    linear-gradient(to right,  rgba(199, 165, 109, 0.09) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.09) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px, 140px 140px, 140px 140px;
  -webkit-mask-image: radial-gradient(ellipse 82% 78% at 30% 50%, #000 30%, transparent 80%);
          mask-image: radial-gradient(ellipse 82% 78% at 30% 50%, #000 30%, transparent 80%);
}

/* a gold rule under the interior page title, matching the section rules */
.professionals-hero,
.content-hero,
.archive-hero,
.industry-detail-hero { position: relative; }

.professionals-hero > *,
.content-hero > *,
.archive-hero > *,
.industry-detail-hero > * { position: relative; z-index: 1; }

.hero--masthead h1::after {
  content: "";
  display: block;
  width: 54px;
  height: 2px;
  margin-top: 22px;
  background: var(--gold);
}

/* Shared blueprint atmosphere for interior mastheads. The landing page owns
   a bespoke version in hero.css; motion.js installs this lighter variant on
   every other major navy hero so the visual language carries across pages. */
.has-interior-hero-effects {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.has-interior-hero-effects > :not(.interior-hero-effects):not(.about-hero__sky) {
  position: relative;
  z-index: 2;
}

/* The shared real grid replaces the older one-layer pseudo grid. About keeps
   its own ::after scrim because that layer protects text over the skyline. */
.professionals-hero.has-interior-hero-effects::after,
.content-hero.has-interior-hero-effects::after,
.archive-hero.has-interior-hero-effects::after,
.industry-detail-hero.has-interior-hero-effects::after,
.hero.has-interior-hero-effects:not(.about-hero)::after {
  content: none;
}

.interior-hero-effects,
.interior-hero-grid,
.interior-hero-glow,
.interior-hero-sparks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.interior-hero-effects { z-index: 1; }

.interior-hero-grid {
  inset: -12% -5%;
  background-image:
    linear-gradient(to right, rgba(199, 165, 109, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.055) 1px, transparent 1px),
    linear-gradient(to right, rgba(199, 165, 109, 0.1) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.1) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px, 140px 140px, 140px 140px;
  -webkit-mask-image: radial-gradient(ellipse 82% 76% at 58% 48%, #000 34%, transparent 80%);
          mask-image: radial-gradient(ellipse 82% 76% at 58% 48%, #000 34%, transparent 80%);
}

.interior-hero-glow {
  inset: -25% 0 -25% 35%;
  background: radial-gradient(ellipse at center, rgba(199, 165, 109, 0.11), transparent 64%);
  animation: interiorHeroGlow 9s ease-in-out infinite alternate;
}

.interior-hero-sparks {
  inset: -12% -5%;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(ellipse 82% 76% at 58% 48%, #000 34%, transparent 80%);
          mask-image: radial-gradient(ellipse 82% 76% at 58% 48%, #000 34%, transparent 80%);
}

.interior-hero-spark {
  position: absolute;
  display: block;
  opacity: 0;
  filter: drop-shadow(0 0 2px rgba(255, 214, 130, 0.22));
}

.interior-hero-spark--v {
  top: 0;
  left: var(--spark-pos);
  /* 1px, matching the grid rule it rides: a 2px filament straddles the line */
  width: 1px;
  height: var(--spark-length);
  background: linear-gradient(to bottom, transparent, rgba(246, 222, 174, 0.86), transparent);
  animation: interiorSparkFall var(--spark-time) linear var(--spark-delay) infinite backwards;
}

.interior-hero-spark--h {
  top: var(--spark-pos);
  left: 0;
  width: var(--spark-length);
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(246, 222, 174, 0.86), transparent);
  animation: interiorSparkCross var(--spark-time) linear var(--spark-delay) infinite backwards;
}

@keyframes interiorSparkFall {
  0% { transform: translateY(-160px); opacity: 0; }
  18% { opacity: 0.78; }
  48% { opacity: 0.12; }
  72% { opacity: 0.68; }
  100% { transform: translateY(760px); opacity: 0; }
}

@keyframes interiorSparkCross {
  0% { transform: translateX(-180px); opacity: 0; }
  20% { opacity: 0.72; }
  55% { opacity: 0.1; }
  78% { opacity: 0.64; }
  100% { transform: translateX(1500px); opacity: 0; }
}

@keyframes interiorHeroGlow {
  from { transform: translate3d(0, -2%, 0); opacity: 0.72; }
  to { transform: translate3d(-3%, 4%, 0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .interior-hero-spark { display: none; }
  html:not(.force-motion) .interior-hero-glow { animation: none; }
}

/* ══ services page tiles ═══════════════════════════════════════════════════
   .service-suite and .service-category shipped with no CSS, so their
   children fell through to the landing page's .service-card rule, which is a
   horizontal photo+text flex row. That is what put the heading on the left
   and the list on the right. These reset that and give the page its own
   tile system. */
.service-suite {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  margin-top: 34px;
}

/* override the landing-page card, which is display:flex */
.service-suite .service-card {
  display: block;
  padding: 26px 24px 28px;
  background: var(--white);
  border: 1px solid var(--line-dark);
  border-radius: 6px;
  box-shadow: none;
}

.service-suite .service-card:hover {
  transform: none;
  box-shadow: var(--shadow);
  border-color: rgba(199, 165, 109, 0.45);
}

.service-suite .service-card h4 {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--navy);
}

/* the same gold tick used on section eyebrows, tying the tiles to the system */
.service-suite .service-card h4::before {
  content: "";
  display: block;
  width: 24px;
  height: 2px;
  margin-bottom: 12px;
  background: var(--gold);
}

.service-suite .service-card ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.service-suite .service-card li {
  position: relative;
  padding: 7px 0 7px 16px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.5;
}

.service-suite .service-card li:first-child { border-top: 0; }

.service-suite .service-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 15px;
  width: 5px;
  height: 1px;
  background: var(--gold);
}

/* ── the four practice-area blocks ──────────────────────────────────────
   Same tile language as .service-suite above: white card, hairline border,
   gold tick over the heading. The list items are short labels, so they run
   two-up rather than as full-width rows — five of them stacked made each card
   twice as tall as its own description.

   The marker is a dot, not the 5x1px dash used elsewhere: at this size, next
   to a short label, the dash read as a stray hyphen in the copy. The dot
   echoes the anchor points on the drafting plates instead.            */
.service-category-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 34px;
}

.service-category {
  padding: 32px 30px 34px;
  background: var(--white);
  border: 1px solid var(--line-dark);
  border-radius: 6px;
  transition: box-shadow 240ms ease, border-color 240ms ease;
}

.service-category:hover {
  box-shadow: var(--shadow);
  border-color: rgba(199, 165, 109, 0.45);
}

.service-category h3 {
  margin: 0 0 12px;
  color: var(--navy);
  font-size: 1.3rem;
  line-height: 1.25;
}

/* the gold tick used on section eyebrows and the .service-suite tiles */
.service-category h3::before {
  content: "";
  display: block;
  width: 24px;
  height: 2px;
  margin-bottom: 14px;
  background: var(--gold);
}

.service-category > p {
  margin: 0 0 22px;
  color: var(--muted);
  font-size: 0.96rem;
  line-height: 1.7;
}

.service-category .service-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 11px 26px;
  margin: 0;
  padding: 21px 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
}

.service-category .service-list li {
  position: relative;
  padding-left: 15px;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.5;
}

.service-category .service-list li::before {
  content: "";
  position: absolute;
  left: 0;
  /* .55em rather than a fixed px: the dot stays on the first line's centre
     when a label wraps to two lines. */
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--gold);
}

@media (max-width: 620px) {
  .service-category { padding: 26px 22px 28px; }
  .service-category .service-list { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 980px) {
  .service-suite { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 760px) {
  .service-suite,
  .service-category-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── randomized shareholder feature ────────────────────────────────────── */
.attorney-feature {
  overflow: hidden;
  background: var(--navy);
  color: var(--white);
}

.attorney-feature-grid {
  display: grid;
  grid-template-columns: minmax(360px, 0.9fr) minmax(380px, 1fr);
  align-items: center;
  gap: clamp(64px, 9vw, 140px);
}

.attorney-stack {
  position: relative;
  width: min(100%, 440px);
  height: 500px;
  margin-inline: auto;
}

/* The stack doubles as the control that advances to the next shareholder
   (services-specialists.js). Only the affordance is added — the resting look
   is unchanged: a pointer, a focus ring, and a brief dip while the portraits
   swap underneath. */
.attorney-stack.is-interactive {
  cursor: pointer;
  transition: opacity 150ms ease;
  -webkit-tap-highlight-color: transparent;
}

.attorney-stack.is-interactive:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 8px;
}

.attorney-stack.is-turning { opacity: 0.4; }

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .attorney-stack.is-interactive { transition: none; }
  html:not(.force-motion) .attorney-stack.is-turning { opacity: 1; }
}

/* The stack and its controls share one grid cell (see services-specialists.js);
   the reveal animation rides on the stack itself, so the wrapper is layout only. */
.attorney-stack-column { min-width: 0; }

/* Prev/next controls, injected by services-specialists.js beneath the stack.
   Hidden below 900px, where the swipe gesture is the control instead. */
.attorney-nav {
  display: flex;
  justify-content: center;
  gap: 14px;
  /* the front card is rotated, so it overhangs its own box by ~6px; 42 leaves
     a real gap rather than the 2px the geometry actually produced */
  margin-top: 42px;
}

.attorney-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0 0 4px;
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  background: none;
  color: rgba(255, 255, 255, 0.75);
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.25s ease, color 0.25s ease, background 0.25s ease;
}

.attorney-nav-btn:hover,
.attorney-nav-btn:focus-visible {
  border-color: var(--gold);
  background: rgba(199, 165, 109, 0.12);
  color: var(--gold);
}

@media (max-width: 900px) {
  .attorney-nav { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .attorney-nav-btn { transition: none; }
}

.attorney-stack-card {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  border-radius: 5px;
  box-shadow: 0 24px 54px rgba(0, 20, 31, 0.38);
}

.attorney-stack-card-back {
  z-index: 1;
  transform: translate(-42px, 24px) rotate(-7deg) scale(0.9);
  filter: saturate(0.72) brightness(0.72);
}

.attorney-stack-card-middle {
  z-index: 2;
  transform: translate(42px, 15px) rotate(6deg) scale(0.94);
  filter: saturate(0.82) brightness(0.84);
}

.attorney-stack-card-front {
  z-index: 3;
  transform: rotate(-1.5deg);
}

.attorney-feature-copy { max-width: 600px; }

.attorney-feature-copy h2 {
  max-width: 18ch;
  margin: 0 0 20px;
  color: var(--white);
  font-size: clamp(2.75rem, 4.2vw, 4.15rem);
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.attorney-feature-intro {
  margin: 0 0 42px;
  color: rgba(255, 255, 255, 0.76);
  font-size: 1.05rem;
  line-height: 1.75;
}

.attorney-feature-role {
  margin: 0 0 8px;
  color: var(--gold);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.attorney-feature-name {
  margin: 0 0 12px;
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(1.65rem, 3vw, 2.45rem);
}

.attorney-feature-bio {
  margin: 0;
  color: rgba(255, 255, 255, 0.82);
  line-height: 1.7;
}

.attorney-feature-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px;
  margin-top: 30px;
}

.attorney-feature-all {
  color: var(--white);
  font-weight: 700;
  text-decoration-color: var(--gold);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

.attorney-feature-all:hover { color: var(--gold); }

@media (max-width: 900px) {
  .attorney-feature-grid {
    grid-template-columns: 1fr;
    gap: 64px;
  }

  .attorney-stack {
    width: min(78vw, 420px);
    height: min(92vw, 490px);
  }

  .attorney-feature-copy { max-width: 680px; }
}

@media (max-width: 520px) {
  .attorney-stack {
    width: min(72vw, 330px);
    height: min(90vw, 410px);
  }

  .attorney-stack-card-back { transform: translate(-24px, 18px) rotate(-6deg) scale(0.91); }
  .attorney-stack-card-middle { transform: translate(24px, 12px) rotate(5deg) scale(0.95); }
  .attorney-feature-intro { margin-bottom: 32px; }
}



/* ── Reading measure ────────────────────────────────────────────────────────
   Body copy set to the full-width container was running to ~145ch, roughly
   double the band where sustained reading holds up. Capped at the container
   level. Because a max-width never widens anything, grid columns, cards, and
   footer copy — all already narrower than 68ch — are unaffected. */
.section-shell .container p,
.section-shell .container li,
.culture-cta-inner p,
.position-description {
  max-width: var(--measure);
}

/* The culture CTA is a centred band, so its capped copy centres too. */
.culture-cta-inner p { margin-inline: auto; }

/* The navy CTA bands are three short lines — heading, one sentence, button.
   At the full 90px section rhythm they read as a mostly-empty panel, so they
   get a tighter block of their own. */
.section-shell[style*="text-align: center"],
.section-shell[style*="text-align:center"] {
  padding: 56px 0;
}

@media (max-width: 640px) {
  .section-shell[style*="text-align: center"],
  .section-shell[style*="text-align:center"] {
    padding: 44px 0;
  }
}

/* Centred callout panels keep their copy centred under the cap.
   Two shapes carry the centring — an inner div, and the section itself (the
   navy CTA bands on About and Services). Both need it: the cap leaves the
   paragraph's BOX narrower than the container, and a box with margin 0 sits
   flush left however its text is aligned, which reads as left-aligned copy
   under a centred heading. */
.section-shell .container div[style*="text-align: center"] > p,
.section-shell[style*="text-align: center"] .container > p,
.section-shell[style*="text-align:center"] .container > p {
  margin-inline: auto;
}

/* ══ The Real McCoy signature ═══════════════════════════════════════════════
   Set in Parisienne and rendered by Tegaki (npm `tegaki`), then exported with
   its toSVG() and baked in at build time by tools/signature/build_signature.py.

   WHY BAKED RATHER THAN RUNTIME: Tegaki at runtime costs ~80 KB gz for the
   Parisienne bundle plus a 19 KB font and an ESM waterfall, and its `speed`
   option does not change the timeline at all — every value still reports a
   21.6s duration, far too slow for a hero. The baked export is 14 KB gz, needs
   no JavaScript, and lets the writing join the hero's existing arrival
   sequence and honour prefers-reduced-motion.

   HOW IT DRAWS: each glyph is a run of variable-width <line> segments — that
   is where the thick/thin contrast comes from, and why a constant-width
   hand-drawn path could never match it — revealed by a centreline stroke used
   as a <mask>. Those mask strokes carry pathLength="1", so dashoffset runs
   1 -> 0 regardless of a stroke's real length and --dur alone sets its pace.
   Timings are proportional to stroke length, so the nib moves at one speed. */
.sig { display: block; width: 100%; height: auto; color: var(--gold); }

.sig-stroke {
  /* Tegaki's own easing curve, carried over from its keySplines. */
  animation: sigWrite var(--dur) cubic-bezier(0.33, 0, 0.15, 1) var(--t0) forwards;
}

@keyframes sigWrite { to { stroke-dashoffset: 0; } }

/* Fails visible: finished signature rather than a blank space. */
@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .sig-stroke { animation: none; stroke-dashoffset: 0; }
}

/* ══ About hero — Detroit ═══════════════════════════════════════════════════
   The skyline is the same material as the landing hero's patent plate: white
   ink on transparency, so it TINTS to the navy instead of sitting on it as a
   pasted rectangle. The source art was cyan line work on black; luminance was
   converted to an alpha matte (see media/hero/detroit-skyline-ink.png), which
   is why it belongs to this palette rather than fighting it.

   It is a horizon, not a photograph: anchored to the bottom edge, masked away
   toward the top so the headline never competes with building detail. */
/* `.hero--masthead` (0,2,0) out-specifies a bare `.about-hero`, so specificity is
   matched here and the tie broken on order.

   Sized to the content, not to a round number: at 700px the copy and record
   together came to 418px and the hero carried 282px of dead navy above the
   headline. */
.hero.about-hero {
  flex-direction: column;
  justify-content: flex-end;
  gap: 0;
  min-height: 520px;
  overflow: hidden;
}

/* Full-bleed horizon anchored to the bottom edge. The asset is cropped to the
   waterline (ratio ~2.03), so at any viewport the shoreline lands just above
   the datum rule and only the tower tops run past the hero — and the mask has
   already faded those to nothing, so the clip is never visible. */
.about-hero__sky {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 26%, rgba(0,0,0,.5) 54%, transparent 82%);
          mask-image: linear-gradient(to top, #000 0%, #000 26%, rgba(0,0,0,.5) 54%, transparent 82%);
}

.about-hero__sky img {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.4;
}

/* Scrim under the datum block: the water reflection is busy, and the record
   names sit directly on it. */
.about-hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 340px;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(to top, var(--navy-deep) 6%, rgba(10, 29, 45, 0.92) 42%,
              rgba(10, 29, 45, 0.7) 70%, transparent 100%);
}

.about-hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 56px;
  width: min(1200px, calc(100% - 40px));
  margin-inline: auto;
  padding: 54px 0 26px;
}

.about-hero__copy { flex: 1 1 56%; max-width: 640px; }
/* The about hero uses .about-hero__copy, not .hero-copy, so it never picked up
   the `.hero-copy h1 { color: var(--white) }` rule and fell back to the body
   ink colour -- dark navy text on a dark navy hero. */
.about-hero h1 { max-width: 15ch; color: var(--white); }
.about-hero .lead { max-width: 48ch; }

.about-hero__mark { flex: 0 1 40%; max-width: 400px; }
.about-hero__mark .sig { overflow: visible; }

.about-hero__note {
  margin: 12px 0 0;
  color: rgba(255, 255, 255, 0.62);
  font-size: 0.8rem;
  line-height: 1.6;
}

/* ── the datum line: annotation voice, as on the blueprint ───────────────── */
.about-hero__datum {
  position: relative;
  z-index: 1;
  width: min(1200px, calc(100% - 40px));
  margin-inline: auto;
  padding: 0 0 40px;
}

.about-hero__place {
  margin: 0 0 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(199, 165, 109, 0.3);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
}

.about-hero__place span { opacity: 0.5; margin: 0 6px; }

.about-hero__names {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-hero__names li { display: flex; flex-direction: column; gap: 3px; }

.about-hero__names b {
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--white);
  letter-spacing: -0.005em;
}

.about-hero__names span {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--gold-soft);
  opacity: 0.85;
}

@media (max-width: 900px) {
  /* must match .hero.about-hero (0,2,0) or the desktop min-height wins */
  .hero.about-hero { min-height: 0; }
  .about-hero__inner { flex-direction: column; align-items: stretch; gap: 30px; padding-top: 52px; }
  .about-hero__mark { max-width: 320px; }
  .about-hero__names { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  /* At 390px the full-width band is only ~190px tall and reads as a smear, so
     it is scaled up. The scaled box must be CLIPPED rather than allowed to
     stick out: .about-hero has overflow:hidden, but the element was still
     reported at 975px wide against a 390px viewport by layout. Keeping it
     centred with a transform on a zero-width anchor removes it from the
     scrollable area entirely. */
  /* At 390px the full-width band is only ~190px tall and reads as a smear, so
     it is scaled up. The scaled image must be CLIPPED by this element rather
     than allowed to widen the document: at 320px the img's own layout box was
     832px and added 15px of horizontal scroll even though its parent section
     was overflow:hidden. Clipping here, on the element that owns the scale,
     keeps the visual and contributes nothing to scroll width. */
  .about-hero__sky {
    left: 0;
    right: 0;
    width: auto;
    max-width: 100%;
    overflow: hidden;
    transform: none;
  }

  .about-hero__sky img {
    width: 260%;
    max-width: none;
    margin-left: -80%;      /* centres the 260% band: (260 - 100) / 2 */
  }
}

@media (max-width: 560px) {
  .about-hero__names { grid-template-columns: 1fr; }
}


/* ══ art hero ═══════════════════════════════════════════════════════════════
   A navy masthead with copy left and a line-art plate right, carrying the
   landing page's exact blueprint treatment. Was authored inline on
   Industries; promoted here verbatim (class names generalised) when Services
   took the same shape, so the two cannot drift apart.
   ══════════════════════════════════════════════════════════════════════════ */
.art-hero {
  min-height: 380px;
  overflow: hidden;
  /* the landing hero sits on flat navy-deep; a gradient here made the
     same grid and sparks read differently across the two pages */
  background: var(--navy-deep);
}

.art-hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  /* The art column is sized to its content (auto) rather than given a fixed
     1.22fr share: the plates are capped by max-height, so a fractional column
     reserved far more width than the image used and left the copy squeezed
     against a gap. The copy now takes everything the art does not. */
  grid-template-columns: minmax(320px, 1fr) auto;
  gap: clamp(2.5rem, 4vw, 4rem);
  align-items: center;
  min-height: 380px;
  padding-block: clamp(2.25rem, 3.6vw, 3.25rem);
}

.art-hero-copy {
  color: white;
}

/* Type matches the landing hero (hero.css .hero h1 / .hero__lead) exactly, so
   the three mastheads read as one system. The earlier 5.4rem setting stacked a
   four-word title into four lines and pushed the section past 600px tall. */
.art-hero h1 {
  max-width: 17ch;
  margin: 0 0 clamp(18px, 2.6vw, 30px);
  color: var(--white);
  font-size: clamp(2.05rem, 4.15vw, 3.55rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

/* The short gold rule the other interior mastheads carry under their title
   (.hero--masthead h1::after). Same 54x2 mark in --gold, so Services and
   Industries sit in the same family rather than being the two without it. */
.art-hero h1::after {
  content: "";
  display: block;
  width: 54px;
  height: 2px;
  margin-top: 22px;
  background: var(--gold);
}

.art-hero .lead {
  max-width: 46ch;
  margin: 0;
  color: rgba(255, 255, 255, 0.76);
  font-size: clamp(0.98rem, 1.15vw, 1.08rem);
  line-height: 1.68;
}

.art-hero-art {
  position: relative;
  /* Shrink-to-fit so justify-self:end actually pins the artwork to the right
     edge; at width:100% the box stayed wide and the image floated inside it. */
  width: auto;
  max-width: 100%;
  /* eased back off the container edge rather than bleeding past it */
  margin-right: clamp(0px, 3.2vw, 56px);
  display: flex;
  align-items: center;
  justify-self: end;
}

.art-hero-art::before {
  content: "";
  position: absolute;
  inset: 12% 8%;
  background: radial-gradient(ellipse, rgba(199, 165, 109, 0.12), transparent 68%);
  pointer-events: none;
}

.art-hero-art img {
  position: relative;
  width: auto;
  max-width: 100%;
  max-height: 290px;
  height: auto;
  object-fit: contain;
  object-position: center;
  filter: drop-shadow(0 20px 28px rgba(5, 15, 25, 0.2));
}

/* Exact landing-page blueprint treatment, scoped to Industries. */
.art-hero .interior-hero-effects {
  z-index: 1;
}

/* Landing-page stacking: the sparks are the lowest layer above the navy,
   with the grid and glow over them, so a burst never crosses a rule. */
.art-hero .interior-hero-sparks { z-index: 0; }
.art-hero .interior-hero-grid,
.art-hero .interior-hero-glow { z-index: 1; }

/* hero.css fades the grid and glow in on load (heroFade / heroGlow);
   nothing gates it there in practice, so run it straight from CSS. */
.art-hero .interior-hero-grid {
  opacity: 0;
  animation: artHeroFade 1100ms ease-out 60ms forwards;
}

.art-hero .interior-hero-grid,
.art-hero .interior-hero-sparks {
  inset: -10% -5%;
  -webkit-mask-image: radial-gradient(ellipse 78% 68% at 62% 45%, #000 35%, transparent 78%);
          mask-image: radial-gradient(ellipse 78% 68% at 62% 45%, #000 35%, transparent 78%);
}

.art-hero .interior-hero-grid {
  background-image:
    linear-gradient(to right, rgba(199, 165, 109, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.055) 1px, transparent 1px),
    linear-gradient(to right, rgba(199, 165, 109, 0.1) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(199, 165, 109, 0.1) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px, 140px 140px, 140px 140px;
}

.art-hero .interior-hero-glow {
  inset: -30% 0 0 auto;
  width: 70vw;
  height: 130%;
  background: radial-gradient(ellipse at center, rgba(199, 165, 109, 0.09), transparent 62%);
  opacity: 0;
  animation: artHeroFade 1600ms ease-out 200ms forwards;
}

.art-hero .interior-hero-spark {
  filter: drop-shadow(0 0 2px rgba(255, 214, 130, 0.22));
}

.art-hero .interior-hero-spark--v {
  width: 1px;
  background: linear-gradient(to bottom, transparent 0%, rgba(199, 165, 109, 0.3) 45%, rgba(238, 210, 156, 0.52) 78%, rgba(246, 232, 199, 0.6) 92%, transparent 100%);
  animation: artSparkFall var(--spark-time, 4s) linear var(--spark-delay, 0s) infinite backwards;
}

.art-hero .interior-hero-spark--h {
  height: 1px;
  background: linear-gradient(to right, transparent 0%, rgba(199, 165, 109, 0.28) 45%, rgba(238, 210, 156, 0.52) 78%, rgba(246, 232, 199, 0.56) 92%, transparent 100%);
  animation: artSparkRight var(--spark-time, 5s) linear var(--spark-delay, 0s) infinite backwards;
}

.art-hero .interior-hero-spark--left {
  background: linear-gradient(to left, transparent 0%, rgba(199, 165, 109, 0.28) 45%, rgba(238, 210, 156, 0.52) 78%, rgba(246, 232, 199, 0.56) 92%, transparent 100%);
  animation: artSparkLeft var(--spark-time, 5s) linear var(--spark-delay, 0s) infinite backwards;
}

@keyframes artHeroFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes artSparkFall {
  0% { transform: translateY(-260px); opacity: 0; }
  12% { opacity: 0.42; }
  26% { opacity: 0.1; }
  42% { opacity: 0.58; }
  58% { opacity: 0.14; }
  74% { opacity: 0.46; }
  88% { opacity: 0.08; }
  100% { transform: translateY(1180px); opacity: 0; }
}

@keyframes artSparkRight {
  0% { transform: translateX(-320px); opacity: 0; }
  12% { opacity: 0.42; }
  26% { opacity: 0.1; }
  42% { opacity: 0.58; }
  58% { opacity: 0.14; }
  74% { opacity: 0.46; }
  88% { opacity: 0.08; }
  100% { transform: translateX(1800px); opacity: 0; }
}

@keyframes artSparkLeft {
  0% { transform: translateX(1800px); opacity: 0; }
  12% { opacity: 0.42; }
  26% { opacity: 0.1; }
  42% { opacity: 0.58; }
  58% { opacity: 0.14; }
  74% { opacity: 0.46; }
  88% { opacity: 0.08; }
  100% { transform: translateX(-320px); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html:not(.force-motion) .art-hero .interior-hero-grid {
    animation: none;
    opacity: 1;
  }

  html:not(.force-motion) .art-hero .interior-hero-glow {
    animation: none;
    opacity: 0.85;
  }

  html:not(.force-motion) .art-hero .interior-hero-spark {
    display: block;
    animation: none !important;
    opacity: 0.5;
  }

  html:not(.force-motion) .art-hero .interior-hero-spark--v {
    transform: translateY(320px);
  }

  html:not(.force-motion) .art-hero .interior-hero-spark--h {
    transform: none;
  }
}

@media (max-width: 980px) {
  .art-hero {
    min-height: auto;
  }

  .art-hero-inner {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    min-height: auto;
    padding-block: 3.25rem 1.75rem;
  }

  .art-hero h1 {
    max-width: none;
    font-size: clamp(2.75rem, 13vw, 4.25rem);
  }

  .art-hero-art {
    width: 100%;
    max-width: 680px;
    margin: 0 auto -0.75rem;
    justify-self: center;
    /* the image is auto-width now, so the flex box has to centre it */
    justify-content: center;
  }

  .art-hero-art img {
    max-height: 230px;
    object-position: center;
  }
}

/* ══ Perspectives search ═══════════════════════════════════════════════════
   The archive's base styles (.archive-hero, .archive-filters, .perspective-
   card) live in content-pages.css, which is minified; this component is new
   and hand-maintained, so it goes here with the session's other additions.

   The field sits in the navy hero under the category chips: those are the
   coarse cut (News / Articles / Speaking Engagements) and this is the fine
   one. It is injected by perspectives-search.js and therefore cannot render
   without the code that makes it work.
   ══════════════════════════════════════════════════════════════════════════ */
.archive-search {
  max-width: 620px;
  margin-top: 30px;
}

.archive-search__label {
  display: block;
  margin-bottom: 10px;
  color: var(--gold-soft);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.archive-search__field {
  position: relative;
  display: flex;
  align-items: center;
}

/* A rule under the field rather than a box around it — the same drafting
   convention the rest of the site uses for an input on navy. */
.archive-search__input {
  width: 100%;
  padding: 14px 42px 14px 0;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.32);
  background: none;
  color: #fff;
  font-family: inherit;
  font-size: 1.05rem;
  transition: border-color 200ms ease;
}

.archive-search__input::placeholder {
  color: rgba(255, 255, 255, 0.42);
}

.archive-search__input:focus {
  outline: none;
  border-bottom-color: var(--gold);
}

/* Chrome draws its own clear affordance on type=search; we ship one that can
   be styled and that screen readers can name. */
.archive-search__input::-webkit-search-cancel-button { display: none; }

.archive-search__clear {
  position: absolute;
  right: 0;
  display: flex;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(255, 255, 255, 0.6);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: color 200ms ease;
}

.archive-search__clear:hover,
.archive-search__clear:focus-visible {
  color: var(--gold);
}

.archive-search__status {
  min-height: 1.2em;
  margin: 12px 0 0;
  color: rgba(255, 255, 255, 0.62);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
}

.archive-search__empty {
  margin: 0;
  color: var(--muted);
  font-size: 1.05rem;
}

/* The hidden ATTRIBUTE is how the JS switches between the server-rendered
   archive and the result set, but the UA rule behind it is only
   [hidden]{display:none} at the lowest specificity — a class setting
   display:grid or display:flex silently beats it, leaving both grids on
   screen at once. These put it back. */
.perspective-grid[hidden],
.archive-search__clear[hidden],
.archive-search__empty[hidden] {
  display: none;
}

/* Matched text inside a result card. The gold wash reads on the card's white
   ground without the yellow highlighter <mark> defaults to. */
.perspective-card mark {
  padding: 0 2px;
  background: rgba(199, 165, 109, 0.32);
  color: inherit;
  font-weight: 600;
}

@media (max-width: 640px) {
  .archive-search { margin-top: 24px; }
  .archive-search__input { font-size: 1rem; }
}
