.hero.product {
  .pill::before {
    width: 12px;
    height: 12px;
    transform: none;
    mask: url("../img/interadmin-solo.svg") center / contain no-repeat;
  }

  /* A logo, so the nameplate's teal, not daylight's darker ink accent. Not nested in ::before: & cannot
     stand for a pseudo-element, so a rule inside one matches nothing. */
  :root[data-theme="light"] & .pill::before {
    background: #00a3a3;
  }

  /* The headline runs longer than the home's, so it sets smaller to keep within the copy's column. */
  h1 {
    font-size: max(40px, 60 * var(--hero-unit));
    text-wrap: balance;

    /* Kept whole, or a phone strands "contínua" on its own line; balance then stops "em" being left alone. */
    .emphasis {
      white-space: nowrap;
    }

    @media (min-width: 900px) {
      max-width: min(11.67em, 50vw);
    }

    /* Sized to the column, so a phone breaks it in four at any width: 9.7em holds the widest line,
       "evolving continuously" (9.54em; the Portuguese "conteúdo da JP7, em" is 9.05em). */
    @media (max-width: 899px) {
      font-size: min(56px, (100vw - 2 * var(--gutter)) / 9.7);
    }
  }

  /* A mouse drag on the scene turns the screen (screens-scene.js). The copy's box spans the hero over
     the scene, so only what is in it takes the pointer, and a press beside it reaches the scene. */
  .hero-copy {
    pointer-events: none;

    > * {
      pointer-events: auto;
    }
  }

  @media (hover: hover) and (pointer: fine) {
    .hero-scene[data-scene="screens"] {
      cursor: grab;

      &.is-orbiting {
        cursor: grabbing;
      }
    }
  }

  /* The screens' chapter buttons, which screens-scene.js turns onto the strip it draws under the
     screen: unseen, there for the pointer and the keyboard, the strip showing what they would. */
  .hero-chapters {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    transform-origin: 0 0;
    opacity: 0;

    ul {
      display: grid;
      grid-auto-flow: column;
      grid-auto-columns: 1fr;
      height: 100%;
    }

    button {
      width: 100%;
      height: 100%;
      border: 0;
      background: none;
      cursor: pointer;
    }
  }

  /* On phones the keys stand between the screen and the copy, so the copy steps down to clear them. */
  @media (max-width: 899px) {
    &:has(.hero-chapters) .hero-copy {
      margin-top: var(--space-56);
    }

    /* The screens fit above the copy rather than in the frame, so the copy's shade starts where
       screens-scene.js says they end; in frame widths it fell across the intro's name. */
    .hero-scene[data-scene="screens"]::after {
      background: linear-gradient(transparent var(--art-bottom), color-mix(in srgb, var(--bg) 86%, transparent) calc(var(--art-bottom) + 48px));
    }
  }
}

.section-head h2 {
  text-wrap: balance;
}

.features {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-20);

  /* The drawing stands on a stage across the card's top, so it reads apart from its caption; the
     stage is a box on the drawing's grid row, so it takes each drawing's height. It is lighter than
     the card, not darker: the VFD windows are near-black recesses, and on a darker stage they sank
     into it. */
  & li:not(.slider) {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    row-gap: var(--space-12);
    padding: var(--space-12) var(--space-12) var(--space-28);
    border: 1px solid var(--line);
    border-radius: var(--radius-panel);
    background: var(--surface);
    /* Set in a shallow groove: the keys' well, at half its depth. */
    box-shadow:
      0 0 0 2px rgb(from var(--bg) calc(r - 7) calc(g - 9) calc(b - 10)),
      0 -1px 0 2px rgba(0, 0, 0, 0.3),
      0 1px 0 2px rgba(255, 255, 255, 0.04);

    &.wide {
      grid-column: span 2;
    }

    &::before {
      content: "";
      grid-area: 1 / 1;
      margin: calc(-1 * var(--space-12)) calc(-1 * var(--space-12)) calc(-1 * var(--space-28));
      border-bottom: 1px solid var(--line);
      border-radius: calc(var(--radius-panel) - 1px) calc(var(--radius-panel) - 1px) 0 0;
      background: color-mix(in srgb, var(--surface), white 4%);
    }

    & > .mockup {
      grid-area: 1 / 1;
    }

    & > h3,
    & > p {
      padding-inline: var(--space-16);
    }

    & > h3 {
      grid-area: 2 / 1;
    }

    & > p {
      grid-area: 3 / 1;
    }
  }

  h3 {
    margin-top: var(--space-36);
    font-size: var(--font-size-20);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.3px;
    text-wrap: balance;
  }

  & li > p {
    max-width: 560px;
    color: var(--muted);
  }

  /* Six cards are slides on a phone; wider, their wrappers step aside and they are grid cells. */
  .slider,
  .slides {
    display: contents;
  }

  .slide-keys {
    display: none;
  }

  @media (max-width: 1099px) {
    grid-template-columns: repeat(2, minmax(0, 1fr));

    & .slides > li.wide {
      grid-column: span 2;
    }

    & > li.wide:last-child {
      grid-column: auto;
    }
  }

  /* On a phone the cards stand 20 px apart and 20 px from the page's edge, so their content keeps that
     from their own edge on all four sides: the drawing by its box, the caption by its letters, whose
     line height already adds the rest. */
  @media (max-width: 699px) {
    grid-template-columns: minmax(0, 1fr);

    & li:not(.slider) {
      padding-bottom: var(--space-16);

      &::before {
        margin-bottom: calc(-1 * var(--space-20));
      }
    }

    & .slides > li.wide {
      grid-column: auto;
    }

    /* The tenants' tree needs every pixel, so its card runs to the screen's edges, a band across
       the page; its 12 + 8 px inset then lands its content on the page's 20 px gutter. */
    & > li.wide:last-child {
      margin-inline: calc(-1 * var(--gutter));
      border-inline: 0;
      border-radius: 0;

      &::before {
        border-radius: 0;
      }
    }

    & li:not(.slider) > .mockup {
      margin-top: calc(-1 * var(--space-8));
      margin-inline: var(--space-8);
    }

    & li:not(.slider) > h3,
    & li:not(.slider) > p {
      padding-inline: var(--space-8);
    }

    /* The slides run to the screen's edges, so the next one shows past the gutter as the cue to
       swipe; each snaps to the gutter, one per swipe. Grid rows keep the four as tall as the tallest. */
    .slider {
      display: grid;
      row-gap: var(--space-16);
      margin-inline: calc(-1 * var(--gutter));
    }

    .slides {
      display: grid;
      grid-auto-flow: column;
      grid-auto-columns: calc(100% - var(--space-28));
      gap: var(--space-20);
      padding-inline: var(--gutter);
      scroll-padding-inline: var(--gutter);
      overflow-x: auto;
      overscroll-behavior-x: contain;
      scroll-snap-type: x mandatory;
      scrollbar-width: none;

      &::-webkit-scrollbar {
        display: none;
      }

      & > li {
        scroll-snap-align: start;
        scroll-snap-stop: always;
      }
    }

    /* A round key per slide, the footer's in its own well, its ring lit for the slide in view
       (site.js). Spaced as the footer's, a third of a key apart, six keys and their 2 px wells
       fill the gutters: 6 + 5/3 = 23/3 keys across, so 36 px on a 320 px phone, up to 40 px. */
    .slide-keys {
      --button: min(40px, round(down, (100vw - 2 * var(--gutter) - 4px) * 3 / 23, 1px));
      display: flex;
      justify-content: center;
      gap: round(var(--button) / 3, 1px);

      button {
        cursor: pointer;
      }
    }

    h3 {
      margin-top: var(--space-24);
    }
  }
}

/* The cards' icons, drawn by <use>. `hidden` does not reach an <svg>, which renders 150 px tall. */
.sprite {
  display: none;
}

/* A feature drawn in the site's own terms rather than a screenshot. Its colours repeat the hero
   screens' palette in interadmin/svg.js, so the cards and the hero read as one set. Every card's
   ink spans the same band, 16 px down to its 216 px bottom. */
