/* ---------- Tokens ---------- */
/* registered so they can transition when the active scene changes */
@property --accent { syntax: '<color>'; inherits: true; initial-value: #169CD8; }
@property --deep   { syntax: '<color>'; inherits: true; initial-value: #182342; }
@property --bg     { syntax: '<color>'; inherits: true; initial-value: #FFFFFF; }

:root {
  /* brand palette */
  --navy: #182342;
  --blue: #169CD8;
  --slate: #5A6586;     /* secondary / body text */
  --off-white: #FFFFFF; /* section backgrounds */
  --panel: #F5F5F5;     /* panels */
  --white: #ffffff;

  /* per-scene colour pairs are set on each .scene via data-accent / data-deep
     (scene 1 navy, scene 2 Myton blue on cyan tint, scene 3 Myton green) */
  --accent: var(--blue);
  --deep: var(--navy);

  /* roles */
  --paper: var(--white);
  --bg: var(--off-white);
  --muted: var(--slate);
  --soft: var(--panel);

  --font-sans: "azo-sans-web", system-ui, sans-serif;

  --pad: 40px;
  --cell-pad: calc(var(--pad) * .75); /* left / right padding inside the text squares (heading, quote, name) */
  --ease: cubic-bezier(.22, .8, .24, 1);
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--navy);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}


/* ---------- Section + pin ---------- */
.tst {
  position: relative;
  background: var(--bg);
  color: var(--deep);
  --grid-line: color-mix(in srgb, var(--deep) 10%, transparent);
  transition: --accent .6s var(--ease), --deep .6s var(--ease), --bg .6s var(--ease);
  /* height is set by script.js from the number of scenes */
}
.tst__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

/* 5 x 4 grid, equal columns. The video fills the centre column across two rows
   (object-fit: cover crops it to fit) */
.tst__grid {
  position: relative;
  height: 100%;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(4, 1fr);
}

.tst__lines {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: inherit;
  grid-template-rows: inherit;
  pointer-events: none;
}
/* shared chrome (progress, pause, animals) fades in with the first scene */
.tst { --intro: 0; }
.tst__motion { opacity: var(--intro); }

.tst__lines > span {
  border-right: 1px solid var(--grid-line);
  border-bottom: 1px solid var(--grid-line);
}
.tst__lines > span:nth-child(5n) { border-right: 0; }
.tst__lines > span:nth-child(n + 16) { border-bottom: 0; }

/* ---------- Cover (start of the block) ----------
   Five columns over the grid showing one slowly rotating, blurred water photo,
   one column per grid column. script.js
   sets --p (0→1) on each and it wipes away from its top edge down, column
   after column, left to right. */
.tst__cover {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  pointer-events: none;
}
.tst__cover > span {
  --p: 0;
  position: relative;
  overflow: hidden;
  clip-path: inset(calc(var(--p) * 100%) 0 0 0);
}
/* Each column is a window onto one shared square layer centred on the frame
   (shifted per column by --k), so the picture lines up exactly across columns.
   The square is just big enough to cover the frame at any angle (~the frame's
   diagonal), so it can rotate without zooming in much — keeping the photo's
   light and dark tones — and reads as a slowly moving gradient. */
.tst__cover > span::before {
  content: "";
  position: absolute;
  width: 142vmax;
  height: 142vmax;
  left: calc((2.5 - var(--k)) * 100% - 71vmax);
  top: calc(50% - 71vmax);
  background: #182342 url("assets/images/cover-water.jpg") center / cover no-repeat;
  filter: grayscale(1) contrast(1.05); /* water photo in black and white; the blue comes from the tint above it */
  animation: cover-spin 60s linear infinite;
}
/* light grid lines over the water (matching the 5 x 4 grid underneath), plus a
   light navy tint so the white heading reads over the paler water */
.tst__cover > span::after {
  --cover-line: rgba(255, 255, 255, .28);
  content: "";
  position: absolute;
  inset: 0;
  background:
    /* right edge of the column = vertical grid line */
    linear-gradient(to left, var(--cover-line) 0 1px, transparent 1px),
    /* row lines at 25%, 50% and 75% */
    linear-gradient(to bottom,
      transparent calc(25% - 1px), var(--cover-line) calc(25% - 1px) 25%,
      transparent 25% calc(50% - 1px), var(--cover-line) calc(50% - 1px) 50%,
      transparent 50% calc(75% - 1px), var(--cover-line) calc(75% - 1px) 75%,
      transparent 75%),
    rgba(24, 35, 66, .62);
}
/* no vertical line on the far right edge */
.tst__cover > span:last-child::after {
  background:
    linear-gradient(to bottom,
      transparent calc(25% - 1px), var(--cover-line) calc(25% - 1px) 25%,
      transparent 25% calc(50% - 1px), var(--cover-line) calc(50% - 1px) 50%,
      transparent 50% calc(75% - 1px), var(--cover-line) calc(75% - 1px) 75%,
      transparent 75%),
    rgba(24, 35, 66, .62);
}
.tst__cover > span:nth-child(1) { --k: 0; }
.tst__cover > span:nth-child(2) { --k: 1; }
.tst__cover > span:nth-child(3) { --k: 2; }
.tst__cover > span:nth-child(4) { --k: 3; }
.tst__cover > span:nth-child(5) { --k: 4; }
@keyframes cover-spin {
  to { transform: rotate(360deg); }
}
.tst.is-paused .tst__cover > span::before { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .tst__cover > span::before { animation: none; }
}

/* ---------- Hero (before the first story) ----------
   The heading, centred in the frame in white, with three faces in squares
   around it, all above the cover image (z-index over the cover's 10). */
.hero-scene { display: contents; }
.hero-scene.is-gone > * { visibility: hidden; }
.hero__face {
  position: relative;
  z-index: 11;
  overflow: hidden;
}
.hero__face img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero__face--1 { grid-area: 1 / 2; }  /* top, second column */
.hero__face--2 { grid-area: 2 / 5; }  /* right, second row */
.hero__face--3 { grid-area: 4 / 1; }  /* bottom-left */
.hero__heading {
  grid-area: 1 / 1 / 5 / 6;
  align-self: center;
  justify-self: center;
  margin: 0;
  padding: 0 var(--pad);
  position: relative;
  z-index: 12;
  text-align: center;
  font-size: clamp(40px, 5.6vw, 96px);
  line-height: 1.02;
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--white);
}

/* scenes share the grid; their children are placed directly into it */
.scene { display: contents; }
.scene.is-gone > * { visibility: hidden; }
.scene:not(.is-active) > * { pointer-events: none; }

/* ---------- Static chrome (follows the active scene's colours) ---------- */
/* heading, centred in row 2 across columns 1–2 */
.tst__intro {
  grid-area: 2 / 1 / 3 / 3;
  justify-content: center;
  padding: 0 var(--cell-pad);
}
/* ---------- Scene content ---------- */
.tst__heading {
  margin: 0;
  font-size: clamp(36px, 4.2vw, 68px);
  line-height: 1.02;
  font-weight: 700;
  letter-spacing: -.025em;
  color: var(--deep);
  position: relative;
  z-index: 2;
}
.line { display: block; overflow: hidden; padding-bottom: .1em; margin-bottom: -.1em; }

.tst__media {
  grid-area: 2 / 3 / 4 / 4;
  position: relative;
  z-index: 1;
}
.tst__video {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--soft);
}
.tst__video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* sign sits centred in the cell above the video — hidden for now, delete the display line to bring back */
.tst__sign {
  display: none;
  grid-area: 1 / 3;
  align-self: center;
  justify-self: center;
  width: 64%;
  height: auto;
  position: relative;
  z-index: 3;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .2));
  pointer-events: none;
}

