:root {
  --bg: #070a0b;
  --surface: #0c1213;
  --panel: #0a0f10;
  --line: #172022;
  --line-strong: #243033;
  --line-hover: #3a4a4d;
  --text: #eef4f4;
  --text-soft: #c4d2d3;
  --muted: #93a3a5;
  --faint: #6b7b7d;
  --ghost: #3e4b4d;
  --accent: #00cccc;
  --accent-hover: #33d6d6;
  --glow: rgba(0, 204, 204, 0.24);
  --emit: 0 0 1px rgba(0, 204, 204, 0.5), 0 0 7px rgba(0, 204, 204, 0.35), 0 0 20px rgba(0, 204, 204, 0.18);
  --emit-box: 0 0 5px rgba(0, 204, 204, 0.55), 0 0 16px rgba(0, 204, 204, 0.25);
  --emit-action: 0 0 1px rgba(255, 154, 60, 0.5), 0 0 7px rgba(255, 154, 60, 0.35), 0 0 20px rgba(255, 154, 60, 0.18);
  --emit-action-box: 0 0 5px rgba(255, 154, 60, 0.55), 0 0 16px rgba(255, 154, 60, 0.25);
  /* Doto's glyphs are sparse dots, so they need a stronger glow than solid text to read as lit. */
  --emit-dots: 0 0 2px rgba(0, 204, 204, 0.9), 0 0 10px rgba(0, 204, 204, 0.6), 0 0 28px rgba(0, 204, 204, 0.35);
  --emit-action-dots: 0 0 2px rgba(255, 154, 60, 0.9), 0 0 10px rgba(255, 154, 60, 0.6), 0 0 28px rgba(255, 154, 60, 0.35);
  /* A vacuum fluorescent display, after the rack study's unit readouts: a field of unlit phosphor
     dots in a bezel, under glass whose grid wires are the logo's lattice. */
  --bezel: 6px;
  --display-surface: radial-gradient(circle, rgba(0, 204, 204, 0.11) 1.4px, transparent 1.9px) 0 0 / 9px 9px, #051011;
  --display-bezel:
    inset 0 0 50px rgba(0, 0, 0, 0.9),
    inset 0 0 0 1px #0e2324,
    0 0 0 3px #040606,
    0 0 0 4px rgba(0, 0, 0, 0.55),
    0 -1px 0 var(--bezel) rgba(0, 0, 0, 0.75),
    0 1px 0 var(--bezel) rgba(255, 255, 255, 0.07);
  --display-glass:
    linear-gradient(115deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.02) 28%, transparent 42%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='10.392'%3E%3Cpath d='M0 0H6M0 5.196H6M0 0L6 10.392M6 0L0 10.392' stroke='black' stroke-opacity='0.55' stroke-width='0.8' fill='none'/%3E%3C/svg%3E") 0 0 / 6px 10.392px;
  --drop-blur: blur(2px);
  /* Chrome shows the room it is in: a lit ceiling above a sharp horizon, and this dark page below. */
  --chrome: linear-gradient(#e8eeee, #aab4b5 42%, #3b4546 47%, #263031 72%, #667374);
  /* The keys' dark cap: a moulded face, its grain, and edges lit from above. */
  --rubber: linear-gradient(#192224, #0e1314);
  --rubber-edge: #334143 #1f2a2c #131a1b;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.14 0 0 0 -0.04'/%3E%3C/filter%3E%3Crect width='96' height='96' filter='url(%23g)'/%3E%3C/svg%3E");
  /* A bright cap hides that white grain, so its own adds dark flecks under the white. */
  --grain-bright:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0.12 0 0 0 0 0.12 0.36 0 0 0 -0.15'/%3E%3C/filter%3E%3Crect width='96' height='96' filter='url(%23g)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.28 0 0 0 -0.12'/%3E%3C/filter%3E%3Crect width='96' height='96' filter='url(%23g)'/%3E%3C/svg%3E");
  --channel: #020303;
  --engrave-panel: 0 1px 0 rgba(255, 255, 255, 0.08), 0 -1px 0 rgba(0, 0, 0, 0.7);
  --action: #ff9a3c;
  --action-hover: #ffae63;
  --on-action: #140c04;
  /* Tailwind's spacing scale, named by its pixels. Gaps, padding and margins take a step of it; a
     value off the scale is fitted to its component and stays a literal there. */
  --space-4: 4px;
  --space-6: 6px;
  --space-8: 8px;
  --space-10: 10px;
  --space-12: 12px;
  --space-14: 14px;
  --space-16: 16px;
  --space-20: 20px;
  --space-24: 24px;
  --space-28: 28px;
  --space-32: 32px;
  --space-36: 36px;
  --space-40: 40px;
  --space-44: 44px;
  --space-48: 48px;
  --space-56: 56px;
  --space-64: 64px;
  --space-80: 80px;
  --space-96: 96px;
  --space-112: 112px;
  /* Text sizes. Doto readouts and fluid headings are sized to their boxes, not from here. */
  --font-size-11: 11px;
  --font-size-12: 12px;
  --font-size-13: 13px;
  --font-size-14: 14px;
  --font-size-15: 15px;
  --font-size-16: 16px;
  --font-size-17: 17px;
  --font-size-18: 18px;
  --font-size-19: 19px;
  --font-size-20: 20px;
  --font-size-26: 26px;
  --radius-inset: 10px;
  --radius-panel: 14px;
  --gutter: clamp(20px, 4.44vw, 64px);
  /* Stepped, where a fluid clamp() lands off the scale between its ends: 67px at 1000px wide. */
  --section-space: var(--space-96);
  --section-gap: var(--space-56);
  --header-height: 80px;
  --sans: "Geist", "Helvetica Neue", sans-serif;
  --mono: "Geist Mono", ui-monospace, monospace;
  --display: "Barlow Semi Condensed", "Arial Narrow", sans-serif;
  color-scheme: dark;

  @media (max-width: 1199px) {
    --section-space: var(--space-80);
    --section-gap: var(--space-48);
  }

  @media (max-width: 899px) {
    --section-space: var(--space-64);
    --section-gap: var(--space-32);
    --header-height: 72px;
  }
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-height);

  @media (prefers-reduced-motion: reduce) {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--font-size-16);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Out of flow rather than display: none, which drops the filters it defines in some browsers. */
.filter-defs {
  position: absolute;
}

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

h1,
h2,
h3,
p,
ul,
ol,
figure,
blockquote,
pre {
  margin: 0;
  padding: 0;
}

ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;

  &:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
  }
}

.wrap {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  color: var(--text);

  img {
    display: block;
    width: 28px;
    height: 25px;
    filter: drop-shadow(0 0 5px rgba(0, 204, 204, 0.4)) drop-shadow(0 0 14px rgba(0, 204, 204, 0.2));
  }

  .wordmark {
    font-family: var(--display);
    font-weight: 600;
    font-size: var(--font-size-26);
    line-height: 1;
    letter-spacing: 0.3px;
  }

  .slogan {
    font-family: var(--display);
    font-weight: 500;
    font-size: var(--font-size-26);
    line-height: 1;
    color: var(--faint);
  }
}

/* A key off the rack study's panels: a machined cap lit from above, standing in a well cut into the
   page, its label engraved, and a lamp lens that lights under the pointer. A key that opens contact
   lights in the action colour. A .button is the same key at panel size. */
.keycap,
.button {
  --lamp: var(--accent);
  --lamp-glow: var(--emit-box);
  --spill: transparent;
  --lens: 6px;
  --pad-x: 11px;
  --travel: 1px;
  --drop: var(--travel);
  --sink: calc(var(--travel) - var(--drop));
  --well: #020303;
  --well-gap: 2px;
  --cap-face: var(--rubber);
  --edge: var(--rubber-edge);
  --skirt: #0a0e0f;
  --rim: rgba(255, 255, 255, 0.07);
  --sheen: rgba(255, 255, 255, 0.05);
  --engrave: 0 1px 0 rgba(255, 255, 255, 0.08), 0 -1px 0 rgba(0, 0, 0, 0.7);
  --halo: 0 0 transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  margin-inline: var(--well-gap);
  padding: 7px var(--pad-x);
  border: 1px solid;
  border-color: var(--edge);
  border-radius: 5px;
  /* The lamp's spill is centred on the lens: the padding plus its radius. */
  background:
    radial-gradient(32px 100% at calc(var(--pad-x) + var(--lens) / 2) 50%, var(--spill), transparent),
    radial-gradient(140% 100% at 50% 0%, var(--sheen), transparent 70%),
    var(--grain),
    var(--cap-face);
  /* The skirt is the cap's front face. The well is two rings, one around the cap and one around its
     travel, because a single spread ring would open wider at the sides than at the ends; the page's
     rim is dark above it and catches light below. Sinking moves the cap and not the well. */
  box-shadow:
    inset 0 1px 0 var(--rim),
    0 var(--drop) 0 var(--skirt),
    0 calc(-1 * var(--sink)) 0 var(--well-gap) var(--well),
    0 calc(var(--travel) - var(--sink)) 0 var(--well-gap) var(--well),
    0 calc(-1 * var(--sink) - 1px) 0 var(--well-gap) rgba(0, 0, 0, 0.6),
    0 calc(var(--travel) - var(--sink) + 1px) 0 var(--well-gap) rgba(255, 255, 255, 0.07),
    var(--halo);
  translate: 0 var(--sink);
  font-family: var(--mono);
  font-size: var(--font-size-11);
  font-weight: 500;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--faint);
  text-shadow: var(--engrave);
  transition: color 0.15s;

  /* A domed lens set in the cap, tinted even when off, as the display's unlit phosphor is. */
  &::before {
    content: "";
    flex: none;
    width: var(--lens);
    aspect-ratio: 1;
    border-radius: 50%;
    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%, #0a0f10), #070a0b);
    box-shadow: inset 0 1px 1.5px rgba(0, 0, 0, 0.8), 0 0 0 1px #040606, 0 1px 0 1px rgba(255, 255, 255, 0.07);
  }

  &[href^="mailto:"],
  &[href="#contact"] {
    --lamp: var(--action);
    --lamp-glow: var(--emit-action-box);
  }

  &:hover,
  &:focus-visible {
    color: var(--text-soft);
  }

  /* Lit at rest in the open slot, as the study's "book this slot" key is. */
  &:hover,
  &:focus-visible,
  .next & {
    --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);
    }
  }

  &:active {
    --drop: 0px;
  }

  svg {
    flex: none;
    width: 11px;
    height: 11px;
  }
}

