/* ============================================================
   Hero: the Colours Wood Works Ken Burns slideshow, ported.
   Same mechanism: three slides, one 18s CSS loop, delays 0/6/12s,
   each slide fades in, zooms to scale(1.05), fades out.

   Four defects in the original are fixed here:
   1. .hero had no background, so the picture dipped toward the
      page colour between slides. It now sits on --bg.
   2. The outgoing slide used to start fading before the incoming
      one arrived. The keyframes now hold it until it is covered.
   3. The photos were CSS background images, so the browser found
      them late. They are real <img> now, cover fitted.
   4. There was no way to stop it. There is a pause control.
   ============================================================ */

.hero {
  position: relative;
  height: 88svh;
  min-height: 460px;
  overflow: hidden;
  padding: 0;
  background: var(--bg);        /* fix 1: no dip between slides */
  isolation: isolate;
}

.hero__slides { position: absolute; inset: 0; }

.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: kenburns 18s infinite;
  will-change: transform, opacity;
}
.hero__slide:nth-child(1) { animation-delay: 0s;  z-index: 3; }
.hero__slide:nth-child(2) { animation-delay: 6s;  z-index: 2; }
.hero__slide:nth-child(3) { animation-delay: 12s; z-index: 1; }

.hero__slide img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 70% 30%;     /* keeps him right of the headline */
}

/* fix 2: opacity holds at 1 until 38%, by which point the next
   slide has fully faded in, so the ground never shows through. */
@keyframes kenburns {
  0%   { opacity: 0; transform: scale(1); }
  4%   { opacity: 1; }
  33%  { opacity: 1; transform: scale(1.05); }
  38%  { opacity: 0; transform: scale(1.05); }
  100% { opacity: 0; transform: scale(1); }
}

/* One photo: no crossfade (it would fade out to an empty panel), just a
   slow Ken Burns push that eases back, so the picture never stops breathing. */
.hero--single .hero__slide {
  opacity: 1;
  animation: kenburns-single 18s ease-in-out infinite alternate;
  transform-origin: 66% 40%;
}
@keyframes kenburns-single {
  from { transform: scale(1); }
  to   { transform: scale(1.07); }
}

/* Video mode. The clip already moves, so no zoom on top of it. */
.hero--video .hero__slide { animation: none; transform: none; }
.hero__video {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 70% 30%;
}
@media (max-width: 640px) { .hero__video { object-position: 62% 20%; } }

/* Three scene mode: the Colours slideshow keyframes run as they are, with a
   video inside each slide instead of a photo. */
/* Anchored to the TOP of the frame: a wide, short screen crops a 16:9 clip
   top and bottom, and his head sits near the top edge, so all the crop is
   taken from the bottom (desk and keyboard). */
.hero--scenes .hero__video { object-position: 50% 0%; }
/* No zoom on the videos. Scaling moving video every frame made it shimmer
   and shake, and pushed his head further out of frame. Crossfade only.
   The next scene is fully in by 37% of the loop, so the outgoing one holds
   until 38% and fades by 42%. The ground never shows between scenes. */
.hero--scenes .hero__slide { animation-name: fade-scenes; will-change: opacity; transform: none; }
@keyframes fade-scenes {
  0%   { opacity: 0; }
  4%   { opacity: 1; }
  38%  { opacity: 1; }
  42%  { opacity: 0; }
  100% { opacity: 0; }
}
/* A phone shows only about a third of the frame's width, and each clip pans,
   so each scene is framed on the middle of the path his head takes. */
@media (max-width: 640px) {
  .hero--scenes .hero__slide:nth-child(1) .hero__video { object-position: 76% 0%; }
  .hero--scenes .hero__slide:nth-child(2) .hero__video { object-position: 53% 0%; }
  .hero--scenes .hero__slide:nth-child(3) .hero__video { object-position: 90% 0%; }
}

/* Empty slide state, until the owner's photos arrive. The crossfade still
   runs on these panels, so the timing is visible with no image loaded. */
.hero__slide--empty {
  display: grid; place-items: center;
  background:
    radial-gradient(80% 70% at 70% 30%, color-mix(in srgb, var(--purple) 14%, transparent), transparent 70%),
    linear-gradient(180deg, var(--card) 0%, var(--bg-2) 100%);
  box-shadow: inset 0 0 0 1px var(--border);
}
.hero__slot {
  font-family: var(--mono); font-size: 12px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted-2);
  padding: 9px 16px; border-radius: 40px;
  border: 1px dashed var(--border-glow);
}
/* With no photo there is nothing to darken, so the wash comes off and the
   headline sits on the panel itself. */
