@font-face {
  font-family: "Lexend";
  font-weight: 400;
  font-style: normal;
  font-display: block;
  src: url("fonts/lexend-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Lexend";
  font-weight: 500;
  font-style: normal;
  font-display: block;
  src: url("fonts/lexend-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Lexend";
  font-weight: 600;
  font-style: normal;
  font-display: block;
  src: url("fonts/lexend-latin-600-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Lexend";
  font-weight: 700;
  font-style: normal;
  font-display: block;
  src: url("fonts/lexend-latin-700-normal.woff2") format("woff2");
}

:root {
  color-scheme: light;

  --green: #56bb6e;
  --green-hover: #399e54;
  --green-deep: #15803d;
  --green-tint: #e7f6eb;
  --bg: #f9fafb;
  --card: #ffffff;
  --shape: #f3f4f6;
  --line: #c9ced6;
  --text: #111827;
  --text-2: rgba(17, 24, 39, 0.68);
  --hairline: #e5e7eb;
  --bezel: #d5d9e0;
  --lid-base: #e3e6eb;
  --dot: #d1d5db;
  --accent-text: #15803d;
  --flow-c: #15803d;
  --wash-a: rgba(86, 187, 110, 0.2);
  --wash-b: rgba(86, 187, 110, 0.13);

  --pad-x: clamp(20px, 5vw, 96px);
  --pad-y: clamp(16px, 3.2vh, 40px);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dir: 1;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: "Lexend", sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

button:focus-visible {
  outline: 2px solid var(--green-deep);
  outline-offset: 4px;
}

/* ---------- Frame ---------- */

/* Two decks stacked in one window. The rail moves up to show the second. */
.viewport {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: #111827;
}
.rail {
  height: 100%;
  transition: transform 1.1s cubic-bezier(0.76, 0, 0.24, 1);
}
.rail.at-future {
  transform: translateY(-100%);
}

.deck.dark {
  color-scheme: dark;
  --bg: #111827;
  --card: #1f2937;
  --shape: #111827;
  --line: #4b5563;
  --text: #f3f4f6;
  --text-2: rgba(243, 244, 246, 0.72);
  --hairline: #374151;
  --green-tint: rgba(86, 187, 110, 0.16);
  --bezel: #374151;
  --lid-base: #2b3646;
  --dot: #4b5563;
  --accent-text: #86dc9b;
  --flow-c: #d6f5dd;
  --wash-a: rgba(86, 187, 110, 0.12);
  --wash-b: rgba(86, 187, 110, 0.08);
}

.deck {
  position: relative;
  height: 100%;
  color: var(--text);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  padding: var(--pad-y) var(--pad-x);
  padding-bottom: max(var(--pad-y), env(safe-area-inset-bottom));
  background: var(--bg);
  overflow: hidden;
  isolation: isolate;
}

/* Two soft green washes that drift slowly behind everything. */
.deck::before,
.deck::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
}
.deck::before {
  width: 52vmax;
  height: 52vmax;
  right: -14vmax;
  top: -12vmax;
  background: var(--wash-a);
  animation: drift-a 22s ease-in-out infinite alternate;
}
.deck::after {
  width: 40vmax;
  height: 40vmax;
  left: -14vmax;
  bottom: -18vmax;
  background: var(--wash-b);
  animation: drift-b 28s ease-in-out infinite alternate;
}
@keyframes drift-a {
  to {
    transform: translate(-12vmax, 10vmax) scale(1.15);
  }
}
@keyframes drift-b {
  to {
    transform: translate(14vmax, -8vmax) scale(1.2);
  }
}

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  --logo-h: clamp(26px, 3.4vh + 8px, 46px);
  display: flex;
  align-items: baseline;
  gap: 0px;
}

.wordmark {
  display: block;
  height: var(--logo-h);
  width: auto;
}

/* "One" set beside the wordmark, sized so its capitals match the logo lettering. */
.brand-one {
  font-size: calc(var(--logo-h) * 0.93);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--text);
}

.fs {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  color: var(--text-2);
  opacity: 0.6;
  transition: opacity 0.2s, background-color 0.2s;
}
.fs:hover {
  opacity: 1;
  background: var(--hairline);
}
.fs svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Slides ---------- */

.stage {
  position: relative;
  min-height: 0;
}

.slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  grid-template-rows: minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 5vw, 96px);
  padding: clamp(8px, 2vh, 32px) 0;
  visibility: hidden;
}