.mockup {
  --row: rgb(from var(--bg) calc(r + 8) calc(g + 13) calc(b + 13));
  --row-edge: rgb(from var(--bg) calc(r + 20) calc(g + 27) calc(b + 28));
  --raised: rgb(from var(--bg) calc(r + 5) calc(g + 9) calc(b + 9));
  --well: rgb(from var(--bg) calc(r - 1) calc(g - 1) calc(b - 2));
  --well-edge: rgb(from var(--bg) calc(r + 29) calc(g + 38) calc(b + 40));
  --wire: rgb(from var(--bg) calc(r + 30) calc(g + 39) calc(b + 40));
  /* A 1 px wire through the middle of a box. Every horizontal wire is drawn this way, as a
     background of a box the row's full height, because a background snaps to the pixel grid as a
     1 px box at top: 50% does not, so on a fractional row the two land half a pixel apart. */
  --wire-across: linear-gradient(var(--wire), var(--wire)) center / 100% 1px no-repeat;
  --recede: rgb(from var(--bg) calc(r + 40) calc(g + 48) calc(b + 48));
  --window: var(--display-base);
  --window-edge: rgb(from var(--bg) calc(r + 11) calc(g + 22) calc(b + 22));
  --window-bezel:
    inset 0 0 8px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px var(--window-edge),
    0 0 0 1.5px rgb(from var(--bg) calc(r - 6) calc(g - 8) calc(b - 9)),
    0 -1px 0 1.5px rgba(0, 0, 0, 0.5),
    0 1px 0 1.5px rgba(255, 255, 255, 0.06);
  display: flex;
  flex-direction: column;
  height: 216px;
  margin-inline: var(--space-16);
  padding-top: var(--space-16);
  font-size: var(--font-size-13);
  font-weight: 500;
  line-height: 20px;
  color: var(--text);

  /* In daylight a window is a hole in the plate onto the readouts' LCD, edged with the keys' bevel.
     The bevel is drawn inward, by a ring on ::before, so a window keeps dark's box and its text
     dark's place; the shadows only shade the glass inside it. */
  :root[data-theme="light"] & {
    --ink-dim: color-mix(in srgb, var(--lcd-ink) 55%, transparent);
    --ink-ghost: color-mix(in srgb, var(--lcd-ink) 16%, transparent);
    /* The home page's hairline; lifted off the plate as dark's is, the wire read white. */
    --wire: var(--line-strong);
    --window: var(--display-field);
    --window-edge: var(--ink-ghost);
    --window-ring:
      inset 0 0 0 calc(var(--key-bevel) + 1px) rgba(10, 16, 14, 0.4),
      inset 0 calc(var(--key-bevel) + 3px) 3px -1px rgba(20, 30, 28, 0.28);
    --window-bezel: var(--window-ring), inset 0 0 5px calc(var(--key-bevel) + 1px) rgba(90, 225, 210, 0.22);
    /* A window whose switch is off loses its backlight and dims, but a reflective LCD still reads.
       The dimming is a shadow too, so the switch can fade from one to the other. */
    --window-bezel-unlit: var(--window-ring), inset 0 0 0 100vmax rgba(20, 30, 26, 0.08);
    /* A graphic LCD's square pixels, as Doto's are, for what a window draws rather than writes.
       Doto's own pitch at 13 px is 1.3 px, too fine to read; 3 px is the tour screens' grid. Each
       pixel is the top-right of its cell, so a box anchored at its bottom-left starts on ink. A gap
       lets half the ink through, or a picture reads as a screen door. */
    --pixel: 3px;
    --lcd-grid:
      linear-gradient(90deg, #000 calc(var(--pixel) - 1px), rgba(0, 0, 0, 0.55) 0) 0 100% / var(--pixel) var(--pixel),
      linear-gradient(rgba(0, 0, 0, 0.55) 1px, #000 0) 0 100% / var(--pixel) var(--pixel);
  }

  /* A monochrome LCD: everything a window shows is its one ink, in Doto's dots. Grey phosphor is
     ink half pressed, a lit state full ink, an unused segment a ghost. Doto's advance at 13 px is
     Geist Mono's, so no window changes width. */
  :root[data-theme="light"] & :is(.chip, .field, .upload, .screen) {
    --text: var(--lcd-ink);
    --text-soft: var(--lcd-ink);
    --muted: var(--ink-dim);
    --faint: var(--ink-dim);
    --accent: var(--lcd-ink);
    --action: var(--lcd-ink);
    --wire: var(--ink-ghost);
    font-family: "Doto", var(--mono);
    font-weight: 900;
  }

  b {
    font-weight: 500;
  }

  i {
    font-style: normal;
  }

  /* A 24-unit icon from the page's sprite, its stroke 1.25 px at any --size. */
  .glyph {
    --size: 16;
    flex: none;
    width: calc(var(--size) * 1px);
    height: calc(var(--size) * 1px);
    fill: none;
    stroke: currentColor;
    stroke-width: calc(30 / var(--size));
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* A small VFD window: the readout's bezel scaled down and its glass laid over the text, without
     the dot field. Grey is a dim white phosphor with a tight glow, since a wide grey glow reads as
     blur; a state is lit in its colour with the page's --emit, so ?glow= reaches it too. The form
     fields, the upload and the audience chart take a window too. */
  .chip,
  &.sign-in .field,
  &.assistant .field,
  &.files .upload,
  &.audience .screen {
    --phosphor: var(--muted);
    --phosphor-glow:
      0 0 1px color-mix(in srgb, var(--phosphor) 45%, transparent),
      0 0 3px color-mix(in srgb, var(--phosphor) 25%, transparent);
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding-inline: 10px;
    border-radius: 6px;
    background:
      radial-gradient(closest-side, color-mix(in srgb, var(--phosphor) 10%, transparent), transparent),
      var(--window);
    box-shadow: var(--window-bezel);
    font-family: var(--mono);
    font-weight: 400;
    line-height: 1;
    color: var(--phosphor);
    text-shadow: var(--phosphor-glow);

    &::after {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      background: var(--display-glass);
      /* Its wires are 6 px apart, two to a 13 px letter, so at full strength they cut the glyphs. */
      opacity: 0.4;
    }

    .glyph {
      --size: 14;
      color: var(--phosphor);
      filter: drop-shadow(0 0 2px color-mix(in srgb, var(--phosphor) 35%, transparent));
    }

    &.bright {
      --phosphor: var(--accent);
      --phosphor-glow: var(--emit);
    }

    &.action {
      --phosphor: var(--action);
      --phosphor-glow: var(--emit-action);
    }

    /* Powers on as it comes into view, as the home's displays do: what it shows stutters while
       the filament warms (lamp-on, in site.css) and the glass stays. Under reduced motion it is
       simply on. */
    &[data-power] > * {
      animation: lamp-on 0.6s steps(1, end) var(--jitter, 0ms) both;
    }

    &[data-power="off"] > * {
      animation-play-state: paused;
    }

    /* In daylight each segment casts its shadow on the reflector where it glowed, and the window
       darkens in rather than flickering on. The shadow is half the readouts' --lcd-shadow, in
       scale with 13 px text; the full offset read as a second copy of each glyph. */
    :root[data-theme="light"] & {
      --window-shadow: 0.75px 1px 0 rgba(28, 40, 32, 0.2);
      --emit: var(--window-shadow);
      --emit-box: var(--window-shadow);
      --emit-action: var(--window-shadow);
      /* A half-pressed segment casts a lighter shadow; the full one made it read doubled. */
      --phosphor-glow: 0.75px 1px 0 color-mix(in srgb, var(--phosphor) 20%, transparent);
      background: var(--window);
      transition: box-shadow 0.4s;

      &::before {
        content: "";
        position: absolute;
        inset: 0;
        border: var(--key-bevel) solid transparent;
        border-radius: inherit;
        pointer-events: none;
        background: var(--key-bevel-face);
        mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
      }

      .glyph {
        filter: drop-shadow(var(--window-shadow));
      }

      &[data-power] > * {
        animation-name: lcd-dot-on;
      }
    }
  }

  /* In daylight a key's well stands past its cap by the 2 px gap and the bevel, and by the 1 px
     travel too below (site.css .button; its inset's 1 px is the cap's border). A window beside a
     key reaches as far, padded back by as much, so its text and its place stay dark's. */
  :root[data-theme="light"] & {
    .chip,
    &.sign-in .field {
      --well-reach: calc(2px + var(--key-bevel));
      margin-block: calc(-1 * var(--well-reach)) calc(-1 * var(--well-reach) - 1px);
      padding-block: var(--well-reach) calc(var(--well-reach) + 1px);
    }

    .chip {
      height: calc(32px + 2 * var(--well-reach) + 1px);
    }

    &.sign-in .field {
      height: calc(40px + 2 * var(--well-reach) + 1px);
    }
  }

  .row {
    display: flex;
    flex: 1;
    align-items: center;
  }

  .field {
    display: flex;
    align-items: center;
    gap: var(--space-8);
    padding-inline: var(--space-12);
    border-radius: var(--radius-inset);
    background: var(--well);
    box-shadow: inset 0 0 0 1px var(--well-edge);
  }

  /* The conversation beside the form it filled; narrower, one column with only what was asked and
     what was written. */
  &.assistant {
    container-type: inline-size;

    .panes {
      display: grid;
      grid-template-columns: 47fr 53fr;
      column-gap: var(--space-32);
      height: 100%;
    }

    .chat {
      display: flex;
      flex-direction: column;
      padding-inline: var(--space-16);
      border-radius: var(--radius-inset);
      background: var(--raised);
      box-shadow: inset 0 0 0 1px var(--well-edge);
    }

    .chat-head {
      display: flex;
      align-items: center;
      gap: var(--space-8);
      height: 44px;
      margin-inline: calc(-1 * var(--space-16));
      padding-inline: var(--space-16);
      border-bottom: 1px solid rgb(from var(--bg) calc(r + 16) calc(g + 22) calc(b + 23));
      font-weight: 600;

      .glyph {
        color: var(--action);
      }
    }

    .prompt {
      margin-top: var(--space-16);
      padding: var(--space-8) var(--space-12);
      border-radius: 6px;
      background: rgb(from var(--bg) calc(r + 11) calc(g + 18) calc(b + 18));
      box-shadow: inset 0 0 0 1px var(--row-edge);
      line-height: 24px;
      text-wrap: balance;
      color: var(--text-soft);
    }

    .status {
      margin-top: var(--space-12);
      color: var(--muted);

      .glyph {
        display: none;
      }
    }

    .form {
      display: flex;
      flex-direction: column;
      gap: 2px;
    }

    .name {
      color: var(--faint);

      &:not(:first-child) {
        margin-top: var(--space-12);
      }
    }

    .field {
      --phosphor: var(--text);
      flex: none;
      height: 32px;
    }

    /* site.js plays the exchange (is-scripted): the request pops in (is-asked), the title lights
       in with a cursor (is-typing), the text's lines pop in in turn (is-writing) and the reply
       comes last (is-answered). */
    &.is-scripted {
      .prompt,
      .status {
        opacity: 0;
        scale: 0.96;
        transform-origin: left top;
        transition: opacity 0.25s ease-out, scale 0.25s ease-out;
      }

      .written i {
        opacity: 0;
        scale: 0.9;
        transform-origin: left;
        transition: opacity 0.2s ease-out, scale 0.2s ease-out;

        &:nth-child(2) {
          transition-delay: 0.25s;
        }

        &:nth-child(3) {
          transition-delay: 0.5s;
        }

        &:nth-child(4) {
          transition-delay: 0.75s;
        }
      }
    }

    &.is-asked .prompt,
    &.is-answered .status {
      opacity: 1;
      scale: 1;
    }

    &.is-typing .field:not(.written) > span::after {
      content: "";
      display: inline-block;
      width: 0.55em;
      height: 1.1em;
      margin-left: 1px;
      vertical-align: -0.2em;
      background: var(--phosphor);
      box-shadow: var(--phosphor-glow);
    }

    &.is-writing .written i {
      opacity: 1;
      scale: 1;
    }

    /* The text it wrote, as lit segments rather than letters. */
    .written {
      --phosphor: var(--accent);
      flex: 1;
      flex-direction: column;
      align-items: stretch;
      gap: var(--space-12);
      padding-block: 14px;

      i {
        height: 8px;
        border-radius: 4px;
        background: var(--phosphor);
        box-shadow: var(--emit-box);

        &:nth-child(1) {
          width: 86%;
        }

        &:nth-child(2) {
          width: 93%;
        }

        &:nth-child(3) {
          width: 90%;
        }

        &:nth-child(4) {
          width: 55%;
        }
      }
    }

    @container (width < 480px) {
      .panes {
        display: flex;
        flex-direction: column;
      }

      .chat,
      .form {
        display: contents;
      }

      .chat-head,
      .name,
      .status span,
      .written i:nth-child(2),
      .written i:nth-child(3) {
        display: none;
      }

      .prompt {
        margin-top: 0;
      }

      .status {
        display: flex;
        align-items: center;
        gap: 6px;
        margin-top: 10px;

        .glyph {
          --size: 14;
          display: block;
          color: var(--action);
        }
      }

      .field {
        margin-top: var(--space-12);
      }

      .written {
        margin-top: var(--space-8);
      }
    }
  }

  /* The home page's keys, with an icon where the lens would be, so nothing lights under the pointer
     either: the lamp's spill is centred on the lens. */
  .button {
    --spill: transparent;

    &::before {
      content: none;
    }
  }

  /* A mockup's main action is the rubber key with amber letters and edges, an outline beside the
     page's solid amber CTA. Under the pointer they light: the edge glows inward over the cap and out
     past the well. */
  .provider.google,
  .add {
    --edge:
      color-mix(in srgb, var(--action) 75%, transparent)
      color-mix(in srgb, var(--action) 45%, transparent)
      color-mix(in srgb, var(--action) 35%, transparent);
    color: var(--action);

    &:hover {
      --halo: inset 0 0 6px rgba(255, 154, 60, 0.22), var(--emit-action-box);
      text-shadow: var(--emit-action);

      .glyph {
        filter: drop-shadow(0 0 3px rgba(255, 154, 60, 0.45));
      }
    }

    /* In daylight the legend is amber ink cut into the metal, too pale in the lamp's own amber, and
       nothing glows: under the pointer only the edge lights, and the cut stays. */
    :root[data-theme="light"] & {
      color: var(--print-amber);

      &:hover {
        text-shadow: var(--engrave);

        .glyph {
          filter: var(--engrave-icon);
        }
      }
    }
  }

  /* The providers are the home page's keys, and the e-mail link sits on the bottom edge, with "ou"
     between. */
  &.sign-in {
    container-type: inline-size;

    .provider {
      display: flex;
      height: 40px;

      .glyph {
        --size: 14;
      }

      & + .provider {
        margin-top: var(--space-12);
      }

      /* Narrower, the keycap's type size, and on a 320 px phone "Sign in with Microsoft" alone fills
         the key. */
      @container (width < 290px) {
        font-size: var(--font-size-11);
        letter-spacing: 1.5px;
      }

      @container (width < 240px) {
        .glyph {
          display: none;
        }
      }
    }

    .or {
      display: grid;
      flex: 1;
      grid-template-columns: 1fr 48px 1fr;
      align-items: center;
      text-align: center;
      color: var(--faint);

      &::before,
      &::after {
        content: "";
        height: 1px;
        background: var(--wire);
      }
    }

    .field {
      height: 40px;
      padding-inline: 14px;
    }
  }

  /* Each field is a key holding its grip and name, wired to its type's window, as the versions are.
     The rows hug their keys and the slack goes between them: a 1fr row centres its key, which
     drew the first one below the band's top and read lower than the cards beside it. */
  &.sections {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: repeat(3, auto) 44px;
    align-content: space-between;
    column-gap: var(--space-12);

    .row {
      display: grid;
      grid-template-columns: subgrid;
      grid-column: 1 / -1;
      background: var(--wire-across);
    }

    /* As tall as the windows, and as wide as the widest, its dots where the lens would be. site.js
       drags it to reorder the fields; held, the key stays pressed. touch-action keeps a finger on
       the grip from scrolling the page instead. */
    .grip {
      align-self: center;
      justify-content: flex-start;
      height: 32px;
      padding-block: 0;
      padding-left: var(--space-10);
      color: var(--text-soft);
      cursor: grab;
      touch-action: none;
      user-select: none;
    }

    /* The field being dragged: a lifted copy that follows the pointer, its key held down and its
       window lit, over the ghost it leaves in the list where it will land. */
    .is-lifted {
      position: absolute;
      z-index: 2;
      pointer-events: none;
      filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.55));

      .grip {
        --drop: 0px;
        color: var(--text);
      }

      .chip {
        --phosphor: var(--accent);
        --phosphor-glow: var(--emit);
      }
    }

    .is-ghost {
      opacity: 0.25;
    }

    /* A row moved in the page restarts its window's switch-on, so once a field has been dragged the
       windows stay simply on. */
    &.is-settled .chip > * {
      animation: none;
    }

    .chip {
      grid-column: 3;
    }

    /* As wide as the widest type, so the windows stand in a column. */
    .chip span {
      flex: 1;
    }

    .add {
      grid-column: 1 / -1;

      .glyph {
        --size: 14;
      }
    }
  }

  /* One upload filling the card: the picture on top, then its name, where it goes and how far. Under
     the pointer the upload finishes: the bar runs on to the end, lit teal. */
  &.files {
    .upload {
      --phosphor: var(--text);
      display: grid;
      flex: 1;
      grid-template-columns: minmax(0, 1fr) auto;
      grid-template-rows: minmax(0, 1fr) 20px 6px;
      gap: var(--space-10) var(--space-12);
      padding: 10px;
      border-radius: var(--radius-inset);

      img {
        grid-column: 1 / -1;
        width: 100%;
        height: 100%;
        object-fit: cover;
        border-radius: 6px;

        /* Shown in the LCD's one ink: its tones laid over the reflector, dots and all, in pixels. */
        :root[data-theme="light"] & {
          filter: grayscale(1) brightness(2.2);
          mix-blend-mode: multiply;
          mask: var(--lcd-grid);
          mask-composite: intersect;
        }
      }

      b {
        overflow: hidden;
        font-weight: inherit;
        white-space: nowrap;
        text-overflow: ellipsis;
      }

      /* An unlit segment beside the lit name. */
      i {
        color: var(--faint);
        text-shadow: none;
      }

      .progress {
        grid-column: 1 / -1;
        height: 6px;
        border-radius: 3px;
        background: rgb(from var(--bg) calc(r + 7) calc(g + 12) calc(b + 12));

        /* Two rows of pixels, unlit ones for the track. */
        :root[data-theme="light"] & {
          border-radius: 0;
          background: var(--ink-ghost);
          mask: var(--lcd-grid);
          mask-composite: intersect;
        }

        &::before {
          content: "";
          display: block;
          width: 62%;
          height: 100%;
          border-radius: inherit;
          background: var(--muted);
          box-shadow: var(--phosphor-glow);
          transition: width 1.4s cubic-bezier(0.3, 0, 0.2, 1), background-color 0.3s, box-shadow 0.3s;
        }
      }
    }
  }

  /* Always 28 days, as the card's text says: a wider card spaces them out rather than adding days.
     The chart is one window filling the card; its days are lit segments and today is teal. */
  &.audience .screen {
    --phosphor: var(--text);
    flex: 1;
    flex-direction: column;
    align-items: stretch;
    height: auto;
    padding: 14px 14px 10px;

    /* The figure on the left and its legend on the right, the pointed day's date after it: an
       unlit 00/00 until a day is chosen. */
    .total {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: var(--space-10);

      /* Unlit as the tenants' unused systems are, dimmer than the legend beside it. */
      .day {
        color: rgb(from var(--bg) calc(r + 45) calc(g + 54) calc(b + 55));

        :root[data-theme="light"] &:not(.is-chosen) {
          color: color-mix(in srgb, var(--lcd-ink) 16%, transparent);
        }

        &.is-chosen {
          color: var(--text-soft);
        }
      }

      /* Trimmed to the digits' cap height, so their ink, not the line box, starts the band. */
      b {
        font-size: 22px;
        font-weight: 500;
        line-height: 1;
        text-box: trim-both cap alphabetic;
      }
    }

    /* Unlit segments around the lit count. */
    .total,
    .dates {
      color: var(--faint);
      text-shadow: none;
    }

    .total b {
      color: var(--phosphor);
      text-shadow: var(--phosphor-glow);
    }

    .bars {
      display: grid;
      flex: 1;
      grid-template-columns: repeat(28, minmax(0, 1fr));
      grid-template-rows: minmax(0, 1fr);
      align-items: end;
      min-height: 0;
      margin-top: var(--space-12);

      i {
        justify-self: center;
        width: 60%;
        height: max(4px, var(--h) * 1%);
        border-radius: 2px;
        background: color-mix(in srgb, var(--muted) 70%, transparent);
        box-shadow: 0 0 3px color-mix(in srgb, var(--muted) 25%, transparent);
        transform-origin: bottom;

        &:last-child,
        &.is-pointed {
          background: var(--accent);
          box-shadow: var(--emit-box);
        }
      }

      /* Pointing at another day hands it today's light. */
      &:has(.is-pointed) i:last-child:not(.is-pointed) {
        background: color-mix(in srgb, var(--muted) 70%, transparent);
        box-shadow: 0 0 3px color-mix(in srgb, var(--muted) 25%, transparent);
      }

      /* In daylight a day is a column of whole pixels on the baseline. The mask would cut a bar's
         shadow too, so the chart casts it, from the pixels. */
      :root[data-theme="light"] & {
        filter: drop-shadow(var(--window-shadow));

        i,
        &:has(.is-pointed) i:last-child:not(.is-pointed) {
          width: max(2 * var(--pixel), round(down, 60%, var(--pixel)));
          height: max(var(--pixel), round(var(--h) * 1%, var(--pixel)));
          border-radius: 0;
          box-shadow: none;
          mask: var(--lcd-grid);
          mask-composite: intersect;
        }
      }
    }

    /* The days rise in turn, left to right, once the window has warmed up. */
    &[data-power] .bars i {
      animation: day-rise 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) calc(var(--jitter, 0ms) + 0.5s + var(--i) * 40ms) both;
    }

    &[data-power="off"] .bars i {
      animation-play-state: paused;
    }

    /* The dates sit on the bottom edge by their baseline, which is their digits' ink; the slash
       hangs below it as a descender would. */
    .dates {
      display: flex;
      align-items: end;
      justify-content: space-between;
      height: 19px;
      margin-top: 4px;
      border-top: 1px solid var(--wire);

      i {
        line-height: 1;
        text-box: trim-both cap alphabetic;
      }
    }
  }

  /* Keys whose lamp tells a state, the companies' and the versions': off, a dark tinted lens; on (a
     pressed company, the live version), lit in the key's colour. The lens is drawn here, not by the
     pointer, so hovering a key never shows it lit. */
  &.tenants .name,
  &.versions b {
    --pad-x: var(--space-10);

    &::before {
      content: "";
      background:
        radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.4) 0 0.5px, transparent 1.2px),
        radial-gradient(circle at 50% 60%, color-mix(in srgb, var(--lamp) 22%, rgb(from var(--bg) calc(r - 6) calc(g - 6) calc(b - 7))), rgb(from var(--bg) calc(r - 9) calc(g - 11) calc(b - 12)));
      box-shadow: inset 0 1px 1.5px rgba(0, 0, 0, 0.8), 0 0 0 1px rgb(from var(--bg) calc(r - 12) calc(g - 15) calc(b - 17)), 0 1px 0 1px rgba(255, 255, 255, 0.07);
    }

    &[aria-pressed="true"],
    &.on {
      --spill: color-mix(in srgb, var(--lamp) 14%, transparent);

      &::before {
        background:
          radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.5) 0 0.5px, transparent 1.2px),
          radial-gradient(circle, color-mix(in srgb, var(--lamp) 40%, white) 0 1px, var(--lamp) 2.5px);
        box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4), var(--lamp-glow);
      }
    }
  }

  /* The states stand in one column as wide as the longest, as a display's window is, and give up
     width before the version's name does. */
  &.versions {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr) minmax(0, max-content);
    align-content: space-between;
    column-gap: var(--space-12);

    .row {
      display: grid;
      grid-template-columns: subgrid;
      grid-column: 1 / -1;
      /* A wire from the version to its state, drawn behind both: a window is opaque, so it shows
         only between them. */
      background: var(--wire-across);
    }

    /* Each version is a key, as the page's buttons are, as tall as the state's window across from
       it (both rings draw outside the box); the wire runs out from under it. */
    b {
      align-self: center;
      height: 32px;
      padding-block: 0;
      color: var(--text-soft);
      cursor: pointer;
    }

    /* site.js sets --state-width on the first switch, so the column keeps its width at rest. */
    .chip {
      grid-column: 3;
      min-width: var(--state-width, 0);
    }

    /* On a phone's card the long state truncates rather than leaving its row; its lamp stays. */
    .chip > span {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

    .old {
      b {
        color: var(--faint);
      }

      /* An unlit lamp, dimmer than its label. */
      .glyph {
        opacity: 0.55;
        filter: none;
      }
    }

    /* In daylight only the live version's window is backlit. */
    :root[data-theme="light"] & .row:not(:has(.on)) {
      --window-bezel: var(--window-bezel-unlit);
    }
  }

  /* InterAdmin wired to each company it serves. Beside them from 736 px; narrower it stands above
     them and the rows shed detail by meaning: the systems' names, then the languages and the
     database icon. The rows share their columns with the headings through subgrid. The headings and
     companies are the versions' four rows, keys 32 px tall and 24 apart, so beside that card the
     two read as one table. */
  &.tenants {
    container-type: inline-size;
    padding-top: 0;

    .tree {
      --gap: var(--space-24);
      --reach: 24px;
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: repeat(4, 32px);
      row-gap: var(--gap);
      height: 100%;
      padding-top: var(--space-16);
    }

    .hub {
      position: relative;
      z-index: 1;
      grid-area: 1 / 1;
      justify-self: start;
      display: flex;
      align-items: center;
      gap: 6px;
      height: 36px;
      padding-inline: 10px;
      border-radius: var(--radius-inset);
      background: var(--raised);
      box-shadow: inset 0 0 0 1px var(--row-edge);
      font-weight: 600;

      .glyph {
        --size: 20;
        stroke: none;
        color: var(--accent);
      }
    }

    .companies {
      display: grid;
      grid-template-rows: subgrid;
      grid-template-columns: auto minmax(0, 1fr) auto;
      grid-area: 1 / 1 / -1;
      column-gap: var(--space-8);
      margin-left: 32px;
    }

    .heading {
      align-self: center;
      color: var(--faint);

      &:first-child {
        padding-left: 10px;
        visibility: hidden;
      }
    }

    .company {
      position: relative;
      display: grid;
      grid-template-columns: subgrid;
      grid-column: 1 / -1;
      align-items: center;
      /* The rail's stub carries on through the row, behind its windows, so it shows only between
         them. */
      background: var(--wire-across);

      /* The stub from the rail, and the rail from the row above's middle to this one's. The first
         row's rail runs up behind the hub. */
      &::before,
      &::after {
        content: "";
        position: absolute;
        right: 100%;
        background: var(--wire);
      }

      &::before {
        top: 0;
        bottom: 0;
        width: var(--reach);
        background: var(--wire-across);
      }

      &::after {
        right: calc(100% + var(--reach));
        bottom: 50%;
        width: 1px;
        height: calc(100% + var(--gap));
      }
    }

    /* Each wire between windows as long as the stub into the first, past the column gap. */
    .name,
    .systems {
      margin-right: calc(var(--reach) - var(--space-8));
    }

    /* Each company is a key, as tall as its windows, with an amber lamp: pressed, the lamp lights and
       the company's windows turn amber with it (site.js toggles aria-pressed). */
    .name {
      --lamp: var(--action);
      --lamp-glow: var(--emit-action-box);
      align-self: center;
      justify-content: flex-start;
      height: 32px;
      padding-block: 0;
      color: var(--text-soft);
      cursor: pointer;

      b {
        overflow: hidden;
        font-weight: inherit;
        text-overflow: ellipsis;
      }
    }

    .company:has([aria-pressed="true"]) {
      .systems,
      .languages {
        --phosphor: var(--action);
      }

      .lit {
        color: var(--action);
        text-shadow: var(--emit-action);
      }
    }

    /* Daylight's windows have one ink, so dark's amber cannot show a pressed company; its backlight
       does. Once one is pressed the others' go unlit; until then all are lit, as every window is. */
    :root[data-theme="light"] & .companies:has([aria-pressed="true"]) .company:not(:has([aria-pressed="true"])) {
      --window-bezel: var(--window-bezel-unlit);
    }

    /* One window per company, filling its column, so every row's is the same width. */
    .systems {
      gap: var(--space-12);
      overflow: hidden;
    }

    .system {
      display: inline-flex;
      flex: none;
      align-items: center;
      gap: 6px;
    }

    .languages {
      gap: var(--space-8);
    }

    /* Every company shows the same panel, as a display has fixed segments: what it runs is lit and
       the rest stays dark. */
    .system,
    .languages > span {
      color: rgb(from var(--bg) calc(r + 45) calc(g + 54) calc(b + 55));
      text-shadow: none;

      /* An unlit LCD segment is a faint ghost of the ink; pale, it read as lit. */
      :root[data-theme="light"] &:not(.lit) {
        color: color-mix(in srgb, var(--lcd-ink) 16%, transparent);
      }

      .glyph {
        color: inherit;
        filter: none;
      }

      &.lit {
        color: var(--accent);
        text-shadow: var(--emit);

        .glyph {
          filter: drop-shadow(0 0 2px color-mix(in srgb, var(--accent) 45%, transparent));
        }
      }
    }

    @container (width >= 736px) {
      .tree {
        --reach: 16px;
        /* The hub's wire one reach to the rail, as long as every other wire; the systems' windows
           take up the slack instead. */
        grid-template-columns: auto calc(2 * var(--reach)) minmax(max-content, 1fr);

        &::before {
          content: "";
          grid-area: 3 / 2;
          margin-right: var(--reach);
          background: var(--wire-across);
        }
      }

      .hub {
        grid-area: 3 / 1;
        align-self: center;
        justify-self: stretch;
        height: 72px;
        padding-left: 14px;
      }

      .companies {
        grid-area: 1 / 3 / -1;
        margin-left: 0;
      }

      .heading:first-child {
        visibility: visible;
      }

      .company:first-of-type::after {
        content: none;
      }
    }

    /* Four wires of 32 px need about 802 px of card, so they double only on the widest. */
    @container (width >= 804px) {
      .tree {
        --reach: 32px;
      }
    }

    /* Four systems' names need about 612 px of card; below it the window shows their icons. */
    @container (width < 616px) {
      .systems {
        gap: var(--space-8);
      }

      .system > span {
        display: none;
      }
    }

    @container (width < 560px) {
      .languages {
        gap: 6px;
        padding-inline: 8px;
      }
    }

    /* The icons stay in one window, closer together. */
    @container (width < 368px) {
      .systems {
        gap: var(--space-4);
        padding-inline: var(--space-6);
      }
    }

    /* The languages go before the name is squeezed, and the four lamps shrink a size. */
    @container (width < 310px) {
      .languages,
      .heading:last-of-type {
        display: none;
      }

      .systems .glyph {
        --size: 12;
      }
    }

    /* A single column has the card to itself, so the card grows instead: each company is one
       window, its name, systems and languages ruled apart inside it, and the systems keep their
       names, wrapping where they must. One wire drops from the hub's middle behind them all. */
    @media (max-width: 699px) {
      height: auto;

      .tree {
        --gap: var(--space-16);
        position: relative;
        grid-template-rows: auto repeat(3, minmax(0, 1fr));
      }

      /* Left unplaced, the wire keeps the static position the hub's centring gives it, so it
         finds the hub's middle whatever its width; the hub is left unpositioned so the wire's box
         is the tree's, and it starts at the hub's foot, 36 px under the tree's padding. */
      .hub {
        position: static;
        z-index: auto;
        justify-content: center;

        &::after {
          content: "";
          position: absolute;
          top: calc(var(--space-16) + 36px);
          bottom: var(--space-16);
          width: 1px;
          background: var(--wire);
        }
      }

      /* The first stays, unseen, to hold the hub's row, or the companies would fill it. */
      .heading {
        display: none;

        &:first-child {
          display: block;
          grid-column: 1;
        }
      }

      .companies {
        grid-template-columns: minmax(0, 1fr);
        margin-left: 0;
      }

      .company {
        grid-template-columns: minmax(0, 1fr);
        border-radius: 6px;
        background: var(--window);
        box-shadow: var(--window-bezel);
        transition: box-shadow 0.4s;

        &::before {
          content: none;
        }

        /* The windows' bevel ring, as the card windows draw it. */
        :root[data-theme="light"] &::before {
          content: "";
          position: absolute;
          inset: 0;
          width: auto;
          border: var(--key-bevel) solid transparent;
          border-radius: inherit;
          pointer-events: none;
          background: var(--key-bevel-face);
          mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
        }

        &::after {
          inset: 0;
          width: auto;
          height: auto;
          border-radius: inherit;
          pointer-events: none;
          background: var(--display-glass);
          opacity: 0.4;
        }

      }

      /* Square, so the rule between two rows runs straight into the window's bevel instead of
         curling down at each end. */
      .name,
      .systems,
      .languages {
        margin-right: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;

        /* Daylight's window paints its own field; one row after another restarts the dots. */
        :root[data-theme="light"] & {
          background: none;
        }

        &::after {
          content: none;
        }
      }

      /* A row of the window, not a key: daylight's cap border framed it apart from the rest. */
      .name {
        height: 32px;
        border-color: transparent;
      }

      .systems,
      .languages {
        display: flex;
        flex-wrap: wrap;
        grid-column: 1 / -1;
        height: auto;
        padding: 6px 10px;
        border-top: 1px solid var(--window-edge);
        line-height: 20px;

        /* Rows of the one window here, not windows beside keys, so they keep their own box and
           drop daylight's bezel and bevel ring, each of which drew a row as a window of its own.
           The power-on animations (site.css) paint from these bezels, so emptying them stills
           those too. Inset by the window's bevel and ring, so a rule stops at the bevel. */
        :root[data-theme="light"] & {
          --window-bezel-unlit: 0 0 #0000;
          --window-bezel-hot: 0 0 #0000;
          --window-bezel-lit: 0 0 #0000;
          height: auto;
          margin: 0 calc(var(--key-bevel) + 1px);
          padding-block: 6px;
          padding-inline: calc(10px - var(--key-bevel) - 1px);
          box-shadow: none;

          &::before {
            content: none;
          }
        }
      }

      /* Fixed places, as a display's segments are: four across, two by two, or one column. */
      .systems {
        display: grid;
        grid-template-columns: repeat(2, max-content);
        gap: 0 var(--space-20);

        .glyph {
          --size: 14;
        }

        /* The four names take 283 px in either language, so at a 14 px gap they share a row from
           345 px of card: every current iPhone, not a 360 or 375 px phone. */
        @container (width >= 345px) {
          grid-template-columns: repeat(4, max-content);
          column-gap: var(--space-14);
        }

        @container (width < 252px) {
          grid-template-columns: max-content;
        }
      }

      .languages {
        gap: var(--space-8);
      }

      .system > span {
        display: inline;
      }
    }
  }
}

