/* ==========================================================================
   Pyflx — site stylesheet

   Replica of the corticallabs.com homepage layout, built at the client's
   request. Values (sizes, spacing, gradients, breakpoints) follow the
   reference; typography is Baloo 2; the logo is the Pyflx wordmark.

   1. Tokens        palette copied from the reference for this stage; swap
                    the values here to re-skin to the brand palette later
   2. Fonts         self-hosted Baloo 2 + metric-matched fallback
   3. Base          reset and document defaults
   4. Buttons       .button and variants
   5. Decoration    dots, lines, placeholders
   6. Header        fixed header with pill nav and mobile menu
   7. Hero          animated soft backdrop, oversized headline
   7b. Tech band    rolling tape of vendor logos
   8. CTA cards     four tall cards
   9. Showcase      accent heading, long paragraph, framed figure
   10. Pong         split panel with animated paddles
   11. Info cards   two wide colour cards
   12. Footer       gradient bars, CTAs, link lists, bottom bar
   12b. Reveals     blocks fade and rise as they scroll into view
   13. Keyframes
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */

:root {
  --color-ink: #000000;
  --color-paper: #ffffff;
  --color-cloud: #f6f5f2;
  --color-canary: #ffedaf;
  --color-slate: #b6bab9;
  --color-body-muted: #a3a8a7;

  /* Pyflx brand accent (Lime Green from the guideline's secondary palette) */
  --color-brand-accent: #9dfb1c;
  /* Secondary palette, used for the "How we work" cards. */
  --color-brand-navy: #1c2d5a;
  --color-brand-purple: #6c4cf5;
  --color-brand-turquoise: #00c2a8;
  --color-brand-magenta: #91298c;
  --color-brand-jet: #111111;
  --color-brand-grey-light: #f5f5f5; /* Light Grey, secondary background */
  --color-brand-grey-dark: #555555;
  --color-brand-grey-medium: #9a9a9a; /* muted text on dark surfaces only */

  --font-sans: "Baloo 2", "Baloo 2 Fallback", Arial, sans-serif;

  /* Brand guidelines, typeface section: Baloo 2 Bold for headlines and titles,
     Baloo 2 Regular for body text. Those are the only two weights the page
     uses; nothing sits at Medium or SemiBold. */
  --weight-body: 400;
  --weight-heading: 700;

  --site-max-width: 1120px;
}

/* 2. Fonts ----------------------------------------------------------------- */

@font-face {
  font-family: "Baloo 2";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/baloo-2-latin-wght-normal.woff2") format("woff2");
}

/* Arial adjusted to Baloo 2's advance widths and vertical metrics, so text
   occupies the same space before and after the web font arrives. */
@font-face {
  font-family: "Baloo 2 Fallback";
  src:
    local("Arial"),
    local("Liberation Sans"),
    local("Helvetica Neue");
  size-adjust: 95.62%;
  ascent-override: 112.74%;
  descent-override: 54.8%;
  line-gap-override: 0%;
}

/* 3. Base ------------------------------------------------------------------ */

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

* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
}

/* In-page navigation. scroll-padding-top keeps a target from landing behind
   the fixed header; it applies to link clicks and to keyboard focus alike,
   which a per-section scroll-margin would not. */
