body {
  margin: 0;
}

/* =========================
   HERO SLIDER
========================= */

.hero-slider {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background: var(--color-white);
}

#hero-slider,
.hero-slider__stage {
  width: 100%;
  height: 100%;
}

.hero-slider__stage {
  position: relative;
}

.hero-slider__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.hero-slider__media.is-active {
  opacity: 1;
}

/* object-fit doesn't apply to <iframe> in most browsers, so the Vimeo
   embed can't just "cover" the box like an <img> does. Instead, size the
   iframe assuming a 1440/840 source (matches the ratio used for images
   across the site) so it's always at least as big as the viewport in both
   dimensions, then center and let it overflow - the same math as
   background-size: cover, done manually. */
.hero-slider__media--video {
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  width: 100vw;
  height: 58.33vw; /* 100 / (1440/840) */
  min-height: 100vh;
  min-width: 171.43vh; /* 100 * (1440/840) */
  transform: translate(-50%, -50%);
}

/* Mobile vimeo sources are portrait (400/874), not the desktop 1440/840
   landscape ratio above - reusing the desktop math here leaves the iframe
   box sized for the wrong shape, so Vimeo's own player letterboxes the
   real (portrait) video inside it, showing as white bars. Same cover
   formula, just solved for the mobile source ratio instead.
   Breakpoint matches getAssetConfig()'s isMobile check (800px) in main.js,
   not the 900px used elsewhere in this file - the video source itself
   switches at 800px, so the sizing math must switch at exactly the same
   point or the two fall out of sync in the 800-900px gap. */
@media (max-width: 800px) {
  .hero-slider__media--video {
    height: 218.5vw; /* 100 / (400/874) */
    min-width: 45.77vh; /* 100 * (400/874) */
  }
}

.hero-slider__animation svg {
  width: 100%;
  height: 100%;
  display: block;
}

.hero-slider__controls {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px;
  mix-blend-mode: exclusion;
}

.hero-slider__dot {
  width: 20px;
  height: 16px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-white);
  display: grid;
  place-items: center;
  cursor: pointer;
}

.hero-slider__dot-mark {
  width: 8px;
  height: 8px;
  display: block;
  border-radius: 50%;
  background: currentColor;
}

.hero-slider__progress {
  width: 12px;
  height: 12px;
  display: none;
  overflow: visible;
  transform: rotate(-90deg);
}

.hero-slider__progress circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 30.16;
  stroke-dashoffset: 30.16;
}

.hero-slider__dot.is-active .hero-slider__dot-mark {
  display: none;
}

.hero-slider__dot.is-active .hero-slider__progress {
  display: block;
}

.hero-slider__dot.is-active .hero-slider__progress circle {
  animation: hero-progress var(--slide-duration) linear forwards;
}

@keyframes hero-progress {
  to {
    stroke-dashoffset: 0;
  }
}

/* =========================
   CONTENT
========================= */

.home-content {
  position: relative;
  z-index: 1;
  margin-top: 100vh;
  background: var(--color-white);
}

.home-text {
  padding: var(--space-16) 16px 320px;
}

.home-text h1 {
  margin: 0 0 var(--space-120);
}

.home-connect {
  display: flex;
  align-items: baseline;
  gap: var(--space-12);
}

.home-connect__label {
  color: var(--color-grey-400);
}

.home-connect__links {
  color: var(--color-black);
}

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

/* =========================
   PROJECTS PAGE
========================= */

html {
  scroll-behavior: smooth;
}

.projects-page,
.project-detail {
  background: var(--color-white);
  min-height: 100vh;
}

.project-index {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  box-sizing: border-box;
  padding: var(--space-16) var(--space-16) 0;
}

.project-index__item > h3 {
  display: block;
  margin: 0;
}

.project-index__text {
  color: inherit;
}

.project-index__external {
  position: relative;
  top: 1px;
  margin-left: var(--space-4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
}

.project-index__icon {
  display: block;
}

.project-index__icon--hover {
  display: none;
}

.project-index__external:hover .project-index__icon--default {
  display: none;
}

.project-index__external:hover .project-index__icon--hover {
  display: block;
}

.project-title {
  margin: 0;
}

.project-title__secondary {
  color: var(--color-grey-400);
}

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

.project-section__content,
.project-detail__content {
  box-sizing: border-box;
  padding: 0 var(--space-16);
}

.project-detail__content {
  padding-top: var(--space-16);
}

.project-detail__media {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: var(--space-200);
}

/* =========================
   PROJECT TEXT BLOCK
========================= */

.project-text {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-16) var(--space-16) var(--space-320);
}

