/* show.nitrowise.com, visual mockup, round 3. Night airport at the top of every page, one warm
   light (the lamp colour of the marshaller's wands), everything else quiet. Content keeps to the
   Campus column; the window runs the full width. Only transform and opacity ever animate. */

:root {
  color-scheme: dark;

  --deep: #040f1a;
  --night: #07192a;
  --panel: #0a1f33;
  --panel-2: #0d2740;
  --ground: #0b2236;
  --brand: #0a426b;
  --rail: #3a77a2;
  --lamp: #f2c27b;
  --paper: #ece5d8;
  --white: #fbf8f2;
  --fog: #93a6b8;
  --line: rgb(147 166 184 / 0.16);
  --hover: rgb(236 229 216 / 0.08);

  --display: "Saira", "Plus Jakarta Sans", system-ui, sans-serif;
  --sans: "Plus Jakarta Sans", system-ui, sans-serif;

  --t-14: 0.875rem;
  --t-16: 1rem;
  --t-18: 1.125rem;
  --t-21: 1.3125rem;
  --t-24: 1.5rem;
  --t-28: 1.75rem;
  --t-36: 2.25rem;

  --column: 70rem;
  --gutter: 20px;
  --overlap: clamp(90px, 10vw, 150px);
}

@media (max-width: 719px) {
  :root {
    --gutter: 16px;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--deep);
  -webkit-text-size-adjust: 100%;
}

/* Moving between pages: the window and the header stay where they are, only the window's light
   changes; the demo on its way travels between its tile and the player; the old page's title and
   content sink back, the new ones rise in, the title first. The names are given only for the move
   (assets/vt.js). Compositor only. */
@view-transition {
  navigation: auto;
}

.header {
  view-transition-name: header;
}

::view-transition-group(*) {
  animation-duration: 560ms;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

::view-transition-group(scene) {
  z-index: 1;
}

::view-transition-group(out-head),
::view-transition-group(out-body),
::view-transition-group(in-head),
::view-transition-group(in-body) {
  z-index: 2;
}

::view-transition-group(app) {
  z-index: 3;
  animation-duration: 640ms;
}

::view-transition-group(header) {
  z-index: 4;
}

/* The window keeps its size and place: the two pictures only fade into each other. */
::view-transition-old(scene),
::view-transition-new(scene) {
  height: 100%;
  object-fit: none;
  object-position: top;
}

::view-transition-old(scene) {
  animation: 300ms ease-out both vt-fade-out;
}

::view-transition-new(scene) {
  animation: 520ms ease both vt-fade-in;
}

::view-transition-old(app),
::view-transition-new(app) {
  height: 100%;
  object-fit: cover;
}

::view-transition-old(root),
::view-transition-old(out-head),
::view-transition-old(out-body) {
  animation: 200ms cubic-bezier(0.4, 0, 1, 1) both vt-sink;
}

::view-transition-new(in-head) {
  animation: 480ms cubic-bezier(0.2, 0.8, 0.2, 1) 120ms both vt-rise;
}

::view-transition-new(in-body),
::view-transition-new(root) {
  animation: 540ms cubic-bezier(0.2, 0.8, 0.2, 1) 220ms both vt-rise;
}

@keyframes vt-sink {
  to {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
}

@keyframes vt-rise {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
}

@keyframes vt-fade-out {
  to {
    opacity: 0;
  }
}

@keyframes vt-fade-in {
  from {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Our own scrollbar where there is a mouse; touch screens keep their thin overlay bar. */
@media (pointer: fine) {
  html {
    scrollbar-gutter: stable;
    scrollbar-color: #2a5374 var(--deep);
  }

  ::-webkit-scrollbar {
    width: 12px;
    height: 12px;
  }

  ::-webkit-scrollbar-track {
    background: var(--deep);
  }

  ::-webkit-scrollbar-thumb {
    border: 3px solid var(--deep);
    border-radius: 8px;
    background: #2a5374;
  }

  ::-webkit-scrollbar-thumb:hover {
    background: var(--rail);
  }
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--deep);
  color: var(--paper);
  font-family: var(--sans);
  font-size: var(--t-18);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--lamp);
  color: var(--night);
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--lamp);
  outline-offset: 3px;
  border-radius: 4px;
}

h1,
h2,
h3 {
  margin: 0;
  text-wrap: balance;
}

h1,
h2 {
  font-family: var(--display);
  font-weight: 450;
  font-variation-settings: "wdth" 112;
  line-height: 1.15;
}

p {
  margin: 0;
}

html[lang="hu"] [lang="en"]:not(html, .lang-option, .keep-lang),
html[lang="en"] [lang="hu"]:not(html, .lang-option, .keep-lang) {
  display: none !important;
}

.column {
  width: min(var(--column), 100% - 2 * var(--gutter));
  margin-inline: auto;
}

[hidden] {
  display: none !important;
}

/* ---------- Hover labels: ours, never the browser's title bubble ---------- */

[data-tip] {
  position: relative;
}

[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  z-index: 40;
  top: calc(100% + 8px);
  left: 50%;
  width: max-content;
  max-width: 20rem;
  padding: 6px 11px 7px;
  border: 1px solid rgb(58 119 162 / 0.38);
  border-radius: 7px;
  background: #0b2336;
  color: var(--paper);
  font-family: var(--sans);
  font-size: var(--t-14);
  font-weight: 500;
  line-height: 1.25;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -3px);
  transition:
    opacity 120ms ease,
    transform 120ms ease;
}

[data-tip]:hover::after,
[data-tip]:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
  transition-delay: 350ms;
}

[data-tip][data-tip-align="end"]::after {
  left: auto;
  right: 0;
  transform: translateY(-3px);
}

[data-tip][data-tip-align="end"]:hover::after,
[data-tip][data-tip-align="end"]:focus-visible::after {
  transform: none;
}

[data-tip][data-tip-above]::after {
  top: auto;
  bottom: calc(100% + 8px);
}

[data-tip=""]::after,
[aria-expanded="true"][data-tip]::after {
  display: none;
}

/* ---------- Header: the logo and the flags, on the column's edges ---------- */