.tour {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--space-20);

  /* Spaced as the Recursos cards are. */
  .tour-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-20);
  }

  /* A halo of the page's dark around the cards and the window clears the grid off their edges, so
     they stand above it rather than being drawn on it. */
  --halo: 0 0 32px 10px rgb(from var(--bg) r g b / 0.9);
  /* The cards and the window stand 2px proud of the grid, twice the page's --raised. The page's
     dark is darker than a band's grey and leaves a shadow less to take away, so the cast shadows
     are darker here than on a band to read about the same. */
  --plate-edge: var(--line-strong) var(--line) rgb(from var(--bg) calc(r - 4) calc(g - 5) calc(b - 6));
  --plate:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 1px 0 rgb(from var(--bg) calc(r - 3) calc(g - 4) calc(b - 4)),
    0 2px 0 rgb(from var(--bg) calc(r - 6) calc(g - 8) calc(b - 8)),
    0 4px 6px -1px rgba(0, 0, 0, 0.8),
    0 12px 24px -8px rgba(0, 0, 0, 0.85);
  /* In daylight the cards and the window's bar are cut from the page's brushed plate, its sheen
     fixed as the body's is, so the light slides across them together. */
  --plate-face: var(--surface);

  :root[data-theme="light"] & {
    --plate-face: var(--sheen) fixed, var(--brushed), var(--bg);
  }

  /* The step shares the title's size and first baseline, so "01" reads as part of the heading. */
  [role="tab"] {
    display: flex;
    align-items: first baseline;
    gap: var(--space-16);
    padding: var(--space-20) var(--space-24);
    border: 1px solid;
    border-color: var(--plate-edge);
    border-radius: var(--radius-panel);
    background: var(--plate-face);
    box-shadow: var(--plate), var(--halo);
    font: inherit;
    text-align: left;
    color: var(--muted);
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;

    &:hover {
      border-color: var(--line-hover);
    }

    &[aria-selected="true"] {
      border-color: rgba(0, 204, 204, 0.45);
      background: radial-gradient(90% 120% at 0% 0%, rgba(0, 204, 204, 0.08), transparent), var(--plate-face);

      .step {
        color: var(--accent);
        text-shadow: var(--emit);
      }
    }
  }

  .step {
    font-family: var(--mono);
    font-size: var(--font-size-18);
    color: var(--faint);
  }

  /* The number is a key only on a phone; wider, the key gives way to the step's own digits. */
  .step .keycap {
    @media (min-width: 700px) {
      all: unset;

      &::before,
      &::after {
        content: none;
      }
    }
  }

  .label {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    font-size: var(--font-size-15);

    strong {
      font-size: var(--font-size-18);
      font-weight: 600;
      color: var(--text);
    }
  }

  /* The screens are light and the page dark: set on the section's square grid, the mark's, the
     window reads as placed on the page rather than cut out of it. The grid is a whole number of
     cells, about 30px, across the window, laid from its edges, so they are grid lines too; it runs
     out to the section's edges, which clip it (#screens). */
  .tour-stage {
    --cells: 40;
    --grid-line: rgba(0, 204, 204, 0.1);
    --cell: calc(100cqi / var(--cells));
    position: relative;

    &::before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: calc(-30 * var(--cell)) calc(-1 * var(--cells) * var(--cell));
      pointer-events: none;
      background:
        radial-gradient(40% 35% at 50% 50%, rgba(0, 204, 204, 0.1), transparent 70%),
        linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / var(--cell) var(--cell),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / var(--cell) var(--cell);
    }

    /* Daylight's teal ink: dark's bright teal at 0.1 is lost on the pale plate. */
    :root[data-theme="light"] & {
      --grid-line: rgba(0, 123, 123, 0.2);
    }

    @media (max-width: 899px) {
      --cells: 24;
    }

    @media (max-width: 479px) {
      --cells: 12;
    }

    .window {
      border-color: var(--plate-edge);
      box-shadow: var(--plate), 0 0 56px 20px rgb(from var(--bg) r g b / 0.9), 0 24px 64px rgba(0, 0, 0, 0.55);

      :root[data-theme="light"] & .window-bar {
        background: var(--plate-face);
      }
    }
  }

  /* The screens are 1280 CSS px captures at 2x, so at the page's full width they show near their own
     size, which is what keeps them legible. All three are shot at 1280x800, so the footer bar shows. */
  .tour-panels {
    position: relative;
    isolation: isolate;
    aspect-ratio: 1280 / 800;

    /* The screens are shown as if lit on the page's displays: a bloom on their bright marks, then
       the display's glass over them, all faint enough that every label still reads. */
    /* Lifted, since daylight's filtered screen is a stacking context and would paint over ::before. */
    &::before,
    &::after {
      content: "";
      position: absolute;
      z-index: 1;
      inset: 0;
      pointer-events: none;
    }

    &::before {
      backdrop-filter: blur(5px) brightness(1.6);
      mix-blend-mode: screen;
      opacity: 0.12;
    }

    &::after {
      background: var(--display-glass);
      box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.4);
      opacity: 0.2;
    }

    /* In daylight the screens are shown on the readouts' reflective LCD instead: the white is its
       grey-green reflector behind the pixel grid, each dark mark casts its shadow on it (#lcd-ink),
       and the glass carries the sheen and the faint teal edge light. */
    :root[data-theme="light"] & {
      &::before {
        backdrop-filter: none;
        background: var(--lcd-pixels), linear-gradient(#edf2ec, #e4ebe3);
        mix-blend-mode: multiply;
        opacity: 1;
      }

      &::after {
        box-shadow:
          inset 0 4px 4px -2px rgba(20, 30, 28, 0.16),
          inset 0 0 24px 2px rgba(90, 225, 210, 0.14);
        opacity: 1;
      }

      img {
        filter: url("#lcd-ink");
      }
    }

    /* Holds #lcd-ink: an svg that is display: none loses its filters in Firefox. */
    svg {
      position: absolute;
      width: 0;
      height: 0;
    }

    picture {
      display: contents;
    }

    img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: top;

      &[hidden] {
        display: none;
      }
    }
  }

  /* On a phone the three tabs are rows of one card, split by rules, each led by its number on a
     rubber key: the selected one held down with its number lit, its title brighter than the rest. */
  @media (max-width: 699px) {
    .tour-tabs {
      grid-template-columns: minmax(0, 1fr);
      gap: 0;
      border: 1px solid;
      border-color: var(--plate-edge);
      border-radius: var(--radius-panel);
      background: var(--plate-face);
      box-shadow: var(--plate), var(--halo);
    }

    [role="tab"] {
      align-items: center;
      padding: var(--space-16) var(--space-20);
      border: 0;
      border-radius: 0;
      background: none;
      box-shadow: none;

      & + [role="tab"] {
        border-top: 1px solid var(--line);
      }

      &[aria-selected="true"] {
        border-color: var(--line);
        background: none;
      }

      strong {
        font-size: var(--font-size-16);
        line-height: 1.35;
        text-wrap: balance;
      }

      &:not([aria-selected="true"]) strong {
        color: var(--muted);
      }
    }

    .step {
      display: flex;

      .keycap {
        --pad-x: var(--space-10);
        margin-inline: 0;
        padding-block: var(--space-8);
        font-size: var(--font-size-13);
        line-height: 1;
        letter-spacing: 1px;

        &::before {
          content: none;
        }
      }
    }

    .detail {
      display: none;
    }

    /* A phone gets its own captures: the same screens at 1024x768, InterAdmin's narrowest width
       with its header whole, so a whole screen shows at a readable scale without a tall frame. */
    .tour-panels {
      aspect-ratio: 1024 / 768;
    }
  }
}