.button {
  --lens: 7px;
  --pad-x: var(--space-16);
  gap: var(--space-10);
  padding-block: var(--space-10);
  border-radius: 6px;
  font-size: var(--font-size-12);
  letter-spacing: 2px;
  color: var(--muted);

  &:hover,
  &:focus-visible {
    color: var(--text);
  }

  svg {
    width: 13px;
    height: 13px;
  }

  /* The call to action is an amber cap lit from inside, its light spilling out of the well, so it
     needs no lens of its own. */
  &.primary {
    --cap-face: linear-gradient(#ffac5c, #f2872b);
    --edge: #ffcf9e #e98128 #dc7620;
    --skirt: #a9530f;
    --rim: rgba(255, 255, 255, 0.45);
    --sheen: rgba(255, 255, 255, 0.28);
    --engrave: 0 1px 0 rgba(255, 226, 190, 0.4);
    --halo: 0 0 18px rgba(255, 154, 60, 0.28);
    color: var(--on-action);
    font-weight: 600;

    &::before {
      content: none;
    }

    &:hover,
    &:focus-visible {
      --cap-face: linear-gradient(#ffba77, #f7933a);
      --halo: 0 0 26px rgba(255, 154, 60, 0.45);
      color: var(--on-action);
    }
  }

  &.large {
    --lens: 8px;
    --pad-x: var(--space-24);
    gap: var(--space-12);
    padding-block: 15px;
    border-radius: 7px;
    font-size: var(--font-size-14);

    svg {
      width: 14px;
      height: 14px;
    }
  }
}

/* A two-position slide switch that is one link, to the other language. The thumb rests on the page's
   language, leans toward the other under the pointer and throws all the way while pressed. */
.lang-switch {
  --throw: 16px;
  --rest: 0;
  --toward: 1;
  --lean: 0px;
  display: flex;
  align-items: center;
  gap: var(--space-10);
  font-family: var(--mono);
  font-size: var(--font-size-11);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 1.5px;
  color: var(--faint);
  text-shadow: var(--engrave-panel);

  html:lang(en) & {
    --rest: 1;
    --toward: -1;
  }

  span {
    transition: color 0.15s, text-shadow 0.15s;
  }

  html:lang(pt) & [lang="pt-BR"],
  html:lang(en) & [lang="en"] {
    color: var(--accent);
    text-shadow: var(--emit);
  }

  /* The groove is cut into a surround of the keys' rubber, whose border is the surround's face. The
     outer shadows are the keys' edge colours, lit from above. */
  .slot {
    --bezel-width: 3px;
    display: grid;
    width: calc(var(--throw) * 2 + 4px + 2 * var(--bezel-width));
    height: calc(16px + 2 * var(--bezel-width));
    padding: 2px;
    border: var(--bezel-width) solid transparent;
    border-radius: 5px;
    background:
      linear-gradient(var(--channel), var(--channel)) padding-box,
      radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 70%) border-box,
      var(--grain) border-box,
      var(--rubber) border-box;
    box-shadow:
      inset 0 0 0 1px rgba(0, 0, 0, 0.8),
      inset 0 2px 3px rgba(0, 0, 0, 0.9),
      0 -1px 0 #334143,
      0 1px 0 #131a1b,
      0 0 0 1px #1f2a2c,
      0 2px 3px rgba(0, 0, 0, 0.6);

    &::before {
      content: "";
      width: var(--throw);
      border: 1px solid;
      border-color: var(--rubber-edge);
      border-radius: 3px;
      background: radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 70%), var(--grain), var(--rubber);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), 0 1px 0 #0a0e0f;
      translate: calc(var(--rest) * var(--throw) + var(--toward) * var(--lean));
      transition: translate 0.18s cubic-bezier(0.3, 0.7, 0.4, 1);

      @media (prefers-reduced-motion: reduce) {
        transition: none;
      }
    }
  }

  &:hover,
  &:focus-visible {
    --lean: 3px;
    color: var(--text-soft);
  }

  &:active {
    --lean: var(--throw);
  }
}

.eyebrow {
  font-family: var(--mono);
  font-size: var(--font-size-13);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: var(--emit);

  @media (max-width: 899px) {
    font-size: var(--font-size-12);
  }
}