.header-over {
  position: absolute;
  inset: 0 0 auto;
  z-index: 5;
  padding: 18px 0;
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand {
  display: block;
  padding: 4px 0;
}

.logo {
  display: block;
  height: 30px;
  width: auto;
}

.logo path {
  fill: var(--white);
  transition: fill 160ms ease;
}

.brand:hover .logo path {
  fill: var(--fog);
}

.langs {
  display: flex;
  gap: 6px;
  margin: 0 -4px 0 0;
  padding: 0;
  list-style: none;
}

.lang-option {
  display: block;
  padding: 6px 4px;
  border: 0;
  border-radius: 4px;
  background: none;
  cursor: pointer;
  opacity: 0.45;
  filter: grayscale(0.9);
  transition:
    opacity 140ms ease,
    filter 140ms ease;
}

.lang-option:hover,
.lang-option[aria-current="true"] {
  opacity: 1;
  filter: none;
}

.lang-option[aria-current="true"] {
  cursor: default;
}

.flag {
  display: block;
  width: 26px;
  height: 13px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgb(236 229 216 / 0.25);
}

@media (max-width: 719px) {
  .logo {
    height: 25px;
  }

  .flag {
    width: 22px;
    height: 11px;
  }
}

/* ---------- The window: the backdrop of the page's top ---------- */

/* The same picture on every page, so moving between pages leaves it where it is. Point 650 of the
   scene's 920 (the marshaller's waist) sits on the top of the front page's tile grid: the plane and
   the waving marshaller above the title, the tower and the floodlights still in the window. On a
   wide screen the grid moves down a little, so that the plane fits under the header. */
:root {
  --fold: clamp(240px, 36svh, 420px);
  --anchor: max(calc(var(--fold) + 92px), calc(74px + 22vw));
  --scene-w: max(100vw, calc(var(--anchor) * 2.4615));
  /* Then the picture goes up by up to 90 px, while the plane's fin (262 of 920) stays at least
     12 px below the page's top: on a tall window the empty sky above the plane goes, and the
     marshaller comes out whole above the grid. */
  --lift: 90px;
  --fin-min: 12px;
  --scene-top: max(calc(var(--anchor) - var(--scene-w) * 0.40625 - var(--lift)), calc(var(--fin-min) - var(--scene-w) * 0.16375));
}

/* On a phone the title runs the full width, so the marshaller stands above the title itself. */
@media (max-width: 719px) {
  :root {
    --fold: 40svh;
    --anchor: var(--fold);
    --lift: 0px;
  }
}

.terminal {
  position: absolute;
  inset: 0 0 auto;
  z-index: 0;
  height: calc(var(--scene-top) + var(--scene-w) * 0.575);
  overflow: hidden;
  background: var(--deep);
  container-type: size;
}

.scene-box {
  --w: max(100cqw, calc(var(--anchor) * 2.4615));
  position: absolute;
  left: 50%;
  top: max(calc(var(--anchor) - var(--w) * 0.40625 - var(--lift)), calc(var(--fin-min) - var(--w) * 0.16375));
  width: var(--w);
  aspect-ratio: 1600 / 920;
  transform: translateX(-50%);
  will-change: transform;
}

/* The window's upright posts, over the picture. Placed by the content column, not by the picture,
   so that none falls on the column's edge at any width: two at a quarter of the column from its
   middle (a wide middle pane), and on a wide screen two more halfway out in the margins. They
   stand down to the floor (722 of the scene's 920). */
.posts {
  --c: min(var(--column), 100cqw - 2 * var(--gutter));
  position: absolute;
  inset: 0 0 auto;
  height: 78.48%;
  pointer-events: none;
}

.posts i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: calc(var(--w) * 0.0075);
  background: linear-gradient(to right, #02080f calc(100% - 1px), rgb(58 119 162 / 0.28) 0);
  translate: -50% 0;
}

.posts i:nth-child(1) {
  left: calc(50% - var(--c) / 4);
}

.posts i:nth-child(2) {
  left: calc(50% + var(--c) / 4);
}

.posts i:nth-child(3),
.posts i:nth-child(4) {
  display: none;
}

@container (min-width: 1400px) {
  .posts i:nth-child(3) {
    display: block;
    left: calc(50% - (50cqw + var(--c) / 2) / 2);
  }

  .posts i:nth-child(4) {
    display: block;
    left: calc(50% + (50cqw + var(--c) / 2) / 2);
  }
}

/* Scrolling: the window drifts down at a third of the page's speed, so the content slides over
   it. A scroll-driven transform on one layer: nothing is repainted. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .scene-box {
      animation: drift linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 100vh;
    }
  }
}

@keyframes drift {
  from {
    transform: translateX(-50%) translateY(0);
  }
  to {
    transform: translateX(-50%) translateY(34vh);
  }
}

/* The window melts into the page's colour at its foot; on a demo page it is dimmer all over. */
.terminal::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to bottom,
    rgb(4 15 26 / 0) calc(var(--anchor) - 24px),
    rgb(4 15 26 / 0.6) calc(var(--anchor) + var(--scene-w) * 0.08),
    var(--deep) calc(100% - 4px)
  );
  pointer-events: none;
}

.page-demo .terminal::after {
  background: linear-gradient(to bottom, rgb(4 15 26 / 0.5) 0%, rgb(4 15 26 / 0.62) 45%, rgb(4 15 26 / 0.86) 72%, var(--deep) 96%);
}

.scene {
  display: block;
  width: 100%;
  height: 100%;
}

.fx {
  position: absolute;
  display: block;
  overflow: visible;
  pointer-events: none;
}

.arm {
  animation: sway 2.8s ease-in-out infinite alternate;
  will-change: transform;
}

.arm-right {
  animation-delay: -1.4s;
}

@keyframes sway {
  from {
    transform: rotate(-7deg);
  }
  to {
    transform: rotate(6deg);
  }
}

.beacon {
  animation: blink 1.6s steps(1, end) infinite;
  will-change: opacity;
}

@keyframes blink {
  0%,
  70% {
    opacity: 0.15;
  }
  71%,
  100% {
    opacity: 1;
  }
}

