/* =========================================================
   Components and sections. Mobile first; each block carries
   its own wider-screen rules directly underneath it, so a
   component is read in one place.

   Breakpoints: 40em (large phone), 48em (tablet),
   64em (laptop), 80em (desktop).
   ========================================================= */

/* ═══════════════════════════ PRIMITIVES ═══════════════════════════ */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}

.container--narrow {
  max-width: var(--container-narrow);
}

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

.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--ink);
  color: var(--porcelain);
  font-weight: 700;
  text-decoration: none;
}

.skip-link:focus-visible {
  width: auto;
  height: auto;
  padding: 0.75rem 1.25rem;
  clip-path: none;
  outline-color: var(--sol);
  outline-offset: -4px;
}

/* ---------- The mark ---------- */

.mark {
  flex: none;
  overflow: visible;
}

.mark__face {
  fill: var(--mark-face, var(--porcelain));
  stroke: var(--mark-ink, var(--ink));
}

.mark__eye {
  fill: var(--mark-ink, var(--ink));
}

/* ---------- Icons ---------- */

.icon {
  flex: none;
  width: 1em;
  height: 1em;
  transition: transform 0.3s var(--ease);
}

/* ---------- Label ----------
   The technical label above a heading: index box, mono name, trailing rule. */

.label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.label::after {
  content: "";
  flex: 1 1 auto;
  max-width: 4rem;
  height: 1px;
  background: currentColor;
  opacity: 0.4;
}

.label__index {
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--rule-mid);
  color: var(--sol-ink);
  letter-spacing: 0.06em;
}

.heading--center .label {
  justify-content: center;
}

/* ---------- Section heading ---------- */

.heading {
  max-width: 48rem;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.heading--center {
  margin-inline: auto;
  text-align: center;
}

.heading__title {
  font-size: var(--step-4);
}

.heading__lead {
  max-width: 42rem;
  margin-top: 1.25rem;
  color: var(--text-2);
  font-size: var(--step-1);
  line-height: 1.55;
}

.heading--center .heading__lead {
  margin-inline: auto;
}

/* ---------- Buttons ----------
   A printed offset rather than a blur: the button sits on the page like a
   stamped label and presses into it on click. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: 3rem;
  padding: 0.75rem 1.25rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 700;
  line-height: 1.1;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform 0.2s var(--ease),
    box-shadow 0.2s var(--ease),
    background-color 0.2s var(--ease),
    color 0.2s var(--ease);
}

.btn:hover .icon--arrow {
  transform: translateX(3px);
}

.btn--primary {
  background: var(--ink);
  color: var(--porcelain);
  box-shadow: 3px 3px 0 var(--sol);
}

.btn--primary:hover {
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--sol);
}

.btn--secondary {
  background: var(--porcelain);
  color: var(--ink);
  box-shadow: var(--offset);
}

.btn--secondary:hover {
  transform: translate(-1px, -1px);
  box-shadow: var(--offset-hover);
}

.btn--sploit {
  border-color: var(--sploit);
  background: var(--sploit);
  color: var(--night-deep);
  box-shadow: 3px 3px 0 var(--on-night);
}

.btn--sploit:hover {
  transform: translate(-1px, -1px);
  box-shadow: 5px 5px 0 var(--on-night);
}

.btn:active {
  transform: translate(2px, 2px);
  box-shadow: 0 0 0 transparent;
}

.btn--small {
  min-height: 2.5rem;
  padding: 0.5rem 0.9rem;
  font-size: var(--step--1);
}

.section-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: clamp(2rem, 4vw, 2.75rem);
}

/* ---------- Links ---------- */

.more {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.75rem;
  color: var(--sol-ink);
  font-weight: 700;
  text-decoration: none;
}

.more:hover {
  text-decoration: underline;
}

.more:hover .icon--arrow {
  transform: translateX(3px);
}

/* ---------- Tags ---------- */

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.tag {
  padding: 0.2rem 0.55rem;
  border: 1px solid var(--rule-mid);
  border-radius: var(--radius);
  background: var(--porcelain);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.5;
}

.tag--future {
  border-style: dashed;
  background: transparent;
}

.tag--edu {
  border-color: var(--edu);
  background: var(--porcelain);
  color: var(--edu-ink);
}

.tags--large .tag {
  padding: 0.4rem 0.75rem;
  font-size: var(--step--1);
}

/* ---------- Check list ---------- */

.checks {
  display: grid;
  gap: 0.55rem;
}

.checks li {
  position: relative;
  padding-left: 1.75rem;
  color: var(--text-2);
}

.checks li::before {
  content: "";
  position: absolute;
  top: 0.42em;
  left: 0.2rem;
  width: 0.8rem;
  height: 0.45rem;
  border-bottom: 2px solid var(--sol-ink);
  border-left: 2px solid var(--sol-ink);
  transform: rotate(-45deg);
}

.checks--compact {
  gap: 0.3rem;
  margin-block: 0.75rem;
  font-size: var(--step--1);
}

/* ---------- Status ---------- */

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.status__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 3px rgb(63 122 90 / 0.15);
}

.status--warn .status__dot {
  background: var(--warn);
  box-shadow: 0 0 0 3px rgb(168 112 29 / 0.18);
}

.status--bad .status__dot {
  background: var(--bad);
}

.status--info .status__dot {
  background: var(--sol);
  box-shadow: 0 0 0 3px rgb(143 155 208 / 0.22);
}

/* ---------- Disclosure ---------- */

.disclosure {
  margin-top: 0.75rem;
}

.disclosure__summary {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.25rem;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}

.disclosure__summary::-webkit-details-marker {
  display: none;
}

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

.disclosure__icon {
  position: relative;
  width: 0.9rem;
  height: 0.9rem;
  border: 1px solid currentColor;
}

.disclosure__icon::before,
.disclosure__icon::after {
  content: "";
  position: absolute;
  inset: 50% 20% auto;
  height: 1px;
  background: currentColor;
  transition: transform 0.25s var(--ease);
}

.disclosure__icon::after {
  transform: rotate(90deg);
}

.disclosure[open] .disclosure__icon::after {
  transform: rotate(0deg);
}

.disclosure__body {
  padding: 0.75rem 0 0.25rem;
}

/* ---------- Skull illustrations ---------- */

.skull {
  margin: 0;
}

.skull__svg {
  width: 100%;
  max-width: 100%;
  height: auto;
}

.skull__caption {
  margin-top: 0.4rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  text-align: center;
}

/* The Skull's movement lives in motion.css. */

/* ═══════════════════════════ HEADER ═══════════════════════════ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  padding-top: env(safe-area-inset-top);
  background: rgb(242 239 235 / 0.94);
  border-bottom: 1px solid var(--rule);
  backdrop-filter: saturate(1.2) blur(10px);
  -webkit-backdrop-filter: saturate(1.2) blur(10px);
}

/* Fills the band iOS paints behind its translucent status strip. */
.site-header::before {
  content: "";
  position: absolute;
  right: 0;
  bottom: 100%;
  left: 0;
  height: 6rem;
  background: var(--paper);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  text-decoration: none;
}

/* The header's mark is the animated Skull (the "brand" role), held to the
   glyph's box so the row does not move when it arrives. */
.brand .skull__svg {
  flex: none;
  width: 30px;
  height: auto;
}

.brand__word {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

.site-header .brand__word b {
  font-weight: 700;
}

.brand--footer .brand__word {
  font-weight: 600;
}

/* ---------- Menu (below 64em) ---------- */

.menu__button {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.75rem;
  padding-inline: 0.9rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}

.menu__button::-webkit-details-marker {
  display: none;
}

.menu__bars {
  position: relative;
  width: 1rem;
  height: 0.625rem;
}

.menu__bars::before,
.menu__bars::after {
  content: "";
  position: absolute;
  right: 0;
  left: 0;
  height: 2px;
  background: currentColor;
  transition: transform 0.3s var(--ease);
}

.menu__bars::before {
  top: 0;
}

.menu__bars::after {
  bottom: 0;
}

/* The open menu lives in the header, which sits under the chat launcher; lift
   it while open so the launcher cannot cover the menu's last links. */
.site-header:has(.menu[open]) {
  z-index: 70;
}

.menu[open] .menu__bars::before {
  transform: translateY(0.25rem) rotate(45deg);
}

.menu[open] .menu__bars::after {
  transform: translateY(-0.25rem) rotate(-45deg);
}

.menu__panel {
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  max-height: calc(100dvh - 100%);
  overflow-y: auto;
  padding: 0.5rem max(var(--gutter), env(safe-area-inset-right)) calc(1.5rem + env(safe-area-inset-bottom))
    max(var(--gutter), env(safe-area-inset-left));
  background: var(--paper);
  border-bottom: 1.5px solid var(--ink);
  box-shadow: 0 24px 40px -30px rgb(23 20 28 / 0.5);
  animation: menu-drop 0.24s var(--ease) both;
}

@keyframes menu-drop {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
}

.nav__list {
  display: flex;
  flex-direction: column;
}

.nav__list > li + li {
  border-top: 1px solid var(--rule);
}

.nav__link {
  display: block;
  padding-block: 0.9rem;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 1.625rem;
  font-weight: 600;
  text-decoration: none;
}

.nav__link.is-current {
  color: var(--sol-ink);
}

.nav__link.is-current::after {
  content: " ·";
}

.menu__cta {
  width: 100%;
  margin-top: 1rem;
}

@media (max-width: 22em) {
  .menu__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .brand__word {
    font-size: 1.3rem;
  }
}

@media (min-width: 64em) {
  .menu__button {
    display: none;
  }

  .menu__panel {
    position: static;
    display: flex;
    align-items: center;
    gap: 2rem;
    max-height: none;
    overflow: visible;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    animation: none;
  }

  .menu::details-content {
    content-visibility: visible;
    block-size: auto;
  }

  .nav__list {
    flex-direction: row;
    gap: 1.75rem;
  }

  .nav__list > li + li {
    border-top: 0;
  }

  .nav__link {
    position: relative;
    padding-block: 1.4rem;
    font-family: var(--font-body);
    font-size: var(--step--1);
    font-weight: 500;
  }

  .nav__link::before {
    content: "";
    position: absolute;
    right: 0;
    bottom: 1rem;
    left: 0;
    height: 1.5px;
    background: var(--sol);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s var(--ease);
  }

  .nav__link:hover::before,
  .nav__link:focus-visible::before,
  .nav__link.is-current::before {
    transform: scaleX(1);
  }

  .nav__link.is-current {
    color: var(--ink);
  }

  .nav__link.is-current::after {
    content: none;
  }

  .menu__cta {
    width: auto;
    margin-top: 0;
  }
}

/* ═══════════════════════════ SECTIONS ═══════════════════════════ */

.section {
  position: relative;
  padding-block: var(--section-space);
}

.section--paper {
  background: var(--paper);
}

.section--porcelain {
  background: var(--porcelain);
  border-block: 1px solid var(--rule);
}

.section--grid {
  background-color: var(--paper);
  background-image: var(--grid-dot);
  background-size: var(--grid-size);
  border-block: 1px solid var(--rule);
}

.section--periwinkle {
  background:
    radial-gradient(120% 90% at 100% 0%, rgb(251 249 247 / 0.9) 0%, transparent 55%),
    var(--sol-wash);
}

.section--edu {
  background:
    radial-gradient(110% 90% at 20% 30%, var(--porcelain) 0%, transparent 60%),
    var(--edu-wash);
}

.section--night {
  background: var(--night);
  color: var(--on-night);
}

/* The mascot's teeth, rising from a dark band into whatever sits above it.
   Drawn in the band's own colour, so it never needs to know its neighbour. */
.teeth {
  position: absolute;
  right: 0;
  bottom: 100%;
  left: 0;
  height: 30px;
  background-color: var(--night);
  -webkit-mask: var(--teeth) repeat-x center bottom / 98px 30px;
  mask: var(--teeth) repeat-x center bottom / 98px 30px;
  transform: scaleY(-1);
  pointer-events: none;
}

/* ═══════════════════════════ SPLIT LAYOUTS ═══════════════════════════ */

.split {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
}

.split__skull {
  width: min(100%, 15rem);
  margin-inline: auto;
}

.split__main > .heading:last-child {
  margin-bottom: 0;
}

.split__label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.split__label--sploit {
  margin-top: 1.5rem;
  margin-bottom: 0;
  --mark-face: var(--porcelain);
}

@media (min-width: 64em) {
  .split {
    grid-template-columns: 5fr 7fr;
    align-items: start;
  }

  .split--eng,
  .split--process,
  .split--stack {
    grid-template-columns: 7fr 5fr;
  }

  .split--about {
    grid-template-columns: 4fr 8fr;
    align-items: center;
  }

  .split--process .split__aside,
  .split--stack .split__aside {
    align-self: end;
  }

  .split__skull {
    margin-inline: 0;
  }

  .split--process .split__skull,
  .split--stack .split__skull,
  .split--net .split__skull {
    margin-inline: auto 0;
  }
}

/* ═══════════════════════════ HERO ═══════════════════════════ */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3.5rem, 8vw, 6.5rem);
  background:
    radial-gradient(70% 70% at 78% 40%, var(--porcelain) 0%, rgb(251 249 247 / 0) 70%),
    var(--paper);
  border-bottom: 1px solid var(--rule);
}

