/*
 * Agent Lookout, the landing page.
 *
 * The tokens, the ground and the glass are copied from the app's own
 * stylesheet, src/dashboard/styles/index.css, so the page is made of the same
 * material as the app. Nothing is fetched from another host: the fonts and the
 * pictures are in assets/.
 *
 * The lamp rule holds here too. Amber means a session needs you right now, and
 * nothing else. The page opens with nothing waiting and no warm colour. When
 * the lamp lights, the amber outside the pictures is the tour's, and only
 * while the lamp is lit: the lamp's own light behind the frame, its sparks,
 * the scene's icon and meter, and the ring round what the scene points at.
 * One more amber thing is on the page by choice: the lit mark in the second
 * fact, beside the same mark with its lamp out. That pair is the page's
 * explanation of what amber means.
 */

/* Fonts, bundled. Only the weights the page uses. */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/atkinson-hyperlegible-next-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/atkinson-hyperlegible-next-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/atkinson-hyperlegible-next-latin-600-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/atkinson-hyperlegible-mono-latin-400-normal.woff2") format("woff2");
}

/*
 * What stands in until a font arrives: a local face scaled to the same width
 * and set on the same baseline, so nothing moves when the real one swaps in.
 */
@font-face {
  font-family: "Lookout Fallback";
  font-weight: 400;
  src: local("Helvetica Neue"), local("HelveticaNeue"), local("Arial");
  size-adjust: 97.8%;
  ascent-override: 100.2%;
  descent-override: 32.7%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Lookout Fallback";
  font-weight: 500;
  src: local("Helvetica Neue Medium"), local("HelveticaNeue-Medium"), local("Arial");
  size-adjust: 97.7%;
  ascent-override: 100.3%;
  descent-override: 32.8%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Lookout Fallback";
  font-weight: 600;
  src: local("Helvetica Neue Bold"), local("HelveticaNeue-Bold"), local("Arial Bold");
  size-adjust: 96.9%;
  ascent-override: 101.1%;
  descent-override: 33%;
  line-gap-override: 0%;
}

/* ------------------------------------------------------------------ tokens */

/* What does not change with the theme. */
:root {
  --field-main-width: 1760px;
  --field-main-height: 470px;
  --field-main-right: -420px;
  --field-main-top: -150px;
  --field-main-turn: -13deg;
  --glass-blur: 30px;

  --font-sans: "Atkinson Hyperlegible Next", "Lookout Fallback", system-ui, sans-serif;
  --font-mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --radius-panel: 24px;
  --radius-chrome: 22px;
  --radius-inner: 14px;
  --radius-row: 10px;
  --radius-capsule: 999px;
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  /* The lit picture spreading from the lamp: it blooms, sweeps and settles. */
  --ease-wipe: cubic-bezier(0.4, 0, 0.2, 1);
  /* Springs, for what the tour throws in: one that settles, and one that bounces. */
  --spring: linear(
    0,
    0.109,
    0.346,
    0.606,
    0.827,
    0.982,
    1.071,
    1.106,
    1.104,
    1.082,
    1.054,
    1.028,
    1.008,
    0.995,
    0.989,
    0.988,
    0.99,
    0.993,
    0.996,
    0.998,
    1
  );
  --spring-bouncy: linear(
    0,
    0.13,
    0.412,
    0.714,
    0.954,
    1.102,
    1.163,
    1.158,
    1.118,
    1.067,
    1.022,
    0.991,
    0.975,
    0.972,
    0.977,
    0.985,
    0.994,
    1,
    1.003,
    1.005,
    1
  );
  --expo: cubic-bezier(0.16, 1, 0.3, 1);

  /* The page's own measures. One gap between panels, as in the app. */
  --gap: 16px;
  --gutter: 24px;
  --section: 136px;
  --pad: 28px;

  /*
   * The frame: a screen seated in a bezel of glass. The picture is the app's
   * whole window, whose rail sits 12px in with a 22px corner, so the screen's
   * own corner is 34px at the picture's full size and scales with it. The
   * bezel's corner is that plus its own width. Every corner stays concentric.
   */
  --bezel: 10px;
  --shot-width: 1280;
  /*
   * The window is 1280 by 800. The screen shows its first 784 rows, which end
   * under a whole row of the list whether a session is waiting or not.
   */
  --shot-ratio: 1280 / 784;
  --radius-screen: calc((100cqw - 2 * var(--bezel)) * 34 / var(--shot-width));
  --radius-frame: calc(var(--radius-screen) + var(--bezel));
  /* Where the lamp is in the picture. The lit picture is let in from here. */
  --lamp-at: 10.7% 14.9%;
  /* The count the Dock puts on an app's icon, in the system's own colours, in both lights. */
  --badge: #ff3b30;
  --on-badge: #ffffff;
}

@supports not (animation-timing-function: linear(0, 1)) {
  :root {
    --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --spring-bouncy: cubic-bezier(0.34, 1.56, 0.64, 1);
  }
}

/* Night, the default. */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  --ground-top: #060605;
  --ground: linear-gradient(180deg, #060605 0%, #080706 46%, #0c0b0a 100%);
  --field: 218 214 207;
  --field-deep: 142 137 130;
  --field-strength: 0.16;
  --grain: 0.3;

  /* The lamp's light, and the light that holds the frame when nothing waits. */
  --lamp: 255 166 60;
  --lamp-strength: 0.48;
  --rest: 226 221 213;
  --rest-strength: 0.28;
  /* How much of the lamp's strength reaches the page outside the frame. */
  --halo-strength: 0.8;
  /* The light of the tour's effects when nothing waits, and the shade a spotlight leaves. */
  --beat-rgb: 243 240 234;
  --spot-dim: rgba(6, 6, 5, 0.45);

  --glass-chrome: rgba(11, 10, 9, 0.64);
  /* The header's own glass. Bright things pass behind it, so at Night it is denser. */
  --glass-bar: rgba(11, 10, 9, 0.86);
  --glass-card: rgba(13, 12, 11, 0.66);
  --glass-raised: rgba(25, 23, 21, 0.68);
  --glass-float: rgba(21, 20, 18, 0.88);
  --saturate: 118%;
  --saturate-hero: 185%;

  --rim: linear-gradient(
    205deg,
    rgba(255, 248, 238, 0.36) 0%,
    rgba(255, 248, 238, 0.11) 20%,
    rgba(255, 248, 238, 0.035) 58%,
    rgba(255, 248, 238, 0.09) 100%
  );
  --rim-raised: linear-gradient(
    205deg,
    rgba(255, 248, 238, 0.5) 0%,
    rgba(255, 248, 238, 0.15) 20%,
    rgba(255, 248, 238, 0.05) 58%,
    rgba(255, 248, 238, 0.14) 100%
  );
  --rim-lamp: linear-gradient(
    135deg,
    rgba(255, 184, 96, 0.55) 0%,
    rgba(255, 184, 96, 0.16) 22%,
    rgba(255, 184, 96, 0) 46%
  );
  --rim-rest: linear-gradient(
    135deg,
    rgba(240, 234, 224, 0.34) 0%,
    rgba(240, 234, 224, 0.09) 24%,
    rgba(240, 234, 224, 0) 48%
  );
  --sheen: linear-gradient(
    180deg,
    rgba(255, 248, 238, 0.04),
    rgba(255, 248, 238, 0.007) 120px,
    rgba(255, 248, 238, 0) 240px
  );
  --elev-1:
    0 0 0 1px rgba(0, 0, 0, 0.55), 0 1px 1px rgba(0, 0, 0, 0.35),
    0 14px 34px -18px rgba(0, 0, 0, 0.8);
  --elev-2:
    0 0 0 1px rgba(0, 0, 0, 0.58), 0 1px 1px rgba(0, 0, 0, 0.38),
    0 26px 52px -26px rgba(0, 0, 0, 0.88);
  --elev-3:
    0 0 0 1px rgba(0, 0, 0, 0.62), 0 2px 2px rgba(0, 0, 0, 0.42),
    0 44px 90px -34px rgba(0, 0, 0, 0.95);

  --fill-quiet: rgba(255, 248, 238, 0.055);
  --fill-hover: rgba(255, 248, 238, 0.045);
  --fill-selected: rgba(255, 248, 238, 0.1);
  --control-rim: rgba(255, 248, 238, 0.11);
  --control-top: rgba(255, 248, 238, 0.1);
  --well: rgba(0, 0, 0, 0.3);
  --well-shade: rgba(0, 0, 0, 0.35);
  --thumb: rgba(255, 248, 238, 0.11);
  /* The thumb's edge is what says which choice is made, so it is a firm line. */
  --thumb-edge: rgba(255, 248, 238, 0.42);
  --thumb-drop: rgba(0, 0, 0, 0.35);

  --hairline: rgba(255, 248, 238, 0.085);
  --rule: rgba(255, 248, 238, 0.135);
  --rule-strong: rgba(255, 248, 238, 0.24);

  --ink: #f3f0ea;
  --ink-secondary: #c3beb5;
  --ink-muted: #9e988f;

  /* The lamp. On this page, only in the lit mark of the second fact. */
  --status-needs-you: #ffb547;
  --status-needs-you-edge: #ffb547;

  --status-working: #a9bcd4;
  --status-idle: #948e85;

  --focus: #c3d3e6;

  /*
   * Page only. The one solid button is drawn in ink, the colour of the rest
   * light, because the lamp's amber is not the page's to spend.
   */
  --on-ink: #0c0b0a;
  --solid-top: rgba(255, 255, 255, 0.7);
  --solid-drop: rgba(0, 0, 0, 0.7);
  --solid-hover: #ffffff;
  /* The line that seats a picture in its bezel. */
  --screen-line: 0 0 0 1px rgba(0, 0, 0, 0.62);
  /* The shadow under the Mac app's window on its desktop. */
  --window-drop: 0 22px 60px rgba(0, 0, 0, 0.5);
}

/*
 * Day: the same material in daylight. The block is written twice, once for a
 * system that prefers light and once for the switch, because plain CSS cannot
 * share one set of declarations between a media query and an attribute. Keep
 * the two the same.
 */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    color-scheme: light;

    --ground-top: #d4d0ca;
    --ground: linear-gradient(180deg, #d4d0ca, #ebe9e5);
    --field: 255 255 255;
    --field-deep: 240 235 227;
    --field-strength: 0.72;
    --grain: 0.3;

    --lamp: 255 176 80;
    --lamp-strength: 0.46;
    --rest: 255 255 255;
    --rest-strength: 0.7;
    --halo-strength: 0.7;
    --beat-rgb: 24 22 19;
    --spot-dim: rgba(40, 32, 24, 0.22);

    --glass-chrome: rgba(252, 251, 249, 0.52);
    --glass-bar: rgba(252, 251, 249, 0.52);
    --glass-card: rgba(255, 255, 254, 0.56);
    --glass-raised: rgba(255, 255, 255, 0.66);
    --glass-float: rgba(253, 252, 250, 0.84);
    --saturate: 160%;
    --saturate-hero: 190%;

    --rim: linear-gradient(
      205deg,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 255, 255, 0.62) 20%,
      rgba(255, 255, 255, 0.42) 60%,
      rgba(255, 255, 255, 0.8) 100%
    );
    --rim-raised: linear-gradient(
      205deg,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 255, 255, 0.75) 20%,
      rgba(255, 255, 255, 0.52) 60%,
      rgba(255, 255, 255, 0.9) 100%
    );
    --rim-lamp: linear-gradient(
      135deg,
      rgba(232, 150, 40, 0.55) 0%,
      rgba(232, 150, 40, 0.14) 22%,
      rgba(232, 150, 40, 0) 46%
    );
    --rim-rest: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 40%);
    --sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 96px);
    --elev-1:
      0 0 0 0.5px rgba(38, 32, 26, 0.12), 0 1px 2px rgba(38, 32, 26, 0.06),
      0 14px 30px -18px rgba(38, 32, 26, 0.3);
    --elev-2:
      0 0 0 0.5px rgba(38, 32, 26, 0.12), 0 1px 2px rgba(38, 32, 26, 0.06),
      0 24px 46px -26px rgba(38, 32, 26, 0.36);
    --elev-3:
      0 0 0 0.5px rgba(38, 32, 26, 0.14), 0 2px 3px rgba(38, 32, 26, 0.07),
      0 40px 80px -34px rgba(38, 32, 26, 0.45);

    --fill-quiet: rgba(255, 255, 255, 0.62);
    --fill-hover: rgba(255, 255, 255, 0.55);
    --fill-selected: rgba(255, 255, 255, 0.85);
    --control-rim: rgba(38, 32, 26, 0.13);
    --control-top: rgba(255, 255, 255, 0.9);
    --well: rgba(38, 32, 26, 0.055);
    --well-shade: rgba(38, 32, 26, 0.06);
    --thumb: #ffffff;
    --thumb-edge: rgba(38, 32, 26, 0.7);
    --thumb-drop: rgba(38, 32, 26, 0.3);

    --hairline: rgba(38, 32, 26, 0.08);
    --rule: rgba(38, 32, 26, 0.13);
    --rule-strong: rgba(38, 32, 26, 0.28);

    --ink: #181613;
    --ink-secondary: #3f3b36;
    --ink-muted: #5b564f;

    --status-needs-you: #f4a62a;
    --status-needs-you-edge: #a35a00;

    --status-working: #36577e;
    --status-idle: #6f6961;

    --focus: #36577e;

    --on-ink: #f3f0ea;
    --solid-top: rgba(255, 255, 255, 0.18);
    --solid-drop: rgba(38, 32, 26, 0.5);
    --solid-hover: #2b2823;
    --screen-line: 0 0 0 0.5px rgba(38, 32, 26, 0.2);
    --window-drop: 0 18px 48px rgba(38, 32, 26, 0.22);
  }
}