.terminal[data-paused] .arm,
.terminal[data-paused] .beacon {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .arm,
  .beacon {
    animation: none !important;
  }
}

/* The content scrolls over the window. */
.page {
  position: relative;
  z-index: 2;
}

.page-front .page {
  padding-top: calc(var(--anchor) - 92px);
}

.page-demo .page {
  padding-top: clamp(92px, 12svh, 128px);
}

.welcome {
  margin-bottom: clamp(20px, 2.6vw, 32px);
}

.welcome h1 {
  font-size: clamp(var(--t-36), 3.8vw, 3.25rem);
  text-shadow: 0 1px 18px rgb(4 15 26 / 0.7);
}

.welcome-title {
  display: flex;
  align-items: center;
  gap: 16px;
}

.app-icon {
  width: 60px;
  height: 60px;
  padding: 9px;
  border-radius: 16px;
  background: rgb(14 44 69 / 0.85);
  box-shadow: inset 0 0 0 1px rgb(147 166 184 / 0.25);
  flex: none;
}

@media (max-width: 719px) {
  .page-front .page {
    padding-top: var(--anchor);
  }

  .page-demo .page {
    padding-top: 84px;
  }

  .welcome h1 {
    font-size: var(--t-36);
  }

  .app-icon {
    width: 48px;
    height: 48px;
    padding: 7px;
    border-radius: 13px;
  }
}

/* ---------- Tiles: a thumbnail, the 23-second video on hover, sound on a click ---------- */

.showcase {
  padding-bottom: clamp(56px, 8vw, 96px);
}

.tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 3.4vw, 44px) clamp(20px, 2.4vw, 32px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile {
  display: grid;
  align-content: start;
  gap: 12px;
}

/* Under the mouse the tile, video and text together, grows a touch. Only where there is a mouse:
   a tap on a phone would leave it grown. In the carousel the side ones stay as they are. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .tiles > .tile {
    transition: transform 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .tiles > .tile:hover,
  .carousel-track > .tile:not(.is-side):hover {
    transform: scale(1.02);
  }
}

.tile-window {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: var(--panel);
  aspect-ratio: 16 / 9;
  box-shadow: 0 0 0 1px rgb(147 166 184 / 0.14);
  transition: box-shadow 160ms ease;
}

/* The tile lights up as one: over the video or over its name, the frame and the text brighten. */
.tile:hover .tile-window {
  box-shadow: 0 0 0 1px rgb(236 229 216 / 0.38);
}

.tile-thumb,
.tile-window video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tile-thumb {
  z-index: 1;
  transition: opacity 220ms ease;
}

.tile[data-state="preview"] .tile-thumb,
.tile[data-state="playing"] .tile-thumb,
.tile[data-state="paused"] .tile-thumb {
  opacity: 0;
}

/* The whole window is the play button; the icon shows only before the sound starts. */
.tile-start {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.tile-start-icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgb(7 25 42 / 0.72);
  color: var(--white);
  opacity: 0;
  transform: scale(0.9);
  transition:
    opacity 180ms ease,
    transform 180ms ease,
    background-color 160ms ease;
}

.tile-start-icon svg {
  width: 22px;
  height: 22px;
  margin-left: 3px;
}

.tile-window:hover .tile-start-icon,
.tile-start:focus-visible .tile-start-icon,
.tile[data-state="paused"] .tile-start-icon {
  opacity: 1;
  transform: none;
}

.tile-start:hover .tile-start-icon {
  background: var(--lamp);
  color: var(--night);
}

/* A ring breathes out of the button while the pointer is on it; a press pops it. */
.tile-start-icon::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--lamp);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.tile-start:hover .tile-start-icon::before {
  animation: breathe 1.6s ease-out infinite;
}

.tile-start:active .tile-start-icon {
  transform: scale(0.9);
}

.tile[data-state="playing"] .tile-start-icon {
  animation: pop 420ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes breathe {
  from {
    opacity: 0.7;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(1.55);
  }
}

@keyframes pop {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1.6);
  }
}


.tile[data-state="playing"] .tile-start-icon {
  opacity: 0;
}

.tile-ui {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  display: none;
  align-items: center;
  gap: 4px;
  padding: 18px 8px 6px 12px;
  background: linear-gradient(to top, rgb(4 15 26 / 0.85), rgb(4 15 26 / 0));
}

.tile[data-state="playing"] .tile-ui,
.tile[data-state="paused"] .tile-ui {
  display: flex;
}

.tile-progress {
  position: relative;
  flex: 1;
  height: 3px;
  margin-right: 6px;
  overflow: hidden;
  border-radius: 2px;
  background: rgb(236 229 216 / 0.25);
}

.tile-progress span {
  position: absolute;
  inset: 0;
  background: var(--lamp);
  transform: scaleX(0);
  transform-origin: left center;
}

.tile-btn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--paper);
  cursor: pointer;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.tile-btn:hover {
  background: rgb(236 229 216 / 0.14);
  color: var(--white);
}

.tile-btn svg {
  width: 18px;
  height: 18px;
}

