/* ==========================================================================
   Page sections
   ========================================================================== */

/* --------------------------------------------------------------------------
   section INTRO  (Figma 2001:9958 — 1920×1080)
   content frame 1104×636 @ x408 y364 (horizontally centred)
   subheading 16 · gap 29 · line 1 160 · line 2 160 · gap 134 · button 137
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  /* content frame starts 364/1080 down the frame and ends 80px above its
     foot — expressed proportionally so it holds at any viewport height. */
  padding-top: 33.7svh;
  padding-bottom: 7.4svh;
  /* `clip`, not `hidden` — same reason as <body> in base.css: keeps the
     aurora canvas and background grid from causing horizontal scroll
     without turning .hero into a scroll container of its own. */
  overflow: clip;
}

/* Empty in the design — reserved for the background video/still that the
   Figma frame masks in but never fills.
   [derived] Filled with a canvas aurora: three slow-drifting radial fields
   that follow the pointer. Cheap (60×34 backing store, upscaled + blurred)
   and it gives the hero the depth a flat navy plate cannot. */
.hero__media {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.hero__aura {
  position: absolute;
  inset: -12%;
  width: 124%;
  height: 124%;
  filter: blur(46px) saturate(130%);
  opacity: 0.55;
  transition: opacity 1.2s var(--ease-out);
}

:root[data-theme="light"] .hero__aura {
  opacity: 0.4;
  mix-blend-mode: multiply;
}

/* A faint 1px grid, masked to a soft vignette. Reads as paper texture at
   rest and gives the parallax something to bite on. [derived] */
.hero__grid {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(var(--color-rule-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--color-rule-soft) 1px, transparent 1px);
  background-size: calc(100% / 12) calc(100% / 12);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 40%, #000 20%, transparent 72%);
  mask-image: radial-gradient(120% 90% at 50% 40%, #000 20%, transparent 72%);
  opacity: 0.5;
}

/* [derived] The original 1104px measure was designed for a two-word name.
   The sentence-length title needs a broader fluid measure so it can scale
   down naturally without producing short or isolated lines. */
.hero__content {
  position: relative;
  display: flex;
  flex-direction: column;
  /* Stretches to fill the hero's inner height (the section is now a flex
     column) so .hero__scroll's auto margin below has room to push it
     all the way down to the section's foot. */
  flex: 1;
  width: 100%;
  max-width: calc(
    clamp(280px, calc(72 * var(--vw)), 1382px) + var(--gutter) * 2
  );
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* The Figma subheading is a 381px frame whose children overflow it to the
   right (7…426), so the group reads ~26px right of the content centre.
   Reproduced with the frame's own percentages rather than a centred flex
   row, which would lose that offset. */
.hero__eyebrow {
  position: relative;
  width: clamp(240px, calc(19.844 * var(--vw)), 381px);
  height: 16px;
  margin-inline: auto;
  font-weight: 700;
  font-size: var(--fs-body);
  line-height: 1;
  white-space: nowrap;
}

.hero__eyebrow-left,
.hero__eyebrow-right {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.hero__eyebrow-left {
  right: 67.19%; /* text ends at 125/381 */
  text-align: right;
}

.hero__eyebrow-right {
  left: 76.9%; /* text starts at 293/381 */
}

.hero__eyebrow-rule {
  position: absolute;
  top: 43.75%; /* 7/16 */
  left: 38.06%; /* 145/381 */
  width: 33.33%; /* 127/381 */
  height: 1px;
  background-color: var(--color-line);
}

.hero__title {
  margin-top: clamp(12px, calc(1.51 * var(--vw)), 29px);
  color: var(--color-cream);
  /* [derived] Mobile starts at 36px and grows to 40px on wider phones;
     tablet and desktop continue through the breakpoint rules below. */
  font-size: clamp(36px, calc(9.25 * var(--vw)), 40px);
  text-align: center;
  text-wrap: balance;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

/* Increase the sentence scale from tablet landscape upward while leaving
   narrower phones on the compact base size. */
@media (min-width: 700px) {
  .hero__title {
    font-size: clamp(40px, calc(5 * var(--vw)), 52px);
  }
}

/* Continue growing smoothly beyond 1024px, reaching the 86px ceiling near
   the 1920px design width without a size drop at the breakpoint. */
@media (min-width: 1025px) {
  .hero__title {
    font-size: clamp(52px, calc(3.8 * var(--vw) + 13.04px), 86px);
  }
}

.hero__scroll {
  position: relative;
  display: block;
  width: clamp(88px, calc(7.135 * var(--vw)), 137px);
  height: clamp(88px, calc(7.135 * var(--vw)), 137px);
  /* [derived] Figma gives it a fixed 134px gap after the title, which only
     reads as "near the foot of the hero" at the frame's exact proportions.
     Pin it to the section's bottom instead with a flex auto-margin, so it
     sits at the foot of the hero on every viewport regardless of how tall
     the eyebrow/title stack renders. */
  margin: auto auto 0;
}

.hero__scroll img {
  width: 100%;
  height: 100%;
  animation: spin 24s linear infinite;
}

:root[data-theme="light"] .hero__scroll img {
  filter: brightness(0) saturate(100%);
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__scroll img {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   section CONTENT  (Figma 2001:9971 — 1140×456 @ y1280)
   Sections on the landing page sit on a consistent 200px rhythm.
   -------------------------------------------------------------------------- */

.statement {
  padding-top: var(--sp-200);
}

.statement__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-80);
  width: 100%;
  max-width: calc(1140px + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
  text-align: center;
}

.statement__text {
  color: var(--color-text);
}

/* --- Counter (shared by section CONTENT and section ABOUT) --------------- */

.counter {
  display: flex;
  flex-direction: column;
  align-items: center;
  white-space: nowrap;
}

.counter__value {
  color: var(--color-cream);
}

.counter__label {
  color: var(--color-text);
}

/* 485px ring — a 1px white stroke at 20%, so CSS rather than an exported SVG. */
.counter--ring {
  position: relative;
  justify-content: center;
  width: clamp(260px, calc(25.26 * var(--vw)), 485px);
  height: clamp(260px, calc(25.26 * var(--vw)), 485px);
  border: 1px solid var(--color-rule);
  border-radius: 50%;
}

/* --------------------------------------------------------------------------
   section FEATURED WORKS  (Figma 2001:9976 — 1680×4680 @ y1936)
   item 1680×840 · 120px gap · tags inset 80 · marquee top 260
   -------------------------------------------------------------------------- */

.works {
  padding-top: var(--sp-200);
}

/* [derived] Section eyebrow — the design jumps straight from the statement
   into the cards, which leaves the reader without an anchor. */
.works__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-24);
  width: 100%;
  max-width: calc(var(--content-w) + var(--gutter) * 2);
  margin: 0 auto var(--sp-60);
  padding-inline: var(--gutter);
  border-bottom: 1px solid var(--color-rule);
  padding-bottom: var(--sp-24);
}

.works__head p {
  font-weight: 700;
  font-size: var(--fs-caps);
  line-height: var(--lh-caps);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.works__list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-120);
  width: 100%;
  max-width: calc(var(--content-w) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --- Sticky stack [derived] ---------------------------------------------
   Each card pins just under the header and the next one rides up over it,
   so the five works deal like a deck instead of scrolling past as a list.
   Requires <body> to use overflow-x: clip rather than hidden — see base.css.
   The scale/brightness falloff on the covered card is scrubbed in JS.     */
.works__item {
  position: sticky;
  top: calc(var(--header-h) - 20px);
  will-change: transform;
}

.work {
  position: relative;
  display: block;
  aspect-ratio: 1680 / 840;
  overflow: hidden;
  isolation: isolate;
  border-radius: 2px;
  box-shadow: var(--shadow-card);
  transform-origin: 50% 0;
}

.work__media,
.work__overlay {
  position: absolute;
  inset: 0;
}

.work__media {
  overflow: hidden;
}

.work__media img {
  width: 100%;
  /* Taller than the frame so the inner parallax has somewhere to travel. */
  height: 118%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out),
    filter var(--dur-slow) var(--ease-out);
  will-change: transform;
}

/* [derived] Cards rest slightly desaturated and bloom to full colour on
   hover, which makes a five-card stack read as one considered set rather
   than five competing photographs. Kept mild — heavier desaturation plus
   the design's 0.5 scrim turned the photography to mud. */
.work__media img {
  filter: saturate(0.72) contrast(1.03);
}

.work:hover .work__media img,
.work:focus-visible .work__media img {
  filter: saturate(1) contrast(1);
}

.work--contain {
  background-color: #a0e0f0;
}

.work--contain .work__media img {
  object-fit: contain;
}

.work__overlay {
  background-color: #000;
  opacity: 0.44;
  transition: opacity var(--dur-base) var(--ease-out);
}

/* Figma only supplies the hover state ("item 2 [hover]"), so that state is
   the resting style and hover simply lifts the scrim a little. */
.work:hover .work__overlay,
.work:focus-visible .work__overlay {
  opacity: 0.32;
}

.work__tags {
  position: absolute;
  inset: clamp(20px, calc(4.167 * var(--vw)), 80px)
    clamp(20px, calc(4.167 * var(--vw)), 80px) auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  z-index: 2;
}

.tag {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding-inline: 17px;
  border: 1px solid var(--color-rule);
  border-radius: 18px;
  color: var(--color-text);
  font-weight: 700;
  font-size: var(--fs-caps);
  line-height: var(--lh-caps);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  white-space: nowrap;
}

/* [derived] Light theme: the card scrim stays black in both themes, so the
   overlay type must not follow the inverted text tokens. Tags become solid
   white pills with ink text; the running title stays white. */
:root[data-theme="light"] .tag {
  background-color: #fff;
  border-color: rgb(27 36 56 / 0.18);
  color: #1b2438;
}

.work__marquee {
  position: absolute;
  left: 0;
  right: 0;
  /* Running project title, anchored to the card's lower inset. The middle
     term is 0, so this currently resolves to a flat 20px at every width. */
  top: auto;
  bottom: clamp(20px, calc(0 * var(--vw)), 80px);
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--color-cream);
}

:root[data-theme="light"] .work__marquee {
  color: #fff;
}

/* --------------------------------------------------------------------------
   section ABOUT  (Figma 2001:10022 — 1920×1423 @ y6816)
   header 1680×384 · stage 1681×1248 @ y175
   img1 670×1005 @ (120,175) · ring 485 @ (873,466)
   img3 360×540 @ (1441,709) · img2 485 circle @ (548,938)
   -------------------------------------------------------------------------- */

.about {
  padding-top: var(--sp-200);
}

.about__inner {
  position: relative;
  width: 100%;
  max-width: calc(var(--content-w) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.about__header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, calc(2.865 * var(--vw)), 55px);
  min-height: clamp(200px, calc(20 * var(--vw)), 384px);
}

.about__label {
  color: var(--color-text);
}

.about__body {
  color: var(--color-text);
}

/* The three images and the ring are absolutely placed inside a 1680×1248
   stage — this block is genuinely overlapping artwork, not a flow layout. */
/* The image stage starts 175px into the section while the header runs 384px,
   so the collage deliberately overlaps the copy by 209px. */
.about__stage {
  position: relative;
  margin-top: calc(-1 * clamp(0px, calc(10.885 * var(--vw)), 209px));
  aspect-ratio: 1680 / 1248;
}

.about__img {
  position: absolute;
  margin: 0;
  overflow: hidden;
}

.about__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.2s var(--ease-out), filter var(--dur-slow) var(--ease-out);
}

.about__img:hover img {
  transform: scale(1.05);
}

.about__img--1 {
  left: 0;
  top: 0;
  width: 39.88%; /* 670/1680 */
  height: 80.53%; /* 1005/1248 */
}

.about__img--3 {
  left: 78.63%; /* 1321/1680 */
  top: 42.79%; /* 534/1248 */
  width: 21.43%; /* 360/1680 */
  height: 43.27%; /* 540/1248 */
}

.about__img--3 img {
  object-position: bottom;
}

.about__img--2 {
  left: 25.48%; /* 428/1680 */
  top: 61.14%; /* 763/1248 */
  width: 28.87%; /* 485/1680 */
  aspect-ratio: 1;
  height: auto;
  border-radius: 50%;
}

.about__img--2 img {
  object-position: bottom;
}

.about .counter--ring {
  position: absolute;
  left: 44.82%; /* (873-120)/1680 */
  top: 23.32%; /* (466-175)/1248 */
  width: 28.87%;
  height: auto;
  aspect-ratio: 1;
  container-type: inline-size;
}

/* [derived] Keep "Years of Experience" on one line at every width. Its
   shared fs-h4 size bottoms out at 20px before this percentage-sized ring
   stops shrinking, so the label used to cross the stroke on tablets.
   Container units tie this one label to the ring itself instead: it stays at
   the designed 20px whenever space allows and scales only as the circle gets
   smaller. The 14px floor still leaves at least 17px of measured clearance
   at the tightest pre-mobile width. The vw declaration is a fallback for
   browsers without container-query units. */
.about .counter--ring .counter__label {
  font-size: clamp(14px, calc(1.64 * var(--vw)), 20px);
  font-size: clamp(14px, 6.5cqw, 20px);
  white-space: nowrap;
  text-align: center;
}

/* --------------------------------------------------------------------------
   section AWARDS  (Figma 2001:10034 — 1680×824 @ y8439)
   hairline top per item · 60px below it · two 814.5 columns, 51px gap
   -------------------------------------------------------------------------- */

.credentials {
  padding-top: var(--sp-200);
}

.credentials__list {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.credentials__item {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, calc(2.656 * var(--vw)), 51px);
  align-items: center;
  padding-top: var(--sp-60);
  /* Replaces the list's old `gap: var(--sp-50)` — each item now carries its
     own trailing space instead of the list spacing them. */
  padding-bottom: var(--sp-50);
  border-top: 1px solid var(--color-rule);
  transition: padding var(--dur-base) var(--ease-out);
}

/* [derived] The rule above each row draws in from the left on hover, and a
   soft wash follows the pointer across the row. */
.credentials__item::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--color-yellow);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-slow) var(--ease-out);
}