[data-theme="light"] {
  color-scheme: light;

  --ground-top: #d4d0ca;
  --ground: linear-gradient(180deg, #d4d0ca, #ebe9e5);
  --field: 255 255 255;
  --field-deep: 240 235 227;
  --field-strength: 0.72;
  --grain: 0.3;

  --lamp: 255 176 80;
  --lamp-strength: 0.46;
  --rest: 255 255 255;
  --rest-strength: 0.7;
  --halo-strength: 0.7;
  --beat-rgb: 24 22 19;
  --spot-dim: rgba(40, 32, 24, 0.22);

  --glass-chrome: rgba(252, 251, 249, 0.52);
  --glass-bar: rgba(252, 251, 249, 0.52);
  --glass-card: rgba(255, 255, 254, 0.56);
  --glass-raised: rgba(255, 255, 255, 0.66);
  --glass-float: rgba(253, 252, 250, 0.84);
  --saturate: 160%;
  --saturate-hero: 190%;

  --rim: linear-gradient(
    205deg,
    rgba(255, 255, 255, 1) 0%,
    rgba(255, 255, 255, 0.62) 20%,
    rgba(255, 255, 255, 0.42) 60%,
    rgba(255, 255, 255, 0.8) 100%
  );
  --rim-raised: linear-gradient(
    205deg,
    rgba(255, 255, 255, 1) 0%,
    rgba(255, 255, 255, 0.75) 20%,
    rgba(255, 255, 255, 0.52) 60%,
    rgba(255, 255, 255, 0.9) 100%
  );
  --rim-lamp: linear-gradient(
    135deg,
    rgba(232, 150, 40, 0.55) 0%,
    rgba(232, 150, 40, 0.14) 22%,
    rgba(232, 150, 40, 0) 46%
  );
  --rim-rest: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 40%);
  --sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 96px);
  --elev-1:
    0 0 0 0.5px rgba(38, 32, 26, 0.12), 0 1px 2px rgba(38, 32, 26, 0.06),
    0 14px 30px -18px rgba(38, 32, 26, 0.3);
  --elev-2:
    0 0 0 0.5px rgba(38, 32, 26, 0.12), 0 1px 2px rgba(38, 32, 26, 0.06),
    0 24px 46px -26px rgba(38, 32, 26, 0.36);
  --elev-3:
    0 0 0 0.5px rgba(38, 32, 26, 0.14), 0 2px 3px rgba(38, 32, 26, 0.07),
    0 40px 80px -34px rgba(38, 32, 26, 0.45);

  --fill-quiet: rgba(255, 255, 255, 0.62);
  --fill-hover: rgba(255, 255, 255, 0.55);
  --fill-selected: rgba(255, 255, 255, 0.85);
  --control-rim: rgba(38, 32, 26, 0.13);
  --control-top: rgba(255, 255, 255, 0.9);
  --well: rgba(38, 32, 26, 0.055);
  --well-shade: rgba(38, 32, 26, 0.06);
  --thumb: #ffffff;
  --thumb-edge: rgba(38, 32, 26, 0.7);
  --thumb-drop: rgba(38, 32, 26, 0.3);

  --hairline: rgba(38, 32, 26, 0.08);
  --rule: rgba(38, 32, 26, 0.13);
  --rule-strong: rgba(38, 32, 26, 0.28);

  --ink: #181613;
  --ink-secondary: #3f3b36;
  --ink-muted: #5b564f;

  --status-needs-you: #f4a62a;
  --status-needs-you-edge: #a35a00;

  --status-working: #36577e;
  --status-idle: #6f6961;

  --focus: #36577e;

  --on-ink: #f3f0ea;
  --solid-top: rgba(255, 255, 255, 0.18);
  --solid-drop: rgba(38, 32, 26, 0.5);
  --solid-hover: #2b2823;
  --screen-line: 0 0 0 0.5px rgba(38, 32, 26, 0.2);
  --window-drop: 0 18px 48px rgba(38, 32, 26, 0.22);
}

/* -------------------------------------------------------------------- base */

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

html {
  background-color: var(--ground-top);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/*
 * A link to a place on the page, or the keyboard reaching something under the
 * header, brings it to rest below the header. The header's own controls and
 * the tour's stage stay in view as the page scrolls, so they never move it:
 * a press of Night or Day mid-tour leaves the tour where it is.
 */
main,
main *,
footer * {
  scroll-margin-top: 92px;
}
.tour-stage,
.tour-stage * {
  scroll-margin-top: 0;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
dl,
dd,
figure,
pre {
  margin: 0;
}

/* Three weights and no bold: 400 for running text, 500 for labels, 600 for names. */
h1,
h2,
h3,
h4,
strong {
  font-weight: 600;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
svg {
  display: block;
}

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
}

code,
pre {
  font-family: var(--font-mono);
  letter-spacing: -0.02em;
  word-spacing: -0.22em;
  font-variant-numeric: tabular-nums;
}

/* One focus treatment for everything. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

::selection {
  background-color: color-mix(in srgb, var(--focus) 32%, transparent);
}

.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 50;
  padding: 10px 16px;
  border-radius: var(--radius-capsule);
  background: var(--ink);
  color: var(--on-ink);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus-visible {
  transform: none;
}

.wrap {
  width: min(1200px, 100% - 2 * var(--gutter));
  margin-inline: auto;
}

/* A link in running text: ink, on a line firm enough to say it is a link. */
.link {
  border-radius: 4px;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--ink-muted);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 120ms;
}
.link:hover {
  text-decoration-color: currentColor;
}

/* ------------------------------------------------------------------ ground */

.ground {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background-image: var(--ground);
}

.ground > i {
  position: absolute;
  display: block;
  border-radius: 50%;
}

.ground-main {
  top: var(--field-main-top);
  right: var(--field-main-right);
  width: var(--field-main-width);
  height: var(--field-main-height);
  transform: rotate(var(--field-main-turn));
  background-image: radial-gradient(
    closest-side,
    rgb(var(--field) / var(--field-strength)),
    rgb(var(--field) / calc(var(--field-strength) * 0.4)) 52%,
    transparent 100%
  );
}

.ground-deep {
  top: 520px;
  left: -300px;
  width: 1180px;
  height: 880px;
  background-image: radial-gradient(
    closest-side,
    rgb(var(--field-deep) / calc(var(--field-strength) * 0.85)),
    rgb(var(--field-deep) / calc(var(--field-strength) * 0.3)) 55%,
    transparent 100%
  );
}

.ground-far {
  top: 820px;
  left: 46%;
  width: 900px;
  height: 600px;
  background-image: radial-gradient(
    closest-side,
    rgb(var(--field) / calc(var(--field-strength) * 0.45)),
    transparent 100%
  );
}

/* The dither, so the dark gradients do not band. Not visible as texture. */
.ground::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: var(--grain);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5  0 0 0 0 .5  0 0 0 0 .5  0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* The ground keeps still. What moves on this page is the lamp, the tour and the cards coming in. */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* ------------------------------------------------------------------- glass */

.glass-chrome,
.glass-card,
.glass-raised,
.glass-float {
  position: relative;
  isolation: isolate;
}

.glass-chrome {
  --rim-paint: var(--rim);
  border-radius: var(--radius-chrome);
  background-color: var(--glass-chrome);
  box-shadow: var(--elev-1);
}

.glass-card {
  --rim-paint: var(--rim);
  border-radius: var(--radius-panel);
  background-color: var(--glass-card);
  box-shadow: var(--elev-2);
}

.glass-raised {
  --rim-paint: var(--rim-raised);
  border-radius: var(--radius-panel);
  background-color: var(--glass-raised);
  box-shadow: var(--elev-3);
}

.glass-float {
  --rim-paint: var(--rim-raised);
  border-radius: var(--radius-panel);
  background-color: var(--glass-float);
  box-shadow: var(--elev-3);
}

/* The rim: a 1px edge of light, cut from a gradient by a mask. */
:is(.glass-chrome, .glass-card, .glass-raised, .glass-float)::before,
.frame-lamp {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  padding: 1px;
  border-radius: inherit;
  pointer-events: none;
  background: var(--rim-paint);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
}

/* The sheen, under the top edge, behind the content. */
:is(.glass-chrome, .glass-card, .glass-raised, .glass-float)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background-image: var(--sheen);
}

@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  :is(.glass-chrome, .glass-card, .glass-raised, .glass-float)::before {
    padding: 0;
    background: none;
    -webkit-mask: none;
    mask: none;
    box-shadow:
      inset 0 1px 0 var(--control-top),
      inset 0 0 0 1px var(--rule);
  }
  .frame-lamp {
    display: none;
  }
}

/* Real blur, only where something passes behind the glass. */
.glass-blur {
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--saturate));
}

/* ---------------------------------------------------------------- controls */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 0 22px;
  border: 0;
  border-radius: var(--radius-capsule);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.006em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 120ms,
    color 120ms;
}

/* The one solid button: ink, never amber. */
.btn-solid {
  background-color: var(--ink);
  color: var(--on-ink);
  box-shadow:
    inset 0 1px 0 var(--solid-top),
    0 10px 24px -12px var(--solid-drop);
}
.btn-solid:hover {
  background-color: var(--solid-hover);
}

/* Every other button is quiet: a capsule of fill inside a rim. */
.btn-quiet {
  background-color: var(--fill-quiet);
  color: var(--ink-secondary);
  box-shadow:
    inset 0 0 0 1px var(--control-rim),
    inset 0 1px 0 var(--control-top);
}
.btn-quiet:hover {
  background-color: var(--fill-selected);
  color: var(--ink);
}

.btn-small {
  height: 30px;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 500;
}

/*
 * The segmented switch, as in the app: a recessed well, and a thumb that
 * slides under the choice. It is a pair of radio buttons, so the arrow keys
 * move between the two and Tab passes it in one stop.
 */
.seg {
  position: relative;
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  flex: none;
  padding: 3px;
  border-radius: var(--radius-capsule);
  background-color: var(--well);
  box-shadow:
    inset 0 0 0 1px var(--control-rim),
    inset 0 1px 2px var(--well-shade);
}

