/* ==========================================================================
   Service visuals: six hand-built, animated illustrations.

   Every illustration lives in .viz__art, whose font-size is tied to the stage
   width (container query units), so all inner measurements are in em and the
   whole drawing scales as one piece.

   Motion only runs while a figure carries .is-live (set by sections.js when it
   is the active rail panel or scrolled into view). The base styles are the
   finished drawing, so nothing is lost without JavaScript.
   ========================================================================== */

.viz {
  margin: 0;
}

.viz__stage {
  position: relative;
  aspect-ratio: 4 / 3;
  container-type: inline-size;
  background-color: var(--white);
  background-image: radial-gradient(rgba(16, 28, 53, 0.13) 1px, transparent 1.2px);
  background-size: 4.166% 5.555%;
  border: 1px solid var(--rule);
  color: var(--navy);
  overflow: hidden;
}

.viz__art {
  position: absolute;
  inset: 0;
  font-size: 2.6cqw;
  line-height: 1.2;
}

@supports not (container-type: inline-size) {
  .viz__art {
    font-size: clamp(8px, 1.2vw, 15px);
  }
}

.viz__caption {
  display: flex;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: var(--fg-3);
}

.viz__caption span {
  color: var(--fg-2);
}

/* Pause every loop until the figure is live */
.js .viz:not(.is-live) *,
.js .viz:not(.is-live) *::before,
.js .viz:not(.is-live) *::after {
  animation-play-state: paused !important;
}

/* ---------- Chain: the step-by-step line under each visual ---------- */

.chain {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0;
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg);
}

.chain li {
  display: flex;
  align-items: center;
  transition: color 0.4s ease calc(var(--i, 0) * 0.16s + 0.2s);
}

.chain li + li::before {
  content: '';
  width: clamp(0.9rem, 2vw, 1.75rem);
  height: 1px;
  margin-inline: 0.6rem;
  background: var(--accent);
  transform-origin: left center;
  transition: transform 0.5s var(--ease-out) calc(var(--i, 0) * 0.16s + 0.1s);
}

.chain li:nth-child(1) { --i: 0; }
.chain li:nth-child(2) { --i: 1; }
.chain li:nth-child(3) { --i: 2; }
.chain li:nth-child(4) { --i: 3; }
.chain li:nth-child(5) { --i: 4; }
.chain li:nth-child(6) { --i: 5; }

.chain li:last-child {
  color: var(--accent);
}

.js:not(.no-motion) [data-chain]:not(.is-live) li {
  color: var(--fg-3);
}

.js:not(.no-motion) [data-chain]:not(.is-live) li::before {
  transform: scaleX(0);
}

/* ==========================================================================
   1. SEO — search bar, results, visibility line
   ========================================================================== */

.serp {
  position: absolute;
  left: 7%;
  top: 10%;
  width: 62%;
}

.serp__bar {
  display: flex;
  align-items: center;
  gap: 0.8em;
  height: 3.4em;
  padding-inline: 1.1em;
  background: var(--white);
  border: 1px solid var(--navy);
  box-shadow: 0.45em 0.45em 0 rgba(22, 115, 230, 0.16);
  font-weight: 500;
}

.serp__bar .icon {
  width: 1.4em;
  height: 1.4em;
  color: var(--blue);
}

.serp__query {
  display: inline-block;
  max-width: 32ch;
  overflow: hidden;
  white-space: nowrap;
}

.serp__caret {
  width: 1px;
  height: 1.3em;
  margin-left: -0.55em;
  background: var(--navy);
  animation: blink 1s steps(1) infinite;
}

.viz.is-live .serp__query {
  animation: type 1.5s steps(30, end) 0.2s both;
}

@keyframes type {
  from { max-width: 0; }
  to { max-width: 32ch; }
}

@keyframes blink {
  50% { opacity: 0; }
}

.serp__results {
  margin-top: 1.5em;
  background: var(--white);
  border: 1px solid var(--rule);
}

.serp__row {
  position: relative;
  padding: 0.95em 1.1em;
  border-bottom: 1px solid var(--rule);
  transition: opacity 0.5s ease calc(var(--i) * 0.12s + 1.5s), transform 0.7s var(--ease-out) calc(var(--i) * 0.12s + 1.5s);
}

.serp__row:last-child {
  border-bottom: 0;
}

