/* v404.ai: shared stylesheet. Plain CSS, no build step, no web fonts.
   The site is dark only: the black hole is drawn on a void. Brand colours
   come from docs/brand/v404/README.md (off-white #F3F4F5, void #000000,
   icon glow #7E93B5). */

:root {
  color-scheme: dark;
  --void: #000000;
  --ink: #F3F4F5;
  --text-2: #B8BEC7;
  --text-3: #A0A7B1;
  --line: rgba(243, 244, 245, 0.16);
  --line-strong: rgba(243, 244, 245, 0.55);
  --accent: #93A7C9;
  --wordmark: #F3F4F5;
  --gutter: clamp(20px, 6.5vw, 112px);
  --ease: cubic-bezier(0.19, 0.72, 0.1, 1);
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "Segoe UI", Roboto, Arial, sans-serif;
  --display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", "Segoe UI", Roboto, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  background: var(--void);
  scroll-padding-top: 88px;
}

/* No CSS smooth scrolling: a link to a place on the page must not play the
   whole page's animation on the way. assets/site.js decides how a link
   scrolls (a fade and a jump for a long way, a smooth scroll for a hop). */

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--ink);
  text-decoration-color: rgba(243, 244, 245, 0.4);
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-color: var(--ink);
}

/* Two tones, so the ring holds on the void and on the bright disk: a
   black band, the accent ring, and another black band outside it. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  box-shadow: 0 0 0 7px #000;
}

::selection {
  background: rgba(147, 167, 201, 0.35);
  color: var(--ink);
}

.skip {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 50;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--void);
  font-size: 14px;
  text-decoration: none;
}

.skip:focus {
  top: 12px;
}

main:focus,
.scene:focus,
.interlude:focus {
  outline: none;
}

/* A quick black fade for a long jump to a place on the page (site.js). */
.veil {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: var(--void);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease-out;
}

.veil.on {
  opacity: 1;
  transition-duration: 0.2s;
  transition-timing-function: ease-in;
}

@media (prefers-reduced-motion: reduce) {
  .veil {
    display: none;
  }
}

/* Header */

header.site {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: max(18px, env(safe-area-inset-top)) var(--gutter) 18px;
}

/* A dark band behind the header: solid under the wordmark and nav, clear by
   150 px, so text scrolling up fades out before it reaches them. On the
   home page site.js sets --scrim from 0 to 1 over the first 120 px of
   scroll, so the opening frame keeps the whole picture. */
header.site::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  right: 0;
  height: 150px;
  background: linear-gradient(to bottom, #000 0, rgba(0, 0, 0, 0.96) 70px, rgba(0, 0, 0, 0.62) 100px, rgba(0, 0, 0, 0) 100%);
  opacity: calc(0.4 + 0.6 * var(--scrim, 1));
  pointer-events: none;
}

.head-end {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.4vw, 30px);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  /* Clear space of half the cap height on every side (brand rule). */
  padding: 11px 0;
  color: var(--wordmark);
  text-decoration: none;
}

.wordmark svg {
  /* 28px tall (cap about 27px). The header uses the lensed drawing, as John
     asked on 28 Sep, even though the kit reserves it for 128px and up. */
  height: 28px;
  width: auto;
  display: block;
}

nav.site {
  display: flex;
  gap: clamp(18px, 3vw, 36px);
  white-space: nowrap;
}