/* inset: 0 — the -1px top offset left the row's own border-top uncovered,
   and items sized by their content meant the glow stopped short of the
   rule below. Stretch to the full element instead.
   [derived] Masked at the left/right edges so the wash reads as a soft
   spotlight that fades into the background, rather than a hard-edged panel
   the row's own bounding box clips flat when the cursor nears either side. */
.credentials__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    28rem 20rem at var(--px, 50%) var(--py, 50%),
    color-mix(in srgb, var(--color-yellow) 9%, transparent),
    transparent 70%
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    black clamp(32px, calc(4 * var(--vw)), 96px),
    black calc(100% - clamp(32px, calc(4 * var(--vw)), 96px)),
    transparent
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black clamp(32px, calc(4 * var(--vw)), 96px),
    black calc(100% - clamp(32px, calc(4 * var(--vw)), 96px)),
    transparent
  );
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.credentials__item:hover::before {
  transform: scaleX(1);
}

.credentials__item:hover::after {
  opacity: 1;
}

.credentials__term {
  transition: transform var(--dur-slow) var(--ease-out);
}

.credentials__item:hover .credentials__term {
  transform: translateX(clamp(4px, calc(0.6 * var(--vw)), 14px));
}

.credentials__item--last {
  padding-bottom: var(--sp-60);
  border-bottom: 1px solid var(--color-rule);
}