.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);

  h2 {
    font-weight: 600;
    font-size: clamp(34px, 3.61vw, 52px);
    line-height: 1.08;
    letter-spacing: -0.038em;
    text-wrap: balance;

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

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

  &.centered {
    align-items: center;
    text-align: center;

    p {
      max-width: 560px;
    }
  }

  &.split {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--space-48);

    & > div {
      display: flex;
      flex-direction: column;
      gap: var(--space-16);
      max-width: 720px;
    }

    p {
      max-width: 420px;
    }

    @media (max-width: 899px) {
      flex-direction: column;
      align-items: flex-start;
      gap: var(--space-16);
    }
  }

  @media (max-width: 899px) {
    gap: var(--space-12);
  }
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;

  /* Runs past the header, so the blur eases off below it instead of ending on a line. */
  &::before {
    content: "";
    position: absolute;
    inset: 0 0 -32px;
    z-index: -1;
    background: color-mix(in srgb, var(--bg) 90%, transparent);
    backdrop-filter: var(--drop-blur);
    mask-image: linear-gradient(#000 var(--header-height), transparent);
    pointer-events: none;
    animation: header-drop linear both;
    animation-timeline: scroll();
    animation-range: 0 var(--header-height);
  }

  /* The padding is room over the row, which on desktop gives the key bank's labels the room above
     them that the plate has below it. */
  & > .wrap {
    display: flex;
    align-items: center;
    gap: var(--space-48);
    height: var(--header-height);
    padding-top: var(--space-8);

    @media (max-width: 1099px) {
      gap: var(--space-32);
    }

    /* Only the plate and the menu button are left, and 390px must hold the whole plate beside it. */
    @media (max-width: 999px) {
      gap: var(--space-12);
    }

    /* Equal side columns, so the key bank sits on the page's centre line whatever the widths of the
       plate and the actions. */
    @media (min-width: 1000px) {
      display: grid;
      grid-template-columns: 1fr auto 1fr;
    }
  }

  /* The brand on a nameplate of brushed dark metal, a groove cut 2px in from its rim and 13px of room
     inside it at the sides. As tall as the CTA key's 41.2px cap and its 1px skirt, which hangs below
     the key's box: the 1px margin lowers the plate by half of it, so they meet top and bottom.
     text-box trims the name to cap height over descenders, the mark's span, so centring hits ink. */
  .brand {
    position: relative;
    justify-self: start;
    height: 42.2px;
    margin-top: 1px;
    padding-inline: var(--space-16);
    border-radius: 6px;
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='48'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0025 1.8' numOctaves='2' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.12 0 0 0 -0.045'/%3E%3C/filter%3E%3Crect width='300' height='48' filter='url(%23b)'/%3E%3C/svg%3E"),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='48'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.003 2.2' numOctaves='2' seed='9' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0 0 0 -0.12'/%3E%3C/filter%3E%3Crect width='300' height='48' filter='url(%23b)'/%3E%3C/svg%3E"),
      linear-gradient(90deg, transparent 5%, rgba(255, 255, 255, 0.03) 30%, transparent 52%, rgba(255, 255, 255, 0.018) 78%, transparent 95%),
      linear-gradient(#1a2123, #121819 55%, #0e1314);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 -1px 0 rgba(0, 0, 0, 0.5);

    &::before {
      content: "";
      position: absolute;
      inset: 2px;
      border: 1px solid rgba(0, 0, 0, 0.6);
      border-radius: 4px;
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 0 rgba(255, 255, 255, 0.06);
      pointer-events: none;
    }

    img {
      width: auto;
      height: 23.5px;
    }

    .name {
      font-family: var(--display);
      font-size: var(--font-size-26);
      line-height: 1;
      white-space: nowrap;
      text-box: trim-both cap text;
    }

    .slogan {
      margin-left: var(--space-10);
      color: var(--muted);
      text-shadow: var(--engrave-panel);

      /* Below 1200px the key bank has no room beside it, and below 390px the menu button, so the
         page would scroll sideways or the button would be squeezed. */
      @media (min-width: 1000px) and (max-width: 1199px), (max-width: 389px) {
        display: none;
      }
    }

    /* The glass knob (?glass=1): the plate in clear glass, lit from above. The page shows through
       it, its rim is a chamfer 2px wide that catches the light at the top and lets it out at the
       bottom, and the name throws a shadow through the glass's depth. */
    &.is-glass {
      background:
        linear-gradient(115deg, transparent 13.6%, rgba(255, 255, 255, 0.06) 14% 26%, transparent 26.4% 30.6%, rgba(255, 255, 255, 0.035) 31% 33.6%, transparent 34%),
        radial-gradient(90% 150% at 8% -20%, rgba(255, 255, 255, 0.06), transparent 60%),
        linear-gradient(transparent 55%, rgba(0, 204, 204, 0.07)),
        rgba(12, 26, 28, 0.22);
      backdrop-filter: blur(1.5px) saturate(1.8) brightness(1.5);
      box-shadow:
        inset 0 0 0 2px rgba(200, 255, 250, 0.06),
        inset 0 -2px 0 rgba(0, 204, 204, 0.1),
        inset 0 -9px 8px -7px rgba(0, 204, 204, 0.12),
        0 1px 0 rgba(0, 0, 0, 0.8),
        0 2px 1px rgba(0, 204, 204, 0.1),
        0 5px 12px rgba(0, 0, 0, 0.45);

      /* Where the chamfer meets the face. */
      &::before {
        border: 0;
        box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.45), inset 0 0.5px 0 rgba(255, 255, 255, 0.14);
      }

      /* The rim's glint, brightest where the light comes in and where it leaves. */
      &::after {
        content: "";
        position: absolute;
        inset: 0;
        padding: 1px;
        border-radius: inherit;
        background: linear-gradient(165deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.16) 22%, rgba(255, 255, 255, 0.06) 50%, rgba(140, 255, 245, 0.16) 78%, rgba(170, 255, 248, 0.32));
        mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
        pointer-events: none;
      }

      .name,
      .slogan {
        text-shadow: 0 2px 3px rgba(0, 0, 0, 0.6);
      }
    }
  }

  nav {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-32);

    /* normal takes the header's own column gap, which the subgrid's tracks were laid out with. */
    @media (min-width: 1000px) {
      grid-column: 2 / 4;
      display: grid;
      grid-template-columns: subgrid;
      column-gap: normal;
    }

    /* A bank of latching keys, after a deck's source selector: chrome keys in one channel, each under
       its label, and the key of the section on screen stays down with its label lit. The columns
       share one width, the widest label's, so every key is the same size. */
    ul {
      --key: 9px;
      --key-radius: 3px;
      --travel: 3px;
      --label-size: var(--font-size-11);
      --label-gap: var(--space-10);
      --label-room: var(--space-12);
      display: flex;
      gap: var(--space-32);
      font-size: var(--font-size-15);

      @media (max-width: 1099px) {
        --label-room: var(--space-4);
      }

      /* The margin mirrors the labels below the keys, plus the travel the channel hangs by, so the
         row centres the channel on the plate and the actions and the labels stand above it. */
      @media (min-width: 1000px) {
        position: relative;
        isolation: isolate;
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 1fr;
        gap: var(--space-4);
        margin-bottom: calc(var(--label-size) + var(--label-gap) + var(--travel));

        &::before {
          content: "";
          position: absolute;
          inset: auto -3px calc(-3px - var(--travel));
          z-index: -1;
          height: calc(var(--key) + var(--travel) + 6px);
          border-radius: calc(var(--key-radius) + 3px);
          background: var(--channel);
          box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.9), 0 -1px 0 rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.07);
        }

        /* The hero's Seven caught in the chrome, placed by hero-scene.js: its face lands between
           --glint-from and --glint-to along the bank, its bloom spreads further, --glint is how bright,
           and the drive pulse's front runs across it between --flare-from and --flare-to. Lying below
           the bank, it shows only under the chrome's horizon. Overlay blending tints the keys and
           leaves the dark channel dark. */
        &::after {
          --soft: 60px;
          --halo: 360px;
          content: "";
          position: absolute;
          inset: auto 0 calc(-1 * var(--travel));
          height: calc(var(--key) + var(--travel));
          background:
            linear-gradient(90deg, transparent calc(var(--flare-from) - var(--soft)), rgb(170 255 255 / var(--flare, 0)) var(--flare-from) var(--flare-to), transparent calc(var(--flare-to) + var(--soft))),
            linear-gradient(90deg, transparent calc(var(--glint-from) - var(--soft)), rgba(0, 204, 204, 0.5) var(--glint-from) var(--glint-to), transparent calc(var(--glint-to) + var(--soft))),
            linear-gradient(90deg, transparent calc(var(--glint-from) - var(--halo)), rgba(0, 204, 204, 0.08) calc(var(--glint-from) - var(--halo) / 2), rgba(0, 204, 204, 0.25) var(--glint-from) var(--glint-to), rgba(0, 204, 204, 0.08) calc(var(--glint-to) + var(--halo) / 2), transparent calc(var(--glint-to) + var(--halo)));
          mask-image: linear-gradient(transparent calc(var(--key) * 0.3), #000 calc(var(--key) * 0.65));
          mix-blend-mode: overlay;
          opacity: var(--glint, 0);
          pointer-events: none;
        }
      }
    }

    ul a {
      color: var(--muted);

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

      @media (min-width: 1000px) {
        --drop: var(--travel);
        --sink: calc(var(--travel) - var(--drop));
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--label-gap);
        padding-inline: var(--label-room);
        font-family: var(--mono);
        font-size: var(--label-size);
        font-weight: 500;
        line-height: 1;
        letter-spacing: 1.5px;
        text-transform: uppercase;
        white-space: nowrap;
        color: var(--faint);
        text-shadow: var(--engrave-panel);
        transition: color 0.15s, text-shadow 0.15s;

        @media (max-width: 1099px) {
          letter-spacing: 1px;
        }

        &::after {
          content: "";
          align-self: stretch;
          height: var(--key);
          margin-inline: calc(-1 * var(--label-room));
          border-radius: var(--key-radius);
          background: var(--chrome);
          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 var(--drop) 0 #56615f;
          translate: 0 var(--sink);
          transition: translate 0.12s, box-shadow 0.12s;
        }

        &:hover,
        &:focus-visible {
          color: var(--text-soft);
        }

        &:active,
        &[aria-current] {
          --drop: 1px;
        }

        &[aria-current] {
          color: var(--accent);
          text-shadow: var(--emit);
        }
      }
    }
  }

  .actions {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: var(--space-12);
  }

  /* A rubber key as tall as the CTA key's cap, so its skirt meets the plate top and bottom as the CTA
     does on desktop. It has no lamp, and stays down while its menu is open. */
  .menu-button {
    --lamp: transparent;
    display: none;
    place-items: center;
    width: 41.2px;
    height: 41.2px;
    padding: 0;
    cursor: pointer;

    &::before {
      content: none;
    }

    svg {
      width: 20px;
      height: 20px;
    }

    .close {
      display: none;
    }

    &:focus-visible {
      outline: 2px solid var(--accent);
      outline-offset: 3px;
    }
  }

  @media (max-width: 999px) {
    & > .wrap {
      justify-content: space-between;
    }

    .menu-button {
      display: grid;
    }

    nav {
      display: none;
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      flex-direction: column;
      align-items: stretch;
      gap: var(--space-24);
      padding: var(--space-8) var(--gutter) var(--space-24);
      border-bottom: 1px solid var(--line);
      background: var(--bg);

      ul {
        flex-direction: column;
        gap: 0;
        font-size: var(--font-size-17);
      }

      ul a {
        display: block;
        padding: var(--space-14) 0;
        border-bottom: 1px solid var(--line);
      }
    }

    .actions {
      justify-content: space-between;
    }

    &.is-open {
      &::before {
        background: var(--bg);
        animation: none;
      }

      nav {
        display: flex;
      }

      .menu-button {
        --drop: 0px;

        .open {
          display: none;
        }

        .close {
          display: inline;
        }
      }
    }
  }
}

/* Lighter at the top of the page, so the hero still shows through; a browser without scroll
   timelines jumps straight to the end and keeps the full tint. */
@keyframes header-drop {
  from {
    opacity: 0.35;
  }
}