nav.site a,
footer.site nav a {
  display: inline-block;
  padding: 12px 0;
  color: var(--text-2);
  text-decoration: none;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

nav.site a:hover,
footer.site nav a:hover {
  color: var(--ink);
}

/* Pause and play for the animation: a small aperture in the header. */
.motion {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid rgba(243, 244, 245, 0.3);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  color: var(--text-2);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.motion[hidden] {
  display: none;
}

.motion svg {
  display: block;
  width: 10px;
  height: 10px;
  fill: currentColor;
}

.motion[data-paused="1"] .i-pause,
.motion[data-paused="0"] .i-play {
  display: none;
}

.motion:hover {
  color: var(--ink);
  border-color: var(--line-strong);
}

/* The stage: a fixed canvas behind everything. 100lvh keeps its size fixed
   while a phone's toolbar slides in and out, so the renderer never resizes
   mid-scroll. */

.stage {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  z-index: 0;
  background: var(--void);
}

.stage canvas {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1.8s var(--ease);
}

/* The first frame fades in from the void once it is drawn. */
.stage canvas[data-blackhole-ready] {
  opacity: 1;
}

/* A still frame when there is no renderer: no JavaScript, a failed
   site.js, no WebGL2, or a shader that would not compile. */
html:not(.js) .stage,
html[data-sky="still"] .stage,
.stage[data-blackhole-fallback] {
  background: var(--void) url("assets/still-wide.jpg") 72% 50% / cover no-repeat;
}

html[data-sky="still"] .stage canvas,
.stage[data-blackhole-fallback] canvas {
  visibility: hidden;
}

@media (max-aspect-ratio: 4/5) {
  html:not(.js) .stage,
  html[data-sky="still"] .stage,
  .stage[data-blackhole-fallback] {
    background-image: url("assets/still-tall.jpg");
    background-position: 50% 0%;
  }
}

/* Scroll scale: a thin focus scale on the right edge, one tick per scene. */

.scale {
  position: fixed;
  right: calc(var(--gutter) * 0.42);
  top: 50%;
  z-index: 5;
  width: 1px;
  height: 200px;
  margin-top: -100px;
  background: var(--line);
  pointer-events: none;
}

.scale::before {
  content: "";
  position: absolute;
  left: -3px;
  width: 7px;
  top: 0;
  height: calc(100% + 1px);
  background: repeating-linear-gradient(to bottom, rgba(243, 244, 245, 0.34) 0 1px, transparent 1px 20px);
}

.scale-fill {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 100%;
  background: var(--ink);
  transform-origin: top;
  transform: scaleY(var(--progress, 0));
}

@media (max-width: 899px) {
  .scale {
    display: none;
  }
}

/* Scenes */

main {
  position: relative;
  z-index: 1;
  overflow-x: clip;
}

.scene {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100vh;
  min-height: 100svh;
  padding: 120px var(--gutter);
}

.scene-right {
  justify-content: flex-end;
}

.hero {
  align-items: flex-start;
  padding-top: clamp(128px, 23vh, 240px);
}

/* The last scene shares the final screen with the footer, so it is only as
   tall as its text on wide screens. */
@media (min-width: 701px) and (min-aspect-ratio: 801/1000) {
  #download {
    min-height: 0;
    align-items: flex-start;
    padding-top: 140px;
    padding-bottom: 24px;
  }
}

.panel {
  position: relative;
  isolation: isolate;
  width: min(100%, 37rem);
}

/* A soft dark field behind every block of text, so it reads over the
   brightest part of the disk. */
.panel::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -22% -30%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.84) 0%, rgba(0, 0, 0, 0.78) 60%, rgba(0, 0, 0, 0.4) 84%, rgba(0, 0, 0, 0) 100%);
  pointer-events: none;
}

/* A close shadow on the words themselves, for the edges of the field. */
.panel .label,
.panel h1,
.panel h2,
.panel .body,
.panel .status {
  text-shadow: 0 0 14px rgba(0, 0, 0, 0.9), 0 1px 2px rgba(0, 0, 0, 0.85);
}

.label {
  margin: 0;
  color: var(--text-2);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.32em;
  text-transform: uppercase;
}

.label .num {
  color: var(--accent);
  margin-right: 1.1em;
  font-variant-numeric: tabular-nums;
}

.label-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hero .label-stack {
  color: var(--ink);
}