.credentials__term {
  color: var(--color-yellow);
}

.credentials__desc {
  margin: 0;
  color: var(--color-text);
}

.credentials__bullets {
  list-style: disc;
  padding-left: 36px;
}

.btn-circle {
  display: grid;
  place-items: center;
  width: clamp(132px, calc(8.854 * var(--vw)), 170px);
  height: clamp(132px, calc(8.854 * var(--vw)), 170px);
  margin: var(--sp-120) auto 0;
  border-radius: 50%;
  background-color: var(--color-invert-surface);
  color: var(--color-invert-text);
  font-weight: 700;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  text-align: center;
  transition: background-color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn-circle:hover,
.btn-circle:focus-visible {
  background-color: var(--color-yellow);
  transform: scale(1.04);
}

/* [derived] The disc is magnetic; JS writes a translate to the wrapper and
   the label counter-drifts inside it for a bit of parallax depth. */
.btn-circle__label {
  display: block;
  will-change: transform;
  pointer-events: none;
}

/* Footer sits on the same 200px rhythm as every other section. */
.site-footer {
  margin-top: var(--sp-200);
}

/* --------------------------------------------------------------------------
   section 404  (Figma 2001:9646 — 1920×1080, content 2355×584 @ y416)
   marquee @ 34 (h160) · copy @ 240 (w600) · disc @ 384 (200)
   -------------------------------------------------------------------------- */

.error {
  display: flex;
  align-items: flex-start;
  min-height: 100svh;
  padding-top: 38.52svh; /* 416/1080 */
  overflow: hidden;
}

.error__content {
  width: 100%;
  padding-top: clamp(16px, calc(1.771 * var(--vw)), 34px);
  text-align: center;
}

.error__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--fs-display-lg);
  line-height: var(--lh-display-lg);
  letter-spacing: var(--ls-display);
  color: var(--color-cream);
}