.features li:not(.slider):hover .mockup.files .progress::before {
  width: 100%;
  background: var(--accent);
  box-shadow: var(--emit-box);
}

/* The tour's grid reaches the section's edges (.tour-stage::before) and stops there. */
#screens {
  isolation: isolate;
  overflow: clip;

  /* In daylight the screens sit on the plain plate, without the brushing, so only the grid marks it. */
  :root[data-theme="light"] & {
    background: var(--bg);
  }

  @media (max-width: 699px) {
    .section-head > p {
      display: none;
    }
  }
}

/* Doubled, to outrank site.css's .section > .wrap column. Four columns, one a figure: the story takes
   two and the diff two, as tall as the story, logo to paragraph, so every edge meets another. */
.wrap.case {
  --gap: var(--space-32);
  /* The figures size by this width: as their own container they would lose the subgrid, which
     layout containment turns off. */
  container-type: inline-size;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-40) var(--gap);

  .case-story {
    grid-column: span 2;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-20);

    & > p {
      max-width: 480px;
      font-size: var(--font-size-17);
      color: var(--muted);
    }
  }

  .case-logo {
    width: 160px;
    aspect-ratio: 1321.45 / 467.74;
    background: var(--text-soft);
    mask: url("../img/clients/central-de-intercambio.svg") left center / contain no-repeat;
  }

  /* Each figure is a readout with its legend below, as the home's figures are. Up to 40px, as large
     as lets the longest, 8 characters, fill a quarter of the row. */
  .case-figures {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    row-gap: var(--space-28);

    li {
      display: flex;
      flex-direction: column;
      gap: var(--space-16);
    }

    strong {
      font-size: clamp(24px, ((100cqi - 3 * var(--gap)) / 4 - 2 * var(--pad) - 8 * 2px) / (8 * 0.6), 40px);
      white-space: nowrap;
    }

    li > span {
      color: var(--muted);
    }

    @media (max-width: 999px) {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      column-gap: var(--gap);

      strong {
        font-size: clamp(22px, ((100cqi - var(--gap)) / 2 - 2 * var(--pad) - 8 * 2px) / (8 * 0.6), 40px);
      }
    }

    @media (max-width: 479px) {
      --gap: var(--space-16);

      li > span {
        font-size: var(--font-size-15);
      }
    }
  }

  /* Set in the readouts' bezel, as the display it is, so it matches the figures under it. */
  .terminal {
    grid-column: span 2;
    width: calc(100% + 2 * var(--bevel));
    max-width: none;
    margin: calc(-1 * var(--bevel));
    border: var(--bevel) solid transparent;
    border-radius: calc(var(--radius-panel) + var(--bevel));
    box-shadow: var(--display-bezel);

    /* The terminal's panel inside the window, bar included, and the displays' bevel round it. */
    :root[data-theme="light"] & {
      background: var(--terminal-panel) padding-box, var(--display-bevel);
      box-shadow: var(--display-bezel);
    }
  }

  @media (max-width: 999px) {
    grid-template-columns: minmax(0, 1fr);

    .case-story,
    .terminal {
      grid-column: auto;
    }
  }
}