.serp__row i {
  display: block;
  width: var(--w);
  height: 0.5em;
  margin-top: 0.55em;
  background: rgba(16, 28, 53, 0.1);
}

.serp__row i:first-child {
  height: 0.7em;
  margin-top: 0;
  background: rgba(16, 28, 53, 0.24);
}

.serp__row--brand {
  background: rgba(22, 115, 230, 0.06);
  box-shadow: inset 0.3em 0 0 var(--blue);
}

.serp__row--brand b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.05em;
  font-weight: 600;
  color: var(--blue);
}

.serp__ping {
  position: absolute;
  right: 1.2em;
  top: 50%;
  width: 0.7em;
  height: 0.7em;
  margin-top: -0.35em;
  border-radius: 50%;
  background: var(--blue);
}

.serp__ping::before,
.serp__ping::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--blue);
  animation: ping 2.4s ease-out infinite;
}

.serp__ping::after {
  animation-delay: 1.2s;
}

@keyframes ping {
  from { transform: scale(1); opacity: 0.8; }
  to { transform: scale(4.2); opacity: 0; }
}

.js .viz:not(.is-live) .serp__row {
  opacity: 0;
  transform: translateX(-1em);
  transition-delay: 0s;
}

.seo-signal {
  position: absolute;
  right: 6%;
  bottom: 9%;
  width: 43%;
  padding: 1em 1.1em 0.9em;
  background: var(--navy);
  color: var(--paper);
}

.seo-signal__title {
  display: block;
  margin-bottom: 0.7em;
  font-size: 0.78em;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--d-ink-2);
}

.seo-signal svg {
  width: 100%;
  height: 7.4em;
  overflow: visible;
}