.tst__quote {
  grid-area: 2 / 4 / 3 / 5; /* one square */
  justify-content: flex-start; /* top of the square */
  align-items: flex-start;
  margin: 0;
  padding: var(--pad) var(--cell-pad) 0; /* same top inset as the name / position */
}
.quote-mark {
  display: block;
  height: 11px;
  aspect-ratio: 55.76 / 36.88; /* matches the icon, ~17px wide */
  margin-bottom: 12px;
  background: var(--deep); /* same as the quote text */
  -webkit-mask: url("assets/quote.svg") center / contain no-repeat;
          mask: url("assets/quote.svg") center / contain no-repeat;
}
.tst__quote blockquote {
  margin: 0;
  font-weight: 400;
  font-size: clamp(13px, 1vw, 17px);
  line-height: 1.28;
  letter-spacing: -.015em;
  color: var(--deep);
}

.tst__cite {
  grid-area: 3 / 4 / 4 / 6;
  justify-content: flex-start; /* top of the square, like the other layouts */
  margin: 0;
  padding: var(--pad) var(--cell-pad);
  gap: 4px;
}

/* Text blocks fill their whole grid area and paint the background colour over it,
   so the grid lines inside a multi-cell block disappear and it reads as one rectangle
   (no text ever crosses a line). The outer right/bottom lines are kept via the 1px inset.
   The fill fades with the block's own --in / --out. */