/* Engineering paper behind the figure, fading out towards the copy. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grid-dot);
  background-size: var(--grid-size);
  -webkit-mask-image: radial-gradient(60% 70% at 75% 45%, #000 0%, transparent 75%);
  mask-image: radial-gradient(60% 70% at 75% 45%, #000 0%, transparent 75%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  display: grid;
  gap: clamp(2.5rem, 6vw, 3rem);
  align-items: center;
}

.hero__title {
  font-size: var(--step-5);
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.hero__title em {
  color: var(--sol-ink);
}

.hero__lede {
  max-width: 36rem;
  margin-top: 1.5rem;
  color: var(--text-2);
  font-size: var(--step-1);
  line-height: 1.55;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 2rem;
}

@media (min-width: 64em) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  }
}

/* ---------- The hero figure ---------- */

.system {
  position: relative;
  width: 100%;
  max-width: 38rem;
  margin-inline: auto;
  aspect-ratio: 600 / 520;
}

.system__lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.system__ring {
  fill: none;
  stroke: var(--rule-mid);
  stroke-width: 1;
  stroke-dasharray: 3 5;
  vector-effect: non-scaling-stroke;
}

.system__ring--inner {
  stroke: var(--rule);
  stroke-dasharray: none;
}

.system__wire {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1;
  stroke-dasharray: 5 4;
  vector-effect: non-scaling-stroke;
  opacity: 0.55;
}

.system__joint {
  fill: var(--porcelain);
  stroke: var(--ink);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}

.system__hub {
  position: absolute;
  top: 57.69%;
  left: 50%;
  width: 29%;
  transform: translate(-50%, -52%);
}

.system__nodes {
  position: absolute;
  inset: 0;
  /* The labels take the pointer; the empty layer between them does not, so
     the Skull underneath can still be poked. */
  pointer-events: none;
}

.system__node {
  pointer-events: auto;
}

.system__node {
  position: absolute;
  display: grid;
  gap: 0.1rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  box-shadow: 2px 2px 0 var(--ink);
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

.system__name {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.04em;
}

.system__node .status {
  font-size: 0.625rem;
}

.system__node--joke {
  transform: translate(-50%, -50%) rotate(-3deg);
  border-style: dashed;
}

/* Positions match heroNodes in src/components/diagrams.mjs (x/600, y/520). */
.system__node--1 { left: 15.33%; top: 18.46%; }
.system__node--2 { left: 50%; top: 7.69%; }
.system__node--3 { left: 85.33%; top: 18.46%; }
.system__node--4 { left: 9.33%; top: 57.69%; }
.system__node--5 { left: 91.33%; top: 57.69%; }
.system__node--6 { left: 17.33%; top: 91.92%; }
.system__node--7 { left: 82.67%; top: 91.92%; }

.system__caption {
  position: absolute;
  right: 0;
  bottom: -2.25rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.system__mobile-lines,
.system__mobile-nodes {
  display: none;
}

/* Match the self-hosted display face while it is loading. The local fallback
   keeps the italic third line clear of the desk even on a cold connection. */
@font-face {
  font-family: "Hero serif fallback";
  src: local("Times New Roman Bold"), local("TimesNewRomanPS-BoldMT");
  font-weight: 600;
  size-adjust: 92%;
}

@font-face {
  font-family: "Hero serif fallback";
  src: local("Times New Roman Italic"), local("TimesNewRomanPS-ItalicMT");
  font-weight: 500;
  font-style: italic;
  size-adjust: 88%;
}

/* A phone-sized field card. The same headline and desk share a single grid
   area; the wiring ends below both, before the copy and actions. Keep this
   below 40em so the tablet and desktop composition stay as they were. */
@media (max-width: 39.99em) {
  .hero {
    container: hero / inline-size;
    padding-block: 1.25rem 1.5rem;
  }

  .hero::before {
    -webkit-mask-image: linear-gradient(90deg, transparent 42%, #000);
    mask-image: linear-gradient(90deg, transparent 42%, #000);
    opacity: 0.7;
  }

  .hero > .doodles {
    display: none;
  }

  .hero__inner {
    grid-template-areas: "label" "cover" "lede" "actions" "ask";
    gap: 0;
    align-items: start;
    max-width: 30rem;
  }

  .hero__text {
    display: contents;
  }

  .hero__text > .label {
    grid-area: label;
    gap: 0.5rem;
    margin-bottom: 1rem;
    font-size: 0.625rem;
    letter-spacing: 0.08em;
  }

  .hero__title {
    grid-area: cover;
    z-index: 1;
    justify-self: start;
    font-family: "Cormorant Garamond", "Hero serif fallback", Garamond, "Times New Roman", serif;
    font-size: clamp(2.75rem, 14vw, 4rem);
    line-height: 1.02;
    letter-spacing: -0.035em;
    pointer-events: none;
  }

  .hero__figure {
    grid-area: cover;
    min-width: 0;
    margin-bottom: 1rem;
  }

  .hero .system {
    height: clamp(12.5rem, 57vw, 15.5rem);
    aspect-ratio: auto;
  }

  .hero .system__lines,
  .hero .system__nodes,
  .hero .system__caption {
    display: none;
  }

  /* Small enough to stay clear of the headline, so a tap pokes the Skull and
     not the words beside it. Its chin rests on the wire. */
  .hero .system__hub {
    top: 66%;
    left: 83%;
    width: 27%;
    transform: translate(-50%, -100%);
  }

  .system__mobile-lines {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
  }

  .system__mobile-nodes {
    position: absolute;
    inset: auto 0 0;
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
  }

  .system__mobile-nodes li {
    min-width: 27%;
    padding: 0.25rem 0.4rem;
    border: 1px solid var(--ink);
    background: var(--porcelain);
    box-shadow: 2px 2px 0 var(--ink);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    line-height: 1.4;
    text-align: center;
  }

  .hero__lede {
    grid-area: lede;
    max-width: 24rem;
    margin-top: 0;
    font-size: 1rem;
    line-height: 1.45;
  }

  .hero__desktop-copy {
    display: none;
  }

  .hero__invitation {
    display: block;
    margin-top: 0.5rem;
    color: var(--ink);
    font-weight: 600;
  }

  .hero__actions {
    grid-area: actions;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.25rem;
  }

  .hero__actions .btn {
    gap: 0.4rem;
    padding-inline: 0.75rem;
    font-size: 0.875rem;
  }

  .hero__actions .btn--secondary {
    min-height: 3rem;
    padding-inline: 0;
    border-color: transparent;
    background: transparent;
    box-shadow: none;
    text-decoration: underline;
    text-underline-offset: 0.25em;
    font-weight: 500;
  }

  .hero__actions .btn--secondary:hover {
    transform: none;
    color: var(--sol-ink);
  }

  .hero__text > .ask {
    grid-area: ask;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--rule-mid);
    font-size: 0.875rem;
  }

  .hero__text > .ask .ask__button {
    min-height: 2.75rem;
    padding: 0;
    border: 0;
    background: transparent;
    font-size: 0.875rem;
  }

  .hero__text > .ask .ask__button:hover {
    color: var(--sol-ink);
    box-shadow: none;
  }

  .page-home .capabilities-section {
    padding-top: 2rem;
  }
}

/* When enlarged text leaves too little room for the shared composition,
   give the drawing its own row. The content remains in normal flow. */
@container hero (max-width: 18rem) {
  .hero__inner {
    grid-template-areas: "label" "title" "figure" "lede" "actions" "ask";
  }

  .hero__title {
    grid-area: title;
    font-size: 2.5rem;
  }

  .hero__figure {
    grid-area: figure;
  }

  .hero .system {
    height: 9rem;
  }

  .hero .system__hub {
    top: 50%;
    left: 50%;
    width: 75%;
  }

  .system__mobile-lines,
  .system__mobile-nodes {
    display: none;
  }
}

@media (max-width: 29.99em) {
  .system__node--minor,
  .system__wire--minor {
    display: none;
  }

  .system__node {
    padding: 0.25rem 0.4rem;
  }

  .system__hub {
    width: 52%;
  }
}

@media (min-width: 48em) {
  .system__name {
    font-size: 0.75rem;
  }

  .system__node .status {
    font-size: 0.6875rem;
  }
}

/* ═══════════════════════════ CAPABILITIES ═══════════════════════════ */

.capabilities {
  display: grid;
  gap: 1rem;
}

.capability {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  transition:
    transform 0.25s var(--ease),
    box-shadow 0.25s var(--ease);
}

.capability:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--sol);
}

.capability:focus-within {
  box-shadow: 6px 6px 0 var(--sol);
}

.capability__art {
  display: grid;
  place-items: center;
  min-height: 8.5rem;
  padding: 1rem;
  border-bottom: 1px solid var(--rule-mid);
  background-color: var(--paper);
  background-image: var(--grid-dot);
  background-size: var(--grid-size);
}

.capability__art .skull {
  width: 7.5rem;
}

@media (min-width: 64em) {
  .capability__art {
    min-height: 11rem;
  }

  .capability__art .skull {
    width: 9rem;
  }
}

.capability__text {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.25rem 1.25rem 1.4rem;
}

.capability__index {
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
}

.capability__title {
  font-size: var(--step-3);
}

/* The whole card is the link's hit area; the heading keeps the accessible name. */
.capability__link {
  text-decoration: none;
}

.capability__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.capability__link:focus-visible {
  outline: none;
}

.capability__link:focus-visible::after {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

.capability__body {
  color: var(--text-2);
}

.capability__tags {
  margin-top: 0.25rem;
}

.capability__more {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: auto;
  padding-top: 0.5rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.capability__more::after {
  content: "→";
  transition: transform 0.25s var(--ease);
}

.capability:hover .capability__more::after {
  transform: translateX(4px);
}

/* On a phone the art sits beside the text, so five categories scan in one or
   two screens instead of five. */
@media (max-width: 39.99em) {
  .capability {
    grid-template-rows: none;
    grid-template-columns: 5.5rem 1fr;
  }

  .capability__art {
    min-height: 0;
    padding: 0.5rem;
    border-right: 1px solid var(--rule-mid);
    border-bottom: 0;
  }

  .capability__art .skull {
    width: 4.5rem;
  }

  .capability__text {
    gap: 0.4rem;
    padding: 1rem;
  }

  .capability__title {
    font-size: var(--step-2);
  }
}

@media (min-width: 40em) {
  .capabilities {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .capabilities {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 1.25rem;
  }

  .capability {
    grid-column: span 4;
  }

  .capability--wide {
    grid-column: span 6;
    grid-template-rows: none;
    grid-template-columns: 15rem 1fr;
  }

  .capability--wide .capability__art {
    border-right: 1px solid var(--rule-mid);
    border-bottom: 0;
  }

  .capability--wide .capability__art .skull {
    width: 10rem;
  }
}

.services-preview__more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-top: 1.5rem;
  padding: 1rem 1.1rem;
  border-left: 3px solid var(--sol);
  background: var(--sol-tint);
}

.services-preview__more > p:first-child {
  max-width: 42rem;
  color: var(--text-2);
}

.services-preview__more .section-actions {
  margin-top: 0;
}

/* ═══════════════════════════ PROBLEMS ═══════════════════════════ */

.problems {
  display: grid;
  gap: 1.25rem 2rem;
}

.problem {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  grid-template-areas:
    "face quote"
    ". route";
  gap: 0.5rem 0.9rem;
  align-items: start;
}

.problem__face {
  grid-area: face;
  padding-top: 0.25rem;
}

.problem__quote {
  position: relative;
  grid-area: quote;
  padding: 0.9rem 1.1rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
}

/* The speech tail, pointing back at the Skull. Two triangles: the ink edge and
   the paper fill inside it. */
.problem__quote::before,
.problem__quote::after {
  content: "";
  position: absolute;
  top: 1.25rem;
  width: 0;
  height: 0;
  border-style: solid;
}

.problem__quote::before {
  left: -11px;
  border-width: 8px 11px 8px 0;
  border-color: transparent var(--ink) transparent transparent;
}

.problem__quote::after {
  left: -8px;
  border-width: 7px 9px 7px 0;
  margin-top: 1px;
  border-color: transparent var(--paper) transparent transparent;
}

.problem__quote p {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-style: italic;
  font-weight: 500;
  line-height: 1.2;
}

.problem__quote p::before {
  content: "“";
}

.problem__quote p::after {
  content: "”";
}

.problem__route {
  grid-area: route;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.04em;
}

.problem__route a {
  color: var(--sol-ink);
  font-weight: 500;
  text-decoration: none;
}

.problem__route a::before {
  content: "→ ";
}

.problem__route a:hover {
  text-decoration: underline;
}

@media (min-width: 48em) {
  .problems {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem 2.5rem;
  }

  /* The last two are the ones that route to a person; they read as the
     conversation's closing lines, so they sit apart. */
  .problem:nth-last-child(-n + 2) .problem__quote {
    background: var(--sol-tint);
  }

  .problem:nth-last-child(-n + 2) .problem__quote::after {
    border-right-color: var(--sol-tint);
  }
}

@media (min-width: 80em) {
  .problem {
    grid-template-columns: 5.25rem 1fr;
  }
}

/* ═══════════════════════════ SERVICE SCOPE & PRICES ═══════════════════════════ */

.service__note {
  margin-top: 0.75rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--sol);
  color: var(--text-2);
  font-size: var(--step--1);
}

.price {
  display: inline-block;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--rule-mid);
  border-radius: var(--radius);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.price--published {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--porcelain);
}

/* ═══════════════════════════ DIAGRAMS ═══════════════════════════ */

.diagram {
  padding: clamp(1rem, 3vw, 1.75rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.diagram__caption {
  margin-bottom: 1.25rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.diagram__fig {
  margin-right: 0.5rem;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--rule-mid);
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

/* ---------- Network: a column on phones, a row from tablet up ---------- */

.net {
  display: grid;
  gap: 1.5rem;
}

.net__stage {
  position: relative;
}

/* The wire between stages. */
.net__stage + .net__stage::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 1.25rem;
  width: 1.5px;
  height: 1.5rem;
  background: repeating-linear-gradient(to bottom, var(--ink) 0 4px, transparent 4px 7px);
}

.net__box {
  position: relative;
  display: grid;
  gap: 0.15rem;
  padding: 0.65rem 0.8rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
}

.net__box--muted {
  border-style: dashed;
  background: transparent;
}

.net__box--key {
  background: var(--sol-wash);
  box-shadow: 3px 3px 0 var(--ink);
}

.net__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
}

.net__detail {
  color: var(--text-2);
  font-size: var(--step--2);
  line-height: 1.4;
}

.net__badge {
  justify-self: start;
  margin-top: 0.3rem;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--sol-ink);
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
}

.net__branches {
  display: grid;
  gap: 0.6rem;
  padding-left: 1.25rem;
  border-left: 1.5px solid var(--ink);
}

.net__branch {
  position: relative;
}

.net__branch::before {
  content: "";
  position: absolute;
  top: 50%;
  right: 100%;
  width: 1.25rem;
  height: 1.5px;
  background: var(--ink);
}

@media (min-width: 48em) {
  .net {
    grid-template-columns: repeat(3, minmax(0, 0.8fr)) minmax(0, 1.4fr);
    align-items: center;
    gap: 1.25rem;
  }

  .net__stage + .net__stage::before {
    top: 50%;
    right: 100%;
    bottom: auto;
    left: auto;
    width: 1.25rem;
    height: 1.5px;
    background: repeating-linear-gradient(to right, var(--ink) 0 4px, transparent 4px 7px);
  }

  .net__stage--split::before {
    display: none;
  }

  .net__branches {
    padding-left: 1.25rem;
  }
}

/* ---------- Architecture: stacked layers ---------- */

.arch {
  display: grid;
  gap: 0.4rem;
}

.arch__layer {
  display: grid;
  gap: 0.4rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--rule-mid);
  background: var(--paper);
}