.seo-signal__grid {
  stroke: rgba(245, 247, 251, 0.14);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.seo-signal__line {
  fill: none;
  stroke: var(--sky);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.8s var(--ease-in-out) 1.9s;
}

.seo-signal__area {
  transition: opacity 1s ease 3s;
}

.seo-signal__dot {
  position: absolute;
  right: calc(1.1em + 2% - 0.35em);
  top: calc(1em + 0.78em * 1.2 + 0.7em + 7.4em * 0.145 - 0.35em);
  width: 0.7em;
  height: 0.7em;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 0 0.3em rgba(242, 176, 30, 0.22);
  transition: transform 0.5s var(--ease-out) 3.5s;
}

.js .viz:not(.is-live) .seo-signal__line {
  stroke-dashoffset: 1;
  transition: none;
}

.js .viz:not(.is-live) .seo-signal__area {
  opacity: 0;
  transition: none;
}

.js .viz:not(.is-live) .seo-signal__dot {
  transform: scale(0);
  transition: none;
}

/* ==========================================================================
   2. Social — content wall, audience network, engagement signals
   ========================================================================== */

.wall {
  position: absolute;
  left: 4%;
  top: -18%;
  width: 60%;
  height: 136%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1em;
  transform: rotate(-5deg);
}

.wall__col {
  display: flex;
  flex-direction: column;
  gap: 1em;
  animation: wall-up 26s linear infinite;
}

.wall__col--down {
  animation-name: wall-down;
}

.wall__col--slow {
  animation-duration: 38s;
}

/* each column holds its tile set twice, so -50% is a seamless loop */
@keyframes wall-up {
  from { transform: translateY(0); }
  to { transform: translateY(calc(-50% - 0.5em)); }
}

@keyframes wall-down {
  from { transform: translateY(calc(-50% - 0.5em)); }
  to { transform: translateY(0); }
}

.tile {
  position: relative;
  flex: none;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

.tile--reel { aspect-ratio: 9 / 15; }
.tile--square { aspect-ratio: 1; }
.tile--photo { aspect-ratio: 4 / 3.4; }

.tile--navy { background: var(--navy); color: var(--paper); }
.tile--blue { background: var(--blue); color: var(--white); }
.tile--sky { background: var(--sky); color: var(--navy); }
.tile--amber { background: var(--amber); color: var(--navy); }
.tile--paper { background: var(--paper); color: var(--navy); box-shadow: inset 0 0 0 1px var(--rule-strong); }

/* post: a headline and two lines of caption */
.tile--post::before {
  content: '';
  position: absolute;
  left: 12%;
  top: 14%;
  width: 46%;
  height: 22%;
  border: 1px solid currentColor;
  opacity: 0.7;
}

.tile--post::after {
  content: '';
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: 12%;
  height: 1.5em;
  opacity: 0.6;
  background:
    linear-gradient(currentColor, currentColor) 0 0 / 78% 0.32em no-repeat,
    linear-gradient(currentColor, currentColor) 0 100% / 48% 0.32em no-repeat;
}

/* reel: a play mark and a progress line */
.tile--reel::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1.9em;
  height: 1.9em;
  margin: -0.95em 0 0 -0.75em;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.tile--reel::after {
  content: '';
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: 8%;
  height: 2px;
  background: linear-gradient(90deg, currentColor 38%, transparent 38%) , currentColor;
  background-blend-mode: normal;
  opacity: 0.55;
}

/* photo: sun and horizon */
.tile--photo::before {
  content: '';
  position: absolute;
  right: 18%;
  top: 18%;
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
  border: 1px solid currentColor;
}

.tile--photo::after {
  content: '';
  position: absolute;
  inset: 46% 0 0 0;
  background: currentColor;
  opacity: 0.16;
  clip-path: polygon(0 100%, 0 62%, 26% 22%, 48% 58%, 68% 8%, 100% 52%, 100% 100%);
}

/* square: a single mark */
.tile--square::before {
  content: '';
  position: absolute;
  inset: 30%;
  border: 1px solid currentColor;
  border-radius: 50%;
}

.audience {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 37%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.4em;
  padding: 1.6em 1.8em;
  background: var(--white);
  border-left: 1px solid var(--rule);
}

.audience__title {
  font-size: 0.78em;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.audience svg {
  width: 100%;
  overflow: visible;
}

.audience__links {
  fill: none;
  stroke: var(--rule-strong);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}

.audience__node {
  fill: var(--white);
  stroke: var(--navy);
  stroke-width: 1.2;
  transform-box: fill-box;
  transform-origin: center;
  animation: node-pop 3.6s ease-in-out calc(var(--i) * 0.6s) infinite;
}

.audience__core {
  fill: var(--blue);
}

@keyframes node-pop {
  0%, 70%, 100% { transform: scale(1); fill: var(--white); }
  12% { transform: scale(1.35); fill: var(--sky); }
}

.signals {
  display: grid;
  gap: 0.7em;
}

.signals li {
  display: flex;
  align-items: center;
  gap: 0.8em;
}

.signals .icon {
  width: 1.5em;
  height: 1.5em;
  color: var(--blue);
}

.signals span {
  position: relative;
  flex: 1;
  height: 0.35em;
  background: var(--rule);
}

.signals span::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--navy);
  transform-origin: left center;
  animation: meter 4.2s var(--ease-in-out) calc(var(--i) * 0.7s) infinite alternate;
}

@keyframes meter {
  from { transform: scaleX(0.22); }
  to { transform: scaleX(0.9); }
}

/* ==========================================================================
   3. Performance marketing — funnel of campaign paths
   ========================================================================== */

.funnel {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.funnel__gate {
  stroke: var(--rule-strong);
  stroke-width: 1;
  stroke-dasharray: 2 4;
  fill: none;
}

.funnel__stage {
  font-family: var(--font-body);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--ink-3);
}

.funnel__base {
  fill: none;
  stroke: rgba(16, 28, 53, 0.2);
  stroke-width: 1;
}

.funnel__flow {
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 3 21;
  animation: flow 1.5s linear infinite;
}

.funnel__flow--dropped {
  stroke: var(--sky);
}

.funnel__flow--converted {
  stroke: var(--blue);
  stroke-width: 2.2;
  stroke-dasharray: 5 19;
}

@keyframes flow {
  to { stroke-dashoffset: -24; }
}

.funnel__ends circle {
  fill: var(--white);
  stroke: rgba(16, 28, 53, 0.45);
  stroke-width: 1;
}

.funnel__source rect {
  fill: var(--navy);
}

.funnel__source text {
  font-family: var(--font-display);
  font-size: 9.5px;
  font-weight: 600;
  fill: var(--paper);
}

.funnel__target circle {
  fill: none;
  stroke: var(--navy);
  stroke-width: 1.2;
}

.funnel__target .funnel__bull {
  fill: var(--amber);
  stroke: none;
}

.funnel__target .funnel__pulse {
  stroke: var(--blue);
  transform-box: fill-box;
  transform-origin: center;
  animation: pulse 2.2s ease-out infinite;
}

@keyframes pulse {
  from { transform: scale(1); opacity: 0.9; }
  to { transform: scale(2); opacity: 0; }
}

.ads-test {
  position: absolute;
  left: 50%;
  bottom: 6%;
  display: flex;
  align-items: center;
  gap: 0.5em;
  transform: translateX(-50%);
  white-space: nowrap;
}

.ads-test__label {
  margin-right: 0.5em;
  font-size: 0.78em;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.ads-test__option {
  display: grid;
  place-items: center;
  width: 2.4em;
  height: 2.4em;
  border: 1px solid var(--navy);
  font-family: var(--font-display);
  font-size: 0.9em;
  font-weight: 600;
  animation: ab 4s steps(1) infinite;
}

.ads-test__option--b {
  animation-delay: -2s;
}

@keyframes ab {
  0% { background: var(--navy); color: var(--paper); }
  50% { background: transparent; color: var(--navy); }
}

/* ==========================================================================
   4. Branding — identity artboard
   ========================================================================== */

.artboard {
  position: absolute;
  inset: 8% 7%;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  grid-template-rows: 1fr auto auto;
  gap: 1.1em;
}

.artboard__mark,
.artboard__type {
  position: relative;
  background: var(--white);
  border: 1px solid var(--rule-strong);
}

.artboard__mark {
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
}

.artboard__mark svg {
  width: 82%;
  height: 82%;
}

.artboard__guides {
  fill: none;
  stroke: rgba(22, 115, 230, 0.4);
  stroke-width: 0.6;
  stroke-dasharray: 2 3;
}

.artboard__shape {
  fill: none;
  stroke: var(--navy);
  stroke-width: 2.4;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.4s var(--ease-in-out) 0.3s;
}

.artboard__shape + .artboard__shape {
  transition-delay: 0.9s;
}

.artboard__overlap {
  fill: var(--blue);
  transition: opacity 0.6s ease 2.1s;
}

.artboard__tag {
  position: absolute;
  left: 0.9em;
  top: 0.8em;
  font-size: 0.72em;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.artboard__type {
  display: grid;
  place-items: end start;
  padding: 0 1.2em 0.9em;
  /* baseline and x-height guides */
  background-image:
    linear-gradient(rgba(86, 197, 245, 0.9), rgba(86, 197, 245, 0.9)),
    linear-gradient(rgba(86, 197, 245, 0.5), rgba(86, 197, 245, 0.5));
  background-size: 100% 1px, 100% 1px;
  background-position: 0 calc(100% - 2.55em), 0 calc(100% - 5.4em);
  background-repeat: no-repeat;
  background-color: var(--white);
  overflow: hidden;
}

.artboard__specimen {
  font-family: var(--font-display);
  font-size: 7.2em;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.05em;
  transition: transform 0.9s var(--ease-out) 1.2s;
}

.artboard__palette {
  display: flex;
  height: 3.4em;
  border: 1px solid var(--rule-strong);
}

.artboard__palette span {
  flex: var(--f);
  background: var(--c);
  transform-origin: left center;
  transition: transform 0.6s var(--ease-out) calc(var(--i) * 0.1s + 1.7s);
}

.artboard__apps {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1.5fr 2.4fr;
  gap: 1.1em;
  height: 6.4em;
}

.app {
  position: relative;
  transition: opacity 0.5s ease calc(var(--i) * 0.14s + 2.3s), transform 0.7s var(--ease-out) calc(var(--i) * 0.14s + 2.3s);
}

.app--social {
  background: var(--navy);
}

.app--social::after {
  content: '';
  position: absolute;
  inset: 28%;
  border: 1.5px solid var(--sky);
  border-radius: 50%;
}

.app--brochure {
  background: linear-gradient(90deg, var(--paper) 50%, var(--white) 50%);
  border: 1px solid var(--rule-strong);
}

.app--brochure::after {
  content: '';
  position: absolute;
  inset: 22% 58% 22% 10%;
  background: var(--blue);
}

.app--banner {
  background: var(--blue);
}

.app--banner::after {
  content: '';
  position: absolute;
  left: 8%;
  top: 30%;
  width: 60%;
  height: 40%;
  background:
    linear-gradient(var(--white), var(--white)) 0 0 / 100% 0.5em no-repeat,
    linear-gradient(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.6)) 0 100% / 62% 0.4em no-repeat;
}

.js .viz:not(.is-live) .artboard__shape {
  stroke-dashoffset: 1;
  transition: none;
}

.js .viz:not(.is-live) .artboard__overlap {
  opacity: 0;
  transition: none;
}

.js .viz:not(.is-live) .artboard__specimen {
  transform: translateY(110%);
  transition: none;
}

.js .viz:not(.is-live) .artboard__palette span {
  transform: scaleX(0);
  transition: none;
}

.js .viz:not(.is-live) .app {
  opacity: 0;
  transform: translateY(0.8em);
  transition: none;
}

/* ==========================================================================
   5. Website development — wireframe becoming interface
   ========================================================================== */

.browser {
  position: absolute;
  left: 6%;
  top: 9%;
  width: 76%;
  background: var(--white);
  border: 1px solid var(--navy);
  box-shadow: 0.5em 0.5em 0 rgba(22, 115, 230, 0.14);
}

.browser__bar {
  display: flex;
  align-items: center;
  gap: 0.45em;
  height: 2.3em;
  padding-inline: 0.9em;
  border-bottom: 1px solid var(--navy);
}

.browser__bar i {
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  border: 1px solid var(--navy);
}

.browser__url {
  flex: 1;
  height: 0.9em;
  margin-left: 0.8em;
  background: var(--paper);
  border: 1px solid var(--rule);
}

.browser__body {
  display: grid;
  gap: 1em;
  padding: 1.1em;
}

.browser__nav {
  display: flex;
  align-items: center;
  gap: 0.9em;
}

.browser__row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.9em;
}

/* .wf = a block that starts as a dashed wireframe outline, then fills in */
.wf {
  display: block;
  transition: background-color 0.7s ease calc(var(--i) * 0.28s + 0.5s), outline-color 0.5s ease calc(var(--i) * 0.28s + 0.5s);
  outline: 1px dashed transparent;
  outline-offset: -1px;
}

.wf--logo {
  width: 1.5em;
  height: 1.5em;
  margin-right: auto;
  background: var(--navy);
}

.wf--navline {
  width: 2.6em;
  height: 0.4em;
  background: rgba(16, 28, 53, 0.3);
}

.wf--hero {
  display: grid;
  align-content: center;
  gap: 0.6em;
  height: 9.5em;
  padding-inline: 1.4em;
  background: var(--blue);
}

.wf__bar {
  width: var(--w);
  height: 0.9em;
  background: var(--white);
  transition: opacity 0.5s ease 1.3s;
}

.wf__bar + .wf__bar {
  height: 0.5em;
  opacity: 0.65;
}

.wf__button {
  width: 5.2em;
  height: 1.7em;
  margin-top: 0.4em;
  background: var(--navy);
  animation: press 5s ease-in-out infinite;
}

@keyframes press {
  0%, 52%, 64%, 100% { transform: scale(1); }
  58% { transform: scale(0.9); }
}

.wf--block {
  height: 4.6em;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--rule);
}