/* A band, as the home's Produtos is: the section holds one thing, so a card around it adds nothing.
   It takes the keys' grain, softened. */
#reliability {
  background: var(--grain-band), var(--surface);
}

/* Five cards, spaced as the Recursos ones: the SLA across two columns beside the year that measures
   it (the SLA is the target; the 365 days are what the probe saw, and the two always stand
   together), then AWS, tests and security. Each is a label beside the home's lit icon, then its
   figure in the headings' type, then the line under it; the year's card also draws its days. */
.uptime {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-20);

  /* Each card is lit faintly from its top left, as the active tour tab and the home's featured
     service are, behind the label. */
  & > li {
    position: relative;
    isolation: isolate;
    container-type: inline-size;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto 1fr;
    grid-template-areas:
      "title icon"
      "figure figure"
      "text text"
      "days days"
      "scale scale";
    column-gap: var(--space-16);
    padding: var(--space-28);
    border: 1px solid;
    border-color: var(--raised-edge);
    border-radius: var(--radius-panel);
    background: var(--bg);
    box-shadow: var(--raised);

    &::before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      border-radius: inherit;
      pointer-events: none;
      background: radial-gradient(90% 120% at 0% 0%, rgba(0, 204, 204, 0.08), transparent);
    }
  }

  .icon {
    grid-area: icon;
  }

  .headline {
    display: contents;
  }

  .compact {
    display: none;
  }

  h3 {
    grid-area: title;
    align-self: center;
    font-size: var(--font-size-16);
    font-weight: 600;
    color: var(--text-soft);
  }

  .figure {
    grid-area: figure;
    margin-top: var(--space-20);
    font-size: 48px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.038em;
  }

  p {
    grid-area: text;
    margin-top: var(--space-12);
    color: var(--muted);
  }

  /* site.js climbs the nines in, one at a time; each fades in where it stands. */
  .sla .figure {
    font-size: clamp(48px, 11cqi, 96px);

    .nine {
      display: none;

      &.is-lit {
        display: inline;
        animation: nine-in 0.25s ease-out both;
      }
    }
  }

  .sla {
    grid-column: span 2;
  }

  .year .uptime-days {
    grid-area: days;
    align-self: end;
    padding-top: var(--space-24);
  }

  .year .uptime-scale {
    grid-area: scale;
    width: calc(53 * round(down, 100cqi / 53, 1px));
    margin-top: var(--space-8);
  }

  @media (max-width: 899px) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* On a phone the five are rows of one card, split by rules. Each reads as one line at the phone
     readouts' 22px, the figure in teal inside a short lowercase title, centred on its icon; the
     desktop title stays for screen readers, which the short one is hidden from. */
  /* The cards become rows of one, so the one card is what stands proud. */
  @media (max-width: 599px) {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    border: 1px solid;
    border-color: var(--raised-edge);
    border-radius: var(--radius-panel);
    box-shadow: var(--raised);
    background:
      radial-gradient(90% 120% at 0% 0%, rgba(0, 204, 204, 0.08), transparent),
      var(--bg);

    .sla {
      grid-column: auto;
    }

    & > li {
      grid-template-areas:
        "headline icon"
        "text ."
        "days days"
        "scale scale";
      padding: var(--space-20) var(--space-24);
      border: 0;
      border-radius: 0;
      background: none;
      box-shadow: none;

      &::before {
        content: none;
      }

      & + li {
        border-top: 1px solid var(--line);
      }
    }

    .headline {
      display: block;
      grid-area: headline;
      align-self: center;
      font-size: 22px;
      line-height: 1.2;
      font-weight: 600;
      color: var(--text-soft);
    }

    .compact {
      display: inline;
    }

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

    .figure {
      color: var(--accent);
    }

    /* The figures are the teal here, so the lit caps would compete with them: each icon sits on a
       key of the page's rubber instead, set in its well as the menu button is. */
    .icon {
      border-color: var(--rubber-edge);
      background:
        radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 70%),
        var(--grain),
        var(--rubber);
      box-shadow:
        0 1px 0 rgb(from var(--bg) calc(r - 6) calc(g - 7) calc(b - 8)),
        0 0 0 2px rgb(from var(--bg) calc(r - 14) calc(g - 18) calc(b - 20)),
        0 -1px 0 2px rgba(0, 0, 0, 0.6),
        0 1px 0 2px rgba(255, 255, 255, 0.07);
      color: var(--accent);

      /* In daylight the keys' well, translucent and lit along its lip, round bare aluminium. */
      :root[data-theme="light"] & {
        background: radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 70%), var(--rubber);
        box-shadow:
          0 1px 0 rgb(from var(--bg) calc(r - 6) calc(g - 7) calc(b - 8)),
          0 0 0 2px rgba(30, 40, 42, 0.3),
          0 -1px 0 2px rgba(0, 0, 0, 0.6),
          0 1px 0 2px var(--lip);
      }
    }

    h3,
    .figure,
    .sla .figure {
      display: inline;
      margin: 0;
      font-size: inherit;
      line-height: inherit;
    }

    h3 {
      letter-spacing: -0.02em;
    }

    p {
      margin-top: var(--space-8);
    }
  }

  /* site.js fills it with LEDs, each set in a hole in the panel. The <i> is the hole (a dark rim, its
     chamfer shaded above and catching light below, as the keycaps' wells are) holding the lens unlit:
     tinted epoxy with a specular. ::after is the light, at the --level of brightness the LED came out
     of the factory with, so no two match, and its spill onto the panel around the hole. */
  /* A whole-pixel pitch, so every column steps the same: in a third of a row a day is about 7px,
     and a fractional one stepped 13 and 14 device pixels by turns, which read as uneven. The few
     pixels it leaves over go to the right, and the scale below is cut to the same width. */
  .uptime-days {
    --pitch: round(down, 100cqi / 53, 1px);
    --space: round(var(--pitch) * 0.3, 1px);
    --ring: 0.5px;
    display: grid;
    grid-template-rows: repeat(7, var(--pitch));
    grid-auto-columns: var(--pitch);
    grid-auto-flow: column;
    width: calc(53 * var(--pitch));

    --spread: 1;

    /* In daylight --accent is a teal ink, which lit a dull LED; the LEDs take the page's lit lamp.
       With no glow to even them out, the factory's spread read as noise, so it is cut to half. */
    :root[data-theme="light"] & {
      --accent: var(--led);
      --spread: 0.5;
    }

    /* A round LED at the start of its day's square, the panel showing after it: a whole size at a
       whole offset, so every lamp lands on the same pixels whatever the pitch. */
    i {
      --led: var(--accent);
      position: relative;
      place-self: start;
      width: calc(var(--pitch) - var(--space));
      aspect-ratio: 1;
      border-radius: 50%;
      background:
        radial-gradient(ellipse 45% 32% at 32% 24%, rgba(255, 255, 255, 0.16), transparent),
        radial-gradient(circle at 50% 56%, #0f3537, #091a1c 80%);
      box-shadow:
        0 0 0 var(--ring) rgb(from var(--bg) calc(r - 12) calc(g - 15) calc(b - 17)),
        0 calc(var(--ring) * -1) 0 calc(var(--ring) * 1.5) rgba(0, 0, 0, 0.6),
        0 var(--ring) 0 calc(var(--ring) * 1.5) rgba(255, 255, 255, 0.08);

      /* Above every hole's rim, so the spill lands on the panel between them. */
      &::after {
        content: "";
        position: absolute;
        z-index: 1;
        inset: 0;
        border-radius: inherit;
        opacity: calc(1 - (1 - var(--level, 1)) * var(--spread));
        background:
          radial-gradient(ellipse 28% 16% at 30% 20%, rgba(255, 255, 255, 0.3), transparent),
          radial-gradient(circle at var(--die, 50% 54%), color-mix(in srgb, var(--led) 55%, white) 0 5%, color-mix(in srgb, var(--led) 88%, white) 18%, var(--led) 45%, color-mix(in srgb, var(--led) 70%, #06292a) 100%);
        box-shadow:
          0 0 calc(var(--ring) * 3) color-mix(in srgb, var(--led) 50%, transparent),
          0 0 calc(var(--ring) * 10) color-mix(in srgb, var(--led) 16%, transparent);
      }
    }

    /* Each LED's own tint, from site.js, turned off the page's teal so the tone knob still moves it. */
    @supports (color: oklch(from red l c h)) {
      i {
        --led: oklch(from var(--accent) calc(l + var(--lightness, 0) * var(--spread)) c calc(h + var(--hue, 0) * var(--spread)));
      }
    }

    .off::after {
      content: none;
    }

    /* site.js holds every LED dark until the grid comes into view, then the year lights a week at a
       time, each LED stuttering on as the readout does. Under reduced motion they are simply on. */
    &[data-power] i::after {
      animation: lamp-on 0.6s steps(1, end) calc(var(--jitter, 0ms) + 250ms + var(--week) * 22ms + var(--flicker)) both;
    }

    &[data-power="off"] i::after {
      animation-play-state: paused;
    }
  }

  .uptime-scale {
    display: flex;
    justify-content: space-between;
    font-family: var(--mono);
    font-size: var(--font-size-12);
    color: var(--faint);
  }
}

/* Where the server is: São Paulo to Virginia on a display of land dots (route-land.svg, a symbol the
   page colours), the trip drawn as a trace bowed over the sea. 7.665 km is the great circle to
   Ashburn, us-east-1; 170 and 370 ms are production's medians, application and network, and size
   the bar's segments. */
.route {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: center;
  gap: var(--space-48);
  margin-top: var(--space-48);
  padding-top: var(--space-40);
  border-top: 1px solid var(--line);

  .route-map,
  .trip-bar {
    position: relative;
    isolation: isolate;
    margin: calc(-1 * var(--bevel));
    border: var(--bevel) solid transparent;
    border-radius: calc(var(--radius-inset) + var(--bevel));
    background: var(--display-surface);
    box-shadow: var(--display-bezel);

    &::after {
      content: "";
      position: absolute;
      z-index: 1;
      inset: 0;
      border-radius: var(--radius-inset);
      pointer-events: none;
      background: var(--display-glass);
    }
  }

  svg {
    display: block;
    width: 100%;
    height: auto;
    padding: var(--space-16);
    overflow: visible;
  }

  .land {
    color: color-mix(in srgb, var(--accent) 30%, rgb(from var(--bg) calc(r - 6) calc(g - 3) calc(b - 4)));

    :root[data-theme="light"] & {
      color: color-mix(in srgb, var(--lcd-ink) 18%, transparent);
    }
  }

  .trace {
    fill: none;
    stroke: var(--accent);
    stroke-width: 3;
    stroke-linecap: round;
    filter: drop-shadow(0 0 3px var(--accent)) drop-shadow(0 0 8px color-mix(in srgb, var(--accent) 50%, transparent));
  }

  /* Dark's map is a VFD, its route a segment cut to shape; the dot matrix is daylight's. */
  .matrix {
    display: none;
  }

  /* In daylight the map is a dot-matrix LCD: unlit pixels on the land's own grid, so the reflector
     drops the field's 9px dots, and the route one row of pixels about as big as Doto's, which
     switch on one at a time and off in a run of three for the trip; the cities stay whole lamps.
     Each casts its shadow on the reflector, so a pixel switched off leaves none: the mask cuts the
     dots and the shadow is filtered after it, on the group. */
  :root[data-theme="light"] & {
    .route-map {
      background: var(--display-reflector), var(--display-bevel);
    }

    .matrix {
      display: inline;
    }

    .pulse {
      display: none;
    }

    .land {
      color: color-mix(in srgb, var(--lcd-ink) 14%, transparent);
    }

    pattern circle {
      fill: color-mix(in srgb, var(--lcd-ink) 5%, transparent);
    }

    .route-line,
    .city,
    text {
      filter: drop-shadow(var(--lcd-shadow));
    }

    /* 84 intervals of 5.5 units on the 461-unit route; the period sits a hair under 1/84 so
       Virginia's dot is not lost to rounding past the end. */
    .route-map .trace {
      stroke: var(--lcd-ink);
      stroke-width: 3;
      stroke-dasharray: 0 0.011904;
      filter: none;
      mask: url(#route-segments);
    }

    .city,
    text {
      fill: var(--lcd-ink);
    }

    .route-map[data-power] :is(.origin, .server) {
      animation-name: lcd-dot-on;
    }
  }

  /* The mask's edges fall halfway between dots, so each step shows or hides whole pixels. The hole
     covers three and rests just before the start. */
  .reveal,
  .hole {
    fill: none;
    stroke-width: 14;
  }

  .reveal {
    stroke: white;
  }

  .hole {
    stroke: black;
    stroke-dasharray: 0.035714 3;
    stroke-dashoffset: 0.041667;
  }

  /* A bright dash that rides the trace there and back once, so it rests out of sight before 0. */
  .pulse {
    fill: none;
    stroke: color-mix(in srgb, var(--accent) 25%, white);
    stroke-width: 6;
    stroke-linecap: round;
    stroke-dasharray: 0.07 2;
    stroke-dashoffset: 0.07;
    filter: drop-shadow(0 0 4px var(--accent)) drop-shadow(0 0 12px var(--accent));
  }

  .city {
    fill: color-mix(in srgb, var(--accent) 60%, white);
    filter: drop-shadow(0 0 6px var(--accent)) drop-shadow(0 0 2px white);
  }

  text {
    font-family: "Doto", var(--mono);
    font-size: 24px;
    font-weight: 900;
    letter-spacing: 2px;
    fill: var(--accent);
    filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 70%, transparent));
  }

  /* site.js powers it on in view: São Paulo lights, the route draws to Virginia, which lights as the
     trace lands, then one round trip. Under reduced motion it is simply drawn. */
  .route-map[data-power] {
    .trace {
      stroke-dasharray: 1;
      animation: route-draw 1.2s cubic-bezier(0.4, 0, 0.2, 1) calc(var(--jitter, 0ms) + 0.5s) both;
    }

    .pulse {
      animation: route-trip 2.4s ease-in-out calc(var(--jitter, 0ms) + 2.2s) both;
    }

    .origin {
      animation: lamp-on 0.6s steps(1, end) var(--jitter, 0ms) both;
    }

    .server {
      animation: lamp-on 0.6s steps(1, end) calc(var(--jitter, 0ms) + 1.6s) both;
    }

    /* Daylight draws and trips through the mask, so the dots never slide along the route. */
    :root[data-theme="light"] & {
      .trace {
        animation: none;
      }

      .reveal {
        stroke-dasharray: 2;
        animation: route-draw-dots 1.2s steps(84) calc(var(--jitter, 0ms) + 0.5s) both;
      }

      .hole {
        animation: route-trip-dots 2.4s steps(88) calc(var(--jitter, 0ms) + 2.2s) both;
      }
    }
  }

  .route-map[data-power="off"] * {
    animation-play-state: paused;
  }

  /* The Caso CI readouts' sizes: theirs at full width, and on a phone, where they fit two to a row. */
  .route-facts {
    --figure: 40px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-32);
  }

  .route-head {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);

    h3 {
      max-width: 440px;
      font-size: clamp(24px, 2.2vw, 32px);
      font-weight: 600;
      line-height: 1.15;
      letter-spacing: -0.02em;
      text-wrap: balance;
    }
  }

  /* A figure's legend sits below its glass, as the home's figures do. */
  .route-figure,
  .trip {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    color: var(--muted);
  }

  .route-figure .readout {
    font-size: var(--figure);
  }

  .trip {
    align-self: stretch;
  }

  /* One grid with the bar, so each legend's column is its segment's, however the digits bend the
     shares; the grid's edge is the bezel's, where "Distância" starts. */
  .trip {
    display: grid;
    grid-template-columns: minmax(max-content, 170fr) minmax(max-content, 370fr);
    column-gap: 0;
  }

  .trip-bar,
  .trip-legend {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
  }


  /* Each segment as wide as its share of the round trip (the grid's fr), set as the readout above it
     is; never narrower than its digits, which at that size outgrow 170 ms's share on a phone. */
  .trip-bar {
    overflow: hidden;

    :root[data-theme="light"] & {
      background-position: right top;
    }

    /* The readout's padding and leading, so the bar stands as tall as the readout above it. */
    span {
      padding: var(--space-12) 18px;
      line-height: 1.15;
      white-space: nowrap;
    }

    b {
      font-family: "Doto", var(--mono);
      font-size: var(--figure);
      font-weight: 900;
      line-height: 1.15;
      letter-spacing: 2px;
      text-transform: uppercase;
      color: var(--accent);
      text-shadow: var(--emit-dots);

      :root[data-theme="light"] & {
        color: var(--lcd-ink);
      }
    }

    /* The trip's share is lit in negative: phosphor falling off toward the bezel, as a lit field
       does, and its digits the glass's dark, each with a dark halo where the others have a glow. */
    span:last-child {
      background: radial-gradient(130% 150% at 40% 45%, color-mix(in srgb, var(--accent) 95%, white), color-mix(in srgb, var(--accent) 72%, rgb(from var(--bg) calc(r - 6) calc(g - 3) calc(b - 4))));
      box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.22), 0 0 18px color-mix(in srgb, var(--accent) 35%, transparent);

      b {
        color: #041314;
        text-shadow:
          0 0 2px rgba(4, 19, 20, 0.8),
          0 0 7px rgba(4, 19, 20, 0.45);
      }

      /* In daylight a negative LCD segment: a dark field printed inside the window with reflector
         round it but on the 170 side, the digits clear to the reflector, and the field's pixels
         showing pale through it. Both grids hang from the bar's top right corner, the one edge the
         shares never move. */
      :root[data-theme="light"] & {
        --field-inset: 5px;
        position: relative;
        background: none;
        box-shadow: none;

        &::before {
          content: "";
          position: absolute;
          z-index: -1;
          inset: var(--field-inset) var(--field-inset) var(--field-inset) 0;
          border-radius: 0 calc(var(--radius-inset) - var(--field-inset)) calc(var(--radius-inset) - var(--field-inset)) 0;
          background:
            radial-gradient(circle, rgb(from var(--display-base) r g b / 0.09) 1.4px, transparent 1.9px)
              right calc(-1 * var(--field-inset)) top calc(-1 * var(--field-inset)) / 9px 9px,
            linear-gradient(#2a332e, var(--lcd-ink));
          box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
        }

        b {
          color: var(--display-base);
          text-shadow: none;
        }
      }
    }
  }

  @media (max-width: 899px) {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-32);
  }

  /* The cities paint at 22px, as the phone's readouts do, instead of shrinking with the map to 10px.
     Below about 375px they give way so VIRGÍNIA, 5.55em wide and ending 299.7 units in, keeps 12px of
     glass. A label is sized in the map's units, so it takes that size times the map's 730 units over
     its drawn width; tan(atan2()) is the ratio as a number, which dividing lengths is not everywhere.
     Each moves its cap middle back onto its dot, and São Paulo goes to its dot's left, as Virginia
     is, since to the right it would run 35px past the glass. */
  @media (max-width: 699px) {
    .route-map {
      container-type: inline-size;
    }

    text {
      --drawn: calc(100cqi - 2 * var(--space-16));
      --painted: min(22px, (var(--space-16) - 12px + var(--drawn) * 299.7 / 730) / 5.55);
      --label: calc(var(--painted) * tan(atan2(730px, var(--drawn))));
      font-size: var(--label);
      letter-spacing: calc(var(--label) / 11);
      translate: 0 calc(0.345 * var(--label) - 9px);

      &.origin {
        translate: -32px calc(0.345 * var(--label) - 9px);
        text-anchor: end;
      }
    }
  }

  @media (max-width: 479px) {
    .route-facts {
      --figure: 22px;
    }
  }
}