.tile-length {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  padding: 1px 7px;
  border-radius: 5px;
  background: rgb(4 15 26 / 0.78);
  color: var(--paper);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.tile[data-state="playing"] .tile-length,
.tile[data-state="paused"] .tile-length {
  display: none;
}

.tile-link {
  display: grid;
  gap: 4px;
  border-radius: 6px;
}

.tile-name {
  font-family: var(--sans);
  font-size: var(--t-18);
  font-weight: 600;
  line-height: 1.3;
  transition: color 160ms ease;
}

.tile-desc {
  color: var(--fog);
  font-size: var(--t-16);
  line-height: 1.45;
  transition: color 160ms ease;
}

.tile:hover .tile-name {
  color: var(--white);
}

.tile:hover .tile-desc {
  color: #b9c6d2;
}

@media (max-width: 959px) {
  .tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 599px) {
  .tiles {
    grid-template-columns: 1fr;
  }
}

/* More demos than fit: the next row waits under the grid, faded and set back like the carousel's
   side ones, and one button opens the rest. */
.tiles-more {
  position: relative;
  margin-top: clamp(28px, 3.4vw, 44px);
}

.tiles-more[data-collapsed] {
  max-height: clamp(150px, 15vw, 200px);
  overflow: hidden;
}

.tiles-more[data-collapsed] .tiles {
  opacity: 0.4;
  transform: scale(0.94);
  transform-origin: 50% 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 10%, transparent 92%);
  mask-image: linear-gradient(to bottom, #000 10%, transparent 92%);
}

.more-button {
  position: absolute;
  left: 50%;
  bottom: clamp(14px, 2vw, 24px);
  z-index: 2;
  background: rgb(4 15 26 / 0.92);
  transform: translateX(-50%);
}

.more-button svg {
  width: 18px;
  height: 18px;
}

/* ---------- Lightbox: the tile's video, large ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: clamp(12px, 4vw, 56px);
}

.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgb(2 8 15 / 0.86);
}

.lightbox-frame {
  position: relative;
  width: min(1120px, 100%, (100svh - 140px) * 16 / 9);
  transform-origin: 0 0;
}

.lightbox-stage {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  background: #000;
  aspect-ratio: 16 / 9;
}

.lightbox-stage video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Recordings of dark apps carry the recorded browser's scrollbar gutter at the right edge
   (build.py, edge()): scaled out of the frame from the left. */
.tile-window video,
.lightbox-stage video,
.player video {
  transform: scale(var(--edge, 1));
  transform-origin: 0 50%;
}

.lightbox-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 10px;
}

.lightbox-track {
  position: relative;
  flex: 1;
  height: 4px;
  margin: 0 8px;
  overflow: hidden;
  border-radius: 2px;
  background: rgb(236 229 216 / 0.24);
  cursor: pointer;
}

.lightbox-track span {
  position: absolute;
  inset: 0;
  background: var(--lamp);
  transform: scaleX(0);
  transform-origin: left center;
}

.lightbox-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0 6px;
  padding: 8px 10px 8px 14px;
  border: 1px solid rgb(242 194 123 / 0.6);
  border-radius: 8px;
  color: var(--lamp);
  font-size: var(--t-16);
  font-weight: 600;
  white-space: nowrap;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.lightbox-more:hover {
  background: var(--lamp);
  color: var(--night);
}

.lightbox-more svg {
  width: 18px;
  height: 18px;
}

@media (max-width: 599px) {
  .lightbox-more {
    font-size: var(--t-14);
    padding: 6px 6px 6px 10px;
  }

  .lightbox .time {
    display: none;
  }
}

/* ---------- The player ---------- */

.stage {
  position: relative;
}

.player {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  background: #000;
  aspect-ratio: 16 / 9;
}

.player video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: pointer;
}

.player[data-full] {
  border-radius: 0;
  aspect-ratio: auto;
}

.player[data-idle],
.player[data-idle] video {
  cursor: none;
}

.big {
  position: absolute;
  inset: 0;
  z-index: 5;
  margin: auto;
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--lamp);
  color: var(--night);
  cursor: pointer;
  transition: transform 160ms ease;
}

.big:hover {
  transform: scale(1.06);
}

.big svg {
  width: 28px;
  height: 28px;
  margin-left: 4px;
}

/* Muted start: the video plays as part of the page. Top left, one press brings the sound in from
   the beginning. */
.restart {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 18px 11px 14px;
  border: 1px solid var(--lamp);
  border-radius: 10px;
  background: var(--lamp);
  box-shadow: 0 6px 22px rgb(4 15 26 / 0.45);
  color: var(--night);
  font-size: var(--t-18);
  font-weight: 700;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    border-color 140ms ease;
}

.restart:hover {
  border-color: #f6d29c;
  background: #f6d29c;
}

/* The video plays muted: a soft ring keeps going out from the button, so the sound is not missed. */
.restart::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  box-shadow: 0 0 0 2px var(--lamp);
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .restart::after {
    animation: ring-out 1.8s cubic-bezier(0.2, 0.7, 0.3, 1) infinite;
  }
}

@keyframes ring-out {
  from {
    opacity: 0.85;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(1.1, 1.35);
  }
}

.restart svg {
  width: 22px;
  height: 22px;
}

/* The other version, waiting in the corner. */
.upnext {
  position: absolute;
  right: 16px;
  bottom: 72px;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 270px;
  padding: 8px 14px 8px 8px;
  border: 1px solid rgb(236 229 216 / 0.24);
  border-radius: 12px;
  background: rgb(4 15 26 / 0.8);
  color: var(--paper);
  text-align: left;
  cursor: pointer;
  transition:
    border-color 140ms ease,
    background-color 140ms ease,
    opacity 220ms ease,
    transform 220ms ease;
}

.upnext:hover {
  border-color: rgb(242 194 123 / 0.7);
  background: rgb(14 39 64 / 0.92);
}

.upnext-thumb {
  display: block;
  width: 96px;
  aspect-ratio: 16 / 9;
  border-radius: 7px;
  object-fit: cover;
  flex: none;
}

.upnext-text {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.upnext-label {
  color: var(--fog);
  font-size: 13px;
}

.upnext-title {
  font-size: var(--t-16);
  font-weight: 600;
  line-height: 1.3;
}

.player[data-idle] .upnext {
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
}

/* The end: big, plain choices. */
.endscreen {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 2vw, 24px);
  padding: 20px;
  background: rgb(4 15 26 / 0.82);
}

.end-card {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 12px;
  min-width: 170px;
  min-height: 170px;
  padding: 18px 22px;
  border: 1px solid rgb(236 229 216 / 0.24);
  border-radius: 16px;
  background: rgb(10 31 51 / 0.85);
  color: var(--white);
  font-size: var(--t-18);
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition:
    border-color 140ms ease,
    background-color 140ms ease,
    transform 160ms ease;
}

.end-card:hover {
  border-color: rgb(242 194 123 / 0.75);
  background: rgb(18 48 76 / 0.95);
  transform: translateY(-2px);
}

.end-icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: rgb(236 229 216 / 0.1);
}

.end-icon svg {
  width: 30px;
  height: 30px;
}

.end-next {
  min-width: 300px;
}