.phone {
  position: absolute;
  right: 6%;
  bottom: 7%;
  width: 23%;
  aspect-ratio: 9 / 17.5;
  display: grid;
  align-content: start;
  gap: 0.6em;
  padding: 1.7em 0.75em 0.9em;
  background: var(--white);
  border: 1px solid var(--navy);
  border-radius: 1.5em;
  box-shadow: 0.45em 0.45em 0 rgba(86, 197, 245, 0.4);
}

.phone__notch {
  position: absolute;
  top: 0.65em;
  left: 50%;
  width: 26%;
  height: 0.3em;
  margin-left: -13%;
  border-radius: 1em;
  background: var(--navy);
}

.wf--phone-hero {
  height: 7em;
  background: var(--blue);
}

.wf--phone-line {
  height: 0.5em;
  background: rgba(16, 28, 53, 0.3);
}

.wf--short {
  width: 60%;
}

.wf--phone-block {
  height: 4.2em;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--rule);
}

.web-cursor {
  position: absolute;
  left: 15%;
  top: 47%;
  width: 1.9em;
  height: 1.9em;
  fill: var(--navy);
  stroke: var(--white);
  stroke-width: 1.2;
  animation: cursor-path 5s var(--ease-in-out) infinite;
}

@keyframes cursor-path {
  0%, 100% { transform: translate(18em, 9em); }
  50%, 66% { transform: translate(0, 0); }
}