.slide.is-active {
  visibility: visible;
}

.slide.is-leaving {
  visibility: visible;
  pointer-events: none;
  animation: leave 0.32s var(--ease) both;
}
@keyframes leave {
  to {
    opacity: 0;
    transform: translateX(calc(var(--dir) * -48px)) scale(0.985);
  }
}

.copy h1 {
  margin: 0;
  font-size: clamp(28px, 3.6vw + 4px, 68px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.copy h1 .w {
  display: inline-block;
}
.slide.is-active .copy h1 .w {
  animation: word-in 0.75s var(--ease) both;
  animation-delay: calc(var(--i) * 75ms + 220ms);
}
@keyframes word-in {
  from {
    opacity: 0;
    transform: translateY(0.7em) rotate(4deg);
    filter: blur(8px);
  }
}

.copy p {
  margin: clamp(14px, 2.6vh, 32px) 0 0;
  max-width: 26em;
  font-size: clamp(17px, 1.35vw + 6px, 30px);
  font-weight: 400;
  line-height: 1.5;
  color: var(--text-2);
  text-wrap: pretty;
}
.slide.is-active .copy p {
  animation: rise 0.8s var(--ease) 0.7s both;
}
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
}

.benefits {
  list-style: none;
  margin: clamp(12px, 2.2vh, 28px) 0 0;
  padding: 0;
  display: grid;
  gap: clamp(6px, 1.1vh, 14px);
  font-size: clamp(16px, 1.15vw + 6px, 26px);
  font-weight: 500;
  line-height: 1.3;
}
.benefits li {
  display: flex;
  align-items: center;
  gap: 0.6em;
}
.benefits li::before {
  content: "";
  flex: none;
  width: 1.15em;
  height: 1.15em;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%23fff%27 stroke-width=%273.2%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M6.5 12.5l3.6 3.6 7.4-8.2%27/%3E%3C/svg%3E") center / 100% no-repeat,
    var(--green);
}
.slide.is-active .benefits li {
  animation: rise 0.7s var(--ease) both;
  animation-delay: calc(var(--i) * 160ms + 1.2s);
}
.slide.is-active .benefits li::before {
  animation: pop 0.6s var(--spring) both;
  animation-delay: calc(var(--i) * 160ms + 1.4s);
}

.diagram {
  display: block;
  width: 100%;
  max-height: 100%;
  aspect-ratio: 640 / 430;
  justify-self: end;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: clamp(16px, 2vw, 28px);
  box-shadow:
    0 1px 2px rgba(17, 24, 39, 0.04),
    0 30px 60px -28px rgba(17, 24, 39, 0.22);
  overflow: hidden;
  transition: border-color 0.25s, box-shadow 0.25s, translate 0.25s var(--ease);
}
.diagram:hover {
  border-color: var(--green);
  translate: 0 -3px;
  box-shadow:
    0 1px 2px rgba(17, 24, 39, 0.04),
    0 38px 70px -28px rgba(21, 128, 61, 0.35);
}
.diagram[tabindex="-1"] {
  cursor: default;
}
.diagram[tabindex="-1"]:hover {
  border-color: var(--hairline);
  translate: none;
}
.slide.is-active .diagram {
  animation: card-in 0.8s var(--ease) 0.18s both;
}
@keyframes card-in {
  from {
    opacity: 0;
    transform: translateX(calc(var(--dir) * 64px)) scale(0.94);
  }
}
.diagram svg {
  display: block;
  width: 100%;
  height: 100%;
  user-select: none;
  -webkit-user-select: none;
}

/* ---------- Diagram parts ---------- */

.shape {
  fill: var(--shape);
  stroke: var(--line);
  stroke-width: 2;
}

/* The clinic desk computer: a laptop made of a lid, its display and a base. */
.bezel {
  fill: var(--bezel);
  stroke: var(--line);
  stroke-width: 2;
}
.display {
  fill: var(--shape);
}
.base {
  fill: var(--lid-base);
  stroke: var(--line);
  stroke-width: 2;
}
.notch {
  fill: var(--line);
}

.link {
  fill: none;
  stroke: var(--green);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A short dash that runs along a green line once it is drawn. */
.flow {
  fill: none;
  stroke: var(--flow-c);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 0.07 0.93;
  opacity: 0;
}

.route {
  stroke: rgba(17, 24, 39, 0.4);
  stroke-width: 3;
  stroke-dasharray: 0.1 13;
  stroke-linecap: round;
}

.trail {
  stroke: var(--text);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 0.22;
}

.map {
  fill: var(--green-tint);
  stroke: var(--green);
  stroke-width: 2;
  stroke-linejoin: round;
}
.label.map-name {
  fill: rgba(21, 128, 61, 0.55);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-size: 14px;
}

.place {
  fill: var(--card);
  stroke: var(--text);
  stroke-width: 2.5;
}

.person {
  fill: var(--green);
}

.ripple {
  fill: none;
  stroke: var(--green);
  stroke-width: 2;
  opacity: 0;
}

.pill {
  fill: var(--card);
  stroke: var(--line);
  stroke-width: 1.5;
}

.label {
  fill: var(--text-2);
  font-size: 20px;
  font-weight: 500;
  text-anchor: middle;
}
.label.small {
  font-size: 17px;
}
.label.end {
  text-anchor: end;
}
.label.start {
  text-anchor: start;
}
.label.strong {
  fill: var(--text);
  font-size: 24px;
  font-weight: 600;
}

.code rect {
  fill: var(--text);
}

.ok {
  fill: var(--green);
}
.tick {
  fill: none;
  stroke: #fff;
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tick.thin {
  stroke-width: 2.4;
}

.card {
  fill: var(--card);
  stroke: var(--green);
  stroke-width: 2;
}
.card-text {
  fill: var(--text);
  font-size: 22px;
  font-weight: 600;
  text-anchor: middle;
}
.card-text.tight {
  font-size: 17px;
}
.card-text.mini {
  font-size: 14px;
}

.chip {
  fill: var(--green-tint);
}
.chip-text {
  fill: var(--accent-text);
  font-size: 17px;
  font-weight: 600;
  text-anchor: middle;
}
.chip-text.mini {
  font-size: 13px;
}

.packet {
  fill: var(--flow-c);
  opacity: 0;
}

/* ---------- Diagram motion ----------
   Everything below plays when its slide is shown, and replays on each visit.
   --t is the moment an element comes in. Nothing here changes slide. */

.pop,
.file,
.maria,
.ripple,
.float {
  transform-box: fill-box;
  transform-origin: center;
}

.slide.is-active .pop {
  animation: pop 0.6s var(--spring) var(--t, 0.5s) both;
}
.slide.is-active .pop.big {
  animation-name: pop-big;
  animation-duration: 0.8s;
}
@keyframes pop {
  from {
    opacity: 0;
    transform: scale(0.55);
  }
}
@keyframes pop-big {
  0% {
    opacity: 0;
    transform: scale(0.2) rotate(-25deg);
  }
  60% {
    opacity: 1;
    transform: scale(1.18) rotate(4deg);
  }
}

.slide.is-active .fade {
  animation: fade 0.6s var(--ease) var(--t, 0.6s) both;
}
@keyframes fade {
  from {
    opacity: 0;
    translate: 0 8px;
  }
}

.slide.is-active .link {
  animation: draw 0.75s var(--ease) var(--t, 1s) both;
}
@keyframes draw {
  from {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  to {
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
  }
}

.slide.is-active .flow {
  animation:
    flow-in 0.3s linear calc(var(--flow, var(--t, 1s) + 0.8s)) both,
    flow 1.5s linear calc(var(--flow, var(--t, 1s) + 0.8s)) infinite;
}
.slide.is-active .flow.rev {
  animation-direction: normal, reverse;
}
@keyframes flow-in {
  to {
    opacity: 1;
  }
}
@keyframes flow {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}

.slide.is-active .march {
  animation:
    fade 0.6s var(--ease) var(--t, 0.6s) both,
    march 1.2s linear infinite;
}
@keyframes march {
  to {
    stroke-dashoffset: -13.1;
  }
}

.slide.is-active .ripple {
  animation: ripple 2.4s ease-out 2.4s infinite;
}
.slide.is-active .ripple.late {
  animation-delay: 3.6s;
}
@keyframes ripple {
  from {
    opacity: 0.7;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(3.2);
  }
}

/* Slide 1: Maria starts in Windhoek, visits Rundu, and settles between them. */
.slide.is-active .maria {
  animation: maria 2.2s var(--ease) 0.9s both;
}
@keyframes maria {
  0% {
    opacity: 0;
    transform: translateX(-210px) scale(0.3);
  }
  18% {
    opacity: 1;
    transform: translateX(-210px) scale(1);
  }
  62% {
    transform: translateX(210px) scale(1);
  }
  100% {
    transform: translateX(0) scale(1);
  }
}

/* The file card arriving on a desk. */
.slide.is-active .file.from-phone {
  animation: from-phone 0.9s var(--ease) var(--t) both;
}
@keyframes from-phone {
  from {
    opacity: 0;
    transform: translate(-335px, 33px) scale(0.2);
  }
  30% {
    opacity: 1;
  }
}

.slide.is-active .file.via-box {
  animation: via-box 1.5s var(--ease) var(--t) both;
}
@keyframes via-box {
  0% {
    opacity: 0;
    transform: translate(-335px, 0) scale(0.25);
  }
  12% {
    opacity: 1;
  }
  48% {
    transform: translate(-205px, 170px) scale(0.25);
  }
  100% {
    transform: none;
  }
}

.slide.is-active .file.across {
  animation: across 1.8s var(--ease) var(--t) both;
}
@keyframes across {
  0% {
    opacity: 0;
    transform: translateX(-215px) scale(0.4);
  }
  15% {
    opacity: 1;
    transform: translateX(-215px) scale(0.7);
  }
  60% {
    transform: translateX(215px) scale(0.7);
  }
  100% {
    transform: none;
  }
}
.slide.is-active .float {
  animation: float 3.2s ease-in-out 3.9s infinite alternate;
}
@keyframes float {
  to {
    transform: translateY(-7px);
  }
}

/* Slide 4: the update leaves the desk and lands on the phone. */
.slide.is-active .packet {
  animation: packet 0.7s cubic-bezier(0.65, 0, 0.35, 1) var(--t) both;
}
@keyframes packet {
  0% {
    opacity: 0;
    transform: translateX(0);
  }
  15%,
  85% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateX(-165px);
  }
}
.slide.is-active .ripple {
  animation-delay: var(--ripple, 2.4s);
}

/* Slide 5: the map draws itself, then the phone makes the trip. */
.slide.is-active .map {
  animation: map-in 1.5s var(--ease) 0.45s both;
}
@keyframes map-in {
  0% {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    fill-opacity: 0;
  }
  70% {
    fill-opacity: 0;
  }
  100% {
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
    fill-opacity: 1;
  }
}

.slide.is-active .traveller {
  animation: travel 2.6s cubic-bezier(0.65, 0, 0.35, 1) 2.1s both;
}
@keyframes travel {
  0% {
    opacity: 0;
    transform: translate(0, 0);
  }
  8% {
    opacity: 1;
    transform: translate(0, 0);
  }
  100% {
    transform: translate(62.4px, -116.9px);
  }
}
.slide.is-active .trail {
  animation: trail 2.6s cubic-bezier(0.65, 0, 0.35, 1) 2.1s both;
}
@keyframes trail {
  0%,
  8% {
    stroke-dashoffset: 1;
  }
  100% {
    stroke-dashoffset: 0.22;
  }
}
.slide.is-active .ripple.arrive {
  animation-delay: 4.7s;
}

/* ---------- Second deck: boxes, cloud and radio links ---------- */

.cloud {
  fill: var(--shape);
  stroke: var(--line);
  stroke-width: 2;
  stroke-linejoin: round;
}

.led.on {
  fill: var(--green);
}
.led.off {
  fill: var(--line);
}

/* TV white space: a dashed green line, so it never reads as the internet. */
.radio {
  fill: none;
  stroke: var(--green);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 2 9;
}
.slide.is-active .radio {
  animation: radio 0.9s linear infinite;
}
.slide.is-active .radio.fade {
  animation:
    fade 0.6s var(--ease) var(--t, 0.6s) both,
    radio 0.9s linear infinite;
}
@keyframes radio {
  to {
    stroke-dashoffset: -11;
  }
}

.arc {
  fill: none;
  stroke: var(--green);
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.25;
}
.slide.is-active .arc {
  animation: arc 1.8s ease-in-out infinite;
  animation-delay: calc(var(--i) * 0.22s + 1.6s);
}
@keyframes arc {
  0%,
  100% {
    opacity: 0.15;
  }
  35% {
    opacity: 1;
  }
}

.node.on {
  fill: var(--green);
  stroke: var(--card);
  stroke-width: 2;
}
.node.off {
  fill: var(--card);
  stroke: var(--text);
  stroke-width: 2;
}

.label.tiny {
  font-size: 15px;
}
.label.accent {
  fill: var(--accent-text);
}
.label.note {
  font-size: 13px;
  font-weight: 400;
}
.chip-text.small {
  font-size: 15px;
}

.row {
  fill: var(--shape);
  stroke: var(--line);
  stroke-width: 1.5;
}
.num {
  fill: #fff;
  font-size: 22px;
  font-weight: 700;
  text-anchor: middle;
}
.row-text {
  fill: var(--text);
  font-size: 23px;
  font-weight: 600;
}

.dim {
  opacity: 0.5;
}
.slide.is-active .pop.dim {
  animation-name: pop-dim;
}
@keyframes pop-dim {
  from {
    opacity: 0;
    transform: scale(0.55);
  }
  to {
    opacity: 0.5;
  }
}

/* A packet that keeps making the trip: box to box, then box to cloud. */
.relay {
  fill: var(--flow-c);
  opacity: 0;
}
.slide.is-active .relay.out {
  animation: relay-out 4.6s cubic-bezier(0.45, 0, 0.55, 1) 2.2s infinite backwards;
}
.slide.is-active .relay.home {
  animation: relay-home 4.6s cubic-bezier(0.45, 0, 0.55, 1) 2.2s infinite backwards;
}
@keyframes relay-out {
  0% {
    opacity: 0;
    transform: translateX(0);
  }
  6% {
    opacity: 1;
  }
  34%,
  44% {
    transform: translateX(172px);
  }
  76% {
    opacity: 1;
    transform: translateX(330px);
  }
  80%,
  100% {
    opacity: 0;
    transform: translateX(330px);
  }
}
@keyframes relay-home {
  0% {
    opacity: 0;
    transform: translateX(0);
  }
  6% {
    opacity: 1;
  }
  34%,
  44% {
    transform: translateX(-158px);
  }
  76% {
    opacity: 1;
    transform: translateX(-330px);
  }
  80%,
  100% {
    opacity: 0;
    transform: translateX(-330px);
  }
}

/* Appears each time the packet arrives, then clears for the next trip. */
.sync-end {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
}
.slide.is-active .sync-end {
  animation: sync-end 4.6s var(--ease) 2.2s infinite backwards;
}
@keyframes sync-end {
  0%,
  74% {
    opacity: 0;
    transform: scale(0.5);
  }
  80% {
    opacity: 1;
    transform: scale(1.15);
  }
  84%,
  96% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1);
  }
}

.slide.is-active .file.from-cloud {
  animation: from-cloud 0.9s var(--ease) var(--t) both;
}
@keyframes from-cloud {
  from {
    opacity: 0;
    transform: translateY(-173px) scale(0.2);
  }
  30% {
    opacity: 1;
  }
}

/* ---------- Controls ---------- */

.controls {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
}

.back {
  justify-self: start;
  padding: 12px 8px;
  font-size: clamp(15px, 1vw + 6px, 20px);
  font-weight: 500;
  color: var(--text-2);
  border-radius: 8px;
  transition: color 0.2s, translate 0.2s var(--ease);
}
.back:hover {
  color: var(--text);
  translate: -3px 0;
}
.back[disabled] {
  visibility: hidden;
}

.actions {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: clamp(8px, 1vw, 16px);
}

/* Shown only on the story's last slide: slides down to the second deck. */
.more {
  display: none;
  align-items: center;
  gap: 0.5em;
  padding: clamp(11px, 1.6vh, 16px) clamp(18px, 2vw, 32px);
  font-size: clamp(16px, 1vw + 7px, 22px);
  font-weight: 600;
  color: var(--text);
  border: 2px solid var(--text);
  border-radius: 12px;
  white-space: nowrap;
  transition: background-color 0.2s, color 0.2s, translate 0.2s var(--ease);
}
.deck.at-end .more {
  display: inline-flex;
  animation: rise 0.6s var(--ease) 0.2s both;
}
.more:hover {
  background: var(--text);
  color: var(--bg);
  translate: 0 -2px;
}
.more svg {
  width: 1.05em;
  height: 1.05em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: nudge 1.4s ease-in-out infinite;
}
@keyframes nudge {
  50% {
    transform: translateY(4px);
  }
}

.next {
  justify-self: end;
  padding: clamp(13px, 1.6vh, 18px) clamp(26px, 2.6vw, 44px);
  font-size: clamp(16px, 1vw + 7px, 22px);
  font-weight: 600;
  color: #fff;
  background: var(--green);
  border-radius: 12px;
  white-space: nowrap;
  box-shadow: 0 10px 24px -10px rgba(21, 128, 61, 0.6);
  transition: background-color 0.2s, translate 0.2s var(--ease), box-shadow 0.2s;
}
.next:hover {
  background: var(--green-hover);
  translate: 0 -2px;
  box-shadow: 0 16px 28px -10px rgba(21, 128, 61, 0.65);
}
.next:active {
  background: var(--green-deep);
  translate: 0 1px;
}
.next.bump {
  animation: bump 0.35s var(--spring);
}
@keyframes bump {
  40% {
    transform: scale(0.94);
  }
}

.progress {
  display: grid;
  justify-items: center;
  gap: 4px;
}

.dots {
  display: flex;
}

.dot {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
}
.dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 5px;
  background: var(--dot);
  transition: background-color 0.3s, width 0.45s var(--spring);
}
.dot:hover::before {
  background: var(--text-2);
}
.dot[aria-current="true"] {
  width: 40px;
  transition: width 0.45s var(--spring);
}
.dot[aria-current="true"]::before {
  width: 28px;
  background: var(--green);
}

.caption {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

/* ---------- Narrow or portrait: stack ---------- */

@media (max-width: 820px), (orientation: portrait) {
  .slide {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    align-items: start;
    gap: clamp(18px, 3.5vh, 40px);
  }
  .diagram {
    justify-self: center;
  }
  .label {
    font-size: 23px;
  }
  .label.small {
    font-size: 20px;
  }
  .label.map-name {
    font-size: 15px;
  }
  .card-text.tight {
    font-size: 18px;
  }
}

@media (max-width: 640px) {
  .controls {
    grid-template-columns: auto 1fr;
    row-gap: 8px;
  }
  .progress {
    grid-row: 1;
    grid-column: 1 / -1;
  }
}

@media (max-width: 480px) {
  .dot {
    width: 18px;
  }
  .dot::before {
    width: 8px;
    height: 8px;
  }
  .dot[aria-current="true"] {
    width: 28px;
  }
  .dot[aria-current="true"]::before {
    width: 20px;
  }
  .fs {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}