.hero--noimg .hero__overlay { display: none; }

/* Dark enough on the left that the headline holds, clear enough on the
   right that you can actually see him. */
.hero__overlay {
  position: absolute; inset: 0; z-index: 4;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--bg) 90%, transparent) 0%,
      color-mix(in srgb, var(--bg) 74%, transparent) 30%,
      color-mix(in srgb, var(--bg) 30%, transparent) 58%,
      transparent 80%),
    linear-gradient(180deg, transparent 62%, color-mix(in srgb, var(--bg) 55%, transparent) 100%);
}

.hero__content {
  position: relative; z-index: 5;
  height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  max-width: 1440px;            /* wider than the page column, so the text sits further left */
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* Room between each line, so the name, headline, text and buttons read
   as separate steps rather than one block. */
.hero__content .h1 { margin: 26px 0 30px; max-width: 20ch; line-height: 1.08; }
.hero__content .lede { max-width: 46ch; line-height: 1.7; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 40px; }

/* dots. Decorative in the original and decorative here, so they are
   hidden from screen readers rather than pretending to be buttons. */
.hero__dots {
  position: absolute; bottom: 22px; left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  display: flex; gap: .5em;
}
.hero__dots span {
  width: 8px; height: 8px; border-radius: 50%;
  background: color-mix(in srgb, var(--text) 45%, transparent);
  animation: dotcycle 18s infinite;
}
.hero__dots span:nth-child(1) { animation-delay: 0s; }
.hero__dots span:nth-child(2) { animation-delay: 6s; }
.hero__dots span:nth-child(3) { animation-delay: 12s; }
@keyframes dotcycle {
  0%     { background: var(--text); }
  4%     { background: var(--text); }
  33.34% { background: color-mix(in srgb, var(--text) 45%, transparent); }
  100%   { background: color-mix(in srgb, var(--text) 45%, transparent); }
}

/* fix 4: pause control */
.hero__pause { position: absolute; right: var(--gutter); bottom: 18px; z-index: 6; }
.hero.is-paused .hero__slide,
.hero.is-paused .hero__dots span { animation-play-state: paused; }
.hero__pause .ico-pause { display: block; }
.hero__pause .ico-play  { display: none; }
.hero.is-paused .hero__pause .ico-pause { display: none; }
.hero.is-paused .hero__pause .ico-play  { display: block; }

/* ---------- phone ---------- */
@media (max-width: 640px) {
  .hero { height: 82svh; }
  .hero__content { justify-content: flex-end; padding-bottom: 4.5em; }
  .hero__overlay {
    background: linear-gradient(to top,
      color-mix(in srgb, var(--bg) 92%, transparent) 0%,
      color-mix(in srgb, var(--bg) 45%, transparent) 48%,
      color-mix(in srgb, var(--bg) 30%, transparent) 100%);
  }
  .hero__slide img { object-position: 50% 20%; }
  .hero__content .h1 { max-width: none; }
}

/* ---------- reduced motion: one still photo, nothing moving ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero__slide { animation: none; opacity: 0; }
  .hero__slide:nth-child(1) { opacity: 1; }
  .hero__dots, .hero__pause { display: none; }
}

/* ---------- phone layout (2026-09-17) ----------
   The text used to sit over his face. On phones the video now fills the top
   of the hero on its own, fades into the page, and the text sits below it.
   Delete this block to go back to the text over the video. */
@media (max-width: 640px) {
  .hero { height: auto; min-height: 0; display: flex; flex-direction: column; }
  .hero__slides { position: relative; inset: auto; height: min(58svh, 128vw); flex: 0 0 auto; }
  .hero__overlay {
    inset: 0 0 auto 0; height: min(58svh, 128vw);
    background: linear-gradient(to bottom,
      color-mix(in srgb, var(--bg) 0%, transparent) 55%,
      color-mix(in srgb, var(--bg) 75%, transparent) 85%,
      var(--bg) 100%);
  }
  .hero__content {
    height: auto; justify-content: flex-start;
    margin-top: -64px; padding-top: 0; padding-bottom: 44px;
  }
  .hero__content .h1 { margin: 12px 0 16px; font-size: clamp(34px, 9.6vw, 44px); line-height: 1.04; }
  .hero__content .lede { font-size: 17px; line-height: 1.6; }
  .hero__cta { margin-top: 26px; flex-direction: column; gap: 12px; }
  .hero__cta .btn { width: 100%; justify-content: center; }
  .hero__dots { top: calc(min(58svh, 128vw) - 96px); bottom: auto; }
}