.end-thumb {
  position: relative;
  display: block;
  width: 260px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 10px;
}

.end-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.end-play {
  position: absolute;
  inset: 0;
  margin: auto;
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--lamp);
  color: var(--night);
}

.end-play svg {
  width: 24px;
  height: 24px;
  margin-left: 3px;
}

.end-title {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
}

.dur {
  color: var(--fog);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 30px 10px 8px;
  background: linear-gradient(to top, rgb(4 15 26 / 0.88), rgb(4 15 26 / 0));
  transition: opacity 220ms ease;
}

.player[data-idle] .bar {
  opacity: 0;
}

.control {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--paper);
  cursor: pointer;
  transition:
    color 140ms ease,
    background-color 140ms ease;
}

.control:hover {
  background: rgb(236 229 216 / 0.12);
  color: var(--white);
}

.control svg {
  width: 20px;
  height: 20px;
}

.control[aria-pressed="true"] {
  color: var(--lamp);
}

.control[aria-expanded="true"] {
  background: rgb(236 229 216 / 0.14);
}

.time {
  flex: none;
  margin: 0 8px;
  color: var(--paper);
  font-size: var(--t-14);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The track: one segment per chapter. The segment under the pointer thickens, everything before
   the pointer lights up, the bubble names the chapter. */
.track {
  position: relative;
  flex: 1;
  height: 38px;
  margin: 0 6px;
  cursor: pointer;
  touch-action: none;
}

.track:focus-visible {
  outline-offset: -2px;
}

.segments {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  display: flex;
  gap: 3px;
  height: 4px;
  margin-top: -2px;
}

.seg {
  position: relative;
  min-width: 2px;
  height: 100%;
  overflow: hidden;
  border-radius: 2px;
  background: rgb(236 229 216 / 0.24);
  transition: transform 120ms ease;
}

.seg-preview,
.seg-fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: left center;
}

.seg-preview {
  background: rgb(251 248 242 / 0.42);
}

.seg-fill {
  background: var(--lamp);
}

.track[data-hover] .seg.is-hover {
  transform: scaleY(2.2);
}

.bubble {
  position: absolute;
  bottom: calc(50% + 14px);
  left: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: max-content;
  max-width: 16rem;
  padding: 7px 12px 8px;
  border: 1px solid rgb(58 119 162 / 0.42);
  border-radius: 8px;
  background: #0b2336;
  color: var(--white);
  font-size: var(--t-14);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  pointer-events: none;
  transform: translateX(var(--x, 0));
}

.bubble-at {
  color: var(--fog);
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* Menus for subtitles and sound: a dark panel like the hover label, no glow. */
.menu {
  position: absolute;
  right: 12px;
  bottom: 56px;
  z-index: 7;
  display: grid;
  min-width: 13rem;
  padding: 6px;
  border: 1px solid rgb(58 119 162 / 0.4);
  border-radius: 10px;
  background: #0b2336;
}

.menu-title {
  padding: 6px 10px 4px;
  color: var(--fog);
  font-size: 13px;
}

.menu-item {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--paper);
  font-size: var(--t-16);
  text-align: left;
  cursor: pointer;
  transition:
    background-color 120ms ease,
    color 120ms ease;
}

.menu-item:hover:not(:disabled) {
  background: rgb(236 229 216 / 0.1);
  color: var(--white);
}

.menu-item[aria-checked="true"] {
  font-weight: 600;
  color: var(--white);
}

.menu-item svg {
  width: 16px;
  height: 16px;
  color: var(--lamp);
}

.menu-item:disabled {
  color: rgb(147 166 184 / 0.6);
  cursor: default;
}

.menu-note {
  color: var(--fog);
  font-size: 12px;
}

/* Subtitles in the page's colours. */
.caption {
  position: absolute;
  left: 50%;
  bottom: 74px;
  z-index: 2;
  display: grid;
  justify-items: center;
  gap: 3px;
  width: max-content;
  max-width: 84%;
  margin: 0;
  transform: translateX(-50%);
  color: var(--white);
  font-size: clamp(0.8125rem, 0.55rem + 1.1vw, 1.45rem);
  font-weight: 500;
  line-height: 1.32;
  text-align: center;
  pointer-events: none;
  transition: transform 220ms ease;
}

.player[data-idle] .caption {
  transform: translate(-50%, 48px);
}

.caption:empty {
  display: none;
}

.caption span {
  padding: 0.12em 0.55em 0.16em;
  border-radius: 7px;
  background: rgb(7 25 42 / 0.86);
  box-shadow: inset 0 0 0 1px rgb(58 119 162 / 0.3);
}

.lightbox .caption {
  bottom: 18px;
}

@media (max-width: 719px) {
  .bar {
    padding: 24px 4px 4px;
    gap: 0;
  }

  .control {
    width: 34px;
    height: 34px;
  }

  .track {
    margin: 0 4px;
  }

  .time {
    margin: 0 4px;
    font-size: 12px;
  }

  .time .total {
    display: none;
  }

  .caption {
    bottom: 50px;
  }

  .player[data-idle] .caption {
    transform: translate(-50%, 34px);
  }

  .restart {
    top: 8px;
    left: 8px;
    gap: 7px;
    padding: 6px 11px 6px 9px;
    border-radius: 8px;
    font-size: var(--t-14);
  }

  .restart svg {
    width: 18px;
    height: 18px;
  }

  /* on a phone the bottom belongs to the captions and the bar: the card waits top right */
  .upnext {
    top: 8px;
    right: 8px;
    bottom: auto;
    width: auto;
    padding: 6px 10px;
  }

  .upnext-thumb,
  .upnext-label {
    display: none;
  }

  .upnext-title {
    font-size: var(--t-14);
  }
}

/* The narrowest phones have room for one corner button: the card waits until the sound is on. */
@media (max-width: 359px) {
  .player:has(.restart:not([hidden])) .upnext {
    display: none;
  }

  .endscreen {
    gap: 8px;
    padding: 10px;
  }

  .end-card {
    min-width: 0;
    min-height: 0;
    padding: 10px 12px;
    font-size: var(--t-14);
    gap: 6px;
  }

  .end-icon {
    width: 40px;
    height: 40px;
  }

  .end-icon svg {
    width: 20px;
    height: 20px;
  }

  .end-next {
    min-width: 0;
  }

  .end-thumb {
    width: 120px;
  }

  .end-play {
    width: 36px;
    height: 36px;
  }

  .end-more {
    display: none;
  }
}

