/* ============================================================================
   components.css — all component + layout styles
   Consumes tokens from tokens.css. Mobile-first; desktop refinements live in
   @media (min-width: 768px) blocks. Class names are plain semantic (no BEM,
   no utility-first) per CLAUDE.md L1054.
   Line refs (e.g. L188) point back to CLAUDE.md.
   ============================================================================ */

/* ============================================================================
   1. Containers (L145–157)
   ============================================================================ */

.page {
  max-width: var(--layout-max-width);
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--layout-padding-mobile);
  padding-right: var(--layout-padding-mobile);
}

.prose {
  max-width: var(--prose-max-width);
}

/* Escape a constrained ancestor and span the full viewport */
.full-bleed {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

@media (min-width: 768px) {
  .page {
    padding-left: var(--layout-padding-desktop);
    padding-right: var(--layout-padding-desktop);
  }
}

/* ============================================================================
   2. Sections — vertical rhythm (L159–170)
   Section padding sets the top/bottom whitespace. Within a section: the gap
   AFTER a headline uses --space-headline-to-body; the gap BEFORE a CTA uses
   --space-body-to-cta; gaps BETWEEN paragraphs inherit the 1.5em rule from
   base.css (so prose breathes correctly inside section rhythm).
   ============================================================================ */

.section {
  padding-top: var(--space-section);
  padding-bottom: var(--space-section);
}

/* Anything immediately after a headline gets pushed down by headline-to-body */
.section > .display + *,
.section > .section-headline + *,
.section > .medium-headline + *,
.section > h1 + *,
.section > h2 + *,
.section > h3 + * {
  margin-top: var(--space-headline-to-body);
}

/* CTAs pull away from the preceding body with the larger body-to-CTA gap */
.section > .cta {
  margin-top: var(--space-body-to-cta);
}

/* Deliberate tight rhythm — headline + body sit very close. Applied
   ALONGSIDE .section (e.g. <section class="section section-tight">). Only
   zeros the headline gap; paragraph-to-paragraph spacing remains unchanged. */
.section-tight > .display + *,
.section-tight > .section-headline + *,
.section-tight > .medium-headline + *,
.section-tight > h1 + *,
.section-tight > h2 + *,
.section-tight > h3 + * {
  margin-top: 0;
}

/* Center the contents of a section — used for "moment of return" beats
   like the homepage closing, where text and CTA sit on the same axis as
   a preceding centered inset image. Applied alongside .section.
   Prose paragraphs inside also get auto margins so their max-width-constrained
   block sits centered (not just the text inside the block). */
.section-center {
  text-align: center;
}

.section-center > p {
  margin-left: auto;
  margin-right: auto;
}

/* Halve the top/bottom padding of a section. Used in pairs around a
   between-sections image to compress a unified visual beat (e.g. quote →
   inset image → CTA reading as one closing movement instead of three
   orphaned sections). Applied alongside .section. */
.section-tight-top {
  padding-top: clamp(40px, 6vw, 80px);
}

.section-tight-bottom {
  padding-bottom: clamp(40px, 6vw, 80px);
}

/* ----------------------------------------------------------------------------
   Journal-post article rhythm (scoped to <body class="journal-post">)
   Journal posts stack many short sections — an em-dash label, then the prose it
   introduces — plus margin-less standalone images. Because every .section pads
   top AND bottom, adjacent sections double their padding into ~160px dead gaps,
   so the label floats away from its paragraph and the page reads as glitchy
   instead of editorial. Here, section spacing is driven by COLLAPSING MARGINS
   instead, giving one clean gap between blocks: a full break above each label,
   the label hugging the prose below it, and a tighter rhythm around photos.
   ---------------------------------------------------------------------------- */
.journal-post main > .section {
  padding-top: 0;
  padding-bottom: 0;
}
/* In label-only sections the label's own 32px is redundant — the section
   margins set the spacing. (Kept on the title section's label, which sits with
   an h1 and isn't an only-child.) */
.journal-post main > .section > .section-label:only-child {
  margin-bottom: 0;
}
/* Default editorial break between stacked blocks. */
.journal-post main > * + * {
  margin-top: var(--space-section);
}
/* Anything adjacent to a standalone photo sits on the tighter photo rhythm
   (and keeps consecutive insets from butting together). */
.journal-post main > * + img,
.journal-post main > * + .photo-pair,
.journal-post main > img + *,
.journal-post main > .photo-pair + * {
  margin-top: var(--space-photo);
}
/* The em-dash label hugs the prose it introduces. */
.journal-post main > .section:has(> .section-label:only-child) + .section {
  margin-top: var(--space-headline-to-body);
}
/* The last section's bottom padding is now zero — restore space before the footer. */
.journal-post main {
  padding-bottom: var(--space-section);
}

/* ============================================================================
   3. Headlines (L79–86, italic rule L93–99)
   .display is italic by default (every locked use is italic).
   .section-headline and .medium-headline are roman (informational).
   ============================================================================ */

.display {
  font-family: var(--font-display);
  font-weight: var(--font-weight-extralight);
  font-style: italic;
  font-size: var(--size-display);
  color: var(--color-nav);
  line-height: 1.0;
  text-align: center;
}

.section-headline {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-section-headline);
  color: var(--color-nav);
  line-height: 1.1;
}