.hero {
  position: relative;
  overflow: hidden;
  min-height: min(880px, 61.11vw);

  /* Starts under the sticky header, so the scene shows through it at the top of the page. */
  &:has(.hero-scene) {
    overflow: clip visible;
    box-sizing: content-box;
    margin-top: calc(-1 * var(--header-height));
    padding-top: var(--header-height);
    /* A finger dragged across turns the Seven (hero-scene.js); up and down still scroll. */
    touch-action: pan-y pinch-zoom;
  }

  .hero-copy {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-28);
    padding-top: clamp(64px, 8.9vw, 128px);
    padding-bottom: var(--space-64);
  }

  .pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-10);
    padding: 7px var(--space-14);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: rgba(12, 18, 19, 0.8);
    font-family: var(--mono);
    font-size: var(--font-size-13);
    line-height: 1.4;
    color: var(--text-soft);

    &::before {
      content: "";
      width: 8px;
      height: 8px;
      background: var(--accent);
      box-shadow: var(--emit-box);
      transform: skewX(-30deg);
    }
  }

  h1 {
    max-width: min(700px, 50vw);
    font-weight: 600;
    font-size: clamp(44px, 5.56vw, 80px);
    line-height: 1.02;
    letter-spacing: -0.0425em;

    .emphasis {
      color: var(--action);
      text-shadow: 0 0 28px rgba(255, 154, 60, 0.3);
    }
  }

  .lead {
    max-width: min(560px, 44vw);
    font-size: clamp(17px, 1.39vw, 20px);
    color: var(--muted);
  }

  .hero-actions {
    display: flex;
    gap: var(--space-12);
    margin-top: var(--space-8);
  }

  /* The canvas runs on past the frame, up under the header and down under the client band; the
     padding is that run, and content-box keeps the aspect ratio on the frame alone. */
  .hero-scene {
    --bleed-above: var(--header-height);
    --bleed-below: 200px;
    position: absolute;
    bottom: calc(-1 * var(--bleed-below));
    left: 50%;
    translate: -50% 0;
    box-sizing: content-box;
    width: min(1440px, 100%);
    aspect-ratio: 1440 / 880;
    padding-top: var(--bleed-above);
    padding-bottom: var(--bleed-below);

    &::before {
      --frame-height: calc(100% - var(--bleed-above) - var(--bleed-below));
      content: "";
      position: absolute;
      left: 44.44%;
      top: calc(var(--bleed-above) + var(--frame-height) * 0.0227);
      width: 59.72%;
      height: calc(var(--frame-height) * 0.7955);
      background: radial-gradient(closest-side, var(--glow), transparent);
    }

    &::after {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(90deg, rgba(7, 10, 11, 0.92) 0%, rgba(7, 10, 11, 0.6) 38%, rgba(7, 10, 11, 0) 58%);
    }

    picture {
      position: absolute;
      inset: 0 0 var(--bleed-below);
      transition: opacity 0.8s ease;
    }

    /* The desktop art runs 120 units above the frame; scaled to the width and pinned to the
       bottom, it shows just the header's height of that at any desktop width. */
    img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: bottom;
    }

    canvas {
      position: absolute;
      inset: 0;
      display: block;
      width: 100%;
      height: 100%;
      opacity: 0;
      transition: opacity 0.8s ease;
      mask-image: linear-gradient(#000 calc(100% - var(--bleed-below)), transparent);
    }

    &.is-live {
      picture {
        opacity: 0;
      }

      canvas {
        opacity: 1;
      }
    }

    /* Past 1440px the frame stays 1440 wide and centred, and padding either side runs the canvas out
       to the page's edges, as it runs above and below. The glow, the copy's shade and the art keep to
       the frame; the art there is a wider drawing of the same wall, shown 1:1. */
    @media (min-width: 1441px) {
      --bleed-side: calc((100% - 1440px) / 2);
      padding-inline: var(--bleed-side);

      &::before {
        left: calc(var(--bleed-side) + 640px);
        width: 860px;
      }

      &::after {
        background: linear-gradient(90deg, rgba(7, 10, 11, 0) 0, rgba(7, 10, 11, 0.92) var(--bleed-side), rgba(7, 10, 11, 0.6) calc(var(--bleed-side) + 547px), rgba(7, 10, 11, 0) calc(var(--bleed-side) + 835px));
      }

      img {
        object-fit: none;
        object-position: center bottom;
      }
    }
  }

  @media (max-width: 899px) {
    min-height: 0;

    /* The mobile design's faint triangle lattice, faded out from the headline. */
    &::before {
      content: "";
      position: absolute;
      inset: 0;
      background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='110.851'%3E%3Cpath d='M0 0H64M0 55.4256H64M0 0L64 110.851M64 0L0 110.851' stroke='rgba(255,255,255,0.06)' fill='none'/%3E%3C/svg%3E") 0 0 / 64px 110.851px;
      mask-image: radial-gradient(ellipse 90% 50% at 30% 10%, #000 0%, transparent 75%);
    }

    .hero-copy {
      gap: 22px;
      padding-top: var(--space-56);
      padding-bottom: 0;
    }

    .pill {
      gap: var(--space-8);
      padding: var(--space-6) var(--space-12);
      font-size: var(--font-size-12);

      &::before {
        width: 7px;
        height: 7px;
      }
    }

    h1 {
      max-width: none;
      font-size: clamp(40px, 11.3vw, 56px);
      line-height: 1.05;
    }

    .lead {
      max-width: 560px;
      font-size: var(--font-size-17);
    }

    .hero-actions {
      flex-direction: column;
      align-self: stretch;
      gap: var(--space-10);
      margin-top: 0;
    }

    /* The Seven fills the top of the screen and the copy stands at the bottom, over the Seven's
       foot, whose depth in the frame is 0.89 of its width. On a screen too short for both, the
       copy's padding keeps the pill on the foot and the hero grows instead. */
    &:has(.hero-scene) {
      --frame-top: calc(var(--header-height) - 22px);
      --frame-width: min(90vw, 440px, 50svh);
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
      min-height: calc(100svh - var(--header-height));

      &::before {
        content: none;
      }

      .hero-copy {
        gap: var(--space-20);
        padding-top: calc(var(--frame-top) + var(--frame-width) * 0.89 - var(--header-height) - 36px);
        padding-bottom: 22px;
      }
    }

    /* The frame is the content box, flush right; the padding around it is the canvas's run over
       the whole hero and on under the client band. */
    .hero-scene {
      --bleed-above: var(--frame-top);
      --bleed-below: 160px;
      inset: 0 0 auto;
      translate: none;
      box-sizing: border-box;
      width: 100%;
      height: calc(100% + var(--bleed-below));
      padding-left: calc(100% - var(--frame-width));

      &::before {
        left: calc(100% - var(--frame-width) * 1.0256);
        top: var(--frame-top);
        width: calc(var(--frame-width) * 1.0513);
        height: calc(var(--frame-width) * 0.9744);
      }

      &::after {
        background: linear-gradient(rgba(7, 10, 11, 0) calc(var(--frame-top) + var(--frame-width) * 0.59), rgba(7, 10, 11, 0.86) calc(var(--frame-top) + var(--frame-width)));
      }

      picture {
        inset: var(--frame-top) 0 auto auto;
        width: var(--frame-width);
        aspect-ratio: 390 / 420;
      }
    }
  }
}

@keyframes client-roll {
  to {
    translate: -100% 0;
  }
}

/* Sizing: equal box area (height by 1/sqrt(ratio)), eased toward equal ink by --density, the
   share of its box the ink covers, to the 0.25 power; --scale is a by-eye residual. Each logo
   then moves halfway from box-centred to --ink-center, where its ink balances (both measured per
   SVG): all the way let a globe or a shield's point stick out. --shift is a by-eye extra, as a
   share of the height. The name stays as text for screen readers, pushed out of the box. */
.logo-list li,
.client-grid li[class] strong,
.language-row li span,
.site-footer .social span {
  flex: none;
  height: calc(var(--size) * var(--scale, 1) / pow(var(--density, 1), 0.25) / sqrt(var(--ratio)));
  translate: 0 calc((0.5 - var(--ink-center, 0.5)) * 50% + var(--shift, 0%));
  aspect-ratio: var(--ratio);
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-indent: 100%;
  background: var(--logo-tint, var(--ghost));
  mask: var(--logo) center / contain no-repeat;
  transition: background-color 0.2s ease;

  &:hover {
    background-color: var(--logo-lit, var(--text));
  }
}

/* Each client's logo and its measured sizing, shared by the band and the grid; the grid's logo is
   the cell's <strong>, which inherits them. */
:is(.client-band, .client-grid) li {
  &.itau {
    --logo: url("../img/clients/itau.svg");
    --ratio: 1;
    --density: 0.788;
    --scale: 0.8;
    --ink-center: 0.475;
  }

  &.carrefour {
    --logo: url("../img/clients/carrefour.svg");
    --ratio: 5.51;
    --density: 0.278;
    --ink-center: 0.532;
  }

  &.casas-bahia {
    --logo: url("../img/clients/casas-bahia.svg");
    --ratio: 9.48;
    --density: 0.423;
    --ink-center: 0.526;
  }

  &.americanas {
    --logo: url("../img/clients/americanas.svg");
    --ratio: 6.41;
    --density: 0.497;
    --scale: 1.15;
  }

  &.cambridge {
    --logo: url("../img/clients/cambridge.svg");
    --ratio: 4.77;
    --density: 0.239;
    --ink-center: 0.429;
  }

  &.cyrela {
    --logo: url("../img/clients/cyrela.svg");
    --ratio: 4.13;
    --density: 0.199;
    --ink-center: 0.587;
  }

  &.porto {
    --logo: url("../img/clients/porto.svg");
    --ratio: 4.38;
    --density: 0.462;
    --ink-center: 0.532;
  }

  &.grupo-sinal {
    --logo: url("../img/clients/grupo-sinal.svg");
    --ratio: 6;
    --density: 0.362;
    --ink-center: 0.451;
    --shift: 8%;
  }

  &.central-de-intercambio {
    --logo: url("../img/clients/central-de-intercambio.svg");
    --ratio: 2.83;
    --density: 0.209;
    --ink-center: 0.709;
  }

  &.abn-amro {
    --logo: url("../img/clients/abn-amro.svg");
    --ratio: 4.09;
    --density: 0.31;
    --ink-center: 0.345;
  }

  &.a-house {
    --logo: url("../img/clients/a-house.svg");
    --ratio: 4.54;
    --density: 0.435;
    --ink-center: 0.408;
  }

  &.abipe {
    --logo: url("../img/clients/abipe.svg");
    --ratio: 4.16;
    --density: 0.517;
  }

  &.americanas-com {
    --logo: url("../img/clients/americanas-com.svg");
    --ratio: 7.09;
    --density: 0.441;
  }

  &.atech {
    --logo: url("../img/clients/atech.svg");
    --ratio: 4.82;
    --density: 0.344;
    --ink-center: 0.489;
  }

  &.b2w {
    --logo: url("../img/clients/b2w.svg");
    --ratio: 1;
    --density: 0.641;
  }

  &.ccz-eletrica {
    --logo: url("../img/clients/ccz-eletrica.svg");
    --ratio: 5.76;
    --density: 0.167;
    --ink-center: 0.462;
  }

  &.cdf {
    --logo: url("../img/clients/cdf.svg");
    --ratio: 2.98;
    --density: 0.562;
  }

  &.excelia {
    --logo: url("../img/clients/excelia.svg");
    --ratio: 3.93;
    --density: 0.317;
    --ink-center: 0.614;
  }

  &.expressa {
    --logo: url("../img/clients/expressa.svg");
    --ratio: 2.01;
    --density: 0.238;
    --ink-center: 0.546;
  }

  &.foco {
    --logo: url("../img/clients/foco.svg");
    --ratio: 4.48;
    --density: 0.212;
    --ink-center: 0.482;
  }

  &.fertilitat {
    --logo: url("../img/clients/fertilitat.svg");
    --ratio: 3.15;
    --density: 0.217;
  }

  &.lineastudio {
    --logo: url("../img/clients/lineastudio.svg");
    --ratio: 11.76;
    --density: 0.562;
  }

  &.lumini {
    --logo: url("../img/clients/lumini.svg");
    --ratio: 3.12;
    --density: 0.36;
  }

  &.maru {
    --logo: url("../img/clients/maru.svg");
    --ratio: 4.34;
    --density: 0.209;
  }

  &.mastersaf {
    --logo: url("../img/clients/mastersaf.svg");
    --ratio: 5.09;
    --density: 0.301;
    --ink-center: 0.431;
  }

  &.minerbo-fuchs {
    --logo: url("../img/clients/minerbo-fuchs.svg");
    --ratio: 2.32;
    --density: 0.455;
    --ink-center: 0.454;
  }

  &.musiartes {
    --logo: url("../img/clients/musiartes.svg");
    --ratio: 3.35;
    --density: 0.208;
    --ink-center: 0.423;
  }

  &.new-age {
    --logo: url("../img/clients/new-age.svg");
    --ratio: 4.7;
    --density: 0.316;
  }

  &.norsul {
    --logo: url("../img/clients/norsul.svg");
    --ratio: 8.26;
    --density: 0.346;
  }

  &.otorrino-carpes {
    --logo: url("../img/clients/otorrino-carpes.svg");
    --ratio: 3.4;
    --density: 0.064;
    --ink-center: 0.482;
  }

  &.sindirrefino {
    --logo: url("../img/clients/sindirrefino.svg");
    --ratio: 2.57;
    --density: 0.561;
  }

  &.toptal {
    --logo: url("../img/clients/toptal.svg");
    --ratio: 3.51;
    --density: 0.361;
  }

  &.unitri {
    --logo: url("../img/clients/unitri.svg");
    --ratio: 2.35;
    --density: 0.241;
    --ink-center: 0.512;
  }

  &.upgrade {
    --logo: url("../img/clients/upgrade.svg");
    --ratio: 3.41;
    --density: 0.377;
    --ink-center: 0.461;
  }

  /* The eye centres the letters, not the bracket above them: they span 0.28-1 of the height, so
     their middle (0.64) needs a 10.8% lift beyond the ink centre's. */
  &.vdi-brasil {
    --logo: url("../img/clients/vdi-brasil.svg");
    --ratio: 1.6;
    --density: 0.396;
    --ink-center: 0.565;
    --shift: -10.8%;
  }

  &.vida-alimentos {
    --logo: url("../img/clients/vida-alimentos.svg");
    --ratio: 1.36;
    --density: 0.634;
  }

  &.whirlpool {
    --logo: url("../img/clients/whirlpool.svg");
    --ratio: 3;
    --density: 0.276;
    --ink-center: 0.448;
  }
}