@keyframes route-draw {
  from {
    stroke-dashoffset: 1;
  }

  to {
    stroke-dashoffset: 0;
  }
}

@keyframes route-trip {
  50% {
    stroke-dashoffset: -0.93;
  }
}

/* Half a dot (0.5/84) past each step, so the reveal's edge never cuts one. */
@keyframes route-draw-dots {
  from {
    stroke-dashoffset: 1.994048;
  }

  to {
    stroke-dashoffset: 0.994048;
  }
}

/* From three and a half dots before São Paulo to half a dot past Virginia, 88 dots, and back. */
@keyframes route-trip-dots {
  50% {
    stroke-dashoffset: -1.005952;
  }
}

/* site.css lays the home's terminal out as a chat, a grid of rewrapped messages; a diff keeps its
   lines as written. */
.terminal {
  pre {
    display: block;
    white-space: pre;
  }

  .meta {
    color: var(--faint);
  }

  .hunk {
    color: var(--muted);
  }

  .del {
    color: #f07178;
  }

  .add {
    color: var(--accent);
    text-shadow: var(--emit);
  }
}

.contact p a {
  color: var(--accent);

  &:hover {
    color: var(--accent-hover);
  }
}

@keyframes day-rise {
  from {
    scale: 1 0;
  }
}

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