/* Each radio lies over its own option, so focus and a reader's cursor land on it. */
.seg input {
  position: absolute;
  top: 3px;
  width: calc(50% - 3px);
  height: calc(100% - 6px);
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.seg input:nth-of-type(1) {
  left: 3px;
}
.seg input:nth-of-type(2) {
  right: 3px;
}

.seg label {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 30px;
  padding-inline: 15px;
  border-radius: var(--radius-capsule);
  color: var(--ink-secondary);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
}
.seg label:has(svg) {
  padding-inline: 12px 14px;
}
.seg label:hover,
.seg input:checked + label {
  color: var(--ink);
}
.seg input:focus-visible + label {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.seg svg {
  flex: none;
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.seg-thumb {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  border-radius: var(--radius-capsule);
  background-color: var(--thumb);
  box-shadow:
    inset 0 0 0 1px var(--thumb-edge),
    inset 0 1px 0 var(--control-top),
    0 2px 6px -2px var(--thumb-drop);
  pointer-events: none;
}
/*
 * The thumb moves by its own width, taken to a whole pixel where the browser
 * can do that: moved by a fraction, its 1px edge would be drawn faint across two.
 */
.seg input:nth-of-type(2):checked ~ .seg-thumb {
  transform: translateX(100%);
  transform: translateX(round(100%, 1px));
}
/* A switch moves only once the page has been drawn. It opens where it belongs. */
.ready .seg label {
  transition: color 120ms;
}
.ready .seg-thumb {
  transition: transform 220ms var(--ease-out);
}

/* The switches need script. Without it the page shows no dead control. */
html:not(.js) .seg {
  display: none;
}

/* The mark: a round lens, a horizon across it, and the lamp above the horizon. */
.lookout {
  flex: none;
  color: var(--ink);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
}
.lookout .sea {
  fill: currentColor;
  stroke: none;
  opacity: 0.13;
}
.lookout .lamp {
  stroke-width: 1.4;
}
.lookout-lit .lamp {
  fill: var(--status-needs-you);
  stroke: var(--status-needs-you-edge);
  stroke-width: 1;
}
.lookout-lit .glint {
  stroke: var(--status-needs-you-edge);
  stroke-width: 1.5;
  stroke-linecap: round;
}

/* ------------------------------------------------------------------ header */

.bar {
  position: sticky;
  top: 12px;
  z-index: 30;
  display: flex;
  align-items: center;
  height: 56px;
  margin-top: 12px;
  padding: 0 10px 0 18px;
  background-color: var(--glass-bar);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: var(--radius-row);
  text-decoration: none;
}

.wordmark {
  font-size: 19px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.015em;
  white-space: nowrap;
}

.bar-rule {
  width: 1px;
  height: 22px;
  margin: 0 18px;
  background-color: var(--rule);
}

.bar-status {
  font-size: 13px;
  line-height: 1.2;
  color: var(--ink-secondary);
  min-width: 0;
  white-space: normal;
}
.bar-status span {
  margin-left: 10px;
  font-size: 12px;
  color: var(--ink-muted);
}

.bar-nav {
  display: flex;
  gap: 4px;
  margin-left: auto;
  margin-right: 12px;
}
.bar-nav a {
  padding: 8px 12px;
  border-radius: var(--radius-capsule);
  font-size: 14px;
  line-height: 1;
  color: var(--ink-secondary);
  text-decoration: none;
  transition:
    color 120ms,
    background-color 120ms;
}
.bar-nav a:hover {
  color: var(--ink);
  background-color: var(--fill-hover);
}

/* -------------------------------------------------------------------- hero */

/*
 * The opening. On the left the one large line, which is the app's own
 * sentence for the state the picture is in. On the right what the thing is.
 * The large line and the last line of the pitch stand on one baseline.
 */
.hero {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gap);
  align-items: end;
  align-items: last baseline;
  padding-top: clamp(36px, 7.2vh, 88px);
}

.state {
  grid-column: 1 / 8;
  margin-left: -0.04em;
  font-size: clamp(44px, 6.4vw, 76px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.035em;
}

/* Its second line never moves. Only the first one turns. */
.state-turn {
  display: grid;
}
.state-turn > span {
  grid-area: 1 / 1;
  justify-self: start;
  white-space: nowrap;
}
.state-still {
  display: block;
}

/* One is gone before the other arrives, so the two never show through each other. */
.when-lit {
  transition: opacity 500ms ease 240ms;
}
.when-out {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 240ms ease,
    visibility 0s 240ms;
}
.lamp-out .when-out {
  opacity: 1;
  visibility: visible;
  transition: opacity 500ms ease 240ms;
}
.lamp-out .when-lit {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 240ms ease,
    visibility 0s 240ms;
}

.pitch {
  grid-column: 8 / 13;
}

/* The page's heading is the sentence that says what the thing is. */
.pitch h1 {
  font-size: 18px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.pitch h1 span {
  color: var(--ink);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 22px;
  margin-top: 24px;
}

.fine {
  margin-top: 16px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-secondary);
  text-wrap: balance;
}

/* -------------------------------------------------------------------- tour */

/*
 * The dashboard, and what it does, played as the page scrolls. The stage
 * stays in view under the header while the page scrolls a stretch for each
 * scene, and then the page carries on. The stretches are there from the first
 * paint, so nothing moves when the dashboard arrives. Without script there
 * are no stretches and no chips: the frame shows its lit picture.
 *
 * The stage is the head (the scene's number and name, its line, the lamp's
 * switch), the frame and the chips. The frame takes whatever height the
 * others leave: every other part has a height of its own, so a line of
 * another length moves nothing.
 *
 * The scroll never looks stuck. A meter in the screen and a bar under the
 * scene's chip fill with every bit of it; entering a scene, the thumb slides
 * to its chip and the number turns; and once the dashboard draws the scene,
 * the frame is punched, swept and ringed, the scene's name is stamped on the
 * screen and flies down to its chip, and the lamp throws sparks as it lights.
 * Each of those is an animation started again by tour.js flipping an
 * attribute between a and b. --beat sets how loud they are: every distance
 * and peak brightness is multiplied by it.
 */
.tour {
  --stage-top: 80px;
  --stage-height: calc(100svh - var(--stage-top) - 12px);
  --stretch: 60svh;
  --scenes: 12;
  --head-height: 52px;
  --line-size: 16px;
  --line-lines: 2;
  --line-height: calc(var(--line-size) * 1.4 * var(--line-lines));
  --nav-height: 68px;
  --row-gap: 14px;
  --frame-room: calc(
    var(--stage-height) - max(var(--head-height), var(--line-height)) - var(--nav-height) - 2 *
      var(--row-gap)
  );
  --beat: 1;
  --way: 1;
  /* How far through the scene the scroll is, 0 to 1, and how many parts the scene has. */
  --p: 0;
  --parts: 1;
  position: relative;
  margin-top: clamp(26px, 4.4vh, 44px);
  overflow-x: clip;
  overflow-clip-margin: var(--gutter);
}
.js .tour {
  height: calc(var(--stage-height) + var(--scenes) * var(--stretch));
}

.tour-stage {
  position: sticky;
  top: var(--stage-top);
  height: var(--stage-height);
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) auto auto auto;
  grid-template-rows: max(var(--head-height), var(--line-height)) auto var(--nav-height);
  grid-template-areas:
    "title line back controls skip"
    "stage stage stage stage stage"
    "nav nav nav nav nav";
  align-content: center;
  column-gap: 20px;
  row-gap: var(--row-gap);
}

/*
 * The head. It sits above the light behind the frame, which would otherwise
 * wash its words out in Day. The number and name are said again, hidden, at
 * the start of the line, which is what a reader hears.
 */
.tour-title,
.tour-line,
.tour-controls,
.tour-back,
.tour-skip {
  position: relative;
  z-index: 3;
  align-self: center;
}
.tour-title {
  grid-area: title;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.tour-count {
  display: flex;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: pre;
}
/* The number turns: the last one leaves the way the page goes, and the next comes in behind it. */
.tour-roll {
  display: inline-grid;
  overflow: hidden;
}
.tour-roll > span {
  grid-area: 1 / 1;
}
.tour-roll > :first-child {
  opacity: 0;
}
.tour-name {
  overflow: hidden;
  font-size: 28px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tour-line {
  grid-area: line;
  max-width: 62ch;
  font-size: var(--line-size);
  line-height: 1.4;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.tour-controls {
  grid-area: controls;
  display: flex;
}
.tour-back {
  grid-area: back;
}
.tour-back[hidden] {
  display: none;
}
.tour-skip {
  grid-area: skip;
  padding-block: 12px;
  font-size: 13px;
  color: var(--ink-secondary);
  white-space: nowrap;
}
.tour-skip-arrow {
  display: none;
}
.tour.is-yours .tour-title {
  visibility: hidden;
}

/* No script, no stretches, no chips and no switch: the page shows its one picture, lit. */
html:not(.js) :is(.tour-title, .tour-line, .tour-controls, .tour-skip, .tour-chapters) {
  display: none;
}

/*
 * The chips: the twelve scenes, numbered, each with its icon, in a recessed
 * well with a thumb under the one on show. They are one stop for the
 * keyboard: the arrow keys move between them, and each takes the page to its
 * scene. Wide, they are one row of twelve, each as wide as its name needs and
 * the rest shared out; narrower or short, a strip that keeps the scene's chip
 * in its middle, between Previous and Next.
 */
.tour-chapters {
  --chip-radius: 14px;
  grid-area: nav;
  position: relative;
  z-index: 1;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 4px;
  border-radius: calc(var(--chip-radius) + 4px);
  background-color: var(--well);
  box-shadow:
    inset 0 0 0 1px var(--control-rim),
    inset 0 1px 2px var(--well-shade);
  transition: opacity 200ms;
}
.tour.is-yours .tour-chapters {
  opacity: 0.55;
}
.tour-chapters ol {
  position: relative;
  z-index: 1;
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(var(--scenes), minmax(max-content, 1fr));
  gap: 4px;
  counter-reset: scene;
}
/* The icon, then the number and, close after it, the part dots; the name under them. */
.tour-chapters li {
  position: relative;
  display: grid;
  grid-template-columns: 24px auto minmax(0, 1fr);
  grid-template-rows: 24px auto;
  align-items: center;
  column-gap: 4px;
  row-gap: 1px;
  height: 60px;
  padding: 4px 8px 0;
  border-radius: var(--chip-radius);
  color: var(--ink-secondary);
  counter-increment: scene;
  translate: calc(var(--lean, 0) * -4px) 0;
  transition:
    color 160ms,
    background-color 120ms,
    translate 200ms var(--ease-out);
}
/* The scene's number, from the list's own count, which a reader does not hear. */
.tour-chapters li::before {
  content: counter(scene, decimal-leading-zero);
  content: counter(scene, decimal-leading-zero) / "";
  grid-area: 1 / 2;
  color: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tour-chapters li:hover {
  background-color: var(--fill-hover);
}
.tour-chapters li:has(> [aria-current]) {
  color: var(--ink);
}
.tour-chapters li:is(:has(> [aria-current]), :has(~ li > [aria-current]))::before {
  color: inherit;
}

/* An icon, 16px of line on a 24px tile, in the chip's own colour. */
.tour-icon {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background-color: var(--fill-quiet);
  box-shadow: inset 0 0 0 1px var(--control-rim);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: color 300ms;
}
.tour-icon .dot {
  fill: currentColor;
  stroke: none;
}
.tour-chapters .tour-icon {
  grid-area: 1 / 1;
}
/* While a session waits, the scene's icon is the lamp's colour. */
:root:not(.lamp-out) .tour-chapters li:has(> [aria-current]) .tour-icon {
  color: var(--status-needs-you-edge);
}

/* The name is the button, and the button covers the whole chip. */
.tour-chapters ol button {
  grid-area: 2 / 1 / 3 / 4;
  align-self: start;
  min-width: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: none;
  color: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.05;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.tour-chapters li:has(> [aria-current]) button {
  font-weight: 600;
}
.tour-chapters ol button::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--chip-radius);
}
.tour-chapters ol button:focus-visible::after {
  outline: 2px solid var(--focus);
  outline-offset: -3px;
}

/* The bar at the chip's foot fills through the scene. A scene passed keeps a faint full one. */
.tour-chapters ol button::before {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 2px;
  height: 2px;
  border-radius: 1px;
  background-color: currentColor;
  opacity: 0;
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.tour-chapters li:has(> [aria-current]) button::before {
  opacity: 1;
  transform: scaleX(var(--p));
}
.tour-chapters li:has(~ li > [aria-current]) button::before {
  opacity: 0.35;
  transform: none;
}

/*
 * A scene of more than one part has a dot for each, and the part on show is
 * the long one. The long one's room is kept while none is on, so a chip keeps
 * its width as the scenes change.
 */
.tour-dots {
  grid-area: 1 / 3;
  justify-self: start;
  display: flex;
  gap: 2px;
  width: 24px;
  margin-left: 4px;
}
.tour-dots:has(> :nth-child(3)) {
  width: 32px;
}
.tour-dots i {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background-color: currentColor;
  opacity: 0.35;
  transition:
    width 420ms var(--spring),
    opacity 200ms;
}
.tour-dots i:has(~ .is-on) {
  opacity: 0.7;
}
.tour-dots .is-on {
  width: 16px;
  opacity: 1;
}

/* As the scroll nears the end of a scene, the next chip leans towards it. */
.tour-chapters li:has(> [aria-current]) + li {
  --lean: clamp(0, (var(--p) - 0.8) * 1000, 1);
}
.tour-chapters li:has(> [aria-current]) + li .tour-icon {
  color: color-mix(in srgb, var(--ink) calc(var(--lean) * 100%), var(--ink-secondary));
}

/* The thumb under the chip on show. It slides once it has been put in place. */
.tour-thumb {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: var(--w, 0);
  height: var(--h, 0);
  border-radius: var(--chip-radius);
  background-color: var(--thumb);
  box-shadow:
    inset 0 0 0 1px var(--thumb-edge),
    inset 0 1px 0 var(--control-top),
    0 2px 6px -2px var(--thumb-drop);
  transform: translate(var(--x, 0), var(--y, 0));
  pointer-events: none;
}
.tour-chapters[data-placed] .tour-thumb {
  transition:
    transform 420ms cubic-bezier(0.34, 1.3, 0.64, 1),
    width 420ms cubic-bezier(0.34, 1.3, 0.64, 1),
    height 420ms cubic-bezier(0.34, 1.3, 0.64, 1);
}

/* Previous and Next are a phone's. */
.tour-prev,
.tour-next {
  display: none;
}

/*
 * The frame is as large as the room the stage leaves it: as wide as the page,
 * or as wide as its height allows, and never a strip wider than 1280 by 560.
 * It lies over the chips, so the scene's name can fly down to its own.
 */
.stage {
  grid-area: stage;
  position: relative;
  z-index: 2;
}
.rig {
  position: relative;
  container-type: inline-size;
  width: min(100%, calc((var(--frame-room) - 2 * var(--bezel)) * 1280 / 560 + 2 * var(--bezel)));
  margin-inline: auto;
}

/*
 * The light behind the frame. It is the app's own recipe for the light behind
 * its top panel: a broad wash with a hotter core, each full at the centre, 35%
 * at 55% and then nothing. Here the core sits on the frame's top edge, over
 * the panel, so the light rises above the frame the way the lamp sits above
 * the horizon in the mark. Every measure is a share of the frame's width.
 *
 * As in the app, the light belongs to the glass. Warm light spilt on bare
 * black reads as a brown haze, so the mask draws nothing left of the frame.
 */
.light {
  position: absolute;
  z-index: 0;
  top: -18.75cqw;
  left: -5cqw;
  width: 75cqw;
  height: 43.75cqw;
  border-radius: 50%;
  pointer-events: none;
  background-image: radial-gradient(
    closest-side,
    rgb(var(--light) / calc(var(--strength) * 0.3)),
    rgb(var(--light) / calc(var(--strength) * 0.09)) 50%,
    transparent 100%
  );
  -webkit-mask-image: linear-gradient(to right, transparent 3.3%, #000 6.67%);
  mask-image: linear-gradient(to right, transparent 3.3%, #000 6.67%);
}
.light::before {
  content: "";
  position: absolute;
  top: 21.4%;
  left: 10.3%;
  width: 62%;
  height: 46%;
  border-radius: 50%;
  background-image: radial-gradient(
    closest-side,
    rgb(var(--light) / var(--strength)),
    rgb(var(--light) / calc(var(--strength) * 0.35)) 55%,
    transparent 100%
  );
}

/*
 * When a wait begins the lamp's light springs up from 85% of its size and
 * fades in over 0.6s. Going out, it only fades.
 */
.light-lamp {
  --light: var(--lamp);
  --strength: calc(var(--lamp-strength) * var(--halo-strength));
  filter: saturate(var(--saturate-hero));
  transition:
    opacity 600ms var(--ease-out),
    transform 600ms var(--spring);
}
.light-rest {
  --light: var(--rest);
  --strength: var(--rest-strength);
  opacity: 0;
  transition: opacity 900ms ease;
}
.lamp-out .light-lamp {
  opacity: 0;
  transform: translate3d(0, 7.5cqw, 0) scale(0.85);
  transition:
    opacity 400ms ease,
    transform 0s 400ms;
}
.lamp-out .light-rest {
  opacity: 1;
}

.frame {
  z-index: 1;
  padding: var(--bezel);
  border-radius: var(--radius-frame);
  --rim-paint: var(--rim-rest), var(--rim-raised);
  /* How far a punch takes the frame in, and then past where it rests. */
  --punch-in: 0.968;
  --punch-out: 1.012;
  transform-origin: 50% 45%;
}

/* The frame's top left edge catching the lamp. */
.frame-lamp {
  --rim-paint: var(--rim-lamp);
  transition: opacity 900ms var(--ease-out);
}
.lamp-out .frame-lamp {
  opacity: 0;
  transition-duration: 400ms;
}

/*
 * A picture seated in glass, as tall as the app's window at this width, or as
 * tall as the stage has room for, whichever is less.
 */
.screen {
  position: relative;
  overflow: hidden;
  /* A width of its own, so a height held by the room left is not passed back to the width. */
  width: 100%;
  max-height: max(160px, calc(var(--frame-room) - 2 * var(--bezel)));
  border-radius: var(--radius-screen);
  background-color: var(--ground-top);
  box-shadow: var(--screen-line);
  aspect-ratio: var(--shot-ratio);
}
/* Its edge takes the page's ring while the keyboard is in the dashboard. */
.frame:has(iframe:focus) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/*
 * A picture is drawn at its own size from the top, and what is taller than
 * its box is cut off the bottom. So the type in the picture keeps its own
 * pixels and stays sharp.
 */
.shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
}

/*
 * The lit picture lies over the quiet one and is let in from the lamp
 * outwards: a circle, centred on the light in the picture, that grows until
 * it covers the screen. So the panel lights first. The circle's edge is kept
 * narrow, so the words of the two pictures never show through each other.
 * Whichever picture is not showing is hidden once that is done, so only one is
 * ever described. Going out, the lit picture only fades.
 */
.shot-lit {
  -webkit-mask: radial-gradient(farthest-corner at var(--lamp-at), #000 56%, transparent 60%)
    var(--lamp-at) / 240% 240% no-repeat;
  mask: radial-gradient(farthest-corner at var(--lamp-at), #000 56%, transparent 60%)
    var(--lamp-at) / 240% 240% no-repeat;
  transition:
    -webkit-mask-size 1000ms var(--ease-wipe),
    mask-size 1000ms var(--ease-wipe);
}
.shot-out {
  visibility: hidden;
  transition: visibility 0s 1000ms;
}
.lamp-out .shot-lit {
  opacity: 0;
  visibility: hidden;
  -webkit-mask-size: 0% 0%;
  mask-size: 0% 0%;
  transition:
    opacity 240ms ease,
    visibility 0s 240ms,
    -webkit-mask-size 0s 240ms,
    mask-size 0s 240ms;
}
.lamp-out .shot-out {
  visibility: visible;
  transition: none;
}

/*
 * A Night or Day choice kept from an earlier visit can differ from the
 * system's. The pictures follow the system until the script has pointed them
 * at the kept choice, so they are held back for that moment.
 */
.unsettled .shot {
  visibility: hidden;
}

/*
 * The dashboard itself, once it has arrived: the app's own window, drawn at
 * its own size and scaled to the screen, over the pictures. It fades in over
 * them once it has drawn its first scene, and from then on the pictures are
 * put away.
 */
.screen iframe {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: var(--tour-width, 1280px);
  height: var(--tour-height, 100%);
  border: 0;
  transform: scale(var(--tour-scale, 1));
  transform-origin: 0 0;
  opacity: 0;
  border-radius: 14px;
  transition:
    opacity 200ms ease,
    transform 420ms var(--ease-out);
}
.tour.is-live .screen iframe {
  opacity: 1;
}
/* On each picture itself, so the lamp's rules above cannot show one again, nor a reader hear it. */
.tour.is-live .shot {
  visibility: hidden;
  transition: visibility 0s 200ms;
}

/*
 * While the page plays the tour, a clear layer lies over the dashboard, so a
 * finger or a wheel always scrolls the page. A tap on it gives the dashboard
 * to the visitor, and the tap lands where it was made.
 */
.tour-cover {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
  touch-action: pan-y pinch-zoom;
  transition: background-color 240ms ease;
}
.tour.is-notifying .tour-cover {
  background-color: color-mix(in srgb, var(--ground-top) 35%, transparent);
}
.tour.is-yours .tour-cover {
  display: none;
}

/*
 * A notification, as the system draws one: floating glass at the screen's
 * top right, under the dashboard's own header, with the app's icon, who sent
 * it and when, and the session's name and what it is waiting for. It springs
 * in from the right edge for the Notification scene, over a dimmed screen,
 * and goes after it.
 */
.tour-banner {
  position: absolute;
  top: calc(var(--tour-scale, 0.92) * 78px);
  right: 12px;
  z-index: 3;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  grid-template-areas:
    "icon head"
    "icon title"
    "icon body";
  column-gap: 11px;
  align-items: start;
  width: min(344px, calc(100% - 24px));
  padding: 11px 14px 12px 12px;
  border-radius: 16px;
  font-size: 13px;
  line-height: 1.35;
  opacity: 0;
  visibility: hidden;
  transform: translate3d(115%, 0, 0) rotate(3deg);
  transition:
    opacity 200ms ease,
    transform 620ms var(--spring-bouncy),
    visibility 0s 620ms;
  pointer-events: none;
}
.tour-banner-icon {
  grid-area: icon;
  width: 34px;
  height: 34px;
  margin-top: 2px;
}
.tour-banner-head {
  grid-area: head;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-secondary);
}
.tour-banner-from {
  font-weight: 600;
}
.tour-banner-when {
  color: var(--ink-muted);
}
.tour-banner-title {
  grid-area: title;
  font-weight: 600;
  color: var(--ink);
}
.tour-banner-body {
  grid-area: body;
  color: var(--ink-secondary);
}
.tour.is-notifying .tour-banner {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

/*
 * Jump, said by the computer: once the tour has pressed it, the dashboard
 * steps back for a moment while the computer says where it went, as the
 * Terminal comes forward.
 */
.tour-switched {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: grid;
  place-items: center;
  background-color: color-mix(in srgb, var(--ground-top) 42%, transparent);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 220ms ease,
    visibility 0s 220ms;
  pointer-events: none;
}
.tour-switched p {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 14px 16px;
  border-radius: 16px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  transform: translate3d(0, 6px, 0) scale(0.96);
  transition: transform 320ms var(--ease-out);
}
.tour-switched svg {
  flex: none;
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tour.is-switched .tour-switched {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
.tour.is-switched .tour-switched p {
  transform: none;
  animation: tour-switch 520ms var(--spring);
}
/* The dashboard steps aside for a moment, as the Terminal comes forward. */
.tour.is-switched .screen iframe {
  animation: tour-shift 360ms ease-in-out;
}

/*
 * The Mac app. The dashboard springs into a window on the desktop, a little
 * smaller, the menu bar drops in over it, and the Dock bounces up under it
 * with the app's own icon, whose count pops on last. The window's size and
 * place are worked out by the tour's script from the screen's.
 */
.tour.is-docked .screen iframe {
  /* 34px under the menu bar, and as tour.js has it, 92px over the foot. */
  transform: translate3d(var(--dock-x, 0px), 34px, 0) scale(var(--dock-scale, 1));
  box-shadow: var(--window-drop);
  transition:
    opacity 200ms ease,
    transform 640ms var(--spring);
}
.tour-dock {
  position: absolute;
  bottom: calc(var(--bezel) + 10px);
  left: 50%;
  z-index: 3;
  opacity: 0;
  visibility: hidden;
  transform: translate3d(-50%, 40px, 0);
  transition:
    opacity 240ms ease,
    transform 380ms var(--ease-out),
    visibility 0s 380ms;
  pointer-events: none;
}
.tour-shelf {
  display: flex;
  padding: 7px 26px 11px;
  border-radius: 22px;
}
.tour-tile {
  position: relative;
  display: block;
}
.tour-tile img {
  display: block;
  width: 56px;
  height: 56px;
}
/* The Dock's mark under an app that is open. */
.tour-tile::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background-color: var(--ink-secondary);
}
.tour-badge {
  position: absolute;
  top: -3px;
  right: -5px;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--radius-capsule);
  background-color: var(--badge);
  color: var(--on-badge);
  font-size: 13px;
  font-weight: 600;
  line-height: 22px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.tour.is-docked .tour-dock {
  opacity: 1;
  visibility: visible;
  transform: translate3d(-50%, 0, 0);
  transition:
    opacity 240ms ease 120ms,
    transform 680ms var(--spring-bouncy) 120ms,
    visibility 0s;
}
.tour.is-docked .tour-badge {
  animation: tour-badge 480ms var(--spring) 520ms both;
}

/*
 * The menu bar across the top of the screen, with the app's item at its right:
 * the lamp lit, as it is while a session needs you, and the count beside it.
 * The lamp is the item's own template image, drawn in the bar's colour.
 */
.tour-menubar {
  position: absolute;
  top: var(--bezel);
  left: var(--bezel);
  right: var(--bezel);
  z-index: 3;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  height: 24px;
  padding: 0 14px;
  border-radius: var(--radius-screen) var(--radius-screen) 0 0;
  background-color: var(--glass-float);
  color: var(--ink);
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, -100%, 0);
  transition:
    opacity 240ms ease,
    transform 380ms var(--ease-out),
    visibility 0s 380ms;
  pointer-events: none;
}
.tour-menubar-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tour-menubar-item svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
.tour-menubar-item .lens {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
}
.tour.is-docked .tour-menubar {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity 240ms ease 60ms,
    transform 520ms var(--spring) 60ms,
    visibility 0s;
}

/*
 * What the scroll does, as it happens. Each effect below is still until
 * tour.js flips its attribute between a and b, which starts its animation
 * again; at rest each is out of sight, so with motion reduced, when no
 * animation runs, none is ever seen. Lit scenes take the lamp's colour.
 */

/*
 * The meter: a line in the foot of the screen that fills through the scene,
 * in a segment for each part, on a band of the ground so it never reads as
 * part of the dashboard under it.
 */
.tour-meter {
  position: absolute;
  left: calc(var(--radius-screen) - 3px);
  right: calc(var(--radius-screen) - 3px);
  bottom: 5px;
  z-index: 2;
  height: 9px;
  border-radius: var(--radius-capsule);
  background-color: color-mix(in srgb, var(--ground-top) 72%, transparent);
  pointer-events: none;
}
.tour-meter i {
  position: absolute;
  inset: 3px;
  overflow: hidden;
  background-color: rgb(var(--beat-rgb) / 0.18);
  -webkit-mask: repeating-linear-gradient(
    to right,
    #000 0 calc((100% + 2px) / var(--parts) - 2px),
    transparent 0 calc((100% + 2px) / var(--parts))
  );
  mask: repeating-linear-gradient(
    to right,
    #000 0 calc((100% + 2px) / var(--parts) - 2px),
    transparent 0 calc((100% + 2px) / var(--parts))
  );
}
.tour-meter i::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--ink-secondary);
  transform: scaleX(var(--p));
  transform-origin: 0 50%;
}
:root:not(.lamp-out) .tour-meter i::after {
  background-color: var(--status-needs-you);
}
.tour.is-yours .tour-meter,
html:not(.js) .tour-meter {
  display: none;
}

/* The punch: the frame is knocked in and springs back past where it rests. A next part only nudges it. */
.frame[data-jolt="pa"] {
  animation: tour-punch-a 520ms;
}
.frame[data-jolt="pb"] {
  animation: tour-punch-b 520ms;
}
.frame[data-jolt="na"] {
  animation: tour-nudge-a 380ms var(--spring);
}
.frame[data-jolt="nb"] {
  animation: tour-nudge-b 380ms var(--spring);
}

/* The flash: a ring of light round the frame, and a glow either side of it. */
.tour-flash {
  --flash: var(--beat-rgb);
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
  box-shadow:
    inset 0 0 0 1.5px rgb(var(--flash)),
    inset 0 0 48px rgb(var(--flash) / 0.5),
    0 0 48px rgb(var(--flash) / 0.55);
  opacity: 0;
  pointer-events: none;
}
:root:not(.lamp-out) .tour-flash {
  --flash: var(--lamp);
}
.tour-flash[data-go="a"] {
  animation: tour-flash-a 700ms linear;
}
.tour-flash[data-go="b"] {
  animation: tour-flash-b 700ms linear;
}

/* The sweep: a band of light with a sharp front crosses the screen, from top left going on and back going back. */
.tour-sweep {
  --sweep-at: calc(50% + 50% * var(--way));
  --sweep-to: calc(50% - 50% * var(--way));
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(
      120deg,
      transparent 36%,
      rgb(var(--beat-rgb) / calc(0.04 * var(--sweep, 1) * var(--beat))) 44%,
      rgb(var(--beat-rgb) / calc(0.18 * var(--sweep, 1) * var(--beat))) 50%,
      transparent 50.4%
    )
    0 0 / 200% 200% no-repeat;
  opacity: 0;
  pointer-events: none;
}
.tour-sweep[data-go="a"] {
  animation: tour-sweep-a 560ms cubic-bezier(0.45, 0, 0.25, 1) 40ms;
}
.tour-sweep[data-go="b"] {
  animation: tour-sweep-b 560ms cubic-bezier(0.45, 0, 0.25, 1) 40ms;
}

/*
 * The stamp: the scene's name and icon pop up low on the screen, under what the
 * scene is about, then fly down to the scene's chip, shrinking as they go.
 * tour.js gives the way to the chip from where it rests.
 */
.tour-stamp {
  position: absolute;
  top: calc(var(--bezel) + (100% - 2 * var(--bezel)) * 0.74);
  left: 50%;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 18px 8px 8px;
  border-radius: var(--radius-capsule);
  background-color: var(--ink);
  color: var(--on-ink);
  box-shadow: 0 16px 36px -14px rgb(0 0 0 / 0.65);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  translate: -50% -50%;
  opacity: 0;
  pointer-events: none;
}
.tour-stamp .tour-icon {
  background-color: color-mix(in srgb, var(--on-ink) 12%, transparent);
  box-shadow: none;
}
.tour-stamp[data-go="a"] {
  animation:
    tour-pop-a 800ms var(--spring-bouncy) 60ms,
    tour-fly-a 800ms ease-in 60ms;
}
.tour-stamp[data-go="b"] {
  animation:
    tour-pop-b 800ms var(--spring-bouncy) 60ms,
    tour-fly-b 800ms ease-in 60ms;
}
.tour.is-yours .tour-stamp,
html:not(.js) .tour-stamp {
  display: none;
}

/* The name and line rise in from the way the page is going, the line a moment after. */
.tour-name[data-go="a"] {
  animation: tour-say-a 380ms var(--expo) both;
}
.tour-name[data-go="b"] {
  animation: tour-say-b 380ms var(--expo) both;
}
.tour-line[data-go="a"] {
  animation: tour-say-a 380ms var(--expo) 70ms both;
}
.tour-line[data-go="b"] {
  animation: tour-say-b 380ms var(--expo) 70ms both;
}

/* Entering a scene, its icon springs up on the thumb, and the number turns. */
.tour-chapters[data-cross="a"] li:has(> [aria-current]) .tour-icon {
  animation: tour-pip-a 480ms var(--spring-bouncy);
}
.tour-chapters[data-cross="b"] li:has(> [aria-current]) .tour-icon {
  animation: tour-pip-b 480ms var(--spring-bouncy);
}
.tour-roll[data-go="a"] > :first-child {
  animation: tour-leave-a 160ms ease-in;
}
.tour-roll[data-go="b"] > :first-child {
  animation: tour-leave-b 160ms ease-in;
}
.tour-roll[data-go="a"] > :last-child {
  animation: tour-come-a 320ms var(--spring);
}
.tour-roll[data-go="b"] > :last-child {
  animation: tour-come-b 320ms var(--spring);
}

/*
 * The spotlight: a ring round what the scene points at or presses, the
 * waiting session's request, Jump or Stop in the lamp's colour and the row
 * for watching resumed in ink, with the rest of the screen dimmed. It lands
 * from larger and glows twice.
 */
.tour-spot {
  --ring: var(--status-needs-you);
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: var(--sw, 0);
  height: var(--sh, 0);
  border-radius: 10px;
  box-shadow:
    0 0 0 2px var(--ring),
    0 0 0 100vmax var(--spot-dim);
  opacity: 0;
  visibility: hidden;
  /* Placed with translate, not transform, so the entrance's scale is about the ring's own middle. */
  translate: var(--sx, 0) var(--sy, 0);
  transition:
    opacity 200ms ease,
    visibility 0s 200ms;
  pointer-events: none;
}
.tour-spot[data-tone="ink"] {
  --ring: var(--ink-secondary);
}
.tour-spot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 16px 4px var(--ring);
  opacity: 0;
}
.tour.is-spotting .tour-spot {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
.tour.is-spotting .tour-spot[data-go="a"] {
  animation: tour-spot-a 520ms var(--spring);
}
.tour.is-spotting .tour-spot[data-go="b"] {
  animation: tour-spot-b 520ms var(--spring);
}
.tour.is-spotting .tour-spot[data-go="a"]::after {
  animation: tour-glow-a 700ms ease-in-out 520ms 2;
}
.tour.is-spotting .tour-spot[data-go="b"]::after {
  animation: tour-glow-b 700ms ease-in-out 520ms 2;
}

/* "Scroll to play", for somebody who has not yet scrolled into the tour. */
.tour-hint {
  position: absolute;
  bottom: 22px;
  left: 50%;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px 8px 16px;
  border-radius: var(--radius-capsule);
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  translate: -50% 0;
  transition:
    opacity 240ms ease,
    visibility 0s 240ms;
  pointer-events: none;
}
.tour-hint svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: tour-bob 1.2s ease-in-out infinite;
}
.tour.is-hinting .tour-hint {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
.tour.is-yours .tour-hint {
  display: none;
}

/*
 * Sparks, over everything, fixed to the window: fourteen out of the lamp as
 * it lights, ten amber and four ink, with a ring that widens behind them;
 * eight out of a notification's icon as it lands; ten out of the Dock's count
 * as it pops; and as the lamp goes out, the amber ones jump and tumble down.
 */
.tour-sparks {
  position: fixed;
  inset: 0;
  z-index: 5;
  overflow: hidden;
  pointer-events: none;
}
.tour-sparks > * {
  position: absolute;
  top: var(--sy);
  left: var(--sx);
  opacity: 0;
}
.tour-sparks i {
  width: 6px;
  height: 6px;
  margin: -3px;
  border-radius: 50%;
  background-color: var(--status-needs-you);
}
.tour-sparks i:nth-child(4n + 2) {
  background-color: var(--ink);
}
.tour-sparks i:nth-child(3n) {
  width: 4px;
  height: 4px;
  margin: -2px;
}
.tour-sparks b {
  width: 24px;
  height: 24px;
  margin: -12px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--status-needs-you);
}
.tour-sparks i:nth-child(1) {
  --a: 0deg;
  --d: 110px;
}
.tour-sparks i:nth-child(2) {
  --a: 26deg;
  --d: 64px;
}
.tour-sparks i:nth-child(3) {
  --a: 51deg;
  --d: 92px;
}
.tour-sparks i:nth-child(4) {
  --a: 77deg;
  --d: 52px;
}
.tour-sparks i:nth-child(5) {
  --a: 103deg;
  --d: 104px;
}
.tour-sparks i:nth-child(6) {
  --a: 129deg;
  --d: 74px;
}
.tour-sparks i:nth-child(7) {
  --a: 154deg;
  --d: 88px;
}
.tour-sparks i:nth-child(8) {
  --a: 180deg;
  --d: 48px;
}
.tour-sparks i:nth-child(9) {
  --a: 206deg;
  --d: 100px;
}
.tour-sparks i:nth-child(10) {
  --a: 231deg;
  --d: 70px;
}
.tour-sparks i:nth-child(11) {
  --a: 257deg;
  --d: 96px;
}
.tour-sparks i:nth-child(12) {
  --a: 283deg;
  --d: 58px;
}
.tour-sparks i:nth-child(13) {
  --a: 309deg;
  --d: 84px;
}
.tour-sparks i:nth-child(14) {
  --a: 334deg;
  --d: 66px;
}
.tour-sparks[data-go="a"] i {
  animation: tour-spark-a 700ms cubic-bezier(0.15, 0.8, 0.3, 1) var(--delay, 0ms);
}
.tour-sparks[data-go="b"] i {
  animation: tour-spark-b 700ms cubic-bezier(0.15, 0.8, 0.3, 1) var(--delay, 0ms);
}
.tour-sparks[data-go="a"] b {
  animation: tour-ring-a 600ms cubic-bezier(0.15, 0.8, 0.3, 1) var(--delay, 0ms);
}
.tour-sparks[data-go="b"] b {
  animation: tour-ring-b 600ms cubic-bezier(0.15, 0.8, 0.3, 1) var(--delay, 0ms);
}
.tour-sparks[data-kind="banner"] {
  --delay: 300ms;
}
.tour-sparks[data-kind="badge"] {
  --delay: 520ms;
}
.tour-sparks[data-kind="banner"] i:nth-child(n + 9),
.tour-sparks[data-kind="badge"] i:nth-child(n + 11),
.tour-sparks[data-kind="out"] b {
  display: none;
}
.tour-sparks[data-kind="out"] i {
  width: 7px;
  height: 3px;
  margin: -1.5px -3.5px;
  border-radius: 1px;
  background-color: var(--status-needs-you);
}
.tour-sparks[data-kind="out"][data-go="a"] i {
  animation: tour-fall-a 1000ms linear;
}
.tour-sparks[data-kind="out"][data-go="b"] i {
  animation: tour-fall-b 1000ms linear;
}

/*
 * The keyframes, each twice, a and b, so a flip starts it again. Every
 * distance and peak brightness is multiplied by --beat.
 */
@keyframes tour-punch-a {
  0% {
    animation-timing-function: cubic-bezier(0.4, 0, 1, 1);
  }
  20% {
    scale: calc(1 - (1 - var(--punch-in)) * var(--beat));
    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
  }
  55% {
    scale: calc(1 + (var(--punch-out) - 1) * var(--beat));
    animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  }
}
@keyframes tour-punch-b {
  0% {
    animation-timing-function: cubic-bezier(0.4, 0, 1, 1);
  }
  20% {
    scale: calc(1 - (1 - var(--punch-in)) * var(--beat));
    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
  }
  55% {
    scale: calc(1 + (var(--punch-out) - 1) * var(--beat));
    animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  }
}
@keyframes tour-nudge-a {
  35% {
    scale: calc(1 - 0.015 * var(--beat));
  }
}
@keyframes tour-nudge-b {
  35% {
    scale: calc(1 - 0.015 * var(--beat));
  }
}
@keyframes tour-flash-a {
  18% {
    opacity: min(1, var(--beat));
  }
}
@keyframes tour-flash-b {
  18% {
    opacity: min(1, var(--beat));
  }
}
@keyframes tour-sweep-a {
  from {
    opacity: 1;
    background-position: var(--sweep-at) var(--sweep-at);
  }
  to {
    opacity: 1;
    background-position: var(--sweep-to) var(--sweep-to);
  }
}
@keyframes tour-sweep-b {
  from {
    opacity: 1;
    background-position: var(--sweep-at) var(--sweep-at);
  }
  to {
    opacity: 1;
    background-position: var(--sweep-to) var(--sweep-to);
  }
}
@keyframes tour-pop-a {
  0% {
    scale: 0.6;
  }
  30%,
  100% {
    scale: 1;
  }
}
@keyframes tour-pop-b {
  0% {
    scale: 0.6;
  }
  30%,
  100% {
    scale: 1;
  }
}
@keyframes tour-fly-a {
  0% {
    opacity: 0;
  }
  6%,
  62% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: translate(var(--fx, 0), var(--fy, 0)) scale(0.3);
  }
}
@keyframes tour-fly-b {
  0% {
    opacity: 0;
  }
  6%,
  62% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: translate(var(--fx, 0), var(--fy, 0)) scale(0.3);
  }
}
@keyframes tour-say-a {
  from {
    opacity: 0;
    translate: 0 calc(var(--way) * 18px * var(--beat));
  }
}
@keyframes tour-say-b {
  from {
    opacity: 0;
    translate: 0 calc(var(--way) * 18px * var(--beat));
  }
}
@keyframes tour-pip-a {
  0% {
    scale: 0.6;
    rotate: -14deg;
    translate: 0 calc(4px * var(--beat));
  }
  45% {
    scale: calc(1 + 0.15 * var(--beat));
  }
}
@keyframes tour-pip-b {
  0% {
    scale: 0.6;
    rotate: -14deg;
    translate: 0 calc(4px * var(--beat));
  }
  45% {
    scale: calc(1 + 0.15 * var(--beat));
  }
}
@keyframes tour-leave-a {
  from {
    opacity: 1;
  }
  to {
    translate: 0 calc(var(--way) * -100%);
  }
}
@keyframes tour-leave-b {
  from {
    opacity: 1;
  }
  to {
    translate: 0 calc(var(--way) * -100%);
  }
}
@keyframes tour-come-a {
  from {
    translate: 0 calc(var(--way) * 100%);
  }
}
@keyframes tour-come-b {
  from {
    translate: 0 calc(var(--way) * 100%);
  }
}
@keyframes tour-spot-a {
  from {
    scale: 1.3;
  }
}
@keyframes tour-spot-b {
  from {
    scale: 1.3;
  }
}
@keyframes tour-glow-a {
  50% {
    opacity: min(0.7, 0.7 * var(--beat));
  }
}
@keyframes tour-glow-b {
  50% {
    opacity: min(0.7, 0.7 * var(--beat));
  }
}
@keyframes tour-spark-a {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    scale: 0.2;
    translate: calc(cos(var(--a)) * var(--d) * var(--beat))
      calc(sin(var(--a)) * var(--d) * var(--beat));
  }
}
@keyframes tour-spark-b {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    scale: 0.2;
    translate: calc(cos(var(--a)) * var(--d) * var(--beat))
      calc(sin(var(--a)) * var(--d) * var(--beat));
  }
}
@keyframes tour-ring-a {
  from {
    opacity: min(1, var(--beat));
  }
  to {
    opacity: 0;
    scale: 6;
  }
}
@keyframes tour-ring-b {
  from {
    opacity: min(1, var(--beat));
  }
  to {
    opacity: 0;
    scale: 6;
  }
}
@keyframes tour-fall-a {
  0% {
    opacity: 1;
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1);
  }
  30% {
    opacity: 1;
    translate: calc(cos(var(--a)) * var(--d) * 0.35 * var(--beat)) calc(-44px * var(--beat));
    animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6);
  }
  100% {
    opacity: 0;
    translate: calc(cos(var(--a)) * var(--d) * 0.7 * var(--beat)) calc(106px * var(--beat));
    rotate: 720deg;
  }
}
@keyframes tour-fall-b {
  0% {
    opacity: 1;
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.4, 1);
  }
  30% {
    opacity: 1;
    translate: calc(cos(var(--a)) * var(--d) * 0.35 * var(--beat)) calc(-44px * var(--beat));
    animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6);
  }
  100% {
    opacity: 0;
    translate: calc(cos(var(--a)) * var(--d) * 0.7 * var(--beat)) calc(106px * var(--beat));
    rotate: 720deg;
  }
}
@keyframes tour-switch {
  from {
    scale: 0.7;
  }
}
@keyframes tour-shift {
  50% {
    translate: calc(-14px * var(--beat)) 0;
  }
}
@keyframes tour-badge {
  0% {
    scale: 0;
  }
  55% {
    scale: calc(1 + 0.35 * var(--beat));
  }
  100% {
    scale: 1;
  }
}
@keyframes tour-bob {
  50% {
    translate: 0 5px;
  }
}