.client-band {
  --size: 45px;
  --gap: var(--space-64);
  --fade: 96px;
  position: relative;
  padding: var(--space-64) 0 var(--section-space);

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    backdrop-filter: var(--drop-blur);
    mask-image: linear-gradient(transparent, #000 128px);
  }

  .wrap {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-28);
  }

  .eyebrow {
    align-self: flex-start;
  }

  .client-marquee {
    display: flex;
    justify-content: center;
    width: 100%;

    /* The trailing padding is the seam between the two copies, so it matches the gap. The block
       padding is room for the --ink-center shifts, which the overflow and the edge mask would
       otherwise clip; the negative margin takes it back out of the layout. */
    &.is-rolling {
      justify-content: flex-start;
      overflow: hidden;
      padding-block: calc(var(--size) / 4);
      margin-block: calc(var(--size) / -4);
      mask-image: linear-gradient(90deg, transparent, #000 var(--fade), #000 calc(100% - var(--fade)), transparent);

      ul {
        display: flex;
        flex: none;
        flex-wrap: nowrap;
        width: max-content;
        max-width: none;
        gap: var(--gap);
        padding-right: var(--gap);
        animation: client-roll 116s linear infinite;
      }

      &:hover ul {
        animation-play-state: paused;
      }
    }
  }

  /* Static, when the list does not roll: narrow enough that the fifteen logos wrap as three rows of five. */
  ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--space-32) var(--gap);
    max-width: 1000px;
  }

  @media (max-width: 1099px) {
    --gap: var(--space-48);
  }

  @media (max-width: 899px) {
    --size: 34px;
    --gap: var(--space-40);
    --fade: 48px;
    padding-top: var(--space-48);

    .wrap {
      gap: var(--space-20);
    }

    ul {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      place-items: center;
      gap: var(--space-28) var(--space-20);
      width: 100%;
    }
  }
}

.section {
  padding-block: var(--section-space);
  border-top: 1px solid var(--line);

  & > .wrap {
    display: flex;
    flex-direction: column;
    gap: var(--section-gap);
  }
}

.card-grid {
  --tile-padding: var(--space-36);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-panel);
  background: var(--line);

  li {
    display: flex;
    flex-direction: column;
    gap: var(--space-14);
    padding: var(--tile-padding);
    background: var(--bg);
  }

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

  p {
    color: var(--muted);
  }

  /* A teal cap lit from inside, as the call to action is amber, so a service never reads as one of
     the products' dark tiles. */
  .icon {
    border-color: #7ff0f0 #00c2c2 #00a6a6;
    background:
      radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.3), transparent 70%),
      var(--grain-bright),
      linear-gradient(#22dede, #00b4b4);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.45),
      0 1px 0 #006f6f,
      0 0 0 2px #020303,
      0 0 18px rgba(0, 204, 204, 0.28);
    color: #031414;
  }

  /* The featured tile spans both rows and takes their lines through subgrid, so the terminal starts
     on the divider of the column beside it. Its -1px top margin covers the grid's 1px row gap, which
     is where that divider is drawn. */
  &.bento .featured {
    display: grid;
    grid-template-rows: subgrid;
    grid-column: span 2;
    grid-row: span 2;
    row-gap: normal;
    background: radial-gradient(80% 60% at 0% 0%, rgba(0, 204, 204, 0.08), transparent), var(--bg);

    .intro {
      display: flex;
      flex-direction: column;
      gap: var(--space-14);
    }

    .terminal {
      width: auto;
      max-width: none;
      margin: -1px calc(-1 * var(--tile-padding)) calc(-1 * var(--tile-padding));
      border-width: 1px 0 0;
      border-color: var(--line);
      border-radius: 0;
    }
  }

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

    &.bento {
      .featured {
        display: flex;
        grid-row: auto;

        .terminal {
          margin-top: var(--space-16);
        }
      }

      li:last-child {
        grid-column: span 2;
      }
    }
  }

  @media (max-width: 599px) {
    --tile-padding: var(--space-24);
    grid-template-columns: minmax(0, 1fr);

    li:not(.featured),
    &.bento .featured .intro {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      align-items: center;
      gap: var(--space-14) var(--space-16);

      p {
        grid-column: 1 / -1;
      }
    }

    h3 {
      margin-top: 0;
      font-size: var(--font-size-18);
    }

    p {
      font-size: var(--font-size-15);
    }

    &.bento {
      .featured,
      li:last-child {
        grid-column: auto;
      }

      /* One column makes the featured tile as narrow as the rest, so it keeps to their length. */
      .featured .wide-only {
        display: none;
      }
    }
  }
}

.icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-inset);
  background: var(--surface);
  color: var(--accent);

  svg {
    width: 20px;
    height: 20px;
  }
}

.products {
  background: var(--surface);
}

/* Below 1100px a vertical list, with the rail down the left edge. From 1100px an alternating timeline:
   seven columns, each product anchored to its own column and spanning two, odd ones above the rail and
   even ones below it, so neighbours on the same side never collide. */
.product-timeline {
  --dot: 11px;
  --year-size: 34px;
  /* The readout's box: its line-height of 1.15 and 12px of padding above and below. */
  --year-height: calc(var(--year-size) * 1.15 + 24px);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  max-width: 640px;
  margin-inline: auto;

  li {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-14);
    padding: 0 0 var(--space-40) var(--space-36);

    &::before {
      content: "";
      position: absolute;
      z-index: 1;
      top: calc(var(--year-height) / 2 - var(--dot) / 2);
      left: 0;
      width: var(--dot);
      aspect-ratio: 1;
      border-radius: 50%;
      background: var(--accent);
      box-shadow: 0 0 0 5px var(--surface), 0 0 14px 5px var(--glow);
    }

    &:not(:last-child)::after {
      content: "";
      position: absolute;
      top: calc(var(--year-height) / 2);
      bottom: calc(var(--year-height) / -2);
      left: calc(var(--dot) / 2 - 0.5px);
      width: 1px;
      background: var(--line-strong);
    }

    &:has(+ .next)::after {
      background: repeating-linear-gradient(180deg, var(--action) 0 4px, transparent 4px 9px);
    }

    &:last-child {
      padding-bottom: 0;
    }

    &.interadmin {
      --mark: url("../img/products/interadmin.svg");
      --mark-size: 23px;
    }

    &.intermail {
      --mark: url("../img/products/intermail.svg");
      --mark-size: 26px;
    }

    &.maru {
      --mark: url("../img/products/maru.svg");
      --mark-size: 29px;
    }

    &.hanayomi {
      --mark: url("../img/products/hanayomi.svg");
      --mark-size: 29px;
    }
  }

  /* The bezel paints 1px further than its width outside the box, and would eat half the gap below. */
  .year {
    margin-bottom: calc(var(--bezel) + 1px);
    font-size: var(--year-size);
  }

  .product-title {
    display: flex;
    align-items: center;
    gap: var(--space-14);
  }

  /* fpag has no vector mark, so its tile sets the favicon's "Fp" as text; every other tile is empty
     and draws its product's mark. The tile is as tall as the name and the line under it. */
  .icon {
    flex: none;
    width: 48px;
    height: 48px;
    background: var(--bg);
    font-weight: 600;
    font-size: var(--font-size-19);
    line-height: 1;
    letter-spacing: -0.02em;

    &:empty::before {
      content: "";
      width: var(--mark-size);
      aspect-ratio: 1;
      background: currentColor;
      mask: var(--mark) center / contain no-repeat;
    }
  }

  h3 {
    font-size: var(--font-size-20);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.3px;
  }

  p {
    color: var(--muted);
  }

  li > p {
    text-wrap: pretty;
  }

  hgroup {
    display: flex;
    flex-direction: column;
    gap: 2px;

    p {
      font-family: var(--mono);
      font-size: var(--font-size-13);
      color: var(--faint);
    }
  }

  /* The stack, then the key under it: a key beside the stack does not fit a column at 1440px. */
  .product-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-14);
    padding-top: var(--space-14);
    border-top: 1px solid var(--line);
    font-family: var(--mono);
    font-size: var(--font-size-13);
    color: var(--faint);
  }

  .next {
    &::before {
      background: var(--surface);
      box-shadow: inset 0 0 0 1.5px var(--action), 0 0 0 5px var(--surface);
    }

    .year {
      --lamp: var(--action);
      --lamp-dots: var(--emit-action-dots);
    }

    /* A dot-matrix panel like the readout above it, with a plus lit where a product's mark would be.
       Its dots carry their own colours, so it is an image rather than a mask. */
    .icon {
      background: #051011;

      &::before {
        width: 35px;
        background: url("../img/products/next.svg") center / contain no-repeat;
        mask: none;
        filter: drop-shadow(0 0 1.5px rgba(255, 154, 60, 0.9)) drop-shadow(0 0 6px rgba(255, 154, 60, 0.45));
      }
    }
  }

  @media (min-width: 1100px) {
    --inset: calc(var(--bezel) + 24px);
    grid-template-columns: repeat(7, minmax(0, 1fr));
    max-width: none;
    padding-inline: var(--inset);

    /* Narrower, a 40px year runs into the next product's dot. */
    @media (min-width: 1280px) {
      --year-size: 40px;
    }

    /* The rail is one display, and each year lights on it at its product's column. It reaches into
       the padding, so the first product's dot lands on it too. The glass is a layer of its own above
       the products, so its wires cross the years and the dots. Both are grid items, so they sit on
       the line between the two sides whatever height the products above it reach. */
    &::before,
    &::after {
      content: "";
      grid-row: 4;
      grid-column: 1 / -1;
      align-self: start;
      height: var(--year-height);
      margin-inline: calc(var(--bezel) - var(--inset));
      border-radius: var(--radius-inset);
      translate: 0 -50%;
      pointer-events: none;
    }

    &::before {
      background: var(--display-surface);
      box-shadow: var(--display-bezel);
    }

    &::after {
      z-index: 2;
      background: var(--display-glass);
    }

    li {
      --indent: 22px;
      --clearance: calc(var(--year-height) / 2 + 56px);
      /* Where the display's bezel begins, so each product's line stops at it. */
      --bezel-edge: calc(var(--year-height) / 2 + var(--bezel));
      z-index: 1;
      /* Each side shares three rows (title, description, links), so its products and the open slot
         line up whatever their copy runs to. */
      display: grid;
      grid-template-rows: subgrid;
      padding: 0 var(--space-32) 0 var(--indent);
      border-left: 1px solid;

      /* Each product's dot is a lamp on the display, where its line meets the rail. */
      &::before {
        left: calc(var(--dot) / -2 - 0.5px);
        box-shadow: var(--emit-box);
      }

      &.next::before {
        background: none;
        box-shadow: inset 0 0 0 1.5px var(--action), var(--emit-action-box);
      }

      /* It powers on with its year, so both take the rail's step and neither the jitter. */
      &:has(> .year[data-power])::before {
        animation: lamp-on 0.6s steps(1, end) calc(var(--step) * 120ms) both;
      }

      &:has(> .year[data-power="off"])::before {
        animation-play-state: paused;
      }

      &:not(:last-child)::after {
        content: none;
      }

      /* The display is the box, so each year drops its own. The years light left to right. */
      .year {
        position: absolute;
        left: calc(var(--dot) / 2 + 10px);
        margin: 0;
        padding: 0;
        background: none;
        box-shadow: none;
        translate: 0 -50%;
        animation-delay: calc(var(--step) * 120ms);

        &::before {
          content: none;
        }
      }

      &:nth-child(odd) {
        grid-row: 1 / span 3;
        padding-bottom: var(--clearance);
        border-image: linear-gradient(to top, transparent var(--bezel-edge), var(--line-strong) var(--bezel-edge), transparent) 1;

        &::before {
          top: auto;
          bottom: calc(var(--dot) / -2);
        }

        .year {
          top: 100%;
        }
      }

      &:nth-child(even) {
        grid-row: 4 / span 3;
        padding-top: var(--clearance);
        border-image: linear-gradient(to bottom, transparent var(--bezel-edge), var(--line-strong) var(--bezel-edge), transparent) 1;

        &::before {
          top: calc(var(--dot) / -2);
        }

        .year {
          top: 0;
        }
      }

      &:nth-child(1) {
        --step: 0;
        grid-column: 1 / span 2;
      }

      &:nth-child(2) {
        --step: 1;
        grid-column: 2 / span 2;
      }

      &:nth-child(3) {
        --step: 2;
        grid-column: 3 / span 2;
      }

      &:nth-child(4) {
        --step: 3;
        grid-column: 4 / span 2;
      }

      &:nth-child(5) {
        --step: 4;
        grid-column: 5 / span 2;
      }

      &:nth-child(6) {
        --step: 5;
        grid-column: 6 / span 2;
      }
    }
  }

  @media (max-width: 599px) {
    --year-size: 30px;

    li {
      padding-left: var(--space-28);
    }

    hgroup p {
      font-size: var(--font-size-12);
    }

    p {
      font-size: var(--font-size-15);
    }
  }
}