.js .viz:not(.is-live) .wf {
  background-color: transparent;
  outline-color: rgba(16, 28, 53, 0.42);
  box-shadow: none;
  transition: none;
}

.js .viz:not(.is-live) .wf__bar,
.js .viz:not(.is-live) .wf__button {
  opacity: 0;
}

/* ==========================================================================
   6. Content, video and consulting — storyboard and edit timeline
   ========================================================================== */

.storyboard {
  position: absolute;
  left: 6%;
  right: 6%;
  top: 9%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1em;
}

.frame {
  position: relative;
  aspect-ratio: 16 / 11;
  background: var(--white);
  border: 1px solid var(--navy);
  animation: frame-on 8s steps(1) calc(var(--i) * 2s) infinite;
}

.frame span {
  position: absolute;
  left: 0.5em;
  top: 0.35em;
  font-size: 0.72em;
  font-weight: 600;
  color: var(--ink-3);
}

@keyframes frame-on {
  0% { background: var(--navy); color: var(--paper); }
  25%, 100% { background: var(--white); color: var(--navy); }
}

.frame::before,
.frame::after {
  content: '';
  position: absolute;
}

/* 1 idea: a spark */
.frame--idea::before {
  left: 50%;
  top: 50%;
  width: 2em;
  height: 2em;
  margin: -1em 0 0 -1em;
  background: currentColor;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
}