html {
  scroll-padding-top: 118px;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* No scroll lock while the menu is open. `html` is 100% tall here, so hiding
   its overflow clips everything past one viewport and leaves the rest of a
   scrolled page blank. The header is fixed, so the menu stays put regardless. */

body {
  font-family: var(--font-sans);
  font-size: 28px;
  font-weight: var(--weight-body);
  line-height: 1.5;
  color: var(--color-ink);
  background-color: var(--color-cloud);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

p {
  line-height: 1.3em;
}

p,
h1,
h2,
h3 {
  overflow-wrap: break-word;
}

h1,
h2,
h3 {
  font-size: inherit;
  font-weight: var(--weight-heading);
  line-height: inherit;
}

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

button {
  font: inherit;
  color: inherit;
  border: none;
  background: none;
  cursor: pointer;
}

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

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

.clip-width {
  max-width: 100%;
  overflow: hidden;
}

.svg-defs {
  position: absolute;
}

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

/* Reduced motion: every animation and transition collapses to a single frame. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* 4. Buttons --------------------------------------------------------------- */

.button {
  display: flex;
  justify-content: center;
  padding: 20px 36px;
  font-size: 20px;
  line-height: 20px;
  text-align: center;
  white-space: nowrap;
  color: var(--color-ink);
  border-radius: 100px;
  background: linear-gradient(180deg, #f9f7f5 0%, #ecebe9 100%);
  box-shadow:
    0 2px 0 0 #fff inset,
    0 1px 1px 0 rgb(255 255 255 / 0.5) inset,
    0 0 1px 0 rgb(0 0 0 / 0.5),
    0 2px 4px 0 rgb(0 0 0 / 0.1),
    0 12px 30px 0 rgb(0 0 0 / 0.1);
  transform: translateY(0);
  transition:
    box-shadow 0.15s ease,
    transform 0.15s ease-out;
}

.button:active {
  transform: translateY(1.5px);
  box-shadow:
    0 2px 0 0 #fff inset,
    0 1px 1px 0 rgb(255 255 255 / 0.5) inset,
    0 0 1px 0 rgb(0 0 0 / 0.5),
    0 1px 4px 0 rgb(0 0 0 / 0.1),
    0 5px 18px 0 rgb(0 0 0 / 0.08);
}

.button--small {
  padding: 12px 22px;
  font-size: 16px;
  line-height: 16px;
}

.button--dark {
  color: var(--color-paper);
  background: var(--color-ink);
  box-shadow:
    0 2px 3px 0 rgb(0 0 0 / 0.15),
    0 2px 0 0 rgb(255 255 255 / 0.1) inset,
    0 1px 1px 0 rgb(255 255 255 / 0.5) inset;
}

.button--outline {
  color: var(--color-paper);
  background: none;
  border: 1px solid var(--color-paper);
  box-shadow: none;
}

@media (max-width: 800px) {
  .button {
    padding: 14px 24px;
    font-size: 16px;
  }
}

/* 5. Decoration ------------------------------------------------------------ */

.dot,
.line {
  position: absolute;
  background-color: var(--color-paper);
}

.dot {
  width: 3px;
  height: 3px;
}

.line--vert {
  width: 1px;
  height: 100%;
}

.line--horz {
  width: 100%;
  height: 1px;
}

.line--l {
  left: 0;
}

.line--r {
  right: 0;
}

.line--t {
  top: -1px;
}

.line--b {
  bottom: -1px;
}

.dot--tl {
  top: -2px;
  left: -2px;
}

.dot--tr {
  top: -2px;
  right: -2px;
}

.dot--br {
  bottom: -2px;
  right: -2px;
}

.dot--bl {
  bottom: -2px;
  left: -2px;
}

/* Labelled stand-ins where the reference shows photography. */
.placeholder {
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: var(--weight-body);
  letter-spacing: 0.02em;
  color: rgb(255 255 255 / 0.7);
  border: 1px dashed rgb(255 255 255 / 0.45);
  border-radius: 6px;
  background: rgb(0 0 0 / 0.12);
}

/* 6. Header ---------------------------------------------------------------- */

/* Dark logo and icon over the light hero; white once the bar darkens. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  width: 100%;
  font-size: 16px;
  color: var(--color-ink);
  transition:
    background-color 0.5s linear,
    color 0.2s linear;
}

/* Over a dark hero (homepage, services) the header starts light instead of
   ink and keeps the scrolled and open states. */
.site-header--on-dark {
  color: var(--color-paper);
}

.site-header.is-scrolled,
.site-header.is-open {
  color: var(--color-paper);
}

.site-header__inner {
  display: flex;
  justify-content: space-between;
  padding: 30px 40px;
}

/* The logo stays white on every page, whatever the hero behind it
   (client). */
.site-header__brand {
  display: flex;
  align-items: center;
  color: var(--color-paper);
}

.brand {
  display: inline-flex;
  align-items: center;
}

/* Header wordmark 26px tall (client: a step smaller; was 30px). */
.brand__mark {
  height: 26px;
  width: auto;
}

.site-header__middle {
  position: absolute;
  left: 50%;
  width: max-content;
  transform: translateX(-50%);
}

.site-nav {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  color: var(--color-paper);
  border-radius: 100px;
  background: rgb(128 130 129 / 0.6);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: background-color 0.5s linear;
}

.site-nav a {
  display: flex;
  align-items: center;
  padding: 8px 24px;
  white-space: nowrap;
}

/* The page the visitor is on sits in a light pill, as on the reference: the
   same face as "Get Started" (.button), filling the bar's height. */
.site-nav a[aria-current="page"],
.site-nav a[aria-current="true"] {
  color: var(--color-ink);
  border-radius: 100px;
  background: linear-gradient(180deg, #f9f7f5 0%, #ecebe9 100%);
  box-shadow:
    0 2px 0 0 #fff inset,
    0 1px 1px 0 rgb(255 255 255 / 0.5) inset,
    0 0 1px 0 rgb(0 0 0 / 0.5),
    0 2px 4px 0 rgb(0 0 0 / 0.1),
    0 12px 30px 0 rgb(0 0 0 / 0.1);
}

.site-nav a.site-nav__mobile-only {
  display: none;
}
.site-header__right {
  position: relative;
  display: flex;
  align-items: center;
  gap: 30px;
}

.site-header.is-scrolled {
  background-color: rgb(0 0 0 / 0.3);
  -webkit-backdrop-filter: blur(30px);
  backdrop-filter: blur(30px);
}

.site-header.is-scrolled .site-nav {
  background-color: rgb(0 0 0 / 0.15);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.nav-toggle {
  display: none;
  flex-shrink: 0;
  align-items: center;
  height: 37px;
  color: inherit;
}

.nav-toggle__close {
  display: none;
}

/* Open state: the menu takes the header, the logo steps aside, the icon becomes a cross. */
.site-header.is-open .site-header__middle {
  display: flex;
}

.site-header.is-open .site-header__brand {
  display: none;
}

.site-header.is-open .nav-toggle__open {
  display: none;
}

.site-header.is-open .nav-toggle__close {
  display: block;
}

/* Watched by main.js: leaving the viewport switches the header to .is-scrolled */
[data-scroll-sentinel] {
  position: absolute;
  top: 0;
  width: 1px;
  height: 100px;
  pointer-events: none;
}

main {
  position: relative;
}

@media (max-width: 900px) {
  .site-header__middle {
    display: none;
    position: relative;
    left: auto;
    transform: none;
  }

  .site-nav {
    gap: 0;
  }

  .site-header__right,
  .nav-toggle {
    display: flex;
  }
}

@media (max-width: 700px) {
  /* The button keeps its place beside the menu toggle; the gap tightens.
     While the menu is open it steps out of the way of the close icon and
     appears as the menu's last item instead. */
  .site-header__right {
    gap: 16px;
  }

  .site-header.is-open .site-header__cta {
    display: none;
  }

  .site-header__inner {
    align-items: flex-start;
    gap: 30px;
  }

  /* The row is top-aligned so the open menu can drop below it; the logo
     takes Get Started's height so the two share a centre line. */
  .site-header__brand {
    height: 44px;
  }

  .site-header.is-open {
    background-color: rgb(0 0 0 / 0.45);
    -webkit-backdrop-filter: blur(30px);
    backdrop-filter: blur(30px);
  }

  .site-header__middle {
    flex: 1;
    width: 100%;
  }

  .site-nav {
    flex-direction: column;
    gap: 4px;
    width: 100%;
    padding: 10px;
    border-radius: 20px;
  }

  .site-nav a {
    align-items: flex-start;
    width: 100%;
    font-size: 20px;
  }

  .site-nav a.site-nav__mobile-only {
    display: flex;
    margin-top: 10px;
    padding-top: 20px;
    border-top: 1px solid rgb(255 255 255 / 0.2);
  }

  .site-header.is-scrolled .site-nav {
    background-color: transparent;
  }
}

@media (max-width: 500px) {
  /* Header is shorter here, so the anchor offset shrinks with it. */
  html {
    scroll-padding-top: 84px;
  }

  .site-header__inner {
    padding: 20px;
  }

  .site-header__brand {
    height: 37px; /* the toggle's height; Get Started is shorter here */
  }

  .brand__mark {
    height: 22px; /* a step smaller on phones (client) */
  }

  .site-header__cta {
    padding: 10px 16px;
    font-size: 14px;
    line-height: 14px;
  }

  .site-nav {
    padding: 0;
  }
}

/* Narrowest phones: brand, button and toggle still fit on one row. */
@media (max-width: 360px) {
  .site-header__inner {
    gap: 16px;
  }

  .site-header__right {
    gap: 12px;
  }

  .site-header__cta {
    padding: 10px 14px;
  }
}

/* 7. Hero ------------------------------------------------------------------ */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 100px;
  padding: 180px 9.5vw 130px 9.5vw;
  color: var(--color-paper);
  /* Dark Grey (--color-brand-grey-dark, #555555), a step lighter at the top
     and darker at the foot. */
  background: linear-gradient(180deg, #5e5e5e 0%, #4c4c4c 100%);
}

/* Animated soft backdrop on Dark Grey: blurred blooms, lighter and darker
   than the base, drift over it, with faint vertical light streaks sliding
   across. Fades in after
   load like the reference's scene. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  opacity: 0;
  animation: bg-in 2s linear 0.5s forwards;
}

/* Live backdrop: main.js draws the blooms in motion on this canvas and marks
   the hero .hero--live; the CSS blooms below remain the still fallback. */
.hero__canvas {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.hero--live .hero__canvas {
  display: block;
}

.hero--live .hero__blob {
  display: none;
}

/* The WebGL beams carry their own light streaks and grain. */
.hero--beams .hero__streaks {
  display: none;
}

.hero__blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(4.5vw);
  animation: drift-a 26s ease-in-out infinite alternate;
  will-change: transform;
}

.hero__blob--teal {
  top: -22vw;
  left: -14vw;
  width: 62vw;
  height: 62vw;
  background: radial-gradient(circle, rgb(255 255 255 / 0.3) 0%, transparent 62%);
}

.hero__blob--blush {
  top: -12vw;
  left: 48vw;
  width: 48vw;
  height: 48vw;
  background: radial-gradient(circle, rgb(243 240 235 / 0.22) 0%, transparent 62%);
  animation-name: drift-b;
  animation-duration: 31s;
}

.hero__blob--sky {
  top: 22vw;
  left: 18vw;
  width: 52vw;
  height: 52vw;
  background: radial-gradient(circle, rgb(40 42 44 / 0.7) 0%, transparent 62%);
  animation-name: drift-c;
  animation-duration: 23s;
}

.hero__blob--lilac {
  top: 26vw;
  left: 62vw;
  width: 46vw;
  height: 46vw;
  background: radial-gradient(circle, rgb(226 228 230 / 0.2) 0%, transparent 62%);
  animation-name: drift-d;
  animation-duration: 35s;
}

.hero__blob--deep {
  top: 44vw;
  left: -8vw;
  width: 58vw;
  height: 58vw;
  background: radial-gradient(circle, rgb(28 30 32 / 0.75) 0%, transparent 62%);
  animation-name: drift-e;
  animation-duration: 29s;
}

.hero__streaks {
  position: absolute;
  inset: 0 -20%;
  background: repeating-linear-gradient(
    90deg,
    transparent 0,
    rgb(255 255 255 / 0.14) 1.4vw,
    transparent 2.8vw,
    transparent 4.2vw,
    rgb(0 0 0 / 0.2) 5.6vw,
    transparent 7vw
  );
  filter: blur(6px);
  animation: streaks-slide 14s ease-in-out infinite alternate;
}

/* Gentle depth: lighter at the top, a touch darker where the next section begins. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(180deg, rgb(255 255 255 / 0.12) 0%, rgb(0 0 0 / 0.06) 100%);
  pointer-events: none;
}

.hero__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 55px;
  color: var(--color-paper);
}

.hero h1 {
  font-size: 9.5vw;
  font-weight: var(--weight-heading);
  line-height: 11vw;
  text-wrap: balance;
}

/* Dimmed word as on the reference; the line itself carries the brand accent. */
.hero__strike {
  color: rgb(255 255 255 / 0.45);
  text-decoration-line: line-through;
  text-decoration-color: var(--color-brand-accent);
  text-decoration-thickness: 0.07em;
}

/* A bit smaller, within the heading's "run the business." width (client). */
.hero p {
  max-width: 68vw;
  font-size: 1.8vw;
}

.hero__buttons {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 60px;
}

.hero__buttons .button {
  min-width: 300px;
}

@media (max-width: 900px) {
  .hero {
    gap: 60px;
  }

  .hero h1 {
    font-size: 80px;
    line-height: 86px;
  }

  .hero p {
    max-width: none;
    font-size: 22px;
  }
}

@media (max-width: 800px) {
  .hero__buttons .button {
    flex: 1;
    width: 100%;
    min-width: initial;
  }
}

@media (max-width: 600px) {
  .hero h1 {
    font-size: 11.5vw;
    line-height: 13vw;
  }

  .hero__buttons .button {
    flex: none;
  }
}

@media (max-width: 400px) {
  .hero {
    padding: 40vw 9.5vw 30vw 9.5vw;
  }

  .hero__body {
    gap: 40px;
  }

  .hero h1 {
    font-size: 44px;
    line-height: 50px;
  }

  .hero__buttons {
    gap: 30px;
  }

  .hero__buttons .button {
    width: 100%;
    min-width: initial;
  }
}

/* 7b. Technology band ------------------------------------------------------ */

/* Rolling tape of vendor logos. The set appears four times (three copies
   hidden from screen readers) and the track travels exactly half its width,
   so each half is wider than the screen and the loop never shows a gap.
   Paused on hover, still for reduced motion. */
/* The logos alone, no label (client). */
.tech-band {
  padding: 34px 40px;
  background: var(--color-cloud);
}

.tech-band__tape {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
}

.tech-band__track {
  display: flex;
  align-items: center;
  width: max-content;
  list-style: none;
  animation: tape 80s linear infinite;
}

.tech-band__tape:hover .tech-band__track {
  animation-play-state: paused;
}

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

.tech-band__track li {
  display: flex;
  padding-right: 64px;
}

/* Vendor logos, here and on the Services page. The grey is baked into the
   files; heights are set by eye so wordmarks, lockups and the AWS badge read
   the same size. */
.vendor-logo {
  width: auto;
  height: 24px;
}

.vendor-logo[src*="anthropic"] {
  height: 18px;
}

.vendor-logo[src*="google-cloud"] {
  height: 22px;
}

.vendor-logo[src*="azure"],
.vendor-logo[src*="postgresql"] {
  height: 28px;
}

.vendor-logo[src*="mongodb"],
.vendor-logo[src*="cloudflare"] {
  height: 30px;
}

.vendor-logo[src*="aws"] {
  height: 32px;
}

@media (max-width: 700px) {
  .tech-band {
    padding: 28px 20px;
  }

  .tech-band__track li {
    padding-right: 48px;
  }
}

/* 8. CTA cards ------------------------------------------------------------- */

.cta-cards {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 20px;
  padding: 20px;
}

/* Three cards across at desktop, as on the reference; stacked at 1000px and
   below, where three-up would squeeze the titles to four lines.
   Content sits at the foot of each card, as the reference's does, so the
   figure on the first card rides above its copy. */
.cta-card {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 48px;
  max-width: 100%;
  min-width: 0;
  min-height: 750px;
  padding: 36px;
  border-radius: 8px;
  background: linear-gradient(180deg, #b6bab9 0%, #dbdbdb 100%);
}

.cta-card--dark {
  background: linear-gradient(160deg, #23262e 0%, #14161c 55%, #2a2331 100%);
}

/* The middle card's photo (fluorescent neurons on black) fills the card,
   anchored to the top so the cell bodies show. A fade measured up from the
   card's foot (near-black behind the copy, clear from 520px up) keeps the
   white title and copy readable at any card height; stacked, the card is
   taller (below) so the cells still show above the text. The card's own
   gradient stays underneath while the photo loads. */
.cta-card--neurons {
  --neurons-fade: linear-gradient(0deg, rgb(20 22 28 / 0.95) 0, rgb(20 22 28 / 0.82) 340px, rgb(20 22 28 / 0) 520px);

  background:
    var(--neurons-fade),
    url("../img/home-neurons.jpg") center top / cover no-repeat,
    linear-gradient(160deg, #23262e 0%, #14161c 55%, #2a2331 100%);
  background:
    var(--neurons-fade),
    image-set(url("../img/home-neurons.webp") type("image/webp"), url("../img/home-neurons.jpg") type("image/jpeg")) center top / cover no-repeat,
    linear-gradient(160deg, #23262e 0%, #14161c 55%, #2a2331 100%);
}

.cta-card--pale {
  background: linear-gradient(180deg, #e9ebe6 0%, #d3d8d0 100%);
}

.cta-card--light-text .cta-card__body {
  color: var(--color-paper);
}

/* The first and last cards carry a figure (photos below). */
.cta-card__figure {
  flex: none;
  width: 271px;
  height: 278px;
  max-width: 100%;
  color: rgb(0 0 0 / 0.55);
  border-color: rgb(0 0 0 / 0.3);
  background: rgb(255 255 255 / 0.35);
}

/* The first and last cards' photos (a server rack on a grey studio ground,
   the chameleon mark on off-white): square, up to 380px, the four edges
   faded out so each sits on its card's own ground instead of reading as a
   pasted-in square. */
.cta-card__figure--photo {
  display: block;
  width: min(100%, 380px);
  height: auto;
  aspect-ratio: 1;
  border: 0;
  background: none;
}

.cta-card__figure--photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 10%, #000 90%, transparent),
    linear-gradient(to bottom, transparent, #000 6%, #000 92%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 10%, #000 90%, transparent),
    linear-gradient(to bottom, transparent, #000 6%, #000 92%, transparent);
  mask-composite: intersect;
}

.cta-card--light-text .cta-card__figure {
  color: rgb(255 255 255 / 0.7);
  border-color: rgb(255 255 255 / 0.45);
  background: rgb(255 255 255 / 0.08);
}

.cta-card__body {
  display: flex;
  flex-direction: column;
  gap: 32px;
  width: 100%;
}

/* Reference: 50px. Scales down on narrower desktops so each title holds
   to two lines three-up. */
.cta-card__title {
  font-size: clamp(34px, 3.2vw, 50px);
  font-weight: var(--weight-heading);
  line-height: 1.2;
  text-wrap: balance; /* whole words only, no hyphens (client) */
}

/* Side by side, every title reserves two lines so the paragraphs beneath
   start on one line whether the title takes one line or two. Stacked cards
   don't need the reserve. */
/* Side by side, the three cards share one set of rows (subgrid), so the
   titles, the copy and the buttons each sit level across the row whatever
   each paragraph wraps to. The first row takes the spare height, which keeps
   the content at the foot of each card as on the reference and holds the
   first card's figure just above its title. */
@media (min-width: 1001px) {
  .cta-cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: minmax(0, 1fr) auto auto auto;
  }

  @supports (grid-template-rows: subgrid) {
    .cta-card {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
      row-gap: 32px;
      justify-items: stretch;
    }

    .cta-card__body {
      display: contents;
    }

    .cta-card__figure {
      grid-row: 1;
      align-self: end;
      justify-self: center;
      margin-bottom: 16px;
    }

    .cta-card__title {
      grid-row: 2;
      align-self: end;
    }

    .cta-card__body p {
      grid-row: 3;
    }

    .cta-card .button {
      grid-row: 4;
      align-self: end;
      margin-top: 16px;
    }
  }
}

.cta-card p {
  font-size: 24px;
  font-weight: var(--weight-body);
}

/* The button holds the foot of the card. Long labels wrap inside the pill
   instead of running past its edges. */
.cta-card .button {
  width: 100%;
  padding-inline: 20px;
  white-space: normal;
  text-wrap: balance;
}

@media (max-width: 1000px) {
  .cta-cards {
    flex-direction: column;
  }

  .cta-card {
    flex: none;
    min-height: 560px;
  }

  .cta-card--neurons {
    min-height: 720px;
  }
}

@media (max-width: 600px) {
  /* 40px, easing down on the narrowest phones so "Four Practices." still
     holds one line now that words no longer hyphenate. */
  .cta-card__title {
    font-size: min(40px, calc((100vw - 112px) / 6.7));
    line-height: 1.2;
  }

  .cta-card p {
    font-size: 20px;
  }
}

@media (max-width: 430px) {
  .cta-card {
    gap: 32px;
    min-width: 300px;
    min-height: 500px;
  }

  .cta-card--neurons {
    min-height: 640px;
  }

  .cta-card__body {
    gap: 20px;
  }

  .cta-card p {
    font-size: 18px;
  }
}

/* 9. Showcase -------------------------------------------------------------- */

.showcase {
  position: relative;
  display: flex;
  flex-direction: column;
  max-width: 100%;
  padding: 20vw 9.5vw;
  color: var(--color-paper);
  background-color: var(--color-slate);
}

.showcase__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 60px;
  max-width: var(--site-max-width);
  margin: 0 auto;
}

.showcase__body .line {
  opacity: 0.12;
}

/* Frame lines with a travelling highlight, as on the reference. */
.showcase__body .line--vert {
  top: -20vw;
  height: calc(100% + 40vw);
  opacity: 1;
  background: linear-gradient(
    0deg,
    rgb(255 255 255 / 0.12) 0%,
    rgb(255 255 255 / 0.12) 50%,
    rgb(255 255 255 / 0.5) 60%,
    rgb(255 255 255 / 1) 66%,
    rgb(255 255 255 / 0) 66.1%,
    rgb(255 255 255 / 0.12) 100%
  );
  background-size: 200% 200%;
  animation: silicon-vert-l 5s ease infinite;
}

.showcase__body .line--vert.line--r {
  background: linear-gradient(
    0deg,
    rgb(255 255 255 / 0.12) 0%,
    rgb(255 255 255 / 0.12) 50%,
    rgb(255 255 255 / 0) 65.9%,
    rgb(255 255 255 / 1) 66%,
    rgb(255 255 255 / 0.5) 70%,
    rgb(255 255 255 / 0.12) 100%
  );
  background-size: 200% 200%;
  animation: silicon-vert-r 5s ease infinite;
}

.showcase__body .line--horz {
  left: -40vw;
  width: 180vw;
}

.showcase__body .line--horz.line--b {
  opacity: 1;
  background: linear-gradient(
    270deg,
    rgb(255 255 255 / 0.12) 0%,
    rgb(255 255 255 / 0.12) 50%,
    rgb(255 255 255 / 0) 65.9%,
    rgb(255 255 255 / 1) 66%,
    rgb(255 255 255 / 0.5) 70%,
    rgb(255 255 255 / 0.12) 100%
  );
  background-size: 200% 200%;
  animation: silicon-horz-b 5s ease infinite;
}

.showcase__title {
  position: relative;
}

.showcase__title h2 {
  font-size: 90px;
  font-weight: var(--weight-heading);
  line-height: 90px;
  color: var(--color-canary); /* as the Services card titles (client) */
}

.showcase__title .line--horz {
  bottom: 8px;
}

.showcase__description {
  display: flex;
  flex-direction: column;
  gap: 1em;
  font-size: 34px;
}

.showcase__figure {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 40px;
  padding: 40px;
  border: 1px solid rgb(255 255 255 / 0.4);
  background-image: radial-gradient(rgb(255 255 255 / 0.35) 0.6px, transparent 1.2px);
  background-size: 12px 12px;
}

.showcase__figure-image {
  position: relative;
}

/* The x-ray photo of the forgotten machine, at its own 1600 x 893 so its
   label bars (top and bottom) are never cropped. */
.showcase__photo,
.showcase__photo img {
  display: block;
  width: 100%;
  height: auto;
}

.showcase__figure-image .dot--tl {
  top: -1px;
  left: -1px;
}

.showcase__figure-image .dot--tr {
  top: -1px;
  right: -1px;
}

.showcase__figure-image .dot--br {
  bottom: -1px;
  right: -1px;
}

.showcase__figure-image .dot--bl {
  bottom: -1px;
  left: -1px;
}

/* Warm light streak over the top of the section, after the reference's overlay image. */
.showcase__flare {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 1680px;
  max-height: 100%;
  pointer-events: none;
  background:
    linear-gradient(112deg, rgb(255 196 150 / 0.5) 0%, rgb(255 220 205 / 0.22) 16%, transparent 38%),
    radial-gradient(55% 32% at 100% 18%, rgb(214 168 178 / 0.55), transparent 70%);
}

@media (max-width: 800px) {
  .showcase__title h2 {
    font-size: 70px;
    line-height: 76px;
  }

  .showcase__description {
    font-size: 28px;
  }
}

@media (max-width: 600px) {
  .showcase {
    padding: 80px 20px;
  }

  .showcase__figure {
    gap: 20px;
    padding: 20px;
    font-size: 16px;
  }
}

@media (max-width: 400px) {
  .showcase__description {
    font-size: 24px;
  }
}

/* 10. Pong ----------------------------------------------------------------- */

.pong {
  --pong-item: var(--color-ink);

  display: flex;
  padding: 100px 4.25vw 130px 4.25vw;
}

.pong__body {
  position: relative;
  display: flex;
  flex-direction: row;
  max-width: calc(var(--site-max-width) + 200px);
  margin: 0 auto;
}

.pong__left,
.pong__right {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50%;
}

.pong__left {
  padding: 150px 100px;
  color: var(--color-body-muted);
}

/* Two paragraphs, a line's space apart (client). */
.pong__text p + p {
  margin-top: 1em;
}

.pong__left strong {
  font-weight: var(--weight-heading);
  color: var(--pong-item);
}

.pong__divider {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 6px;
  height: 100%;
  background-image: linear-gradient(to top, transparent 50%, var(--pong-item) 50%);
  background-size: 100% 30px;
}

.pong__paddle,
.pong__ball {
  position: absolute;
  z-index: 2;
  background-color: var(--pong-item);
}

.pong__paddle {
  width: 14px;
  height: 114px;
}

.pong__paddle--left {
  top: 0;
  left: 0;
  animation: paddle-left 5s ease infinite;
}

.pong__paddle--right {
  right: 0;
  bottom: 0;
  animation: paddle-right 5s ease infinite;
}

.pong__ball-wrap {
  position: absolute;
  right: 70px;
  bottom: 98px;
  animation: pong-ball 5s linear infinite;
}

.pong__ball {
  width: 28px;
  height: 28px;
}

.pong__ball--2 {
  top: -18px;
  left: -20px;
  opacity: 0.06;
}

.pong__ball--3 {
  top: -35px;
  left: -38px;
  opacity: 0.035;
}

.pong__ball--4 {
  top: -52px;
  left: -56px;
  opacity: 0.018;
}

@media (max-width: 1050px) {
  .pong__body {
    flex-direction: column;
  }

  .pong__divider {
    display: none;
  }

  .pong__left {
    width: 100%;
    padding: 60px 100px;
  }

  .pong__right {
    width: 100%;
  }
}

@media (max-width: 800px) {
  .pong__left {
    padding: 60px;
  }
}

/* 11. Info cards ------------------------------------------------------------- */

/* Two wide cards, 20px apart in a 20px frame, 5.5vw 6vw inside; titles at
   5vw with a white rule above the copy, as on the reference. Brand fills
   (Navy and Magenta) stand in for its photographs; titles are Lime Green,
   which the guideline allows on dark surfaces. */
.info-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 20px;
}

.info-card {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  justify-content: flex-start;
  max-width: 100%;
  padding: 5.5vw 6vw;
  color: var(--color-paper);
  border-radius: 8px;
  background-color: var(--color-slate);
}

.info-card__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6.5vw;
}

/* 4vw (reference 5vw) so both titles hold to two lines side by side; two
   lines are reserved so the rule and the paragraph sit level across the
   pair. */
.info-card__title {
  min-height: calc(2 * 4.6vw);
  font-size: 4vw;
  font-weight: var(--weight-heading);
  line-height: 4.6vw;
  color: var(--color-brand-accent);
  text-wrap: balance;
}

.info-card p {
  position: relative;
  max-width: 44ch;
  font-size: 20px;
  line-height: 1.5;
}

.info-card p::before {
  content: "";
  position: absolute;
  width: 85%;
  height: 2px;
  margin-top: -40px;
  background-color: var(--color-paper);
}

.info-card .button {
  align-self: stretch;
  margin-top: 40px;
}

/* Photograph cards, as the reference's: the client's photograph shown as is,
   no scrim, a Canary title at a lighter weight and larger white copy
   (reference: title 500 in --color-canary, copy at the body size). The
   fill underneath is the fallback while an image loads. White copy sits
   near 3:1 over the lightest patches (the mauve of the streaks, the lit
   curtain), below AA for body text; this follows the client's reference. */
.info-card--photo {
  background-position: center;
  background-size: cover;
}

.info-card--photo .info-card__title {
  font-weight: 500;
  color: var(--color-canary);
}

/* Reference sizes, side by side only: 8vw from the title down to the rule,
   as the reference. The reference's 5vw title is 4.5vw here, since Baloo 2
   runs wider than the reference's face and "Close enough to knock on the
   door" would break to three lines. Stacked, the shared card sizes apply. */
@media (min-width: 1051px) {
  .info-card--photo .info-card__body {
    gap: 8vw;
  }

  .info-card--photo .info-card__title {
    min-height: calc(2 * 5.2vw);
    font-size: 4.5vw;
    line-height: 5.2vw;
  }
}

/* Between the stacked layout and 1300px the cards are too narrow for 4.5vw;
   the shared 4vw title keeps both titles to two lines and the rules level. */
@media (min-width: 1051px) and (max-width: 1300px) {
  .info-card--photo .info-card__title {
    min-height: calc(2 * 4.6vw);
    font-size: 4vw;
    line-height: 4.6vw;
  }

  .info-card--photo p {
    font-size: 22px;
  }
}

.info-card--photo p {
  font-size: 26px;
  line-height: 1.4;
}

/* Homepage closing pair at the reference's card size (client): side by
   side, corticallabs.com's cards measure 729 / 668 / 620 / 608 / 566px tall
   at 1920 / 1600 / 1440 / 1280 / 1024 wide (their longer copy sets it);
   380px + 18.2vw follows that, so the shorter copy here keeps the same
   card. Width and padding already match. Stacked, the cards fit their text. */
@media (min-width: 1051px) {
  .info-cards--closing .info-card {
    min-height: calc(380px + 18.2vw);
  }
}

/* Homepage closing cards: the client's illustrations (neurons on near-black;
   a silhouette on Magenta, framed on the head). The neurons are busy and
   light under the text (1.5:1 bare), so that card alone takes a 60% dark
   wash: title 5.7:1, copy 6.8:1. The silhouette needs none (7.8:1). */
.info-card--neurons {
  box-shadow: inset 0 0 0 100vmax rgb(18 16 14 / 0.6); /* the dark wash, over the photo */
  background-color: #2a2622;
  background-image: url("../img/cards/card-neurons.jpg");
  background-image: -webkit-image-set(url("../img/cards/card-neurons.webp?v=2") type("image/webp"), url("../img/cards/card-neurons.jpg") type("image/jpeg"));
  background-image: image-set(url("../img/cards/card-neurons.webp?v=2") type("image/webp"), url("../img/cards/card-neurons.jpg") type("image/jpeg"));
}

.info-card--portrait {
  background-color: #7a2d4a;
  background-image: url("../img/cards/card-portrait.jpg");
  background-image: -webkit-image-set(url("../img/cards/card-portrait.webp") type("image/webp"), url("../img/cards/card-portrait.jpg") type("image/jpeg"));
  background-image: image-set(url("../img/cards/card-portrait.webp") type("image/webp"), url("../img/cards/card-portrait.jpg") type("image/jpeg"));
  background-position: center 30%;
}

/* Company and Insights closing cards (client, 2026-10-07): the same two
   photographs on both pages. A backlit figure by a window, framed on the
   head, for the first card; rose-to-blue streaks for careers. */
/* The window glows almost white behind the title, so this card takes a
   warm dark wash (as the homepage's neurons card) to keep the Canary title
   and white copy readable. */
.info-card--window {
  box-shadow: inset 0 0 0 100vmax rgb(24 18 12 / 0.55); /* the dark wash, over the photo */
  background-color: #5a4a3a;
  background-image: url("../img/cards/card-window.jpg");
  background-image: -webkit-image-set(url("../img/cards/card-window.webp") type("image/webp"), url("../img/cards/card-window.jpg") type("image/jpeg"));
  background-image: image-set(url("../img/cards/card-window.webp") type("image/webp"), url("../img/cards/card-window.jpg") type("image/jpeg"));
  background-position: center 30%;
}

.info-card--haze {
  background-color: #8a7484;
  background-image: url("../img/cards/card-haze.jpg");
  background-image: -webkit-image-set(url("../img/cards/card-haze.webp") type("image/webp"), url("../img/cards/card-haze.jpg") type("image/jpeg"));
  background-image: image-set(url("../img/cards/card-haze.webp") type("image/webp"), url("../img/cards/card-haze.jpg") type("image/jpeg"));
}

/* Their text one step up (client): the reference's 5vw title and 28px copy
   side by side; stacked, 56px titles and 28px copy (44px / 20px on
   phones). Two title lines stay reserved so the rules sit level. */
@media (min-width: 1051px) {
  .info-cards--large .info-card__title {
    min-height: calc(2 * 5.7vw);
    font-size: 5vw;
    line-height: 5.7vw;
  }

  .info-cards--large .info-card p {
    font-size: 28px;
  }
}

@media (min-width: 1051px) and (max-width: 1300px) {
  .info-cards--large .info-card__title {
    min-height: calc(2 * 5.2vw);
    font-size: 4.5vw;
    line-height: 5.2vw;
  }

  .info-cards--large .info-card p {
    font-size: 24px;
  }
}

/* At this size the Company page's "Close enough to knock on the door" runs
   to three lines side by side, so that pair reserves three, keeping the
   rules and copy level. */
@media (min-width: 1301px) {
  .info-cards--three-line .info-card__title {
    min-height: calc(3 * 5.7vw);
  }
}

@media (min-width: 1051px) and (max-width: 1300px) {
  .info-cards--three-line .info-card__title {
    min-height: calc(3 * 5.2vw);
  }
}

@media (max-width: 1050px) {
  .info-cards--large .info-card__title {
    font-size: 56px;
    line-height: 62px;
  }

  .info-cards--large .info-card p {
    font-size: 28px;
  }
}

@media (max-width: 500px) {
  .info-cards--large .info-card__title {
    font-size: 44px;
    line-height: 50px;
  }

  .info-cards--large .info-card p {
    font-size: 20px;
  }
}

@media (max-width: 1050px) {
  .info-card {
    flex: none;
    width: 100%;
    padding: 60px 70px;
  }

  /* Stacked, so no reserve is needed. */
  .info-card__title {
    min-height: 0;
    font-size: 50px;
    line-height: 56px;
  }

  .info-card__body {
    gap: 70px;
  }
}

@media (max-width: 800px) {
  .info-card {
    padding: 40px;
  }
}

@media (max-width: 500px) {
  .info-card {
    padding: 30px;
  }

  .info-card__title {
    font-size: 40px;
    line-height: 46px;
  }

  .info-card p {
    font-size: 18px;
  }
}

/* 12. Footer --------------------------------------------------------------- */

.site-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 16px;
  color: var(--color-paper);
  background: var(--color-brand-jet, #111111); /* flat Jet Black, no glow (client) */
}

.horz-grads {
  width: 100%;
}

.horz-grads__bar {
  position: relative;
  width: 100%;
  height: 40px;
}

/* The bars fade into the footer's Jet Black, so they meet it without a
   seam. */
.horz-grads__bar--1 {
  background: linear-gradient(270deg, #f6f5f2 0%, var(--color-brand-jet, #111111) 77%);
}

.horz-grads__bar--2 {
  background: linear-gradient(270deg, #f6f5f2 0%, var(--color-brand-jet, #111111) 59%);
}

.horz-grads__bar::before {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background-size: 200% 200%;
}

.horz-grads__bar--1::before {
  background-image: linear-gradient(
    270deg,
    rgb(255 255 255 / 0) 0%,
    rgb(255 255 255 / 0) 50%,
    rgb(255 255 255 / 0) 65.9%,
    rgb(255 255 255 / 0.5) 66%,
    rgb(255 255 255 / 0.2) 70%,
    rgb(255 255 255 / 0.08) 100%
  );
  animation: silicon-horz-b 5s ease infinite;
}

.horz-grads__bar--2::before {
  background-image: linear-gradient(
    270deg,
    rgb(255 255 255 / 0) 0%,
    rgb(255 255 255 / 0) 50%,
    rgb(255 255 255 / 0.2) 60%,
    rgb(255 255 255 / 0.5) 66%,
    rgb(255 255 255 / 0) 66.1%,
    rgb(255 255 255 / 0.08) 100%
  );
  animation: silicon-horz-t 3s ease 1s infinite;
}

.site-footer__ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 40px 80px;
  padding: 90px 0;
}

.site-footer__ctas .button {
  border: none;
  background: linear-gradient(90deg, rgb(255 255 255 / 0.1) 0%, rgb(255 255 255 / 0.05) 100%);
  box-shadow:
    0 0 1px 0 rgb(255 255 255 / 0.4) inset,
    0 2px 0 0 rgb(255 255 255 / 0.15) inset,
    0 1px 2px 0 rgb(255 255 255 / 0.15) inset;
}

.site-footer__ctas .button:first-of-type {
  background: linear-gradient(270deg, rgb(255 255 255 / 0.1) 0%, rgb(255 255 255 / 0.05) 100%);
}

/* Four columns on one grid: the brand column a little wider so the tagline
   holds to two lines and the Practices column so its names stay on one
   line, the other two equal. Every column shares the
   same top padding, title line and 30px title-to-items gap, so the logo,
   the three titles, the tagline and the first links all sit level. */
.site-footer__lists {
  display: grid;
  grid-template-columns: 1.25fr 1.25fr 1fr 1fr; /* room for the tagline and the longest practice name */
  width: 100%;
  max-width: 1360px;
  padding: 0 4vw 40px;
}

.site-footer__list {
  display: flex;
  flex-direction: column;
  gap: 30px;
  padding: 4.3vw 4vw;
  border: 1px solid;
  border-width: 1px;
  border-top: 0;
  border-bottom: 0;
  border-left: 0;
  border-image-slice: 1;
  border-image-source: linear-gradient(
    to top,
    rgb(255 255 255 / 0),
    rgb(255 255 255 / 0.14),
    rgb(255 255 255 / 0)
  );
}

.site-footer__list:first-of-type {
  border-left: 1px solid;
}

.site-footer__list-title {
  margin: 0;
  font-size: 26px;
  font-weight: var(--weight-heading);
  line-height: 1.2;
}

/* The logo occupies the same 31px line as the titles beside it. */
.site-footer__list--brand .brand {
  display: flex;
  align-items: center;
  height: calc(26px * 1.2);
}

.site-footer__tagline {
  max-width: 26ch;
  font-size: 16px;
  line-height: 1.5;
}

.site-footer__items {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.site-footer__items a {
  font-size: 16px;
  line-height: 1.5;
}

.site-footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 60px;
  border-top: 1px solid rgb(255 255 255 / 0.1);
  background: none; /* the whole footer one flat Jet Black */
}

.site-footer__bottom > * {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 60px;
}

.brand__mark--footer {
  height: 28px;
}

/* The bottom bar carries the chameleon mark instead of the wordmark
   (client), square, 48px (client: a touch larger). */
.brand__mark--chameleon {
  width: 48px;
  height: 48px;
}

@media (max-width: 900px) {
  .site-footer__lists {
    grid-template-columns: repeat(2, 1fr);
  }

  .site-footer__list {
    padding: 30px 40px;
  }

  .site-footer__bottom {
    flex-flow: column-reverse;
    justify-content: center;
    gap: 40px;
    padding: 40px;
  }

  .site-footer__bottom > * {
    flex-flow: wrap-reverse;
    justify-content: center;
    gap: 40px;
  }
}

@media (max-width: 560px) {
  .site-footer__lists {
    grid-template-columns: 1fr;
  }

  .site-footer__list {
    border: none;
  }

  .site-footer__list:first-of-type {
    border-left: none;
  }
}

@media (max-width: 800px) {
  body {
    font-size: 22px;
  }
}

@media (max-width: 400px) {
  body {
    font-size: 18px;
  }
}

/* 12b. Section reveals ------------------------------------------------------ */

/* main.js adds .js-reveal to the document and .reveal to each block, then
   .is-in as it scrolls into view. Nothing here applies without that, so the
   page is fully visible with JavaScript off. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity 0.7s ease,
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.js-reveal .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* Cards arrive one after another rather than all at once. */
.js-reveal .cta-card:nth-child(2),
.js-reveal .info-cards--closing .info-card:nth-child(2) {
  transition-delay: 90ms;
}

.js-reveal .cta-card:nth-child(3) {
  transition-delay: 180ms;
}

.js-reveal .showcase__description {
  transition-delay: 90ms;
}

.js-reveal .showcase__figure {
  transition-delay: 180ms;
}

.js-reveal .pong__right {
  transition-delay: 120ms;
}

.js-reveal .site-footer__lists {
  transition-delay: 180ms;
}

/* 12c. Contact dialog ------------------------------------------------------ */

/* main.js builds it (2c). A Jet Black panel like the footer: the WhatsApp
   button solid white as the footer's "Book an assessment", the form below
   it, the privacy line last. Phones get it as a full-screen panel. */
.contact {
  width: min(560px, calc(100% - 32px));
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: 24px;
  color: var(--color-paper);
  background: var(--color-brand-jet);
  box-shadow: 0 24px 80px rgb(0 0 0 / 0.4);
}

.contact::backdrop {
  background: rgb(0 0 0 / 0.6);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* The form and thank-you swap with [hidden]; the flex layout below would
   otherwise keep the form showing. */
.contact [hidden] {
  display: none;
}

.contact__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 48px 40px 32px;
}

.contact__close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
}

.contact__close:hover {
  background: rgb(255 255 255 / 0.08);
}

.contact__title {
  padding-right: 40px; /* clear of the close button */
  font-size: 32px;
  line-height: 1.15;
}

.contact__lead {
  font-size: 18px;
  line-height: 1.45;
  color: rgb(255 255 255 / 0.75);
}

.contact__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 8px;
  padding-top: 24px;
  border-top: 1px solid rgb(255 255 255 / 0.12);
}

.contact__form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  line-height: 1.4;
  color: rgb(255 255 255 / 0.75);
}

.contact__form input,
.contact__form textarea {
  padding: 12px 16px;
  font: inherit;
  font-size: 16px; /* 16px keeps iOS from zooming into the field */
  color: var(--color-paper);
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.2);
  border-radius: 12px;
}

.contact__form textarea {
  resize: vertical;
}

.contact__form input:focus-visible,
.contact__form textarea:focus-visible {
  border-color: var(--color-paper);
  outline: none;
}

/* The honeypot: out of sight and out of the tab order. */
.contact__trap {
  position: absolute;
  left: -9999px;
}

.contact__form [type="submit"]:disabled {
  opacity: 0.6;
  cursor: progress;
}

.contact__small,
.contact__error {
  font-size: 14px;
  line-height: 1.5;
  color: rgb(255 255 255 / 0.6);
}

.contact__error {
  color: #ffb4a8;
}

.contact__small a,
.contact__error a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.contact__thanks {
  padding: 24px 0;
  font-size: 20px;
  line-height: 1.45;
  border-top: 1px solid rgb(255 255 255 / 0.12);
}

@media (max-width: 600px) {
  .contact {
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    border-radius: 0;
  }

  .contact__panel {
    min-height: 100%;
    padding: 64px 20px 32px;
  }
}

/* 13. Keyframes ------------------------------------------------------------ */

@keyframes bg-in {
  to {
    opacity: 1;
  }
}

@keyframes drift-a {
  to {
    transform: translate3d(9vw, 7vw, 0) scale(1.18);
  }
}

@keyframes drift-b {
  to {
    transform: translate3d(-8vw, 9vw, 0) scale(1.12);
  }
}

@keyframes drift-c {
  to {
    transform: translate3d(10vw, -6vw, 0) scale(0.9);
  }
}

@keyframes drift-d {
  to {
    transform: translate3d(-9vw, -7vw, 0) scale(1.22);
  }
}

@keyframes drift-e {
  to {
    transform: translate3d(7vw, -9vw, 0) scale(1.1);
  }
}

@keyframes streaks-slide {
  to {
    transform: translateX(10vw);
  }
}

@keyframes tape {
  to {
    transform: translateX(-50%);
  }
}

@keyframes silicon-horz-t {
  0% {
    background-position: -100% 0;
  }

  50%,
  100% {
    background-position: 100% 0;
  }
}

@keyframes silicon-horz-b {
  0% {
    background-position: 100% 0;
  }

  50%,
  100% {
    background-position: -100% 0;
  }
}

@keyframes silicon-vert-l {
  0% {
    background-position: 0 -100%;
  }

  50%,
  100% {
    background-position: 0 100%;
  }
}

@keyframes silicon-vert-r {
  0%,
  50% {
    background-position: 0 100%;
  }

  100% {
    background-position: 0 -100%;
  }
}

@keyframes paddle-left {
  0%,
  100% {
    top: calc(100% - 114px);
  }

  25% {
    top: 0;
  }

  50% {
    top: 80%;
  }

  75% {
    top: 30%;
  }
}

@keyframes paddle-right {
  0%,
  100% {
    bottom: 0;
  }

  50% {
    bottom: calc(100% - 114px);
  }
}

@keyframes pong-ball {
  0%,
  100% {
    right: 32px;
    bottom: 98px;
    transform: rotate(180deg);
  }

  25%,
  75% {
    right: 40%;
    bottom: 100%;
  }

  50% {
    right: calc(100% - 30px);
    bottom: 15%;
    transform: rotate(270deg);
  }

  0.01%,
  24.99% {
    transform: rotate(180deg);
  }

  25%,
  49.99% {
    transform: rotate(90deg);
  }

  74.99% {
    transform: rotate(270deg);
  }

  75%,
  99.99% {
    transform: rotate(360deg);
  }
}