.medium-headline {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-medium-headline);
  color: var(--color-nav);
  line-height: 1.15;
}

/* ============================================================================
   4. Labels (L86) — small all-caps tracked, color inherits from context
   ============================================================================ */

.label {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
}

/* Editorial label — small em-dash-prefixed tag that sits above a section
   ("— Philosophy", "— Weddings at", "— From a client"). The structural
   move that pushes the page from "big titles website" toward "magazine
   spread." Wider tracking than .label, mixed-case (preserves the em-dash
   typography), secondary color so it sits beneath the headline visually. */
.section-label {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-section-label);
  letter-spacing: var(--tracking-section-label);
  text-transform: uppercase;
  color: var(--color-text-secondary);
  text-align: center;
  margin-bottom: 32px;
}

/* Vendor-credit byline links — currently the only links that appear inside a
   .section-label. Make them obviously clickable by reusing the site's thin
   always-on underline link language (same register as the .cta underline),
   kept in the inherited grey so the byline still reads as a quiet masthead.
   Hover fades to 60% to match the nav links. */
.section-label a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--color-text-tertiary);
  text-underline-offset: 4px;
  transition: opacity var(--motion-duration-hover) var(--motion-easing);
}

.section-label a:hover {
  opacity: 0.6;
}

/* Work-story chapter headings (.section-label.chapter-label) — the 11px gray
   label disappears while scrolling, so these stay an UPPERCASE tracked label
   (same register as the rest of the system) but a touch larger and in dark ink.
   Visible as a waypoint without becoming a headline that out-shouts the couple
   name and venue above it. Scoped via the extra class so homepage labels, the
   intro subtitle, and the credits byline keep the small size. Two-class selector
   wins regardless of source order. */
.section-label.chapter-label {
  font-size: 16px;
  color: var(--color-nav);
}

/* ============================================================================
   5. Bullet lists (L1330–1335) — em-dash markers for editorial restraint
   ============================================================================ */

.bullet-list {
  list-style: none;
  padding-left: 0;
  max-width: var(--prose-max-width);
}

.bullet-list > li {
  position: relative;
  padding-left: 1.5em;
}

.bullet-list > li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--color-text-tertiary);
}

.bullet-list > li + li {
  margin-top: 12px;
}

/* ============================================================================
   5b. Pricing table — investment-guide.html packages.
   No cell borders, no row striping, no shaded headers. Hairline rule
   between rows. Editorial spec-sheet feel, not SaaS pricing card.
   ============================================================================ */

.pricing-table {
  width: 100%;
  max-width: var(--prose-max-width);
  border-collapse: collapse;
  text-align: left;
}

.pricing-table th {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-section-label);
  letter-spacing: var(--tracking-section-label);
  text-transform: uppercase;
  color: var(--color-text-secondary);
  padding: 16px 0;
  border-bottom: 1px solid var(--color-text-tertiary);
}

.pricing-table td {
  font-family: var(--font-text);
  font-weight: var(--font-weight-body);
  font-size: var(--size-body);
  color: var(--color-text);
  padding: 24px 0;
  border-bottom: 1px solid var(--color-text-tertiary);
}

.pricing-table tr:last-child td {
  border-bottom: none;
}

/* ============================================================================
   6. Text-link CTAs (L935–944)
   Always-on underline under the text. Arrow appended via ::after, translates
   right on hover. Underline stays put — arrow slides out from under it.
   ============================================================================ */

.cta {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: inherit;
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1px solid currentColor;
}