/* ------------------------------------------------------------------- facts */

.facts {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap);
  margin-top: var(--section);
}

.fact {
  display: flex;
  flex-direction: column;
  padding: var(--pad);
}
.fact h3 {
  font-size: 28px;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
.fact p {
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.fact h3 + p {
  max-width: 54ch;
  margin-top: 12px;
}

.fact-finds {
  grid-column: 1 / 8;
}
.fact-shows {
  grid-column: 8 / 13;
}

/* Fact one: the sessions it found, drawn as the app lists them. */
.found {
  margin-top: 26px;
  padding-top: 4px;
  border-top: 1px solid var(--hairline);
}
.group {
  margin: 16px 0 2px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink-secondary);
}
.group span {
  margin-left: 5px;
  font-weight: 500;
  color: var(--ink-muted);
}
.rows li {
  display: grid;
  grid-template-columns: 14px minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 56px;
  column-gap: 14px;
  align-items: center;
  min-height: 40px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-secondary);
}
.rows .name {
  overflow: hidden;
  color: var(--ink);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rows .time {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* The agent and the app are two columns here, and one line on a phone. */
.rows .where {
  display: contents;
}
.mark {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}
.mark path {
  fill: currentColor;
  stroke: none;
}
.mark-working {
  color: var(--status-working);
}
.mark-idle {
  color: var(--status-idle);
}

/*
 * Beside the second fact the card can be taller than its list. The six rows
 * then share the spare height, so no glass is left empty under them.
 */
@media (width >= 901px) {
  .fact-finds .found {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  .fact-finds .rows {
    display: grid;
    grid-auto-rows: minmax(40px, 1fr);
  }
  .fact-finds .rows:nth-of-type(1) {
    flex: 4;
  }
  .fact-finds .rows:nth-of-type(2) {
    flex: 2;
  }
}

/* Fact two: the mark with its lamp out, and lit. The page's one amber. */
.fact-shows code {
  font-size: 14px;
  color: var(--ink);
  white-space: nowrap;
}
.lamp-pair {
  position: relative;
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-content: center;
  margin-top: 26px;
  border-block: 1px solid var(--hairline);
}
.lamp-pair::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background-color: var(--hairline);
}
.lamp-pair > div {
  display: flex;
  flex-direction: column;
  padding: 26px 0;
}
/* Each caption keeps clear of the rule between the two marks. */
.lamp-pair > div:first-child {
  padding-right: 16px;
}
.lamp-pair > div + div {
  padding-left: 24px;
}
.lamp-pair strong {
  margin-top: 16px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.006em;
}
.lamp-pair span {
  margin-top: 3px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-secondary);
  text-wrap: balance;
}
.fact-shows .limit {
  padding-top: 18px;
  font-size: 14px;
}

/* Under the two facts, one slim band: what it sends, which by default is nothing. */
.sends {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 24px 16px 20px;
}
.sends h3 {
  font-size: 17px;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.sends p {
  margin-top: 2px;
  font-size: 14px;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.sends .link {
  white-space: nowrap;
}

/* ---------------------------------------------------- install and the rest */

.split {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gap);
  align-items: start;
  margin-top: var(--section);
}
.split .intro {
  grid-column: 1 / 5;
  padding-right: 24px;
}
.split .body {
  grid-column: 5 / 13;
}

h2 {
  font-size: 34px;
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.intro p {
  margin-top: 14px;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.intro .actions {
  margin-top: 24px;
}

@media (width >= 901px) {
  .intro-sticky {
    position: sticky;
    top: 104px;
  }
}

.steps {
  padding: 6px var(--pad);
}
.steps li {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  column-gap: 16px;
  padding: 24px 0 26px;
}
.steps li + li {
  border-top: 1px solid var(--hairline);
}
.steps .n {
  font-size: 28px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.steps h3 {
  padding-top: 3px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.006em;
}
.steps p {
  margin-top: 4px;
  font-size: 14px;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
/* A flag or a command stays on one line, so --port never breaks after its hyphens. */
.steps p code {
  font-size: 13px;
  color: var(--ink);
  white-space: nowrap;
}
/* A line the app prints is too long for a phone, so it wraps at its spaces. */
.steps p code.printed {
  white-space: normal;
}

/*
 * Commands: literal strings in a recessed well, one to a line. A line too long
 * for a narrow well wraps, and what wraps hangs indented so it still reads as
 * one command.
 */
.steps pre {
  margin-top: 14px;
  padding: 13px 16px;
  border-radius: var(--radius-row);
  background-color: var(--well);
  box-shadow:
    inset 0 0 0 1px var(--control-rim),
    inset 0 1px 2px var(--well-shade);
  color: var(--ink);
  font-size: 13px;
  line-height: 1.7;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.steps pre span {
  display: block;
  padding-left: 1.5em;
  text-indent: -1.5em;
}
/* What a command prints comes after it. */
.steps pre + p {
  margin-top: 12px;
}

/* Positioned, so the card's shadow falls under these words and not over them. */
.after {
  position: relative;
  margin-top: 18px;
  font-size: 14px;
  color: var(--ink-secondary);
  text-wrap: pretty;
}

/*
 * What it does today: four groups of small cards, each a link to its part of
 * the guide. The whole card is the link; its ring is drawn on the card.
 */
.today {
  margin-top: var(--section);
}
.today-head p {
  max-width: 62ch;
  margin-top: 14px;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.today-groups {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 36px var(--gap);
  align-items: start;
  margin-top: 36px;
}
.today-title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 22px;
}
.today-title,
.today-title h3 {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.tag {
  padding: 2px 8px;
  border-radius: var(--radius-capsule);
  background-color: var(--fill-quiet);
  box-shadow: inset 0 0 0 1px var(--control-rim);
  color: var(--ink-secondary);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}
.today-note {
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-muted);
}
.today-cards {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.today-card {
  padding: 16px 18px;
  border-radius: var(--radius-inner);
  transition: background-color 120ms;
}
.today-card:hover {
  background-color: var(--glass-raised);
}
.today-card:has(a:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.today-card h4 {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: -0.006em;
}
.today-card a {
  outline: none;
  text-decoration: none;
}
/* The whole card is the link. */
.today-card a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
}
/* Where it goes, shown under the pointer. */
.today-card h4::after {
  content: "↗";
  content: "↗" / "";
  flex: none;
  color: var(--ink-muted);
  font-weight: 500;
  opacity: 0;
  transition: opacity 120ms;
}
.today-card:hover h4::after {
  opacity: 1;
}
.today-card p {
  margin-top: 4px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-secondary);
  text-wrap: pretty;
}
.today-card code {
  font-size: 13px;
  color: var(--ink);
}
.today-foot {
  max-width: 80ch;
  margin-top: 28px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-muted);
  text-wrap: pretty;
}
.today-foot .link {
  color: var(--ink-secondary);
}

/* The cards rise into place as they come into view, where the browser ties that to the scroll. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .today-card {
      animation: today-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 80%;
    }
  }
  /* On a phone each group is one card, and the card rises whole. */
  @media (prefers-reduced-motion: no-preference) and (width < 761px) {
    .today-card {
      animation: none;
    }
    .today-cards {
      animation: today-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }
  }
}
@keyframes today-in {
  from {
    translate: 0 20px;
    scale: 0.98;
  }
}

/* ------------------------------------------------------------------- close */

.closing {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: var(--section);
  padding: 12px 12px 12px 18px;
}
.closing p {
  margin-right: auto;
  color: var(--ink-secondary);
}
.closing p strong {
  margin-right: 6px;
  color: var(--ink);
  font-weight: 600;
}

.foot {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: 24px 48px;
  padding: 28px 0 64px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-muted);
}
.foot p {
  max-width: 62ch;
}
/*
 * Each link is 44px tall for a finger: its 19.5px line and 12.25px above and
 * below. The row is drawn back by as much, so the words stay where they were.
 * Beside the paragraph the links keep their one row, and the paragraph gives way.
 */
.foot nav {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0 20px;
  margin-block: -12.25px;
}
.foot nav a {
  padding-block: 12.25px;
}
.foot a {
  border-radius: 4px;
  color: var(--ink-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.foot a:hover {
  color: var(--ink);
}
.foot p a {
  text-decoration: underline;
  text-decoration-color: var(--ink-muted);
  text-underline-offset: 3px;
}

/* --------------------------------------------------------- the lost page */

/* The page is as tall as the window and no taller, with its footer at the foot. */
body:has(> .lost) {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
.lost {
  flex: 1;
}
.lost .hero {
  padding-top: clamp(64px, 18vh, 200px);
}

/* --------------------------------------------------------------- narrower */

/* Under 1200px the twelve chips in a row have a little less room inside. */
@media (width < 1200px) {
  .tour-chapters li {
    padding-inline: 6px;
  }
}

/* Under 1128px a little less again, so the twelve names keep to one row down to 1024px. */
@media (width < 1128px) {
  .tour-chapters li {
    padding-inline: 4px;
  }
}

/*
 * Under 1024px, or in a short window, the chips are one strip between
 * Previous and Next, which keeps the scene's chip in its middle; a finger can
 * swipe it too. Each chip is its icon, number, name and dots in a line.
 */
@media (width < 1024px), (height < 520px) {
  .tour {
    --nav-height: 44px;
  }
  .tour-chapters {
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }
  .tour-prev,
  .tour-next {
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background-color: var(--fill-quiet);
    box-shadow:
      inset 0 0 0 1px var(--control-rim),
      inset 0 1px 0 var(--control-top);
    color: var(--ink);
    cursor: pointer;
  }
  .tour-prev svg,
  .tour-next svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .tour-prev[aria-disabled="true"],
  .tour-next[aria-disabled="true"] {
    color: var(--ink-muted);
    opacity: 0.5;
    cursor: default;
  }
  .tour-thumb {
    display: none;
  }
  .tour-chapters ol {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(
      to right,
      transparent,
      #000 24px,
      #000 calc(100% - 24px),
      transparent
    );
    mask-image: linear-gradient(
      to right,
      transparent,
      #000 24px,
      #000 calc(100% - 24px),
      transparent
    );
  }
  .tour-chapters ol::-webkit-scrollbar {
    display: none;
  }
  .tour-chapters li {
    flex: none;
    display: flex;
    align-items: center;
    gap: 6px;
    height: 44px;
    padding: 0 12px 0 10px;
    scroll-snap-align: center;
  }
  .tour-chapters li .tour-icon {
    order: -1;
    width: 22px;
    height: 22px;
  }
  .tour-chapters ol button {
    align-self: center;
    font-size: 13px;
    line-height: 1.2;
  }
  .tour-chapters .tour-dots {
    margin-left: 0;
  }
  /* The chip on show is drawn as the thumb would be. */
  .tour-chapters li:has(> [aria-current]) {
    background-color: var(--thumb);
    box-shadow:
      inset 0 0 0 var(--ring-width, 1px) var(--thumb-edge),
      inset 0 1px 0 var(--control-top);
  }
}

/* Under 1101px the groups of what it does today take two columns. */
@media (width < 1101px) {
  .today-groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bar-status span {
    display: none;
  }

  /*
   * The head is two rows: the number and name beside the switch, and the
   * line under them. The stage keeps to the top, so no band opens over it.
   */
  .tour {
    --head-height: 40px;
    --line-lines: 2;
    --row-gap: 10px;
    --frame-room: calc(
      var(--stage-height) - var(--head-height) - var(--line-height) - var(--nav-height) - 3 *
        var(--row-gap)
    );
  }
  .tour-stage {
    grid-template-columns: minmax(0, 1fr) auto auto auto;
    grid-template-rows: var(--head-height) var(--line-height) auto var(--nav-height);
    grid-template-areas:
      "title back controls skip"
      "line line line line"
      "stage stage stage stage"
      "nav nav nav nav";
    align-content: start;
  }
  .tour-title {
    flex-direction: row;
    align-items: baseline;
    gap: 12px;
  }
  .tour-name {
    font-size: 24px;
  }
  .tour-line {
    align-self: start;
    max-width: none;
  }
}

/*
 * A tablet held upright. Its width holds the frame, so the screen is drawn
 * down to the chips and the dashboard shows that much more of itself. The
 * picture shown before the dashboard arrives keeps its own shape, at the top.
 */
@media (761px <= width < 1101px) and (orientation: portrait) {
  .js .screen {
    aspect-ratio: auto;
    height: calc(var(--frame-room) - 2 * var(--bezel));
  }
  .js .shot {
    object-fit: contain;
  }
}

/* Under 901px everything is one column, in reading order. */
@media (width < 901px) {
  :root {
    --section: 104px;
  }

  .bar-rule,
  .bar-status {
    display: none;
  }

  .hero {
    row-gap: 22px;
  }
  .state,
  .pitch {
    grid-column: 1 / -1;
  }
  .pitch {
    max-width: 560px;
  }

  .fact-finds,
  .fact-shows {
    grid-column: 1 / -1;
  }
  .split .intro,
  .split .body {
    grid-column: 1 / -1;
  }
  .split .intro {
    padding-right: 0;
    margin-bottom: 28px;
  }

  /* The footer's links take one row under its paragraph. */
  .foot {
    flex-direction: column;
  }
}

/*
 * Under 761px: a phone, or a narrow window. What a finger presses is 44px
 * tall.
 */
@media (width < 761px) {
  :root {
    --gutter: 16px;
    --section: 84px;
    --pad: 20px;
    --bezel: 6px;
  }

  .bar {
    padding: 0 6px 0 14px;
  }
  .bar-nav {
    display: none;
  }
  .theme-switch {
    margin-left: auto;
  }
  .seg label {
    height: 38px;
  }

  /* The opening is drawn close, so the frame's first session is on the first screen. */
  .hero {
    row-gap: 18px;
    padding-top: 24px;
  }
  .pitch h1 {
    font-size: 16px;
  }
  .actions {
    margin-top: 20px;
  }
  .actions .link {
    padding-block: 11px;
  }
  .fine {
    margin-top: 12px;
  }

  .fact h3 {
    font-size: 22px;
  }
  h2 {
    font-size: 28px;
  }

  /* A row is two lines: the name, then where it runs. */
  .rows li {
    grid-template-columns: 14px minmax(0, 1fr) auto;
    grid-template-areas:
      "mark name time"
      ".    where time";
    column-gap: 12px;
    padding: 7px 0;
  }
  .rows .mark {
    grid-area: mark;
  }
  /* A long name takes a second line before it is cut. */
  .rows .name {
    grid-area: name;
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .rows .time {
    grid-area: time;
  }
  .rows .where {
    grid-area: where;
    display: flex;
    gap: 6px;
    font-size: 13px;
  }
  .rows .agent::after {
    content: "·";
    margin-left: 6px;
    color: var(--ink-muted);
  }

  .steps {
    padding: 2px var(--pad);
  }
  .steps li {
    grid-template-columns: 26px minmax(0, 1fr);
    column-gap: 12px;
  }
  .steps .n {
    font-size: 22px;
    padding-top: 2px;
  }
  .steps pre {
    padding: 12px 14px;
    font-size: 12px;
  }

  .sends {
    align-items: start;
    gap: 14px;
    padding: 16px 18px 16px 16px;
  }
  .sends svg {
    width: 28px;
    height: 28px;
  }

  /* One column, and each group is one card, its rows split by a hairline. Each row is still a link. */
  .today-groups {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }
  .today-cards {
    --rim-paint: var(--rim);
    position: relative;
    isolation: isolate;
    gap: 0;
    padding-block: 2px;
    border-radius: var(--radius-panel);
    background-color: var(--glass-card);
    box-shadow: var(--elev-2);
  }
  .today-cards::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    padding: 1px;
    border-radius: inherit;
    pointer-events: none;
    background: var(--rim-paint);
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    mask-composite: exclude;
  }
  .today-card {
    padding: 14px 18px;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
  }
  .today-card::before,
  .today-card::after {
    display: none;
  }
  .today-card + .today-card {
    border-top: 1px solid var(--hairline);
  }
  .today-card:first-child {
    border-radius: var(--radius-panel) var(--radius-panel) 0 0;
  }
  .today-card:last-child {
    border-radius: 0 0 var(--radius-panel) var(--radius-panel);
  }
  .today-card:has(a:focus-visible) {
    outline-offset: -2px;
  }

  .closing {
    flex-wrap: wrap;
    padding: 16px;
    row-gap: 14px;
  }
  .closing p {
    flex: 1 1 200px;
  }
  .closing .btn {
    width: 100%;
  }

  .foot {
    padding-bottom: 48px;
  }
  .foot nav {
    gap: 0 4px;
    margin: -6px -10px 0;
  }
  .foot nav a {
    padding-inline: 10px;
  }
}

/*
 * In that same layout the frame shows the app's own one-column layout, as a
 * phone draws it, in place of the wide window, whose type would be too small
 * to read here. Its rail keeps the same 12px inset and 22px corner, so the
 * screen's corner is still 34px at the picture's full size. The frame is
 * never drawn wider than a large phone.
 */
@media (width < 761px) {
  :root {
    --shot-width: 390;
    --shot-ratio: 390 / 844;
    --lamp-at: 28% 13.9%;
  }

  /*
   * On a phone the switch and Skip sit over the frame, and the number and
   * name, the line and the chips' strip under it, all as wide as the frame.
   */
  .tour {
    --stretch: 52svh;
    --controls-height: 44px;
    --head-height: 26px;
    --line-size: 15px;
    --line-lines: 3;
    --line-height: calc(var(--line-size) * 1.42 * var(--line-lines));
    --row-gap: 8px;
    --frame-room: calc(
      var(--stage-height) - var(--controls-height) - var(--head-height) - var(--line-height) -
        var(--nav-height) - 4 * var(--row-gap)
    );
    margin-top: 20px;
  }
  .tour-stage {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows:
      var(--controls-height) auto var(--head-height) var(--line-height)
      var(--nav-height);
    grid-template-areas:
      "controls skip"
      "stage stage"
      "title back"
      "line line"
      "nav nav";
    width: min(100%, 492px);
    margin-inline: auto;
    column-gap: 12px;
  }
  .tour-controls {
    align-self: end;
  }
  .tour-skip {
    align-self: end;
    justify-self: end;
  }
  .tour-skip-rest {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .tour-skip-arrow {
    display: inline;
  }
  .tour-title {
    gap: 8px;
  }
  .tour-name {
    font-size: 20px;
  }
  .tour-line {
    align-self: start;
    line-height: 1.42;
  }

  .tour-banner {
    top: 8px;
    right: 8px;
    width: calc(100% - 16px);
    padding: 10px 12px 11px 10px;
  }
  /* A phone's screen is tall, and what a scene is about reaches lower in it. */
  .tour-stamp {
    top: calc(var(--bezel) + (100% - 2 * var(--bezel)) * 0.88);
  }
  .frame {
    --punch-in: 0.975;
    --punch-out: 1.008;
  }

  /*
   * A phone is not a Mac: the dashboard stays as it is, and the app's icon,
   * with its count, sits under the frame's corner, beside the number and name
   * and as tall as their row, so the line under them keeps its whole width.
   */
  .tour.is-docked .screen iframe {
    transform: scale(var(--tour-scale, 1));
    box-shadow: none;
  }
  .tour-dock {
    --tile: calc(var(--head-height) + var(--row-gap));
    top: calc(100% + var(--row-gap) / 2);
    bottom: auto;
    left: auto;
    right: 6px;
    transform: translate3d(0, 10px, 0);
  }
  .tour.is-docked .tour-dock {
    transform: none;
  }
  .tour-shelf {
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .tour-tile img {
    width: var(--tile);
    height: var(--tile);
  }
  .tour-tile::after {
    display: none;
  }
  .tour-badge {
    top: -5px;
    right: -7px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    font-size: 12px;
    line-height: 18px;
  }
  /* And its menu bar item beside the icon, without the bar. */
  .tour-menubar {
    top: calc(100% + var(--row-gap) / 2);
    left: auto;
    right: calc(var(--head-height) + var(--row-gap) + 18px);
    height: calc(var(--head-height) + var(--row-gap));
    padding: 0;
    border-radius: 0;
    background: none;
    transform: translate3d(0, 10px, 0);
  }
  .tour.is-docked .tour-title {
    padding-right: calc(var(--head-height) + var(--row-gap) + 8px);
  }

  /*
   * The frame is narrow here, so the light is smaller and keeps to the
   * frame's top left, under the rail's own lamp.
   */
  .light {
    top: -20cqw;
    left: -8cqw;
    width: 60cqw;
    height: 44cqw;
    -webkit-mask-image: linear-gradient(to right, transparent 10%, #000 14%);
    mask-image: linear-gradient(to right, transparent 10%, #000 14%);
  }
  .light::before {
    top: 23%;
    left: 14%;
    width: 56%;
    height: 46%;
  }
}

/*
 * A short phone window, as when the browser's bars are showing on a small
 * phone. The opening is drawn closer still and its small line is left out, so
 * the waiting session is on the first screen when the lamp lights. What the
 * small line says is said again further down the page. The lost page has no
 * frame under its opening, and keeps its spacing.
 */
@media (width < 761px) and (height < 640px) {
  .hero:has(+ .tour) {
    row-gap: 12px;
    padding-top: 12px;
  }
  .hero:has(+ .tour) .actions {
    margin-top: 14px;
  }
  .fine {
    display: none;
  }
  /*
   * The tour's rows close up and its words come down a step, so the frame is
   * tall enough to show the waiting session's Deny and Allow over the meter.
   */
  .tour {
    --head-height: 22px;
    --line-size: 14px;
    --line-height: calc(var(--line-size) * 1.36 * var(--line-lines));
    --row-gap: 4px;
    margin-top: 14px;
  }
  .tour-name {
    font-size: 18px;
  }
  .tour-line {
    line-height: 1.36;
  }
}

/*
 * A short window, as a phone held on its side. The switch, the number and
 * name, the line and Skip are a column beside the frame, and the chips' strip
 * runs under the frame. So the frame takes the stage's whole height but that
 * one row, and the chips are always in view.
 */
@media (height < 520px) {
  .tour {
    --side-width: 250px;
    --line-size: 14px;
    --row-gap: 8px;
    --frame-room: calc(var(--stage-height) - var(--nav-height) - var(--row-gap));
  }
  .tour-stage {
    grid-template-columns: fit-content(var(--side-width)) minmax(0, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr) var(--nav-height);
    grid-template-areas:
      "controls stage"
      "title stage"
      "line stage"
      "back stage"
      "skip nav";
    align-content: stretch;
    width: auto;
    margin-inline: 0;
    column-gap: 16px;
  }
  .tour-controls,
  .tour-title,
  .tour-line {
    align-self: start;
  }
  .tour-back {
    align-self: end;
    justify-self: start;
  }
  .tour-skip {
    align-self: center;
    justify-self: start;
  }
  .tour-name {
    font-size: 20px;
  }
  .tour-line {
    line-height: 1.36;
  }
  .screen {
    max-height: calc(var(--frame-room) - 2 * var(--bezel));
  }
}

/*
 * A phone on its side has the chips under its frame, so the app's icon and
 * count sit in the frame's corner.
 */
@media (width < 761px) and (height < 520px) {
  .tour-dock,
  .tour-menubar {
    top: auto;
    bottom: calc(var(--bezel) + 8px);
  }
  .tour-dock {
    --tile: 36px;
    right: calc(var(--bezel) + 10px);
  }
  .tour-menubar {
    right: calc(var(--bezel) + 64px);
    height: 36px;
  }
  .tour.is-docked .tour-title {
    padding-right: 0;
  }
}

/* The theme switch keeps its words while there is room for them. */
@media (width < 400px) {
  .theme-switch label:has(svg) {
    padding-inline: 15px;
  }
  .theme-switch label span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
}

/* The five footer links keep to one row down to 330px. */
@media (width < 370px) {
  .foot nav {
    gap: 0;
    margin-inline: -7px;
  }
  .foot nav a {
    padding-inline: 7px;
  }
}

/*
 * The narrowest window. The wordmark and the large line come down a step, so
 * the header and the line still fit when a reader widens the spacing of text.
 */
@media (width < 360px) {
  .wordmark {
    font-size: 16px;
  }
  .state {
    font-size: 40px;
  }
}

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

  /*
   * Nothing in the tour moves, so each change shows in what is marked: the
   * number and name change, the chip on show is ringed, amber while a session
   * waits, the meter and the chip's bar fill a part at a time, and a still
   * label on the screen names the scene.
   */
  .tour-chapters li {
    translate: none;
  }
  .tour-thumb,
  .tour-chapters li:has(> [aria-current]) {
    --ring-width: 2px;
  }
  .tour-thumb {
    box-shadow:
      inset 0 0 0 2px var(--thumb-edge),
      inset 0 1px 0 var(--control-top);
  }
  :root:not(.lamp-out) .tour-thumb,
  :root:not(.lamp-out) .tour-chapters li:has(> [aria-current]) {
    --thumb-edge: var(--status-needs-you-edge);
  }
  .tour-stamp {
    top: auto;
    bottom: calc(var(--bezel) + 18px);
    left: calc(var(--bezel) + 12px);
    gap: 6px;
    padding: 4px 12px 4px 4px;
    font-size: 13px;
    opacity: 1;
    translate: none;
  }
  .tour-stamp .tour-icon {
    width: 20px;
    height: 20px;
  }
  /*
   * On a phone's small screen it would cover what the scene is about, and the
   * number and name under the frame and the ringed chip say the same, so it is
   * left out.
   */
  @media (width < 761px) {
    .tour-stamp {
      display: none;
    }
  }
}

/*
 * Forced colours. The system paints its own, and drops every shadow and
 * gradient this page draws its edges with. So the ground's dither is put away,
 * each control and card gets a real edge, and the choice made in a switch is
 * ringed.
 */
@media (forced-colors: active) {
  .ground {
    display: none;
  }
  .seg,
  .btn,
  .steps pre,
  .glass-chrome,
  .glass-card,
  .glass-raised,
  .glass-float {
    border: 1px solid ButtonBorder;
  }
  .seg-thumb {
    border: 2px solid Highlight;
  }
  /* The frame's edge goes outside its box, so its picture keeps its size. */
  .frame {
    border: 0;
    outline: 1px solid ButtonBorder;
  }
  /* The scene the tour is on, and how far it has come, in the system's own colours. */
  .tour-chapters li:has(> [aria-current]),
  .tour-chapters li:has(> [aria-current]) .tour-icon,
  :root:not(.lamp-out) .tour-chapters li:has(> [aria-current]) .tour-icon {
    color: Highlight;
  }
  .tour-thumb,
  .tour-chapters li:has(> [aria-current]) {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .tour-prev,
  .tour-next {
    border: 1px solid ButtonBorder;
  }
  .tour-meter i {
    background-color: GrayText;
  }
  .tour-meter i::after,
  :root:not(.lamp-out) .tour-meter i::after,
  .tour-chapters ol button::before {
    background-color: Highlight;
  }
  /* The effects are light and colour, which the system would flatten, so they are left out. */
  .tour-sparks,
  .tour-sweep,
  .tour-flash,
  .tour-stamp {
    display: none;
  }
  .tour-spot {
    box-shadow: none;
    outline: 2px solid Highlight;
  }
  .tour-badge {
    border: 1px solid CanvasText;
  }
  .tour-menubar {
    border-bottom: 1px solid ButtonBorder;
  }
}