.tst__intro,
.tst__quote,
.tst__cite {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;
}
/* (name/role is short enough not to cross a line, so it keeps the grid) */
.tst__intro::before,
.tst__quote::before {
  content: "";
  position: absolute;
  inset: 0 1px 1px 0;
  background: var(--bg);
  z-index: -1;
  opacity: calc(var(--in, 1) - var(--out, 0));
}
.tst__intro { z-index: 2; }
.name { font-weight: 700; font-size: 17px; color: var(--deep); }
.role { color: var(--deep); font-size: 15px; }
/* scroll grid: the position matches the quote text size */
.tst__cite .role { font-size: clamp(13px, 1vw, 17px); }

/* bottom gradient for legibility of the labels */
.tst__video::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 40%;
  background: linear-gradient(to top, rgba(0, 0, 0, .4), rgba(0, 0, 0, 0));
  pointer-events: none;
  transition: opacity .3s;
}

/* "Watch story" bottom-left */
.play {
  position: absolute;
  bottom: 20px;
  z-index: 1;
  color: var(--white);
  font: 400 15px/1 var(--font-sans);
  transition: opacity .3s;
}
.play {
  left: 20px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.play .icon { width: 13px; height: 13px; fill: currentColor; flex: none; }
.play { transform-origin: left center; transition: transform .25s var(--ease), opacity .3s; }
.play:hover, .play:focus-visible { transform: scale(1.06); }
.play:focus-visible { outline: 2px solid var(--white); outline-offset: 4px; }
.tst__video.is-playing::after { opacity: 0; }

/* pause / resume motion */
.tst__motion {
  grid-area: 4 / 5;
  align-self: end;
  justify-self: end;
  margin: var(--pad);
  width: 44px;
  height: 44px;
  padding: 0;
  position: relative;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--deep) 25%, transparent);
  background: transparent;
  color: var(--deep);
  cursor: pointer;
  transition: border-color .2s;
}
.tst__motion:hover { border-color: var(--deep); }
.tst__motion:focus-visible { outline: 2px solid var(--deep); outline-offset: 3px; }
.tst__motion .icon { width: 14px; height: 14px; fill: currentColor; }
.tst__motion .when-paused,
.tst__motion[aria-pressed="true"] .when-playing { display: none; }
.tst__motion[aria-pressed="true"] .when-paused { display: contents; }
.tst__motion .when-playing { display: contents; }

.tst__video.is-playing .play { opacity: 0; pointer-events: none; }

/* scroll grid: the pause button sits on each video, bottom right, in white */
.tst__video .tst__motion {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 2;
  margin: 0;
  opacity: 1;
  border-color: rgba(255, 255, 255, .5);
  color: var(--white);
  transition: border-color .2s, opacity .3s;
}
.tst__video .tst__motion:hover { border-color: var(--white); }
.tst__video .tst__motion:focus-visible { outline-color: var(--white); }
/* out of the way of the native controls while a story plays with sound */
.tst__video.is-playing .tst__motion { opacity: 0; pointer-events: none; }