/* Astronomical notation and clock times: never uppercased. */
.label .coords,
.label .time {
  text-transform: none;
  letter-spacing: 0.16em;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.rule {
  display: block;
  width: 44px;
  height: 1px;
  margin: 24px 0 28px;
  background: linear-gradient(90deg, rgba(243, 244, 245, 0.85), rgba(243, 244, 245, 0.15));
  transform-origin: left center;
}

h1,
h2 {
  margin: 0 0 22px;
  font-family: var(--display);
  font-weight: 300;
  color: var(--ink);
  text-wrap: balance;
}

h1 {
  font-size: clamp(2rem, 1.2rem + 2.2vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.018em;
  max-width: 12.5em;
}

h2 {
  font-size: clamp(1.75rem, 1.05rem + 2.3vw, 2.8rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  max-width: 15em;
}

/* The hero headline is the whole first sentence of the pitch. */
.hero h1 {
  font-size: clamp(1.75rem, 1.05rem + 1.5vw, 2.25rem);
  line-height: 1.16;
  max-width: 17em;
}

.body {
  margin: 0 0 20px;
  max-width: 33em;
  color: var(--text-2);
  font-size: clamp(1rem, 0.96rem + 0.18vw, 1.1rem);
  line-height: 1.62;
  text-wrap: pretty;
}

/* Section 06: four features, each a small bold name and its sentences. */
.items {
  margin: 0 0 8px;
  max-width: 33em;
}

.items dt {
  margin-top: 16px;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.4;
}

.items dt:first-child {
  margin-top: 0;
}

.items dd {
  margin: 4px 0 0;
  color: var(--text-2);
  font-size: clamp(0.95rem, 0.92rem + 0.12vw, 1.02rem);
  line-height: 1.55;
  text-wrap: pretty;
}

.panel .items {
  text-shadow: 0 0 14px rgba(0, 0, 0, 0.9), 0 1px 2px rgba(0, 0, 0, 0.85);
}

.status {
  margin: 16px 0 0;
  color: var(--text-3);
  font-size: 13.5px;
  line-height: 1.5;
  letter-spacing: 0.01em;
}

.placeholder {
  font-family: var(--mono);
  font-size: 0.86em;
  color: var(--ink);
  letter-spacing: 0.02em;
  border-bottom: 1px dashed var(--accent);
  white-space: nowrap;
}

.placeholder-wrap {
  white-space: normal;
}

/* Keeps a hyphenated word such as "to-do" on one line. */
.nw {
  white-space: nowrap;
}

/* After section 08: a screen with no words, for the pull back to the black
   hole and its close companion. */
.interlude {
  height: 80vh;
  height: 80svh;
}

/* Pre-order: two options side by side, stacked on a phone. */
.panel-wide {
  width: min(100%, 36rem);
}

/* The options carry their own dark ground, so the field behind the words
   stays close to them and leaves the companion star beside them clear. */
.panel-wide::before {
  inset: -14% -10%;
}

.plans {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 30px;
}

.plan {
  display: flex;
  flex-direction: column;
  padding: 22px 22px 24px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.62);
}

.plan h3 {
  margin: 0;
  color: var(--text-2);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

.plan .price {
  margin: 14px 0 12px;
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 300;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.plan .plan-line {
  margin: 0 0 14px;
  color: var(--text-2);
  font-size: 15px;
  line-height: 1.55;
}

.plan .terms {
  margin: 0 0 22px;
  color: var(--text-3);
  font-size: 13.5px;
  line-height: 1.5;
}

.plan .btn {
  align-self: flex-start;
  margin-top: auto;
}

.plan .placeholder {
  white-space: normal;
}

.plans-note {
  margin-top: 22px;
}

/* Buttons */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 30px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  margin: 0;
  padding: 0 30px;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.35);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease), color 0.4s var(--ease);
}

.btn:hover {
  background: rgba(243, 244, 245, 0.1);
  border-color: var(--ink);
}

/* A quieter outline, for a link that only moves down the page. */
.btn-quiet {
  border-color: rgba(243, 244, 245, 0.3);
  color: var(--text-2);
  background: rgba(0, 0, 0, 0.3);
}

.btn-quiet:hover {
  color: var(--ink);
}

/* Buttons for things that do not exist yet: shown, and disabled. */
.btn:disabled {
  color: var(--text-3);
  border-color: var(--line);
  background: transparent;
  cursor: default;
}

/* Scroll cue */

.cue {
  position: absolute;
  left: var(--gutter);
  top: calc(100vh - 100px);
  top: calc(100svh - 100px);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 0;
  color: var(--text-3);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  text-decoration: none;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.95), 0 1px 2px rgba(0, 0, 0, 0.9);
}

.cue::before {
  content: "";
  display: block;
  width: 1px;
  height: 44px;
  background:
    linear-gradient(to bottom, rgba(243, 244, 245, 0), rgba(243, 244, 245, 0.95) 50%, rgba(243, 244, 245, 0)) 0 -44px / 1px 44px no-repeat,
    rgba(243, 244, 245, 0.18);
  animation: cue 3.6s var(--ease) infinite;
}

.cue:hover {
  color: var(--ink);
}

/* A small dark field behind the word, for when the disk runs under it. */
.cue {
  isolation: isolate;
}

.cue span {
  position: relative;
}

.cue span::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -18px -26px;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.88), rgba(0, 0, 0, 0.7) 58%, rgba(0, 0, 0, 0));
  pointer-events: none;
}