/* ---------- Under the player ---------- */

.demo {
  padding-bottom: clamp(56px, 8vw, 96px);
}

.details {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(36px, 5vw, 72px);
  margin-top: clamp(48px, 6vw, 80px);
}

.details h2,
.related h2 {
  margin-bottom: 18px;
  font-size: var(--t-28);
}

.lead {
  max-width: 40rem;
  font-size: var(--t-18);
}

/* What it is for: a few lines first, then the flow, then a short paragraph or two. */
.about-summary {
  max-width: 40rem;
  color: var(--white);
  font-size: var(--t-18);
}

.about-intro p {
  max-width: 40rem;
  color: #c2cdd8;
  font-size: var(--t-16);
}

.about-intro p + p {
  margin-top: 12px;
}

/* How the app goes, from what comes in to what comes out: icons on a line of taxiway lights across
   the whole column, the result lit in the lamp colour. The first step keeps to the left edge, the
   last to the right, the ones between sit centred under their light, evenly spaced. */
.flow {
  --seg: calc((100% - 46px) / (var(--steps, 4) - 1));
  position: relative;
  display: flex;
  margin: 26px 0;
  padding: 0;
  list-style: none;
}

.flow::before {
  content: "";
  position: absolute;
  top: 21px;
  left: 23px;
  right: 23px;
  height: 4px;
  background: radial-gradient(circle, #6fa6cf 0 1.4px, transparent 1.9px) 0 50% / 10px 4px repeat-x;
  opacity: 0.8;
}

.flow-step {
  position: relative;
  display: grid;
  flex: 0 0 var(--seg);
  min-width: 0;
  justify-items: center;
  align-content: start;
  gap: 12px;
  padding-inline: 6px;
  text-align: center;
}

.flow-step:first-child,
.flow-step:last-child {
  flex-basis: calc(23px + var(--seg) / 2);
}

.flow-step:first-child {
  justify-items: start;
  padding-left: 0;
  text-align: left;
}

.flow-step:last-child {
  justify-items: end;
  padding-right: 0;
  text-align: right;
}

.flow-icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 12px;
  background: var(--panel);
  box-shadow:
    inset 0 0 0 1px rgb(147 166 184 / 0.22),
    0 0 0 8px var(--deep);
  color: #a9c4da;
}

.flow-icon svg {
  width: 22px;
  height: 22px;
}

.flow-step:last-child .flow-icon {
  background: linear-gradient(rgb(242 194 123 / 0.12) 0 0), var(--deep);
  box-shadow:
    inset 0 0 0 1px rgb(242 194 123 / 0.55),
    0 0 0 8px var(--deep);
  color: var(--lamp);
}

.flow-text {
  display: grid;
  gap: 2px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.flow-label {
  color: var(--white);
  font-size: var(--t-16);
  font-weight: 600;
  line-height: 1.3;
}

.flow-note {
  color: var(--fog);
  font-size: var(--t-14);
  line-height: 1.4;
}

/* On a phone the line runs down, the text beside each light. */
@media (max-width: 559px) {
  .flow {
    display: grid;
    gap: 18px;
  }

  .flow::before {
    display: none;
  }

  .flow-step,
  .flow-step:first-child,
  .flow-step:last-child {
    grid-template-columns: 46px minmax(0, 1fr);
    justify-items: start;
    align-items: start;
    gap: 14px;
    padding: 0;
    text-align: left;
  }

  .flow-step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 54px;
    bottom: -14px;
    left: 21px;
    width: 4px;
    background: radial-gradient(circle, #6fa6cf 0 1.4px, transparent 1.9px) 50% 0 / 4px 10px repeat-y;
    opacity: 0.8;
  }
}

/* "Read more": a few short blocks, each a heading and a paragraph. */
.about-more {
  display: grid;
  gap: 24px;
  max-width: 40rem;
  margin-top: 32px;
}

.about-block h3 {
  margin-bottom: 6px;
  font-family: var(--sans);
  font-size: var(--t-18);
  font-weight: 600;
  line-height: 1.3;
}

.about-block p {
  color: #c2cdd8;
  font-size: var(--t-16);
}

.more-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 22px;
  padding: 6px 0;
  border: 0;
  background: none;
  color: var(--lamp);
  font-size: var(--t-16);
  font-weight: 600;
  cursor: pointer;
  transition: color 140ms ease;
}

.more-toggle:hover {
  color: #f8dcae;
}

.more-toggle svg {
  width: 18px;
  height: 18px;
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.more-toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

.more-toggle .when-open,
.more-toggle[aria-expanded="true"] .when-closed {
  display: none;
}

.more-toggle[aria-expanded="true"] .when-open {
  display: inline;
}


/* One line from the narration, set large: the claim the video makes, in its own words. */
.quote {
  margin: 0;
  padding: 2px 0 2px 22px;
  border-left: 3px solid var(--lamp);
}

.quote p {
  font-family: var(--display);
  font-size: clamp(var(--t-21), 2.2vw, var(--t-28));
  font-variation-settings: "wdth" 106;
  font-weight: 400;
  line-height: 1.3;
  color: var(--white);
  text-wrap: balance;
}

.features {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px 36px;
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
}

.features h3 {
  margin-bottom: 6px;
  font-family: var(--sans);
  font-size: var(--t-18);
  font-weight: 600;
  line-height: 1.3;
}

.features p {
  color: var(--fog);
  font-size: var(--t-16);
}

.jump {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 10px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--lamp);
  font-size: var(--t-14);
  font-weight: 600;
  cursor: pointer;
  transition: color 140ms ease;
}

.jump:hover {
  color: #f8dcae;
}