/* 2 story: lines of script */
.frame--story::before {
  inset: 36% 18% 24% 18%;
  background:
    linear-gradient(currentColor, currentColor) 0 0 / 100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) 0 50% / 72% 2px no-repeat,
    linear-gradient(currentColor, currentColor) 0 100% / 88% 2px no-repeat;
}

/* 3 scene: horizon */
.frame--scene::before {
  inset: 40% 0 0 0;
  background: currentColor;
  opacity: 0.85;
  clip-path: polygon(0 100%, 0 70%, 30% 18%, 52% 60%, 72% 0, 100% 56%, 100% 100%);
}

/* 4 motion: play */
.frame--motion::before {
  left: 50%;
  top: 50%;
  width: 1.7em;
  height: 1.9em;
  margin: -0.95em 0 0 -0.6em;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.timeline {
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: 8%;
  display: grid;
  gap: 0.7em;
  padding: 2em 1em 1em 2.6em;
  background: var(--white);
  border: 1px solid var(--rule-strong);
}

.timeline__ruler {
  position: absolute;
  left: 2.6em;
  right: 1em;
  top: 0.7em;
  height: 0.6em;
  background-image: repeating-linear-gradient(90deg, var(--rule-strong) 0 1px, transparent 1px 5%);
}

.timeline__track {
  position: relative;
  display: flex;
  gap: 0.4em;
  height: 2.5em;
}

.timeline__track b {
  position: absolute;
  left: -1.9em;
  top: 50%;
  translate: 0 -50%;
  font-size: 0.72em;
  font-weight: 600;
  color: var(--ink-3);
}

.timeline__track--video span {
  width: var(--w);
  background: var(--c);
}

.timeline__track--audio {
  height: 2.2em;
}

.timeline__track--audio svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: rgba(16, 28, 53, 0.55);
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
}

.timeline__track--audio path {
  vector-effect: non-scaling-stroke;
}

.timeline__track--text {
  height: 1.3em;
  gap: 1.3em;
}

.timeline__track--text span {
  width: var(--w);
  border: 1px solid var(--rule-strong);
  background: var(--paper);
}

.timeline__playhead {
  position: absolute;
  left: 2.6em;
  top: 0.4em;
  bottom: 0.6em;
  width: 2px;
  background: var(--amber);
  animation: playhead 8s linear infinite;
}

.timeline__playhead::before {
  content: '';
  position: absolute;
  left: -0.3em;
  top: 0;
  width: calc(0.6em + 2px);
  height: 0.6em;
  background: var(--amber);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

@keyframes playhead {
  from { transform: translateX(0); }
  to { transform: translateX(calc(88cqw - 3.6em - 2px)); }
}