.error__copy {
  width: 100%;
  max-width: calc(600px + var(--gutter) * 2);
  margin: clamp(24px, calc(2.396 * var(--vw)), 46px) auto 0;
  padding-inline: var(--gutter);
  color: var(--color-text);
}

.error .btn-circle {
  margin-top: clamp(40px, calc(4.167 * var(--vw)), 80px);
  width: clamp(150px, calc(10.417 * var(--vw)), 200px);
  height: clamp(150px, calc(10.417 * var(--vw)), 200px);
}

/* 1px white stroke, no fill — matches "Button / Circle / Solid / Accent",
   which despite its name exports as a stroked circle. */
/* Fixed rather than fluid: the label inside does not scale, so shrinking the
   disc below the design's 140px pushes the text outside it. */
.btn-circle--sm {
  width: 140px;
  height: 140px;
}

.btn-circle--outline {
  background-color: transparent;
  border: 1px solid var(--color-text);
  color: var(--color-text);
}

.btn-circle--outline:hover,
.btn-circle--outline:focus-visible {
  background-color: var(--color-text);
  color: var(--color-bg);
}

/* The 404 footer sits 180px below the section, not the landing page's 200. */
.page-404 .site-footer {
  margin-top: var(--sp-180);
}

/* 404 is the only page with neither a hero nor a masthead to close the header
   off, so in Figma 2001:9644 the header carries its own rules: the 1px divider
   right of the logo and a full-width bottom rule, both white. --color-line is
   the full-strength rule token, so it flips to ink in the light theme.
   Limited to the resting header — scrolled, the glass bar keeps its softer
   --color-rule, and an open menu stays borderless. */