/* Doto's dots glowing at full strength on the display. */
.readout {
  --lamp: var(--accent);
  --lamp-dots: var(--emit-dots);
  --pad: 18px;
  position: relative;
  isolation: isolate;
  margin-inline: var(--bezel);
  padding: var(--space-12) var(--pad);
  border-radius: var(--radius-inset);
  background: var(--display-surface);
  box-shadow: var(--display-bezel);
  font-family: "Doto", var(--mono);
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--lamp);
  text-shadow: var(--lamp-dots);

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

  /* site.js holds it dark, as the ignition's first frame, until it comes into view. Without site.js
     it is simply on. */
  &[data-power] {
    animation: ignite 0.6s steps(1, end) var(--jitter, 0ms) both;
  }

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

  /* Prototype, behind ?hum: a composited flicker to compare with the ignition alone. */
  &[data-power].is-humming {
    animation:
      ignite 0.6s steps(1, end) var(--jitter, 0ms) both,
      hum var(--hum-period) linear var(--hum-offset) infinite;
  }
}

.feature-rows {
  container-type: inline-size;
  border-top: 1px solid var(--line);

  li {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    gap: var(--space-8) var(--space-48);
    padding-block: 30px;
    border-bottom: 1px solid var(--line);
    view-timeline: --channel;

    @media (hover: hover) {
      /* Teal the scroll has not reached lights at once. Stepping it up from the scroll's level is
         not possible: both engines time a transition from the value without the animation, so a
         delay built from --meter-fill always reads the full level. The first row runs hot on its
         own once the stack is reached (site.js), until a pointer comes onto the rows. */
      &:hover h3::after,
      :not(:hover) > &.is-hot h3::after {
        --meter-boost: var(--lit);
        --meter-hot: var(--hot-bars);
        transition-delay: calc(-1 * var(--lit) * var(--bar-time)), 0s;
      }
    }
  }

  h3 {
    --bars: 10;
    --lit: 7;
    --hot-bars: calc(var(--bars) - var(--lit));
    --bar-time: 80ms;
    --meter: calc(var(--bars) * 8px - 3px);
    padding-right: calc(2 * var(--pad) + var(--meter));
    /* Up to 32px, as large as lets 24 characters and the meter share half the row: the longest
       title is 23. */
    font-size: clamp(22px, (50cqi - 24px - 2 * var(--bezel) - 3 * var(--pad) - var(--meter) - 24 * 2px) / (24 * 0.6), 32px);
    text-wrap: balance;

    /* Bars at the lattice's angle, 5px on an 8px pitch. The bars above the level are the hot zone,
       tinted amber even when off, as a VU meter's are, and the pointer on the row runs the whole
       meter up. */
    &::after {
      --lit-width: calc(var(--lit) * 8px);
      --meter-fill: var(--lit);
      content: "";
      position: absolute;
      inset-block: 0;
      right: var(--pad);
      width: var(--meter);
      height: 14px;
      margin-block: auto;
      background:
        repeating-linear-gradient(90deg, var(--accent) 0 5px, transparent 5px 8px) 0 0 / calc(max(var(--meter-fill), var(--meter-boost)) * 8px) 100% no-repeat,
        repeating-linear-gradient(90deg, var(--action) 0 5px, transparent 5px 8px) var(--lit-width) 0 / calc(var(--meter-hot) * 8px) 100% no-repeat,
        repeating-linear-gradient(90deg, rgba(0, 204, 204, 0.09) 0 5px, transparent 5px 8px) 0 0 / var(--lit-width) 100% no-repeat,
        repeating-linear-gradient(90deg, rgba(255, 154, 60, 0.14) 0 5px, transparent 5px 8px) var(--lit-width) 0 / 100% 100% no-repeat;
      /* The pages' #meter-glow blurs each bar in its own colour. drop-shadow() takes one colour, and
         put a teal halo round the amber bars. */
      filter: url(#meter-glow);
      transform: skewX(-30deg);

      @media (prefers-reduced-motion: no-preference) {
        /* Off the row, amber drains first and teal falls back to the scroll's level after it. */
        transition:
          --meter-boost calc(var(--lit) * var(--bar-time)) steps(var(--lit), jump-start) calc(var(--hot-bars) * var(--bar-time)),
          --meter-hot calc(var(--hot-bars) * var(--bar-time)) steps(var(--hot-bars), jump-start);
      }
    }

    /* After the text powers on, the meter fills bar by bar. */
    @supports (animation-timeline: view()) {
      @media (prefers-reduced-motion: no-preference) {
        &::after {
          animation: meter-on steps(var(--lit)) both;
          animation-timeline: --channel;
          animation-range: cover 10% cover 35%;
        }
      }
    }

    @media (max-width: 899px) {
      --bars: 5;
      --lit: 4;
      font-size: 22px;
    }
  }

  p {
    max-width: 600px;
    font-size: var(--font-size-17);
    color: var(--muted);
    text-wrap: pretty;
  }

  @media (max-width: 899px) {
    li {
      grid-template-columns: minmax(0, 1fr);
      padding-block: 22px;
    }

    p {
      font-size: var(--font-size-15);
    }
  }
}

/* A VFD stutters as its filament warms: it catches at half, sags, then its glow blooms to full. */
@keyframes ignite {
  0% {
    color: color-mix(in srgb, var(--lamp) 9%, transparent);
    text-shadow: none;
  }

  10% {
    color: color-mix(in srgb, var(--lamp) 50%, transparent);
    text-shadow: none;
  }

  20% {
    color: color-mix(in srgb, var(--lamp) 30%, transparent);
    text-shadow: none;
  }

  30% {
    color: color-mix(in srgb, var(--lamp) 55%, transparent);
    text-shadow: none;
    animation-timing-function: ease-out;
  }

  100% {
    color: var(--lamp);
    text-shadow: var(--lamp-dots);
  }
}

/* The same warm-up for a lamp, whose glow is its box-shadow. */
@keyframes lamp-on {
  0% {
    opacity: 0.12;
  }

  10% {
    opacity: 0.55;
  }

  20% {
    opacity: 0.35;
  }

  30% {
    opacity: 0.6;
    animation-timing-function: ease-out;
  }
}

@keyframes hum {
  0%,
  9%,
  23%,
  41%,
  58%,
  70%,
  91%,
  100% {
    opacity: 1;
  }

  14% {
    opacity: calc(1 - var(--hum-depth) * 0.6);
  }

  31% {
    opacity: calc(1 - var(--hum-depth) * 0.3);
  }

  47% {
    opacity: calc(1 - var(--hum-depth));
  }

  49% {
    opacity: calc(1 - var(--hum-depth) * 0.4);
  }

  52% {
    opacity: calc(1 - var(--hum-depth) * 0.9);
  }

  80% {
    opacity: calc(1 - var(--hum-depth) * 0.5);
  }
}

/* Bar counts, registered so they can animate at all. The scroll owns --meter-fill and the pointer
   the other two, because an animation overrides any value a hover sets on the same property. All run
   on steps(): WebKit interpolates a registered integer through fractions, lighting part of a bar. */
@property --meter-fill {
  syntax: "<integer>";
  inherits: false;
  initial-value: 0;
}

@property --meter-boost {
  syntax: "<integer>";
  inherits: false;
  initial-value: 0;
}

@property --meter-hot {
  syntax: "<integer>";
  inherits: false;
  initial-value: 0;
}

@keyframes meter-on {
  from {
    --meter-fill: 0;
  }
}

/* A round key after the keycaps: a cap lit from above, seated in a well, with a ring lamp round a
   dished centre. The ring is tinted when off and lights with the logo under the pointer. The
   padding keeps a wide logo such as Go inside the ring, since its max-width shrinks it. */
.language-row li,
.site-footer .social a {
  --ring: color-mix(in srgb, var(--accent) 16%, #0a0f10);
  --well: #020303;
  position: relative;
  display: grid;
  place-items: center;
  width: var(--button);
  aspect-ratio: 1;
  padding: calc(var(--button) * 0.17);
  border: 1px solid;
  border-color: #334143 #1f2a2c #0b1011;
  border-radius: 50%;
  background:
    radial-gradient(100% 70% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 70%),
    linear-gradient(#192224, #0e1314);
  box-shadow:
    0 1px 0 #0a0e0f,
    0 0 0 2px var(--well),
    0 -1px 0 2px rgba(0, 0, 0, 0.6),
    0 1px 0 2px rgba(255, 255, 255, 0.07);

  &::before {
    content: "";
    position: absolute;
    inset: calc(var(--button) * 0.07);
    border: 1.5px solid var(--ring);
    border-radius: 50%;
    background: linear-gradient(#0b1011, #151c1e);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
  }

  span {
    position: relative;
  }

  &:hover,
  &:focus-visible {
    --ring: var(--accent);

    &::before {
      box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7), inset 0 0 8px rgba(0, 204, 204, 0.25), var(--emit-box);
    }

    span {
      background-color: var(--logo-lit);
    }
  }
}

.language-row {
  --button: clamp(60px, 7.5vw, 72px);
  --size: calc(var(--button) * 0.42);
  --logo-lit: var(--accent);
  display: flex;
  align-items: center;
  gap: var(--space-20) var(--space-64);

  .eyebrow {
    flex: none;
  }

  ul {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-16);
  }

  li {
    &.go {
      --logo: url("../img/languages/go.svg");
      --ratio: 2.68;
      --density: 0.482;
    }

    &.typescript {
      --logo: url("../img/languages/typescript.svg");
      --ratio: 1;
      --density: 0.816;
      --ink-center: 0.47;
    }

    &.php {
      --logo: url("../img/languages/php.svg");
      --ratio: 1.9;
      --density: 0.607;
    }

    &.ruby {
      --logo: url("../img/languages/ruby.svg");
      --ratio: 1.01;
      --density: 0.629;
      --ink-center: 0.536;
    }

    &.python {
      --logo: url("../img/languages/python.svg");
      --ratio: 1;
      --density: 0.632;
    }

    &.swift {
      --logo: url("../img/languages/swift.svg");
      --ratio: 1;
      --density: 0.755;
      --ink-center: 0.481;
    }

    &.kotlin {
      --logo: url("../img/languages/kotlin.svg");
      --ratio: 1;
      --density: 0.75;
    }
  }

  @media (max-width: 899px) {
    --button: 56px;
    container-type: inline-size;
    flex-direction: column;
    align-items: flex-start;

    ul {
      width: 100%;
      justify-content: center;
      gap: var(--space-14);
    }
  }

  /* Seven 56px keys and their 14px gaps need 476px. Narrower, they go four over three across the
     full width, the three sitting between the four as a honeycomb, rather than wrapping one key. */
  @container (width < 476px) {
    ul {
      display: grid;
      grid-template-columns: repeat(8, minmax(0, 1fr));
      justify-items: center;
      gap: var(--space-14) 0;
    }

    li {
      grid-column: span 2;

      &:nth-child(5) {
        grid-column: 2 / span 2;
      }
    }
  }
}

.window {
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-panel);
  background: var(--panel);

  .window-bar {
    display: flex;
    gap: var(--space-8);
    padding: var(--space-14) 18px;
    border-bottom: 1px solid var(--line);

    span {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: var(--line-strong);
    }
  }

  & > img {
    display: block;
    width: 100%;
    height: auto;
  }
}

.terminal {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 760px;
  margin-inline: auto;

  /* Each message is a row of name, arrow and text, so a wrapped line hangs under the text and the
     arrows line up in either language. As large as lets the longest request, 102 characters in
     English, wrap into two lines beside its name, up to 22px: with half a line between the messages,
     the terminal then stays within the height the card beside it gives it. */
  pre {
    --cap: 1cap;
    --cell: 1ch;
    position: relative;
    display: grid;
    grid-template-columns: max-content max-content minmax(0, 1fr);
    align-content: start;
    gap: 0.5lh 1ch;
    flex-grow: 1;
    overflow-x: auto;
    padding: var(--space-28) var(--space-32) var(--space-32);
    background: radial-gradient(55% 90% at 32% 55%, rgba(0, 204, 204, 0.07), transparent);
    font-family: var(--mono);
    font-size: clamp(15px, (100cqi - 64px) / (62 * 0.6), 22px);
    line-height: 1.7;
    white-space: normal;
    text-wrap: balance;
    color: var(--text-soft);
    text-shadow: 0 0 8px rgba(196, 210, 211, 0.18);

    /* The grid wires of a vacuum fluorescent display, which is the logo's own lattice, lie in front
       of the glyphs, and the glass sheen over both. */
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      pointer-events: none;
      background:
        linear-gradient(115deg, rgba(255, 255, 255, 0.045) 0%, rgba(255, 255, 255, 0.012) 30%, transparent 45%),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='10.392'%3E%3Cpath d='M0 0H6M0 5.196H6M0 0L6 10.392M6 0L0 10.392' stroke='rgba(0,0,0,0.45)' stroke-width='0.8' fill='none'/%3E%3C/svg%3E") 0 0 / 6px 10.392px;
    }
  }

  /* Geist Mono has no non-breaking hyphen (U+2011), so a hyphenated word keeps whole in a span. */
  .compound {
    white-space: nowrap;
  }

  .user,
  .user + .arrow {
    color: var(--action);
    text-shadow: var(--emit-action);
  }

  .arrow,
  .assistant,
  .response {
    color: var(--accent);
    text-shadow: var(--emit);
  }

  /* The cursor is one cell of the monospace grid standing on the baseline, --cell by --cap, so the
     block matches the glyphs at every size. It is an empty inline box of no font size, whose content
     area is a point on the baseline, so its top padding rises exactly a cap height from it. An
     inline-block would sit there too, but WebKit's balanced wrapping breaks lines early around one. */
  .response::after,
  &.is-typing :is(.request, .response)::before,
  &.is-typing :is(.keystroke, .token)::after {
    content: "";
    padding: var(--cap) 0 0 var(--cell);
    font-size: 0;
    background: var(--action);
    box-shadow: var(--emit-action-box);
  }

  .response::after {
    margin-left: calc(0.4 * var(--cell));
    animation: cursor-blink 1.1s steps(1) infinite;

    @media (prefers-reduced-motion: reduce) {
      animation: none;
    }
  }

  /* site.js splits the messages and gives each keystroke and token the step of --typed it lights on,
     --at, and the step the next one lights on, --until, which is how long it holds the cursor. Once
     the terminal is on screen, --typed runs up through the steps in time, not with the scroll: tied
     to the scroll, the request stops mid-sentence wherever the reader does, as the nav link leaves it. */
  &.is-typing {
    &.is-seen {
      animation: type-on calc(var(--steps) * 30ms) steps(var(--steps)) 0.5s both;
    }

    .keystroke,
    .token,
    .assistant,
    .assistant + .arrow {
      opacity: clamp(0, var(--typed) - var(--at) + 1, 1);
    }

    /* The moving cursor gives its cell back, so nothing reflows under it. */
    :is(.request, .response)::before,
    :is(.keystroke, .token)::after {
      margin-right: calc(-1 * var(--cell));
    }

    .response::before,
    :is(.keystroke, .token)::after {
      opacity: clamp(0, min(var(--typed) - var(--at) + 1, var(--until) - var(--typed)), 1);
    }

    /* Waiting for the request, for as long as the reader takes to scroll to it. The wait for the
       reply is shorter than a blink, so its cursor holds steady. */
    .request::before {
      opacity: clamp(0, 1 - var(--typed), 1);
      animation: cursor-blink 1.1s steps(1) infinite;
    }

    .response::after {
      opacity: clamp(0, var(--typed) - var(--steps) + 1, 1);
    }
  }

  @media (max-width: 599px) {
    pre {
      padding: var(--space-20);
      font-size: var(--font-size-13);
    }
  }
}

