/*
Theme Name: CodeTrappers
Theme URI: https://codetrappers.com
Author: CodeTrappers
Author URI: https://codetrappers.com
Description: Marketing theme for CodeTrappers — WordPress development, maintenance and emergency support. Hand-written CSS, no framework, WCAG AA colour system.
Version: 1.0.0
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: codetrappers
Tags: business, portfolio, custom-colors, custom-menu, featured-images, translation-ready
*/

@font-face {
  font-family: "Inter";
  font-style: normal;
  /* One variable file spanning every weight the stylesheet asks for. */
  font-weight: 400 800;
  font-display: swap;
  src: url("assets/fonts/inter-var.woff2") format("woff2-variations");
}



/* ==========================================================================
   CodeTrappers — static stylesheet
   Palette sampled from codetrappers.com:
   bg #ffffff · text #2b2f33 · muted #808285 · accent #fd6d2c · teal #4ec2ca
   ========================================================================== */

:root {
  --brand-50: #fff4ed;
  --brand-100: #ffe6d5;
  --brand-200: #ffc9aa;
  --brand-300: #ffa374;
  --brand-400: #ff8a3d;
  --brand-500: #fd6d2c;
  --brand-600: #ee5312;
  --brand-700: #c53e0f;

  --accent-100: #d5f2f4;
  --accent-400: #6fd3d9;
  --accent-500: #4ec2ca;
  --accent-600: #2fa2ab;

  --night: #08090a;
  --ink-900: #1f2225;
  --ink-800: #2b2f33;

  --bg: #ffffff;
  --surface: #f8fafb;
  --surface-2: #f5f6f8;
  --fg: #2b2f33;
  --muted: #5c6268;          /* 6.17:1 on white */
  --subtle: #6b7075;         /* 5.00:1 on white — was #808285 at 3.85:1 */
  --line: #e8ebef;
  --line-strong: #d8dde3;

  /* Brand orange as *text* on light surfaces. #fd6d2c is only 2.84:1, so
     anything smaller than a display heading uses this instead. */
  --brand-ink: #c53e0f;      /* 5.16:1 on white, 4.77:1 on brand-50 */
  --accent-ink: #186c73;   /* 6.12:1 on white, 5.66:1 on tinted surfaces */
  --on-brand: #1a1c1e;       /* 6.02:1 on brand-500 — buttons keep the vivid fill */

  /* Type scale — 6 steps. Nothing between these. */
  --fs-2xs: 0.75rem;         /* 12 — micro labels, badges */
  --fs-xs: 0.875rem;         /* 14 — meta, dense UI */
  --fs-sm: 1rem;             /* 16 — body, card copy */
  --fs-md: 1.125rem;         /* 18 — lede, card titles */
  --fs-lg: 1.5rem;           /* 24 */
  --fs-xl: 2rem;             /* 32 */

  /* Radius scale — 4 steps. */
  --r-sm: 0.5rem;
  --r-md: 1rem;
  --r-lg: 1.5rem;
  --r-pill: 999px;

  --radius-shell: 1.75rem;
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  --shadow-card: 0 1px 2px rgb(16 24 40 / 0.04), 0 8px 24px -12px rgb(16 24 40 / 0.12);
  --shadow-lg: 0 1px 3px rgb(16 24 40 / 0.05), 0 24px 60px -24px rgb(16 24 40 / 0.22);
  --shadow-brand: 0 8px 30px -8px var(--brand-500);

  --header-h: 4.5rem;
}

/* --------------------------------------------------------------- reset -- */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0 solid var(--line);
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--fg);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

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

ul,
ol {
  list-style: none;
}

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

/* brand-500 is only 2.84:1 against white, so the ring itself was hard to see.
   brand-ink clears 3:1 on both the light surfaces and the dark hero. */
:focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 2px;
  border-radius: 2px;
}
/* On the dark bands, add a light halo so the ring reads either way. */
.hero :focus-visible,
.guarantee :focus-visible,
.footer :focus-visible,
.featured__art :focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 4px rgb(0 0 0 / 0.5);
}

::selection {
  background: var(--line-strong);
  color: var(--ink-800);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--surface);
}
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 2px solid var(--surface);
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--subtle);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 100;
  padding: 0.625rem 1.25rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: #fff;
  background: var(--ink-900);
  border: 2px solid var(--brand-400);
  border-radius: var(--r-pill);
  transform: translateY(-200%);
}
.skip-link:focus {
  transform: none;
}

/* ------------------------------------------------------------- layout -- */

.container {
  width: 100%;
  max-width: 80rem;
  margin-inline: auto;
  padding-inline: 1.25rem;
}
@media (min-width: 640px) {
  .container {
    padding-inline: 2rem;
  }
}
@media (min-width: 1024px) {
  .container {
    padding-inline: 2.5rem;
  }
}

.icon {
  width: 1rem;
  height: 1rem;
  flex: none;
}

.section {
  padding-block: 3.5rem;
}
@media (min-width: 640px) {
  .section {
    padding-block: 5rem;
  }
}
@media (min-width: 1024px) {
  .section {
    padding-block: 8rem;
  }
}

.section--tint {
  background: var(--surface);
  border-block: 1px solid var(--line);
}

/* Emphasis in the headings now comes from weight and a darker ink, not from
   colour — the brand orange is reserved for the primary action, the hero
   horizon and the emergency bar. */
.text-gradient {
  color: var(--night);
  -webkit-text-fill-color: currentColor;
}

.text-gradient-dark {
  color: #fff;
  -webkit-text-fill-color: currentColor;
}

/* ----------------------------------------------------------- headings -- */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.75rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}

.section-head {
  max-width: 42rem;
}
.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.section-head p {
  margin-top: 1.25rem;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--muted);
  text-wrap: pretty;
}

/* ------------------------------------------------------------ buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 2.75rem;
  padding-inline: 1.5rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  white-space: nowrap;
  border-radius: var(--r-pill);
  transition:
    transform 0.3s var(--ease-out-expo),
    box-shadow 0.3s var(--ease-out-expo),
    background-color 0.3s var(--ease-out-expo),
    border-color 0.3s var(--ease-out-expo),
    color 0.3s var(--ease-out-expo);
}
.btn:active {
  transform: scale(0.97);
}
.btn--sm {
  height: 2.25rem;
  padding-inline: 1rem;
  font-size: var(--fs-xs);
}
.btn--lg {
  height: 3.25rem;
  padding-inline: 2rem;
  font-size: var(--fs-sm);
}

/* Dark ink on the vivid brand fill: white on #fd6d2c is 2.84:1 and fails AA
   at any size. This keeps the brand orange exactly and reaches 6.02:1. */
.btn--primary {
  color: var(--on-brand);
  font-weight: 600;
  background-image: linear-gradient(to right, var(--brand-400), var(--brand-500));
  box-shadow: var(--shadow-brand);
}
.btn--primary:hover {
  filter: brightness(1.08);
  box-shadow: 0 12px 44px -8px var(--brand-400);
}

.btn--secondary {
  color: var(--fg);
  background: rgb(255 255 255 / 0.75);
  border: 1px solid var(--line);
  backdrop-filter: blur(12px);
}
.btn--secondary:hover {
  border-color: var(--line-strong);
  background: #fff;
}

.btn--outline {
  color: var(--fg);
  border: 1px solid var(--line);
}
.btn--outline:hover {
  border-color: var(--ink-900);
  color: var(--ink-900);
}

/* On the dark hero. */
.btn--ghost-dark {
  color: #fff;
  background: rgb(255 255 255 / 0.04);
  border: 1px solid rgb(255 255 255 / 0.15);
  backdrop-filter: blur(8px);
}
.btn--ghost-dark:hover {
  background: rgb(255 255 255 / 0.1);
  border-color: rgb(255 255 255 / 0.3);
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;   /* was ~21px tall */
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--ink-900);
}
.link-arrow svg {
  transition: transform 0.3s var(--ease-out-expo);
}
.link-arrow:hover svg {
  transform: translateX(4px);
}

/* ------------------------------------------------- scroll progress bar -- */

.scroll-progress {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 60;
  height: 2px;
  transform-origin: left;
  transform: scaleX(0);
  background-image: linear-gradient(to right, var(--ink-800), var(--night));
}

/* --------------------------------------------------------------- header -- */

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
  transition:
    background-color 0.5s var(--ease-out-expo),
    border-color 0.5s var(--ease-out-expo),
    backdrop-filter 0.5s var(--ease-out-expo);
}
.header.is-solid {
  background: rgb(255 255 255 / 0.82);
  backdrop-filter: blur(18px) saturate(180%);
  border-bottom-color: var(--line);
}

/* The admin bar is fixed to the top for logged-in users, so anything pinned to
   0 scrolls underneath it. It is 32px wide-screen, 46px below 783px, and below
   601px it stops being fixed and scrolls away — so no offset is wanted there.
   --admin-bar-h carries the height to every pinned element. */
.admin-bar {
  --admin-bar-h: 32px;
}
@media screen and (max-width: 782px) {
  .admin-bar {
    --admin-bar-h: 46px;
  }
}
@media screen and (max-width: 600px) {
  .admin-bar {
    --admin-bar-h: 0px;
  }
}
.admin-bar .header,
.admin-bar .scroll-progress {
  top: var(--admin-bar-h);
}
.admin-bar .mobile-nav {
  top: calc(var(--header-h) + var(--admin-bar-h));
}

.header__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: var(--header-h);
}

.logo {
  display: inline-flex;
  align-items: center;
}
/* The wordmark is a wide 6.7:1 lockup, so height translates into a lot of
   width. 26px keeps it legible without letting it dominate the 4.5rem bar. */
.logo img {
  width: auto;
  height: 24px;
}
@media (min-width: 640px) {
  .logo img {
    height: 26px;
  }
}

.nav {
  display: none;
}
@media (min-width: 1024px) {
  .nav {
    display: block;
  }
}
.nav__list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}
.nav__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  height: 2.5rem;
  padding-inline: 1rem;
  font-size: var(--fs-sm);
  color: var(--muted);
  border-radius: var(--r-pill);
  transition: color 0.3s, background-color 0.3s;
}
.nav__link:hover,
.nav__item.is-open .nav__link {
  color: var(--fg);
}
.nav__item.is-open .nav__link {
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.nav__link svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 0.3s;
}
.nav__item.is-open .nav__link svg {
  transform: rotate(180deg);
}

.header__actions {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}
.header__actions .btn--secondary {
  display: none;
}
@media (min-width: 1280px) {
  .header__actions .btn--secondary {
    display: inline-flex;
  }
}
.header__actions .btn--primary {
  display: none;
}
@media (min-width: 640px) {
  .header__actions .btn--primary {
    display: inline-flex;
  }
}

.burger {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: background-color 0.3s;
}
.burger:hover {
  background: var(--surface-2);
}
@media (min-width: 1024px) {
  .burger {
    display: none;
  }
}
.burger svg {
  width: 1.25rem;
  height: 1.25rem;
}
.burger__close {
  display: none;
}
body.is-menu-open .burger__open {
  display: none;
}
body.is-menu-open .burger__close {
  display: block;
}

/* ------------------------------------------------------------ mega menu -- */

.mega {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  display: none;
  padding-bottom: 1.5rem;
}
@media (min-width: 1024px) {
  .nav__item.is-open .mega {
    display: block;
    animation: mega-in 0.28s var(--ease-out-expo) both;
  }
}

@keyframes mega-in {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
}

.mega__panel {
  display: grid;
  grid-template-columns: 3fr 9fr;
  /* A fourth column of six links pushed Services past 1100px, which runs off
     the bottom of a 900px screen with no way to reach the last items. Cap it
     to the space actually below the header and let the panel scroll itself. */
  max-height: calc(100vh - var(--header-h) - var(--admin-bar-h, 0px) - 1.5rem);
  overflow: hidden auto;
  overscroll-behavior: contain;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}

.mega__feature {
  display: flex;
  flex-direction: column;
  /* Not space-between: the column stretches to the tallest link column, which
     left a 200px hole between the copy and the CTA on Services and Solutions
     while Explore had almost none. Grouping at the top reads the same in all
     three. */
  justify-content: flex-start;
  gap: 1.75rem;
  padding: 1.75rem;
  border-right: 1px solid var(--line);
  background-image: linear-gradient(to bottom right, var(--surface), var(--surface-2));
}
@media (min-width: 1280px) {
  .mega__feature {
    padding: 2.25rem;
  }
}
.mega__feature-eyebrow {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--subtle);
}
.mega__feature h3 {
  margin-top: 1rem;
  font-size: 22px;
  line-height: 1.35;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.mega__feature p {
  margin-top: 1rem;
  font-size: var(--fs-xs);
  line-height: 1.65;
  color: var(--muted);
}
.mega__feature-phone {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
  padding-top: 1rem;
  font-size: var(--fs-xs);
  color: var(--subtle);
  border-top: 1px solid var(--line);
  transition: color 0.3s;
}
.mega__feature-phone:hover {
  color: var(--fg);
}
.mega__feature-phone svg {
  width: 0.875rem;
  height: 0.875rem;
}

.mega__cols {
  display: grid;
  /* Column count follows the number of groups in the menu, set inline by
     inc/nav.php. Hardcoding 3 left a fourth group wrapping onto its own row. */
  grid-template-columns: repeat(var(--mega-cols, 3), minmax(0, 1fr));
  gap: 1.75rem 1rem;
  padding: 1.5rem;
}
@media (min-width: 1280px) {
  .mega__cols {
    gap: 1.75rem 1.5rem;
    padding: 2rem;
  }
}
.mega__col-head {
  margin-bottom: 0.75rem;
  padding-inline: 0.75rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--subtle);
}

.mega__link {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 1.375rem 0.75rem 0.75rem;
  border-radius: var(--r-md);
  transition: background-color 0.3s;
}
.mega__link:hover {
  background: var(--surface-2);
}
.mega__link-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  margin-top: 0.125rem;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.mega__link:hover .mega__link-icon {
  color: var(--ink-900);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.mega__link-icon svg {
  width: 17px;
  height: 17px;
}
/* The text block is a flex item, so it defaulted to shrink-to-fit and capped
   titles at 127px while the column had room to spare — that is what pushed
   almost every title onto a second line. */
.mega__link > span:not(.mega__link-icon) {
  flex: 1;
  min-width: 0;
}
/* Block, not flex: as a flex container the badge became its own flex item and
   wrapped to a third line once the title already used two. Inline flow lets it
   simply follow the last word. Two lines are reserved so every row in every
   column sits on the same rhythm. */
.mega__link-title {
  display: block;
  /* No reserved second line. This was here when four columns squeezed titles
     onto two lines; with the migration and industry links moved out to the chip
     row every title fits on one, so the reservation was pure gap under names
     like "WordPress Maintenance". Row heights are still held by the two-line
     description below. */
  font-size: var(--fs-xs);
  font-weight: 500;
  line-height: 1.35;
}
.mega__link-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  /* Two lines always: reserved so short descriptions do not collapse the row,
     clamped so long ones do not stretch it. */
  min-height: calc(2 * 1.4em);
  margin-top: 0.125rem;
  font-size: var(--fs-2xs);
  line-height: 1.4;
  color: var(--subtle);
}
.mega__link-arrow {
  /* Absolute so the arrow does not reserve ~22px of the title line while
     invisible — that alone pushed several titles onto a second row. */
  position: absolute;
  top: 0.95rem;
  right: 0.5rem;
  width: 0.75rem;
  height: 0.75rem;
  color: var(--subtle);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.3s, transform 0.3s;
}
.mega__link:hover .mega__link-arrow {
  opacity: 1;
  transform: none;
}

.badge-new {
  display: inline-block;
  margin-left: 0.375rem;
  vertical-align: 1px;
  white-space: nowrap;
  padding: 1px 0.375rem;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: rgb(78 194 202 / 0.12);
  border: 1px solid rgb(78 194 202 / 0.4);
  border-radius: var(--r-pill);
}

.mega__foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.875rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.mega__foot p {
  font-size: var(--fs-xs);
  color: var(--subtle);
}

.mega-backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgb(31 34 37 / 0.25);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
body.is-mega-open .mega-backdrop {
  opacity: 1;
}

/* ----------------------------------------------------------- mobile nav -- */

