/* SmartHomeQR. One stylesheet for every page. Tokens first, then layout, then the hero object. */

@font-face {
  font-family: "Schibsted Grotesk";
  src: url("fonts/schibsted-grotesk-400-latin.a1b49272.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Schibsted Grotesk";
  src: url("fonts/schibsted-grotesk-700-latin.519f310a.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Colour, sampled from the app (see docs/superpowers/specs/2026-10-16-app-colours-depth-motion.md).
     The app opens in its dark appearance and offers light, so dark is the base set and the light set
     below overrides it when the reader's system is light. */
  color-scheme: dark;
  --ground: #000000;
  --surface-1: #1C1C1E;
  --surface-2: #2C2C2E;
  --ink: #FFFFFF;
  --body: #D1D1D6;
  --muted: #C7C7CC;
  --hairline: rgba(84, 84, 88, 0.65);
  --button-line: rgba(235, 235, 245, 0.3);
  /* The app's tint #007AFF, held at its hue: darkened just enough for white button text to pass
     APCA Lc 75, and lightened for link text on black to pass Lc 60. */
  --accent: #0072F0;
  --on-accent: #FFFFFF;
  --link: #74BAFF;
  /* The app's systemGreen: its scanner frame turns green when it locks on. */
  --status: #30D158;
  --paper: #F5F6F7;
  --print: #0A0B0D;
  /* The hero scene. */
  --device: #1C1C1E;
  --device-edge: #2C2C2E;
  --residue: #26262A;
  --cast: rgba(0, 0, 0, 0.62);
  --drop: rgba(0, 0, 0, 0.55);
  --far-opacity: 0.7;

  /* Type. Fluid values stop growing at 1280 px. */
  --font: "Schibsted Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --fs-fine: 0.875rem;
  --fs-body: clamp(1rem, 0.974rem + 0.11vw, 1.0625rem);
  --fs-lede: clamp(1.125rem, 1.073rem + 0.221vw, 1.25rem);
  --fs-h3: clamp(1.125rem, 1.073rem + 0.221vw, 1.25rem);
  --fs-h2: clamp(1.75rem, 1.439rem + 1.326vw, 2.5rem);
  --fs-h1: clamp(2.125rem, 1.555rem + 2.431vw, 3.5rem);
  --fs-code: clamp(1.375rem, 1.219rem + 0.663vw, 1.75rem);
  --measure-body: 30em;
  --measure-lede: 28em;
  --measure-h1: 12em;

  /* Space, on an 8 px rhythm. */
  --section: clamp(80px, 63.4px + 4.42vw, 120px);
  --hero-top: clamp(32px, 18.7px + 3.54vw, 64px);
  --max-width: 1120px;
  --gutter: clamp(20px, 15px + 1.33vw, 32px);
  --cols: minmax(0, 7fr) minmax(0, 5fr);
  --col-gap: 64px;
  --phone-shot: clamp(240px, 215px + 6.63vw, 300px);
  --radius: 12px;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --ground: #F2F2F7;
    --surface-1: #FFFFFF;
    --surface-2: #E5E5EA;
    --ink: #000000;
    --body: #3C3C43;
    --muted: #636366;
    --hairline: rgba(60, 60, 67, 0.29);
    --button-line: rgba(60, 60, 67, 0.36);
    --link: #0072F0;
    --status: #248A3D;
    --device: #FFFFFF;
    --device-edge: #D1D1D6;
    --residue: #EBEBF0;
    --cast: rgba(0, 0, 0, 0.3);
    --drop: rgba(0, 0, 0, 0.18);
    --far-opacity: 0.8;
  }
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--body);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

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

img,
svg {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: var(--accent);
  color: var(--on-accent);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Hidden by moving it up by its own height, so it never leaves a bar at the top. */
.skip-link {
  position: absolute;
  top: 0;
  left: var(--gutter);
  z-index: 10;
  padding: 12px 16px;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(calc(-100% - 8px));
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  color: var(--on-accent);
}

.wrap {
  width: 100%;
  max-width: calc(var(--max-width) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Header */

.header-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0 16px;
  padding-block: 16px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--ink);
  font-weight: 700;
  font-size: 1.0625rem;
  text-decoration: none;
}

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

.wordmark img {
  width: 28px;
  height: 28px;
  border-radius: 7px;
}

.nav-links {
  display: flex;
  gap: 8px;
}

.nav-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 8px;
  color: var(--body);
  text-decoration: none;
}

.nav-links a:hover {
  color: var(--ink);
}

/* Shared type */

h1 {
  max-width: var(--measure-h1);
  color: var(--ink);
  font-size: var(--fs-h1);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h2 {
  color: var(--ink);
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h3 {
  color: var(--ink);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.3;
}

.lede {
  max-width: var(--measure-lede);
  font-size: var(--fs-lede);
  line-height: 1.45;
  text-wrap: pretty;
}

.fine {
  color: var(--muted);
  font-size: var(--fs-fine);
  line-height: 1.5;
  text-wrap: pretty;
}

/* Buttons say what happens. The only things on the page that answer a pointer with motion. */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 20px;
  border-radius: var(--radius);
  font-weight: 700;
  font-size: var(--fs-body);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}

.button-primary {
  background: var(--accent);
  color: var(--on-accent);
}

.button-secondary {
  border: 1px solid var(--button-line);
  color: var(--ink);
}

.button-secondary:hover {
  border-color: var(--ink);
  color: var(--ink);
}

/* Hero */

.hero {
  padding-top: var(--hero-top);
  overflow-x: clip;
}

.hero-grid {
  display: grid;
  grid-template-columns: var(--cols);
  column-gap: var(--col-gap);
  align-items: center;
}

.hero-copy .lede {
  margin-top: 32px;
}

.hero-copy .actions {
  margin-top: 40px;
}

.hero-copy .fine {
  margin-top: 16px;
}

/* The scene: three planes in one perspective. Far back, the saved codes; in the middle, the Device
   Details screen; in front, the device and the setup code label peeling off it. The script writes
   --p (0 at rest, 1 once the label has settled flat) from the scroll position, and --px and --py
   (-1 to 1) from a mouse pointer. Without the script the scene rests at --p 0, depth intact. */

.scene {
  --p: 0;
  --px: 0;
  --py: 0;
  position: relative;
  width: 100%;
  max-width: 400px;
  margin-left: auto;
  aspect-ratio: 1 / 0.98;
  perspective: 1000px;
  perspective-origin: 56% 44%;
}

/* Every plane pivots on the one point where the label is still stuck to the device. */
.rig {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform-origin: 69.5% 93%;
  transform:
    rotateX(calc((1 - var(--p)) * 5deg - var(--py) * 6deg))
    rotateY(calc((var(--p) - 1) * 12deg + var(--px) * 6deg));
}

.plane-far,
.plane-phone,
.device {
  position: absolute;
}

/* Back plane: the app's All Devices list, quiet. */
.plane-far {
  top: -7%;
  left: 44%;
  width: 54%;
  height: auto;
  aspect-ratio: 300 / 406;
  opacity: var(--far-opacity);
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 55%, transparent 96%);
  transform: translate3d(0, calc(var(--p) * 28px), -170px);
}

.far-card {
  fill: var(--surface-1);
}

.far-heading,
.far-name,
.far-maker {
  fill: var(--ink);
}

.far-heading {
  fill-opacity: 0.4;
}

.far-name {
  fill-opacity: 0.55;
}

.far-maker {
  fill-opacity: 0.28;
}

.far-tile {
  fill: #FFFFFF;
  stroke: var(--hairline);
  stroke-width: 1;
}

.far-qr {
  fill: #000000;
}

.far-chevron {
  fill: none;
  stroke: var(--ink);
  stroke-opacity: 0.3;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.far-rule {
  stroke: var(--hairline);
  stroke-width: 1;
}

/* Middle plane: the saved copy of the label, on the real Device Details screen. */
.plane-phone {
  top: 3%;
  left: 0;
  width: 50%;
  border-radius: 18px;
  box-shadow: 0 0 0 1px var(--hairline), 12px 22px 36px -14px var(--drop);
  transform: translate3d(0, calc(var(--p) * 6px), -50px);
}

/* Front plane: the device, a slab with a face and an edge 14 px behind it. */
.device {
  top: 27%;
  left: 42%;
  width: 55%;
  aspect-ratio: 220 / 282;
  transform-style: preserve-3d;
  transform: translate3d(0, calc(var(--p) * -18px), 30px);
}

.device-face,
.device-edge {
  position: absolute;
  inset: 0;
  border-radius: 14% / 11%;
}

.device-face {
  background: var(--device);
}

/* The device's shadow falls behind it, so it hangs off the back layer. */
.device-edge {
  background: var(--device-edge);
  box-shadow: 10px 16px 30px -12px var(--drop);
  transform: translateZ(-14px);
}

/* The label: a footprint on the device, a strip still stuck to it, and the sheet hinged on the fold
   just below the QR code. The QR code is never bent, so it scans at every scroll position. */
.label {
  position: absolute;
  top: 7.84%;
  left: 10%;
  width: 80%;
  aspect-ratio: 296 / 400;
  transform-style: preserve-3d;
  transform: translateZ(1px);
}

.label-footprint,
.label-cast,
.label-strip,
.label-sheet,
.corners {
  position: absolute;
}

.label-footprint {
  inset: 0;
  border-radius: 12% / 8.9%;
  background: var(--residue);
}

/* The lifted sheet's shadow on the device: it leans away from a light at the upper left, widest at
   the top of the sheet and nothing at the hinge, and shrinks to a contact shadow as the sheet lands. */
.label-cast {
  top: 3%;
  left: 4%;
  width: 92%;
  height: 89%;
  border-radius: 12% / 9%;
  background: var(--cast);
  filter: blur(9px);
  opacity: calc(1 - var(--p) * 0.8);
  transform-origin: 50% 100%;
  transform:
    translateZ(0.2px)
    translate(calc((1 - var(--p)) * 9%), calc((1 - var(--p)) * 3%))
    skewX(calc((1 - var(--p)) * -18deg));
}

.label-strip {
  bottom: 0;
  left: 0;
  width: 100%;
  height: 7.25%;
}

.label-sheet {
  top: 0;
  left: 0;
  width: 100%;
  height: 93%;
  transform-origin: 50% 100%;
  transform: translateZ(0.5px) rotateX(calc((1 - var(--p)) * -42deg));
}

.sticker-paper {
  fill: var(--paper);
  stroke: var(--print);
}

.sticker-line {
  stroke: var(--print);
}

.sticker-ink {
  fill: var(--print);
}

/* The viewfinder, flat on the device around the footprint. It locks, green as in the app, when the
   label lies flat inside it. */
.corners {
  top: -3.5%;
  left: -4.73%;
  width: 109.46%;
  height: 107%;
  overflow: visible;
  pointer-events: none;
  transform: translateZ(1px);
}

.corners path {
  fill: none;
  stroke-width: 4;
  stroke-linecap: round;
}

.corners-idle path {
  stroke: var(--ink);
}

.corners-lock path {
  stroke: var(--status);
}

.corners-lock,
.is-locked .corners-idle {
  opacity: 0;
}

.is-locked .corners-lock {
  opacity: 1;
}

.scan-hint {
  margin-top: 16px;
  margin-left: auto;
  max-width: 400px;
  text-align: right;
  text-wrap: balance;
}

/* The one load sequence: the planes settle back to front, the viewfinder closes on the footprint,
   then the copy arrives. The headline only moves, so it is readable from the first frame. */

@media (prefers-reduced-motion: no-preference) {
  .plane-far {
    animation: far-in 900ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .plane-phone {
    animation: phone-in 800ms 80ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .device {
    animation: device-in 820ms 160ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .label-sheet {
    animation: sheet-land 900ms 200ms cubic-bezier(0.3, 0.6, 0.25, 1) backwards;
  }

  .label-cast {
    animation: fade-in 520ms 480ms ease-out backwards;
  }

  .corners-idle {
    animation: corners-in 520ms 640ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .corners-idle,
  .corners-lock {
    transition: opacity 300ms ease-in-out;
  }

  .hero-copy h1 {
    animation: rise 640ms 120ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .hero-copy .lede {
    animation: appear 560ms 420ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .hero-copy .actions {
    animation: appear 560ms 500ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  .hero-copy .fine {
    animation: appear 560ms 580ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }
}

@keyframes far-in {
  from {
    opacity: 0;
    translate: 0 -18px;
  }
}

@keyframes phone-in {
  from {
    translate: 0 24px;
  }
}

@keyframes device-in {
  from {
    translate: 32px 0;
  }
}

@keyframes sheet-land {
  from {
    rotate: x -40deg;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

@keyframes corners-in {
  from {
    opacity: 0;
    scale: 1.08;
  }
}

@keyframes rise {
  from {
    translate: 0 10px;
  }
}

@keyframes appear {
  from {
    opacity: 0;
    translate: 0 8px;
  }
}

/* Sections */

.section {
  padding-top: var(--section);
}

.section-head .lede {
  margin-top: 16px;
}

.section-head h2,
.section-head .lede {
  max-width: var(--measure-lede);
}

.section-head h2 {
  max-width: 20em;
}

/* Rows and hairlines. Term in the wide column, description in the narrow one, which lines up with
   the hero media above it. */

.rows {
  margin-top: 40px;
}

.row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: var(--col-gap);
  row-gap: 8px;
  padding-block: 24px;
}

/* The hairline is its own layer over a transparent border, so a list can draw it in from the left
   without moving anything. */
.row + .row {
  border-top: 1px solid transparent;
}

.row + .row::before {
  content: "";
  position: absolute;
  top: -1px;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--hairline);
  transform-origin: 0 50%;
}

/* The last row ends on its text, so the gap to the next section is the section token alone. */
.row:last-child {
  padding-bottom: 0;
}

.row dt {
  min-width: 0;
}

.row-term {
  display: block;
  color: var(--ink);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.3;
}

.row dd {
  max-width: var(--measure-body);
  text-wrap: pretty;
}

.code-sample {
  display: block;
  margin-top: 8px;
  color: var(--body);
  font-size: var(--fs-code);
  font-weight: 400;
  line-height: 1.25;
  font-feature-settings: "tnum" 1;
  letter-spacing: 0.01em;
}

.code-sample-long {
  max-width: 20em;
  overflow-wrap: anywhere;
}

.pin {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
}

/* Gallery of real screens, bottoms on one line. */

.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 40px;
  row-gap: 48px;
  margin-top: 48px;
}

.shot {
  display: grid;
  grid-template-rows: auto 1fr;
  align-content: start;
}

.shot-img {
  align-self: end;
  width: auto;
  box-shadow: 0 0 0 1px var(--hairline);
}

.shot-phone {
  height: clamp(320px, 22vw + 120px, 400px);
  border-radius: 20px;
}

.shot-watch {
  height: clamp(180px, 12vw + 70px, 224px);
  border-radius: 32px;
  margin-top: calc(clamp(320px, 22vw + 120px, 400px) - clamp(180px, 12vw + 70px, 224px));
}

.shot figcaption {
  margin-top: 24px;
}

.shot figcaption p {
  margin-top: 8px;
  max-width: var(--measure-body);
}

/* Pricing: the price is set at h1 size, once. */

.pricing-grid {
  display: grid;
  grid-template-columns: var(--cols);
  column-gap: var(--col-gap);
  align-items: start;
}

/* The figure sits in its own clipped line, so it can rise into place. The padding and the equal
   negative margin give its descender room without moving the layout. */
.price-figure {
  display: block;
  padding-bottom: 0.15em;
  margin-bottom: -0.15em;
  font-size: var(--fs-h1);
  line-height: 1.06;
  letter-spacing: -0.02em;
  clip-path: inset(-0.3em -0.3em 0 -0.3em);
}

.price-roll {
  display: inline-block;
}

.price-terms {
  display: block;
  margin-top: 8px;
}

.pricing-lead .actions {
  margin-top: 32px;
}

.rows-stack {
  margin-top: 0;
}

.rows-stack .row {
  grid-template-columns: minmax(0, 1fr);
  padding-block: 16px;
}

.rows-stack .row:first-child {
  padding-top: 8px;
}

.rows-stack .row-term {
  font-size: var(--fs-body);
}

/* Section reveals. Each list arrives once, in its own way. The start states exist only after the
   script has put .motion on the root, which it never does under reduced motion, so without the
   script every section is already in its final state. */

@media (prefers-reduced-motion: no-preference) {
  .button {
    transition: transform 120ms ease-out;
  }

  .button:hover {
    transform: translateY(-1px);
  }

  .button:active {
    transform: scale(0.98);
  }

  /* Where codes are printed: each sample code prints left to right. */
  .motion [data-reveal="print"] .code-sample {
    clip-path: inset(-0.2em 100% -0.2em -0.2em);
    transition: clip-path 560ms cubic-bezier(0.5, 0, 0.2, 1);
  }

  .motion [data-reveal="print"].is-in .code-sample {
    clip-path: inset(-0.2em -0.2em -0.2em -0.2em);
  }

  .motion [data-reveal="print"] .row:nth-child(2) .code-sample {
    transition-delay: 120ms;
  }

  .motion [data-reveal="print"] .row:nth-child(3) .code-sample {
    transition-delay: 240ms;
  }

  /* What it does: each hairline draws in from the left, then its row's words follow. */
  .motion [data-reveal="draw"] .row::before {
    transform: scaleX(0);
    transition: transform 520ms cubic-bezier(0.6, 0, 0.2, 1);
  }

  .motion [data-reveal="draw"] .row > * {
    opacity: 0;
    transition: opacity 420ms ease-out;
  }

  .motion [data-reveal="draw"].is-in .row::before {
    transform: none;
  }

  .motion [data-reveal="draw"].is-in .row > * {
    opacity: 1;
  }

  .motion [data-reveal="draw"] .row:nth-child(2)::before { transition-delay: 70ms; }
  .motion [data-reveal="draw"] .row:nth-child(3)::before { transition-delay: 140ms; }
  .motion [data-reveal="draw"] .row:nth-child(4)::before { transition-delay: 210ms; }
  .motion [data-reveal="draw"] .row:nth-child(5)::before { transition-delay: 280ms; }
  .motion [data-reveal="draw"] .row:nth-child(6)::before { transition-delay: 350ms; }
  .motion [data-reveal="draw"] .row:nth-child(1) > * { transition-delay: 120ms; }
  .motion [data-reveal="draw"] .row:nth-child(2) > * { transition-delay: 220ms; }
  .motion [data-reveal="draw"] .row:nth-child(3) > * { transition-delay: 290ms; }
  .motion [data-reveal="draw"] .row:nth-child(4) > * { transition-delay: 360ms; }
  .motion [data-reveal="draw"] .row:nth-child(5) > * { transition-delay: 430ms; }
  .motion [data-reveal="draw"] .row:nth-child(6) > * { transition-delay: 500ms; }

  /* Platforms: each screen turns from perspective to face the reader. */
  .motion [data-reveal="straighten"] .shot-img {
    opacity: 0;
    transform: perspective(900px) rotateY(-18deg) rotateX(6deg) translateZ(-40px);
    transform-origin: 50% 100%;
    transition:
      transform 760ms cubic-bezier(0.2, 0.7, 0.2, 1),
      opacity 480ms ease-out;
  }

  .motion [data-reveal="straighten"].is-in .shot-img {
    opacity: 1;
    transform: none;
  }

  .motion [data-reveal="straighten"] .shot:nth-child(2) .shot-img {
    transition-delay: 110ms;
  }

  .motion [data-reveal="straighten"] .shot:nth-child(3) .shot-img {
    transition-delay: 220ms;
  }

  /* Pricing: the price rises out of its own line, then the terms. */
  .motion [data-reveal="price"] .price-roll {
    transform: translateY(115%);
    transition: transform 620ms cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  .motion [data-reveal="price"].is-in .price-roll {
    transform: none;
  }

  .motion [data-reveal="price"] .price-terms {
    opacity: 0;
    transition: opacity 480ms 180ms ease-out;
  }

  .motion [data-reveal="price"].is-in .price-terms {
    opacity: 1;
  }
}

/* Footer */

.site-footer {
  margin-top: var(--section);
  border-top: 1px solid var(--hairline);
  padding-block: 48px 64px;
}

.footer-support {
  max-width: var(--measure-lede);
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px 40px;
  margin-top: 32px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 24px;
}

.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--body);
}

.footer-links a:hover {
  color: var(--ink);
}

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.badge {
  display: inline-flex;
  border-radius: 8px;
}

.badge img {
  height: 44px;
  width: auto;
}

.site-footer .fine {
  margin-top: 24px;
  max-width: 48em;
}

.site-footer .fine + .fine {
  margin-top: 8px;
}

/* Legal pages */

.legal {
  padding-top: var(--hero-top);
}

.legal h1 {
  max-width: none;
}

.legal-body {
  max-width: 40em;
}

.legal-body .last-updated {
  margin-top: 16px;
  color: var(--muted);
  font-size: var(--fs-fine);
}

.legal-body .highlight {
  margin-top: 32px;
  padding: 24px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface-1);
}

.legal-body h2 {
  margin-top: 48px;
  font-size: clamp(1.375rem, 1.219rem + 0.663vw, 1.75rem);
}

.legal-body p,
.legal-body ul {
  margin-top: 16px;
}

.legal-body ul {
  padding-left: 1.25em;
  list-style: disc;
}

.legal-body li + li {
  margin-top: 8px;
}

.legal-body strong {
  color: var(--ink);
}

/* Tablet and phone */

@media (max-width: 900px) {
  :root {
    --col-gap: 40px;
  }

  .hero-grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 48px;
  }

  .hero-media {
    width: min(100%, 440px);
  }

  .scene {
    margin-left: 0;
  }

  .scan-hint {
    display: none;
  }

  .pricing-grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 40px;
  }
}

@media (max-width: 700px) {
  .row {
    grid-template-columns: minmax(0, 1fr);
  }

  .gallery {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 40px;
  }

  .shot {
    grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
    grid-template-rows: auto;
    column-gap: 20px;
    align-items: start;
  }

  .shot-img,
  .shot-phone,
  .shot-watch {
    align-self: start;
    width: 100%;
    height: auto;
    margin-top: 0;
  }

  .shot-phone {
    border-radius: 14px;
  }

  .shot-watch {
    border-radius: 24px;
  }

  .shot figcaption {
    margin-top: 0;
  }
}

@media (max-width: 480px) {
  .nav-links {
    gap: 0;
  }

  .actions .button {
    flex: 1 1 100%;
  }
}