.jump-at {
  padding: 0 6px;
  border-radius: 4px;
  background: rgb(242 194 123 / 0.12);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.chapters {
  margin: 0;
  padding: 0;
  list-style: none;
}

.chapters button {
  display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr);
  align-items: baseline;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--paper);
  font-size: var(--t-16);
  text-align: left;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.chapters button:hover {
  background: var(--hover);
  color: var(--white);
}

.chapters .at {
  color: var(--fog);
  font-variant-numeric: tabular-nums;
}

.chapters button[aria-current="true"] {
  background: rgb(242 194 123 / 0.1);
  color: var(--white);
  font-weight: 600;
}

.chapters button[aria-current="true"] .at {
  color: var(--lamp);
  font-weight: 500;
}

@media (max-width: 859px) {
  .details {
    grid-template-columns: 1fr;
  }

  .features {
    grid-template-columns: 1fr;
  }
}

/* The invitation: the window's marshaller stands on the panel's floor, his wands just over its edge,
   halfway between the panel's left edge and the text. */
.invite {
  --pad-l: clamp(150px, 15vw, 190px);
  --fig-w: clamp(104px, 10vw, 124px);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px clamp(20px, 3vw, 40px);
  margin-top: clamp(72px, 9vw, 112px);
  padding: 28px clamp(20px, 3vw, 40px) 28px var(--pad-l);
  border-radius: 16px;
  background: linear-gradient(100deg, var(--panel-2), var(--panel) 60%);
}

.figure-box {
  position: absolute;
  left: calc(var(--pad-l) / 2 - var(--fig-w) / 2);
  bottom: 0;
  width: var(--fig-w);
  aspect-ratio: 220 / 300;
}

.figure-body {
  display: block;
  width: 100%;
  height: 100%;
}

.invite h2 {
  font-size: var(--t-28);
}

.invite p {
  margin-top: 6px;
  color: var(--fog);
  font-size: var(--t-16);
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  border: 1px solid var(--lamp);
  border-radius: 9px;
  background: none;
  color: var(--lamp);
  font-size: var(--t-16);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.button:hover,
.button-solid {
  background: var(--lamp);
  color: var(--night);
}

.button-solid:hover {
  background: #f6d29c;
}

@media (max-width: 719px) {
  .invite {
    --pad-l: 108px;
    --fig-w: 86px;
    grid-template-columns: 1fr;
    margin-top: 72px;
  }

  .invite h2 {
    font-size: var(--t-24);
  }

  .invite .button {
    justify-self: start;
  }
}

/* An address that leads nowhere. */
.lost-text {
  max-width: 34rem;
  margin: 4px 0 26px;
  color: #c2cdd8;
  font-size: var(--t-18);
}

/* The quick page's invitation, a card beside "What it is for": the title, the line and the button
   stacked, and at their left the marshaller exactly as tall as they are, his wands' tips level
   with the title, his feet with the button's foot. He may reach out of the card. Where the
   columns stack, it is the usual band again. */
.details > .invite {
  margin-top: 24px;
}

@media (min-width: 860px) {
  .details > .invite-side {
    --pad-l: 118px;
    --pad-t: 24px;
    --pad-b: 26px;
    grid-template-columns: 1fr;
    align-self: start;
    gap: 6px;
    margin-top: 0;
    padding: var(--pad-t) 22px var(--pad-b) var(--pad-l);
  }

  /* In the figure's own frame (300 high) the wands' tips are 36 from the top and the feet 11 from
     the bottom: the box is set so that those two lines meet the text's top and foot. */
  .invite-side .figure-box {
    --text-h: calc(100% - var(--pad-t) - var(--pad-b));
    top: calc(var(--pad-t) - var(--text-h) * 36 / 253);
    bottom: calc(var(--pad-b) - var(--text-h) * 11 / 253);
    left: calc(var(--pad-l) / 2);
    width: auto;
    aspect-ratio: 220 / 300;
    translate: -50% 0;
  }

  .invite-side h2 {
    font-size: var(--t-24);
    line-height: 1.2;
  }

  .invite-side p {
    margin-top: 2px;
  }

  .invite-side .button {
    justify-self: start;
    margin-top: 14px;
  }
}

/* Related demos: the three relevant ones in the column, a smaller, fading one at each side. Endless;
   moved by the side ones, a drag, a swipe or a sideways scroll. Only transforms move. */
.related {
  margin: clamp(8px, 1.5vw, 16px) 0 clamp(56px, 7vw, 88px);
}

.related h2 {
  margin-bottom: 18px;
  font-size: var(--t-28);
}

.carousel {
  --gap: clamp(16px, 2vw, 28px);
  position: relative;
  overflow: hidden;
  padding: 4px 0 10px;
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
}

.carousel[data-dragging] {
  cursor: grabbing;
}

.carousel[data-dragging] .tile {
  pointer-events: none;
}

.carousel-track {
  display: flex;
  gap: var(--gap);
  margin: 0;
  padding: 0;
  list-style: none;
  will-change: transform;
}

.carousel-track > .tile {
  flex: none;
  width: var(--item-w, 30%);
  transition:
    transform 320ms cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 320ms ease;
}

.carousel-track > .tile.is-side {
  opacity: 0.4;
  transform: scale(0.86);
}

.carousel-track img {
  -webkit-user-drag: none;
}

/* The page's colour over the outer edges, so the side ones fade out. */
.carousel::before,
.carousel::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 2;
  width: var(--side-w, 12%);
  pointer-events: none;
}

.carousel::before {
  left: 0;
  background: linear-gradient(to right, var(--deep) 18%, rgb(4 15 26 / 0));
}

.carousel::after {
  right: 0;
  background: linear-gradient(to left, var(--deep) 18%, rgb(4 15 26 / 0));
}

.carousel-edge {
  position: absolute;
  top: var(--edge-y, 30%);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-top: -26px;
  padding: 0;
  border: 1px solid rgb(236 229 216 / 0.28);
  border-radius: 50%;
  background: rgb(10 31 51 / 0.86);
  color: var(--paper);
  cursor: pointer;
  transition:
    background-color 140ms ease,
    border-color 140ms ease,
    color 140ms ease,
    transform 160ms ease;
}