.arch__layer--key {
  border: 1.5px solid var(--ink);
  background: var(--sol-wash);
}

.arch__name {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.arch__parts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.arch__parts li {
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--rule-mid);
  background: var(--porcelain);
  font-size: var(--step--2);
}

@media (min-width: 40em) {
  .arch__layer {
    grid-template-columns: 6.5rem 1fr;
    align-items: center;
  }
}

.split__aside--eng {
  display: grid;
  gap: 1.5rem;
}

/* ═══════════════════════════ HEALTH CHECKUP ═══════════════════════════ */

.health {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.health .heading__title em {
  color: var(--sol-ink);
}

.versus {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  margin-block: 0.5rem 1.5rem;
}

.versus__item {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
}

.versus__item .skull {
  width: 7rem;
}

.versus__item figcaption {
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--rule-mid);
  background: var(--porcelain);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.versus__vs {
  align-self: center;
  color: var(--text-3);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-style: italic;
}

.health__caveat,
.caveat {
  max-width: 40rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--sol);
  color: var(--text-2);
  font-size: var(--step--1);
}

.caveat {
  margin-top: 2rem;
}

/* The report: a printout on porcelain, with a torn top edge implied by a
   dashed rule, a header strip and rows like a form. */
.report {
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  box-shadow: 8px 8px 0 rgb(23 20 28 / 0.9);
}

.report__head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1.5px dashed var(--ink);
}

.report__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
}

.report__meta {
  align-self: center;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.report__quarters {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid var(--rule-mid);
}

.report__quarters li {
  padding: 0.5rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  text-align: center;
}

.report__quarters li + li {
  border-left: 1px solid var(--rule);
}

.report__quarters .is-now {
  background: var(--ink);
  color: var(--porcelain);
}

.report__row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "area state"
    "items items";
  gap: 0.25rem 1rem;
  padding: 0.8rem 1.1rem;
}

.report__row + .report__row {
  border-top: 1px solid var(--rule);
}

.report__area {
  grid-area: area;
  font-weight: 700;
}

.report__items {
  grid-area: items;
  color: var(--text-2);
  font-size: var(--step--1);
}

.report__state {
  grid-area: state;
}

@media (min-width: 64em) {
  .health {
    grid-template-columns: 5fr 6fr;
  }

  .report {
    transform: rotate(0.6deg);
  }
}

/* ═══════════════════════════ ENGINEERING ═══════════════════════════ */

.buildables {
  position: relative;
  display: grid;
  gap: 1.25rem;
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding: clamp(1.25rem, 3vw, 2rem);
  padding-bottom: 7rem;
  border: 1.5px dashed var(--ink);
  border-radius: var(--radius);
}

.buildables__title {
  font-size: var(--step-3);
}

.buildables__head p {
  max-width: 38rem;
  margin-top: 0.5rem;
  color: var(--text-2);
}

.buildables__skull {
  position: absolute;
  right: 1rem;
  bottom: 0.5rem;
  width: 6.5rem;
}

@media (min-width: 48em) {
  .buildables {
    grid-template-columns: 18rem 1fr;
    padding-bottom: clamp(1.25rem, 3vw, 2rem);
    padding-right: 9rem;
  }
}

/* ═══════════════════════════ CONSULTING ═══════════════════════════ */

.minor-services {
  display: grid;
  gap: 1px;
  margin-top: clamp(2rem, 4vw, 3rem);
  border-block: 1.5px solid var(--ink);
  background: var(--rule-mid);
}

.minor-services li {
  padding: 1.25rem 0;
  background: var(--paper);
}

.section--porcelain .minor-services li {
  background: var(--porcelain);
}

.section--grid .minor-services li {
  background: var(--paper);
}

.minor-services h3 {
  font-size: var(--step-2);
}

.minor-services p {
  margin-top: 0.35rem;
  color: var(--text-2);
}

@media (min-width: 48em) {
  .minor-services,
  .minor-services--four,
  .minor-services--two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .minor-services li {
    padding: 1.25rem 1.5rem 1.25rem 0;
  }

  .minor-services li:nth-child(even) {
    padding-left: 1.5rem;
  }
}