/* The blink takes visibility, so a typing cursor's opacity can still switch it off. */
@keyframes cursor-blink {
  50% {
    visibility: hidden;
  }
}

/* Registered, so the terminal's cursors inherit them as lengths measured in its own type. */
@property --cap {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

@property --cell {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

/* Inherited, so every keystroke reads the count the terminal's animation sets. */
@property --typed {
  syntax: "<integer>";
  inherits: true;
  initial-value: 0;
}

@keyframes type-on {
  to {
    --typed: var(--steps);
  }
}

.about > .wrap {
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
  align-items: start;
  gap: clamp(40px, 5.56vw, 80px);

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

/* The numbers light on one display down the card's left side, and each row's rule stops at its
   bezel. */
.steps {
  --digits: 22px;
  --margin: var(--space-14);
  --column: calc(var(--digits) * 1.2 + 28px);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-panel);
  counter-reset: step;

  &::before,
  &::after {
    content: "";
    position: absolute;
    z-index: 1;
    inset: var(--margin) auto var(--margin) var(--margin);
    width: var(--column);
    border-radius: var(--radius-inset);
    pointer-events: none;
  }

  &::before {
    background: var(--display-surface);
    box-shadow: var(--display-bezel);
  }

  &::after {
    z-index: 3;
    background: var(--display-glass);
  }

  li {
    --lamp: var(--action);
    --lamp-dots: var(--emit-action-dots);
    display: flex;
    align-items: baseline;
    gap: var(--space-24);
    padding: var(--space-28) var(--space-32) var(--space-28) var(--margin);
    counter-increment: step;

    /* Doto's digits carry 0.1em more bearing on the right than on the left (0.105em against
       0.005em), so a 0.1em indent centres their ink in the column. */
    &::before {
      content: counter(step, decimal-leading-zero);
      position: relative;
      z-index: 2;
      flex: none;
      width: var(--column);
      font: 900 var(--digits)/1 "Doto", var(--mono);
      text-align: center;
      text-indent: 0.1em;
      color: var(--lamp);
      text-shadow: var(--lamp-dots);
    }

    &[data-power]::before {
      animation: ignite 0.6s steps(1, end) var(--jitter, 0ms) both;
    }

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

    &[data-power].is-humming::before {
      animation:
        ignite 0.6s steps(1, end) var(--jitter, 0ms) both,
        hum var(--hum-period) linear var(--hum-offset) infinite;
    }

    & + li {
      background: linear-gradient(var(--line), var(--line)) right top / calc(100% - var(--margin) - var(--column) - var(--bezel)) 1px no-repeat;
    }
  }

  div {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
  }

  h3 {
    font-size: var(--font-size-20);
    font-weight: 600;
    line-height: 1.3;
  }

  p {
    color: var(--muted);
  }

  @media (max-width: 899px) {
    --digits: 20px;

    li {
      gap: var(--space-16);
      padding: var(--space-24) var(--space-20) var(--space-24) var(--margin);
    }

    h3 {
      font-size: var(--font-size-17);
    }

    p {
      font-size: var(--font-size-15);
    }
  }
}

.stats {
  padding-bottom: var(--section-space);
}

.figures {
  --gap: var(--space-40);
  container-type: inline-size;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--gap);
  padding-block: var(--space-40);
  border-block: 1px solid var(--line);

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

  /* Up to 48px, as large as lets the longest figure, 11 characters, fill a third of the row. */
  strong {
    font-size: clamp(26px, ((100cqi - 2 * var(--gap)) / 3 - 2 * var(--bezel) - 2 * var(--pad) - 11 * 2px) / (11 * 0.6), 48px);
  }

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

  @media (max-width: 899px) {
    --gap: var(--space-28);
    grid-auto-flow: row;
    padding-block: var(--space-32);

    strong {
      font-size: 32px;
    }

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

.quote {
  padding: var(--space-40) 0 var(--space-112);

  .wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-32);
    text-align: center;
  }

  figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-32);
  }

  blockquote {
    max-width: 920px;
    font-size: clamp(24px, 2.36vw, 34px);
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -0.024em;
  }

  figcaption {
    display: flex;
    align-items: center;
    gap: var(--space-14);
    font-weight: 600;
  }

  .avatar {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: var(--line);
    font-family: var(--mono);
    font-size: var(--font-size-13);
    font-weight: 400;
    color: var(--accent);
  }

  .wrap > p {
    max-width: 560px;
    font-size: var(--font-size-17);
    color: var(--muted);
  }

  @media (max-width: 899px) {
    padding: var(--space-24) 0 var(--space-64);

    .wrap,
    figure {
      align-items: flex-start;
      gap: var(--space-24);
      text-align: left;
    }

    figcaption {
      gap: var(--space-12);
    }

    .avatar {
      width: 40px;
      height: 40px;
    }

    .wrap > p {
      font-size: var(--font-size-15);
    }
  }
}