/* chickens (coloured with the active scene's deep colour via a mask) */
/* fills the whole cell so fish surface from the cell's bottom grid line */
.coop {
  grid-area: 3 / 1;
  position: relative;
  z-index: 2; /* above any neighbouring text block's fill */
  overflow: hidden;
}
.critters {
  position: absolute;
  inset: 0;
}
/* engraved illustration (ocean / street / farm), cropped to fill its cell, tinted with the scene's deep colour
   through a mask so it changes with the scene */
.illus {
  position: absolute;
  inset: 0;
  background: var(--deep);
  /* cover: fills the cell edge to edge, cropping the sides; --pos picks the part kept */
  -webkit-mask: var(--src) var(--pos, center) / cover no-repeat;
          mask: var(--src) var(--pos, center) / cover no-repeat;
}

/* chickens keep a little breathing room from the side grid lines */
[data-critters="chicken"] { left: var(--pad); right: var(--pad); }

.fish {
  position: absolute;
  left: 0;
  top: 0;
  width: 52px;
  height: 52px;
  will-change: transform;
}
.fish::before,
.fish::after {
  content: "";
  position: absolute;
  inset: 0;
}
.fish::before {
  background: var(--bg);
  -webkit-mask: url("assets/fish-fill.svg") center / contain no-repeat;
          mask: url("assets/fish-fill.svg") center / contain no-repeat;
}
.fish::after {
  background: var(--deep);
  -webkit-mask: url("assets/fish.svg") center / contain no-repeat;
          mask: url("assets/fish.svg") center / contain no-repeat;
}

/* flowers (florist) — outline in the scene colour, grow up from the cell's bottom edge */
[data-critters="flower"] { left: var(--pad); right: var(--pad); }
.flower {
  position: absolute;
  bottom: 0;
  left: var(--x, 0);
  width: var(--s, 56px);
  height: var(--s, 56px);
  transform-origin: 50% 100%;
}
.flower::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--deep);
  -webkit-mask: url("assets/flower-1.svg") center bottom / contain no-repeat;
          mask: url("assets/flower-1.svg") center bottom / contain no-repeat;
}
.flower--b::after {
  -webkit-mask-image: url("assets/flower-2.svg");
          mask-image: url("assets/flower-2.svg");
}
/* falling leaves (florist) */
.leaf {
  position: absolute;
  left: 0;
  top: 0;
  width: 30px;
  height: 30px;
  will-change: transform, opacity;
}
.leaf::before,
.leaf::after {
  content: "";
  position: absolute;
  inset: 0;
}
.leaf::before {
  background: var(--bg);
  -webkit-mask: url("assets/leaf-fill.svg") center / contain no-repeat;
          mask: url("assets/leaf-fill.svg") center / contain no-repeat;
}
.leaf::after {
  background: var(--deep);
  -webkit-mask: url("assets/leaf.svg") center / contain no-repeat;
          mask: url("assets/leaf.svg") center / contain no-repeat;
}

[data-anim="grow"] {
  transform: rotate(var(--r, 0deg)) scale(calc(var(--in) * (1 - var(--out))));
}

/* second fish design */
.fish--b::before {
  -webkit-mask-image: url("assets/fish-2-fill.svg");
          mask-image: url("assets/fish-2-fill.svg");
}
.fish--b::after {
  -webkit-mask-image: url("assets/fish-2.svg");
          mask-image: url("assets/fish-2.svg");
}

.chicken {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 46px;
  height: 46px;
  will-change: transform;
}
.chicken .hen {
  position: relative;
  width: 100%;
  height: 100%;
  transform-origin: 50% 90%;
}
/* solid body in the background colour, so overlapping chickens don't show through */
.chicken .hen::before,
.chicken .hen::after {
  content: "";
  position: absolute;
  inset: 0;
}
.chicken .hen::before {
  background: var(--bg);
  -webkit-mask: url("assets/chicken-fill.svg") center / contain no-repeat;
          mask: url("assets/chicken-fill.svg") center / contain no-repeat;
}
.chicken .hen::after {
  background: var(--deep);
  -webkit-mask: url("assets/chicken.svg") center / contain no-repeat;
          mask: url("assets/chicken.svg") center / contain no-repeat;
}