.page-404 .site-header__rule {
  background: var(--color-line);
}

/* Drawn as ::after rather than border-bottom on purpose. The header's ::before
   scrim sits at z-index -1, and a negative-z child paints *after* the element's
   own border — so a real border-bottom here renders dimmed by ~27% of the
   scrim's navy, well short of the frame's white. ::after paints above it. */
.page-404 .site-header:not(.is-condensed):not(.is-menu-open)::after {
  content: "";
  position: absolute;
  right: 0;
  /* The containing block is the padding box, whose edge sits 1px above the
     border box — so -1px lands the rule on the header's true bottom edge. */
  bottom: -1px;
  left: 0;
  height: 1px;
  background: var(--color-line);
}

/* --------------------------------------------------------------------------
   Derived responsive behaviour — no tablet or mobile frame exists in Figma.
   -------------------------------------------------------------------------- */

/* The card deck needs vertical room to read as a deck. Below this it is a
   plain stack again — sticky cards on a short viewport just feel stuck. */
@media (max-width: 900px), (max-height: 640px) {
  .works__item {
    position: static;
  }

  .work {
    box-shadow: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .works__item {
    position: static;
  }

  .about__img {
    transition: none;
    translate: none;
  }
}

@media (max-width: 1024px) {
  .about__header,
  .credentials__item {
    grid-template-columns: 1fr;
  }

  .credentials__item {
    align-items: start;
  }

  /* The two-column grid no longer sets the lede's width once it stacks —
     cap it to a comfortable reading measure instead of letting it run the
     full inner width. Natural wrapping (not JS line-splitting) is what
     keeps this correct at every width in between. */
  .about__body {
    max-width: 640px;
  }

  /* The About header is a single column below this width, so the collage can
     no longer ride up into its empty right half. Leave enough clearance for
     image 1's 60px upward parallax drift plus a readable 20px minimum gap. */
  .about__stage {
    margin-top: var(--sp-80);
  }
}

/* The inline nav is the design's; below tablet it hands over to the
   full-screen overlay rather than being crammed. [derived] */
@media (max-width: 900px) {
  .site-header__nav,
  .site-header__clock {
    display: none;
  }

  .site-header__toggle {
    display: flex;
  }

  .site-header__actions {
    gap: var(--sp-16);
    padding-right: 0;
  }
}

@media (max-width: 700px) {
  /* Below the design's breakpoint the absolute eyebrow frame stops working —
     fall back to a simple centred row. */
  .hero__eyebrow {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-8);
    width: 100%;
    /* [derived] Was a flat 12px, sized to just barely fit both labels in
       one nowrap row at 320px. Scale it with viewport instead so it reads
       larger on the common 375–430px phone widths while staying at the
       same safe floor at the very narrowest screens. */
    font-size: clamp(12px, calc(3.4 * var(--vw)), 14px);
  }

  .hero__eyebrow-left,
  .hero__eyebrow-right,
  .hero__eyebrow-rule {
    position: static;
    transform: none;
    width: auto;
  }

  .hero__eyebrow-rule {
    width: 40px;
    flex-shrink: 0;
  }

  .hero__scroll {
    margin-left: auto;
  }

  .site-header__rule {
    display: none;
  }

  .site-header__actions {
    gap: var(--sp-8);
  }

  /* A 2:1 card is only ~165px tall at this width — too short to hold two
     stacked tags and the title without them colliding. */
  .work {
    aspect-ratio: 4 / 3;
  }

  .work__tags {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-8);
  }

  .tag {
    height: 28px;
    padding-inline: 12px;
    font-size: 10px;
  }

  .work__marquee {
    font-size: 36px;
  }

  /* [derived] `text-wrap: balance` (see .t-h2) still greedy-wraps close to
     the container's full measure on phones, leaving "Designer" orphaned
     alone on its own line after the manual <br/>. Capping the measure
     well below that forces the break after "a" instead, so "Senior Visual
     Designer" lands together on one line — a fixed, guaranteed break
     point rather than one that depends on balance support. */
  .statement__text {
    max-width: 24ch;
    margin-inline: auto;
  }

  /* Tighten the measure further once the column itself is phone-width —
     on anything narrower than this the inner content width is already
     below the cap, so it is a no-op there and only bites on wider "phone"
     viewports (landscape, foldables). */
  .about__body {
    max-width: 480px;
  }

  /* The overlapping about collage does not survive a narrow column —
     stack it instead. */
  .about__stage {
    aspect-ratio: auto;
    display: grid;
    gap: var(--sp-32);
  }

  .about__img {
    position: static;
    width: 100%;
    height: auto;
    aspect-ratio: 2 / 3;
  }

  .about__img--2 {
    aspect-ratio: 1;
  }

  .about .counter--ring {
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    max-width: 320px;
    margin-inline: auto;
  }

  /* Parallax offsets break the equal grid gaps in this stacked layout and
     pull image 3 over the ring. Keep every collage item in normal flow so
     the complete circle stays centred between the two images. */
  .about__stage > [data-parallax] {
    transform: none !important;
  }

  .site-footer__bottom {
    flex-direction: column;
    justify-content: flex-start;
    gap: var(--sp-16);
    padding: var(--sp-32) var(--gutter);
  }

  .site-footer__social {
    justify-content: center;
    flex-basis: auto;
    width: auto;
    height: 44px;
    gap: 0;
  }

  .site-footer__social li:nth-child(n),
  .site-footer__social li:nth-child(n) a {
    width: 44px;
    height: 44px;
  }

  .site-footer__social img[src$=".svg"] {
    width: 24px;
    height: 24px;
  }

  /* Circle buttons hit their minimum size here while the label does not
     shrink, so "unchealth.org →" would spill outside the disc. */
  .btn-circle {
    font-size: 14px;
    padding-inline: 10px;
  }

}

@media (hover: none), (pointer: coarse) {
  /* Replace the continuously-rendered canvas with a static approximation on
     touch devices. It keeps the intended glow without a permanent 60fps
     paint loop competing with native scrolling. */
  .hero__media {
    background:
      radial-gradient(circle at 48% 48%, rgb(253 249 207 / 0.18), transparent 34%),
      radial-gradient(circle at 58% 58%, rgb(120 158 214 / 0.2), transparent 44%);
  }

  .hero__aura {
    display: none;
  }

  .work:hover .work__media img {
    filter: saturate(0.72) contrast(1.03);
  }

  .work:hover .work__overlay {
    opacity: 0.44;
  }

  .about__img:hover img {
    transform: none;
  }

  .credentials__item:hover::before,
  .credentials__item:hover::after {
    opacity: 0;
    transform: scaleX(0);
  }

  .credentials__item:hover .credentials__term,
  .btn-circle:hover {
    transform: none;
  }

  .btn-circle:hover {
    background-color: var(--color-invert-surface);
    color: var(--color-invert-text);
  }

  .btn-circle--outline:hover {
    background-color: transparent;
    color: var(--color-text);
  }
}