@keyframes cue {
  0% { background-position: 0 -44px, 0 0; }
  75%, 100% { background-position: 0 44px, 0 0; }
}

/* Arrival: each block comes into focus as its scene reaches the screen.
   Only with JavaScript, so without it every word is shown as it is. */

.js .scene .reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  filter: blur(8px);
  transition:
    opacity 1.5s var(--ease),
    transform 1.9s var(--ease),
    filter 1.5s var(--ease);
}

.js .scene .rule.reveal {
  transform: scaleX(0);
  filter: none;
}

.js .scene.is-in .reveal,
.js .scene .panel:focus-within .reveal {
  opacity: 1;
  transform: none;
  filter: none;
}

.js .scene .panel > .reveal:nth-child(2) { transition-delay: 0.1s; }
.js .scene .panel > .reveal:nth-child(3) { transition-delay: 0.22s; }
.js .scene .panel > .reveal:nth-child(4) { transition-delay: 0.36s; }
.js .scene .panel > .reveal:nth-child(5) { transition-delay: 0.5s; }
.js .scene .panel > .reveal:nth-child(6) { transition-delay: 0.62s; }
.js .scene .panel > .reveal:nth-child(7) { transition-delay: 0.72s; }

@media (prefers-reduced-motion: reduce) {
  .js .scene .reveal,
  .js .scene .rule.reveal {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }

  .cue::before {
    animation: none;
    background: rgba(243, 244, 245, 0.35);
  }

  .stage canvas {
    transition: none;
  }
}

/* ?freeze=1: a fixed frame for screenshots. */
.frozen *,
.frozen *::before,
.frozen *::after {
  transition: none !important;
  animation: none !important;
}

/* Footer */

footer.site {
  position: relative;
  z-index: 1;
  padding: 96px var(--gutter) max(48px, env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.88) 38%);
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
  padding-top: 28px;
  margin-bottom: 20px;
  border-top: 1px solid var(--line);
}

footer.site nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 32px;
}

footer.site .mark {
  color: var(--text-2);
}

footer.site .mark svg {
  height: 18px;
  width: auto;
  display: block;
}

.fine {
  margin: 0 0 6px;
  color: var(--text-3);
  font-size: 13px;
  line-height: 1.55;
}

/* The lensed logo (docs/brand/v404/README.md) is drawn for 128 px and up:
   its arc of light is 2 px at 128 px and turns to a grey line below that.
   Every lensed drawing on this page has a 128 px floor; where the room
   is narrower, the approved medium drawing is used instead. */

/* Section 08: the mark, above the label. */
.name-mark {
  display: block;
  margin: 0 0 26px;
  color: var(--ink);
}

.name-mark .logo-lensed {
  display: block;
  width: auto;
  height: clamp(128px, 9vw, 144px);
}

/* The closing wordmark, at the head of the footer. The lensed drawing needs
   a cap height of 128 px, which is 132 px of the drawing's height and 454
   px of width, so it shows from 540 px wide and a phone shows the medium
   drawing. */
.closing {
  margin: 0 0 56px;
  color: var(--ink);
}

.closing svg {
  display: block;
  width: auto;
}

.closing .logo-lensed {
  height: clamp(132px, 13vw, 190px);
}

.closing .logo-medium {
  display: none;
}

@media (max-width: 539px) {
  .closing .logo-lensed {
    display: none;
  }

  .closing .logo-medium {
    display: block;
    width: min(100%, 22rem);
    height: auto;
  }
}

/* Mac beta: the app icon at 128 px beside the disabled download. */
.get {
  display: flex;
  align-items: center;
  gap: 24px 32px;
  margin-top: 30px;
}

.get .status {
  margin-top: 14px;
}

.app-icon {
  display: block;
  flex: none;
  width: 128px;
  height: 128px;
  border-radius: 22.5%;
  box-shadow: 0 0 0 1px rgba(243, 244, 245, 0.14), 0 22px 44px -14px rgba(0, 0, 0, 0.9);
}

@media (max-width: 700px) {
  .get {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Inner pages: privacy, terms, support and the not-found page. A still
   frame of the black hole sits behind the top of the page and fades into
   the void before the text gets long. */

.backdrop {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: min(88vh, 900px);
  z-index: 0;
  background: var(--void) url("assets/still-wide.jpg") 72% 38% / cover no-repeat;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.8) 45%, rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.8) 45%, rgba(0, 0, 0, 0) 100%);
  opacity: 0.62;
  pointer-events: none;
}