/* ---------- Per-scene layouts (desktop) ----------
   5 x 4 grid; counter + pause sit in r4 c5 throughout.
   Each item lands in different cells in every scene:

   Layout 1                Layout 2                Layout 3
   . . . . .               . . . . .               . . . . .
   H H V Q Q               . V H H .               H H . V .
   A . V N N               . V . Q Q               . Q Q V .
   . . . . P               A . . N N/P             . N N/A . P
*/
@media (min-width: 961px) {
  [data-layout="2"] > .tst__intro { grid-area: 2 / 3 / 3 / 5; }
  [data-layout="2"] > .tst__media { grid-area: 2 / 2 / 4 / 3; }
  [data-layout="2"] > .tst__quote { grid-area: 3 / 4 / 4 / 5; }
  [data-layout="2"] > .tst__cite  { grid-area: 4 / 4 / 5 / 6; justify-content: flex-start; }
  [data-layout="2"] > .coop       { grid-area: 4 / 1; }

  [data-layout="3"] > .tst__intro { grid-area: 2 / 1 / 3 / 3; }
  [data-layout="3"] > .tst__media { grid-area: 2 / 4 / 4 / 5; }
  [data-layout="3"] > .tst__quote { grid-area: 3 / 2 / 4 / 3; }
  [data-layout="3"] > .tst__cite  { grid-area: 4 / 2 / 5 / 4; justify-content: flex-start; }
  [data-layout="3"] > .coop       { grid-area: 4 / 3; }
}

/* ---------- Scroll-driven animation ----------
   script.js sets --in (0→1 entering) and --out (0→1 leaving) on each [data-anim] */
[data-anim] { --in: 0; --out: 0; }

/* text lines rise up through a mask, then carry on up and out */
[data-anim="line"] {
  display: block;
  transform: translateY(calc((1 - var(--in)) * 110% - var(--out) * 110%));
}

/* video unrolls top → bottom, then rolls away top → bottom */
[data-anim="wipe"] {
  clip-path: inset(calc(var(--out) * 100%) 0 calc((1 - var(--in)) * 100%) 0);
}
[data-anim="wipe"] video,
[data-anim="wipe"] img,
[data-anim="wipe"] .illus {
  transform: scale(calc(1.2 - var(--in) * .2 + var(--out) * .1));
}

[data-anim="fade"] {
  opacity: calc(var(--in) - var(--out));
  transform: translateY(calc((1 - var(--in)) * 24px - var(--out) * 24px));
}

/* sign drops in from above, leaves upwards */
[data-anim="sign"] {
  opacity: calc(var(--in) - var(--out));
  transform: translateY(calc((1 - var(--in)) * -32px - var(--out) * 32px));
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  :root { --pad: 20px; }
  .tst__lines { display: none; }
  .tst__cover > span::after,
  .tst__cover > span:last-child::after { background: rgba(24, 35, 66, .62); }
  .tst__grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto minmax(0, 1fr) auto auto;
    row-gap: 16px;
    padding-bottom: var(--pad);
  }
  .tst__intro { grid-area: 2 / 1 / 3 / 3; }
  .hero__heading { grid-area: 1 / 1 / -1 / -1; font-size: 40px; }
  .hero__face { display: none; }
  .tst__heading { font-size: 34px; }
  .tst__media {
    grid-area: 3 / 1 / 4 / 3;
    justify-self: center;
    height: calc(100% - 20px);
    aspect-ratio: 9 / 16;
    margin-top: 20px;
  }
  .tst__sign { display: none; }
  .tst__quote { grid-area: 4 / 1 / 5 / 3; padding-top: 0; }
  .quote-mark { display: none; }
  .tst__quote blockquote { font-size: 18px; max-width: none; }
  .tst__cite { grid-area: 5 / 1 / 6 / 3; padding-top: 0; padding-bottom: 0; }
  .coop { display: none; }
}