.cta::after {
  content: " →";
  display: inline-block;
  margin-left: 0.4em;
  transition: transform var(--motion-duration-hover) var(--motion-easing);
}

.cta:hover::after {
  transform: translateX(6px);
}

/* ============================================================================
   7. Site nav (L188–203, 197–201, 929–933, 940–946)
   Fixed at top. Mobile: monogram centered, MENU absolute top-right.
   Desktop: monogram centered, link row beneath.
   ============================================================================ */

.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 24px var(--layout-padding-mobile);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  background-color: var(--color-bg);
  transition: transform var(--motion-duration-hover) var(--motion-easing);
}

@media (min-width: 768px) {
  .site-nav {
    padding: 32px var(--layout-padding-desktop);
  }
}

/* Overlaid on hero — transparent background, light-colored links */
.site-nav.is-overlay {
  background-color: transparent;
}

/* When the mobile menu is open, the white overlay would render the
   overlay-mode nav (white text + inverted monogram) invisible. Body
   gets .menu-is-open from main.js while the menu is open — these rules
   temporarily revert the nav to its solid-background dark-text styling
   so MENU/CLOSE and the monogram stay visible. */
body.menu-is-open .site-nav.is-overlay {
  background-color: var(--color-bg);
}

body.menu-is-open .site-nav.is-overlay .nav-link,
body.menu-is-open .site-nav.is-overlay .menu-trigger {
  color: var(--color-nav);
}

body.menu-is-open .site-nav.is-overlay .nav-monogram {
  filter: none;
}

/* JS toggles this when scrolling down past the hero */
.site-nav.is-hidden {
  transform: translateY(-100%);
}

.nav-monogram-link {
  display: block;
  line-height: 0;
  transition: opacity var(--motion-duration-hover) var(--motion-easing);
}

.nav-monogram-link:hover {
  opacity: 0.6;
}

.site-nav.is-overlay .nav-monogram {
  filter: invert(1);
}

.nav-monogram {
  display: block;
  height: var(--logo-nav-height);
  width: auto;
}

.nav-links {
  display: none;
  list-style: none;
  padding: 0;
  margin: 0;
}

@media (min-width: 768px) {
  .nav-links {
    display: flex;
    gap: 32px;
  }
}

.nav-link {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-nav);
  text-decoration: none;
  padding-bottom: 4px;
  transition: opacity var(--motion-duration-hover) var(--motion-easing);
}

.site-nav.is-overlay .nav-link {
  color: var(--color-bg);
}

.nav-link:hover {
  opacity: 0.6;
}

.nav-link.is-active {
  border-bottom: 1px solid currentColor;
}

/* ============================================================================
   8. Mobile menu (L956–969)
   Trigger top-right on mobile only. Overlay covers everything beneath the nav
   (z-index 99 sits below site-nav's 100 so nav stays visible above overlay).
   ============================================================================ */

.menu-trigger {
  position: absolute;
  top: 24px;
  right: var(--layout-padding-mobile);
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-nav);
}

.site-nav.is-overlay .menu-trigger {
  color: var(--color-bg);
}

/* Inverted overlay — for pages whose hero is high-key/bright (a white wall,
   pale sky) behind the nav, where the default white overlay text washes out.
   Add `is-overlay-inverted` alongside `is-overlay` on the <nav>: keeps the nav
   transparent but switches the monogram + links to dark. Dark-hero pages keep
   the default white overlay. Chosen over a gradient scrim, which reads as a
   grey haze on pristine-white heroes. The is-active underline uses
   currentColor, so it follows the link color automatically. */
.site-nav.is-overlay.is-overlay-inverted .nav-monogram {
  filter: none;
}

.site-nav.is-overlay.is-overlay-inverted .nav-link,
.site-nav.is-overlay.is-overlay-inverted .menu-trigger {
  color: var(--color-nav);
}

@media (min-width: 768px) {
  .menu-trigger {
    display: none;
  }
}

.menu-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 99;
  background-color: var(--color-bg);
  display: none;
  align-items: center;
  justify-content: center;
}

.menu-overlay.is-open {
  display: flex;
}

.menu-overlay-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.menu-overlay-link {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: 32px;
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-nav);
  text-decoration: none;
  padding-bottom: 4px;
}

.menu-overlay-link.is-active {
  border-bottom: 1px solid currentColor;
}