@media (min-width: 64em) {
  .minor-services--four {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .minor-services--four li,
  .minor-services--four li:nth-child(even) {
    padding: 1.25rem 1.25rem 1.25rem 0;
  }

  .minor-services--four li + li {
    padding-left: 1.25rem;
  }
}

/* ═══════════════════════════ SECURITY & SKULLSPLOIT ═══════════════════════════ */

.sploit {
  --mark-face: var(--on-night);
  --mark-ink: var(--night-deep);
  padding-block: calc(var(--section-space) + 1rem) var(--section-space);
  background:
    radial-gradient(60% 70% at 85% 30%, rgb(189 148 195 / 0.14) 0%, transparent 70%),
    var(--night);
}

.sploit__inner {
  display: grid;
  gap: 3rem;
  align-items: center;
}

.sploit .label {
  color: var(--on-night-2);
}

.sploit .label__index {
  border-color: var(--rule-night);
  color: var(--sploit-ink);
}

.sploit__prompt {
  margin-bottom: 1rem;
  color: var(--on-night-2);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  overflow-wrap: anywhere;
}

.sploit__prompt span {
  color: var(--sploit);
}

.sploit__prompt::after {
  content: "▋";
  margin-left: 0.2rem;
  color: var(--sploit);
}

@media (prefers-reduced-motion: no-preference) {
  .sploit__prompt::after {
    animation: caret 1.1s steps(1) infinite;
  }
}

@keyframes caret {
  50% {
    opacity: 0;
  }
}

.sploit__title {
  color: var(--on-night);
  font-size: var(--step-5);
  line-height: 0.95;
}

.sploit__title em {
  color: var(--sploit-ink);
}

.sploit__lede {
  max-width: 36rem;
  margin-top: 1.25rem;
  color: var(--on-night-2);
  font-size: var(--step-1);
}

.sploit__services {
  display: grid;
  gap: 1px;
  margin-top: 2rem;
  border: 1px solid var(--rule-night);
  background: var(--rule-night);
}

.sploit__services li {
  padding: 1rem 1.1rem;
  background: var(--night);
}

.sploit__services h3 {
  color: var(--on-night);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

.sploit__services p {
  margin-top: 0.3rem;
  color: var(--on-night-2);
  font-size: var(--step--1);
}

.sploit__future {
  margin-top: 1.25rem;
  color: var(--on-night-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.sploit__future-label {
  color: var(--sploit-ink);
}

.sploit__split {
  max-width: 38rem;
  margin-top: 1rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--sploit);
  color: var(--on-night-2);
  font-size: var(--step--1);
}

.sploit__art {
  position: relative;
  display: grid;
  justify-items: center;
}

.sploit__skull {
  width: min(100%, 18rem);
}

.sploit__skull--small {
  width: 8rem;
  margin-top: -1rem;
  justify-self: end;
}

.sploit .skull__caption {
  color: var(--on-night-2);
}

.sploit a:not(.btn) {
  color: var(--sploit-ink);
}

@media (min-width: 48em) {
  .sploit__services {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .sploit__inner {
    grid-template-columns: 7fr 5fr;
  }

  .sploit__skull--small {
    position: absolute;
    right: 0;
    bottom: -3rem;
  }
}

/* ---------- Security page: layers ---------- */

.layers {
  display: grid;
  gap: 0.6rem;
}

.layer {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 0.15rem 1rem;
  padding: 1rem 1.25rem;
  border: 1.5px solid var(--ink);
  background: var(--porcelain);
}

.layer:nth-child(2) { margin-left: clamp(0rem, 2vw, 1.5rem); }
.layer:nth-child(3) { margin-left: clamp(0rem, 4vw, 3rem); }
.layer:nth-child(4) { margin-left: clamp(0rem, 6vw, 4.5rem); }
.layer:nth-child(5) { margin-left: clamp(0rem, 8vw, 6rem); }

.layer--sploit {
  --mark-face: var(--on-night);
  background: var(--night);
  color: var(--on-night);
}

.layer__index {
  grid-row: 1 / 4;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
}

.layer--sploit .layer__index {
  color: var(--sploit-ink);
}

.layer__title {
  font-size: var(--step-2);
}

.layer--sploit .layer__title {
  color: var(--on-night);
}

.layer__body {
  color: var(--text-2);
}

.layer--sploit .layer__body {
  color: var(--on-night-2);
}

.layer__who {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.layer--sploit .layer__who {
  color: var(--sploit-ink);
}

/* ═══════════════════════════ PROCESS ═══════════════════════════ */

.steps {
  display: grid;
  gap: 1.5rem 1.25rem;
  margin-top: clamp(1rem, 3vw, 2rem);
}

.step {
  padding-top: 0.9rem;
  border-top: 2px solid var(--ink);
}

.step__index {
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.step__title {
  margin-block: 0.3rem 0.4rem;
  font-size: var(--step-2);
}

.step__body {
  color: var(--text-2);
  font-size: var(--step--1);
}

@media (min-width: 40em) {
  .steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .steps--five {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.scale {
  margin-top: clamp(2.5rem, 6vw, 4rem);
}

/* position: relative gives the visually-hidden labels in the cells a containing
   block inside the scroller. Without it they are positioned against the page,
   escape the overflow clip, and widen the whole layout viewport on phones. */
.table-wrap {
  position: relative;
  overflow-x: auto;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.table-wrap:focus-visible {
  outline-offset: 4px;
}

.scale__table {
  width: 100%;
  min-width: 46rem;
  font-size: var(--step--1);
}

.scale__table caption {
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--rule-mid);
  font-weight: 700;
  text-align: left;
}

.scale__table caption span {
  color: var(--text-3);
  font-weight: 400;
}

.scale__table th,
.scale__table td {
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--rule);
  text-align: center;
}

.scale__table thead th {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  white-space: nowrap;
}

.scale__table thead th span {
  color: var(--sol-ink);
}

.scale__table th[scope="row"] {
  font-weight: 700;
  text-align: left;
  white-space: nowrap;
}

/* The job names stay put while the stages scroll past them, so a row can be
   read to its end on a phone. */
.scale__table th[scope="row"],
.scale__table thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--porcelain);
  box-shadow: 1px 0 0 var(--rule);
}

.scale__table tbody tr:last-child > * {
  border-bottom: 0;
}

.dot {
  display: inline-block;
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 50%;
  vertical-align: middle;
}

.dot--yes {
  background: var(--ink);
}

.dot--some {
  border: 1.5px solid var(--ink);
  background: linear-gradient(90deg, var(--ink) 50%, transparent 50%);
}

.dot--no {
  width: 0.6rem;
  height: 1.5px;
  border-radius: 0;
  background: var(--rule-mid);
}

.scale__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.scale__legend .dot {
  margin-left: 0.5rem;
}

/* ═══════════════════════════ STACK ═══════════════════════════ */

.stack {
  display: grid;
  gap: 1px;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  border: 1.5px solid var(--ink);
  background: var(--rule-mid);
}

.stack__group {
  padding: 1.1rem 1.25rem 1.3rem;
  background: var(--porcelain);
}

.stack__label {
  margin-bottom: 0.75rem;
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 700;
}

.stack__label span {
  margin-right: 0.35rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
}

.stack .tag {
  background: var(--paper);
}

@media (min-width: 48em) {
  .stack {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .stack__group:last-child {
    grid-column: 1 / -1;
  }
}

@media (min-width: 64em) {
  .stack {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }

  .stack__group:last-child {
    grid-column: auto;
  }
}

/* ═══════════════════════════ PROJECTS ═══════════════════════════ */

.projects {
  margin-top: clamp(1.75rem, 4vw, 3rem);
}

.project-card {
  display: grid;
  border: 1.5px solid var(--ink);
  background: var(--porcelain);
  box-shadow: 7px 7px 0 var(--sol);
}

.project-card__main,
.project-card__scope {
  padding: clamp(1.35rem, 3vw, 2.25rem);
}

.project-card__status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  width: fit-content;
  margin-bottom: 1.5rem;
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--warn);
  background: color-mix(in srgb, var(--warn) 9%, var(--porcelain));
  color: #70480f;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.project-card__status span {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--warn);
}

.project-card__type {
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.project-card__title {
  margin-top: 0.2rem;
  font-size: var(--step-4);
}

.project-card__summary {
  max-width: 42rem;
  margin-top: 0.75rem;
  color: var(--text-2);
  font-size: var(--step-1);
}

.project-card__stack {
  margin-top: 1.25rem;
}

.project-card__scope {
  border-top: 1px solid var(--rule-mid);
  background: var(--paper);
}

.project-card__scope h4 {
  margin-bottom: 1rem;
  font-family: var(--font-body);
  font-size: var(--step-0);
}

.project-card__note {
  margin-top: 1.25rem;
  padding: 0.9rem 1rem;
  background: var(--sol-tint);
  color: var(--text-2);
  font-size: var(--step--1);
}

.project-card__art {
  display: grid;
  place-items: center;
  min-height: 12rem;
  padding: 1.5rem;
  border-top: 1px solid var(--rule-mid);
  background-color: var(--porcelain);
  background-image: var(--grid-dot);
  background-size: var(--grid-size);
}

@media (min-width: 58em) {
  .project-card {
    grid-template-columns: minmax(0, 1.2fr) minmax(18rem, 0.9fr) 13rem;
  }

  .project-card__scope,
  .project-card__art {
    border-top: 0;
    border-left: 1px solid var(--rule-mid);
  }
}

/* ═══════════════════════════ ABOUT ═══════════════════════════ */

.principles {
  display: grid;
  gap: 1.25rem 2rem;
}

.principles li {
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule-mid);
}

.principles h3 {
  font-size: var(--step-2);
}

.principles p {
  margin-top: 0.35rem;
  color: var(--text-2);
}

.principles__index {
  display: block;
  margin-bottom: 0.3rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

@media (min-width: 64em) {
  .principles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .principles--numbered {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.people {
  display: grid;
  gap: 1.25rem;
}

.person {
  padding: 1.25rem;
  border: 1.5px solid var(--ink);
  background: var(--porcelain);
}

.person__name {
  font-size: var(--step-3);
}

.person__role {
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.person__background {
  margin-top: 0.6rem;
  color: var(--text-2);
}

@media (min-width: 48em) {
  .people {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.family-cards {
  display: grid;
  gap: 1.25rem;
}

.family-card {
  display: grid;
  align-content: start;
  gap: 0.5rem;
  padding: 1.5rem;
  border: 1.5px solid var(--ink);
  border-top-width: 6px;
  border-top-color: var(--sol);
  background: var(--porcelain);
}

.family-card .skull {
  width: 6rem;
  margin-bottom: 0.5rem;
}

.family-card h3 {
  font-size: var(--step-3);
}

.family-card h3 a {
  text-decoration: none;
}

.family-card h3 a:hover {
  text-decoration: underline;
}

.family-card p {
  color: var(--text-2);
}

.family-card__role {
  color: var(--sol-ink) !important;
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.family-card--sploit {
  --mark-face: var(--on-night);
  border-top-color: var(--sploit);
  background: var(--night);
}

.family-card--sploit h3,
.family-card--sploit h3 a {
  color: var(--on-night);
}

.family-card--sploit p {
  color: var(--on-night-2);
}

.family-card--sploit .family-card__role {
  color: var(--sploit-ink) !important;
}

.family-card--edu {
  border-top-color: var(--edu);
  background: var(--edu-wash);
}

.family-card--edu .family-card__role {
  color: var(--edu-ink) !important;
}

.family-card__action {
  margin-top: 0.75rem;
}

@media (min-width: 48em) {
  .family-cards--two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Side by side the two are read as a pair, so their buttons sit on one
     baseline. The copy takes whatever height the taller card decides; the
     action stays on the bottom edge rather than following the last line of a
     paragraph that happens to run a line shorter. */
  .family-cards--two .family-card {
    align-content: stretch;
    grid-template-rows: auto auto auto 1fr auto;
  }
}

@media (min-width: 64em) {
  .family-cards:not(.family-cards--two) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.prose {
  max-width: 40rem;
  display: grid;
  gap: 1rem;
  color: var(--text-2);
  font-size: var(--step-1);
  line-height: 1.65;
}

.prose a {
  color: var(--sol-ink);
}

.prose-split {
  display: grid;
  gap: 1rem 4rem;
}

@media (min-width: 64em) {
  .prose-split {
    grid-template-columns: 5fr 7fr;
  }
}

.subheading {
  margin-block: 1.5rem 0.75rem;
  font-size: var(--step-2);
}

/* ---------- Topics (cyber-safety, vibe code scope) ---------- */

.topics {
  display: grid;
  gap: 1px;
  border: 1.5px solid var(--ink);
  background: var(--rule-mid);
}

.topic {
  display: grid;
  align-content: start;
  gap: 0.3rem;
  padding: 1.1rem 1.25rem;
  background: var(--porcelain);
}

.topic__index {
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.topic__title {
  font-size: var(--step-2);
}

.topic__body {
  color: var(--text-2);
  font-size: var(--step--1);
}

@media (min-width: 40em) {
  .topics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .topics {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ═══════════════════════════ CONTACT ═══════════════════════════ */

.contact {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
}

.contact__intro {
  position: relative;
}

.contact__address {
  margin-top: 2rem;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.1;
}

.contact__address a {
  text-decoration-color: var(--sol);
  text-decoration-thickness: 2px;
}

.contact__skull {
  width: 9.5rem;
  margin-top: 1.5rem;
}

.enquiries {
  display: grid;
  gap: 1rem;
  align-content: start;
}

.enquiry {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 1rem;
  padding: 1.25rem 1.4rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  transition:
    transform 0.25s var(--ease),
    box-shadow 0.25s var(--ease);
}

.enquiry:hover,
.enquiry:focus-within {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--ink);
}

.enquiry__index {
  grid-row: 1 / 4;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.enquiry__title {
  font-size: var(--step-3);
}

.enquiry__body {
  color: var(--text-2);
}

.enquiry__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  justify-self: start;
  margin-top: 0.5rem;
  font-weight: 700;
  text-decoration-color: var(--sol);
  text-decoration-thickness: 2px;
}

.enquiry__link::after {
  content: "→";
}

/* The whole card opens the mail link. */
.enquiry__link::before {
  content: "";
  position: absolute;
  inset: 0;
}

@media (min-width: 64em) {
  .contact {
    grid-template-columns: 6fr 5fr;
  }

  .contact__skull {
    position: absolute;
    right: 0;
    bottom: 0;
    margin: 0;
  }

  .contact__address {
    padding-right: 9rem;
  }
}

.contact-address {
  margin-top: 1.25rem;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.contact-address a {
  text-decoration-color: var(--sol);
  text-decoration-thickness: 2px;
}

/* ---------- The assistant hand-off line ---------- */

.ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-top: 2rem;
  color: var(--text-2);
}

.ask[hidden] {
  display: none;
}

.ask__button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.5rem;
  padding: 0.4rem 0.9rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.ask__button:hover {
  box-shadow: 3px 3px 0 var(--ink);
}

/* The panel version: the end of a page, where the assistant is offered with
   starter questions rather than a single button. */
.ask--panel {
  position: relative;
  display: block;
  margin-top: 0;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  box-shadow: 6px 6px 0 var(--ink);
}

.ask__title {
  font-size: var(--step-3);
}

.ask__title em {
  color: var(--sol-ink);
}

.ask--panel .ask__lead {
  display: block;
  max-width: 24rem;
  margin-top: 0.5rem;
}

.ask__questions {
  display: grid;
  gap: 0.6rem;
  justify-items: start;
  margin-top: 1.25rem;
}

.ask__questions .ask__button {
  text-align: start;
  font-weight: 600;
}

/* On a phone the text needs the whole card, so the Skull sits on its top
   edge instead of beside the questions, looking over the card's corner. */
.ask__skull {
  position: absolute;
  right: 1rem;
  bottom: 100%;
  width: 4.5rem;
  margin-bottom: -1rem;
}

@media (max-width: 47.99em) {
  .contact-section .ask--panel {
    margin-top: 1.5rem;
  }

  /* The real Skull is on the card now; the faint doodle one would be a twin. */
  .doodles--contact .doodle--3 {
    display: none;
  }
}

@media (min-width: 48em) {
  .ask--panel {
    padding-right: 9rem;
  }

  .ask__skull {
    bottom: 1rem;
    width: 7rem;
    margin-bottom: 0;
  }
}

/* ═══════════════════════════ PAGE HEAD ═══════════════════════════ */

.page-head {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  background:
    radial-gradient(60% 80% at 85% 50%, var(--porcelain) 0%, rgb(251 249 247 / 0) 70%),
    var(--paper);
  border-bottom: 1px solid var(--rule);
}

.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grid-dot);
  background-size: var(--grid-size);
  -webkit-mask-image: radial-gradient(50% 80% at 85% 50%, #000 0%, transparent 75%);
  mask-image: radial-gradient(50% 80% at 85% 50%, #000 0%, transparent 75%);
  pointer-events: none;
}

.page-head__inner {
  position: relative;
  display: grid;
  gap: 2rem;
  align-items: center;
}

.page-head__title {
  font-size: var(--step-5);
  line-height: 0.98;
}

.page-head__title em {
  color: var(--sol-ink);
}

.page-head__lead {
  max-width: 40rem;
  margin-top: 1.25rem;
  color: var(--text-2);
  font-size: var(--step-1);
}

.page-head__meta {
  margin-top: 1rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.page-head__price {
  margin-top: 1.25rem;
}

.page-head__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 1.75rem;
}

.page-head__art .skull {
  width: min(60vw, 16rem);
  margin-inline: auto;
}

.page-head--center {
  text-align: center;
}

.page-head--center .label,
.page-head--center .page-head__actions {
  justify-content: center;
}

.page-head--center .page-head__lead {
  margin-inline: auto;
}

.not-found__skull {
  width: 14rem;
  margin: 0 auto 1rem;
}

@media (min-width: 64em) {
  .page-head__inner {
    grid-template-columns: minmax(0, 1fr) 18rem;
  }

  .page-head__title {
    font-size: var(--step-5);
  }
}

.trail ol {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.trail li + li::before {
  content: "/";
  margin-inline: 0.5rem;
  color: var(--rule-mid);
}

.trail a {
  display: inline-block;
  padding-block: 0.3rem;
  color: var(--text-2);
  text-decoration: none;
}

.trail a:hover {
  text-decoration: underline;
}

.page-toc ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.25rem;
  margin-top: 2.5rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

/* ═══════════════════════════ FOOTER ═══════════════════════════ */

.site-footer {
  --mark-face: var(--on-night);
  --mark-ink: var(--night-deep);
  position: relative;
  margin-top: 30px;
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--night);
  color: var(--on-night-2);
}

/* The tooth edge sits in a reserved strip above the dark footer. Paint that
   strip blue so the preceding contact surface continues behind the cut-outs. */
.site-footer::before {
  content: "";
  position: absolute;
  right: 0;
  bottom: 100%;
  left: 0;
  height: 30px;
  background: var(--sol-wash);
  pointer-events: none;
}

/* A slight overlap prevents a sub-pixel seam between the masked edge and the
   footer without changing the original tooth silhouette. */
.teeth--footer {
  bottom: calc(100% - 1px);
}

.site-footer a {
  color: var(--on-night);
  text-decoration-color: rgb(239 233 239 / 0.35);
}

.site-footer a:hover {
  text-decoration-color: var(--sol);
}

.site-footer__inner {
  position: relative;
  display: grid;
  align-items: center;
  gap: 1.5rem;
  padding-bottom: 2rem;
}

.brand--footer {
  color: var(--on-night);
}

.site-footer__email {
  margin-top: 0.65rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem 1.5rem;
  font-size: var(--step--1);
}

.site-footer__links a,
.site-footer__legal a {
  display: inline-block;
  padding-block: 0.3rem;
  text-decoration: none;
}

.site-footer__links a:hover {
  text-decoration: underline;
}

.site-footer__skull {
  width: 7rem;
  justify-self: end;
  opacity: 0.95;
}

.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  /* Room for the fixed chat launcher (3rem tall, a gutter off the bottom), so
     scrolling to the end leaves the legal links clear of it. */
  padding-block: 0 calc(max(var(--gutter), env(safe-area-inset-bottom)) + 4rem);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
}

@media (min-width: 64em) {
  .site-footer__inner {
    grid-template-columns: minmax(15rem, 1fr) auto 7rem;
  }

  .site-footer__skull {
    grid-column: 3;
  }
}

/* The footer skull sleeps on the dark ground, so its caption-free image gets a
   faint lift to stay readable against the night. */
.site-footer__skull .skull__svg {
  filter: drop-shadow(0 0 18px rgb(143 155 208 / 0.18));
}

/* ═══════════════════════════ CATALOGUE PAGES ═══════════════════════════ */

.capability__count {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.service-grid,
.category-audience,
.related-categories,
.service-directory {
  display: grid;
  gap: 1.25rem;
}

/* Cards in a row are one height, and their closing links sit on one baseline.
   Left to themselves they ended wherever their copy did, which made two cards
   describing equally real services look like one mattered less than the other. */
.service-card {
  display: grid;
  align-content: start;
  min-width: 0;
  padding: clamp(1rem, 2.5vw, 1.75rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
}

.service-card__links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  margin-top: auto;
  padding-top: 0.75rem;
}

.service-card:target {
  outline: 3px solid var(--sol-ink);
  outline-offset: 4px;
}

.service-card__head {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: 0.75rem;
  align-items: center;
}

.service-card h3,
.category-audience h3,
.service-directory h3 {
  font-size: var(--step-2);
}

.service-card__summary,
.category-audience p,
.related-categories p {
  margin-top: 0.75rem;
  color: var(--text-2);
}

.service-card__price {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
}

.service-card__price > span:not(.price) {
  color: var(--text-3);
  font-size: var(--step--2);
}

/* Spacing between the closing links is the block's own gap. */
.service-card__links .more {
  margin-top: 0;
}

.service-card .disclosure__summary,
.service-finder > summary,
.problem-finder > summary,
.related-categories a,
.related-service-links a,
.service-directory a {
  min-height: 44px;
}

.category-audience li,
.related-categories li {
  min-width: 0;
  border-top: 1.5px solid var(--ink);
  padding-top: 1rem;
}

.related-categories a {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.15;
  letter-spacing: normal;
  text-transform: none;
}

.service-finder {
  margin-top: 2rem;
}

.service-directory ul {
  margin-top: 0.75rem;
}

.service-directory a {
  padding-block: 0.5rem;
  font-family: var(--font-body);
  font-size: var(--step--1);
  letter-spacing: normal;
  text-transform: none;
}

.related-service-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin-top: 1.5rem;
}

.related-service-links a {
  display: inline-flex;
  align-items: center;
}

.service-category .page-head__text,
.services-hub .page-head__text,
.capability__text {
  min-width: 0;
  overflow-wrap: break-word;
}

.service-category .trail li,
.services-hub .trail li {
  max-width: 100%;
}

.service-category .trail a,
.services-hub .trail a {
  display: inline-block;
  padding-block: 0.5rem;
}

.service-category .trail li[aria-current],
.services-hub .trail li[aria-current] {
  padding-block: 0.5rem;
}

@media (min-width: 48em) {
  .service-directory {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Side by side, each card hands its five rows back to the grid the cards
     share, so the summaries, the price chips, the scope line and the closing
     links each sit at one height across the pair — however many lines either
     card's copy runs to. The row gap goes to nothing (it would open inside the
     cards as well as between them) and the separation between rows of cards
     becomes the cards' own bottom margin. */
  .service-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 0;
  }

  .service-card {
    grid-row: span 5;
    grid-template-rows: subgrid;
    margin-bottom: 1.25rem;
  }

  .category-audience,
  .related-categories {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2rem;
  }

  .service-category .page-head__inner,
  .services-hub .page-head__inner {
    grid-template-columns: minmax(0, 1fr) 12rem;
  }
}

@media (min-width: 64em) {
  .capabilities--directory .capability--wide {
    grid-template-columns: 11rem minmax(0, 1fr);
  }

  .service-category .page-head__inner,
  .services-hub .page-head__inner {
    grid-template-columns: minmax(0, 1fr) 18rem;
  }

  .service-directory {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 47.99em) {
  .service-category .page-head__art .skull,
  .services-hub .page-head__art .skull {
    width: 8rem;
    margin-left: auto;
    margin-right: 0;
  }
}

/* ═══════════════════════════ MOBILE HORIZONTAL LISTS ═══════════════════════════
   Selected previews and supplementary choices scroll sideways on phones. Core
   catalogues stay vertical so services and contact options are never hidden. */

.scroll-hint {
  display: none;
}

@media (max-width: 47.99em) {
  .scroll-hint {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.45rem;
    margin: -1rem 0 0.75rem;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--step--2);
  }

  /* Let the question carousel scroll inside its card instead of making the
     contact grid (and the entire home page) as wide as all its questions. */
  .page-home .contact {
    grid-template-columns: minmax(0, 1fr);
  }

  .scroll-hint span {
    color: var(--sol-ink);
    font-size: var(--step--1);
  }

  .mobile-snap {
    --snap-size: clamp(17rem, 84vw, 22rem);
    position: relative;
    /* The off-screen cards must not contribute to the document's width.
       Keep positioned descendants and swipe momentum inside this scroller. */
    contain: inline-size;
    min-width: 0;
    display: grid;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: var(--snap-size);
    align-items: stretch;
    gap: 1rem;
    max-width: 100%;
    padding-bottom: 0.75rem;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-inline: contain;
    overscroll-behavior-block: auto;
    scroll-snap-type: inline mandatory;
    touch-action: pan-x pan-y;
    scrollbar-color: var(--sol) transparent;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
  }

  .mobile-snap > * {
    scroll-snap-align: start;
  }

  .mobile-snap::-webkit-scrollbar {
    height: 0.35rem;
  }

  .mobile-snap::-webkit-scrollbar-thumb {
    border-radius: var(--radius-pill);
    background: var(--sol);
  }

  /* Keep the home preview short as well as sideways: art and copy share a row. */
  .page-home .capabilities.mobile-snap .capability {
    grid-template-rows: none;
    grid-template-columns: 5.5rem minmax(0, 1fr);
  }

  .page-home .capabilities.mobile-snap .capability__art {
    min-height: 0;
    padding: 0.5rem;
    border-right: 1px solid var(--rule-mid);
    border-bottom: 0;
  }

  .page-home .capabilities.mobile-snap .capability__art .skull {
    width: 4.5rem;
  }

  .page-home .capabilities.mobile-snap .capability__text {
    gap: 0.4rem;
    padding: 1rem;
  }

  .page-home .capabilities.mobile-snap .capability__title {
    font-size: var(--step-2);
  }

  .family-cards.mobile-snap {
    --snap-size: clamp(17rem, 86vw, 23rem);
  }

  .related-categories.mobile-snap {
    --snap-size: clamp(15rem, 76vw, 19rem);
  }

  .related-categories.mobile-snap > li {
    padding: 1rem;
    border: 1.5px solid var(--ink);
    background: var(--porcelain);
  }

}

@media (min-width: 48em) and (max-width: 63.99em) {
  .page-home .capabilities {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* A third of a tablet is too narrow for "Infrastructure" at step-3, and
     break-word would split it mid-word. One step down, hyphenated if still
     needed, keeps whole words. */
  .page-home .capability__title {
    font-size: var(--step-2);
    hyphens: auto;
  }
}

/* ═══════════════════════════ PRICING ═══════════════════════════

   /pricing is the one page where the numbers are the content, so the
   typographic job is to keep two kinds of number apart at a glance: what you
   pay once, and what you pay every month. Nothing distinguishes them by colour
   alone — a recurring amount carries its own label, a dashed frame and the
   interval in the figure itself.

   Mobile first throughout. The estimate builder stacks into one column with a
   sticky total that rides along inside the section, and only becomes two
   columns with a pinned summary at the laptop breakpoint. */

/* ---------- A price, with how often you pay it ---------- */

.pricebox {
  display: grid;
  gap: 0.15rem;
  padding: 0.6rem 0.8rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.pricebox__label {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.pricebox__value {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

/* Recurring money is framed rather than filled, so a monthly figure never
   reads as the price of the project. */
.pricebox--recurring {
  border-style: dashed;
  background: var(--sol-tint);
}

.pricebox--recurring .pricebox__value {
  font-size: var(--step-1);
}

/* The same distinction on the service cards under /services. */
.price-recurring {
  padding: 0.25rem 0.5rem;
  border: 1px dashed var(--rule-mid);
  border-radius: var(--radius);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

/* ---------- Published builds ---------- */

/* Each card is a price and a door: the name, the thing in one line, the two
   numbers. Everything else is on the offering's own page, which is what keeps
   a card the height of its own content instead of the height of the longest
   piece of copy in the row. The grid packs whatever fits rather than holding a
   fixed column count, so eight of them never leave a hole in the last row. */
.offers {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15.5rem), 1fr));
}

.offer {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 1.1rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.offer:hover {
  transform: translateY(-2px);
  box-shadow: 4px 4px 0 var(--ink);
}

.offer:target {
  outline: 3px solid var(--sol-ink);
  outline-offset: 4px;
}

.offer__head {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 0.6rem;
  align-items: center;
}

.offer__name {
  font-size: var(--step-1);
  line-height: 1.15;
}

/* The whole card is the link's hit area; the heading keeps the accessible name. */
.offer__link {
  text-decoration: none;
}

.offer__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.offer__link:focus-visible {
  outline: none;
}

.offer__link:focus-visible::after {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

.offer__tagline {
  margin-top: 0.6rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

/* Two figures on two lines, because a one-time price and a monthly one sharing
   a row is exactly the confusion this page exists to avoid. */
.offer__prices {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1.5px solid var(--rule-mid);
}

/* Label above figure, always, even where the two would fit on one line. A row
   that sets itself on one line in one card and wraps to two in the next gives
   every card a different height, which puts the rule above the prices at a
   different place in each — and a row of cards whose rules do not line up
   reads as a mistake before it reads as a price. */
.offer__price {
  padding-top: 0.55rem;
}

/* The browser indents a <dd> by default, which would set every figure in from
   the label above it. */
.offer__price dd {
  margin-inline-start: 0;
}

.offer__price dt {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.offer__price-value {
  margin-top: 0.1rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* Recurring money is set smaller and in mono, so the figure a project costs
   and the figure it costs every month can never be read as the same kind. */
.offer__price--recurring dd {
  margin-top: 0.15rem;
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  white-space: nowrap;
}

.offer__more {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding-top: 1rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.offer__more::after {
  content: "→";
  transition: transform 0.25s var(--ease);
}

.offer:hover .offer__more::after {
  transform: translateX(4px);
}

.offer__note,
.deploy__note,
.third-party__note {
  margin-top: 0.9rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--rule-mid);
  color: var(--text-3);
  font-size: var(--step--1);
}

/* ---------- What moves a range ---------- */

.ladder__ends {
  display: grid;
  gap: 0.5rem;
  padding: 0.9rem;
  border: 1px dashed var(--rule-mid);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.ladder__price {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
}

.ladder__end--high .ladder__price {
  color: var(--sol-ink);
}

.ladder__body {
  color: var(--text-2);
  font-size: var(--step--1);
}

.ladder__arrow {
  color: var(--sol-ink);
  font-size: var(--step-1);
  line-height: 1;
}

.ladder__lead {
  margin-top: 0.9rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ladder__moves {
  margin-top: 0.5rem;
  font-size: var(--step--1);
}

/* ---------- One offering, written up in full ---------- */

/* The two figures, side by side at the top of the page they belong to. */
.offer-detail__prices {
  display: grid;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

/* The ladder is prose next to two numbers, so it is set to a reading measure
   rather than stretched across a desktop container. */
.offer-detail .ladder,
.offer-detail .caveat,
.offer-detail .offer__note {
  max-width: 44rem;
}

.offer-scope__cols {
  display: grid;
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.offer-scope__heading {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 0.75rem;
}

.offer-scope__col--not .crosses {
  color: var(--text-2);
}

.offer-scope__aside {
  padding: 1.1rem;
  border: 1.5px dashed var(--rule-mid);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.offer-scope__skull {
  margin-bottom: 0.75rem;
}

.offer-scope__audience .tag {
  font-size: var(--step--2);
}

.offer-scope__note {
  margin-top: 1.5rem;
}

/* Where to go instead. A row of names and their prices, so leaving this page
   for a more honest one is a single click rather than a trip back through the
   catalogue. */
.offer-siblings {
  display: grid;
  gap: 0;
  margin: 1rem 0 1.5rem;
  border-top: 1.5px solid var(--rule-mid);
}

.offer-siblings__item {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.7rem 0;
  border-bottom: 1.5px solid var(--rule-mid);
}

.offer-siblings__link {
  min-height: 44px;
  display: flex;
  align-items: center;
}

.offer-siblings__price {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.offer-next__heading {
  margin-top: 2rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

@media (min-width: 48em) {
  .offer-detail__prices {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 42rem;
  }

  .offer-scope__cols {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.8fr);
    gap: 2rem;
  }

  .offer-siblings {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 2rem;
  }
}

/* ---------- The estimate builder ---------- */

.builder {
  position: relative;
  margin-top: 2rem;
}

.builder__step {
  min-width: 0;
  margin: 0 0 1.5rem;
  padding: 1rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.builder__legend {
  padding: 0.3rem 0.7rem;
  border: 1.5px solid var(--ink);
  background: var(--ink);
  color: var(--porcelain);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.builder__step-index {
  color: var(--sol);
}

.builder__hint,
.builder__group-body {
  margin-top: 0.6rem;
  color: var(--text-3);
  font-size: var(--step--1);
}

.builder__group {
  margin-top: 1.5rem;
}

.builder__group-name {
  padding-bottom: 0.4rem;
  border-bottom: 1.5px solid var(--ink);
  font-size: var(--step-1);
}

.builder__notice {
  margin-top: 1rem;
  padding: 0.7rem 0.9rem;
  border-left: 3px solid var(--sol-ink);
  background: var(--sol-tint);
  color: var(--text-2);
  font-size: var(--step--1);
}

/* ---------- One choosable thing ---------- */

.options {
  display: grid;
  gap: 0.6rem;
  margin-top: 0.9rem;
}

.option {
  min-width: 0;
}

/* The control stays in the accessibility tree and in the tab order; the label
   is what you see and what you press. */
.option__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.option__label {
  display: grid;
  grid-template-columns: 1.3rem minmax(0, 1fr);
  gap: 0.2rem 0.7rem;
  min-height: 44px;
  padding: 0.7rem 0.8rem;
  border: 1.5px solid var(--rule-mid);
  border-radius: var(--radius);
  background: var(--paper);
  cursor: pointer;
  transition: border-color var(--t-micro, 150ms) var(--ease), background-color var(--t-micro, 150ms) var(--ease);
}

/* The box: square for a feature you can have several of, round for a choice
   between alternatives, the way the native controls read. */
.option__label::before {
  content: "";
  grid-row: 1 / span 3;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.15rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.option--type .option__label::before,
.option--deploy .option__label::before {
  border-radius: var(--radius-pill);
}

.option__name {
  grid-column: 2;
  font-weight: 700;
}

.option__body {
  grid-column: 2;
  color: var(--text-2);
  font-size: var(--step--1);
}

/* The price sits on its own line, pushed to the right edge: the copy keeps the
   full width of the card, and the figures still line up into a column you can
   run your eye down. */
.option__price {
  grid-column: 2;
  justify-self: end;
  margin-top: 0.3rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.02em;
  text-align: right;
}

.option__state {
  grid-column: 2;
  margin-top: 0.35rem;
  padding-left: 2rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

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

.option__input:focus-visible + .option__label {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Selected: a filled box with a tick, a solid border and a tinted ground.
   Three signals, none of them colour on its own. */
.option__input:checked + .option__label {
  border-color: var(--ink);
  background: var(--sol-tint);
}

.option__input:checked + .option__label::before {
  border-color: var(--ink);
  background: var(--ink);
  background-image: linear-gradient(45deg, transparent 42%, var(--porcelain) 42%, var(--porcelain) 58%, transparent 58%),
    linear-gradient(-45deg, transparent 42%, var(--porcelain) 42%, var(--porcelain) 58%, transparent 58%);
  background-position: -0.1rem 0.1rem, 0.1rem 0.1rem;
  background-size: 60% 60%, 60% 60%;
  background-repeat: no-repeat;
}

.option__input:disabled + .option__label {
  cursor: default;
}

/* Already in the base price: ticked, but not charged for again. */
.option--included .option__label {
  border-style: dashed;
}

.option--included .option__price {
  text-decoration: line-through;
}

/* Does not belong in this kind of project: struck out, with the reason under it. */
.option--unavailable .option__label {
  border-color: var(--rule);
  background: transparent;
  opacity: 0.65;
}

.option--unavailable .option__name {
  text-decoration: line-through;
}

.option--unavailable .option__state {
  color: var(--text-3);
}

/* ---------- The summary ---------- */

.builder__panel {
  padding: clamp(1rem, 3vw, 1.4rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
  box-shadow: var(--offset);
}

.builder__panel-head {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 0.6rem;
  border-bottom: 1.5px solid var(--ink);
}

.builder__panel-title {
  font-size: var(--step-2);
}

.builder__skull {
  flex: none;
}

.builder__fallback {
  margin-top: 0.9rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

/* Stated in the markup as well as in the live panel, so the page never shows a
   figure without it — including with the script blocked. */
.builder__disclaimer {
  margin-top: 0.9rem;
  color: var(--text-3);
  font-size: var(--step--2);
}

.estimate__empty {
  margin-top: 0.9rem;
  color: var(--text-3);
  font-size: var(--step--1);
}

.estimate__subhead {
  margin-top: 1rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.estimate__items {
  display: grid;
  gap: 0.35rem;
  margin: 0.5rem 0 1rem;
  padding: 0;
  list-style: none;
}

.estimate__item {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.6rem;
  align-items: baseline;
  font-size: var(--step--1);
}

.estimate__item-name {
  flex: 1 1 auto;
  min-width: 0;
}

.estimate__item-price,
.estimate__item-note {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.estimate__item--type {
  padding-bottom: 0.35rem;
  border-bottom: 1px dashed var(--rule-mid);
  font-weight: 700;
}

.estimate__item--included {
  display: block;
  color: var(--text-3);
  font-size: var(--step--2);
}

.estimate__remove {
  flex: none;
  min-height: 32px;
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--rule-mid);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  cursor: pointer;
}

.estimate__remove:hover {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--porcelain);
}

.estimate__rows {
  display: grid;
  gap: 0.1rem;
  margin-top: 1rem;
  padding: 0;
  list-style: none;
}

.estimate__row {
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.45rem 0;
  border-bottom: 1px dotted var(--rule-mid);
}

.estimate__label {
  color: var(--text-2);
  font-size: var(--step--1);
}

.estimate__value {
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  text-align: right;
}

/* The total gets its own two lines rather than squeezing a three-word label
   against a five-figure number in a column this narrow. */
.estimate__row--total {
  display: grid;
  gap: 0.1rem;
  margin-top: 0.4rem;
  padding-top: 0.7rem;
  border-top: 1.5px solid var(--ink);
  border-bottom: none;
}

.estimate__row--total .estimate__value {
  text-align: left;
}

.estimate__row--total .estimate__label {
  color: var(--ink);
  font-weight: 700;
}

.estimate__row--total .estimate__value {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
}

/* Recurring is framed and labelled, never just a second number in the list. */
.estimate__row--recurring {
  margin-top: 0.5rem;
  padding: 0.5rem 0.6rem;
  border: 1px dashed var(--rule-mid);
  border-radius: var(--radius);
  background: var(--sol-tint);
}

.estimate__row--recurring .estimate__label {
  font-weight: 700;
}

.estimate__row--separate {
  border-bottom: none;
  padding: 0.15rem 0;
}

.estimate__row--separate .estimate__label,
.estimate__row--separate .estimate__value {
  color: var(--text-3);
  font-size: var(--step--2);
}

.estimate__note,
.estimate__warning {
  margin-top: 0.8rem;
  padding-left: 0.8rem;
  border-left: 2px solid var(--sol);
  color: var(--text-2);
  font-size: var(--step--1);
}

.estimate__warning {
  border-left-color: var(--warn);
}

.estimate__disclaimer {
  margin-top: 0.9rem;
  color: var(--text-3);
  font-size: var(--step--2);
}

/* ---------- Sending it ---------- */

.builder__quote {
  margin-top: 1.2rem;
  padding-top: 1rem;
  border-top: 1.5px solid var(--ink);
}

.builder__quote-title {
  font-size: var(--step-1);
}

.builder__privacy,
.builder__note {
  margin-top: 0.4rem;
  color: var(--text-3);
  font-size: var(--step--2);
}

.field {
  margin-top: 0.8rem;
}

.field__label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: var(--step--1);
  font-weight: 700;
}

.field__optional {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.field__input {
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.7rem;
  border: 1.5px solid var(--rule-mid);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
}

.field__input:focus-visible {
  border-color: var(--ink);
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.field__input--area {
  min-height: 5rem;
  resize: vertical;
}

.builder__actions {
  margin-top: 1rem;
}

/* ---------- The running total on a phone ---------- */

/* Sticky inside the builder rather than fixed to the window: the total rides
   along while you are choosing and scrolls away with the section, instead of
   sitting over the rest of the page. It clears the assistant's launcher, which
   is fixed to the same corner. */
.builder__bar {
  position: sticky;
  bottom: calc(3.75rem + max(var(--gutter), env(safe-area-inset-bottom)));
  z-index: 6;
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  margin-top: 1.5rem;
  padding: 0.6rem 0.75rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--porcelain);
  box-shadow: var(--shadow-md);
}

.builder__bar-total {
  min-width: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
}

.builder__bar-label {
  display: block;
  color: var(--on-night-2);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.builder__bar .btn {
  flex: none;
}

@media (min-width: 40em) {
  .option__state {
    padding-left: 0;
  }

  .options--types,
  .options--features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .builder {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 23rem;
    gap: 2rem;
    align-items: start;
  }

  .builder__form {
    min-width: 0;
  }

  .builder__summary {
    position: sticky;
    top: calc(5.5rem + env(safe-area-inset-top));
    min-width: 0;
  }

  .builder__bar {
    display: none;
  }

  .builder__step {
    padding: 1.4rem;
  }
}

/* ---------- Existing projects ---------- */

.existing {
  display: grid;
  gap: 1.5rem;
}

.pipeline {
  display: grid;
  gap: 0;
  padding: 0;
  list-style: none;
  counter-reset: pipeline;
}

.pipeline__step {
  position: relative;
  padding: 0.9rem 0.9rem 0.9rem 3.2rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

/* The arrow between stages: the flow is the argument, so it is drawn rather
   than described. */
.pipeline__step + .pipeline__step {
  margin-top: 1.5rem;
}

.pipeline__step + .pipeline__step::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 1.6rem;
  width: 1.5px;
  height: 1.5rem;
  background: var(--ink);
}

.pipeline__step + .pipeline__step::after {
  content: "";
  position: absolute;
  bottom: calc(100% + 0.1rem);
  left: 1.25rem;
  border-top: 0.45rem solid var(--ink);
  border-right: 0.35rem solid transparent;
  border-left: 0.35rem solid transparent;
}

.pipeline__index {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.pipeline__name {
  font-size: var(--step-1);
}

.pipeline__body {
  margin-top: 0.25rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.existing__note {
  margin-top: 0.9rem;
  color: var(--text-2);
}

@media (min-width: 64em) {
  .existing {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 3rem;
  }

  .existing__aside {
    position: sticky;
    top: calc(6rem + env(safe-area-inset-top));
  }
}

/* ---------- Deployment ---------- */

.deploys,
.third-party {
  display: grid;
  gap: 1.25rem;
}

/* The third-party entries are rows of a list and keep their own heights; the
   two deployments are a comparison, so they are one height. */
.third-party {
  align-items: start;
}

.deploy {
  display: grid;
  align-content: start;
  min-width: 0;
  padding: clamp(1rem, 2.5vw, 1.6rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
}


.deploy__head {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 0.6rem;
  align-items: center;
}

.deploy__name {
  font-size: var(--step-1);
  line-height: 1.15;
}

.deploy__platform {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.deploy__summary {
  margin: 0.9rem 0 0.75rem;
  color: var(--text-2);
}

/* What each one suits is the thing you are choosing between, so it is read
   rather than opened. Only the longer "what the work involves" list stays
   folded: it answers why the fee is what it is, not which one to pick. */
.deploy__suits {
  margin-bottom: 1rem;
}

.deploy__suits .tag {
  font-size: var(--step--2);
}

.deploy__infra {
  margin-top: 1rem;
  font-size: var(--step--1);
  color: var(--text-2);
}

.deploy__infra-label {
  display: block;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Side by side, the two are a comparison, and a comparison whose rows do not
   line up is harder to read than a list. Each card hands its own rows back to
   the section's grid, so the summaries, the tags, the fee, the platform
   charges and the disclosure each sit at one height across both — whatever
   length of copy any of them happens to carry. */
@media (min-width: 48em) {
  .deploys {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(7, auto);
    row-gap: 0;
  }

  .deploy {
    grid-row: span 7;
    grid-template-rows: subgrid;
    align-content: start;
  }

  /* Subgrid does the distributing; nothing needs pushing to the bottom. */
  .deploy .disclosure {
    margin-top: 0;
  }
}

/* ---------- Websites, as three sizes ---------- */

/* Three cards that are read across rather than down, so they hand their rows
   to the grid: label, price, line, inclusions, monthly, link. A tier whose
   list runs a line longer must not drag its price out of line with the others. */
.tiers {
  display: grid;
  gap: 1.25rem;
  margin-top: 2rem;
}

.tier {
  display: grid;
  align-content: start;
  min-width: 0;
  padding: 1.25rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.tier__head {
  padding-bottom: 0.75rem;
  border-bottom: 1.5px solid var(--ink);
}

.tier__label {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.tier__price {
  margin-top: 0.2rem;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.tier__body {
  margin-top: 0.75rem;
  color: var(--text-2);
  font-style: italic;
}

.tier__includes {
  margin-top: 0.9rem;
  font-size: var(--step--1);
}

.tier__monthly {
  margin-top: 0.9rem;
  padding: 0.3rem 0.6rem;
  justify-self: start;
  border: 1px dashed var(--rule-mid);
  border-radius: var(--radius);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.tier__more {
  margin-top: 0.9rem;
}

@media (min-width: 48em) {
  .tiers {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(6, auto);
    row-gap: 0;
  }

  .tier {
    grid-row: span 6;
    grid-template-rows: subgrid;
  }
}

/* ---------- How a price is reached ---------- */

/* The public shape of the model: five steps and the things that move a number.
   Deliberately the same furniture as the existing-software pipeline, because
   it is the same kind of claim — here is the sequence, in order, with nothing
   left out between two of the steps. */
.method {
  display: grid;
  gap: 2rem;
  margin-top: 2rem;
}

.method__steps {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.method__step {
  min-width: 0;
  padding: 0.9rem 0.9rem 0.9rem 3.2rem;
  position: relative;
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.method__index {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  color: var(--sol-ink);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.method__name {
  font-size: var(--step-1);
}

.method__body {
  margin-top: 0.25rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.method__heading,
.retainer__title,
.partner__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

.method__heading {
  margin: 1rem 0 0.75rem;
}

.method__note {
  margin-top: 1rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--sol-ink);
  color: var(--text-2);
  font-size: var(--step--1);
}

@media (min-width: 64em) {
  .method {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 3rem;
  }

  .method__aside {
    position: sticky;
    top: calc(6rem + env(safe-area-inset-top));
  }
}

/* ---------- What a retainer reserves ---------- */

.retainer {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1.5px solid var(--ink);
}

.retainer__lead {
  margin-top: 0.5rem;
  max-width: 48rem;
  color: var(--text-2);
}

.retainer__rules {
  display: grid;
  gap: 1rem;
  margin-top: 1.5rem;
}

.retainer__rule {
  min-width: 0;
  padding-top: 0.75rem;
  border-top: 1px dotted var(--rule-mid);
}

.retainer__rule dt {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 600;
}

.retainer__rule dd {
  margin-inline-start: 0;
  margin-top: 0.25rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

@media (min-width: 48em) {
  .retainer__rules {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 2rem;
  }
}

@media (min-width: 80em) {
  .retainer__rules {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- The rate card ---------- */

/* A table, because it is one: three columns of figures that have to be
   compared down as well as across. It scrolls inside its own box rather than
   pushing the page sideways on a phone. */
/* The table scrolls inside its own box rather than pushing the page sideways
   on a phone, which is why it has a wrapper at all. */
.rate-card {
  overflow-x: auto;
  max-width: 44rem;
  margin-top: 2rem;
}

.rate-card__table {
  width: 100%;
  border-collapse: collapse;
}

.rate-card thead th {
  padding: 0.5rem 1rem 0.5rem 0;
  border-bottom: 1.5px solid var(--ink);
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: right;
}

.rate-card thead th:first-child,
.rate-card tbody th {
  width: 60%;
  text-align: left;
}

.rate-card tbody th {
  padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: 1px dotted var(--rule-mid);
  font-weight: 400;
}

.rate-card td {
  padding: 0.7rem 0 0.7rem 1rem;
  border-bottom: 1px dotted var(--rule-mid);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-align: right;
  white-space: nowrap;
}

.rate-card__note {
  margin-top: 1rem;
  max-width: 48rem;
  color: var(--text-3);
  font-size: var(--step--1);
}

/* ---------- Partner work ---------- */

.partner {
  margin-top: 2rem;
  padding: 1.25rem;
  border: 1.5px dashed var(--rule-mid);
  border-radius: var(--radius);
  background: var(--paper);
}

.partner__body {
  margin-top: 0.5rem;
  max-width: 48rem;
  color: var(--text-2);
}

.partner__note {
  margin-top: 0.75rem;
  color: var(--text-3);
  font-size: var(--step--1);
}

/* ---------- What somebody else charges ---------- */

.third-party__item {
  min-width: 0;
  padding: 1rem;
  border-top: 1.5px solid var(--ink);
}

.third-party__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  align-items: baseline;
  justify-content: space-between;
}

.third-party__name {
  font-size: var(--step-1);
}

.third-party__cost {
  padding: 0.2rem 0.5rem;
  border: 1px dashed var(--rule-mid);
  border-radius: var(--radius);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  white-space: nowrap;
}

.third-party__body {
  margin-top: 0.5rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.ownership {
  display: grid;
  gap: 1.5rem;
  margin-top: 2.5rem;
  padding: clamp(1rem, 3vw, 1.75rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--sol-tint);
}

.ownership__title {
  font-size: var(--step-2);
}

.ownership__body {
  margin-top: 0.6rem;
  color: var(--text-2);
}

.ownership__items {
  display: grid;
  gap: 0.5rem;
  margin-top: 1rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.ownership__art {
  justify-self: center;
}

@media (min-width: 48em) {
  .third-party {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .ownership {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }
}

/* ---------- Maintenance ---------- */

.maintenance {
  display: grid;
  gap: 1.5rem;
  margin-top: 2rem;
}

.maintenance__heading {
  padding-bottom: 0.4rem;
  border-bottom: 1.5px solid var(--ink);
  font-size: var(--step-1);
}

.maintenance__col .checks,
.maintenance__col .crosses {
  margin-top: 0.9rem;
}

.crosses {
  display: grid;
  gap: 0.55rem;
}

.crosses li {
  position: relative;
  padding-left: 1.75rem;
  color: var(--text-2);
}

/* A cross, drawn the same way the tick is, so the two lists read as opposites
   without relying on colour. */
.crosses li::before,
.crosses li::after {
  content: "";
  position: absolute;
  top: 0.62em;
  left: 0.3rem;
  width: 0.85rem;
  height: 2px;
  background: var(--text-3);
}

.crosses li::before {
  transform: rotate(45deg);
}

.crosses li::after {
  transform: rotate(-45deg);
}

.maintenance__boundary,
.maintenance__optional {
  margin-top: 0.9rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.maintenance__skull {
  margin-bottom: 0.5rem;
}

.maintenance-rates {
  display: grid;
  gap: 0;
  margin-top: 2rem;
  border-top: 1.5px solid var(--ink);
}

.maintenance-rates__item {
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.6rem 0.2rem;
  border-bottom: 1px dotted var(--rule-mid);
}

.maintenance-rates__name {
  font-weight: 700;
}

.maintenance-rates__price {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-align: right;
}

@media (min-width: 48em) {
  .maintenance-rates {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 2.5rem;
  }
}

/* Covers and does-not sit side by side; where the line is runs underneath them
   as a full-width band, so the two lists are compared rather than crowded by a
   column of prose twice their height. */
@media (min-width: 48em) {
  .maintenance {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem 2.5rem;
  }

  .maintenance__aside {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-column: 1 / -1;
    gap: 0 1.5rem;
    align-items: start;
    padding-top: 1.5rem;
    border-top: 1.5px solid var(--rule-mid);
  }

  .maintenance__skull {
    grid-row: 1 / span 2;
    margin-bottom: 0;
  }

  .maintenance__boundary {
    margin-top: 0;
  }
}

@media (min-width: 64em) {
  .maintenance__aside {
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 2.5rem;
  }

  .maintenance__skull {
    grid-row: 1;
  }

  .maintenance__optional {
    margin-top: 0;
  }
}

/* ---------- Training ---------- */

.training {
  display: grid;
  gap: 2rem;
  margin-top: 2rem;
}

.training__heading {
  padding-bottom: 0.4rem;
  border-bottom: 1.5px solid var(--ink);
  font-size: var(--step-1);
}

.training__aside .training__heading,
.training__aside .checks {
  margin-top: 1rem;
}

.training__format {
  margin-top: 1.5rem;
}

.spec {
  display: grid;
  gap: 0;
  margin-top: 0.9rem;
}

.spec__row {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px dotted var(--rule-mid);
}

.spec dt {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.spec dd {
  margin: 0;
  color: var(--text-2);
  font-size: var(--step--1);
}

.training__note {
  margin-top: 0.6rem;
  color: var(--text-2);
  font-size: var(--step--1);
}

.training__skull {
  margin-bottom: 1rem;
}

@media (min-width: 64em) {
  .training {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: 3rem;
  }
}

/* ---------- Something else ---------- */

.custom {
  display: grid;
  gap: 1.5rem;
  align-items: center;
}

@media (min-width: 48em) {
  .custom {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}

/* ---------- Questions ---------- */

.faq {
  display: grid;
  gap: 0;
  margin-top: 1.5rem;
  border-top: 1.5px solid var(--ink);
}

.faq > div {
  border-bottom: 1px solid var(--rule);
}

.faq__item {
  margin: 0;
  padding: 0.35rem 0;
}

.faq__item .disclosure__summary {
  width: 100%;
  min-height: 48px;
  justify-content: space-between;
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: normal;
  text-transform: none;
}

.faq__item .disclosure__body {
  max-width: 48rem;
  padding-bottom: 0.75rem;
  color: var(--text-2);
}

/* ═══════════════════════════ SCOPE ═══════════════════════════

   Three small blocks that came out of narrowing what the company
   sells: the home page's price band, the deployment rows on the
   catalogue, and the project-type mail links on /contact. All three
   reuse the existing ink-rule-and-mono vocabulary rather than
   introducing a fourth kind of card. */

/* ---------- The home page's price band ---------- */

.price-teaser {
  display: grid;
  gap: 0;
  margin-top: 2rem;
  border-top: 1.5px solid var(--ink);
}

.price-teaser__item {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.75rem 0.2rem;
  border-bottom: 1px dotted var(--rule-mid);
}

/* Each name goes to the page that explains its range, so the band is a way in
   rather than four numbers you have to go and look up somewhere else. */
.price-teaser__name {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
}

.price-teaser__value {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  white-space: nowrap;
}

.price-teaser__note {
  margin-top: 1.25rem;
  max-width: 44rem;
  color: var(--text-3);
  font-size: var(--step--2);
}

.prices-section .section-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

@media (min-width: 48em) {
  .price-teaser {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 2.5rem;
  }
}

/* ---------- Deployment, as two rows on the catalogue ---------- */

.deploy-rows {
  display: grid;
  gap: 1rem;
  margin-top: 2rem;
}

.deploy-rows__item {
  display: grid;
  gap: 1rem;
  align-items: center;
  min-width: 0;
  padding: clamp(1rem, 2.5vw, 1.5rem);
  border: 1.5px solid var(--ink);
  border-radius: var(--radius);
  background: var(--porcelain);
}

.deploy-rows__name {
  font-size: var(--step-2);
}

.deploy-rows__platform {
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
}

.deploy-rows__summary {
  margin-top: 0.5rem;
  color: var(--text-2);
}

.deploy-rows .pricebox {
  justify-self: start;
}

/* Each row is its own grid, so an auto-sized price column made one fee box as
   wide as "from MVR 199" and the next as wide as "from MVR 1,999+" — two boxes
   on the same right edge whose left edges disagreed. The column is a fixed
   width instead, and both fees are one box. */
@media (min-width: 48em) {
  .deploy-rows__item {
    grid-template-columns: minmax(0, 1fr) 15rem;
  }

  .deploy-rows .pricebox {
    justify-self: stretch;
  }

  .deploy-rows .pricebox__value {
    white-space: nowrap;
  }
}

/* ---------- Project types on /contact ---------- */

.project-types {
  display: grid;
  gap: 0.6rem;
  margin-top: 2rem;
}

.project-types__link {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0.6rem 0.9rem;
  border: 1.5px solid var(--rule-mid);
  border-radius: var(--radius);
  background: var(--porcelain);
  font-weight: 700;
  text-decoration: none;
}

.project-types__link::after {
  content: "→";
  margin-left: auto;
  padding-left: 0.75rem;
  color: var(--sol-ink);
}

.project-types__link:hover {
  border-color: var(--ink);
  box-shadow: var(--offset);
}

@media (min-width: 40em) {
  .project-types {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .project-types {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