.client-grid {
  --size: 48px;
  --logo-tint: var(--muted);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-panel);
  background: var(--line);

  /* A fixed logo row keeps every caption in a row on one line, whatever each logo's height. */
  li {
    display: grid;
    grid-template-rows: 60px auto;
    place-items: center;
    gap: var(--space-12);
    padding: var(--space-28) var(--space-20) 22px;
    background: var(--bg);
    text-align: center;

    &[class]:hover strong {
      background-color: var(--text);
    }
  }

  strong {
    font-weight: 600;
    color: var(--muted);
  }

  span {
    font-size: var(--font-size-13);
    color: var(--faint);
  }

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

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

    li {
      grid-template-rows: 46px auto;
      gap: var(--space-10);
      padding: 22px var(--space-12) 18px;
    }

    strong {
      font-size: var(--font-size-15);
    }

    span {
      font-size: var(--font-size-12);
    }
  }
}

.contact {
  --bleed-below: var(--space-112);
  overflow: clip visible;
  padding-bottom: var(--bleed-below);

  .cta {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-24);
    min-height: 480px;
    padding: var(--space-48) var(--space-32);
    text-align: center;

    & > :not(.cta-scene) {
      position: relative;
      z-index: 1;
    }
  }

  /* Full-bleed like the hero's scene: as wide as the page, and on down through the section's bottom
     padding and the footer, whose height site.js keeps in --footer-height; the wall fades out from
     the copy's bottom edge to the page's. */
  .cta-scene {
    --run-below: calc(var(--bleed-below) + var(--footer-height, 0px));
    position: absolute;
    top: 0;
    bottom: calc(-1 * var(--run-below));
    left: 50%;
    translate: -50% 0;
    width: 100vw;
    mask-image: linear-gradient(#000 calc(100% - var(--run-below)), transparent);

    picture {
      position: absolute;
      inset: 0;
      transition: opacity 0.8s ease;
    }

    img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: none;
      object-position: center top;
    }

    canvas {
      position: absolute;
      inset: 0;
      display: block;
      width: 100%;
      height: 100%;
      opacity: 0;
      transition: opacity 0.8s ease;
    }

    &.is-live {
      picture {
        opacity: 0;
      }

      canvas {
        opacity: 1;
      }
    }
  }

  /* The wall's grid runs behind the copy; a halo in the page's own colour clears its lines from
     around each letter without pulling the grid back from the text. */
  h2,
  p {
    text-shadow: 0 0 3px var(--bg), 0 0 8px var(--bg), 0 0 14px var(--bg);
  }

  h2 {
    font-weight: 600;
    font-size: clamp(36px, 4.17vw, 60px);
    line-height: 1.05;
    letter-spacing: -0.042em;
  }

  p {
    max-width: 640px;
    font-size: var(--font-size-19);
    color: var(--muted);
    text-wrap: balance;
  }

  .cta-actions {
    display: flex;
    gap: var(--space-12);
    margin-top: var(--space-8);
  }

  @media (max-width: 719px) {
    --bleed-below: var(--space-64);

    .cta {
      align-items: stretch;
      justify-content: flex-start;
      gap: 18px;
      min-height: 420px;
      padding: var(--space-44) 0;
      text-align: left;
    }

    h2 {
      letter-spacing: -0.039em;
    }

    p {
      font-size: var(--font-size-16);
    }

    .cta-actions {
      flex-direction: column;
      margin-top: 0;

      .mono {
        display: none;
      }
    }
  }
}

.site-footer {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--line);
  padding: var(--space-56) 0;

  /* The header's resting tint, over the contact wall where it runs on under the footer; it eases
     in above the footer so it does not start on a line. */
  &::before {
    content: "";
    position: absolute;
    inset: -32px 0 0;
    z-index: -1;
    background: color-mix(in srgb, var(--bg) 32%, transparent);
    mask-image: linear-gradient(transparent, #000 32px);
    pointer-events: none;
  }

  /* The contact wall runs on under the footer, where the rule would cut across it. */
  main:has(.cta-scene) + & {
    border-top-color: transparent;
  }

  .wrap {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-24) var(--space-48);
  }

  .brand {
    .wordmark {
      margin-left: 0.3em;
      font-size: var(--font-size-18);
      color: var(--text);
    }
  }

  .imprint {
    font-family: var(--display);
    font-weight: 500;
    font-size: var(--font-size-16);
    line-height: 1.2;
    color: var(--faint);
  }

  .social {
    --button: 48px;
    --size: calc(var(--button) * 0.42);
    --logo-lit: var(--accent);
    display: flex;
    gap: var(--space-16);

    .github {
      --logo: url("../img/social/github.svg");
      --ratio: 1.02;
      --density: 0.439;
      --ink-center: 0.463;
    }

    .linkedin {
      --logo: url("../img/social/linkedin.svg");
      --ratio: 1;
      --density: 0.814;
    }

    .instagram {
      --logo: url("../img/social/instagram.svg");
      --ratio: 1;
      --density: 0.771;
    }
  }

  @media (max-width: 719px) {
    padding: var(--space-40) 0;
  }
}

/* The hero's ?tune panel, which hero-scene.js builds only when the URL asks for it. */
.tuning {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 20;
  display: grid;
  gap: var(--space-10);
  width: min(300px, calc(100vw - 32px));
  padding: var(--space-14) var(--space-16);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-inset);
  background: rgba(7, 10, 11, 0.86);
  backdrop-filter: blur(8px);
  font: var(--font-size-12)/1 var(--mono);
  color: var(--muted);

  label {
    display: grid;
    grid-template-columns: 52px minmax(0, 1fr) 36px;
    align-items: center;
    gap: var(--space-10);
  }

  input {
    width: 100%;
    margin: 0;
    accent-color: var(--accent);
  }

  output {
    color: var(--accent);
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
}