@media (max-aspect-ratio: 4/5) {
  .backdrop {
    background-image: url("assets/still-tall.jpg");
    background-position: 50% 0%;
  }
}

.doc main {
  padding: clamp(150px, 30vh, 300px) var(--gutter) 40px;
}

.doc .sheet {
  position: relative;
  max-width: 44rem;
}

.doc .sheet::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -40px -64px auto;
  height: 420px;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
  pointer-events: none;
}

.doc h1 {
  font-size: clamp(2.2rem, 1.4rem + 3vw, 3.6rem);
  margin-bottom: 18px;
}

.doc h2 {
  font-size: clamp(1.3rem, 1.1rem + 0.7vw, 1.6rem);
  line-height: 1.25;
  letter-spacing: -0.005em;
  margin: 48px 0 12px;
  max-width: none;
}

.doc p,
.doc li,
.doc dd {
  color: var(--text-2);
  max-width: 38em;
}

.doc p {
  margin: 0 0 16px;
}

.doc .lede {
  color: var(--text-3);
  font-size: 15px;
}

.notice {
  margin: 0 0 40px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-left: 1px solid var(--accent);
  background: rgba(0, 0, 0, 0.55);
  color: var(--text-2);
  font-size: 14.5px;
}

.notice strong {
  color: var(--ink);
  font-weight: 600;
}

dl.faq {
  margin: 0;
}

dl.faq dt {
  margin-top: 28px;
  color: var(--ink);
  font-weight: 500;
}

dl.faq dd {
  margin: 6px 0 0;
}

/* Not-found page: the still fills the screen. */

.lost .backdrop {
  position: fixed;
  height: 100%;
  opacity: 0.9;
  background-image: url("assets/still-level.jpg");
  background-position: 30% 50%;
  -webkit-mask-image: none;
  mask-image: none;
}

@media (max-aspect-ratio: 4/5) {
  .lost .backdrop {
    background-image: url("assets/still-level-tall.jpg");
    background-position: 50% 50%;
  }
}

.lost main {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: 120px;
  padding-bottom: 120px;
}

.lost .sheet {
  width: min(100%, 30rem);
}

.lost .sheet::before {
  inset: -30% -30%;
  height: auto;
}

.lost footer.site {
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.9) 50%);
}

/* Narrower wide screens (4:3 tablets): the pre-order options stay side by
   side and the plan names on one line. */
@media (min-width: 701px) and (max-width: 1199px) and (min-aspect-ratio: 801/1000) {
  /* The plan names stay on one line at 4:3. */
  .plan h3 {
    letter-spacing: 0.2em;
  }

  /* The pre-order options stay side by side, narrow enough to leave the
     close companion star clear on a 4:3 screen. */
  .panel-wide {
    width: min(100%, 28rem);
  }

  .plan {
    padding: 18px 16px 20px;
  }

  .plan .price {
    font-size: 1.25rem;
  }
}

/* Phones, and tablets held upright: the camera puts the hole in the upper
   part of a tall frame, so the text sits low. */