.carousel-edge:hover {
  border-color: rgb(236 229 216 / 0.6);
  background: rgb(18 48 76 / 0.95);
  color: var(--white);
  transform: scale(1.06);
}

.carousel-edge svg {
  width: 22px;
  height: 22px;
}

.carousel-prev {
  left: calc(var(--side-w, 12%) / 2 - 26px);
}

.carousel-next {
  right: calc(var(--side-w, 12%) / 2 - 26px);
}

.carousel .tile-name {
  font-size: var(--t-16);
}

.carousel .tile-desc {
  font-size: var(--t-14);
}

@media (max-width: 719px) {
  .carousel-edge {
    width: 40px;
    height: 40px;
    margin-top: -20px;
  }

  .carousel-prev {
    left: 4px;
  }

  .carousel-next {
    right: 4px;
  }
}

/* ---------- The demo request ---------- */

.request {
  width: min(520px, 100% - 2 * var(--gutter));
  max-height: calc(100dvh - 40px);
  margin: auto;
  padding: 0;
  border: 1px solid rgb(58 119 162 / 0.35);
  border-radius: 18px;
  background: var(--panel);
  color: var(--paper);
  overflow: hidden auto;
}

.request::backdrop {
  background: rgb(2 8 15 / 0.82);
}

.request[open] {
  animation: 240ms cubic-bezier(0.2, 0.8, 0.2, 1) both dialog-in;
}

@keyframes dialog-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.98);
  }
}

.request-form {
  position: relative;
  display: grid;
  margin: 0;
}

.request-body,
.request-done {
  display: grid;
  gap: 16px;
  padding: 30px clamp(20px, 4vw, 34px) 30px;
}

.request h2 {
  padding-right: 40px;
  font-size: var(--t-28);
}

.request-done p {
  color: var(--fog);
  font-size: var(--t-16);
}

.request-close {
  position: absolute;
  top: 16px;
  right: 16px;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--paper);
  cursor: pointer;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.request-close:hover {
  background: rgb(236 229 216 / 0.1);
  color: var(--white);
}

.request-close svg {
  width: 20px;
  height: 20px;
}

.field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.field-row {
  display: grid;
  gap: 16px;
}

@media (min-width: 600px) {
  .field-row {
    grid-template-columns: 1fr 1fr;
  }
}

/* A low screen gets the whole form without scrolling. */
@media (max-height: 760px) {
  .request-body,
  .request-done {
    gap: 12px;
    padding-block: 22px;
  }

  .request .field textarea {
    min-height: 116px;
  }
}

.field > span {
  color: var(--fog);
  font-size: var(--t-14);
}

.field input,
.field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid rgb(147 166 184 / 0.32);
  border-radius: 9px;
  background: rgb(7 25 42 / 0.65);
  color: var(--white);
  font: inherit;
  font-size: var(--t-16);
  transition:
    border-color 140ms ease,
    background-color 140ms ease;
}

.field textarea {
  resize: none;
  min-height: 140px;
}

.field input:hover,
.field textarea:hover {
  border-color: rgb(147 166 184 / 0.55);
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--lamp);
  background: rgb(7 25 42 / 0.9);
}

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: #ff9f8e;
}

.trap {
  position: absolute;
  left: -9999px;
}

.request-note {
  color: var(--fog);
  font-size: 13px;
}

.request-error {
  color: #ff9f8e;
  font-size: var(--t-14);
}

.request-actions {
  display: flex;
  justify-content: flex-end;
}

/* Sent: the letter rolls along a short runway of lights and lifts off, then the thanks. Both
   panels keep the form's height (site.js), so the dialog does not jump. */
.request-sending,
.request-done {
  align-content: center;
  justify-items: center;
  text-align: center;
}

.request-sending {
  display: grid;
  gap: 14px;
  padding: 30px clamp(20px, 4vw, 34px);
}

.request-sending p {
  color: var(--fog);
  font-size: var(--t-16);
}

.send-runway {
  position: relative;
  width: 220px;
  height: 60px;
  background: radial-gradient(circle, #6fa6cf 0 1.6px, transparent 2.1px) 3px 100% / 14px 6px repeat-x;
}

.send-letter {
  position: absolute;
  left: 0;
  bottom: 10px;
  width: 48px;
  height: 34px;
  color: var(--lamp);
}

.request-done h2 {
  padding-right: 0;
}

.request-done:focus {
  outline: none;
}

.done-mark {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgb(242 194 123 / 0.12);
  box-shadow: inset 0 0 0 1.5px rgb(242 194 123 / 0.7);
  color: var(--lamp);
}

.done-mark svg {
  width: 28px;
  height: 28px;
}

/* ---------- Footer: a quiet row of apron vehicles on the ground line, then the links ---------- */

.footer {
  margin-top: auto;
}

.apron {
  height: 46px;
  background: url("apron.svg") left bottom / 1380px 46px repeat-x;
  opacity: 0.5;
}

.footer-ground {
  background: var(--ground);
  border-top: 1px solid rgb(58 119 162 / 0.22);
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px 0;
  padding: 22px 0 26px;
  color: var(--fog);
  font-size: var(--t-14);
}

.footer-row a,
.footer-link {
  transition: color 140ms ease;
}

.footer-link {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.footer-row a:hover,
.footer-link:hover {
  color: var(--white);
}

.links,
.socials,
.version {
  display: flex;
  align-items: baseline;
}

.version {
  margin-left: auto;
  padding-left: 24px;
  font-variant-numeric: tabular-nums;
}

.dot {
  display: inline-block;
  flex: none;
  width: 4px;
  height: 4px;
  margin: 0 12px;
  border-radius: 50%;
  background: var(--fog);
  opacity: 0.8;
  transform: translateY(calc(2px - 0.5ex));
}

.social {
  display: inline-flex;
  padding: 0 3px;
}

.social + .social {
  margin-left: 8px;
}

.social svg {
  display: block;
  width: auto;
  height: 0.85em;
  transform: translateY(0.08em);
}

/* On a narrow screen the links and the icons stay on one line; the year and the version move to
   the next one, to the right, only when they do not fit beside them. */
@media (max-width: 672px) {
  .footer-row {
    row-gap: 14px;
  }
}