.mobile-nav {
  position: fixed;
  inset: var(--header-h) 0 0;
  z-index: 40;
  display: none;
  overflow-y: auto;
  background: rgb(255 255 255 / 0.97);
  backdrop-filter: blur(16px);
}
body.is-menu-open .mobile-nav {
  display: block;
  animation: rise-in 0.35s var(--ease-out-expo) both;
}
@media (min-width: 1024px) {
  body.is-menu-open .mobile-nav {
    display: none;
  }
}
.mobile-nav__inner {
  padding-block: 2rem;
}
.mobile-nav__group {
  border-bottom: 1px solid var(--line);
}
.mobile-nav__group:first-child {
  border-top: 1px solid var(--line);
}
.mobile-nav__toggle,
.mobile-nav__plain {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding-block: 1rem;
  font-size: var(--fs-md);
  font-weight: 500;
  text-align: left;
}
.mobile-nav__toggle svg {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--subtle);
  transition: transform 0.3s, color 0.3s;
}
.mobile-nav__group.is-open .mobile-nav__toggle svg {
  transform: rotate(180deg);
  color: var(--ink-900);
}
.mobile-nav__panel {
  display: none;
  padding-bottom: 1.5rem;
}
.mobile-nav__group.is-open .mobile-nav__panel {
  display: block;
}
.mobile-nav__col-head {
  margin-bottom: 0.5rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--subtle);
}
.mobile-nav__col + .mobile-nav__col {
  margin-top: 1.5rem;
}
.mobile-nav__link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.625rem;
  font-size: var(--fs-sm);
  color: var(--muted);
}
.mobile-nav__link .mega__link-icon {
  width: 2rem;
  height: 2rem;
  margin: 0;
}
.mobile-nav__link .mega__link-icon svg {
  width: 1rem;
  height: 1rem;
}
.mobile-nav__cta {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
.mobile-nav__contact {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  font-size: var(--fs-xs);
  color: var(--muted);
  border-top: 1px solid var(--line);
}
.mobile-nav__contact a {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}
.mobile-nav__contact svg {
  color: var(--muted);
}

/* ----------------------------------------------------------------- hero -- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-inline: 0.5rem;
  margin-bottom: 0.5rem;
  padding-top: 6rem;
  padding-bottom: 14rem;
  background: var(--night);
  border-radius: var(--radius-shell);
}
@media (min-width: 1024px) {
  .hero {
    padding-top: 8rem;
    padding-bottom: 18rem;
  }
}

/* The landing hero fills exactly one screenful — the viewport less the sticky
   header, the admin bar when there is one, and the bottom gutter. Fixed
   padding made it 900px tall regardless of screen, pushing the fold off any
   normal laptop, so the padding is viewport-relative now. The decorations are
   already percentage-based, so they follow. Page heroes keep their own size. */
.hero:not(.hero--page) {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* The 1px is the header's own bottom border, which --header-h excludes. */
  min-height: calc(100svh - var(--header-h) - 1px - var(--admin-bar-h, 0px) - 0.5rem);
  padding-top: clamp(1.5rem, 4vh, 6rem);
  padding-bottom: clamp(3.5rem, 11vh, 14rem);
}
@media (min-width: 1024px) {
  .hero:not(.hero--page) {
    padding-top: clamp(1.5rem, 4vh, 8rem);
    padding-bottom: clamp(3.5rem, 11vh, 18rem);
  }
}

/* The rhythm between badge, headline block and trust row is what decides
   whether the hero clears a short laptop screen, so it tracks viewport height
   rather than sitting at a fixed 2.5/3.5rem. */
.hero:not(.hero--page) .hero__main {
  margin-top: clamp(1.25rem, 4vh, 2.5rem);
}
.hero:not(.hero--page) .hero__trust {
  margin-top: clamp(1.5rem, 5vh, 3.5rem);
}

.hero__grid,
.hero__stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.hero__grid {
  background-image:
    linear-gradient(to right, rgb(255 255 255 / 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(900px circle at 50% 0%, #fff, transparent 75%);
  mask-image: radial-gradient(900px circle at 50% 0%, #fff, transparent 75%);
}
.hero__stars {
  -webkit-mask-image: linear-gradient(to bottom, #fff, transparent 75%);
  mask-image: linear-gradient(to bottom, #fff, transparent 75%);
}
.star {
  position: absolute;
  width: 1px;
  height: 1px;
  background: #fff;
  border-radius: var(--r-pill);
  animation: twinkle 4s ease-in-out infinite;
}

/* Glow bloom sitting on the horizon's apex. */
.hero__bloom {
  position: absolute;
  bottom: 14%;
  left: 50%;
  z-index: -10;
  width: min(72rem, 120%);
  height: 24rem;
  transform: translateX(-50%);
  border-radius: 50%;
  pointer-events: none;
  filter: blur(40px);
  background: radial-gradient(
    ellipse at center,
    rgb(253 109 44 / 0.42),
    rgb(253 109 44 / 0.12) 45%,
    transparent 70%
  );
}

/* Planet horizon: a dark disc with a lit top edge. */
.hero__horizon {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: -10;
  height: 46%;
  overflow: hidden;
  pointer-events: none;
}
.hero__horizon::before {
  content: "";
  position: absolute;
  top: 26%;
  left: 50%;
  width: 230%;
  aspect-ratio: 1;
  transform: translateX(-50%);
  background: var(--night);
  border-top: 1px solid rgb(255 163 116 / 0.7);
  border-radius: 50%;
  box-shadow:
    0 -4px 28px -2px rgb(255 138 61 / 0.75),
    0 -24px 90px -12px rgb(253 109 44 / 0.45);
}
@media (min-width: 640px) {
  .hero__horizon::before {
    width: 175%;
  }
}
@media (min-width: 1024px) {
  .hero__horizon::before {
    width: 140%;
  }
}

.hero__wordmark {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}
.hero__wordmark span {
  transform: translateY(26%);
  font-size: clamp(4rem, 19vw, 17rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.05em;
  white-space: nowrap;
  color: rgb(255 255 255 / 0.05);
}

.hero__inner {
  position: relative;
}

.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.375rem 1rem 0.375rem 0.375rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.6);
  background: rgb(255 255 255 / 0.04);
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: var(--r-pill);
  backdrop-filter: blur(8px);
  transition: border-color 0.3s;
}
.hero__badge:hover {
  border-color: rgb(255 255 255 / 0.25);
}
.hero__badge b {
  padding: 0.125rem 0.625rem;
  /* Never break "Five for the Future" across lines: a wrapped label inside a
     pill is what made this look broken on a phone. */
  white-space: nowrap;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  background: rgb(255 255 255 / 0.16);
  border-radius: var(--r-pill);
}

/* Below the point where label and sentence fit side by side, stop pretending
   this is a single-line pill and let it be a small stacked card. Two lines by
   accident looks broken; two lines by design does not. */
/* The inline pill needs ~478px of container width. With the page gutters that
   means a viewport of about 560px, measured rather than guessed: at 520px the
   sentence still wrapped inside a pill that was pretending to be one line. */
@media (max-width: 559px) {
  .hero__badge {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 0.4375rem;
    padding: 0.625rem 1rem;
    border-radius: var(--r-lg);
    text-align: center;
  }
  /* The arrow was the third thing competing for a line that could not hold two.
     The whole badge is the link, so it was never carrying the affordance. */
  .hero__badge svg {
    display: none;
  }
  .hero__badge span {
    line-height: 1.45;
  }
  /* Centre the badge box itself, not just the text inside it. */
  .hero__inner > .hero__badge {
    display: grid;
    margin-inline: auto;
  }
}
.hero__badge svg {
  width: 0.875rem;
  height: 0.875rem;
  color: rgb(255 255 255 / 0.7);
  transition: transform 0.3s;
}
.hero__badge:hover svg {
  transform: translateX(2px);
}

.hero__main {
  display: grid;
  gap: 2.5rem;
  margin-top: 2.5rem;
}
@media (min-width: 1024px) {
  .hero__main {
    grid-template-columns: 7fr 5fr;
    align-items: end;
    gap: 4rem;
  }
}

.hero h1 {
  font-size: clamp(2.7rem, 6.2vw, 4.9rem);
  line-height: 1.02;
  font-weight: 600;
  letter-spacing: -0.04em;
  color: #fff;
  text-wrap: balance;
}

.hero__lede {
  max-width: 28rem;
  font-size: var(--fs-md);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.6);
  text-wrap: pretty;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 2rem;
}

.hero__trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 2rem;
  margin-top: 3.5rem;
  padding-top: 2rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.56);
  border-top: 1px solid rgb(255 255 255 / 0.1);
}
.hero__trust li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.hero__trust svg {
  color: rgb(255 255 255 / 0.45);
}

/* ------------------------------------------------- word / rise reveals -- */

.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}
.word > span {
  display: inline-block;
  padding-bottom: 0.12em;
  /* This heading is the LCP element, and a browser does not count an element
     as painted while it sits at opacity 0. With `both` fill and a 0.66s
     stagger over 0.85s, the last word was not painted until ~1.5s, putting a
     floor under LCP that no bandwidth could beat. Same effect, far sooner. */
  animation: word-rise 0.5s var(--ease-out-expo) both;
  animation-delay: var(--delay, 0s);
}

/* CSS, not JS: a JS tween never starts in a backgrounded tab, which would
   leave the headline stranded at opacity 0. */
@keyframes word-rise {
  from {
    opacity: 0;
    transform: translateY(110%);
    filter: blur(8px);
  }
}

.rise {
  animation: rise-in 0.7s var(--ease-out-expo) both;
  animation-delay: var(--delay, 0s);
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(14px);
    filter: blur(6px);
  }
}

/* Scroll-triggered reveal, driven by IntersectionObserver in script.js.
   Scoped to .js so the page is fully visible when JavaScript never runs —
   otherwise a script error, or a tab that loads in the background (where
   IntersectionObserver never fires), leaves the whole page blank. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  filter: blur(6px);
  transition:
    opacity 0.6s var(--ease-out-expo),
    transform 0.6s var(--ease-out-expo),
    filter 0.6s var(--ease-out-expo);
  transition-delay: var(--delay, 0s);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
  filter: none;
}

@keyframes twinkle {
  0%,
  100% {
    opacity: 0.15;
  }
  50% {
    opacity: 0.9;
  }
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.85);
    opacity: 0.6;
  }
  80%,
  100% {
    transform: scale(1.6);
    opacity: 0;
  }
}

/* ------------------------------------------------------ stats + clients -- */

.stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
@media (min-width: 640px) {
  .stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.stats > div {
  padding: 2rem 1.5rem;
  background: #fff;
}
.stats dd p:first-child {
  font-size: clamp(1.9rem, 3.8vw, 2.6rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stats dd span {
  color: var(--ink-900);
}
/* The counter is a span as well; keep it in the foreground colour. */
.stats dd .count {
  color: var(--fg);
}
.stats dd p:last-child {
  margin-top: 0.625rem;
  font-size: var(--fs-xs);
  color: var(--subtle);
}

.clients {
  padding-block: 4rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.clients__label {
  margin-top: 4rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: center;
  color: var(--subtle);
}

.marquee {
  display: flex;
  gap: 1.5rem;
  overflow: hidden;
  padding-block: 0.5rem;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}
.marquee + .marquee {
  margin-top: 1rem;
}
.marquee__track {
  display: flex;
  flex: none;
  gap: 1.5rem;
  animation: marquee var(--duration, 46s) linear infinite;
}
.marquee--reverse .marquee__track {
  animation-direction: reverse;
}
.marquee:hover .marquee__track {
  animation-play-state: paused;
}

@keyframes marquee {
  to {
    transform: translateX(calc(-100% - 1.5rem));
  }
}

.pill {
  padding: 0.625rem 1.5rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  white-space: nowrap;
  color: var(--muted);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: border-color 0.3s, background-color 0.3s, color 0.3s;
}
.pill:hover {
  color: var(--fg);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.pill--ghost {
  font-weight: 400;
  color: var(--subtle);
  background: transparent;
}
.pill--ghost:hover {
  color: var(--ink-900);
  border-color: var(--line-strong);
  background: transparent;
}

/* ---------------------------------------------------------------- cards -- */

.grid-3 {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}
@media (min-width: 640px) {
  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Imported pages don't always yield a full row. A single card left in a 3- or
   4-track grid would hug the left edge at a third of the width, so span the
   whole row and centre it instead. */
.grid-3 > :only-child,
.g-grid > :only-child {
  grid-column: 1 / -1;
  max-width: 32rem;
  margin-inline: auto;
}

/* Five cards in three tracks leaves the last row two-thirds full with a hole
   on the right. When the final card is the second of its row, let it take the
   spare track so the block closes off square. */
@media (min-width: 1024px) {
  .grid-3 > :last-child:nth-child(3n + 2) {
    grid-column: span 2;
  }
}

/* Cards carrying a bullet list are denser than a plain card, so the list gets
   room to breathe and the card keeps a floor even when its list is short. */
.card .points {
  margin-top: 1.125rem;
}
.card .points li {
  line-height: 1.55;
}

/* Bullet list inside a card or rail item. The marker is a ::before rather than
   list-style so it inherits the brand colour and stays aligned with wrapped
   lines. */
.points {
  display: grid;
  gap: 0.5rem;
  margin-top: 1rem;
}
.points li {
  position: relative;
  padding-left: 1.25rem;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--muted);
}
.points li::before {
  content: "";
  position: absolute;
  top: 0.55em;
  left: 0;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--line-strong);
}
.guarantee .points li {
  color: rgb(255 255 255 / 0.68);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 1.75rem;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: transform 0.5s var(--ease-out-expo), border-color 0.5s, box-shadow 0.5s;
}
.card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
/* Cursor-tracked highlight, positioned from script.js. */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s;
  background: radial-gradient(
    420px circle at var(--spot-x, 50%) var(--spot-y, 50%),
    rgb(16 24 40 / 0.06),
    transparent 70%
  );
}
.card:hover::before {
  opacity: 1;
}
.card > * {
  position: relative;
}

.card__icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 1.5rem;
  color: var(--muted);
  background-image: linear-gradient(to bottom right, var(--surface), var(--surface-2));
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: transform 0.5s var(--ease-out-expo), border-color 0.5s;
}
.card:hover .card__icon {
  transform: scale(1.1);
  border-color: var(--line-strong);
}
.card__icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.card__title {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.card__title svg {
  flex: none;
  margin-top: 0.125rem;
  color: var(--subtle);
  transition: transform 0.3s, color 0.3s;
}
.card:hover .card__title svg {
  color: var(--ink-900);
  transform: translate(2px, -2px);
}
.card__body {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

.center-cta {
  display: flex;
  justify-content: center;
  margin-top: 3rem;
}

/* ------------------------------------------------------------ solutions -- */

.split {
  display: grid;
  gap: 4rem;
}
@media (min-width: 1024px) {
  .split {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    gap: 5rem;
  }
}
.split h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.split > div > p {
  margin-top: 1.25rem;
  max-width: 36rem;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--muted);
}

.usp {
  display: grid;
  gap: 1.25rem;
  margin-top: 2.25rem;
}
.usp li {
  display: flex;
  gap: 1rem;
}
.usp__dot {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.375rem;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.usp__dot svg {
  width: 0.75rem;
  height: 0.75rem;
}
.usp h3 {
  font-size: var(--fs-sm);
  font-weight: 500;
}
.usp p {
  margin-top: 0.25rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

.panel {
  padding: 2rem;
  background: rgb(255 255 255 / 0.75);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  backdrop-filter: blur(12px);
}
@media (min-width: 640px) {
  .panel {
    padding: 2.5rem;
  }
}
.panel__label {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--subtle);
}
.panel__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin-top: 1.5rem;
}
.chip {
  display: inline-block;
  padding: 0.5rem 1rem;
  font-size: var(--fs-xs);
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: transform 0.3s var(--ease-out-expo), background-color 0.3s, border-color 0.3s, color 0.3s;
}
.chip:hover {
  transform: translateY(-2px);
  color: var(--fg);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.panel__note {
  margin-top: 2.25rem;
  padding: 1.5rem;
  background-image: linear-gradient(to bottom right, var(--surface), var(--surface-2));
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.panel__note p {
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}
.panel__note b {
  color: var(--fg);
}

/* --------------------------------------------------------------- bento -- */

/* Four cells: two tall ones flanking a stacked pair. One column on small
   screens, so the row/column placement below only applies from lg up. */
.bento {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}
@media (min-width: 1024px) {
  .bento {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(0, 1fr));
  }
  .bento__cell--tall {
    grid-row: span 2;
  }
  .bento__cell--second {
    grid-column: 2;
    grid-row: 1;
  }
  .bento__cell--third {
    grid-column: 2;
    grid-row: 2;
  }
  .bento__cell--fourth {
    grid-column: 3;
  }
}

.bento__cell {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 1px 2px rgb(31 34 37 / 0.04);
}

/* The outer corners of the block are rounded harder than the seams, so the
   four cells read as one slab. Vertical stack on small screens, horizontal
   from lg — hence the two sets. */
.bento__cell--first {
  border-top-left-radius: var(--radius-shell);
  border-top-right-radius: var(--radius-shell);
}
.bento__cell--fourth {
  border-bottom-right-radius: var(--radius-shell);
  border-bottom-left-radius: var(--radius-shell);
}
@media (min-width: 1024px) {
  .bento__cell--first {
    border-radius: var(--radius-shell) var(--r-lg) var(--r-lg) var(--radius-shell);
  }
  .bento__cell--fourth {
    border-radius: var(--r-lg) var(--radius-shell) var(--radius-shell) var(--r-lg);
  }
}

.bento__head {
  padding: 2rem 1.75rem 0;
}
@media (min-width: 640px) {
  .bento__head {
    padding: 2.5rem 2.25rem 0;
  }
}
.bento__title {
  margin-top: 0.5rem;
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}
.bento__body {
  margin-top: 0.75rem;
  max-width: 32rem;
  font-size: var(--fs-xs);
  line-height: 1.7;
  color: var(--muted);
}

.bento__media {
  position: relative;
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  min-height: 11rem;
  margin-top: 2rem;
  padding: 0 1.75rem 2rem;
}
@media (min-width: 640px) {
  .bento__media {
    padding: 0 2.25rem 2.25rem;
  }
}

.bento__feature-label {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--subtle);
}
.bento__big {
  margin-top: 0.75rem;
  font-size: clamp(2.75rem, 6vw, 4rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.bento__metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.bento__metrics p:first-child {
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.bento__metrics p:last-child {
  margin-top: 0.25rem;
  font-size: var(--fs-2xs);
  line-height: 1.35;
  color: var(--subtle);
}

/* -- browser frame --------------------------------------------------------
   Every screenshot we hold is a full-page desktop capture, so the frame is a
   browser window rather than a phone — a desktop layout in a phone would read
   as a mistake. The window runs off the bottom of the cell, so it looks like a
   view onto a longer page. */
.bento__media--browser {
  /* Anchored left so the overflow falls off the right edge only, and stretched
     so the window takes the cell's height rather than the image's. */
  align-items: stretch;
  justify-content: flex-start;
  min-height: 17rem;
  padding-right: 0;
  padding-bottom: 0;
}
.browser {
  display: flex;
  flex-direction: column;
  /* Wider than the cell and clipped by it. A 940px-wide desktop capture shrunk
     into a 240px column is unreadable; overflowing lets the page render at
     roughly half scale, and the crop reads as a window onto something larger —
     the same move the code panel makes on the opposite side. */
  width: 180%;
  /* A flex item would otherwise shrink straight back to the cell width. */
  flex: 0 0 auto;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  border-right: 0;
  border-bottom: 0;
  border-radius: var(--r-md) 0 0 0;
  box-shadow: 0 24px 48px -18px rgb(31 34 37 / 0.35);
}
.browser__bar {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.5rem 0.75rem;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.browser__bar > span {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--line-strong);
}
.browser__url {
  flex: 1;
  height: 0.9rem;
  margin-left: 0.5rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
/* The image is taken out of flow so it contributes no intrinsic height. In
   flow it fed its own natural height back into the grid row, which grew the
   row, which grew the image — the cell ended up half as tall again. */
.browser__shot {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.browser__shot img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Show the masthead and hero, which is the part that identifies the site. */
  object-position: top center;
}

/* -- launch checklist ----------------------------------------------------- */
.checklist {
  width: 100%;
  display: grid;
  gap: 0.625rem;
  align-self: center;
}
.checklist li {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.875rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.checklist__tick {
  display: inline-flex;
  color: var(--accent-ink);
}
.checklist__tick svg {
  width: 1rem;
  height: 1rem;
}
.checklist__pending {
  color: var(--ink-900);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.checklist__pending .checklist__tick {
  color: var(--ink-900);
}

/* -- uptime bars ---------------------------------------------------------- */
.uptime {
  width: 100%;
  align-self: center;
}
.uptime__bars {
  display: flex;
  gap: 3px;
  align-items: flex-end;
  height: 4rem;
}
.uptime__bars span {
  flex: 1;
  /* A steady band with a little variation, seeded off the index so the shape
     is stable between renders rather than random noise. */
  height: calc(62% + (var(--i) * 37 % 13) * 3%);
  background: var(--accent-400);
  border-radius: 2px;
}
.uptime__bars span:nth-child(3n) {
  background: var(--line-strong);
}
.uptime__label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--subtle);
}
.uptime__label svg {
  width: 1rem;
  height: 1rem;
  color: var(--accent-ink);
}

/* -- code panel -----------------------------------------------------------
   Bled to the right edge the way the reference does, so it reads as a window
   onto a larger file. */
.bento__media--code {
  align-items: stretch;
  min-height: 17rem;
  padding: 0 0 0 1.75rem;
}
@media (min-width: 640px) {
  .bento__media--code {
    padding-left: 2.25rem;
  }
}
.codepanel {
  width: 100%;
  overflow: hidden;
  background: var(--night);
  border-top-left-radius: var(--r-md);
  box-shadow: 0 24px 48px -18px rgb(31 34 37 / 0.45);
}
.codepanel__tabs {
  display: flex;
  font-size: var(--fs-2xs);
  color: rgb(255 255 255 / 0.5);
  border-bottom: 1px solid rgb(255 255 255 / 0.1);
}
.codepanel__tabs span {
  padding: 0.625rem 1rem;
  border-right: 1px solid rgb(255 255 255 / 0.08);
}
.codepanel__tabs .is-active {
  color: #fff;
  background: rgb(255 255 255 / 0.06);
}
.codepanel__code {
  padding: 1.25rem 0 2rem 1.25rem;
  overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 0.7rem;
  line-height: 1.75;
  color: rgb(255 255 255 / 0.72);
  white-space: pre;
}
.c-k { color: #c8ced6; }
.c-t { color: #6fd3d9; }
.c-f { color: #e6eaee; }
.c-v { color: #b8c4d0; }
.c-s { color: #8fd6a8; }

/* ------------------------------------------------------------- process -- */

/* Divided grid on a dark band, with arrow chips straddling the dividers so
   the eight steps read as one flow rather than eight cells. */
.steps-band {
  position: relative;
  overflow: hidden;
  margin: 0.5rem;
  padding-block: 4rem;
  color: #fff;
  background: var(--night);
  border-radius: var(--radius-shell);
}
@media (min-width: 1024px) {
  .steps-band {
    padding-block: 7rem;
  }
}
.steps-band__glow {
  position: absolute;
  top: -40%;
  left: 50%;
  width: min(58rem, 130%);
  height: 30rem;
  transform: translateX(-50%);
  pointer-events: none;
  border-radius: 50%;
  filter: blur(40px);
  background: radial-gradient(ellipse at center, rgb(255 255 255 / 0.1), transparent 70%);
}
.steps-band__inner {
  position: relative;
}
.steps-band .eyebrow {
  color: rgb(255 255 255 / 0.65);
  background: rgb(255 255 255 / 0.08);
  border-color: rgb(255 255 255 / 0.18);
}
.steps-band .section-head h2 {
  color: #fff;
}
.steps-band .section-head p {
  color: rgb(255 255 255 / 0.6);
}

.steps-grid {
  display: grid;
  margin-top: 4rem;
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: var(--r-lg);
}
@media (min-width: 640px) {
  .steps-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .steps-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.steps-cell {
  position: relative;
  padding: 2.25rem 1.75rem;
  transition: background-color 0.4s var(--ease-out-expo);
}
.steps-cell:hover {
  background: rgb(255 255 255 / 0.035);
}
/* Dividers drawn on the cells so the arrow chips can sit on top of them. */
.steps-cell + .steps-cell {
  border-top: 1px solid rgb(255 255 255 / 0.12);
}
@media (min-width: 640px) {
  .steps-cell {
    border-top: 1px solid rgb(255 255 255 / 0.12);
  }
  .steps-cell:nth-child(-n + 2) {
    border-top: 0;
  }
  .steps-cell:nth-child(odd) {
    border-right: 1px solid rgb(255 255 255 / 0.12);
  }
}
@media (min-width: 1024px) {
  .steps-cell:nth-child(-n + 4) {
    border-top: 0;
  }
  .steps-cell:nth-child(odd) {
    border-right: 0;
  }
  .steps-cell:not(:nth-child(4n)) {
    border-right: 1px solid rgb(255 255 255 / 0.12);
  }
}
/* Keep the hover fill inside the container's rounded corners. */
.steps-cell:first-child {
  border-start-start-radius: var(--r-lg);
}
.steps-cell:last-child {
  border-end-end-radius: var(--r-lg);
}
@media (min-width: 1024px) {
  .steps-cell:nth-child(4) {
    border-start-end-radius: var(--r-lg);
  }
  .steps-cell:nth-child(5) {
    border-end-start-radius: var(--r-lg);
  }
}

.steps-cell__num {
  font-size: var(--fs-2xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.16em;
  color: rgb(255 255 255 / 0.62);
}
.steps-cell__kicker {
  margin-left: 0.625rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.56);   /* 0.45 landed at 4.49 — just under AA */
}
.steps-cell h3 {
  margin-top: 1rem;
  font-size: var(--fs-lg);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #fff;
}
.steps-cell p {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.6);
}
/* The number/kicker line is also a <p>; it leads the cell. */
.steps-cell p:first-child {
  margin-top: 0;
}

/* The chip that straddles the divider. */
.steps-cell__arrow {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: rgb(255 255 255 / 0.7);
  background: var(--night);
  border: 1px solid rgb(255 255 255 / 0.14);
  border-radius: var(--r-pill);
  transition: color 0.4s, border-color 0.4s, background-color 0.4s;
}
.steps-cell:hover .steps-cell__arrow {
  color: #fff;
  background: rgb(255 255 255 / 0.16);
  border-color: rgb(255 255 255 / 0.26);
}
.steps-cell__arrow svg {
  width: 1.125rem;
  height: 1.125rem;
}
/* Stacked: chip drops below the cell, rotated to point down. */
.steps-cell__arrow {
  bottom: -1.375rem;
  left: 50%;
  transform: translateX(-50%) rotate(90deg);
}
@media (min-width: 640px) {
  .steps-cell__arrow {
    top: 50%;
    right: -1.375rem;
    bottom: auto;
    left: auto;
    transform: translateY(-50%);
  }
  /* No chip at the end of a row — the flow wraps there. */
  .steps-cell:nth-child(even) .steps-cell__arrow {
    display: none;
  }
}
@media (min-width: 1024px) {
  .steps-cell:nth-child(even) .steps-cell__arrow {
    display: grid;
  }
  .steps-cell:nth-child(4n) .steps-cell__arrow {
    display: none;
  }
}
.steps-cell:last-child .steps-cell__arrow {
  display: none;
}

/* --------------------------------------------------------- case studies -- */

.section-head--row {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
@media (min-width: 1024px) {
  .section-head--row {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}

.case__tag {
  display: inline-flex;
  align-self: flex-start;
  padding: 0.25rem 0.75rem;
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.case h3 {
  margin-top: 1.5rem;
  font-size: var(--fs-lg);
  line-height: 1.35;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.case__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-top: auto;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.case__metric {
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.case__metric-label {
  margin-top: 0.25rem;
  font-size: var(--fs-2xs);
  color: var(--subtle);
}
.case__go {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--subtle);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.card:hover .case__go {
  color: var(--ink-900);
  background: var(--surface-2);
  border-color: var(--line-strong);
}

/* -------------------------------------------------------- testimonials -- */

.quote-card {
  flex: none;
  width: 340px;
  padding: 1.75rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  white-space: normal;
  transition: border-color 0.3s;
}
@media (min-width: 640px) {
  .quote-card {
    width: 400px;
  }
}
.quote-card:hover {
  border-color: var(--line-strong);
}
.quote-card > svg {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--line-strong);
}
.quote-card blockquote {
  margin-top: 1rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  text-wrap: pretty;
}
.quote-card figcaption {
  margin-top: 1.5rem;
  padding-top: 1rem;
  font-size: var(--fs-xs);
  color: var(--subtle);
  border-top: 1px solid var(--line);
}
.quote-card figcaption b {
  font-weight: 500;
  color: var(--fg);
}

.founder {
  max-width: 48rem;
  margin: 4rem auto 0;
  padding: 3rem 2.25rem;
  text-align: center;
  background: rgb(255 255 255 / 0.75);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.founder > svg {
  width: 1.75rem;
  height: 1.75rem;
  margin-inline: auto;
  color: var(--line-strong);
}
.founder blockquote {
  margin-top: 1.5rem;
  font-size: clamp(1.05rem, 2.2vw, 1.4rem);
  line-height: 1.55;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.founder figcaption {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
}
.founder__avatar {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: #fff;
  background-image: linear-gradient(to bottom right, var(--ink-800), var(--night));
  border-radius: var(--r-pill);
}
.founder__who {
  text-align: left;
}
.founder__who b {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 500;
}
.founder__who span {
  display: block;
  font-size: var(--fs-xs);
  color: var(--subtle);
}

/* ----------------------------------------------------------------- faq -- */

.faq {
  display: grid;
  gap: 3.5rem;
}
@media (min-width: 1024px) {
  .faq {
    grid-template-columns: 0.8fr 1.2fr;
    gap: 5rem;
  }
  .faq__aside {
    position: sticky;
    top: 8rem;
    align-self: start;
  }
}
.faq__aside h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.9rem, 4vw, 2.75rem);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.faq__aside p {
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}
.faq__aside .link-arrow {
  margin-top: 1.5rem;
  font-size: var(--fs-sm);
}

.accordion {
  border-block: 1px solid var(--line);
}
.accordion__item + .accordion__item {
  border-top: 1px solid var(--line);
}
.accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
  padding-block: 1.5rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  text-align: left;
  transition: color 0.3s;
}
@media (min-width: 640px) {
  .accordion__trigger {
    font-size: var(--fs-md);
  }
}
.accordion__trigger:hover {
  color: var(--ink-900);
}
.accordion__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: transform 0.5s var(--ease-out-expo), background-color 0.5s, border-color 0.5s;
}
.accordion__item.is-open .accordion__icon {
  transform: rotate(45deg);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease-out-expo);
}
.accordion__item.is-open .accordion__panel {
  grid-template-rows: 1fr;
}
.accordion__panel > div {
  overflow: hidden;
}
.accordion__panel p {
  max-width: 48rem;
  padding-bottom: 1.75rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

/* ----------------------------------------------------------------- cta -- */

.cta {
  position: relative;
  overflow: hidden;
  padding: 2.75rem 1.75rem;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
@media (min-width: 640px) {
  .cta {
    padding: 3.25rem 3.5rem;
  }
}
.cta__inner {
  position: relative;
  max-width: 48rem;
  margin-inline: auto;
}
.cta h2 {
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.cta > .cta__inner > p {
  max-width: 32rem;
  margin: 0.875rem auto 0;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--muted);
  text-wrap: pretty;
}
.cta__buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

/* -------------------------------------------------------------- footer -- */

.footer {
  position: relative;
  overflow: hidden;
  color: rgb(255 255 255 / 0.7);
  background: var(--night);
}

.footer__pledge {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 2.5rem;
  border-bottom: 1px solid rgb(255 255 255 / 0.1);
}
@media (min-width: 768px) {
  .footer__pledge {
    flex-direction: row;
    align-items: center;
  }
}
.footer__pledge-main {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}
.footer__pledge-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  color: rgb(255 255 255 / 0.6);
  background: rgb(255 255 255 / 0.08);
  border: 1px solid rgb(255 255 255 / 0.16);
  border-radius: var(--r-md);
}
.footer__pledge-icon svg {
  width: 1.25rem;
  height: 1.25rem;
}
.footer__pledge b {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: #fff;
}
.footer__pledge p {
  max-width: 36rem;
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.55);
}
.footer__pledge-link {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1.25rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: #fff;
  border: 1px solid rgb(255 255 255 / 0.15);
  border-radius: var(--r-pill);
  transition: background-color 0.3s, border-color 0.3s;
}
.footer__pledge-link:hover {
  background: rgb(255 255 255 / 0.06);
  border-color: rgb(255 255 255 / 0.28);
}

.footer__grid {
  display: grid;
  gap: 3rem;
  padding-block: 4rem;
}
@media (min-width: 1024px) {
  .footer__grid {
    /* About, then Services, Solutions, Learn, Company. The last two are short
       lists, so they take the narrower tracks. */
    grid-template-columns: 4fr 3fr 3fr 2fr 2fr;
    gap: 2rem;
  }
}
.footer__about p {
  max-width: 20rem;
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.55);
}
.footer__contact {
  display: grid;
  gap: 0.25rem;
  margin-top: 1.75rem;
  font-size: var(--fs-xs);
}
.footer__contact a,
.footer__contact p {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  padding-block: 0.45rem;
  transition: color 0.3s;
}
.footer__contact a:hover {
  color: #fff;
}
.footer__contact svg {
  flex: none;
  margin-top: 0.125rem;
  color: rgb(255 255 255 / 0.5);
}
.footer__socials {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.75rem;
}
/* Square tiles now the labels are icons: the old pill was sized for text. */
.footer__socials a {
  display: grid;
  place-items: center;
  width: 2.375rem;
  height: 2.375rem;
  color: rgb(255 255 255 / 0.62);
  border: 1px solid rgb(255 255 255 / 0.15);
  border-radius: var(--r-md);
  transition: color 0.3s, background-color 0.3s, border-color 0.3s;
}
.footer__socials a:hover,
.footer__socials a:focus-visible {
  color: #fff;
  background: rgb(255 255 255 / 0.06);
  border-color: rgb(255 255 255 / 0.28);
}
.footer__socials svg {
  width: 1.0625rem;
  height: 1.0625rem;
}
.footer__col b {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #fff;
}
.footer__col ul {
  display: grid;
  gap: 0.125rem;
  margin-top: 1rem;
}
.footer__col a {
  display: block;
  padding-block: 0.4rem;   /* 32px row instead of a 18px text line */
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.62);
  transition: color 0.3s;
}
.footer__col a:hover {
  color: #fff;
}

.footer__bottom {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.75rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.55);
  border-top: 1px solid rgb(255 255 255 / 0.1);
}
@media (min-width: 768px) {
  .footer__bottom {
    flex-direction: row;
  }
}
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1.25rem;
}
.footer__legal a {
  transition: color 0.3s;
}
.footer__legal a:hover {
  color: #fff;
}

/* --------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

/* ==========================================================================
   Service page — WordPress Malware Removal
   ========================================================================== */

/* Page heroes stay natural height rather than filling the screen — they sit
   above real content — but the padding tracks the viewport so they don't run
   past the fold on a laptop the way a flat 7rem/10rem did. */
.hero--page {
  padding-top: clamp(2rem, 5vh, 5rem);
  padding-bottom: clamp(3rem, 8vh, 8rem);
}
@media (min-width: 1024px) {
  .hero--page {
    padding-top: clamp(2rem, 5vh, 7rem);
    padding-bottom: clamp(3rem, 8vh, 10rem);
  }
}
.hero--page .hero__horizon {
  height: 38%;
}
.hero--page h1 {
  font-size: clamp(2.3rem, 5.2vw, 4rem);
  line-height: 1.06;
}

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.56);
}
.breadcrumb a {
  transition: color 0.3s;
}
.breadcrumb a:hover {
  color: #fff;
}
.breadcrumb svg {
  width: 0.75rem;
  height: 0.75rem;
  opacity: 0.5;
}
.breadcrumb [aria-current] {
  color: rgb(255 255 255 / 0.85);
}

.hero__eyebrow {
  margin-top: 1.5rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.6);
}

/* Urgency strip — this page is what people land on mid-incident. */
.alert {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-top: 2.5rem;
  padding: 1rem 1.25rem;
  font-size: var(--fs-sm);
  color: rgb(255 255 255 / 0.75);
  background: rgb(253 109 44 / 0.1);
  border: 1px solid rgb(253 109 44 / 0.3);
  border-radius: var(--r-md);
}
.alert b {
  color: #fff;
}
.alert__pulse {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--brand-300);
  background: rgb(253 109 44 / 0.18);
  border-radius: var(--r-pill);
}
.alert__pulse::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(253 109 44 / 0.3);
  border-radius: var(--r-pill);
  animation: pulse-ring 3s ease-out infinite;
}
.alert a {
  color: var(--brand-300);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* --------------------------------------------------- sticky rail list -- */

.rail {
  display: grid;
  gap: 3rem;
}
@media (min-width: 1024px) {
  .rail {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 5rem;
  }
  .rail__aside {
    position: sticky;
    top: 8rem;
    align-self: start;
  }
}
.rail__aside h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.9rem, 4vw, 2.75rem);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.rail__aside p {
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

.rail__item {
  display: flex;
  gap: 1.25rem;
  padding-block: 1.75rem;
  border-top: 1px solid var(--line);
}
.rail__item:last-child {
  border-bottom: 1px solid var(--line);
}
.rail__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: background-color 0.4s, border-color 0.4s, transform 0.4s var(--ease-out-expo);
}
.rail__item:hover .rail__icon {
  transform: scale(1.06);
  background: var(--surface-2);
  border-color: var(--line-strong);
}
.rail__icon svg {
  width: 1.25rem;
  height: 1.25rem;
}
.rail__item h3 {
  margin-top: 0.6rem;
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.rail__item p {
  margin-top: 0.5rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* -------------------------------------------------- dark guarantee band -- */

.guarantee {
  position: relative;
  overflow: hidden;
  margin: 0.5rem;
  padding-block: 5rem;
  color: #fff;
  background: var(--night);
  border-radius: var(--radius-shell);
}
@media (min-width: 1024px) {
  .guarantee {
    padding-block: 7rem;
  }
}
.guarantee__glow {
  position: absolute;
  top: -30%;
  left: 50%;
  width: min(60rem, 130%);
  height: 34rem;
  transform: translateX(-50%);
  pointer-events: none;
  border-radius: 50%;
  filter: blur(40px);
  background: radial-gradient(
    ellipse at center,
    rgb(255 255 255 / 0.12),
    rgb(255 255 255 / 0.04) 45%,
    transparent 70%
  );
}
.guarantee__inner {
  position: relative;
}
.guarantee .eyebrow {
  color: rgb(255 255 255 / 0.65);
  background: rgb(255 255 255 / 0.08);
  border-color: rgb(255 255 255 / 0.18);
}
.guarantee h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.9rem, 4.2vw, 3rem);
  line-height: 1.08;
  font-weight: 600;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
.guarantee > .guarantee__inner > .section-head > p {
  color: rgb(255 255 255 / 0.6);
}

.g-grid {
  display: grid;
  gap: 1rem;
  margin-top: 3.5rem;
}
@media (min-width: 768px) {
  .g-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .g-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.g-card {
  height: 100%;
  padding: 1.75rem;
  background: rgb(255 255 255 / 0.03);
  border: 1px solid rgb(255 255 255 / 0.1);
  border-radius: var(--r-lg);
  transition: background-color 0.4s, border-color 0.4s, transform 0.4s var(--ease-out-expo);
}
.g-card:hover {
  transform: translateY(-2px);
  background: rgb(255 255 255 / 0.05);
  border-color: rgb(255 255 255 / 0.24);
}
.g-card__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: rgb(255 255 255 / 0.7);
  background: rgb(255 255 255 / 0.08);
  border: 1px solid rgb(255 255 255 / 0.16);
  border-radius: var(--r-md);
}
.g-card__icon svg {
  width: 1.125rem;
  height: 1.125rem;
}
.g-card h3 {
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.g-card p {
  margin-top: 0.625rem;
  font-size: var(--fs-xs);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.55);
}

.guarantee__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 3rem;
}

/* ==========================================================================
   About · Contact · Emergency · Archive · Single
   ========================================================================== */

/* ------------------------------------------------------------ page hero -- */

.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-inline: 0.5rem;
  padding-block: 3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-shell);
}
/* The dark hero carries a fine grid; without it the light one reads as an
   empty grey slab. Same 64px rhythm, drawn in ink and masked so it fades out
   before it reaches the copy. A pseudo-element keeps it out of the markup,
   which eight templates share. */
.page-hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgb(31 34 37 / 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(31 34 37 / 0.045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(900px circle at 15% 0%, #fff, transparent 70%);
  mask-image: radial-gradient(900px circle at 15% 0%, #fff, transparent 70%);
}
@media (min-width: 640px) {
  .page-hero {
    padding-block: 4.5rem;
  }
}
@media (min-width: 1024px) {
  .page-hero {
    padding-block: 7rem;
  }
}
.page-hero__glow {
  position: absolute;
  top: -60%;
  left: 50%;
  width: min(60rem, 130%);
  height: 32rem;
  transform: translateX(-50%);
  pointer-events: none;
  border-radius: 50%;
  filter: blur(40px);
  background: radial-gradient(ellipse at center, rgb(16 24 40 / 0.05), transparent 70%);
}
/* No max-width here: the block is a .container, and capping it at 52rem both
   wrapped the title early and — because .container centres itself — pushed the
   whole hero out of alignment with the header and the sections below. The lede
   carries its own 40rem measure, so only the headline gains the width. */
.page-hero__inner {
  position: relative;
}
.page-hero h1 {
  margin-top: 1.25rem;
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  line-height: 1.06;
  font-weight: 600;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.page-hero__lede {
  margin-top: 1.5rem;
  max-width: 40rem;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--muted);
  text-wrap: pretty;
}
.page-hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.5rem;
}
.breadcrumb--light {
  color: var(--subtle);
}
.breadcrumb--light a:hover {
  color: var(--fg);
}
.breadcrumb--light [aria-current] {
  color: var(--subtle);
}

/* --------------------------------------------------------------- about -- */

.story {
  display: grid;
  gap: 2.5rem 3rem;
  margin-top: 4rem;
}
@media (min-width: 768px) {
  .story {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.story__item {
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.story__item h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.story__item p {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}
.story__item--wide {
  grid-column: 1 / -1;
}

.figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  margin-top: 4rem;
  background: rgb(255 255 255 / 0.1);
  border: 1px solid rgb(255 255 255 / 0.1);
  border-radius: var(--r-lg);
}
@media (min-width: 1024px) {
  .figures {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.figures > div {
  padding: 2rem 1.75rem;
  background: var(--night);
}
.figures b {
  display: block;
  font-size: clamp(1.8rem, 3.4vw, 2.4rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
/* Direct child only — the counter is a nested <span> inside <b>. */
.figures > div > span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.5);
}
.figures p {
  margin-top: 0.75rem;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: rgb(255 255 255 / 0.55);
}

.values {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}
@media (min-width: 640px) {
  .values {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .values {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------- contact -- */

.contact-grid {
  display: grid;
  gap: 3rem;
}
@media (min-width: 1024px) {
  .contact-grid {
    grid-template-columns: 1.15fr 0.85fr;
    gap: 4rem;
  }
}

.form {
  padding: 2rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
@media (min-width: 640px) {
  .form {
    padding: 2.5rem;
  }
}
.form__row {
  display: grid;
  gap: 1.25rem;
}
@media (min-width: 640px) {
  .form__row--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.form__row + .form__row {
  margin-top: 1.25rem;
}
.field label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--fg);
}
.field small {
  font-size: var(--fs-2xs);
  font-weight: 400;
  color: var(--subtle);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.75rem 1rem;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color 0.3s, background-color 0.3s, box-shadow 0.3s;
}
.field textarea {
  min-height: 8rem;
  resize: vertical;
}
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23808285' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.75rem;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  background: #fff;
  border-color: var(--ink-800);
  box-shadow: 0 0 0 3px rgb(31 34 37 / 0.1);
}
.form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.75rem;
}
.form__note {
  font-size: var(--fs-xs);
  color: var(--subtle);
}
.hp {
  position: absolute;
  left: -9999px;
}

.info-card {
  padding: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.info-card + .info-card {
  margin-top: 1rem;
}
.info-card h3 {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--fs-sm);
  font-weight: 600;
}
.info-card h3 svg {
  color: var(--muted);
}
.info-card ul {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  color: var(--muted);
}
.info-card a:hover {
  color: var(--ink-900);
}
.info-card p {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* ------------------------------------------------------------- archive -- */

.filters {
  display: flex;
  gap: 0.5rem;
  margin-top: 3rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line);
  /* One horizontal rail on small screens instead of three wrapped rows. */
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.filters::-webkit-scrollbar {
  display: none;
}
.filter {
  flex: none;
  scroll-snap-align: start;
}
@media (min-width: 768px) {
  .filters {
    flex-wrap: wrap;
    overflow-x: visible;
  }
}
.filter {
  padding: 0.5rem 1rem;
  font-size: var(--fs-xs);
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.filter:hover {
  border-color: var(--line-strong);
  color: var(--ink-900);
}
.filter.is-active {
  color: var(--on-brand);
  font-weight: 600;
  background: var(--brand-400);
  border-color: var(--brand-500);
}

.posts {
  display: grid;
  gap: 1rem;
  margin-top: 2.5rem;
}
@media (min-width: 640px) {
  .posts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .posts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.post[hidden] {
  display: none;
}

.post__type {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.post__type svg {
  width: 0.75rem;
  height: 0.75rem;
}
.post h3 {
  margin-top: 1.25rem;
  font-size: var(--fs-md);
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.post__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-top: auto;
  padding-top: 1.5rem;
  font-size: var(--fs-2xs);
  color: var(--subtle);
  border-top: 1px solid var(--line);
}
.post__meta span {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.post__meta svg {
  width: 0.875rem;
  height: 0.875rem;
}

.archive__empty {
  padding: 4rem 0;
  text-align: center;
  color: var(--subtle);
}
.archive__empty[hidden] {
  display: none;
}

/* -------------------------------------------------------------- single -- */

.article {
  display: grid;
  gap: 3rem;
}
@media (min-width: 1024px) {
  .article {
    /* Columns sized to their content so there is no dead gutter between the
       capped prose measure and the sidebar. */
    grid-template-columns: minmax(0, 38rem) minmax(0, 16rem);
    justify-content: space-between;
    gap: 4rem;
    align-items: start;
  }
}
.article__aside {
  display: none;
}
@media (min-width: 1024px) {
  .article__aside {
    display: block;
    position: sticky;
    top: 8rem;
  }
}
.toc b {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--subtle);
}
.toc ul {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.25rem;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
}
.toc a {
  font-size: var(--fs-xs);
  color: var(--muted);
  transition: color 0.3s;
}
.toc a:hover {
  color: var(--ink-900);
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-bottom: 2rem;
  margin-bottom: 2.5rem;
  font-size: var(--fs-xs);
  color: var(--subtle);
  border-bottom: 1px solid var(--line);
}
.article__meta span {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.article__author {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  color: var(--fg);
  font-weight: 500;
}
.article__avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: #fff;
  background-image: linear-gradient(to bottom right, var(--ink-800), var(--night));
  border-radius: var(--r-pill);
}

.prose {
  max-width: 38rem;   /* ~68 characters; was 44rem / ~85 */
  font-size: var(--fs-md);
  line-height: 1.75;
  color: var(--muted);
}
.prose > * + * {
  margin-top: 1.5rem;
}
.prose h2 {
  margin-top: 3rem;
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
  scroll-margin-top: 7rem;
}
.prose h3 {
  margin-top: 2.25rem;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--fg);
}
.prose strong {
  font-weight: 600;
  color: var(--fg);
}
.prose ul {
  display: grid;
  gap: 0.75rem;
  padding-left: 0;
}
.prose li {
  position: relative;
  padding-left: 1.75rem;
}
.prose li::before {
  content: "";
  position: absolute;
  top: 0.7em;
  left: 0.25rem;
  width: 0.375rem;
  height: 0.375rem;
  background: var(--line-strong);
  border-radius: var(--r-pill);
}
.prose blockquote {
  padding: 1.5rem 1.75rem;
  font-size: var(--fs-md);
  color: var(--fg);
  background: var(--surface);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 1rem 1rem 0;
}
.prose code {
  padding: 0.15em 0.4em;
  font-family: ui-monospace, "SF Mono", monospace;
  font-size: 0.9em;
  color: var(--ink-900);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.prose pre {
  padding: 1.25rem 1.5rem;
  overflow-x: auto;
  font-family: ui-monospace, "SF Mono", monospace;
  font-size: var(--fs-xs);
  line-height: 1.7;
  color: rgb(255 255 255 / 0.85);
  background: var(--night);
  border-radius: var(--r-md);
}
.prose pre code {
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
}
.prose a:not(.btn) {
  color: var(--ink-900);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.article__share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
  font-size: var(--fs-xs);
  color: var(--subtle);
}

/* ==========================================================================
   Per-type archives and singles
   ========================================================================== */

/* --------------------------------------------------- featured (blog) ---- */

.featured {
  display: grid;
  gap: 0;
  overflow: hidden;
  margin-top: 2.5rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.featured:hover {
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
@media (min-width: 900px) {
  .featured {
    grid-template-columns: 1.1fr 0.9fr;
    align-items: center;
  }
}
.featured__body {
  padding: 2.25rem;
}
@media (min-width: 900px) {
  .featured__body {
    padding: 3rem;
  }
}
.featured h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.featured p {
  margin-top: 1rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}
.featured__art {
  position: relative;
  overflow: hidden;
  min-height: 15rem;
  background: var(--night);
}
.featured__art::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 60% 120%, rgb(255 255 255 / 0.12), transparent 60%),
    linear-gradient(to right, rgb(255 255 255 / 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.04) 1px, transparent 1px);
  background-size: cover, 40px 40px, 40px 40px;
}
.featured__art span {
  position: absolute;
  inset-inline: 0;
  bottom: -0.35em;
  text-align: center;
  font-size: clamp(3rem, 9vw, 6rem);
  font-weight: 600;
  letter-spacing: -0.05em;
  color: rgb(255 255 255 / 0.06);
}

/* -------------------------------------------- spec list (case/research) -- */

.speclist {
  display: grid;
  gap: 0.875rem;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.speclist div {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: 1rem;
  font-size: var(--fs-xs);
}
.speclist dt {
  font-weight: 500;
  color: var(--subtle);
}
.speclist dd {
  color: var(--muted);
}

/* ------------------------------------------------- wide archive rows ---- */

.rows {
  display: grid;
  gap: 1rem;
  margin-top: 2.5rem;
}

.row-card {
  position: relative;
  display: grid;
  gap: 2rem;
  padding: 2rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.row-card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
@media (min-width: 900px) {
  .row-card {
    grid-template-columns: minmax(0, 1fr) 15rem;
    padding: 2.5rem;
  }
  /* No metric block to sit in it, so no second track. */
  .row-card--solo {
    grid-template-columns: minmax(0, 1fr);
  }
  .row-card--doc {
    grid-template-columns: 3.5rem minmax(0, 1fr) 10rem;
    align-items: start;
  }
}
.row-card h3 {
  margin-top: 1rem;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.row-card > div > p {
  margin-top: 0.875rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

.outcome {
  align-self: center;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.outcome b {
  display: block;
  font-size: 1.6rem;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.outcome span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-2xs);
  line-height: 1.45;
  color: var(--muted);
}

.row-card__num {
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--line-strong);
  font-variant-numeric: tabular-nums;
  transition: color 0.4s;
}
.row-card:hover .row-card__num {
  color: var(--ink-900);
}
.row-card__go {
  align-self: center;
  justify-self: start;
}

/* --------------------------------------------------------- guide rows -- */

.guides-list {
  display: grid;
  gap: 0;
  margin-top: 2.5rem;
  border-top: 1px solid var(--line);
}
.guide-item {
  display: grid;
  gap: 0.75rem 1.5rem;
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.3s;
}
@media (min-width: 768px) {
  .guide-item {
    grid-template-columns: 3rem minmax(0, 1fr) 8rem;
    align-items: center;
  }
}
.guide-item:hover {
  background: var(--surface);
}
.guide-item__num {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--subtle);
  font-variant-numeric: tabular-nums;
}
.guide-item h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.guide-item p {
  margin-top: 0.375rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* ------------------------------------------------- metric band (single) -- */

.metrics-band {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  margin-top: 2.5rem;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
@media (min-width: 768px) {
  /* One track per cell, not a fixed four. The band carries between one and
     four figures depending on what the post type records, and the fixed grid
     left the unused tracks showing as empty grey panels. */
  .metrics-band {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
}
.metrics-band > div {
  padding: 1.75rem 1.5rem;
  background: #fff;
}
.metrics-band b {
  display: block;
  font-size: 1.6rem;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.metrics-band span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-2xs);
  line-height: 1.45;
  color: var(--subtle);
}

/* ------------------------------------------------------ abstract block -- */

.abstract {
  padding: 1.75rem 2rem;
  margin-bottom: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 1rem 1rem 0;
}
.abstract b {
  display: block;
  margin-bottom: 0.625rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-900);
}
.abstract p {
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

/* --------------------------------------------------------- steps list -- */

.steps {
  counter-reset: step;
  display: grid;
  gap: 1rem;
}
.steps li {
  counter-increment: step;
  position: relative;
  padding: 1.5rem 1.5rem 1.5rem 4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.steps li::before {
  content: counter(step);
  position: absolute;
  top: 1.5rem;
  left: 1.25rem;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--on-brand);
  background: var(--line-strong);
  border-radius: var(--r-pill);
}
.steps b {
  display: block;
  margin-bottom: 0.375rem;
  color: var(--fg);
}

/* In the narrow article sidebar the two-column spec list wraps badly. */
.info-card .speclist div {
  grid-template-columns: minmax(0, 1fr);
  gap: 0.125rem;
}
.info-card .speclist dd {
  color: var(--fg);
}

/* ---------------------------------------------------------- client grid -- */

.logogrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 3rem 2.5rem;
  max-width: 58rem;
  margin: 3rem auto 0;
}
@media (min-width: 768px) {
  .logogrid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4rem 3rem;
    margin-top: 4rem;
  }
}
.logogrid img {
  width: 100%;
  height: 2rem;
  object-fit: contain;
  /* Uniform monochrome wall so 25 brand palettes don't fight the orange;
     true colour on hover. */
  filter: grayscale(1) contrast(1.15) opacity(0.7);
  transition: filter 0.4s var(--ease-out-expo);
}
@media (min-width: 768px) {
  .logogrid img {
    height: 2.25rem;
  }
}
.logogrid img:hover {
  filter: none;
}
/* Six on small screens, the full set from md up. */
.logogrid li:nth-child(n + 7) {
  display: none;
}
@media (min-width: 768px) {
  .logogrid li:nth-child(n + 7) {
    display: block;
  }
}

.logogrid__more {
  margin-top: 3rem;
  font-size: var(--fs-sm);
  text-align: center;
  color: var(--subtle);
}
@media (min-width: 768px) {
  .logogrid__more {
    margin-top: 4rem;
  }
}

/* ==========================================================================
   About · Contact · Emergency · Archive · Single
   ========================================================================== */

/* ------------------------------------------------------------ page hero -- */

.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-inline: 0.5rem;
  padding-block: 3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-shell);
}
/* The dark hero carries a fine grid; without it the light one reads as an
   empty grey slab. Same 64px rhythm, drawn in ink and masked so it fades out
   before it reaches the copy. A pseudo-element keeps it out of the markup,
   which eight templates share. */
.page-hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgb(31 34 37 / 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(31 34 37 / 0.045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(900px circle at 15% 0%, #fff, transparent 70%);
  mask-image: radial-gradient(900px circle at 15% 0%, #fff, transparent 70%);
}
@media (min-width: 640px) {
  .page-hero {
    padding-block: 4.5rem;
  }
}
@media (min-width: 1024px) {
  .page-hero {
    padding-block: 7rem;
  }
}
.page-hero__glow {
  position: absolute;
  top: -60%;
  left: 50%;
  width: min(60rem, 130%);
  height: 32rem;
  transform: translateX(-50%);
  pointer-events: none;
  border-radius: 50%;
  filter: blur(40px);
  background: radial-gradient(ellipse at center, rgb(16 24 40 / 0.05), transparent 70%);
}
/* No max-width here: the block is a .container, and capping it at 52rem both
   wrapped the title early and — because .container centres itself — pushed the
   whole hero out of alignment with the header and the sections below. The lede
   carries its own 40rem measure, so only the headline gains the width. */
.page-hero__inner {
  position: relative;
}
.page-hero h1 {
  margin-top: 1.25rem;
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  line-height: 1.06;
  font-weight: 600;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.page-hero__lede {
  margin-top: 1.5rem;
  max-width: 40rem;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--muted);
  text-wrap: pretty;
}
.page-hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.5rem;
}
.breadcrumb--light {
  color: var(--subtle);
}
.breadcrumb--light a:hover {
  color: var(--fg);
}
.breadcrumb--light [aria-current] {
  color: var(--subtle);
}

/* --------------------------------------------------------------- about -- */

.story {
  display: grid;
  gap: 2.5rem 3rem;
  margin-top: 4rem;
}
@media (min-width: 768px) {
  .story {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.story__item {
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.story__item h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.story__item p {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}
.story__item--wide {
  grid-column: 1 / -1;
}

.figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  margin-top: 4rem;
  background: rgb(255 255 255 / 0.1);
  border: 1px solid rgb(255 255 255 / 0.1);
  border-radius: var(--r-lg);
}
@media (min-width: 1024px) {
  .figures {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.figures > div {
  padding: 2rem 1.75rem;
  background: var(--night);
}
.figures b {
  display: block;
  font-size: clamp(1.8rem, 3.4vw, 2.4rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
/* Direct child only — the counter is a nested <span> inside <b>. */
.figures > div > span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.5);
}
.figures p {
  margin-top: 0.75rem;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: rgb(255 255 255 / 0.55);
}

.values {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}
@media (min-width: 640px) {
  .values {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .values {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------- contact -- */

.contact-grid {
  display: grid;
  gap: 3rem;
}
@media (min-width: 1024px) {
  .contact-grid {
    grid-template-columns: 1.15fr 0.85fr;
    gap: 4rem;
  }
}

.form {
  padding: 2rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
@media (min-width: 640px) {
  .form {
    padding: 2.5rem;
  }
}
.form__row {
  display: grid;
  gap: 1.25rem;
}
@media (min-width: 640px) {
  .form__row--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.form__row + .form__row {
  margin-top: 1.25rem;
}
.field label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--fg);
}
.field small {
  font-size: var(--fs-2xs);
  font-weight: 400;
  color: var(--subtle);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.75rem 1rem;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color 0.3s, background-color 0.3s, box-shadow 0.3s;
}
.field textarea {
  min-height: 8rem;
  resize: vertical;
}
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23808285' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.75rem;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  background: #fff;
  border-color: var(--ink-800);
  box-shadow: 0 0 0 3px rgb(31 34 37 / 0.1);
}
.form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.75rem;
}
.form__note {
  font-size: var(--fs-xs);
  color: var(--subtle);
}
.hp {
  position: absolute;
  left: -9999px;
}

.info-card {
  padding: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.info-card + .info-card {
  margin-top: 1rem;
}
.info-card h3 {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--fs-sm);
  font-weight: 600;
}
.info-card h3 svg {
  color: var(--muted);
}
.info-card ul {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
  color: var(--muted);
}
.info-card a:hover {
  color: var(--ink-900);
}
.info-card p {
  margin-top: 0.75rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* ------------------------------------------------------------- archive -- */

.filters {
  display: flex;
  gap: 0.5rem;
  margin-top: 3rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line);
  /* One horizontal rail on small screens instead of three wrapped rows. */
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.filters::-webkit-scrollbar {
  display: none;
}
.filter {
  flex: none;
  scroll-snap-align: start;
}
@media (min-width: 768px) {
  .filters {
    flex-wrap: wrap;
    overflow-x: visible;
  }
}
.filter {
  padding: 0.5rem 1rem;
  font-size: var(--fs-xs);
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.filter:hover {
  border-color: var(--line-strong);
  color: var(--ink-900);
}
.filter.is-active {
  color: var(--on-brand);
  font-weight: 600;
  background: var(--brand-400);
  border-color: var(--brand-500);
}

.posts {
  display: grid;
  gap: 1rem;
  margin-top: 2.5rem;
}
@media (min-width: 640px) {
  .posts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .posts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.post[hidden] {
  display: none;
}

.post__type {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.post__type svg {
  width: 0.75rem;
  height: 0.75rem;
}
.post h3 {
  margin-top: 1.25rem;
  font-size: var(--fs-md);
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.post__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-top: auto;
  padding-top: 1.5rem;
  font-size: var(--fs-2xs);
  color: var(--subtle);
  border-top: 1px solid var(--line);
}
.post__meta span {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.post__meta svg {
  width: 0.875rem;
  height: 0.875rem;
}

.archive__empty {
  padding: 4rem 0;
  text-align: center;
  color: var(--subtle);
}
.archive__empty[hidden] {
  display: none;
}

/* -------------------------------------------------------------- single -- */

.article {
  display: grid;
  gap: 3rem;
}
@media (min-width: 1024px) {
  .article {
    /* Columns sized to their content so there is no dead gutter between the
       capped prose measure and the sidebar. */
    grid-template-columns: minmax(0, 38rem) minmax(0, 16rem);
    justify-content: space-between;
    gap: 4rem;
    align-items: start;
  }
}
.article__aside {
  display: none;
}
@media (min-width: 1024px) {
  .article__aside {
    display: block;
    position: sticky;
    top: 8rem;
  }
}
.toc b {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--subtle);
}
.toc ul {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.25rem;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
}
.toc a {
  font-size: var(--fs-xs);
  color: var(--muted);
  transition: color 0.3s;
}
.toc a:hover {
  color: var(--ink-900);
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-bottom: 2rem;
  margin-bottom: 2.5rem;
  font-size: var(--fs-xs);
  color: var(--subtle);
  border-bottom: 1px solid var(--line);
}
.article__meta span {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.article__author {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  color: var(--fg);
  font-weight: 500;
}
.article__avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: #fff;
  background-image: linear-gradient(to bottom right, var(--ink-800), var(--night));
  border-radius: var(--r-pill);
}

.prose {
  max-width: 38rem;   /* ~68 characters; was 44rem / ~85 */
  font-size: var(--fs-md);
  line-height: 1.75;
  color: var(--muted);
}
.prose > * + * {
  margin-top: 1.5rem;
}
.prose h2 {
  margin-top: 3rem;
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
  scroll-margin-top: 7rem;
}
.prose h3 {
  margin-top: 2.25rem;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--fg);
}
.prose strong {
  font-weight: 600;
  color: var(--fg);
}
.prose ul {
  display: grid;
  gap: 0.75rem;
  padding-left: 0;
}
.prose li {
  position: relative;
  padding-left: 1.75rem;
}
.prose li::before {
  content: "";
  position: absolute;
  top: 0.7em;
  left: 0.25rem;
  width: 0.375rem;
  height: 0.375rem;
  background: var(--line-strong);
  border-radius: var(--r-pill);
}
.prose blockquote {
  padding: 1.5rem 1.75rem;
  font-size: var(--fs-md);
  color: var(--fg);
  background: var(--surface);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 1rem 1rem 0;
}
.prose code {
  padding: 0.15em 0.4em;
  font-family: ui-monospace, "SF Mono", monospace;
  font-size: 0.9em;
  color: var(--ink-900);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.prose pre {
  padding: 1.25rem 1.5rem;
  overflow-x: auto;
  font-family: ui-monospace, "SF Mono", monospace;
  font-size: var(--fs-xs);
  line-height: 1.7;
  color: rgb(255 255 255 / 0.85);
  background: var(--night);
  border-radius: var(--r-md);
}
.prose pre code {
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
}
.prose a:not(.btn) {
  color: var(--ink-900);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.article__share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
  font-size: var(--fs-xs);
  color: var(--subtle);
}

/* ==========================================================================
   Per-type archives and singles
   ========================================================================== */

/* --------------------------------------------------- featured (blog) ---- */

.featured {
  display: grid;
  gap: 0;
  overflow: hidden;
  margin-top: 2.5rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.featured:hover {
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
@media (min-width: 900px) {
  .featured {
    grid-template-columns: 1.1fr 0.9fr;
    align-items: center;
  }
}
.featured__body {
  padding: 2.25rem;
}
@media (min-width: 900px) {
  .featured__body {
    padding: 3rem;
  }
}
.featured h2 {
  margin-top: 1.25rem;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.featured p {
  margin-top: 1rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}
.featured__art {
  position: relative;
  overflow: hidden;
  min-height: 15rem;
  background: var(--night);
}
.featured__art::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 60% 120%, rgb(255 255 255 / 0.12), transparent 60%),
    linear-gradient(to right, rgb(255 255 255 / 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 255 255 / 0.04) 1px, transparent 1px);
  background-size: cover, 40px 40px, 40px 40px;
}
.featured__art span {
  position: absolute;
  inset-inline: 0;
  bottom: -0.35em;
  text-align: center;
  font-size: clamp(3rem, 9vw, 6rem);
  font-weight: 600;
  letter-spacing: -0.05em;
  color: rgb(255 255 255 / 0.06);
}

/* -------------------------------------------- spec list (case/research) -- */

.speclist {
  display: grid;
  gap: 0.875rem;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.speclist div {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: 1rem;
  font-size: var(--fs-xs);
}
.speclist dt {
  font-weight: 500;
  color: var(--subtle);
}
.speclist dd {
  color: var(--muted);
}

/* ------------------------------------------------- wide archive rows ---- */

.rows {
  display: grid;
  gap: 1rem;
  margin-top: 2.5rem;
}

.row-card {
  position: relative;
  display: grid;
  gap: 2rem;
  padding: 2rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.row-card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
@media (min-width: 900px) {
  .row-card {
    grid-template-columns: minmax(0, 1fr) 15rem;
    padding: 2.5rem;
  }
  /* No metric block to sit in it, so no second track. */
  .row-card--solo {
    grid-template-columns: minmax(0, 1fr);
  }
  .row-card--doc {
    grid-template-columns: 3.5rem minmax(0, 1fr) 10rem;
    align-items: start;
  }
}
.row-card h3 {
  margin-top: 1rem;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.row-card > div > p {
  margin-top: 0.875rem;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

.outcome {
  align-self: center;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.outcome b {
  display: block;
  font-size: 1.6rem;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.outcome span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-2xs);
  line-height: 1.45;
  color: var(--muted);
}

.row-card__num {
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--line-strong);
  font-variant-numeric: tabular-nums;
  transition: color 0.4s;
}
.row-card:hover .row-card__num {
  color: var(--ink-900);
}
.row-card__go {
  align-self: center;
  justify-self: start;
}

/* --------------------------------------------------------- guide rows -- */

.guides-list {
  display: grid;
  gap: 0;
  margin-top: 2.5rem;
  border-top: 1px solid var(--line);
}
.guide-item {
  display: grid;
  gap: 0.75rem 1.5rem;
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.3s;
}
@media (min-width: 768px) {
  .guide-item {
    grid-template-columns: 3rem minmax(0, 1fr) 8rem;
    align-items: center;
  }
}
.guide-item:hover {
  background: var(--surface);
}
.guide-item__num {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--subtle);
  font-variant-numeric: tabular-nums;
}
.guide-item h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.guide-item p {
  margin-top: 0.375rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* ------------------------------------------------- metric band (single) -- */

.metrics-band {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  margin-top: 2.5rem;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
@media (min-width: 768px) {
  /* One track per cell, not a fixed four. The band carries between one and
     four figures depending on what the post type records, and the fixed grid
     left the unused tracks showing as empty grey panels. */
  .metrics-band {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
}
.metrics-band > div {
  padding: 1.75rem 1.5rem;
  background: #fff;
}
.metrics-band b {
  display: block;
  font-size: 1.6rem;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.metrics-band span {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--fs-2xs);
  line-height: 1.45;
  color: var(--subtle);
}

/* ------------------------------------------------------ abstract block -- */

.abstract {
  padding: 1.75rem 2rem;
  margin-bottom: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 1rem 1rem 0;
}
.abstract b {
  display: block;
  margin-bottom: 0.625rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-900);
}
.abstract p {
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--muted);
}

/* --------------------------------------------------------- steps list -- */

.steps {
  counter-reset: step;
  display: grid;
  gap: 1rem;
}
.steps li {
  counter-increment: step;
  position: relative;
  padding: 1.5rem 1.5rem 1.5rem 4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.steps li::before {
  content: counter(step);
  position: absolute;
  top: 1.5rem;
  left: 1.25rem;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--on-brand);
  background: var(--line-strong);
  border-radius: var(--r-pill);
}
.steps b {
  display: block;
  margin-bottom: 0.375rem;
  color: var(--fg);
}

/* In the narrow article sidebar the two-column spec list wraps badly. */
.info-card .speclist div {
  grid-template-columns: minmax(0, 1fr);
  gap: 0.125rem;
}
.info-card .speclist dd {
  color: var(--fg);
}

/* ---------------------------------------------------------- client wall -- */

/* -------------------------------------------------------- trust factors -- */

.trust-grid {
  display: grid;
  gap: 1rem;
  margin-top: 3rem;
}
@media (min-width: 640px) {
  .trust-grid {
    gap: 1.25rem;
    margin-top: 4rem;
  }
}
@media (min-width: 1024px) {
  .trust-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.trust-card {
  display: flex;
  flex-direction: column;
  padding: 1.75rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
@media (min-width: 640px) {
  .trust-card {
    padding: 2rem;
  }
}

.trust-card__title {
  margin-top: 1.25rem;
  font-size: var(--fs-md);
  line-height: 1.45;
  font-weight: 600;
  letter-spacing: -0.015em;
  text-wrap: pretty;
}

/* The checklist is the proof under each claim, so it sits against the bottom
   of the card and the three line up regardless of headline length. */
.trust-card .points {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-strong);
}
.trust-card .points li {
  color: var(--muted);
}

/* Marker-pen highlight. Brand orange is only 2.84:1 as text, so it is used as
   a fill with the darkest ink on top — 10.8:1. box-decoration-break keeps the
   padding on every line when the phrase wraps. */
.hl {
  padding: 0.1em 0.25em;
  color: var(--ink-900);
  background: var(--line-strong);
  border-radius: 0.25rem;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* --------------------------------------------------- cta underline -- */

/* Marker underline on the headline number, in brand rather than the
   reference's yellow. Drawn as an inset shadow so it sits behind descenders
   instead of pushing the line box taller the way a border would. */
.cta__underline {
  box-shadow: inset 0 -0.2em 0 var(--brand-300);
}

/* Single-line reassurance under a CTA — replaces the three-column contact
   block, whose phone/email/address duplicated the footer directly below. */
.cta__note {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.5rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.cta__note svg {
  width: 1rem;
  height: 1rem;
  color: var(--subtle);
}

/* Imported service headlines vary from 49 to 116 characters. One display size
   cannot serve both, so it steps down as the headline grows — set from the
   template, which is the only place the length is known. */
.hero--page-long h1 {
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  line-height: 1.12;
}
.hero--page-xlong h1 {
  font-size: clamp(1.7rem, 2.7vw, 2.1rem);
  line-height: 1.18;
  letter-spacing: -0.02em;
}

/* A card with no bullet list sitting beside cards that have them gets stretched
   into a mostly empty box by the grid. Centre what little it has and give it
   something to do. */
.card--callout {
  justify-content: center;
  align-items: center;
  text-align: center;
}
.card--callout .card__body {
  max-width: 28rem;
}
.card--callout .card__cta {
  margin-top: 1.5rem;
}

/* ------------------------------------------------ case study row media -- */

/* With a featured image the row becomes shot-left, record-right, matching how
   the case studies read on the live site. */
.row-card__media {
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.row-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
@media (min-width: 900px) {
  .row-card--media {
    grid-template-columns: 20rem minmax(0, 1fr);
    align-items: start;
  }
  /* The image column already carries the eye, so the record starts flush. */
  .row-card--media > div > .post__type {
    margin-top: 0;
  }
}

/* On a phone the 8.5rem label column leaves barely half the row for the value,
   so a long outcome wraps to a ribbon. Stack label over value instead. */
@media (max-width: 599px) {
  .speclist div {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.125rem;
  }
  .speclist dd {
    color: var(--fg);
  }
}

/* ---------------------------------------------------- case study rows -- */

/* The shot fills the full height of the row rather than floating in the top
   half, so the two columns read as one composed block. */
@media (min-width: 900px) {
  .row-card--case {
    grid-template-columns: 22rem minmax(0, 1fr);
    align-items: stretch;
    gap: 2.25rem;
  }
  .row-card--case .row-card__media {
    height: 100%;
  }
}
.row-card--case > div {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.case-row__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.case-row__duration {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--subtle);
}
.case-row__duration svg {
  width: 0.875rem;
  height: 0.875rem;
}

.case-row__solution {
  margin-top: 0.875rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}

/* The result is the reason to read the study, so it gets its own panel rather
   than a fourth identical row in a definition list. */
.case-outcome {
  width: 100%;
  margin-top: 1.25rem;
  padding: 0.875rem 1rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.case-outcome__label {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
}
.case-outcome__label svg {
  width: 0.875rem;
  height: 0.875rem;
}
.case-outcome p {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  line-height: 1.55;
  font-weight: 500;
  color: var(--fg);
}

/* Pushed to the bottom so the call to action lines up across rows. */
.case-row__go {
  margin-top: auto;
  padding-top: 1.25rem;
  font-size: var(--fs-xs);
}

/* ==================================================== case studies -- */

.cases {
  display: grid;
  gap: 3rem;
}
@media (min-width: 900px) {
  .cases {
    gap: 4.5rem;
  }
}

/* -- featured study -------------------------------------------------------
   Dark panel, same vocabulary as the hero and the guarantee band, so the page
   opens with weight rather than a seventh identical row. */
.case-feature {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  gap: 0;
  color: #fff;
  background: var(--night);
  border-radius: var(--radius-shell);
}
@media (min-width: 900px) {
  .case-feature {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: stretch;
  }
}
.case-feature__glow {
  position: absolute;
  z-index: -1;
  bottom: -40%;
  left: -10%;
  width: 60%;
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(60px);
  background: radial-gradient(circle, rgb(255 255 255 / 0.1), transparent 70%);
  pointer-events: none;
}
.case-feature__body {
  padding: 2.25rem;
}
@media (min-width: 900px) {
  .case-feature__body {
    padding: 2.5rem;
    align-self: center;
  }
}
.case-feature .eyebrow {
  color: rgb(255 255 255 / 0.65);
  background: rgb(255 255 255 / 0.08);
  border-color: rgb(255 255 255 / 0.18);
}
.case-feature h2 {
  margin-top: 0.875rem;
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.case-feature__lede {
  margin-top: 0.75rem;
  max-width: 34rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: rgb(255 255 255 / 0.68);
}
.case-feature__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.5rem;
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgb(255 255 255 / 0.12);
}
.case-feature__facts dt {
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.5);
}
.case-feature__facts dd {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  font-weight: 500;
}
.case-feature__outcome {
  display: flex;
  gap: 0.625rem;
  margin-top: 1.125rem;
  padding: 0.75rem 0.875rem;
  font-size: var(--fs-xs);
  line-height: 1.5;
  font-weight: 500;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: var(--r-md);
}
.case-feature__outcome svg {
  flex: none;
  width: 1rem;
  height: 1rem;
  margin-top: 0.1rem;
  color: rgb(255 255 255 / 0.7);
}
.case-feature__go {
  margin-top: 1.5rem;
}
.case-feature__media {
  overflow: hidden;
}
/* Stacked, the shot should lead — the panel opens on the image, not on a
   block of text with a picture tacked underneath. */
@media (max-width: 899px) {
  .case-feature__media {
    order: -1;
  }
  .case-feature__media img {
    aspect-ratio: 16 / 10;
    min-height: 0;
  }
}
.case-feature__media img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 15rem;
  object-fit: cover;
  transition: transform 0.7s var(--ease-out-expo);
}
.case-feature:hover .case-feature__media img {
  transform: scale(1.04);
}

/* -- the rest -------------------------------------------------------------
   No card chrome. Alternating sides give the list rhythm, and a hairline
   separates each study instead of boxing it. */
.case-item {
  display: grid;
  gap: 1.5rem;
  padding-top: 3rem;
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .case-item {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
    align-items: center;
    padding-top: 4.5rem;
  }
  /* Flip every other study so the eye zig-zags down the page. */
  .case-item:nth-child(odd) .case-item__media {
    order: 2;
  }
}
.case-item__media {
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.case-item__media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 0.7s var(--ease-out-expo);
}
.case-item:hover .case-item__media img {
  transform: scale(1.04);
}
.case-item__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.case-item h3 {
  margin-top: 1rem;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.case-item:hover h3 {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.case-item__solution {
  margin-top: 0.875rem;
  font-size: var(--fs-sm);
  line-height: 1.65;
  color: var(--muted);
}
.case-item__go {
  display: inline-flex;
  margin-top: 1.25rem;
  font-size: var(--fs-xs);
}

@media (prefers-reduced-motion: reduce) {
  .case-feature__media img,
  .case-item__media img {
    transition: none;
  }
  .case-feature:hover .case-feature__media img,
  .case-item:hover .case-item__media img {
    transform: none;
  }
}

/* Archive facts under the lede: a real count reads better than another line of
   marketing, and gives the hero something concrete. */
.page-hero__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem 1.5rem;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-strong);
  max-width: 40rem;
}
.page-hero__facts span {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--muted);
}
.page-hero__facts b {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--night);
  font-variant-numeric: tabular-nums;
}
.page-hero__facts svg {
  width: 1rem;
  height: 1rem;
  color: var(--subtle);
}

/* ------------------------------------------- imported prose safeguards -- */

/* Imported content carries inline SVGs with a viewBox but no width/height.
   The reset's `svg { max-width: 100% }` then let each one expand to the column
   width: 580x663px per list bullet, 11,271px of dead space on one case study.
   Anything without dimensions is pinned to text size. */
.prose svg {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
}

/* Those leading icons are list markers, and .prose li already draws its own,
   so the imported one is a duplicate. */
.prose li > svg:first-child {
  display: none;
}

/* Belt and braces for the leading <br> wpautop inserts into list items. The
   content filter removes it, but this covers anything rendered outside that
   filter. Both shapes occur: some items lead with a marker icon, some do not. */
.prose li > br:first-child,
.prose li > svg:first-child + br {
  display: none;
}

/* ==================================================== article body -- */
/* Imported content uses far more than paragraphs and bullets: 226 ordered
   lists, 16 tables, 160 h5s, figures and rules — none of which the original
   .prose rules covered. */

/* -- ordered lists ---------------------------------------------------------
   The reset clears list-style and .prose li::before draws a dot for every
   item, so ordered lists rendered as bullets and lost their numbering
   entirely. Counters restore it. */
.prose ol {
  counter-reset: prose-ol;
}
.prose ol > li {
  counter-increment: prose-ol;
  padding-left: 2.25rem;
}
.prose ol > li::before {
  content: counter(prose-ol) ".";
  top: 0;
  left: 0;
  width: 1.5rem;
  height: auto;
  background: none;
  border-radius: 0;
  font-size: var(--fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--subtle);
}

/* -- headings --------------------------------------------------------------
   h4 and h5 had no rules at all, and h5 appears 160 times. */
.prose h4 {
  margin-top: 2rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
}
.prose h5 {
  margin-top: 1.75rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--fg);
}

/* -- tables ----------------------------------------------------------------
   Previously inherited the reset: no padding, no borders, no header. */
.prose__scroll {
  overflow-x: auto;
  margin-top: 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  -webkit-overflow-scrolling: touch;
}
.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-xs);
  line-height: 1.6;
}
.prose thead th {
  position: sticky;
  top: 0;
  font-weight: 600;
  text-align: left;
  color: var(--fg);
  background: var(--surface-2);
  white-space: nowrap;
}
.prose th,
.prose td {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.prose tbody tr:last-child th,
.prose tbody tr:last-child td {
  border-bottom: 0;
}
.prose tbody tr:nth-child(even) {
  background: var(--surface);
}
.prose td strong {
  color: var(--fg);
}

/* -- figures and images ---------------------------------------------------- */
.prose figure {
  margin-top: 2rem;
}
.prose img {
  width: 100%;
  height: auto;
  border-radius: var(--r-md);
}
.prose figcaption {
  margin-top: 0.75rem;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: var(--subtle);
}

/* -- rules ----------------------------------------------------------------- */
.prose hr {
  height: 1px;
  margin-block: 2.5rem;
  background: var(--line);
  border: 0;
}

/* -- single article extras ------------------------------------------------ */

/* The outcome of a case study is a sentence, not a figure — set as a line
   under the title rather than crammed into the metrics band. */
.page-hero__outcome {
  display: flex;
  gap: 0.625rem;
  max-width: 44rem;
  margin-top: 1.75rem;
  padding: 0.875rem 1rem;
  font-size: var(--fs-sm);
  line-height: 1.6;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--fg);
}
.page-hero__outcome svg {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.15rem;
  color: var(--subtle);
}
.page-hero__outcome b {
  display: block;
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
}

/* The archive leads with the shot; the single showed nothing at all. */
.article__cover {
  margin-bottom: 2.5rem;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.article__cover img {
  display: block;
  width: 100%;
  /* height:auto is what lets aspect-ratio win. WordPress prints a height
     attribute, and the reset only pairs max-width with it — so without this
     the image renders at its full 683px instead of the 16:9 crop. */
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* ============================================ case study / research single -- */

.case-layout {
  display: grid;
  gap: 2rem;
}
@media (min-width: 1000px) {
  .case-layout {
    grid-template-columns: 19rem minmax(0, 1fr);
    gap: 3rem;
    align-items: start;
  }
}

/* -- the rail -------------------------------------------------------------
   Shot, facts and the call to action travel with the reader rather than
   scrolling away at the top. */
@media (min-width: 1000px) {
  .case-rail {
    position: sticky;
    top: 6.5rem;
  }
}
.case-rail__media {
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.case-rail__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.case-rail__facts {
  display: grid;
  gap: 1rem;
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.case-rail__facts dt {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
}
.case-rail__facts dd {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: var(--fg);
}
.case-rail__cta {
  width: 100%;
  margin-top: 1.75rem;
}

/* -- the cards ------------------------------------------------------------
   One per part of the study, so Challenge / Solution / Results / Conclusion
   read as separate moves instead of one unbroken column. */
.case-body {
  display: grid;
  gap: 1.25rem;
}
.case-card {
  padding: 1.75rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
@media (min-width: 640px) {
  .case-card {
    padding: 2.25rem;
  }
}
.case-card__title {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
}
.case-card .prose {
  max-width: none;
  margin-top: 1.25rem;
  font-size: var(--fs-sm);
}
/* The card supplies the leading heading, so the first block inside starts flush. */
.case-card .prose > *:first-child {
  margin-top: 0;
}
.case-card__outcome {
  display: flex;
  gap: 0.625rem;
  margin-top: 1.25rem;
  padding: 0.875rem 1rem;
  font-size: var(--fs-xs);
  line-height: 1.55;
  font-weight: 500;
  color: var(--fg);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.case-card__outcome svg {
  flex: none;
  width: 1rem;
  height: 1rem;
  margin-top: 0.15rem;
  color: var(--subtle);
}

/* ======================================================== showcase grid -- */

.section-head + .showcase-grid {
  margin-top: 4rem;
}
.showcase-grid {
  display: grid;
  gap: 1.25rem;
  /* Close to the filter bar, which controls it — the bar should read as part
     of the grid, not as a second header under the hero. */
  margin-top: 1.5rem;
}
@media (min-width: 640px) {
  .showcase-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .showcase-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: 2rem;
  }
}

.showcase-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.showcase-card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.04), 0 20px 44px -16px rgb(16 24 40 / 0.16);
}
.showcase-card__media {
  overflow: hidden;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.showcase-card__media img {
  display: block;
  width: 100%;
  height: auto;
  /* Screenshots are full-page captures, so show the masthead and hero rather
     than squashing an entire scroll into a card. */
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.7s var(--ease-out-expo);
}
.showcase-card:hover .showcase-card__media img {
  transform: scale(1.03);
}

.showcase-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 1.25rem;
}
.showcase-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.showcase-card__head h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.015em;
}
.showcase-card__type {
  flex: none;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--subtle);
}

.showcase-card__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.showcase-card__stats dt {
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--subtle);
}
.showcase-card__stats dd {
  margin-top: 0.2rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}

.showcase-card__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: auto;
  padding-top: 1rem;
}
.showcase-card__tools li {
  padding: 0.15rem 0.5rem;
  font-size: var(--fs-2xs);
  color: var(--muted);
  background: var(--surface-2);
  border-radius: var(--r-sm);
}
.showcase-card__tools .is-more {
  color: var(--subtle);
  background: none;
}

/* ----------------------------------------------------- showcase filter -- */

/* An archive opens straight into its listing, so the full 8rem section padding
   stacked on the listing's own top margin left up to 176px of nothing between
   the hero and the first result. The listing sets the rhythm here, not the
   section. */
.section--archive {
  padding-top: 2.5rem;
}
@media (min-width: 1024px) {
  .section--archive {
    padding-top: 3rem;
  }
}
/* The section padding is the separation; the first block adds none of its own. */
.section--archive > .container > :first-child,
.section--archive > .container > .sr-only + * {
  margin-top: 0;
}
.sc-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem;
  margin-top: 0;
  padding: 1rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
/* Six controls will not sit on one row until there is real width, and letting
   them wrap wherever they land looks accidental. Below 1200px the search takes
   its own row and the four selects share the next. */
.sc-filter__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 100%;
}
@media (min-width: 1200px) {
  .sc-filter__search {
    flex: 1 1 14rem;
  }
}
.sc-filter__field {
  flex: 1 1 10rem;
}
@media (min-width: 1200px) {
  .sc-filter__field {
    flex: 0 1 auto;
  }
}
.sc-filter select {
  width: 100%;
}
.sc-filter__search svg {
  position: absolute;
  left: 0.75rem;
  width: 1rem;
  height: 1rem;
  color: var(--subtle);
  pointer-events: none;
}
.sc-filter__search input {
  width: 100%;
  padding: 0.625rem 0.875rem 0.625rem 2.25rem;
  font: inherit;
  font-size: var(--fs-xs);
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
}
.sc-filter select {
  padding: 0.625rem 0.75rem;
  font: inherit;
  font-size: var(--fs-xs);
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
}
.sc-filter__search input:focus,
.sc-filter select:focus {
  outline: none;
  border-color: var(--ink-800);
  box-shadow: 0 0 0 3px rgb(31 34 37 / 0.1);
}
.sc-filter .btn {
  padding-block: 0.625rem;
  font-size: var(--fs-xs);
}
.sc-filter__count {
  margin-top: 1rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}

@media (max-width: 639px) {
  /* Stacked, every control takes the full width so nothing is half a row. */
  .sc-filter {
    flex-direction: column;
    align-items: stretch;
  }
  .sc-filter__field,
  .sc-filter select,
  .sc-filter .btn {
    width: 100%;
  }
}

/* ==================================================== closing cta panel -- */

/* Dark slab closing the homepage: the prompt on the left, what happens next on
   the right. Inner pages keep the compact light .cta — this is the one place
   that earns the full treatment. */
.cta-panel {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  gap: 2.5rem;
  padding: 2rem;
  color: #fff;
  background: var(--night);
  border-radius: var(--radius-shell);
  box-shadow: 0 34px 90px -44px rgb(15 23 42 / 0.8);
}
@media (min-width: 640px) {
  .cta-panel {
    padding: 2.5rem;
  }
}
@media (min-width: 1024px) {
  .cta-panel {
    grid-template-columns: 7fr 5fr;
    gap: 3rem;
    align-items: center;
    padding: 3rem;
  }
}
.cta-panel__glow {
  position: absolute;
  z-index: -1;
  top: -30%;
  left: -5%;
  width: 45%;
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(70px);
  background: radial-gradient(circle, rgb(255 255 255 / 0.09), transparent 70%);
  pointer-events: none;
}

.cta-panel__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.875rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: #fff;
  background: rgb(255 255 255 / 0.08);
  border: 1px solid rgb(255 255 255 / 0.14);
  border-radius: var(--r-pill);
}
.cta-panel__badge svg {
  width: 0.875rem;
  height: 0.875rem;
}

.cta-panel h2 {
  margin-top: 1.25rem;
  max-width: 22ch;
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
/* Scoped to the lede only. As `.cta-panel p` this outranked the single-class
   rules on the point paragraphs, so the point titles rendered at 65% white
   with no contrast against their own body copy. */
.cta-panel__body > p {
  margin-top: 1rem;
  max-width: 46ch;
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: rgb(255 255 255 / 0.65);
  text-wrap: pretty;
}
.cta-panel__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

/* -- the three points ----------------------------------------------------- */
.cta-panel__points {
  display: grid;
  gap: 0.75rem;
}
.cta-panel__points li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.09);
  border-radius: var(--r-md);
}
.cta-panel__points > li > svg {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.15rem;
  color: rgb(255 255 255 / 0.75);
}
.cta-panel__point-title {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: #fff;
}
.cta-panel__point-body {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: rgb(255 255 255 / 0.58);
}

/* On white the inset shadow reads as a highlighter swipe behind dark text.
   On the dark slab that inverted to ink-on-ink: the shadow only covers the
   bottom 0.2em, so the rest of the glyph sat at 1.25:1 against the panel and
   the highlighted word vanished. The word keeps the heading's white and the
   brand colour stays where it belongs, as the rule underneath it. */
.cta-panel .cta__underline {
  color: inherit;
  box-shadow: inset 0 -0.2em 0 var(--brand-500);
}

/* Small reassurance under the actions, on the dark panel. */
.cta-panel__note {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.25rem;
  font-size: var(--fs-xs);
  color: rgb(255 255 255 / 0.55);
}
.cta-panel__note svg {
  flex: none;
  width: 1rem;
  height: 1rem;
}

/* ==========================================================================
   EXPERIMENT: paper page background            <-- delete this block to revert
   --------------------------------------------------------------------------
   Modelled on heyretro.io: a warm off-white page, a 1px dot grid at 18px, and
   a white fade over the top so the header still sits on clean white.

   The page colour goes on <html>, not <body>, so the dot layer can sit at
   z-index -1 without being painted over by body's own background. Cards and
   panels keep --bg (#fff) and lift off the paper.
   ========================================================================== */

:root {
  /* One definition for the grain, reused by the page and every grey section.
     0.072 is the page layer's effective alpha (0.12 colour x 0.6 opacity), so
     the texture reads identically whatever it sits on. */
  --dot-grid: radial-gradient(rgb(23 23 23 / 0.072) 1px, transparent 1px);
  --dot-grid-dark: radial-gradient(rgb(255 255 255 / 0.07) 1px, transparent 1px);
  --dot-size: 18px 18px;
}

html {
  background: #f7f5f0;
}
body {
  background: transparent;
}

/* The grey full-width surfaces carry the same grain, so a tinted band reads as
   the same paper rather than a flat panel laid over it. Small components —
   chips, pills, cards — stay plain; grain at that size is just noise. */
.section--tint,
.clients,
.page-hero {
  background-image: var(--dot-grid);
  background-size: var(--dot-size);
}

/* Dark bands get the same grain, drawn in white so it reads on near-black.
   Small dark components — the code panel, buttons, chips — stay plain. */
.hero,
.steps-band,
.guarantee,
.case-feature,
.cta-panel {
  background-image: var(--dot-grid-dark);
  background-size: var(--dot-size);
}
/* The hero drew a 64px line grid of its own; one texture per page. */
.hero__grid {
  background-image: none;
}

/* --subtle was picked for white (5.00:1). The darkest surface is now a dot on
   the paper, where it fell to 3.97 — under AA, and it is used for breadcrumbs
   and duration labels that do sit there. Nudged until it clears 4.5 on all
   three grounds: paper-dot 4.61, grey-dot 4.79, white 5.80. Reverting the
   block restores the original token. */
:root {
  --subtle: #61666b;
}
/* The hero drew a 64px line grid of its own. Two textures on one page read as
   an accident, so it uses the dots now. */
.page-hero::before {
  background-image: var(--dot-grid);
  background-size: var(--dot-size);
  -webkit-mask-image: none;
  mask-image: none;
  opacity: 0;
}
body::before,
body::after {
  content: "";
  z-index: -1;
  pointer-events: none;
}
/* Fixed, so the grain stays put rather than repeating past the page height. */
body::before {
  position: fixed;
  inset: 0;
  background-image: radial-gradient(rgb(23 23 23 / 0.12) 1px, transparent 1px);
  background-size: 18px 18px;
  opacity: 0.6;
}
/* Absolute, not fixed: this washes the top of the *page* so the header opens on
   clean white. Fixed would have kept the top 18rem of the viewport washed out
   the whole way down the page. */
body::after {
  position: absolute;
  inset: 0 0 auto;
  height: 18rem;
  background: linear-gradient(to bottom, rgb(255 255 255 / 0.85), transparent);
}

/* ==================================================== contributions page -- */

.contrib-figure {
  margin-top: 1.25rem;
  font-size: clamp(2.25rem, 5vw, 3rem);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--night);
}
.contrib-figure + .card__title {
  margin-top: 0.5rem;
}

/* -- teams ---------------------------------------------------------------- */
.contrib-teams {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 0.625rem;
}
.contrib-teams li {
  padding: 0.625rem 1rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}

/* -- badges --------------------------------------------------------------- */
.contrib-badges {
  display: grid;
  gap: 0.75rem;
  margin-top: 4rem;
}
@media (min-width: 640px) {
  .contrib-badges {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .contrib-badges {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.contrib-badges li {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 1rem 1.125rem 1rem 1.375rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
/* The dot carries the project's own badge colour, so a Core badge reads red
   here exactly as it does on WordPress.org. Colour is decoration only — the
   name next to it does the work, so contrast is never carried by hue. */
.contrib-badges li {
  position: relative;
  overflow: hidden;
}
.contrib-badges li::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--badge, var(--line-strong));
}
.contrib-badges__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  /* The glyph is mixed toward ink: at full strength the paler project colours
     (WordCamp Organizer's yellow) sat at 1.9:1 against their own tint. The
     stripe keeps the pure colour, so each badge still reads as itself. */
  color: color-mix(in srgb, var(--badge, var(--muted)) 62%, var(--ink-900));
  background: color-mix(in srgb, var(--badge, var(--muted)) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--badge, var(--muted)) 26%, transparent);
  border-radius: 50%;
}
.contrib-badges__icon svg {
  width: 1.125rem;
  height: 1.125rem;
}
.contrib-badges__name {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--fg);
}
.contrib-badges__since {
  margin-top: 0.15rem;
  font-size: var(--fs-2xs);
  color: var(--subtle);
}

/* -- meetups -------------------------------------------------------------- */
.meetups {
  display: grid;
  gap: 0.75rem;
  margin-top: 4rem;
}
.meetups a {
  display: grid;
  gap: 0.25rem 1.5rem;
  align-items: center;
  padding: 1.125rem 1.25rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color 0.3s, transform 0.3s var(--ease-out-expo);
}
@media (min-width: 768px) {
  .meetups a {
    grid-template-columns: 7.5rem minmax(0, 1fr) 1.25rem;
  }
}
.meetups a:hover {
  transform: translateY(-1px);
  border-color: var(--line-strong);
}
.meetups__date {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--subtle);
  font-variant-numeric: tabular-nums;
}
.meetups__title {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--fg);
  text-wrap: pretty;
}
.meetups__venue {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-2xs);
  color: var(--muted);
  white-space: nowrap;
}
.meetups__venue svg {
  width: 0.875rem;
  height: 0.875rem;
  color: var(--subtle);
}
.meetups__go {
  width: 1rem;
  height: 1rem;
  color: var(--subtle);
  opacity: 0;
  transition: opacity 0.3s;
}
.meetups a:hover .meetups__go {
  opacity: 1;
}

/* -- closing quote -------------------------------------------------------- */
.contrib-quote__label {
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--subtle);
}
.abstract blockquote {
  margin-top: 1rem;
  font-size: var(--fs-md);
  line-height: 1.7;
  color: var(--fg);
  text-wrap: pretty;
}
.contrib-quote__by {
  margin-top: 1.25rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.contrib-quote__by b {
  color: var(--fg);
}

/* -- contributor cards ---------------------------------------------------- */
.contrib-person {
  align-items: center;
  text-align: center;
}
.contrib-person__avatar {
  width: 5rem;
  height: 5rem;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.contrib-person .card__title {
  margin-top: 1.125rem;
}
.contrib-person__role {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.contrib-person__handle {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.875rem;
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--subtle);
}
.contrib-person__handle svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 0.3s var(--ease-out-expo);
}
.contrib-person:hover .contrib-person__handle svg {
  transform: translate(2px, -2px);
}

/* ============================================================ industries
   Industry landing pages (templates/page-industry.php). The problem grid
   leads, because that is what the visitor recognises before they recognise
   a service name. */

.problem-grid {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.problem-card {
  padding: 1.75rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.problem-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}
.problem-card__icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: 1rem;
  color: var(--ink-900);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.problem-card__icon svg {
  width: 1.125rem;
  height: 1.125rem;
}
.problem-card h3 {
  margin: 0 0 0.5rem;
  font-size: var(--fs-md);
  line-height: 1.35;
}
.problem-card p {
  margin: 0;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.65;
}

.ind-services {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
.ind-service {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  justify-content: space-between;
  padding: 1.5rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.ind-service:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}
.ind-service h3 {
  margin: 0;
  font-size: var(--fs-md);
  line-height: 1.35;
}
.ind-service__go {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  color: var(--subtle);
  font-size: var(--fs-xs);
  font-weight: 600;
}
.ind-service__go svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 0.3s var(--ease-out-expo);
}
.ind-service:hover .ind-service__go {
  color: var(--ink-900);
}
.ind-service:hover .ind-service__go svg {
  transform: translateX(3px);
}

.ind-more {
  margin: 2rem 0 0;
  text-align: center;
}

/* ============================================================= migrations
   Platform-to-WordPress pages (templates/page-migration.php). The two-column
   split is the point of these pages, so it gets the strongest treatment. */

.mig-split {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}
.mig-col {
  padding: 1.75rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.mig-col h3 {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin: 0 0 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-md);
}
.mig-col h3 svg {
  width: 1.125rem;
  height: 1.125rem;
}
/* Green and amber carry the meaning here, so the pair has to stay legible on
   its own: both are darkened well past their brand tints for contrast. */
.mig-col--yes h3 {
  color: #15803d;
}
.mig-col--no h3 {
  color: #a16207;
}
.mig-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.mig-col li {
  position: relative;
  padding: 0 0 0 1.25rem;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.65;
}
.mig-col li + li {
  margin-top: 0.75rem;
}
.mig-col li::before {
  position: absolute;
  top: 0.6em;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  content: "";
}
.mig-col--yes li::before {
  background: #15803d;
}
.mig-col--no li::before {
  background: #a16207;
}

.mig-steps {
  display: grid;
  gap: 0.75rem;
  max-width: 46rem;
  /* One shorthand, not margin-top followed by `margin: 0 auto`, which silently
     reset the top back to zero and butted the steps against the heading. */
  margin: 4rem auto 0;
  padding: 0;
  list-style: none;
}
.mig-step {
  display: grid;
  gap: 1rem;
  align-items: start;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  padding: 1.25rem 1.5rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.mig-step__n {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--bg);
  background: var(--ink-900);
  border-radius: 50%;
  font-size: var(--fs-xs);
  font-weight: 700;
}
.mig-step h3 {
  margin: 0 0 0.25rem;
  font-size: var(--fs-md);
}
.mig-step p {
  margin: 0;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.65;
}

/* =============================================================== compare
   Freelancer / us / large agency table. Real <table> on desktop; below the
   breakpoint each row becomes a stack, with the column name coming from the
   data-col attribute so the header is not lost. */

.compare {
  /* Room above and below for our column to stand proud of the table. */
  margin-top: 4rem;
  padding: 1.25rem 0 1.5rem;
  overflow-x: auto;
}
.compare__table {
  width: 100%;
  min-width: 46rem;
  /* Separate, not collapse: a collapsed table cannot round the corners of a
     single column, which is what makes ours read as a raised card. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--fs-sm);
}
.compare__table th,
.compare__table td {
  padding: 1.125rem 1.25rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.compare__table thead th {
  padding-block: 1rem;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  border-bottom: 1px solid var(--line-strong);
}
.compare__table tbody th {
  width: 11rem;
  color: var(--ink-900);
  font-weight: 600;
  line-height: 1.4;
}
.compare__table td {
  color: var(--subtle);
  line-height: 1.6;
}
.compare__table tbody tr:last-child th,
.compare__table tbody tr:last-child td {
  border-bottom: 0;
}
/* Nothing to label, so the corner stays empty rather than drawing a rule. */
.compare__table thead th:first-child {
  border-bottom-color: transparent;
}

/* Our column is one continuous card running the height of the table: white
   against the page tint, hairline sides, rounded top and bottom, lifted with a
   shadow. Previously it was a square black cap sitting over a grey stripe, so
   the header read as detached from the column it belonged to. */
.compare__table .is-ours {
  position: relative;
  color: var(--ink-900);
  background: var(--bg);
  font-weight: 500;
  /* --line against the section tint is 1.14:1 and the white fill only 1.05:1,
     so at hairline weight the column had no visible edge at all. The stronger
     token is what actually draws the card. */
  box-shadow: 1px 0 0 var(--line-strong) inset, -1px 0 0 var(--line-strong) inset;
}
.compare__table thead .is-ours {
  color: #fff;
  background: var(--ink-900);
  border-bottom-color: var(--ink-900);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: none;
}
.compare__table tbody tr:last-child .is-ours {
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  box-shadow: 1px 0 0 var(--line-strong) inset, -1px 0 0 var(--line-strong) inset, 0 -1px 0 var(--line-strong) inset;
}
/* No drop shadow: the scroll container would clip it. The lift comes from a
   white column against the tinted section instead, which survives scrolling
   and needs no extra element. */
.compare__tick {
  display: inline-flex;
  margin-right: 0.375rem;
  color: var(--brand-500);
  vertical-align: -0.15em;
}
.compare__tick svg {
  width: 0.9375rem;
  height: 0.9375rem;
}

@media (max-width: 767px) {
  .compare {
    overflow-x: visible;
    border: 0;
    background: none;
  }
  .compare__table,
  .compare__table tbody,
  .compare__table tr,
  .compare__table th,
  .compare__table td {
    display: block;
    width: auto;
  }
  /* The desktop min-width keeps columns readable; once the rows stack it is
     just a 736px floor that pushes the whole page sideways. */
  .compare__table {
    min-width: 0;
  }
  /* Stacked rows are cards in their own right, so the single-column card
     treatment would double up on borders and corners. */
  .compare__table .is-ours {
    box-shadow: none;
    border-radius: 0;
  }
  .compare__table thead {
    display: none;
  }
  .compare__table tr {
    margin-bottom: 0.75rem;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    overflow: hidden;
  }
  .compare__table tbody th {
    width: auto;
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
  }
  .compare__table td::before {
    display: block;
    margin-bottom: 0.125rem;
    color: var(--muted);
    content: attr(data-col);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
}

/* ============================================================== releases
   Published plugins and themes on the contributions page. */

.release {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.release__kind {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  align-self: flex-start;
  padding: 0.25rem 0.625rem;
  color: var(--subtle);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.release__kind svg {
  width: 0.8125rem;
  height: 0.8125rem;
}
.release__body {
  margin: 0;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.65;
}
.release__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1.25rem;
  margin: auto 0 0;
  padding: 0.875rem 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
}
.release__stats li {
  display: flex;
  gap: 0.3125rem;
  align-items: baseline;
  color: var(--muted);
  font-size: var(--fs-2xs);
}
.release__stats b {
  color: var(--ink-900);
  font-size: var(--fs-sm);
  font-weight: 700;
}

.release-grid {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
}

/* ================================================================= roles
   Open positions on the careers page. */

.roles {
  display: grid;
  gap: 0.75rem;
  max-width: 46rem;
  margin: 4rem auto 0;
  padding: 0;
  list-style: none;
}
.role a {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  padding: 1.375rem 1.5rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.role a:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}
.role h3 {
  margin: 0;
  font-size: var(--fs-md);
}
.role__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.5rem;
  margin: 0.625rem 0 0;
  padding: 0;
  list-style: none;
}
.role__facts li {
  padding: 0.1875rem 0.5rem;
  color: var(--subtle);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
}
.role__go {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  flex-shrink: 0;
  color: var(--subtle);
  font-size: var(--fs-xs);
  font-weight: 600;
}
.role__go svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 0.3s var(--ease-out-expo);
}
.role a:hover .role__go {
  color: var(--ink-900);
}
.role a:hover .role__go svg {
  transform: translateX(3px);
}
.roles__empty {
  max-width: 38rem;
  margin: 4rem auto 0;
  color: var(--subtle);
  text-align: center;
  line-height: 1.7;
}

@media (max-width: 599px) {
  .role a {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ============================================================== partners
   The confidentiality commitments on the partner programme page. Two columns
   of plain statements: this section is read, not skimmed. */

.invisible-list {
  display: grid;
  gap: 0.875rem 2rem;
  max-width: 56rem;
  margin: 4rem auto 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 768px) {
  .invisible-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.invisible-list li {
  display: grid;
  gap: 0.75rem;
  align-items: start;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  color: var(--ink-800);
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.invisible-list__tick {
  display: grid;
  place-items: center;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.1em;
  color: #15803d;
}
.invisible-list__tick svg {
  width: 1rem;
  height: 1rem;
}

/* ================================================================== gate
   Email capture in place of the rest of a white paper. The preview fades out
   under the panel so it reads as "continues below" rather than "ends here". */

.prose--preview {
  position: relative;
}
.gate {
  position: relative;
  margin-top: -4rem;
}
.gate__fade {
  height: 4rem;
  background: linear-gradient(to bottom, rgb(255 255 255 / 0), var(--bg));
  pointer-events: none;
}
.gate__body {
  padding: 2rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  text-align: center;
}
.gate__badge {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  padding: 0.25rem 0.75rem;
  color: var(--subtle);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
  font-weight: 600;
}
.gate__badge svg {
  width: 0.8125rem;
  height: 0.8125rem;
}
.gate__body h2 {
  margin: 1rem 0 0.5rem;
  font-size: var(--fs-lg);
}
.gate__body > p {
  max-width: 32rem;
  margin: 0 auto;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.65;
}
.gate__form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  max-width: 30rem;
  margin: 1.5rem auto 0;
}
.gate__form input[type="email"] {
  flex: 1 1 14rem;
  min-width: 0;
  padding: 0.75rem 1rem;
  color: var(--ink-900);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font: inherit;
  font-size: var(--fs-sm);
}
.gate__form input[type="email"]:focus-visible {
  outline: 2px solid var(--ink-900);
  outline-offset: 1px;
}
/* Off-screen rather than display:none, which some bots skip. */
.gate__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.gate__error {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  margin: 1rem auto 0;
  padding: 0.5rem 0.875rem;
  color: #b91c1c;
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: var(--r-md);
  font-size: var(--fs-xs);
}
.gate__error svg {
  width: 0.9375rem;
  height: 0.9375rem;
}
.gate__small {
  display: flex;
  gap: 0.375rem;
  align-items: center;
  justify-content: center;
  margin: 1rem 0 0;
  color: var(--muted);
  font-size: var(--fs-2xs);
}
.gate__small svg {
  width: 0.8125rem;
  height: 0.8125rem;
}

/* =============================================================== scores
   Third-party review badges. Hidden entirely until there are real figures,
   so this only ever renders with something behind it. */

.scores {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.score a,
.score {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  align-items: center;
  padding: 1.25rem 2rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.score a {
  padding: 0;
  border: 0;
  background: none;
}
.score__value {
  color: var(--ink-900);
  font-size: var(--fs-xl);
  font-weight: 800;
  line-height: 1;
}
.score__stars {
  display: inline-flex;
  gap: 0.125rem;
  color: var(--brand-500);
}
.score__stars svg {
  width: 0.875rem;
  height: 0.875rem;
}
.score__meta {
  color: var(--subtle);
  font-size: var(--fs-2xs);
}

/* ========================================================== mega chips
   Secondary groups (platform migrations, industries) shown as one inline row
   under the columns. They are short labels, so a column each was a waste of
   width that the real service columns needed. */

.mega__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-items: center;
  grid-column: 1 / -1;
  margin-top: 0.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.mega__chips .mega__col-head {
  margin: 0;
  padding: 0;
  flex-shrink: 0;
}
.mega__chips ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.mega__chips a {
  display: inline-block;
  padding: 0.3125rem 0.6875rem;
  color: var(--ink-800);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 500;
  transition: color 0.25s, background-color 0.25s, border-color 0.25s;
}
.mega__chips a:hover {
  color: var(--ink-900);
  background: var(--bg);
  border-color: var(--line-strong);
}

/* ========================================================= bento platforms
   Fills the migration cell now that the screenshot is gone. Each row is a
   route to that platform's migration page, so the space does work. */

.bento__media-label {
  display: flex;
  gap: 0.4375rem;
  align-items: center;
  margin: 0 0 0.875rem;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.bento__media-label svg {
  width: 0.875rem;
  height: 0.875rem;
}
/* The base .bento__media is a flex row that bottom-centres a single visual,
   which laid the label out beside the list and squeezed both onto their own
   ragged lines. A list needs the opposite: stacked, full width, top to bottom. */
.bento__media--list {
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
}
.platforms {
  display: grid;
  gap: 0.5rem;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}
.platforms a {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.6875rem 0.875rem;
  color: var(--ink-800);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 500;
  transition: color 0.25s, border-color 0.25s, transform 0.25s var(--ease-out-expo);
}
.platforms a svg {
  width: 0.875rem;
  height: 0.875rem;
  color: var(--muted);
  transition: transform 0.25s var(--ease-out-expo), color 0.25s;
}
.platforms a:hover {
  color: var(--ink-900);
  border-color: var(--line-strong);
  transform: translateY(-1px);
}
.platforms a:hover svg {
  color: var(--ink-900);
  transform: translate(2px, -2px);
}

/* =================================================================== hub
   Landing pages for a top-level menu item (templates/page-hub.php). Cards
   mirror the mega menu they are built from: icon chip, name, one line. */

.hub-grid {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
.hub-card {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 1.75rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: transform 0.4s var(--ease-out-expo), border-color 0.4s, box-shadow 0.4s;
}
.hub-card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}
.hub-card__icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: 0.375rem;
  color: var(--ink-900);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.hub-card__icon svg {
  width: 1.125rem;
  height: 1.125rem;
}
.hub-card h3 {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin: 0;
  font-size: var(--fs-md);
  line-height: 1.35;
}
.hub-card p {
  margin: 0;
  color: var(--subtle);
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.hub-card__go {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  margin-top: auto;
  padding-top: 0.75rem;
  color: var(--subtle);
  font-size: var(--fs-xs);
  font-weight: 600;
}
.hub-card__go svg {
  width: 0.875rem;
  height: 0.875rem;
  transition: transform 0.3s var(--ease-out-expo);
}
.hub-card:hover .hub-card__go {
  color: var(--ink-900);
}
.hub-card:hover .hub-card__go svg {
  transform: translateX(3px);
}

/* ============================================================== logowall
   Client logos as two marquee rows on a dark slab. Same treatment as the
   closing CTA panel, so the page has one dark surface style, not two. */

.logowall {
  position: relative;
  overflow: hidden;
  margin-top: 4rem;
  padding: 3rem 0 2.5rem;
  background: var(--night);
  border-radius: var(--radius-shell);
}
.logowall__title {
  margin: 0 auto 2.5rem;
  padding-inline: 1.5rem;
  max-width: 34rem;
  color: #fff;
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.3;
  text-align: center;
}
.logowall__rows {
  display: grid;
  gap: 1rem;
}
.logowall__row {
  overflow: hidden;
  /* Fade both ends so logos enter and leave rather than popping at the edge. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
  mask-image: linear-gradient(to right, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
}
.logowall__track {
  display: flex;
  /* Spacing lives on the item, not as flex gap: with gap, half the track is
     53 logos + 52.5 gaps while a clean seam needs 53 + 53, so the -50% loop
     landed half a gap out and jumped each cycle. */
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
  animation: logowall-scroll var(--logowall-duration, 60s) linear infinite;
}
.logowall__row--reverse .logowall__track {
  animation-direction: reverse;
}
/* The track holds the logos twice, so half of it is one full cycle. */
@keyframes logowall-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.logowall__item {
  margin-right: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 12.5rem;
  padding: 1.25rem 1.5rem;
  background: rgb(255 255 255 / 0.04);
  border: 1px solid rgb(255 255 255 / 0.08);
  border-radius: var(--r-lg);
}
.logowall__item img {
  width: 100%;
  height: 2rem;
  object-fit: contain;
  /* Client logos are full-colour artwork made for light backgrounds. Knocking
     them back to white is the only way they read consistently on the slab. */
  filter: brightness(0) invert(1);
  opacity: 0.72;
  transition: opacity 0.3s;
}
.logowall__item:hover img {
  opacity: 1;
}
.logowall__more {
  margin: 2.5rem auto 0;
  padding-inline: 1.5rem;
  max-width: 40rem;
  color: rgb(255 255 255 / 0.62);
  font-size: var(--fs-sm);
  line-height: 1.6;
  text-align: center;
}

@media (min-width: 640px) {
  .logowall {
    padding: 4rem 0 3rem;
  }
  .logowall__item {
    width: 14rem;
    padding: 1.5rem 1.75rem;
  }
  .logowall__item img {
    height: 2.5rem;
  }
}

/* A marquee is decoration; anyone who has asked for less motion gets a static,
   scrollable row instead of a moving one. */
@media (prefers-reduced-motion: reduce) {
  .logowall__row {
    overflow-x: auto;
  }
  .logowall__track {
    animation: none;
  }
}

/* ======================================================= case rail related
   Outbound links from showcase entries, which have no prose for the
   contextual linker to work with. */

.case-rail__related {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.case-rail__related-head {
  margin: 0 0 0.75rem;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.case-rail__related ul {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.case-rail__related a {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  color: var(--ink-800);
  font-size: var(--fs-sm);
  font-weight: 500;
}
.case-rail__related a svg {
  width: 0.875rem;
  height: 0.875rem;
  color: var(--muted);
  transition: transform 0.25s var(--ease-out-expo);
}
.case-rail__related a:hover {
  color: var(--ink-900);
}
.case-rail__related a:hover svg {
  transform: translateX(3px);
}


/* ================================================================== blog
   Latest articles as horizontal cards, two across. */

.postgrid {
  display: grid;
  gap: 1.25rem;
  margin-top: 4rem;
}
@media (min-width: 1024px) {
  .postgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.postcard {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.25rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: border-color 0.4s, box-shadow 0.4s;
}
.postcard:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}
@media (min-width: 560px) {
  .postcard {
    flex-direction: row;
    align-items: stretch;
  }
}
.postcard__media {
  display: flex;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--surface-2);
}
@media (min-width: 560px) {
  .postcard__media {
    width: 11rem;
  }
}
.postcard__media img {
  width: 100%;
  height: 11rem;
  object-fit: cover;
  transition: transform 0.5s var(--ease-out-expo);
}
@media (min-width: 560px) {
  .postcard__media img {
    height: 100%;
    min-height: 10rem;
  }
}
.postcard:hover .postcard__media img {
  transform: scale(1.08) rotate(2deg);
}
.postcard__body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  justify-content: space-between;
  min-width: 0;
}
.postcard__cat {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.postcard__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.35;
}
.postcard__title a {
  color: var(--ink-900);
}
.postcard:hover .postcard__title a {
  color: var(--brand-ink);
}
.postcard__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  align-items: center;
  margin: 0;
  color: var(--subtle);
  font-size: var(--fs-2xs);
}
.postcard__meta svg {
  width: 0.8125rem;
  height: 0.8125rem;
  color: var(--muted);
}
.postcard__dot {
  color: var(--muted);
}
.postgrid__more {
  margin: 2.5rem 0 0;
  text-align: center;
}

/* ============================================================= footer ai
   "Ask an AI about us" marks. The footer is near-black, so the marks sit at
   partial white and come up to full on hover. */

.footer__ai {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  padding-block: 2.5rem;
  border-top: 1px solid rgb(255 255 255 / 0.08);
  text-align: center;
}
.footer__ai-head {
  margin: 0;
  color: rgb(255 255 255 / 0.72);
  font-size: var(--fs-sm);
}
.footer__ai-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.footer__ai-links a {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: rgb(255 255 255 / 0.62);
  border: 1px solid rgb(255 255 255 / 0.1);
  border-radius: var(--r-md);
  transition: color 0.25s, background-color 0.25s, border-color 0.25s;
}
.footer__ai-links a:hover,
.footer__ai-links a:focus-visible {
  color: #fff;
  background: rgb(255 255 255 / 0.06);
  border-color: rgb(255 255 255 / 0.24);
}
.footer__ai-links svg {
  width: 1.25rem;
  height: 1.25rem;
}