.project-text h1 {
  margin: 0;
}

.project-meta {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: var(--space-8);
}

/* Detail page: title is the same size as the surrounding text, meta sits
   flush against it with no gap. */
.project-detail__content .project-meta {
  margin-top: 0;
}

.project-meta__row {
  display: block;
  margin: 0;
}

.project-meta__text {
  margin: 0;
}

.project-section__media {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: var(--space-16);
}

.project-media-row {
  display: grid;
  width: 100%;
  gap: 8px;
}

.project-media-row--wide {
  grid-template-columns: 1fr;
}

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

.project-media {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--color-grey-50);
}

.project-media img,
.project-media iframe,
.project-media video,
.project-media__animation,
.project-media__animation svg {
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}

.project-media img,
.project-media video {
  object-fit: cover;
}

.project-media img.is-preview {
  filter: blur(8px);
  transform: scale(1.1);
}

.project-media img {
  transition: filter 0.25s ease, transform 0.25s ease, opacity 0.25s ease;
}

.project-media__sequence-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.project-media__sequence-layer.is-front {
  opacity: 1;
}

.project-media iframe {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.project-media.is-loaded iframe {
  opacity: 1;
}

/* The Vimeo video iframe has its own poster layer sitting above it
   (z-index) doing the reveal, so unlike other iframe types (e.g. Spline)
   it isn't hidden via opacity here - browsers throttle rendering/decoding
   of opacity:0 content, which made the video visibly "catch up" for a
   beat right when it was revealed. Keeping it always fully rendered
   underneath the opaque poster avoids that stutter. */
.project-media iframe.project-media__video {
  opacity: 1;
  transition: none;
}

.project-media__poster {
  position: absolute;
  inset: 0;
  z-index: 1;
  transition: opacity 0.3s ease;
}

.project-media.is-loaded .project-media__poster {
  opacity: 0;
  pointer-events: none;
}

.project-section__more {
  display: inline-flex;
  margin: var(--space-16) 0 0 var(--space-16);
  color: var(--color-grey-400);
}

.project-section__more:hover {
  color: var(--color-grey-600);
}

@media (max-width: 900px) {
  .hero-slider__controls {
    top: 50%;
    right: 16px;
    flex-direction: column;
    transform: translateY(-50%);
  }

  .project-section {
    padding-top: 96px;
  }

  .project-media-row--pair {
    grid-template-columns: 1fr;
  }
}

/* =========================
   PROJECT TEXT + ICONS BLOCK
========================= */

/* Icons sit inline inside the same <h1> flow as the surrounding text
   (see renderTextIconsBlock in projects.js). No forced width/height here -
   each renders at whatever size is baked into its own SVG (its own
   width/height or viewBox), rather than being stretched/squashed to a
   uniform height that doesn't match how they were actually drawn. */
.project-text-icons__icon {
  display: inline-block;
  vertical-align: middle;
  margin: 0 2px;
}

/* =========================
   ABOUT PAGE
========================= */

.about-text {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-16) var(--space-16) var(--space-320);
}

.about-text h1 {
  margin: 0 0 var(--space-120);
}

.about-blocks {
  display: flex;
  flex-direction: column;
  gap: var(--space-40);
  margin-bottom: var(--space-120);
}

.about-block {
  display: flex;
  flex-direction: column;
}

.about-block__label {
  color: var(--color-grey-400);
}

.about-block__value {
  color: var(--color-black);
  font-size: var(--h2-size, 28px);
  line-height: var(--h2-line, 108%);
  font-weight: 400;
}

.about-block__value p {
  font-size: inherit;
  line-height: inherit;
  margin: 0 0 var(--space-16);
}

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

.about-block__value--tight p {
  margin: 0;
}

.about-connect {
  display: flex;
  align-items: baseline;
  gap: var(--space-12);
}

.about-connect__label {
  color: var(--color-grey-400);
}

.about-connect__links {
  color: var(--color-black);
}