/* ============================================================================
   9. Site footer (L219–225)
   ============================================================================ */

.site-footer {
  padding-top: clamp(60px, 8vw, 96px);
  padding-bottom: clamp(60px, 8vw, 96px);
  padding-left: var(--layout-padding-mobile);
  padding-right: var(--layout-padding-mobile);
  background-color: var(--color-bg);
  color: var(--color-text-secondary);
}

@media (min-width: 768px) {
  .site-footer {
    padding-left: var(--layout-padding-desktop);
    padding-right: var(--layout-padding-desktop);
  }
}

.footer-lockup {
  display: block;
  height: var(--logo-footer-height-mobile);
  width: auto;
  margin-bottom: 32px;
}

@media (min-width: 768px) {
  .footer-lockup {
    height: var(--logo-footer-height-desktop);
  }
}

.footer-meta {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.footer-meta a {
  color: inherit;
  transition: opacity var(--motion-duration-hover) var(--motion-easing);
}

.footer-meta a:hover {
  opacity: 0.6;
}

.footer-meta-line + .footer-meta-line {
  margin-top: 12px;
}

/* ============================================================================
   10. Hero (L210, 1162–1163) — 100vh full-bleed photograph, no overlay text
   ============================================================================ */

.hero {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  height: 100vh;
  overflow: hidden;
  background-color: var(--color-surface);
}

.hero-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* ============================================================================
   11. Venue strip (L213–214, 358–359) — single line, no logos, no dark bg
   ============================================================================ */

.venue-strip {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text);
  text-align: center;
}

/* .venue-strip-label removed — venue strip now uses the shared .section-label
   class above the venue list, consistent with Philosophy and Client Quote sections. */

/* Investment guide (.guide-page on <body>) — a long-form info page committed to a
   single left axis. The default section-label + venue-strip are centered, which on
   this page floats them over left-aligned body content (two competing axes). These
   overrides put every label on its content's left edge. The opening brand statement
   and closing stay centered via .section-center as deliberate bookends. Scoped to
   .guide-page so the centered labels on the homepage and work-story pages are unaffected. */
.guide-page .section-label { text-align: left; }
.guide-page .venue-strip { text-align: left; }

/* Packages table on the guide — this is the post-inquiry page, so the prices are
   the one figure the reader came for. Give the dollar amounts a modest hierarchy
   bump (focal, not loud — light weight, primary ink) and recede the coverage label
   to secondary grey. Reads as a calm rate card, not a sales page. */
.guide-page .pricing-table td:last-child {
  font-size: 24px;
  line-height: 1.2;
  color: var(--color-nav);
}
.guide-page .pricing-table td:first-child {
  color: var(--color-text-secondary);
}

/* ============================================================================
   12. Client quote (L101–108, 215–218)
   Italic, centered. Sized smaller than section headlines so the quote reads
   as a moment, not a competing peak.
   ============================================================================ */

.client-quote {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-style: italic;
  font-size: var(--size-medium-headline);
  color: var(--color-nav);
  text-align: center;
  line-height: 1.2;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}

.client-quote-attribution {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  text-align: center;
  margin-top: 24px;
}

/* ============================================================================
   13. Inset images — two-width system (L172–178)
   Mobile: insets reflow to 100% of the page container (aligns with the body
   text gutter at the 24px page padding). Desktop: 60% default, 50% statement
   with three-position alignment (centered, left, right).
   Full-bleed images use .full-bleed (escapes the page container, edge-to-edge).
   ============================================================================ */

/* Mobile: insets sit at ~38px from each viewport edge (P2 framing) — a
   deliberate gutter that reads as "framed image" rather than "edge-to-edge
   photo." 100% width capped at calc(100vw - 76px) achieves this while still
   filling the page container when viewport is narrow.
   Three-position alignment (.is-left, .is-right, default centered) applies
   at all viewport widths — at P2 mobile width the asymmetry reads correctly
   (image hits one page edge with the wider gutter on the opposite side).
   Desktop: 60% / 50% width with the same three-position alignment. */
.inset-default,
.inset-statement {
  display: block;
  width: 100%;
  max-width: calc(100vw - 76px);
  margin-left: auto;
  margin-right: auto;
}

.inset-default.is-left,
.inset-statement.is-left {
  margin-left: 0;
  margin-right: auto;
}

.inset-default.is-right,
.inset-statement.is-right {
  margin-left: auto;
  margin-right: 0;
}