@media (max-width: 700px), (max-aspect-ratio: 4/5) {
  body {
    font-size: 16px;
  }

  header.site {
    padding-top: max(10px, env(safe-area-inset-top));
    padding-bottom: 10px;
  }

  header.site::before {
    height: 112px;
    background: linear-gradient(to bottom, #000 0, rgba(0, 0, 0, 0.96) 54px, rgba(0, 0, 0, 0.62) 76px, rgba(0, 0, 0, 0) 100%);
  }

  /* At least 40% of the screen above the words, so a section whose words
     are too long to sit low (site.js then puts their top at 40%) has the
     previous section off the screen. */
  .scene {
    align-items: flex-end;
    padding-top: max(96px, 40vh);
    padding-top: max(96px, 40svh);
    padding-bottom: max(12vh, 88px);
    padding-bottom: max(12svh, 88px);
  }

  .scene-right {
    justify-content: flex-start;
  }

  .hero {
    align-items: flex-start;
    padding-top: 112px;
    padding-bottom: 120px;
  }

  /* On a tall screen the text spans the width and the label sits at the
     panel's corner, where an oval field is thin. A wide dark band covers
     the whole block instead, label and status lines included, and fades
     out over about 100 px above, below and at the sides, so it reads as
     shade on the picture rather than as a box. */
  .panel::before {
    inset: -100px -90px;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.74) 100px, rgba(0, 0, 0, 0.74) calc(100% - 100px), rgba(0, 0, 0, 0));
    -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0), #000 90px, #000 calc(100% - 90px), rgba(0, 0, 0, 0));
    mask-image: linear-gradient(to right, rgba(0, 0, 0, 0), #000 90px, #000 calc(100% - 90px), rgba(0, 0, 0, 0));
  }

  .rule {
    margin: 20px 0 22px;
  }

  /* Four footer links fit on one line on a phone. */
  footer.site nav {
    gap: 4px 16px;
  }

  footer.site nav a {
    letter-spacing: 0.12em;
  }

  .actions {
    margin-top: 24px;
  }

  .cue {
    top: calc(100vh - 88px);
    top: calc(100svh - 88px);
  }

  .interlude {
    height: 100vh;
    height: 100svh;
  }

  /* No blur in the arrival on a phone: a blur filter on every block over a
     full-screen WebGL canvas costs the frames a scroll needs, and the fade
     and the rise carry the arrival without it. */
  .js .scene .reveal {
    filter: none;
    transition:
      opacity 1.2s var(--ease),
      transform 1.6s var(--ease);
  }

  .plans {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    margin-top: 24px;
  }

  .plan {
    padding: 20px 20px 22px;
  }

  .lost main {
    align-items: flex-end;
    justify-content: flex-start;
  }
}

/* The narrowest phones, and 400% zoom on a laptop: the header still fits
   on one line. */
@media (max-width: 359px) {
  header.site {
    gap: 8px;
  }

  .head-end {
    gap: 8px;
  }

  nav.site {
    gap: 12px;
  }

  nav.site a {
    letter-spacing: 0.14em;
  }

  .motion {
    width: 30px;
    height: 30px;
  }
}

/* For business page (business.html): parts, list and enquiry form. */

.biz-part {
  margin-top: 8px;
}

.biz-part:first-of-type {
  margin-top: 36px;
}

.biz-part + .biz-part {
  margin-top: 44px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

.biz-part h2 {
  margin-top: 36px;
}

.biz-part:first-of-type h2 {
  margin-top: 0;
}

.doc .biz-list {
  margin: 0 0 16px;
  padding: 0 0 0 1.2em;
  max-width: 38em;
}

.doc .biz-list li {
  margin: 0 0 8px;
}

.biz-form {
  margin-top: 28px;
  max-width: 34rem;
}

.biz-form .field {
  margin-bottom: 20px;
}

.biz-form label {
  display: block;
  margin-bottom: 8px;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 500;
}

.biz-form .opt {
  color: var(--text-3);
  font-weight: 400;
}

.biz-form input,
.biz-form select,
.biz-form textarea {
  display: block;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--ink);
  font-family: var(--sans);
  /* 16px keeps iOS from zooming the page when a field is focused. */
  font-size: 16px;
  line-height: 1.4;
  -webkit-appearance: none;
  appearance: none;
}

.biz-form textarea {
  min-height: 9.5rem;
  resize: vertical;
}

.biz-form select {
  padding-right: 40px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

.biz-form select:invalid {
  color: var(--text-3);
}

.biz-form option {
  color: #000;
}

.biz-form input:focus,
.biz-form select:focus,
.biz-form textarea:focus {
  border-color: var(--ink);
}

.biz-form [aria-invalid="true"] {
  border-color: #D9A2A2;
}

.biz-form .hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.doc .form-note {
  margin: 4px 0 0;
  color: var(--text-3);
  font-size: 14px;
}

.doc .form-status {
  min-height: 1.6em;
  margin: 14px 0 0;
  color: var(--ink);
}

.doc .form-status.is-error {
  color: #E8B4B4;
}

.biz-form .actions {
  margin-top: 14px;
}

.biz-form .actions [hidden] {
  display: none;
}

/* Header links: with a third link the header no longer fits on one line on
   a phone, so the link marked nav-extra (still in the footer) is left out
   below 560 px. */
@media (max-width: 559px) {
  nav.site .nav-extra {
    display: none;
  }
}

/* The narrowest phones: the lensed header wordmark steps down so the header
   fits on one line, and on short screens the Scroll cue gives way to the
   hero's status line. */
@media (max-width: 379px) {
  .wordmark svg {
    height: 22px;
  }
}

@media (max-width: 699px) and (max-height: 740px) {
  .hero .cue {
    display: none;
  }
}
