.project-content {
  min-width: 0;
  background: var(--page-paper);
}

.project-page-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 4rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--project-border);
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: 0.75rem;
  line-height: 1.4;
  text-align: right;
}

.project-page-footer__link {
  color: inherit;
  text-decoration: none;
  transition: color 180ms ease;
}

.project-page-footer__label {
  font-weight: 600;
}

.project-page-footer__link:hover,
.project-page-footer__link:focus-visible {
  color: var(--project-heading);
}

/* The carousel may reach the viewport edge, but it must not create page-level overflow. */
html.project-page,
html.project-page body {
  overflow-x: clip;
}

@font-face {
  font-family: "SF Pro Text";
  src: url("../../font/sf-pro/sf-pro-text_regular.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Text";
  src: url("../../font/sf-pro/sf-pro-text_medium.woff2") format("woff2");
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Text";
  src: url("../../font/sf-pro/sf-pro-text_semibold.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Text";
  src: url("../../font/sf-pro/sf-pro-text_bold.woff2") format("woff2");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Display";
  src: url("../../font/sf-pro/sf-pro-display_regular.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Display";
  src: url("../../font/sf-pro/sf-pro-display_medium.woff2") format("woff2");
  font-style: normal;
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Display";
  src: url("../../font/sf-pro/sf-pro-display_semibold.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "SF Pro Display";
  src: url("../../font/sf-pro/sf-pro-display_bold.woff2") format("woff2");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Just Another Hand";
  src: url("../../font/just-another-hand/JustAnotherHand-Regular.ttf") format("truetype");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

.project-page-article {
  --project-heading: rgb(29, 29, 31);
  --project-body: rgba(29, 29, 31, 0.72);
  --project-body-soft: rgba(29, 29, 31, 0.56);
  --project-eyebrow: rgba(29, 29, 31, 0.48);
  --project-font-display: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --project-font-text: "SF Pro Text", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --project-type-eyebrow-size: 0.75rem;
  --project-type-eyebrow-weight: 700;
  --project-type-eyebrow-leading: 1.1904761905;
  --project-type-eyebrow-tracking: 0.011em;
  --project-type-title-size: clamp(2rem, 3.4vw, 3rem);
  --project-type-title-weight: 500;
  --project-type-title-leading: 1.0834933333;
  --project-type-title-tracking: -0.003em;
  --project-type-section-title-size: 2.25rem;
  --project-type-body-size: 16px;
  --project-type-body-weight: 400;
  --project-type-body-leading: 1.4705882353;
  --project-type-body-tracking: -0.022em;
  /* Internal text modules use their own scale, separate from section headers. */
  --project-module-eyebrow-size: 0.75rem;
  --project-module-eyebrow-weight: 700;
  --project-module-eyebrow-leading: 1.1904761905;
  --project-module-eyebrow-tracking: 0.011em;
  --project-module-title-size: 1.3125rem;
  --project-module-title-weight: 600;
  --project-module-title-leading: 1.25;
  --project-module-title-tracking: 0.011em;
  --project-module-body-size: 16px;
  --project-module-body-weight: 400;
  --project-module-body-leading: 1.4705882353;
  --project-module-body-tracking: -0.022em;
  --project-type-highlight-size: clamp(2rem, 3.75vw, 3rem);
  --project-type-highlight-weight: 600;
  --project-type-highlight-leading: 1;
  --project-type-highlight-tracking: -0.003em;
  --project-type-support-size: 0.875rem;
  --project-type-support-leading: 1.2857742857;
  --project-border: rgba(29, 29, 31, 0.08);
  --project-outline: 1px solid var(--line);
  --project-surface: var(--page-surface);
  --project-radius: 28px;
  --project-radius-inner: 18px;
  --project-text-max: 52.5rem;
  --project-media-max: var(--content-max);
  --project-media-split-columns: minmax(0, 3fr) minmax(0, 2fr);
  /* Single-device modules give the explanation a little more room. The
   * device column keeps a stable right-side composition instead of relying on
   * per-module transforms or offsets. */
  --project-phone-single-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  --project-phone-single-gutter: clamp(5rem, 8vw, 9rem);
  /* Multi-device stages reserve a little more room for the shared device
   * scale, so the two phones keep a visible, stable separation. */
  --project-phone-multi-columns: minmax(0, 2fr) minmax(0, 3fr);
  --project-phone-multi-gap: clamp(4.25rem, 5vw, 5.5rem);
  /* Match the copy inset while absorbing the visual overflow from scaled phones. */
  --project-phone-multi-stage-inset: clamp(3rem, 6vw, 6rem);
  --project-device-padding-block: clamp(2rem, 3.5vw, 4rem);
  --project-device-padding-inline: clamp(1rem, 2.5vw, 2rem);
  /* Responsive breathing room for device media: 24–48px vertically. */
  --project-phone-padding-block: clamp(1.5rem, 3vw, 3rem);
  --project-phone-scale: 1.14;
  --project-phone-max-height: 32rem;
  --project-grid-padding: 1.75rem;
  --project-grid-padding-inline: 2rem;
  --project-grid-divider: var(--line);
  /* Shared project rhythm, mapped to the supplied Apple source values. */
  --space-section: 9rem;
  --space-block: 3rem;
  --space-content: 1.5rem;
  --space-tight: 0.75rem;
  --space-paragraph: 0.875rem;
  --space-media: 3rem;
  --project-module-space: 1.5rem;
  --project-carousel-gap: 1.5rem;
  --project-carousel-control-size: 36px;
  --project-carousel-control-gap: 1.125rem;
  --project-carousel-controls-width: calc((var(--project-carousel-control-size) * 2) + var(--project-carousel-control-gap));
  width: 100%;
  max-width: none;
  margin: 0;
  padding: max(0px, calc(var(--section-scroll-margin) - var(--portfolio-content-top-padding))) 0 4rem;
  background: var(--page-paper);
  color: var(--project-heading);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

/* Our own project standard: Apple-derived values, without importing Apple class names. */
.project-page-article.project-apple-standard {
  --project-content-width: var(--content-max);
  /* Scale Apple's 840 / 1260 lockup ratio to our 1280px project rail. */
  --project-apple-viewport-width: 87.5%;
  --project-apple-lockup-max: 53.333rem;
  --project-section-space: 9rem;
  --project-section-intro-space: 3rem;
  --project-hero-overview-space: 7rem;
  --project-media-space: 3rem;
  --project-lockup-space: 1.5rem;
  --project-label-space: 0.75rem;
  --project-media-eyebrow-title-space: 1.25rem;
  --project-paragraph-space: 0.875rem;
  --project-eyebrow-space: 0.875rem;
  --project-headline-space: 1.75rem;
  --project-title-overview-space: 3rem;
  max-width: var(--project-content-width);
  --space-section: var(--project-section-space);
  --space-media: var(--project-media-space);
  --space-content: var(--project-lockup-space);
  --space-tight: var(--project-label-space);
  --space-paragraph: var(--project-paragraph-space);
}

.project-copy--intro {
  margin-top: var(--space-content);
  font-size: 18px;
}

.project-overview {
  /* Hero-to-overview is intentionally independent from the section rhythm. */
  padding: var(--project-hero-overview-space) 0 var(--space-section);
}

/*
 * Apple places the introductory type inside a narrower, left-anchored lockup.
 * Keep the media and fact panels on the shared project rail, while allowing
 * the text to stop before the rail's right edge.
 */
.project-overview-lockup {
  width: min(var(--project-apple-viewport-width), var(--project-apple-lockup-max));
  max-width: var(--project-apple-lockup-max);
  margin-inline: 0;
}

/* Every project overview uses the same eyebrow-to-title lockup rhythm.
 * Keep this in the shared overview structure so individual pages do not need
 * one-off metadata classes to reproduce the Polyverse spacing. */
.project-overview-lockup > .project-eyebrow {
  margin: 0 0 var(--project-eyebrow-space);
}

.project-eyebrow {
  color: var(--project-eyebrow);
  font-family: var(--project-font-display);
  font-size: var(--project-type-eyebrow-size);
  font-weight: var(--project-type-eyebrow-weight);
  letter-spacing: var(--project-type-eyebrow-tracking);
  line-height: var(--project-type-eyebrow-leading);
  text-transform: uppercase;
}

.project-eyebrow-muted {
  color: var(--project-eyebrow);
}

.project-title {
  max-width: var(--project-text-max);
  margin: 0;
  color: var(--project-heading);
  font-family: var(--project-font-display);
  font-size: var(--project-type-title-size);
  font-weight: var(--project-type-title-weight);
  letter-spacing: var(--project-type-title-tracking);
  line-height: var(--project-type-title-leading);
  text-wrap: balance;
}

.project-media-placeholder {
  display: grid;
  width: 100%;
  aspect-ratio: 16 / 9;
  place-items: center;
  overflow: hidden;
  border: 0;
  border-radius: var(--project-radius);
  background: var(--project-surface);
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: var(--project-type-eyebrow-size);
  font-weight: var(--project-type-eyebrow-weight);
  line-height: 1.5;
  text-align: center;
  text-transform: none;
}

.project-media-placeholder span {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--project-border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
}

.project-caption {
  display: none;
  margin-top: 0.75rem;
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: var(--project-type-support-size);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-support-leading);
  text-align: center;
}

.overview-copy {
  max-width: none;
  margin-top: var(--project-title-overview-space);
}

.overview-copy > .project-copy--intro {
  width: 100%;
  max-width: none;
  font-size: 18px;
}

.project-facts {
  display: grid;
  overflow: hidden;
  margin: var(--space-media) 0 0;
  padding: 0;
  border: 0;
  border-radius: var(--project-radius);
  background: var(--project-surface);
}

.project-facts > div {
  padding: var(--project-grid-padding) var(--project-grid-padding-inline);
  text-align: left;
}

.project-facts > div + div {
  border-top: 0;
}

.project-facts dt {
  color: var(--project-body-soft);
  font-family: var(--project-font-display);
  font-size: var(--project-type-eyebrow-size);
  font-weight: var(--project-type-eyebrow-weight);
  letter-spacing: var(--project-type-eyebrow-tracking);
  line-height: var(--project-type-eyebrow-leading);
  text-transform: uppercase;
}

.project-facts dd {
  margin: var(--space-tight) 0 0;
  color: var(--project-heading);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: 500;
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

[data-reveal] {
  opacity: 0;
  transform: translateY(var(--page-reveal-offset));
  transition: opacity var(--page-reveal-duration) var(--page-reveal-ease), transform var(--page-reveal-duration) var(--page-reveal-ease);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

.project-image-block {
  margin-top: var(--space-media);
}

/* Shared media geometry for every migrated case study. The default media
 * fills the enclosing surface; only explicit modifiers add an inset. The
 * media itself stays unrounded while the surface carries the shared radius
 * and outline. */
.project-hero-frame,
.project-media-frame {
  display: grid;
  width: 100%;
  overflow: hidden;
  margin: 0;
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
}

.project-hero-frame {
  aspect-ratio: 16 / 9;
  place-items: center;
}

.project-hero-frame .project-media,
.project-media-frame > .project-media {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

.project-media-frame--contain > .project-media {
  object-fit: contain;
}

/* Use for overview visuals that need to sit inside a consistent 16:9 module,
 * even when the source export uses a different aspect ratio. */
.project-media-frame--16-9 {
  aspect-ratio: 16 / 9;
}

.project-media-frame--16-9 > .project-media {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

.project-media-frame--16-9.project-media-frame--full-bleed > .project-media {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
}

/* Video embeds use the same project surface and 16:9 geometry as image media. */
.project-video-frame {
  --project-video-inset: 0px;
  position: relative;
  aspect-ratio: 16 / 9;
  padding: 0;
  background: var(--project-surface);
  isolation: isolate;
}

.project-video-poster,
.project-video {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: calc(var(--project-radius) - 0.35rem);
}

.project-video-poster {
  position: absolute;
  inset: var(--project-video-inset);
  z-index: 1;
  width: auto;
  height: auto;
  object-fit: cover;
  transition: opacity 360ms cubic-bezier(.22, 1, .36, 1);
}

.project-video {
  position: relative;
  z-index: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 360ms cubic-bezier(.22, 1, .36, 1);
}

.project-video-launch {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  display: grid;
  width: clamp(3.75rem, 6vw, 5.25rem);
  height: clamp(3.75rem, 6vw, 5.25rem);
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--local-nav-active-color, #007aff);
  color: #fff;
  cursor: pointer;
  transform: translate(-50%, -50%);
  transition: transform 220ms cubic-bezier(.22, 1, .36, 1), background-color 220ms ease, opacity 360ms ease;
}

.project-video-launch:hover,
.project-video-launch:focus-visible {
  background: #006edb;
  transform: translate(-50%, -50%) scale(1.06);
}

.project-video-launch:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.project-video-launch__icon {
  width: 0;
  height: 0;
  margin-left: 0.2rem;
  border-top: 0.55rem solid transparent;
  border-bottom: 0.55rem solid transparent;
  border-left: 0.8rem solid currentColor;
}

.project-video-frame.is-playing .project-video-poster,
.project-video-frame.is-playing .project-video-launch {
  opacity: 0;
  pointer-events: none;
}

.project-video-frame.is-playing .project-video {
  z-index: 1;
  opacity: 1;
  pointer-events: auto;
}

/* Inset large diagrams and system maps so the artwork reads as a focused
 * artifact inside the 16:9 surface rather than touching its edges. */
.project-media-frame--padded {
  padding: clamp(1rem, 2.5vw, 2.5rem);
  box-sizing: border-box;
}

.project-media-frame--padded > .project-media {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
  justify-self: center;
  align-self: center;
}

.wave-operating-system-frame > .project-media {
  transform: scale(0.85);
  transform-origin: center;
}

/* Wave's mechanism study is a full-bleed paper artifact. The annotation sits
 * above the image so the exported artwork stays clean and reusable. */
.wave-mechanism-frame {
  position: relative;
}

.wave-mechanism-frame > .project-media {
  object-fit: cover;
}

.wave-mechanism-annotation {
  position: absolute;
  right: 12%;
  bottom: 13%;
  z-index: 1;
  color: rgba(29, 29, 31, 0.72);
  font-family: "Just Another Hand", cursive;
  font-size: clamp(1.25rem, 2vw, 2rem);
  line-height: 1;
  white-space: nowrap;
  transform: rotate(-3deg);
  pointer-events: none;
}

/* Use when an exported diagram needs a little more breathing room inside its
 * shared surface. The inset belongs to the frame, so the artwork keeps its
 * proportions without being offset or cropped by hand. */
.project-media-frame--inset {
  padding: clamp(0.875rem, 1.75vw, 1.75rem);
  box-sizing: border-box;
}

.project-media-frame--inset > .project-media {
  object-fit: contain;
}

/* Use for a diagram that should remain fully visible while occupying less of
 * its existing shared frame. Keeping the scale in the shared modifier
 * preserves the frame geometry and leaves balanced breathing room around the
 * artwork instead of cropping or manually offsetting the image. */
.project-media-frame--half-scale {
  place-items: center;
}

.project-media-frame--half-scale > .project-media {
  transform: scale(0.5);
  transform-origin: center;
}

/* Give wide process artwork a little more vertical breathing room while
 * preserving the complete source image inside the shared surface. */
.project-media-frame--wide-roomy {
  aspect-ratio: 2.15 / 1;
  padding: clamp(0.5rem, 1.25vw, 1.25rem);
  box-sizing: border-box;
}

.project-media-frame--wide-roomy > .project-media {
  object-fit: contain;
}

/* Use when an exported visual needs an even breathing room inside its
 * enclosing media surface. The inset belongs to the media frame, not the
 * page section, so the outer module keeps its shared geometry. */
.project-media-grid {
  display: grid;
  gap: var(--space-content);
  margin-top: var(--space-media);
}

.project-media-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.project-media-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.project-media-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.project-media-grid > * {
  min-width: 0;
}

.project-media-grid .project-media-frame {
  height: 100%;
  margin: 0;
}

.project-media-grid .project-media-frame > .project-media {
  min-height: 12rem;
}

.project-media-grid .project-media-frame--contain > .project-media {
  padding: clamp(1rem, 3vw, 3rem);
}

/* Single full-width 16:9 artboard for grouped studies. The child images
 * share one surface and use contain so the top and bottom inset stay even. */
.project-media-cluster {
  display: grid;
  width: 100%;
  aspect-ratio: 16 / 9;
  gap: clamp(0.75rem, 1.5vw, 1.5rem);
  padding: clamp(1rem, 2.4vw, 2.5rem);
  box-sizing: border-box;
  margin-top: var(--space-media);
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
  overflow: hidden;
}

.project-media-cluster--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

.project-media-cluster--3 > :first-child > .project-media {
  height: 90%;
  align-self: center;
}

.project-media-cluster--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

.project-media-cluster--2 > :first-child > .project-media {
  height: 88%;
  align-self: center;
}
.project-media-cluster--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.5rem, 1vw, 1rem);
  padding: clamp(0.875rem, 2vw, 2rem);
}

.project-media-cluster--asymmetric-60-40 {
  grid-template-columns: minmax(0, 60fr) minmax(0, 40fr);
}

/* Wave's two code studies share one 16:9 surface and should keep the same
 * visual height inside it. */
.wave-code-cluster > :first-child > .project-media {
  height: 100%;
}

.wave-code-cluster {
  gap: clamp(0.25rem, 0.5vw, 0.5rem);
  padding: clamp(1.25rem, 3vw, 3rem);
}

.wave-code-cluster > .project-media-frame > .project-media {
  transform: scale(0.9);
}

.wave-code-cluster > .project-media-frame:first-child > .project-media {
  transform-origin: right center;
}

.wave-code-cluster > .project-media-frame > .project-media {
  border-radius: clamp(0.6rem, 1vw, 1rem);
}

.wave-code-cluster > .project-media-frame:last-child > .project-media {
  transform-origin: left center;
}

.wave-prototype-cluster {
  gap: clamp(0.75rem, 1.5vw, 1.5rem);
  padding: clamp(1rem, 2.5vw, 2.5rem);
}

/* Keep Wave's stacked physical studies on the shared project rhythm: the
 * stack opens with one section-intro gap, then uses the standard module gap. */
.wave-physical-process-media > .project-media-cluster {
  margin-top: 0;
}

.wave-code-cluster .project-media {
  border-radius: clamp(0.25rem, 0.5vw, 0.5rem);
}

.wave-prototype-cluster > :first-child > .project-media {
  height: 100%;
}

.project-carousel--wave-outcome .project-carousel__slide--media-only .project-media-split__media {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: 0;
}

.project-carousel--wave-outcome .project-carousel__media-visual {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  object-position: center center;
  background: #000;
}

.project-media-cluster--2x2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: clamp(0.5rem, 1vw, 1rem);
  padding: clamp(0.875rem, 2vw, 2rem);
}

.project-media-cluster--2x2 .project-media-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: clamp(0.25rem, 0.75vw, 0.75rem);
  box-sizing: border-box;
}

.project-media-cluster--2x2 .project-media-frame > .project-media {
  width: 88%;
  height: auto;
  flex: 0 1 auto;
  object-fit: contain;
}

.project-media-cluster--2x2 .project-media-frame > figcaption {
  width: min(100%, 32rem);
  margin-top: clamp(0.75rem, 1vw, 1.125rem);
  color: var(--project-body);
  font-family: "Just Another Hand", var(--project-font-text), sans-serif;
  font-size: clamp(1.15rem, 1.35vw, 1.65rem);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
  text-align: center;
}

.project-media-cluster--vertical-4 {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: repeat(4, auto);
  box-sizing: border-box;
  aspect-ratio: 16 / 9;
  align-items: start;
  align-content: center;
  justify-items: stretch;
  gap: clamp(0.875rem, 1.25vw, 1.25rem);
  padding: clamp(1.5rem, 3vw, 3rem);
}

.project-media-cluster--vertical-4 .project-media-frame {
  display: block;
  width: 100%;
  min-width: 0;
  align-self: stretch;
}

.project-media-cluster.project-media-cluster--vertical-4 .project-media-frame > .project-media {
  display: block;
  width: 88%;
  height: auto;
  max-width: 100%;
  margin-inline: auto;
  object-fit: contain;
}

/* The survey strips have different intrinsic heights. Let the shared surface
 * grow with all four rows on narrower screens so the final legend never gets
 * clipped by the desktop 16:9 height constraint. */
@media (max-width: 66.75rem) {
  .project-media-cluster--vertical-4 {
    aspect-ratio: auto;
    align-content: start;
    overflow: hidden;
  }

  .project-media-cluster.project-media-cluster--vertical-4 .project-media-frame > .project-media {
    width: 88%;
  }
}

@media (max-width: 45.875rem) {
  .project-media-cluster--vertical-4 {
    gap: 1.25rem;
    padding: 1.5rem;
  }

  .project-media-cluster.project-media-cluster--vertical-4 .project-media-frame > .project-media {
    width: 100%;
  }
}
.project-media-cluster--6-row {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  aspect-ratio: auto;
  gap: clamp(0.5rem, 1vw, 1rem);
  padding: clamp(0.875rem, 2vw, 2rem);
}
.project-media-cluster--6 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
}

.project-media-cluster > * {
  min-width: 0;
  min-height: 0;
  margin: 0;
}

.project-media-cluster.project-module-gap {
  margin-top: var(--project-module-space);
}

.project-media-cluster .project-media-frame {
  min-height: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.project-media-cluster .project-media-frame > .project-media {
  width: 100%;
  height: 100%;
  max-width: 100%;
  min-height: 0;
  object-fit: contain;
}

/* Reusable vertical media stack for case studies where each artifact needs
 * to read as its own module instead of competing in a side-by-side grid. */
.project-media-stack {
  display: grid;
  gap: var(--project-module-space);
  margin-top: var(--space-media);
}

.project-media-stack > * {
  min-width: 0;
  margin: 0;
}

.project-media-stack .project-media-frame {
  margin: 0;
}

/* Stack wide process diagrams as independent 16:9 modules while keeping a
 * consistent inset around each artifact. */
.project-media-stack--16-9 .project-media-frame {
  aspect-ratio: 16 / 9;
  padding: clamp(1.5rem, 3vw, 3rem);
  box-sizing: border-box;
}

.project-media-stack--16-9 .project-media-frame > .project-media {
  object-fit: contain;
}

.project-media-grid + .project-copy,
.project-media-frame + .project-copy {
  margin-top: var(--space-content);
}

/* Keep consecutive modules closer than the larger section-opening rhythm. */
.project-section > .project-panel + .project-panel,
.project-section > .project-panel + .project-image-block,
.project-section > .project-reframe + .project-image-block,
.project-section > .project-image-block + .project-feature-grid,
.project-section > .project-panel + .project-media-split,
.project-section > .project-carousel + .project-media-split,
.project-section > .project-media-split + .project-feature-grid {
  margin-top: var(--project-module-space);
}

/* Reusable spacing between subsequent content modules and text-to-media pairs. */
.project-module-gap {
  margin-top: var(--project-module-space);
}

/* Feature copy opens its own content module with the larger section-intro
 * rhythm; this does not change the 24px gap between sibling modules. */
.project-feature-intro-gap {
  margin-top: var(--project-section-intro-space);
}

/* Reusable stacked feature module for a text block followed by media. */
.project-feature-grid {
  display: grid;
  gap: var(--project-module-space);
}

.project-feature-grid article {
  display: grid;
  min-width: 0;
  grid-template-columns: 1fr;
  gap: 0;
  padding: 0;
}

.project-feature-copy {
  max-width: var(--project-text-max);
}

/* Reusable project module: explanation on the left, product experience on the right. */
.project-media-split {
  display: grid;
  width: 100%;
  grid-template-columns: var(--project-media-split-columns);
  margin-top: var(--space-media);
}

.project-media-split__copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  justify-content: center;
  padding-inline: clamp(2rem, 5vw, 5rem);
}

.project-media-split__title {
  max-width: 28rem;
  margin: 0;
  color: var(--project-heading);
  font-family: "Just Another Hand", "SF Pro Display", sans-serif;
  font-size: clamp(1.5rem, 3vw, 3rem);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1;
}

.project-media-split__copy > .project-type-eyebrow + .project-media-split__title {
  margin-top: var(--project-media-eyebrow-title-space);
}

.project-media-split__body {
  max-width: 28rem;
  margin: var(--space-content) 0 0;
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-media-split__media {
  display: grid;
  min-width: 0;
  min-height: 0;
  place-items: center;
  padding-block: var(--project-device-padding-block);
  padding-inline: var(--project-device-padding-inline);
}

.project-media-split__media .project-device-frame-content {
  width: 100%;
  height: 100%;
}

/* Sharing Economy pairs the service-model explanation with its supporting
 * diagram, keeping the artwork on a quieter, right-hand stage. */
.project-media-split--sharing-economy {
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  column-gap: clamp(0.5rem, 1vw, 1rem);
  padding-inline: clamp(1.5rem, 4vw, 4rem);
  box-sizing: border-box;
  align-items: center;
}

.project-media-split--sharing-economy .project-media-split__copy {
  padding-inline: 0;
}

.project-media-split--sharing-economy .project-media-split__title,
.project-media-split--sharing-economy .project-media-split__body {
  width: 100%;
  max-width: none;
}

.project-media-split--sharing-economy .project-media-split__media {
  padding: 0;
}

.project-media-split--sharing-economy .project-media-split__media > .project-media {
  display: block;
  width: 88%;
  max-width: 88%;
  height: auto;
  max-height: none;
  justify-self: end;
  border: 0;
  border-radius: 0;
}

/*
 * Phone modules share one device stage. The outer frame stays 16:9, while the
 * phone itself keeps the same height whether the stage contains one device or
 * several. Multi-device modules only widen the media column and arrange the
 * same-sized devices side by side.
 */
.project-phone-stage {
  padding-block: var(--project-phone-padding-block);
}

.project-media-split--phone {
  grid-template-columns: var(--project-phone-single-columns);
}

.project-media-split--phone.project-media-split--phone-multi {
  grid-template-columns: var(--project-phone-multi-columns);
}

.project-phone-stage .project-device-frame-content {
  width: max-content;
  max-width: 100%;
  /* Reserve the shared scale before transforming the device, so the visual
   * frame remains inside the 16:9 surface at every responsive size. */
  height: min(calc(100% / var(--project-phone-scale)), var(--project-phone-max-height));
}

.project-phone-module--multi .project-phone-stage .project-device-frame-content {
  width: max-content;
  max-width: 100%;
  margin-inline-start: auto;
  margin-inline-end: 0;
}

.project-phone-stage--multi .project-device-frame-content {
  position: relative;
  gap: var(--project-phone-multi-gap);
}

/* Multi-device evidence reads as a before → after sequence. Keep the cue in
 * the shared stage so every two-device module communicates the same relation. */
.project-phone-stage--multi .project-device-frame-content::after {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: 0;
  height: 0;
  border-top: 0.6rem solid transparent;
  border-bottom: 0.6rem solid transparent;
  border-left: 0.9rem solid var(--project-body-soft);
  content: "";
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.project-phone-stage .project-device-frame-content > * {
  transform: scale(var(--project-phone-scale));
  transform-origin: center;
}

.project-media-split__media .project-media {
  max-height: 100%;
}

/* Project-only carousel. It mirrors the interaction model of the About carousel
 * while keeping the implementation independent for case-study evidence. */
.project-carousel {
  position: relative;
  width: 100%;
  min-width: 0;
  overflow: visible;
  margin-top: var(--space-media);
  padding-bottom: var(--project-module-space);
  /* Match About's full-rail carousel: the parent stays in the content rail,
   * while the viewport expands to the right edge of the browser. */
  --project-carousel-rail-column: var(--portfolio-rail-column);
  --project-carousel-rail-stop: var(--project-carousel-rail-column);
  --project-carousel-parent-inset: calc(var(--project-carousel-rail-column) + var(--portfolio-content-gutter));
  --project-carousel-content-inset: calc(var(--project-carousel-parent-inset) - var(--project-carousel-rail-stop));
  /* Match each slide to the same inner content width used by project-media-split.
   * The viewport still expands past this width to create the right-side peek. */
  --project-carousel-card-width: min(
    var(--project-media-max),
    calc(100vw - var(--project-carousel-rail-stop) - (2 * var(--portfolio-content-gutter)))
  );
}

/* Feature-module Carousels use the separate 24px module rhythm instead of
 * the 48px section-opening default above. */
.project-carousel.project-module-gap {
  margin-top: var(--project-module-space);
}

.project-carousel.project-feature-intro-gap {
  margin-top: var(--project-section-intro-space);
}

.project-carousel__viewport {
  width: calc(100vw - var(--project-carousel-rail-stop));
  margin-left: calc(var(--project-carousel-rail-stop) - var(--project-carousel-parent-inset));
  overflow-x: auto;
  overflow-y: hidden;
  cursor: grab;
  touch-action: pan-y;
  overscroll-behavior-x: contain;
  /* The carousel settles through its own release animation. Keeping native
   * snap off avoids inconsistent browser-driven stopping between cards. */
  scroll-snap-type: none;
  scroll-behavior: auto;
  scrollbar-width: none;
  scroll-padding-inline: var(--project-carousel-content-inset);
}

/* A carousel nested inside an art-step belongs to that step's media column.
 * Keep its viewport and cards inside the parent column instead of applying
 * the page-level right-rail expansion. */
.project-art-step__media .project-carousel {
  --project-carousel-rail-column: 0px;
  --project-carousel-rail-stop: 0px;
  --project-carousel-parent-inset: 0px;
  --project-carousel-content-inset: 0px;
  --project-carousel-card-width: 100%;
}

.project-art-step__media .project-carousel__viewport {
  width: 100%;
  margin-left: 0;
}

.project-carousel__viewport.is-dragging {
  cursor: grabbing;
  user-select: none;
  scroll-snap-type: none;
}

.project-carousel__viewport.is-dragging img,
.project-carousel__viewport.is-dragging video {
  -webkit-user-drag: none;
  user-select: none;
}

.project-carousel__viewport::-webkit-scrollbar {
  display: none;
}

.project-carousel__track {
  display: flex;
  width: max-content;
  gap: var(--project-carousel-gap);
  flex-wrap: nowrap;
  padding-inline: var(--project-carousel-content-inset);
}

.project-media-split,
.project-carousel__slide {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
}

.project-carousel__slide {
  position: relative;
  display: grid;
  width: var(--project-carousel-card-width);
  height: auto;
  grid-template-columns: var(--project-media-split-columns);
  flex: 0 0 var(--project-carousel-card-width);
  scroll-snap-align: start;
}

/* First-card interaction cue: it floats above the card without becoming part
 * of the slide's layout, so the 16:9 geometry and existing content stay put. */
.project-carousel__swipe-hint {
  position: absolute;
  z-index: 2;
  /* The arrow tip lands on the midpoint of the two controls below. */
  right: calc(var(--project-carousel-controls-width) / 2);
  bottom: clamp(0.5rem, 1.4vw, 1.125rem);
  width: clamp(5.5rem, 12%, 7.65625rem);
  pointer-events: none;
  opacity: 0;
}

.project-carousel.is-hint-active .project-carousel__swipe-hint {
  animation: project-carousel-swipe-hint 8s ease-in-out 300ms 1 both;
}

.project-carousel__swipe-hint--label {
  /* Restore the original transparent SVG cue instead of the later pill UI.
   * Keep the same outer width and right/bottom anchors so the arrow remains
   * aligned with the midpoint of the Carousel controls. */
  display: block;
  width: clamp(5.5rem, 12%, 7.65625rem);
  aspect-ratio: 490 / 170;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: url("../../picture/shared/carousel-hint.svg") center / contain no-repeat;
  color: transparent;
  font-size: 0;
  line-height: 0;
  white-space: normal;
}

.project-carousel__swipe-hint--label > span,
.project-carousel__swipe-hint--label > svg {
  display: none;
}

.project-carousel--glamhub-outcome .project-carousel__slide--media-only .project-media-split__media {
  padding: clamp(0.875rem, 2vw, 2rem);
}

/* Some carousel exports use a non-16:9 source ratio. Keep the complete
 * artwork inside the slide with a real, symmetric inset. */
.project-carousel__slide--contained .project-media-split__media {
  --project-carousel-contained-inset: clamp(0.875rem, 2vw, 2rem);
  box-sizing: border-box;
  height: 100%;
  min-height: 0;
  padding: var(--project-carousel-contained-inset);
  place-items: center;
}

.project-carousel__slide--contained .project-carousel__media-visual {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
}

/* The organism study exports already include their complete visual surface;
 * let them reach all four edges of the shared carousel card. */
.project-carousel--organism-studies .project-carousel__slide--media-only .project-media-split__media {
  padding: 0;
}

/* Final-form exports are already framed edge-to-edge; keep the black artwork
 * flush with the shared carousel card instead of adding another inset. */
.project-carousel--organism-final-forms .project-carousel__slide {
  padding: 0;
}

.project-carousel--organism-final-forms .project-carousel__slide--media-only .project-media-split__media {
  padding: 0;
}

/* The C4D exports are taller than the shared 16:9 carousel card. Keep the
 * artwork fully visible inside an explicit, symmetric inset instead of
 * letting the lower edge disappear behind the slide. */
.project-carousel--organism-models .project-carousel__slide--media-only .project-media-split__media {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: clamp(1.5rem, 3vw, 3rem);
  overflow: hidden;
}

.project-carousel--organism-models .project-carousel__slide--media-only .project-carousel__media-visual {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center center;
}

/* Weibo's landscape exports are slightly narrower than the 16:9 card. Keep
 * the full artwork visible inside the shared white carousel surface instead
 * of sizing the image to the card width and letting its lower edge overflow. */
.project-carousel--weibo .project-carousel__slide--media-only .project-media-split__media {
  position: relative;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: 0;
}

.project-carousel--weibo .project-carousel__media-visual {
  position: absolute;
  top: var(--project-device-padding-block);
  right: var(--project-device-padding-inline);
  bottom: var(--project-device-padding-block);
  left: var(--project-device-padding-inline);
  width: calc(100% - (2 * var(--project-device-padding-inline)));
  height: calc(100% - (2 * var(--project-device-padding-block)));
  max-width: none;
  max-height: none;
  object-fit: contain;
}

@keyframes project-carousel-swipe-hint {
  0%,
  8% {
    opacity: 0;
  }

  20%,
  42% {
    opacity: 0.92;
  }

  32% {
    opacity: 0.72;
  }

  54%,
  68% {
    opacity: 0.86;
  }

  61% {
    opacity: 0.68;
  }

  78% {
    opacity: 0.72;
  }

  100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .project-carousel.is-hint-active .project-carousel__swipe-hint {
    animation: none;
    opacity: 0.92;
  }
}

.project-carousel__slide.project-carousel__slide--phone {
  grid-template-columns: var(--project-phone-single-columns);
}

.project-carousel__slide--media-only {
  grid-template-columns: 1fr;
}

.project-carousel__slide--text-only {
  grid-template-columns: 1fr;
  place-items: center;
}

.project-carousel__slide--text-only .project-media-split__copy {
  width: min(100%, 64rem);
  margin-inline: auto;
}

.project-carousel__slide--text-only .project-media-split__title,
.project-carousel__slide--text-only .project-media-split__body {
  max-width: 44rem;
}

/* Reusable two-device module. Use this modifier on any phone module, whether
 * it lives inside a carousel or directly in a project section. */
.project-phone-module.project-phone-module--multi {
  grid-template-columns: var(--project-phone-multi-columns);
}

.project-carousel__slide:last-child {
  scroll-snap-align: start end;
}

.project-carousel__slide--media-only .project-media-split__media {
  grid-column: 1 / -1;
}

.project-carousel__slide .project-media-split__copy {
  padding-inline: clamp(2rem, 5vw, 5rem);
}

.project-carousel__slide .project-media-split__media {
  padding-inline: var(--project-device-padding-inline);
}

.project-phone-module--multi .project-phone-stage {
  padding-inline: 0 var(--project-phone-multi-stage-inset);
}

.project-phone-module--multi .project-media-split__copy {
  padding-right: clamp(1.5rem, 3vw, 3rem);
}

/* Shared single-device geometry. All direct phone modules and single-phone
 * carousel slides use the same content-to-device relationship: the copy can
 * occupy the wider column, while the device resolves against the same right
 * gutter used by the copy's left edge. Multi-device modules intentionally
 * keep their separate composition above. */
.project-media-split--phone:not(.project-phone-module--multi) .project-media-split__copy,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-media-split__copy {
  padding-inline: var(--project-phone-single-gutter) 0;
}

.project-media-split--phone:not(.project-phone-module--multi) .project-media-split__title,
.project-media-split--phone:not(.project-phone-module--multi) .project-media-split__body,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-media-split__title,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-media-split__body {
  max-width: 34rem;
}

.project-media-split--phone:not(.project-phone-module--multi) .project-phone-stage,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-phone-stage {
  justify-items: end;
  padding-inline: 0 var(--project-phone-single-gutter);
}

/* Single-device stages reserve the final visual height in the layout itself.
 * The phone keeps its natural dimensions inside that stage, so both outer
 * edges resolve against the same gutter without a transform or translation. */
.project-media-split--phone:not(.project-phone-module--multi) .project-phone-stage .project-device-frame-content > *,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-phone-stage .project-device-frame-content > * {
  transform: none;
}

.project-media-split--phone:not(.project-phone-module--multi) .project-phone-stage .project-device-frame-content,
.project-carousel__slide--phone:not(.project-phone-module--multi) .project-phone-stage .project-device-frame-content {
  height: min(100%, calc(var(--project-phone-max-height) * var(--project-phone-scale)));
}

.project-carousel__media-visual {
  display: block;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.project-carousel__slide .project-device-frame-content > figure {
  display: grid;
  width: auto;
  height: 100%;
  flex: 0 0 auto;
  min-width: 0;
  min-height: 0;
  margin: 0;
  place-items: center;
}

.project-carousel__slide .project-device-frame-content > figure > .project-media {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
}

.project-carousel__controls {
  display: flex;
  justify-content: flex-end;
  gap: var(--project-carousel-control-gap);
  margin-top: var(--space-tight);
  width: fit-content;
  margin-left: auto;
}

.project-carousel__button {
  --project-carousel-arrow-color: rgba(0, 0, 0, 0.56);
  --project-carousel-arrow-color-hover: rgba(0, 0, 0, 0.64);
  --project-carousel-arrow-color-active: rgba(0, 0, 0, 0.64);
  --project-carousel-button-surface: rgba(210, 210, 215, 0.64);
  --project-carousel-button-surface-hover: rgba(223, 223, 227, 0.6976);
  --project-carousel-button-surface-active: rgba(193, 193, 198, 0.6544);
  display: inline-grid;
  width: var(--project-carousel-control-size);
  height: var(--project-carousel-control-size);
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--project-carousel-button-surface);
  color: var(--project-carousel-arrow-color);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  transition: background 100ms linear, color 100ms linear, opacity 100ms linear;
}

.project-carousel__button svg {
  display: block;
  width: var(--project-carousel-control-size);
  height: var(--project-carousel-control-size);
}

.project-carousel__button path {
  fill: currentColor;
  transition: fill 100ms linear;
}

.project-carousel__button:hover:not(:disabled) {
  background: var(--project-carousel-button-surface-hover);
  color: var(--project-carousel-arrow-color-hover);
}

.project-carousel__button:hover:not(:disabled) path {
  fill: var(--project-carousel-arrow-color-hover);
}

.project-carousel__button:active:not(:disabled) {
  background: var(--project-carousel-button-surface-active);
  color: var(--project-carousel-arrow-color-active);
  outline: none;
}

.project-carousel__button:active:not(:disabled) path {
  fill: var(--project-carousel-arrow-color-active);
}

.project-carousel__button:focus-visible {
  outline: 2px solid #0071e3;
  outline-offset: 3px;
}

.project-carousel__button:disabled {
  pointer-events: none;
  cursor: default;
  opacity: 0.42;
}

.project-feature-grid .project-carousel {
  max-width: 100%;
}

/* Close To Me presents the two user roles as separate journeys. Keep each
 * screen comfortably framed inside the shared carousel surface instead of
 * letting a phone-sized interface fill the entire card. */
.project-carousel-group {
  margin-top: var(--project-section-intro-space);
}

.project-carousel-group + .project-carousel-group {
  margin-top: var(--space-media);
}

.project-carousel-group__label {
  margin: 0 0 var(--project-section-intro-space);
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-carousel-group__label .project-inline-label {
  font-weight: 600;
}

.project-carousel-group .project-carousel {
  --project-carousel-card-width: min(
    56rem,
    calc(
      (100vw - var(--project-carousel-rail-stop) - (2 * var(--portfolio-content-gutter)) -
      (2 * var(--project-carousel-gap))) / 3
    )
  );
  margin-top: 0;
}

.project-carousel--ctm-journey .project-carousel__slide {
  /* Use the same bounded module width as the rest of the case study: the
   * content area to the right of the rail, capped by --content-max. */
  width: calc(
    (
      min(
        var(--content-max),
        calc(100vw - var(--portfolio-rail-column) - (2 * var(--portfolio-content-gutter)))
      ) - (2 * var(--project-carousel-gap))
    ) / 3
    * 0.7
  );
  flex-basis: calc(
    (
      min(
        var(--content-max),
        calc(100vw - var(--portfolio-rail-column) - (2 * var(--portfolio-content-gutter)))
      ) - (2 * var(--project-carousel-gap))
    ) / 3
    * 0.7
  );
  /* Keep the three-column rhythm, but make the phone screens much smaller on
   * wide displays. The slide is intentionally transparent and only provides
   * the spacing needed for the carousel interaction. */
  aspect-ratio: auto;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.project-carousel--ctm-journey .project-carousel__track {
  /* The viewport may extend to the right edge like the shared carousel, while
   * the first card stays aligned with the bounded project module. */
  padding-inline: var(--project-carousel-content-inset);
}

.project-carousel--ctm-journey .project-carousel__slide--media-only {
  place-items: center;
}

.project-carousel--ctm-journey .project-media-split__media {
  display: block;
  width: 100%;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.project-carousel--ctm-journey .project-carousel__media-visual {
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
  /* The source GIFs used transparent pixels outside the rounded phone body.
   * WebM keeps the animation compact but does not reliably expose that alpha
   * channel in every browser, so clip only the former transparent corners. */
  border-radius: 11%;
  clip-path: inset(0 round 11%);
}

/* Rednote and TikTok screens are individual media assets inside transparent
 * carousel slides, so the radius belongs to each image or video rather than
 * the slide or its surrounding spacing. */
.project-carousel--rednote .project-carousel__media-visual,
.project-carousel--tiktok .project-carousel__media-visual,
.project-carousel--wechat .project-carousel__media-visual {
  border-radius: clamp(0.45rem, 0.8vw, 0.8rem);
  clip-path: none;
}

.project-feature-grid .project-feature-copy {
  display: grid;
  gap: var(--space-tight);
}

.project-feature-grid .project-feature-copy .project-type-body,
.project-feature-grid .project-feature-copy .project-card-body {
  margin-top: 0;
}

/* Shared horizontal frame for mobile UI media, following Apple's tile geometry. */
.project-device-frame {
  display: grid;
  width: 100%;
  aspect-ratio: 16 / 9;
  grid-template-rows: minmax(0, 1fr);
  place-items: center;
  overflow: hidden;
  box-sizing: border-box;
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
  padding-block: var(--project-phone-padding-block);
  padding-inline: var(--project-device-padding-inline);
}

.project-device-frame-content {
  display: flex;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  gap: 1.25rem;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
}

.project-device-frame-content > * {
  display: grid;
  width: auto;
  height: 100%;
  flex: 0 0 auto;
  min-width: 0;
  min-height: 0;
  place-items: center;
}

.project-device-frame-content .project-media {
  display: block;
  width: auto;
  height: 100%;
  min-width: 0;
  min-height: 0;
  max-width: 100%;
  max-height: 100%;
  border: 0;
  border-radius: 0;
  object-fit: contain;
}

.project-research-methods {
  margin-top: var(--space-media);
}

.project-research-methods > article {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.project-sections {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 0;
}

.project-section {
  padding: 0 0 var(--space-section);
  scroll-margin-top: var(--section-scroll-margin);
}

/* The final section does not need to reserve space for another section before
 * the page footer begins. */
.project-sections > .project-section:last-child {
  padding-bottom: 0;
}

.project-section-header {
  width: min(var(--project-apple-viewport-width), var(--project-apple-lockup-max));
  max-width: var(--project-apple-lockup-max);
  margin: 0;
}

.project-section-header .project-eyebrow {
  margin: 0 0 var(--project-eyebrow-space);
}

.project-section-header h2 {
  max-width: var(--project-text-max);
  margin: 0 0 var(--project-headline-space);
  color: var(--project-heading);
  font-family: var(--project-font-display);
  font-size: var(--project-type-section-title-size);
  font-weight: var(--project-type-title-weight);
  letter-spacing: var(--project-type-title-tracking);
  line-height: var(--project-type-title-leading);
}

/* Experimental-art pages read as a sequence of full sections rather than a
 * product feature list. Each artefact keeps its own media, but its text uses
 * the same section-level type scale and spacing as the main narrative. */
.project-art-sequence {
  display: grid;
  gap: 0;
  margin-top: 0;
}

.project-art-step {
  display: grid;
  min-width: 0;
  gap: 0;
  padding-bottom: var(--space-section);
}

.project-art-step__copy {
  max-width: var(--project-text-max);
}

.project-art-step__copy .project-eyebrow {
  margin: 0 0 var(--project-eyebrow-space);
}

.project-art-step__copy h3 {
  max-width: var(--project-text-max);
  margin: 0 0 var(--project-headline-space);
  color: var(--project-heading);
  font-family: var(--project-font-display);
  font-size: var(--project-type-section-title-size);
  font-weight: var(--project-type-title-weight);
  letter-spacing: var(--project-type-title-tracking);
  line-height: var(--project-type-title-leading);
}

.project-art-step__copy .project-copy {
  margin-top: 0;
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-art-step__media {
  display: grid;
  min-width: 0;
  max-width: 100%;
  margin-top: var(--space-media);
  overflow: hidden;
  gap: var(--space-content);
}

.project-art-step__media > .project-media-frame {
  margin: 0;
}

.project-art-step__media > .project-media-frame > .project-media {
  min-height: 0;
}

.project-art-step__caption {
  margin: 0;
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: var(--project-type-support-size);
  line-height: var(--project-type-support-leading);
}

.project-copy {
  display: flex;
  max-width: var(--project-text-max);
  flex-direction: column;
  gap: var(--space-paragraph);
  margin-top: var(--space-content);
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-copy.project-copy--intro {
  font-weight: 350;
  color: rgba(29, 29, 31, 0.64);
}

.project-panel {
  display: grid;
  width: 100%;
  gap: 0;
  overflow: hidden;
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
}

/* Full-width, text-only outcome module for launch case studies. */
.project-impact-panel {
  width: 100%;
  max-width: none;
  padding: clamp(3rem, 5vw, 5rem) clamp(1.5rem, 3vw, 3rem);
  box-sizing: border-box;
}

.project-impact-panel p {
  margin: 0;
  color: var(--project-heading);
  font-family: "Just Another Hand", cursive;
  font-size: clamp(1.5rem, 2.4vw, 2.5rem);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
  text-align: center;
}

.project-section > .project-auto-grid {
  margin-top: var(--space-media);
}

/* Section introduction spacing remains independent from module-to-module
 * spacing, even though both currently resolve to 48px. */
.project-section > .project-section-intro-gap {
  margin-top: var(--project-section-intro-space);
}

/* Every standard project inherits the same section rhythm, even when a
 * page does not add the optional spacing classes to its markup. */
.project-section > .project-section-header + * {
  margin-top: var(--project-section-intro-space);
}

.project-section > .project-section-header + * ~ * {
  margin-top: var(--project-module-space);
}

/* Keep each section's media/components in one explicit container. The
 * container owns the section-to-content rhythm; its direct children only
 * add the module spacing between sibling components. */
.project-section-components {
  min-width: 0;
}

.project-section-components > * {
  min-width: 0;
  margin-top: 0;
}

.project-section-components > * + * {
  margin-top: var(--project-module-space);
}

/* Organisms Utopia's split sections keep the shared component rhythm while
 * preventing legacy art-step wrappers from adding a second section gap. */
.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] {
  gap: var(--project-module-space);
  margin-top: 0;
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] > .project-art-step {
  margin-top: 0;
  padding-bottom: 0;
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] .project-art-step__media {
  margin-top: 0;
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] > .project-art-step > .project-carousel {
  margin-top: 0;
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] > .project-art-step > .project-carousel + .project-carousel {
  margin-top: var(--project-module-space);
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] > .project-art-step > .project-media-stack {
  gap: var(--project-module-space);
  margin-top: 0;
}

.project-section-components .project-media-stack[class*="project-media-stack--organisms-"] > .project-art-step > .project-media-stack > .project-media-grid {
  margin-top: 0;
}

.project-section > .project-feature-grid.project-feature-intro-gap {
  margin-top: var(--project-section-intro-space);
}

.project-testing-panel {
  margin: var(--space-media) 0 0;
  padding: 1.5rem;
}

.project-testing-panel p {
  max-width: var(--project-text-max);
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-testing-panel cite {
  display: block;
  margin-top: 0.75rem;
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: var(--project-type-support-size);
  letter-spacing: var(--project-type-body-tracking);
  font-style: normal;
  line-height: var(--project-type-support-leading);
}

.project-reframe {
  max-width: var(--project-text-max);
  margin-top: var(--space-media);
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

.project-emphasis {
  color: var(--project-heading);
  font-weight: 600;
}

/* Shared responsive grid for project facts, evidence, principles, and comparisons. */
.project-auto-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 0;
  background: var(--project-surface);
}

.project-auto-grid > * {
  min-width: 0;
  padding: var(--project-grid-padding) var(--project-grid-padding-inline);
  border: 0;
  background: var(--project-surface);
}

.project-auto-grid > * + * {
  border-inline-start: 1px solid var(--project-grid-divider);
}

/* Standalone principle cards for strategy-led modules. The cards borrow the
 * project's own tokens while keeping the independent-card structure used by
 * the reference case study. */
.project-principle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1.25rem;
  width: 100%;
}

.project-principle-grid > * {
  min-width: 0;
  padding: var(--project-grid-padding) var(--project-grid-padding-inline);
  border: var(--project-outline);
  border-radius: var(--project-radius);
  background: var(--project-surface);
}

.project-principle-grid .project-card-label {
  color: var(--project-body-soft);
}

.project-principle-grid .project-card-title {
  margin-top: 1rem;
}

/* Shared four-level type system for text-led project modules. */
.project-type-eyebrow,
.project-card-label {
  display: block;
  color: var(--project-body-soft);
  font-family: var(--project-font-display);
  font-size: var(--project-module-eyebrow-size);
  font-weight: var(--project-module-eyebrow-weight);
  letter-spacing: var(--project-module-eyebrow-tracking);
  line-height: var(--project-module-eyebrow-leading);
  text-transform: none;
}

.project-type-title,
.project-card-title {
  display: block;
  margin-top: 0.75rem;
  color: var(--project-heading);
  font-family: var(--project-font-display);
  font-size: var(--project-module-title-size);
  font-weight: var(--project-module-title-weight);
  letter-spacing: var(--project-module-title-tracking);
  line-height: var(--project-module-title-leading);
}

.project-type-body,
.project-card-body {
  display: block;
  margin-top: 0.75rem;
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-module-body-size);
  font-weight: var(--project-module-body-weight);
  letter-spacing: var(--project-module-body-tracking);
  line-height: var(--project-module-body-leading);
}

.project-type-highlight,
.project-metric-value {
  display: block;
  color: var(--project-heading);
  font-family: var(--project-font-display);
  font-size: var(--project-type-highlight-size);
  font-weight: var(--project-type-highlight-weight);
  letter-spacing: var(--project-type-highlight-tracking);
  line-height: var(--project-type-highlight-leading);
}

.project-inline-label {
  color: var(--project-heading);
  font-weight: 600;
}

/* Highlight descriptions use the same body level as every other text module. */
.project-type-body.project-metric-body,
.project-metric-body {
  display: block;
  margin-top: var(--space-tight);
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-module-body-size);
  font-weight: var(--project-module-body-weight);
  letter-spacing: var(--project-module-body-tracking);
  line-height: var(--project-module-body-leading);
}

.project-stat-support {
  display: block;
  margin-top: var(--space-tight);
  color: var(--project-body-soft);
  font-family: var(--project-font-text);
  font-size: var(--project-type-support-size);
  line-height: var(--project-type-support-leading);
}

.project-statistics {
  display: grid;
  overflow: hidden;
  margin-top: var(--space-media);
}

.project-statistics > div {
  padding: var(--project-grid-padding) var(--project-grid-padding-inline);
}

/* Supporting copy lives inside the lockup container, matching Apple's structure. */
.project-lockup-copy {
  width: 100%;
  max-width: none;
  margin-top: 0;
  color: var(--project-body);
  font-family: var(--project-font-text);
  font-size: var(--project-type-body-size);
  font-weight: var(--project-type-body-weight);
  letter-spacing: var(--project-type-body-tracking);
  line-height: var(--project-type-body-leading);
}

@media (min-width: 48rem) {
  .project-page-article {
    padding: max(0px, calc(var(--section-scroll-margin) - var(--portfolio-content-top-padding))) 0 6rem;
  }

  .project-page-article:has(> .project-page-footer) {
    padding-bottom: 1.5rem;
  }
}

@media (min-width: 64rem) {
  .project-page-article {
    --space-section: 9rem;
    padding-right: 0;
    padding-left: 0;
  }

  .project-section-header h2 {
    font-size: var(--project-type-section-title-size);
    line-height: var(--project-type-title-leading);
  }

}

@media (max-width: 39.999rem) {
  .project-media-grid--2,
  .project-media-grid--3,
  .project-media-grid--4 {
    grid-template-columns: 1fr;
  }

  .project-auto-grid > * + * {
    border-inline-start: 0;
    border-block-start: 1px solid var(--project-grid-divider);
  }

  .project-media-split__copy {
    padding-block: var(--project-grid-padding);
  }

  .project-media-split--sharing-economy {
    grid-template-columns: 1fr;
  }

  .project-media-split--sharing-economy .project-media-split__copy {
    padding-inline: var(--project-grid-padding);
  }

  .project-media-split--phone:not(.project-phone-module--multi) .project-media-split__copy,
  .project-carousel__slide--phone:not(.project-phone-module--multi) .project-media-split__copy {
    padding-inline: var(--project-grid-padding);
  }

  .project-media-split__media {
    min-height: 22rem;
  }

  .project-carousel__slide {
    --project-carousel-card-width: calc(100vw - (2 * var(--portfolio-content-gutter)));
  }

  .project-carousel__slide .project-media-split__copy {
    padding-inline: var(--project-grid-padding);
  }

  .project-carousel__slide .project-media-split__media {
    min-height: 0;
  }
}

@media (min-width: 110rem) {
  .project-carousel {
    --project-carousel-parent-inset: calc(
      (100vw + var(--project-carousel-rail-column) - var(--content-max)) / 2
    );
    --project-carousel-content-inset: calc(
      var(--project-carousel-parent-inset) - var(--project-carousel-rail-stop)
    );
  }
}

@media (max-width: 47.99rem) {
  .project-carousel {
    --project-carousel-rail-column: 0px;
    --project-carousel-parent-inset: var(--portfolio-content-gutter);
    --project-carousel-content-inset: var(--portfolio-content-gutter);
  }
}

@media (max-width: 66.75rem) {
  .project-page-article {
    --space-section: 9rem;
    --space-media: 2.5rem;
  }

  .project-page-article.project-apple-standard {
    --project-section-space: 9rem;
    --project-section-intro-space: 2.5rem;
    --project-hero-overview-space: 4rem;
    --project-media-space: 2.5rem;
    --project-eyebrow-space: 0.75rem;
    --project-headline-space: 1.25rem;
  }

  .project-title {
    font-size: var(--project-type-title-size);
  }

  .project-section-header h2 {
    font-size: var(--project-type-section-title-size);
    line-height: 1.1;
    letter-spacing: 0;
  }

  .project-eyebrow {
    font-size: var(--project-type-eyebrow-size);
    line-height: 1.2105263158;
  }

  .project-lockup-copy {
    font-family: var(--project-font-text);
    font-size: var(--project-type-body-size);
    font-weight: var(--project-type-body-weight);
    letter-spacing: var(--project-type-body-tracking);
    line-height: var(--project-type-body-leading);
  }
}

@media (max-width: 45.875rem) {
  .project-page-article {
    --space-section: 7rem;
    --space-media: 2rem;
  }

  .project-page-article.project-apple-standard {
    --project-section-space: 7rem;
    --project-section-intro-space: 2rem;
    --project-hero-overview-space: 4rem;
    --project-media-space: 2rem;
    --project-eyebrow-space: 0.625rem;
    --project-headline-space: 1rem;
  }

  .project-title {
    font-size: var(--project-type-title-size);
  }

  .project-section-header h2 {
    font-size: 1.875rem;
    line-height: 1.125;
    letter-spacing: 0.004em;
  }

  .project-art-step__copy h3 {
    font-size: 1.875rem;
    line-height: 1.125;
    letter-spacing: 0.004em;
  }

  .project-eyebrow {
    font-size: var(--project-type-eyebrow-size);
    line-height: 1.2353641176;
  }

  .project-lockup-copy {
    font-family: var(--project-font-text);
    font-size: var(--project-type-body-size);
    font-weight: var(--project-type-body-weight);
    letter-spacing: var(--project-type-body-tracking);
    line-height: var(--project-type-body-leading);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