@media (min-width: 768px) {
  .inset-default {
    width: 60%;
    max-width: none;
  }

  .inset-statement {
    width: 50%;
    max-width: none;
  }
}

/* Work-story photo sequence — vertical breathing room between consecutive
   photos. The site's rhythm normally comes from .section padding around text
   blocks, but /work/ pages stack many photos with no text between them, so
   without this they butt together. Margin-top on every item except the first
   keeps a consistent gap across full-bleed, inset, and paired photos. */
.photo-sequence > * + * {
  margin-top: var(--space-photo);
}

/* 2-up photo pairing — a rhythm device for work-story pages (detail clusters,
   portrait pairs). Side-by-side on desktop halves the vertical space of two
   stacked insets (helps the page-length problem) and adds the "pieced
   together" texture without becoming a dense gallery grid. Mobile: stacks to
   a single column at the same inset framing as .inset-default. Sized to match
   the 60% inset rhythm so pairs read as part of the same system. */
.photo-pair {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(12px, 2vw, 24px);
  width: 100%;
  max-width: calc(100vw - 76px);
  margin-left: auto;
  margin-right: auto;
}

.photo-pair img {
  width: 100%;
}

@media (min-width: 768px) {
  .photo-pair {
    grid-template-columns: 1fr 1fr;
    width: 60%;
    max-width: none;
  }
}

/* ============================================================================
   14. Portfolio grid (L238–246, 181) — 3 col desktop → 2 col tablet → 1 col mobile
   ============================================================================ */

.portfolio-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(24px, 4vw, 64px);
  align-items: start;
}

@media (min-width: 768px) {
  .portfolio-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .portfolio-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.portfolio-card {
  display: block;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.portfolio-card-image {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background-color: var(--color-surface);
}

.portfolio-card-image.is-landscape {
  aspect-ratio: 3 / 2;
}

.portfolio-card-meta {
  margin-top: 16px;
}

.portfolio-card-names {
  font-family: var(--font-text);
  font-weight: var(--font-weight-body);
  font-size: var(--size-body);
  color: var(--color-nav);
}

.portfolio-card-location {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-top: 4px;
}

.portfolio-filter {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-bottom: clamp(40px, 6vw, 80px);
}

.portfolio-filter-item {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-secondary);
  text-decoration: none;
  padding-bottom: 4px;
}

.portfolio-filter-item.is-active {
  color: var(--color-nav);
  border-bottom: 1px solid currentColor;
}

/* ============================================================================
   15. Journal grid (L280–292) — 2 col desktop → 1 col mobile
   ============================================================================ */

.journal-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(32px, 5vw, 80px);
}

@media (min-width: 768px) {
  .journal-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.journal-card {
  display: block;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.journal-card-image {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background-color: var(--color-surface);
}

.journal-card-meta {
  margin-top: 16px;
}

.journal-category {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: 8px;
}

.journal-card-names {
  font-family: var(--font-text);
  font-weight: var(--font-weight-body);
  font-size: var(--size-body);
  color: var(--color-nav);
}

.journal-card-venue {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-labels);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-top: 4px;
}

/* ============================================================================
   16. Process — numbered list "01 — Inquiry" (L254, 489–505)
   ============================================================================ */

.process-list {
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 6vw, 80px);
  list-style: none;
  padding: 0;
  margin: 0;
}

.process-step-title {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--size-medium-headline);
  color: var(--color-nav);
  line-height: 1.15;
  margin-bottom: 16px;
}

.process-step-body {
  max-width: var(--prose-max-width);
}

/* ============================================================================
   17. Fade-up motion (L920–925, 1168–1176)
   Wrapped in prefers-reduced-motion guard — users with reduced-motion see
   content instantly. Base (no-JS / no-reduced-motion) state is visible.
   ============================================================================ */

@media (prefers-reduced-motion: no-preference) {
  .fade-up {
    opacity: 0;
    transform: translateY(var(--motion-fade-distance));
    transition:
      opacity var(--motion-duration-scroll) var(--motion-easing),
      transform var(--motion-duration-scroll) var(--motion-easing);
  }

  .fade-up.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ============================================================================
   18. Focus states (L1178–1180) — keyboard-only outline, never disrupts pointer
   ============================================================================ */

:focus-visible {
  outline: 1px solid var(--focus-outline-color);
  outline-offset: var(--focus-outline-offset);
}
