/* ==========================================================================
   WPStylo — editorial stylesheet
   Every colour is a semantic token, never a hex. Sections marked .ink swap
   the whole token set to the deep-navy palette, so the same components work
   on light and dark without a single override.
   ========================================================================== */

/* fonts.css and tokens.css are enqueued separately by inc/enqueue.php with an
   explicit dependency chain, so they are NOT imported here. @import would make
   the browser fetch them one after another instead of in parallel, which costs
   a round trip on every page load. */

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

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--surface-canvas);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--text-base);
  line-height: var(--leading-prose);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { max-width: 100%; display: block; }
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--text-primary); margin: 0; }
p { margin: 0 0 var(--space-4); }
p:last-child { margin-bottom: 0; }
a { color: var(--brand); text-underline-offset: 3px; }
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
::selection { background: var(--brand); color: var(--text-on-brand); }

/* ---------------------------------------------------------- grain film -- */
/* A single fixed noise layer over the whole document. This is the cheapest
   thing on the page that most makes it look considered — flat colour fields
   read as digital, grain reads as printed. */

.grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  width: 100%; height: 100%; opacity: 0.55; mix-blend-mode: soft-light;
}
@media (max-width: 700px) { .grain { opacity: 0.32; } }

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

/* Sits on the header's bottom border, so it travels with the nav. The faint
   track is what makes the fill legible — a bar with no track reads as a stray
   line until it is already half full. */
.scroll-rail {
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 3px; z-index: 2;
  background: rgb(27 41 102 / .07);
  pointer-events: none;
}
.scroll-rail > i {
  display: block; height: 100%; width: 0%;
  /* Ends at --brand-300, not --brand-50: the ice end of the ramp is 1.1:1 on
     white, so the last third of the bar was invisible on every light page. */
  background: linear-gradient(90deg, var(--brand-900), var(--brand-500), var(--brand-300));
  transition: width 80ms linear;
}

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

.shell { max-width: var(--shell); margin: 0 auto; padding-inline: var(--space-6); position: relative; z-index: 2; }
.shell-wide { max-width: 1440px; margin: 0 auto; padding-inline: var(--space-6); position: relative; z-index: 2; }
.shell-narrow { max-width: var(--shell-narrow); margin: 0 auto; padding-inline: var(--space-6); position: relative; z-index: 2; }

/* Section rhythm. Was 96px / 128px, which stacked to ~250px of empty page
   between every band. 64/88 keeps the sections distinct without the page
   feeling like it is mostly gaps. */
section { padding-block: var(--space-16); position: relative; }
@media (min-width: 900px) { section { padding-block: 88px; } }

.band-ice  { background: var(--surface-sunken); }
.ink       { position: relative; overflow: hidden; }

/* Editorial section marker: numeral, hairline, label. Repeats on every
   section, which is what gives the site its magazine rhythm. */
.rule-num {
  display: flex; align-items: center; gap: var(--space-4);
  margin-bottom: var(--space-8);
}
.rule-num .num {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--text-sm); letter-spacing: .1em;
  color: var(--brand); font-variant-numeric: tabular-nums;
}
.rule-num .line { flex: 0 0 clamp(28px, 6vw, 88px); height: 1px; background: var(--border-strong); opacity: .5; }
.rule-num .lbl {
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted);
}

.eyebrow {
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-muted); margin: 0 0 var(--space-4);
}

.lede {
  font-size: var(--text-lg); line-height: var(--leading-snug);
  color: var(--text-secondary); max-width: 54ch; margin: var(--space-6) 0 0;
}
.prose { max-width: var(--measure); }
.section-head { max-width: 62ch; margin-bottom: var(--space-16); }

/* ---------------------------------------------------------- display type - */

/* Sentence case and a smaller ceiling, matching the reference. Uppercase is
   kept for section headings, where the lines are short enough to carry it. */
.display {
  font-family: var(--font-display); font-weight: 700;
  line-height: 1.02; letter-spacing: -0.02em;
  text-transform: none;
  font-size: clamp(2.25rem, 1.1rem + 4.6vw, 4.5rem);
  margin: 0;
}
.display-md {
  font-family: var(--font-display); font-weight: 700;
  line-height: 1.0; letter-spacing: -0.02em; text-transform: uppercase;
  font-size: clamp(2.25rem, 1.2rem + 4.2vw, 4rem);
  margin: 0;
}
h2 { font-size: clamp(2rem, 1.3rem + 2.6vw, 3.25rem); font-weight: 700;
     line-height: 1.02; letter-spacing: -0.02em; text-transform: uppercase; }
h3 { font-size: var(--text-2xl); font-weight: 600; line-height: 1.12; letter-spacing: -0.01em; }
h4 { font-size: var(--text-xl); font-weight: 600; line-height: var(--leading-snug); }

/* An underline drawn under one phrase in a headline. Editorial emphasis
   without reaching for colour or weight. */
.underscore { position: relative; display: inline-block; }
.underscore::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0.06em; height: 0.07em;
  background: var(--brand); transform-origin: left; transform: scaleX(0);
  transition: transform 900ms var(--ease-out) 400ms;
}
.is-in .underscore::after, .reveal-lines.is-in .underscore::after { transform: scaleX(1); }

/* Words behind a mask, rising into place line by line. The clip is on a
   wrapper so descenders are never sliced. */
.reveal-lines .rl {
  display: block; overflow: hidden; padding-bottom: 0.06em; margin-bottom: -0.06em;
}
.reveal-lines .rl > span {
  display: block; transform: translateY(105%);
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.reveal-lines.is-in .rl > span { transform: translateY(0); }

/* ------------------------------------------------------------- reveal --- */

.reveal { opacity: 0; transform: translateY(26px);
  transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: 110ms; }
.reveal-d2 { transition-delay: 220ms; }
.reveal-d3 { transition-delay: 330ms; }

.reveal-scale { opacity: 0; transform: scale(0.94);
  transition: opacity 900ms var(--ease-out), transform 900ms var(--ease-out); }
.reveal-scale.is-in { opacity: 1; transform: none; }

/* line-art that draws itself */
.art-disc { width: 100%; height: auto; overflow: visible; }
@media (min-width: 1000px) { .art-disc { transform: scale(1.18); transform-origin: center; } }
.art-disc .draw { stroke-dasharray: 1400; stroke-dashoffset: 1400; }
.art-draw .draw {
  stroke-dasharray: 2600; stroke-dashoffset: 2600;
  transition: stroke-dashoffset 2200ms cubic-bezier(0.33, 1, 0.68, 1);
  transition-delay: var(--d, 0s);
}
.is-in .art-draw .draw, .art-draw.is-in .draw { stroke-dashoffset: 0; }

.gauge-arc {
  stroke-dasharray: var(--len); stroke-dashoffset: var(--len);
  transition: stroke-dashoffset 1800ms cubic-bezier(0.16, 1, 0.3, 1) 200ms;
}
.is-in .gauge-arc { stroke-dashoffset: var(--to); }

/* ---------------------------------------------------------------- art --- */

.art-mesh {
  position: absolute; inset: -10%; width: 120%; height: 120%; z-index: 0;
  max-width: none;   /* the global svg{max-width:100%} clamps this and leaves
                        a hard vertical seam where the mesh stops short */
}
/* Vignette over the mesh: without it the blur fills every corner and the
   band reads as flat lavender instead of navy with light in it. */
.ink .art-mesh + .mesh-veil, .mesh-veil {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(24,27,57,.92) 0%, rgba(24,27,57,.78) 30%, rgba(24,27,57,.28) 55%, transparent 70%),
    radial-gradient(105% 85% at 74% 34%, transparent 0%, rgba(24,27,57,.42) 52%, rgba(24,27,57,.88) 100%),
    linear-gradient(180deg, rgba(24,27,57,.40) 0%, transparent 32%, rgba(24,27,57,.62) 100%);
}
.art-lines { position: absolute; left: 0; right: 0; width: 100%; max-width: none; z-index: 0; pointer-events: none; }
.art-iso, .art-gauge { width: 100%; height: auto; overflow: visible; }
.art-map { width: 100%; height: auto; }

.art-frame {
  position: relative; border-radius: var(--radius-xl); overflow: hidden;
  background: linear-gradient(155deg, var(--brand-300), var(--brand-900));
  aspect-ratio: 4 / 5;
  display: grid; place-items: center; padding: var(--space-8);
  color: #fff; text-align: center; font-size: var(--text-sm);
  box-shadow: var(--elevation-4);
}
.art-frame.wide { aspect-ratio: 16 / 10; }

/* parallax layers — translated by the scroll handler, never by scroll-linked
   CSS, so we can switch it off entirely for reduced motion */
.parallax { will-change: transform; }

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

.hero-ed { padding-block: clamp(96px, 16vh, 190px) clamp(80px, 12vh, 150px); }
.hero-ed .display { margin-top: var(--space-6); }

.hero-split { display: grid; gap: var(--space-16); align-items: center; }
@media (min-width: 1000px) {
  .hero-split { grid-template-columns: 1.25fr 0.75fr; gap: var(--space-8); }
  /* the illustration overlaps the type column — the editorial move */
  .hero-split > .hero-art { margin-left: -12%; }
}
.hero-art { position: relative; }

/* A scrim tied to the text column, not to the section. The global mesh veil
   is a fixed guess about where the headline sits; a four-line headline reaches
   further right and drops into the bright part of the mesh. Anchoring the
   scrim to the text block means contrast holds whatever the headline length. */
.hero-ed .hero-split > div:first-child { position: relative; }
.hero-ed .hero-split > div:first-child::before {
  content: ""; position: absolute; inset: -10% -26% -10% -60%;
  z-index: -1; pointer-events: none;
  background: radial-gradient(80% 70% at 42% 50%,
    rgba(24,27,57,.94) 0%, rgba(24,27,57,.86) 48%, rgba(24,27,57,.46) 76%, transparent 94%);
}

.hero-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-8);
  margin-top: var(--space-12); padding-top: var(--space-6);
  border-top: 1px solid var(--border-default);
}
.hero-meta div { min-width: 120px; }
.hero-meta dt { font-size: var(--text-xs); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--space-2); }
.hero-meta dd { margin: 0; font-family: var(--font-display); font-weight: 700;
  font-size: var(--text-2xl); font-variant-numeric: tabular-nums; color: var(--brand); line-height: 1; }

/* ------------------------------------------------------------ marquee --- */

.marquee {
  overflow: hidden; border-block: 1px solid var(--border-default);
  padding-block: var(--space-4); position: relative; z-index: 2;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee-track { display: flex; width: max-content; animation: slide 42s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-track span {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding-inline: var(--space-8);
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; font-size: var(--text-sm); color: var(--text-secondary);
  white-space: nowrap;
}
.marquee-track span::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand); flex: 0 0 auto;
}
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

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

.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-3); min-height: 54px; padding-inline: var(--space-8);
  border: 1px solid transparent; border-radius: var(--radius-full);
  font-family: var(--font-display); font-size: var(--text-sm); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; line-height: 1;
  text-decoration: none; cursor: pointer; white-space: nowrap; overflow: hidden;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-normal) var(--ease-out);
}
.btn > span { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: var(--space-3); }
.btn .arw { transition: transform var(--duration-normal) var(--ease-out); }
.btn:hover .arw { transform: translate(3px, -3px); }

/* a fill that wipes up from the bottom on hover */
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--brand-hover); transform: translateY(101%);
  transition: transform var(--duration-normal) var(--ease-out);
}
.btn:hover::before { transform: translateY(0); }

.btn-primary { background: var(--brand); color: var(--text-on-brand); }
.btn-primary:hover { color: var(--text-on-brand); box-shadow: var(--elevation-3); }
.ink .btn-primary:hover { color: var(--text-on-brand); }

.btn-secondary { background: transparent; border-color: var(--border-strong); color: var(--text-primary); }
.btn-secondary:hover { color: var(--text-on-brand); border-color: var(--brand); }
.btn-secondary::before { background: var(--brand); }

.btn-ghost { background: transparent; color: var(--brand); padding-inline: var(--space-4); }
.btn-ghost::before { display: none; }
.btn-ghost:hover { color: var(--brand-hover); }

.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--neutral-300); color: var(--neutral-600); cursor: not-allowed; box-shadow: none;
}
.btn:disabled::before { display: none; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; margin-top: var(--space-10, 40px); }
.cta-note { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-6); }

/* magnetic wrapper — JS translates this, CSS springs it back */
.magnet { display: inline-block; transition: transform 400ms var(--ease-out); }

.arrow-link {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-size: var(--text-sm); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand); text-decoration: none; padding-bottom: 4px;
  background-image: linear-gradient(var(--brand), var(--brand));
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size var(--duration-normal) var(--ease-out);
}
.arrow-link:hover { background-size: 100% 1px; }
.arrow-link .arw { transition: transform var(--duration-normal) var(--ease-out); }
.arrow-link:hover .arw { transform: translate(3px, -3px); }

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

/* Always white, never transparent — the logo has to read on it at all times,
   and a nav that changes colour on scroll competes with the hero. */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 80;
  background: #FFFFFF;
  border-bottom: 1px solid var(--neutral-200);
  transition: box-shadow var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
}
.site-header.is-stuck { box-shadow: 0 1px 20px rgb(27 41 102 / 0.07); }
.site-header.is-hidden { transform: translateY(-100%); }

.nav { display: flex; align-items: center; gap: var(--space-6); min-height: 96px; }
.brand { display: flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.brand img { height: 62px; width: auto; }
@media (max-width: 600px) { .brand img { height: 46px; } }
.nav-links { display: none; gap: var(--space-2); margin: 0 auto; align-items: center; }
@media (min-width: 1120px) { .nav-links { display: flex; } }
.nav-links a {
  position: relative; font-family: var(--font-ui); font-size: var(--text-sm);
  font-weight: 700; color: var(--neutral-700); text-decoration: none;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
  transition: color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
}
.nav-links a:hover { color: var(--brand-900); background: var(--brand-50); }
.nav-links a[aria-current="page"] { color: var(--brand-900); background: var(--brand-50); }

/* live availability pip, as in the reference */
.nav-status {
  display: none; align-items: center; gap: var(--space-2);
  font-size: var(--text-sm); font-weight: 700; color: var(--neutral-700);
  margin-right: var(--space-4); white-space: nowrap;
}
@media (min-width: 1120px) { .nav-status { display: inline-flex; } }
.nav-status i {
  width: 9px; height: 9px; border-radius: 50%; background: #22A45D; flex: 0 0 auto;
  box-shadow: 0 0 0 0 rgb(34 164 93 / .55); animation: pip 2.4s ease-out infinite;
}
@keyframes pip {
  0%   { box-shadow: 0 0 0 0 rgb(34 164 93 / .55); }
  70%  { box-shadow: 0 0 0 8px rgb(34 164 93 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(34 164 93 / 0); }
}
.nav-cta { margin-left: 0; min-height: 50px; border-radius: var(--radius-md); }
@media (max-width: 1119px) { .nav-cta { display: none; } }

.nav-toggle {
  margin-left: auto;
  border-color: var(--neutral-300); display: inline-flex; flex-direction: column; gap: 5px;
  align-items: center; justify-content: center;
  width: 52px; height: 52px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-full); background: transparent; cursor: pointer;
}
@media (min-width: 1120px) { .nav-toggle { display: none; } }
.nav-toggle i { display: block; width: 18px; height: 1.5px; background: var(--brand-900); border-radius: 2px; }

.mobile-menu {
  position: fixed; inset: 0; z-index: 95; background: #181B39; color: #EAF2F8;
  display: flex; flex-direction: column; padding: var(--space-6);
  clip-path: circle(0% at calc(100% - 52px) 42px); visibility: hidden;
  transition: clip-path 600ms var(--ease-out), visibility 600ms;
}
.mobile-menu.is-open { clip-path: circle(150% at calc(100% - 52px) 42px); visibility: visible; }
.mobile-menu-top { display: flex; align-items: center; justify-content: space-between; min-height: 72px; }
.mobile-menu .brand span { color: #fff; }
.mobile-menu .brand img { filter: brightness(0) invert(1); }
.mobile-menu nav { display: flex; flex-direction: column; margin-top: var(--space-8); }
.mobile-menu nav a {
  font-family: var(--font-display); font-size: clamp(2rem, 9vw, 2.75rem); font-weight: 700;
  text-transform: uppercase; letter-spacing: -0.01em; line-height: 1.1;
  color: #EAF2F8; text-decoration: none; padding-block: var(--space-3);
  border-bottom: 1px solid rgba(216,242,255,.14);
  opacity: 0; transform: translateY(20px);
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out), color 150ms;
}
.mobile-menu.is-open nav a { opacity: 1; transform: none; }
.mobile-menu.is-open nav a:nth-child(1) { transition-delay: 180ms; }
.mobile-menu.is-open nav a:nth-child(2) { transition-delay: 230ms; }
.mobile-menu.is-open nav a:nth-child(3) { transition-delay: 280ms; }
.mobile-menu.is-open nav a:nth-child(4) { transition-delay: 330ms; }
.mobile-menu.is-open nav a:nth-child(5) { transition-delay: 380ms; }
.mobile-menu.is-open nav a:nth-child(6) { transition-delay: 430ms; }
.mobile-menu.is-open nav a:nth-child(7) { transition-delay: 480ms; }
.mobile-menu nav a[aria-current="page"] { color: #D8F2FF; }
.mobile-menu > .btn { margin-top: var(--space-10, 40px); background: #D8F2FF; color: #1B2966; }
.menu-close {
  width: 52px; height: 52px; border: 1px solid rgba(216,242,255,.35);
  border-radius: var(--radius-full); background: transparent; cursor: pointer;
  font-size: 1.6rem; line-height: 1; color: #EAF2F8;
}

.skip-link {
  position: absolute; left: var(--space-4); top: -100px; z-index: 100;
  background: var(--brand-900); color: #fff; padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md); font-size: var(--text-sm); font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: var(--space-4); color: #fff; }

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

.grid { display: grid; gap: var(--space-6); }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
@media (min-width: 720px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 940px) { .grid-3 { grid-template-columns: repeat(3, 1fr); gap: var(--space-8); } }

/* Editorial cards: no shadow at rest, a hairline and a numeral. The whole
   card lifts and the rule fills on hover. */
.card {
  position: relative; background: var(--surface-raised);
  border: 1px solid var(--border-default); border-radius: var(--radius-xl);
  padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-4);
  overflow: hidden;
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out),
              border-color 500ms var(--ease-out);
}
.ink .card { background: var(--surface-glass); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.card::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--brand); transform: scaleX(0); transform-origin: left;
  transition: transform 600ms var(--ease-out);
}
.card:hover { transform: translateY(-6px); box-shadow: var(--elevation-3); border-color: var(--border-strong); }
.card:hover::after { transform: scaleX(1); }
.card h3 { font-size: var(--text-xl); }
.card p { color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-normal); }
.card .arrow-link { margin-top: auto; }
.card-art { margin: calc(var(--space-4) * -1) 0 0; }

/* 3D tilt — applied by JS on pointer devices only */
.tilt { transform-style: preserve-3d; will-change: transform; }
.tilt > * { transform: translateZ(30px); }

.card-index {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  letter-spacing: .16em; color: var(--brand); font-variant-numeric: tabular-nums;
}

/* Asymmetric two-column head: heading stays left and short, content runs
   right. Stops long-form sections leaving half the page empty. */
.split-head { display: grid; gap: var(--space-12); }
@media (min-width: 940px) {
  .split-head { grid-template-columns: 0.85fr 1.15fr; gap: var(--space-16); align-items: start; }
  .split-head > *:first-child { position: sticky; top: 120px; }
}

/* --------------------------------------------------------- editorial rows */

/* Alternating full-width feature rows: art one side, text the other. */
.feature { display: grid; gap: var(--space-12); align-items: center; }
@media (min-width: 900px) {
  .feature { grid-template-columns: 1fr 1fr; gap: var(--space-24); }
  .feature.flip > *:first-child { order: 2; }
}
.feature + .feature { margin-top: var(--space-24); }

.problem-list { list-style: none; padding: 0; margin: var(--space-8) 0 0; }
.problem-list li {
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-6);
  align-items: baseline; padding-block: var(--space-6);
  border-top: 1px solid var(--border-default);
  color: var(--text-secondary); line-height: var(--leading-normal);
  transition: color var(--duration-fast) var(--ease-out);
}
.problem-list li:last-child { border-bottom: 1px solid var(--border-default); }
.problem-list li:hover { color: var(--text-primary); }
.problem-list li::before {
  content: counter(pl, decimal-leading-zero); counter-increment: pl;
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  letter-spacing: .1em; color: var(--brand); font-variant-numeric: tabular-nums;
}
.problem-list { counter-reset: pl; }

.props { display: grid; gap: 0; }
@media (min-width: 800px) { .props { grid-template-columns: repeat(2, 1fr); } }
.prop {
  padding: var(--space-10, 40px) var(--space-8) var(--space-10, 40px) 0;
  border-top: 1px solid var(--border-default);
}
@media (min-width: 800px) { .prop:nth-child(odd) { padding-right: var(--space-16); } }
.prop h4 { margin-bottom: var(--space-3); }
.prop p { color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-normal); margin: 0; }
.prop-num {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-xs);
  letter-spacing: .16em; color: var(--brand); display: block; margin-bottom: var(--space-4);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- counters -- */

.stats { display: grid; gap: var(--space-8); }
@media (min-width: 760px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat-big { border-top: 1px solid var(--border-default); padding-top: var(--space-6); }
.stat-big b {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2.5rem, 1.4rem + 3.4vw, 4rem); line-height: 1;
  color: var(--brand); font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.stat-big span { font-size: var(--text-xs); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-muted); display: block; margin-top: var(--space-3); }

/* -------------------------------------------------------------- pricing -- */

.tiers { display: grid; gap: var(--space-6); align-items: stretch; }
@media (min-width: 1000px) { .tiers { grid-template-columns: repeat(3, 1fr); } }
.tier {
  position: relative; background: var(--surface-raised);
  border: 1px solid var(--border-default); border-radius: var(--radius-xl);
  padding: var(--space-10, 40px) var(--space-8); display: flex; flex-direction: column; gap: var(--space-5, 20px);
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out);
}
.tier:hover { transform: translateY(-6px); box-shadow: var(--elevation-3); }
.tier.is-featured {
  border-color: transparent; box-shadow: var(--elevation-4);
  background:
    linear-gradient(var(--surface-raised), var(--surface-raised)) padding-box,
    linear-gradient(150deg, var(--brand-900), var(--brand-300), var(--brand-50)) border-box;
  border: 2px solid transparent;
}
@media (min-width: 1000px) { .tier.is-featured { transform: scale(1.04); } .tier.is-featured:hover { transform: scale(1.04) translateY(-6px); } }
.tier-badge {
  position: absolute; top: -13px; left: var(--space-8);
  background: var(--brand-900); color: #fff;
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
}
.tier h3 { font-size: var(--text-xl); text-transform: uppercase; letter-spacing: .04em; }
.tier .tier-for { font-size: var(--text-sm); color: var(--text-muted); margin: 0; }
.tier-price {
  font-family: var(--font-display); font-weight: 700; font-size: clamp(2.5rem, 4vw, 3.25rem);
  line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
  color: var(--text-primary);
}
.tier-price small { font-family: var(--font-ui); font-size: var(--text-sm); font-weight: 400;
  color: var(--text-muted); letter-spacing: 0; text-transform: none; }
.tier ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.tier li {
  display: grid; grid-template-columns: 20px 1fr; gap: var(--space-3);
  font-size: var(--text-sm); line-height: var(--leading-normal); color: var(--text-secondary);
}
.tier li::before { content: "→"; color: var(--brand); font-weight: 700; }
.tier .btn { margin-top: auto; width: 100%; }

/* --------------------------------------------------------------- table --- */

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; min-width: 560px; }
th, td { text-align: left; padding: var(--space-6) var(--space-6) var(--space-6) 0;
  border-bottom: 1px solid var(--border-default); font-size: var(--text-sm);
  line-height: var(--leading-normal); }
th { font-family: var(--font-display); font-weight: 700; font-size: var(--text-xs);
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
  border-bottom-color: var(--border-strong); padding-block: var(--space-4); }
td:first-child { font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg);
  color: var(--text-primary); width: 34%; }
td { color: var(--text-secondary); }
tbody tr { transition: background var(--duration-fast) var(--ease-out); }
tbody tr:hover { background: var(--brand-subtle); }
.num { font-variant-numeric: tabular-nums; text-align: right; }

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

.faq { border-top: 1px solid var(--border-strong); max-width: var(--measure); }
.faq details { border-bottom: 1px solid var(--border-default); }
.faq summary {
  cursor: pointer; list-style: none; padding: var(--space-8) var(--space-10, 40px) var(--space-8) 0;
  font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 600;
  text-transform: uppercase; letter-spacing: -0.005em; line-height: 1.15;
  position: relative; color: var(--text-primary);
  transition: color var(--duration-fast) var(--ease-out);
}
.faq summary:hover { color: var(--brand); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 6px; top: 50%; width: 16px; height: 2px;
  background: var(--brand); transform: translateY(-50%);
}
.faq summary::before {
  content: ""; position: absolute; right: 13px; top: 50%; width: 2px; height: 16px;
  background: var(--brand); transform: translateY(-50%);
  transition: transform var(--duration-normal) var(--ease-out), opacity var(--duration-fast);
}
.faq details[open] summary::before { transform: translateY(-50%) rotate(90deg); opacity: 0; }
.faq details > div { padding-bottom: var(--space-8); color: var(--text-secondary); max-width: 62ch; }

/* --------------------------------------------------------------- forms --- */

.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-6); }
.field label { font-size: var(--text-xs); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted); }
.field label .opt { font-weight: 400; letter-spacing: 0; text-transform: none; }
.field input, .field textarea, .field select {
  font-family: var(--font-ui); font-size: var(--text-base); line-height: 1.4;
  padding: var(--space-4) 0; width: 100%;
  border: none; border-bottom: 1px solid var(--border-strong); border-radius: 0;
  background: transparent; color: var(--text-primary);
  transition: border-color var(--duration-normal) var(--ease-out);
}
.field textarea { min-height: 130px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-muted); }
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--brand); }
.field input:focus-visible, .field textarea:focus-visible { box-shadow: 0 2px 0 0 var(--brand); }
.field .hint { font-size: var(--text-xs); color: var(--text-muted); }
.field.has-error input, .field.has-error textarea { border-bottom-color: var(--danger); }
.field.has-error .hint { color: var(--danger); font-weight: 700; }

.inline-form { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: flex-end; }
.inline-form .field { flex: 1 1 280px; margin-bottom: 0; }
.form-note { font-size: var(--text-sm); color: var(--text-muted); margin-top: var(--space-6); }
.form-status { margin-top: var(--space-4); font-size: var(--text-sm); font-weight: 700; }
.form-status[data-state="ok"]  { color: var(--success); }
.form-status[data-state="err"] { color: var(--danger); }

/* -------------------------------------------------------------- badges --- */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-full);
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.badge-brand   { background: var(--brand-subtle);   color: var(--brand); }
.badge-success { background: var(--success-subtle); color: var(--success); }
.badge-warning { background: var(--warning-subtle); color: var(--warning); }
.badge-danger  { background: var(--danger-subtle);  color: var(--danger); }
.badge-info    { background: var(--info-subtle);    color: var(--info); }

.placeholder-flag {
  background: var(--warning-subtle); color: var(--warning);
  border: 1px dashed var(--warning); border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-6); font-size: var(--text-xs); font-weight: 700;
  display: flex; gap: var(--space-3); align-items: flex-start; line-height: 1.5;
}

/* ---------------------------------------------------------- quote/note --- */

blockquote { margin: 0; padding: 0; max-width: 24ch; }
blockquote.pull {
  max-width: none; position: relative; padding-left: var(--space-12);
}
blockquote.pull::before {
  content: "“"; position: absolute; left: -8px; top: -0.25em;
  font-family: var(--font-display); font-size: 7rem; line-height: 1;
  color: var(--brand); opacity: .25;
}
blockquote p {
  font-family: var(--font-display); font-weight: 600; text-transform: none;
  font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); line-height: 1.2;
  letter-spacing: -0.015em; color: var(--text-primary);
}
blockquote cite { display: block; margin-top: var(--space-6); font-style: normal;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-muted); }
blockquote cite strong { color: var(--brand); font-weight: 700; }

.callout {
  border-left: 2px solid var(--brand); padding: var(--space-4) var(--space-6);
  font-size: var(--text-sm); color: var(--text-secondary); max-width: var(--measure);
}
.callout strong { color: var(--text-primary); }

/* ---------------------------------------------------------------- quiz --- */

.quiz-panel {
  position: relative; background: var(--surface-raised);
  border: 1px solid var(--border-default); border-radius: var(--radius-xl);
  box-shadow: var(--elevation-4); padding: var(--space-8);
  max-width: 780px; margin-inline: auto; z-index: 2;
}
.ink .quiz-panel { background: var(--surface-glass); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
@media (min-width: 720px) { .quiz-panel { padding: var(--space-16); } }

.quiz-progress { height: 2px; background: var(--border-default); overflow: hidden; margin-bottom: var(--space-10, 40px); }
.quiz-progress > i { display: block; height: 100%; background: var(--brand); width: 0;
  transition: width 500ms var(--ease-out); }

.quiz-step { display: none; }
.quiz-step.is-active { display: block; animation: qIn 550ms var(--ease-out); }
@keyframes qIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.quiz-count { font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--space-4); }
.quiz-q { font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem); line-height: 1.08;
  letter-spacing: -0.015em; margin-bottom: var(--space-10, 40px); color: var(--text-primary); }

.quiz-options { display: grid; gap: var(--space-3); }
.quiz-option {
  position: relative; display: flex; align-items: center; gap: var(--space-5, 20px);
  padding: var(--space-5, 20px) var(--space-6); text-align: left; overflow: hidden;
  border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  background: transparent; color: var(--text-primary);
  font-family: var(--font-ui); font-size: var(--text-base); line-height: 1.4; cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out), color var(--duration-fast);
}
.quiz-option::before {
  content: ""; position: absolute; inset: 0; background: var(--brand);
  transform: translateX(-101%); transition: transform 420ms var(--ease-out); z-index: 0;
}
.quiz-option > * { position: relative; z-index: 1; }
.quiz-option:hover { border-color: var(--brand); color: var(--text-on-brand); }
.quiz-option:hover::before { transform: translateX(0); }
.quiz-option .key {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: var(--radius-full);
  border: 1px solid var(--border-strong); display: grid; place-items: center;
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  color: var(--text-muted); transition: border-color var(--duration-fast), color var(--duration-fast);
}
.quiz-option:hover .key { border-color: var(--text-on-brand); color: var(--text-on-brand); }
.quiz-back { margin-top: var(--space-8); }

.quiz-score { font-family: var(--font-display); font-weight: 700;
  font-size: clamp(4rem, 3rem + 5vw, 7rem); line-height: 0.9;
  font-variant-numeric: tabular-nums; letter-spacing: -0.03em; color: var(--brand); }
.quiz-result-head { display: flex; align-items: flex-end; gap: var(--space-6);
  margin-bottom: var(--space-8); flex-wrap: wrap; }
.quiz-weak { list-style: none; padding: 0; margin: var(--space-6) 0 0; }
.quiz-weak li {
  display: grid; grid-template-columns: 24px 1fr; gap: var(--space-4);
  font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-normal);
  padding-block: var(--space-4); border-top: 1px solid var(--border-default);
}
.quiz-weak li::before { content: "→"; color: var(--brand); font-weight: 700; }

/* ---------------------------------------------------------------- blog --- */

.post-card { position: relative; display: flex; flex-direction: column; }
.post-thumb {
  aspect-ratio: 16 / 10; border-radius: var(--radius-lg); overflow: hidden; position: relative;
  background: linear-gradient(150deg, var(--brand-900), var(--brand-500));
}
.post-thumb .art-lines { top: 50%; transform: translateY(-50%); height: 100%; }
.post-card:hover .post-thumb::after {
  transform: scale(1);
}
.post-thumb::after {
  content: ""; position: absolute; inset: 0; background: var(--brand-50); opacity: .14;
  transform: scale(0); transform-origin: bottom;
  transition: transform 600ms var(--ease-out);
}
.post-body { padding: var(--space-6) 0 0; display: flex; flex-direction: column; gap: var(--space-3); }
.post-meta { font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); }
.post-card h3 { font-size: var(--text-xl); text-transform: none; }
.post-card h3 a { color: var(--text-primary); text-decoration: none; }
.post-card:hover h3 a { color: var(--brand); }
.post-card p { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-normal); margin: 0; }

.chips { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-8); }
.chip {
  padding: var(--space-3) var(--space-5, 20px); border-radius: var(--radius-full);
  border: 1px solid var(--border-default); background: transparent;
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-secondary); text-decoration: none;
  transition: all var(--duration-fast) var(--ease-out);
}
.chip:hover, .chip[aria-current="true"] { background: var(--brand); border-color: var(--brand); color: var(--text-on-brand); }

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

.case { display: grid; gap: var(--space-12); padding-block: var(--space-24);
  border-top: 1px solid var(--border-default); }
@media (min-width: 940px) { .case { grid-template-columns: 0.95fr 1.05fr; gap: var(--space-16); align-items: start; } }
.case dl { display: grid; gap: var(--space-8); margin: var(--space-8) 0 0; }
.case dt { font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: var(--brand); margin-bottom: var(--space-3); }
.case dd { margin: 0; color: var(--text-secondary); line-height: var(--leading-normal); }
.stat-row { display: flex; flex-wrap: wrap; gap: var(--space-10, 40px); margin-top: var(--space-10, 40px);
  padding-top: var(--space-6); border-top: 1px solid var(--border-default); }
.stat b { display: block; font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 700;
  color: var(--brand); font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -0.02em; }
.stat span { font-size: var(--text-xs); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted); display: block; margin-top: var(--space-2); }

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

.site-footer { padding-block: var(--space-24) var(--space-8); position: relative; overflow: hidden; }
.site-footer a { color: var(--text-secondary); text-decoration: none; font-size: var(--text-sm); }
.site-footer a:hover { color: var(--brand); }
.footer-mark {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(3.5rem, 12vw, 11rem); line-height: 0.85; letter-spacing: -0.03em;
  color: var(--text-primary); opacity: .10; margin-bottom: var(--space-12); user-select: none;
}
.footer-grid { display: grid; gap: var(--space-12); }
@media (min-width: 760px) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; } }
.footer-brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-5, 20px); }
.footer-brand img { width: 40px; height: 40px; filter: brightness(0) invert(1); }
.footer-brand span { font-family: var(--font-display); font-weight: 700; font-size: 1.15rem;
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-primary); }
.site-footer h5 { font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 var(--space-5, 20px); }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.site-footer li { font-size: var(--text-sm); color: var(--text-secondary); }
.site-footer p { font-size: var(--text-sm); color: var(--text-secondary); }
.footer-bottom {
  margin-top: var(--space-16); padding-top: var(--space-6);
  border-top: 1px solid var(--border-default);
  display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: space-between;
  font-size: var(--text-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted);
}
.footer-bottom a { font-size: var(--text-xs); letter-spacing: .1em; text-transform: uppercase; }

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  /* Show everything that motion would otherwise have revealed. Feedback
     (colour, opacity on hover) still works; only travel is removed. */
  .reveal, .reveal-scale { opacity: 1; transform: none; }
  .reveal-lines .rl > span { transform: none; }
  .underscore::after { transform: scaleX(1); }
  .art-draw .draw { stroke-dashoffset: 0; }
  .gauge-arc { stroke-dashoffset: var(--to); }
  .marquee-track { animation: none; }
  .art-mesh animate, .art-mesh animateTransform { display: none; }
}

/* ==========================================================================
   Light hero, custom cursor, and the richer section treatments
   ========================================================================== */

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

.hero-light {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, #E4F3FE 0%, var(--brand-50) 42%, #EDF7FE 100%);
  padding-block: clamp(120px, 15vh, 180px) clamp(80px, 11vh, 130px);
  text-align: center;
}
.hero-light::after {          /* soft fade into whatever follows */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 140px;
  background: linear-gradient(180deg, transparent, var(--surface-canvas));
  pointer-events: none; z-index: 1;
}
.hero-light .shell { max-width: 1080px; }
.hero-light .display { margin-inline: auto; max-width: 30ch; color: var(--brand-900); }
@media (max-width: 720px) { .hero-light .display { max-width: 16ch; } }
.hero-light .lede {
  margin: var(--space-8) auto 0; max-width: 62ch; text-align: center;
  color: var(--brand-700);
}
.hero-light .btn-row { justify-content: center; }

/* the pill above the headline */
.pill {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-6); border-radius: var(--radius-full);
  background: rgb(255 255 255 / .72); border: 1px solid rgb(27 41 102 / .10);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--brand-900);
  margin-bottom: var(--space-8); backdrop-filter: blur(6px);
}
.pill i { width: 7px; height: 7px; border-radius: 50%; background: #E8A33D; flex: 0 0 auto; }

/* trust strip under the hero buttons */
.hero-trust {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--space-6) var(--space-10, 40px); margin-top: var(--space-12);
  padding-top: var(--space-8); border-top: 1px solid rgb(27 41 102 / .10);
}
.hero-trust div { text-align: center; }
.hero-trust b {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: var(--text-2xl); line-height: 1; color: var(--brand-900);
  font-variant-numeric: tabular-nums;
}
.hero-trust span {
  display: block; margin-top: var(--space-2); font-size: var(--text-xs);
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand-700); opacity: .75;
}

/* decorative art behind the light hero */
.hero-light .art-lines { top: auto; bottom: -6%; opacity: .5; }
.hero-orb {
  position: absolute; border-radius: 50%; pointer-events: none; z-index: 0;
  background: radial-gradient(circle at 38% 32%, rgb(255 255 255 / .85), rgb(255 255 255 / 0) 62%);
  filter: blur(18px);
}

/* ------------------------------------------------------ custom cursor ----- */
/* Two elements: a dot that tracks exactly, and a ring that lags. Rendered only
   for fine pointers, and switched off entirely for reduced motion — a lagging
   ring is exactly the kind of continuous motion that causes trouble. */

.cursor-dot, .cursor-ring {
  position: fixed; top: 0; left: 0; z-index: 9999; pointer-events: none;
  border-radius: 50%; opacity: 0;
  transition: opacity 200ms var(--ease-out);
  mix-blend-mode: normal;
}
.cursor-dot  { width: 7px;  height: 7px;  background: var(--brand-900); }
.cursor-ring {
  width: 36px; height: 36px; border: 1.5px solid rgb(27 41 102 / .45);
  transition: opacity 200ms var(--ease-out), width 260ms var(--ease-out),
              height 260ms var(--ease-out), background 260ms var(--ease-out),
              border-color 260ms var(--ease-out);
}
body.cursor-on .cursor-dot, body.cursor-on .cursor-ring { opacity: 1; }
body.cursor-on .cursor-ring.is-hot {
  width: 64px; height: 64px;
  background: rgb(27 41 102 / .10); border-color: rgb(27 41 102 / .75);
}
/* over dark bands the cursor inverts so it never disappears */
body.cursor-on .cursor-dot.on-ink  { background: var(--brand-50); }
body.cursor-on .cursor-ring.on-ink { border-color: rgb(216 242 255 / .55); }
body.cursor-on .cursor-ring.on-ink.is-hot {
  background: rgb(216 242 255 / .14); border-color: rgb(216 242 255 / .85);
}
@media (hover: none), (pointer: coarse) { .cursor-dot, .cursor-ring { display: none; } }

/* ------------------------------------------------------------- bento ----- */
/* The "why me" section. Four equal paragraphs in a 2×2 grid read as filler;
   uneven tiles with art in the large ones give the eye somewhere to go. */

.bento { display: grid; gap: var(--space-4); }
@media (min-width: 860px) {
  .bento {
    grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: minmax(180px, auto);
    gap: var(--space-5, 20px);
  }
  .bento > *:nth-child(1) { grid-column: span 4; grid-row: span 2; }
  .bento > *:nth-child(2) { grid-column: span 2; }
  .bento > *:nth-child(3) { grid-column: span 2; }
  .bento > *:nth-child(4) { grid-column: span 3; }
  .bento > *:nth-child(5) { grid-column: span 3; }
}
.bento-tile {
  position: relative; overflow: hidden;
  background: var(--surface-raised); border: 1px solid var(--border-default);
  border-radius: var(--radius-xl); padding: var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-3);
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out),
              border-color 500ms var(--ease-out);
}
.bento-tile:hover {
  transform: translateY(-5px); box-shadow: 0 18px 40px rgb(27 41 102 / .10);
  border-color: rgb(27 41 102 / .22);
}
.bento-tile h4 { font-size: var(--text-xl); }
.bento-tile p { font-size: var(--text-sm); color: var(--text-secondary);
  line-height: var(--leading-normal); margin: 0; }
.bento-tile .prop-num { margin-bottom: 0; }
.bento-tile.is-feature {
  background: linear-gradient(150deg, var(--brand-900) 0%, #26356F 55%, #2C3F82 100%);
  border-color: transparent; color: #EAF2F8; justify-content: flex-end;
}
.bento-tile.is-feature h4 { color: #fff; font-size: var(--text-2xl); }
.bento-tile.is-feature p { color: var(--brand-100); font-size: var(--text-base); }
.bento-tile.is-feature .prop-num { color: var(--brand-50); }
/* Decoration, so it stays out of the reading path: pushed further out, much
   fainter, and the copy is capped so it never runs underneath the artwork. */
.bento-art {
  position: absolute; right: -14%; top: -22%; width: 52%; opacity: .22;
  pointer-events: none;
}
.bento-tile.is-feature .bento-art { opacity: .30; right: -6%; top: -10%; width: 46%; }
.bento-tile:has(.bento-art) p,
.bento-tile:has(.bento-art) h4 { max-width: 34ch; }
.bento-tile.is-feature:has(.bento-art) p,
.bento-tile.is-feature:has(.bento-art) h4 { max-width: 46ch; }
.bento-tile .stat-num {
  font-family: var(--font-display); font-weight: 700; line-height: 1;
  font-size: clamp(2.25rem, 3vw, 3rem); color: var(--brand);
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}

/* --------------------------------------------------------- problem rows -- */
/* Was a flat bulleted list. Each row now slides and lights up on hover, which
   turns a wall of text into something the eye tracks down. */

.problem-list li {
  position: relative; padding-inline: var(--space-6);
  border-radius: var(--radius-md);
  transition: color var(--duration-normal) var(--ease-out),
              background var(--duration-normal) var(--ease-out),
              padding-inline var(--duration-normal) var(--ease-out);
}
.problem-list li:hover {
  background: var(--brand-50); color: var(--text-primary);
  padding-inline: var(--space-8) var(--space-6);
}
.problem-list li::after {
  content: "→"; position: absolute; right: var(--space-6); top: 50%;
  transform: translateY(-50%) translateX(-8px); opacity: 0; color: var(--brand);
  transition: opacity var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
}
.problem-list li:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }

/* ---------------------------------------------------- testimonial strip -- */

.quote-grid { display: grid; gap: var(--space-6); }
@media (min-width: 900px) { .quote-grid { grid-template-columns: repeat(3, 1fr); } }
.quote-card {
  background: var(--surface-raised); border: 1px solid var(--border-default);
  border-radius: var(--radius-xl); padding: var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-6);
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out);
}
.quote-card:hover { transform: translateY(-5px); box-shadow: 0 18px 40px rgb(27 41 102 / .10); }
.quote-card p {
  font-size: var(--text-lg); line-height: var(--leading-snug);
  color: var(--text-primary); margin: 0;
}
.quote-who { display: flex; align-items: center; gap: var(--space-4); margin-top: auto; }
.quote-avatar {
  width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--brand-900); color: #fff;
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  letter-spacing: .04em;
}
.quote-who b { display: block; font-size: var(--text-sm); color: var(--text-primary); }
.quote-who span { display: block; font-size: var(--text-xs); color: var(--text-muted); }
.stars { color: #E8A33D; font-size: var(--text-sm); letter-spacing: .12em; }

/* ------------------------------------------------------------ pre-footer - */
/* The final CTA used to be dark and sat directly on a dark footer, so the two
   ran together as one long slab. Light CTA, dark footer, clean seam. */

.pre-footer {
  background: linear-gradient(180deg, var(--surface-canvas) 0%, var(--tint-200) 45%, #FFFFFF 100%);
  position: relative; overflow: hidden; text-align: center;
}
.pre-footer .shell { max-width: 860px; }
.pre-footer h2 { color: var(--brand-900); }
.pre-footer .lede { margin-inline: auto; text-align: center; color: var(--brand-700); }
.pre-footer .btn-row { justify-content: center; }
.pre-footer .rule-num { justify-content: center; }

.site-footer { border-top: 3px solid var(--brand-900); }

/* ---------------------------------------------------------------- misc --- */

.dummy { /* marks invented content; see README */ }

.section-head.center { margin-inline: auto; text-align: center; }
.section-head.center .lede { margin-inline: auto; }
.section-head.center .rule-num { justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none !important; }
  .nav-status i { animation: none; }
}

/* Sections that fade back out once scrolled past. Applied to section headers
   only — fading body copy out while someone is still reading it would be
   actively hostile. */
.fade-out { transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out); }
.fade-out.is-out { opacity: 0; transform: translateY(-24px); }
@media (prefers-reduced-motion: reduce) {
  .fade-out.is-out { opacity: 1; transform: none; }
}

/* ==========================================================================
   COLOUR COVERAGE PASS
   No layout changes — the flatness came from two colours covering very little
   surface, not from the structure. This adds tint, panels and accent, all in
   CSS, so every existing template keeps working unchanged.
   ========================================================================== */

/* ---- tinted rounded panels ------------------------------------------------
   The single biggest change. Dark and ice bands become inset rounded panels
   instead of full-bleed slabs, which is what gives the reference its layered
   feel. Pure CSS — the sections already carry overflow:hidden for their art. */

@media (min-width: 900px) {
  .ink, .band-ice, .pre-footer {
    border-radius: var(--panel-radius);
    margin-inline: var(--space-6);
  }
  /* the panel needs air around it or it reads as a broken full-bleed band */
  .ink + section, .band-ice + section, .pre-footer + .site-footer { margin-top: 0; }
}
@media (min-width: 1500px) {
  .ink, .band-ice, .pre-footer { margin-inline: clamp(24px, 4vw, 72px); }
}

/* alternate untinted sections get the faintest wash, so no two adjacent
   sections are both pure canvas */
section:not(.ink):not(.band-ice):not(.pre-footer):not(.hero-light):nth-of-type(even) {
  background: var(--tint-50);
}

/* ---- cards gain a tint wash on hover -------------------------------------- */

.card::before, .bento-tile::before, .quote-card::before, .tier::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(155deg, var(--tint-200), transparent 62%);
  opacity: 0; transition: opacity 450ms var(--ease-out); pointer-events: none;
}
.card > *, .bento-tile > *, .quote-card > *, .tier > * { position: relative; z-index: 1; }
.card:hover::before, .quote-card:hover::before, .tier:hover::before { opacity: 1; }
.bento-tile:not(.is-feature):hover::before { opacity: 1; }
.ink .card::before { background: linear-gradient(155deg, rgb(216 242 255 / .10), transparent 62%); }
.bento-tile.is-feature::before { display: none; }

/* a cursor-tracking glow inside cards — set by JS as --mx/--my percentages */
.card, .bento-tile, .tier, .quote-card { position: relative; overflow: hidden; }
.card::after, .bento-tile::after, .tier::after, .quote-card::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: 0; transition: opacity 400ms var(--ease-out);
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgb(27 41 102 / .07), transparent 62%);
}
.ink .card::after, .bento-tile.is-feature::after {
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgb(216 242 255 / .13), transparent 62%);
}
.card:hover::after, .bento-tile:hover::after,
.tier:hover::after, .quote-card:hover::after { opacity: 1; }
/* the top rule already uses ::after on .card — keep it above the glow */
.card { --_rule: 0; }

/* ---- highlight blocks ------------------------------------------------------
   Navy-filled panels for things that should stop the eye. Uses the exact brand
   navy, and white on it is 13.53:1. */

.highlight {
  background: var(--ink-900); color: #fff;
  border-radius: var(--radius-xl); padding: var(--space-10, 40px) var(--space-8);
  position: relative; overflow: hidden;
}
.highlight h2, .highlight h3, .highlight h4 { color: #fff; }
.highlight p { color: var(--tint-300); }
.highlight .prop-num, .highlight .card-index { color: var(--tint-300); }

/* ---- ratings and status ---------------------------------------------------- */

.stars { color: var(--rating); letter-spacing: .1em; }
.nav-status i { background: var(--status-live); box-shadow: 0 0 0 0 rgb(63 151 88 / .55); }
@keyframes pip {
  0%   { box-shadow: 0 0 0 0 rgb(63 151 88 / .55); }
  70%  { box-shadow: 0 0 0 8px rgb(63 151 88 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(63 151 88 / 0); }
}

/* ---- avatars pick up colour ------------------------------------------------ */

.quote-avatar { background: var(--ink-900); }
.quote-card:nth-child(2) .quote-avatar { background: var(--brand-600); }
.quote-card:nth-child(3) .quote-avatar { background: var(--brand-500); }

/* ---- section numerals get a tinted chip ------------------------------------ */

.rule-num .num {
  background: var(--tint-300); color: var(--ink-900);
  padding: var(--space-1) var(--space-3); border-radius: var(--radius-full);
}
.ink .rule-num .num { background: rgb(216 242 255 / .14); color: var(--tint-300); }

/* ---- problem rows: number chips -------------------------------------------- */

.problem-list li::before {
  background: var(--tint-200); color: var(--ink-900);
  width: 34px; height: 34px; border-radius: var(--radius-full);
  display: grid; place-items: center;
  transition: background 300ms var(--ease-out), color 300ms var(--ease-out);
}
.problem-list li:hover::before { background: var(--ink-900); color: #fff; }

/* ---- featured tier: an animated gradient edge ------------------------------- */

@property --tier-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.tier.is-featured {
  background:
    linear-gradient(var(--surface-raised), var(--surface-raised)) padding-box,
    conic-gradient(from var(--tier-angle),
      var(--ink-900), var(--brand-300), var(--tint-300), var(--brand-500), var(--ink-900)) border-box;
  animation: tierSpin 9s linear infinite;
}
@keyframes tierSpin { to { --tier-angle: 360deg; } }
@media (prefers-reduced-motion: reduce) { .tier.is-featured { animation: none; } }

/* ---- sticky CTA bar after the hero ----------------------------------------- */

.sticky-cta {
  position: fixed; left: 50%; bottom: var(--space-6); z-index: 70;
  transform: translate(-50%, 140%);
  display: flex; align-items: center; gap: var(--space-5, 20px);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6);
  background: var(--ink-900); color: #fff;
  border-radius: var(--radius-full); box-shadow: 0 12px 40px rgb(27 41 102 / .34);
  transition: transform 500ms var(--ease-out);
  max-width: calc(100vw - var(--space-8));
}
.sticky-cta.is-up { transform: translate(-50%, 0); }
.sticky-cta span {
  font-size: var(--text-sm); font-weight: 700; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.sticky-cta .btn { min-height: 44px; background: var(--tint-300); color: var(--ink-900); }
.sticky-cta .btn::before { background: #fff; }
.sticky-cta .close {
  background: none; border: none; color: var(--tint-300); cursor: pointer;
  font-size: 1.3rem; line-height: 1; padding: 0 var(--space-2);
}
/* On a phone the pill cannot hold a sentence and a button on one line. It used
   to hide the sentence, which left a bar that said only "Check my site" with no
   reason to. It now becomes a small card: the line wraps above a full-width
   button, so the offer is still readable. */
@media (max-width: 620px) {
  .sticky-cta {
    left: var(--space-4); right: var(--space-4); bottom: var(--space-4);
    transform: translateY(180%);
    max-width: none; width: auto;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 14px var(--space-3);
    border-radius: 22px;
    padding: 18px 16px 18px 20px;
  }
  .sticky-cta.is-up { transform: translateY(0); }
  .sticky-cta span {
    white-space: normal; overflow: visible; text-overflow: clip;
    font-size: .875rem; line-height: 1.35;
  }
  .sticky-cta .close { grid-column: 2; grid-row: 1; align-self: start; }
  .sticky-cta .btn {
    grid-column: 1 / -1; grid-row: 2;
    width: 100%; justify-content: center;
  }
}
@media (prefers-reduced-motion: reduce) { .sticky-cta { transition: none; } }

/* ---- photo frame with floating badges --------------------------------------- */

.photo-wrap { position: relative; }
.photo-frame {
  position: relative; border-radius: var(--panel-radius); overflow: hidden;
  aspect-ratio: 4 / 5;
  background: linear-gradient(165deg, var(--tint-400), var(--tint-200) 55%, var(--tint-50));
  display: grid; place-items: center; padding: var(--space-8);
  text-align: center; color: var(--brand-700); font-size: var(--text-sm);
}
.photo-frame img { width: 100%; height: 100%; object-fit: cover; }
.float-badge {
  position: absolute; z-index: 3;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
  background: #fff; color: var(--ink-900);
  border: 1px solid rgb(27 41 102 / .10);
  box-shadow: 0 8px 24px rgb(27 41 102 / .12);
  font-size: var(--text-xs); font-weight: 700; white-space: nowrap;
  animation: floaty 6s ease-in-out infinite;
}
.float-badge i { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-500); }
.float-badge.is-live i { background: var(--status-live); }
.float-badge:nth-of-type(2) { animation-delay: -2s; }
.float-badge:nth-of-type(3) { animation-delay: -4s; }
@keyframes floaty { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
@media (prefers-reduced-motion: reduce) { .float-badge { animation: none; } }

.rating-card {
  position: absolute; z-index: 3; left: -6%; bottom: 12%;
  background: #fff; border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5, 20px);
  box-shadow: 0 14px 40px rgb(27 41 102 / .16); border: 1px solid rgb(27 41 102 / .08);
}
.rating-card b { display: block; font-family: var(--font-display); font-size: var(--text-xl);
  color: var(--ink-900); line-height: 1; }
.rating-card span { font-size: var(--text-xs); color: var(--text-muted); }

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

.plugin-card {
  position: relative; overflow: hidden;
  background: var(--surface-raised); border: 1px solid var(--border-default);
  border-radius: var(--panel-radius); padding: var(--space-10, 40px);
  display: flex; flex-direction: column; gap: var(--space-5, 20px);
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out);
}
.plugin-card:hover { transform: translateY(-5px); box-shadow: 0 20px 48px rgb(27 41 102 / .12); }
.plugin-card.is-featured {
  background: linear-gradient(158deg, var(--ink-900) 0%, #24316F 52%, #2C3F82 100%);
  border-color: transparent; color: #fff;
}
.plugin-card.is-featured h3, .plugin-card.is-featured h2 { color: #fff; }
.plugin-card.is-featured p { color: var(--tint-300); }
.plugin-meta { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.plugin-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
  background: var(--tint-200); color: var(--ink-900);
  font-size: var(--text-xs); font-weight: 700;
}
.is-featured .plugin-chip { background: rgb(216 242 255 / .14); color: var(--tint-300); }
.plugin-chip.is-live { background: rgb(63 151 88 / .14); color: #256B3B; }
.plugin-features { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.plugin-features li {
  display: grid; grid-template-columns: 22px 1fr; gap: var(--space-3);
  font-size: var(--text-sm); line-height: var(--leading-normal); color: var(--text-secondary);
}
.plugin-features li::before { content: "→"; color: var(--brand); font-weight: 700; }
.is-featured .plugin-features li { color: var(--tint-300); }
.is-featured .plugin-features li::before { color: var(--tint-300); }

/* The card's animated top rule used ::after, which the cursor glow above now
   claims. Re-implement the rule as a background-image on the card itself so
   both survive. background-color is set separately, or the shorthand would
   reset the image. */
.card {
  background-color: var(--surface-raised);
  background-image: linear-gradient(var(--brand), var(--brand));
  background-repeat: no-repeat;
  background-position: left top;
  background-size: 0% 2px;
  transition: transform 500ms var(--ease-out), box-shadow 500ms var(--ease-out),
              border-color 500ms var(--ease-out), background-size 600ms var(--ease-out);
}
.card:hover { background-size: 100% 2px; }
.ink .card {
  background-color: var(--surface-glass);
  background-image: linear-gradient(var(--brand), var(--brand));
}

/* Below desktop the photo column is full width, so badges hung outside it with
   negative offsets push the page sideways. Bring them inside the frame. */
@media (max-width: 899px) {
  .float-badge { font-size: 0.75rem; padding: var(--space-1) var(--space-3); }
  .float-badge[style*="right:-"] { right: 4% !important; }
  .float-badge[style*="left:-"]  { left: 4% !important; }
  .rating-card { left: 4%; bottom: 6%; padding: var(--space-3) var(--space-4); }
}

/* `.ink .card` sets `background:` (shorthand), which resets background-size to
   auto and has higher specificity than `.card`. That made the 2px top-rule
   gradient fill the entire card with solid ice. Restate the sizing here. */
.ink .card {
  background-size: 0% 2px;
  background-repeat: no-repeat;
  background-position: left top;
}
.ink .card:hover { background-size: 100% 2px; }

/* ==========================================================================
   Footer: navy crest → navy → light bar

   The wave is the footer's own top edge, not a separate band between two
   blocks. Its fill lands on #1B2966 at the bottom and the footer starts on
   #1B2966, so the two surfaces are continuous — there is no fade strip and
   nothing to see at the join.
   ========================================================================== */

.footer-lead {
  position: relative;
  background: #FFFFFF;
  margin-bottom: -1px;   /* kills the sub-pixel hairline some zoom levels show */
}
.wave { display: block; width: 100%; height: clamp(40px, 4.6vw, 72px); }

.site-footer {
  border-top: none;              /* the crest is the transition now */
  padding-block: var(--space-10, 40px) var(--space-8);
  margin-inline: 0 !important;   /* full bleed, never an inset panel */
  border-radius: 0 !important;
}

.footer-social { display: flex; justify-content: center; gap: var(--space-3);
  margin: var(--space-10, 40px) 0 0; }
.footer-social a {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid rgb(216 242 255 / .45);
  display: grid; place-items: center; color: var(--tint-300);
  transition: background var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.footer-social a:hover {
  background: var(--tint-300); color: var(--brand-900);
  border-color: var(--tint-300); transform: translateY(-3px);
}
.footer-social svg { width: 17px; height: 17px; fill: currentColor; }

.footer-bar {
  background: var(--tint-300); color: var(--brand-900);
  text-align: center; padding: 10px var(--space-6);
  font-size: var(--text-xs); letter-spacing: .02em;
}
.footer-bar strong { font-family: var(--font-display); letter-spacing: .06em; text-transform: uppercase; }

/* The watermark is centred above the columns and deliberately shorter than it
   was — it set the footer's whole height on its own before. */
.footer-mark {
  text-align: center;
  font-size: clamp(2.4rem, 8vw, 6.5rem);
  margin-bottom: var(--space-8);
  opacity: .08;
}

/* ==========================================================================
   Contact page
   ========================================================================== */

.contact-grid { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 940px) { .contact-grid { grid-template-columns: 1fr 1.15fr; gap: var(--space-12); } }

.contact-panel {
  background: var(--surface-raised); border: 1px solid var(--border-default);
  border-radius: var(--panel-radius); padding: var(--space-10, 40px);
}
.contact-panel.is-ink {
  background: linear-gradient(158deg, var(--brand-900) 0%, #24316F 55%, #2C3F82 100%);
  border-color: transparent; color: #fff; position: relative; overflow: hidden;
}
.contact-panel.is-ink h2, .contact-panel.is-ink h3 { color: #fff; }
.contact-panel.is-ink p { color: var(--tint-300); }

.detail-list { list-style: none; padding: 0; margin: var(--space-8) 0 0; display: grid; gap: var(--space-5, 20px); }
.detail-list li { display: grid; grid-template-columns: 44px 1fr; gap: var(--space-4); align-items: start; }
.detail-ico {
  width: 44px; height: 44px; border-radius: var(--radius-md);
  background: rgb(216 242 255 / .13); display: grid; place-items: center;
  color: var(--tint-300);
}
.detail-ico svg { width: 20px; height: 20px; fill: currentColor; }
.detail-list dt {
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: rgb(216 242 255 / .72); margin-bottom: 3px;
}
.detail-list dd { margin: 0; font-size: var(--text-base); color: #fff; }
.detail-list dd a { color: #fff; text-decoration: none; border-bottom: 1px solid rgb(216 242 255 / .4); }
.detail-list dd a:hover { border-bottom-color: #fff; }

.avail {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-5, 20px); border-radius: var(--radius-full);
  background: rgb(123 214 143 / .16); color: #A9E8B8;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}
.avail i { width: 8px; height: 8px; border-radius: 50%; background: #7BD68F; }

.field-row { display: grid; gap: var(--space-4); }
@media (min-width: 620px) { .field-row { grid-template-columns: 1fr 1fr; gap: var(--space-6); } }
.field select {
  font-family: var(--font-ui); font-size: var(--text-base);
  padding: var(--space-4) 0; width: 100%;
  border: none; border-bottom: 1px solid var(--border-strong); border-radius: 0;
  background: transparent; color: var(--text-primary);
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--brand) 50%),
                    linear-gradient(135deg, var(--brand) 50%, transparent 50%);
  background-position: calc(100% - 13px) calc(50% + 2px), calc(100% - 8px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field select:focus { outline: none; border-bottom-color: var(--brand); }

.svc-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .svc-grid { grid-template-columns: repeat(4, 1fr); } }
.svc-tile {
  background: var(--surface-raised); border: 1px solid var(--border-default);
  border-radius: var(--radius-lg); padding: var(--space-6) var(--space-5, 20px);
  text-align: center; transition: transform 400ms var(--ease-out),
              border-color 400ms var(--ease-out), box-shadow 400ms var(--ease-out);
}
.svc-tile:hover { transform: translateY(-4px); border-color: var(--brand-300);
  box-shadow: 0 14px 34px rgb(27 41 102 / .10); }
.svc-tile b { display: block; font-family: var(--font-display); font-size: var(--text-base);
  font-weight: 600; color: var(--text-primary); line-height: 1.25; }
.svc-num {
  display: inline-grid; place-items: center; width: 34px; height: 34px;
  border-radius: var(--radius-full); background: var(--tint-200); color: var(--brand-900);
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  margin-bottom: var(--space-3);
}

/* ==========================================================================
   Contact — rebuilt

   The old page was a form beside a details list. This one is built around the
   thing she actually wants people to do: book the call. The booking panel is
   the first thing under the hero, at full width, and everything after it is a
   fallback route for people who would rather not talk yet.
   ========================================================================== */

/* ---- the booking panel ---------------------------------------------- */
.booking {
  position: relative; overflow: hidden;
  border-radius: var(--panel-radius);
  padding: clamp(28px, 4.5vw, 64px);
  /* minmax(0,...) on every track: without it a grid item's automatic minimum
     size is its content, and the week strip inside .slotcard pushes the single
     mobile column wider than the panel — the panel's overflow:hidden then
     clips the copy mid-word instead of letting it wrap. */
  display: grid; gap: clamp(28px, 4vw, 56px);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 940px) {
  .booking { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); align-items: center; }
}
.booking > div { position: relative; z-index: 1; }

.booking h2 { font-size: var(--text-3xl); margin: var(--space-5, 20px) 0 0; }
.booking .lede { margin-top: var(--space-4); max-width: 44ch; }

.book-facts {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  margin-top: var(--space-8);
}
.book-facts span {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--tint-300);
  border: 1px solid rgb(216 242 255 / .3); border-radius: 999px;
  padding: 8px 14px;
  /* The line-art behind this panel crosses the chips and lifts the navy to
     ~rgb(88,106,152) where a stroke passes, which drops ice text to 4.12:1.
     A 70% navy fill puts a floor under the glyphs — 8.97:1 at the worst
     pixel — without flattening the art everywhere else. */
  background: rgb(27 41 102 / .7);
}
.book-facts b { font-family: var(--font-display); font-size: var(--text-sm);
  letter-spacing: .04em; color: #fff; }

/* The availability card. It shows the shape of a normal week, not real slots —
   the exact times live in Calendly, and the label says so. */
.slotcard {
  min-width: 0;
  background: rgb(216 242 255 / .07);
  border: 1px solid rgb(216 242 255 / .18);
  border-radius: 24px; padding: clamp(20px, 2.4vw, 30px);
  backdrop-filter: blur(2px);
}
.slotcard-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-6);
}
.slotcard-top h3 {
  font-family: var(--font-display); font-size: var(--text-lg, 1.25rem);
  color: #fff; margin: 0; letter-spacing: .01em;
}
.slotcard-top em {
  font-style: normal; font-size: var(--text-xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted);
}
.week { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; }
.day { display: grid; gap: 6px; justify-items: stretch; min-width: 0; }
.day > b {
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; text-align: center;
  color: var(--text-muted); margin-bottom: 2px;
}
.day i {
  display: block; height: 12px; border-radius: 4px;
  background: var(--tint-300); opacity: var(--o, .3);
  animation: slotIn 620ms var(--ease-out) both; animation-delay: var(--d, 0ms);
}
@keyframes slotIn { from { opacity: 0; transform: scaleX(.3); } }
.day i.is-off { background: rgb(216 242 255 / .16); opacity: 1; }
.slot-key {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  margin-top: var(--space-6); padding-top: var(--space-5, 20px);
  border-top: 1px dashed rgb(216 242 255 / .22);
  font-size: var(--text-xs); color: var(--text-secondary);
}
.slot-key span { display: inline-flex; align-items: center; gap: 7px; }
.slot-key i { width: 14px; height: 8px; border-radius: 3px; background: var(--tint-300); }
.slot-key i.dim { opacity: .34; }
.slot-key i.off { background: rgb(216 242 255 / .16); }

/* ---- the three routes ----------------------------------------------- */
.routes { display: grid; gap: var(--space-6); }
/* A route with no link is not printed, so the column count is decided in PHP
   from how many actually rendered. auto-fit was tried first and leaves collapsed
   0px tracks behind — the gaps between them survive, so two cards sat in a row
   with 48px of dead space stuck on the end. */
@media (min-width: 820px) {
  .routes { grid-template-columns: repeat(var(--route-cols, 3), minmax(0, 1fr)); }
}
.route {
  position: relative; display: flex; flex-direction: column;
  gap: var(--space-4); padding: clamp(24px, 3vw, 36px);
  border: 1px solid var(--border-default); border-radius: 24px;
  background: #fff; text-decoration: none; color: inherit; overflow: hidden;
  transition: transform var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.route:hover { transform: translateY(-4px); border-color: var(--brand-900, #1B2966);
  box-shadow: 0 18px 44px -28px rgb(27 41 102 / .55); }
.route::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 3px;
  background: linear-gradient(90deg, var(--tint-300), var(--brand-900, #1B2966));
  transform: scaleX(0); transform-origin: left;
  transition: transform 460ms var(--ease-out);
}
.route:hover::after { transform: scaleX(1); }
.route-ico {
  width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center;
  background: var(--tint-200); color: var(--brand-900, #1B2966); flex: 0 0 auto;
}
.route-ico svg { width: 24px; height: 24px; fill: currentColor; }
.route.is-primary .route-ico { background: var(--brand-900, #1B2966); color: var(--tint-300); }
.route b {
  font-family: var(--font-display); font-size: var(--text-xl);
  letter-spacing: .01em; line-height: 1.15;
}
.route p { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }
.route .route-go {
  margin-top: auto; font-size: var(--text-sm); font-weight: 700;
  color: var(--brand-900, #1B2966); display: inline-flex; align-items: center; gap: 8px;
}
.route:hover .route-go .arw { transform: translate(3px, -3px); }
.route .arw { transition: transform var(--duration-fast) var(--ease-out); }

/* ---- form + "what happens next" rail --------------------------------- */
.form-split { display: grid; gap: clamp(32px, 4vw, 64px); align-items: start; }
@media (min-width: 980px) { .form-split { grid-template-columns: 1fr 1.25fr; } }

.next-rail { list-style: none; margin: var(--space-10, 40px) 0 0; padding: 0;
  position: relative; display: grid; gap: var(--space-8); }
.next-rail::before {
  content: ''; position: absolute; left: 17px; top: 10px; bottom: 24px;
  width: 2px; background: linear-gradient(180deg, var(--brand-900, #1B2966), var(--tint-400));
}
.next-rail li { position: relative; padding-left: 56px; }
.next-rail li > b {
  position: absolute; left: 0; top: -2px; width: 36px; height: 36px;
  border-radius: 50%; background: var(--brand-900, #1B2966); color: var(--tint-300);
  display: grid; place-items: center; font-family: var(--font-display);
  font-size: var(--text-sm); font-weight: 700; font-variant-numeric: tabular-nums;
}
.next-rail strong { display: block; font-family: var(--font-display);
  font-size: var(--text-lg, 1.2rem); letter-spacing: .01em; }
.next-rail span { display: block; margin-top: 6px; font-size: var(--text-sm);
  color: var(--text-secondary); }

/* Segmented pickers instead of two more dropdowns — the old page had four
   selects in a row and read like a tax form. */
.seg { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.seg input { position: absolute; opacity: 0; width: 0; height: 0; }
.seg label {
  cursor: pointer; border: 1px solid var(--border-default); border-radius: 999px;
  padding: 9px 16px; font-size: var(--text-sm); font-weight: 700;
  color: var(--text-secondary); background: #fff;
  transition: all var(--duration-fast) var(--ease-out);
  letter-spacing: 0; text-transform: none;
}
.seg label:hover { border-color: var(--brand-900, #1B2966); color: var(--brand-900, #1B2966); }
.seg input:checked + label {
  background: var(--brand-900, #1B2966); border-color: var(--brand-900, #1B2966); color: #fff;
}
.seg input:focus-visible + label { box-shadow: 0 0 0 3px var(--tint-400); }
.field > .fieldlabel {
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
  display: block;
}

/* ---- world clocks ---------------------------------------------------- */
.clocks { display: grid; gap: var(--space-6); margin-top: var(--space-12); }
@media (min-width: 680px) { .clocks { grid-template-columns: repeat(3, 1fr); } }
.clock {
  border: 1px solid rgb(27 41 102 / .16); border-radius: 22px;
  padding: var(--space-6) var(--space-6) var(--space-5, 20px);
  background: rgb(255 255 255 / .6); text-align: center;
}
.clock em {
  font-style: normal; font-family: var(--font-display); font-size: var(--text-xs);
  font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted); display: block;
}
.clock b {
  display: block; margin: 10px 0 6px; font-family: var(--font-display);
  font-size: clamp(2rem, 4.4vw, 2.9rem); line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--brand-900, #1B2966);
}
.clock span { font-size: var(--text-sm); color: var(--text-secondary); }
.clock.is-me { background: var(--brand-900, #1B2966); border-color: var(--brand-900, #1B2966); }
.clock.is-me em { color: rgb(216 242 255 / .72); }
.clock.is-me b { color: #fff; }
.clock.is-me span { color: var(--tint-300); }

/* ==========================================================================
   The Journey — timeline (About)
   ========================================================================== */

.journey { position: relative; margin-top: var(--space-16); }
.journey::before {
  content: ''; position: absolute; left: 21px; top: 12px; bottom: 12px; width: 2px;
  background: var(--tint-400);
}
.journey::after {                     /* the part that has scrolled past */
  content: ''; position: absolute; left: 21px; top: 12px; width: 2px;
  height: var(--fill, 0%);
  background: linear-gradient(180deg, var(--brand-900, #1B2966), #4A5B96);
  transition: height 240ms linear;
}
@media (min-width: 900px) {
  .journey::before, .journey::after { left: 50%; transform: translateX(-1px); }
}

.stop { position: relative; padding: 0 0 var(--space-12) 62px; }
.stop:last-child { padding-bottom: 0; }
.stop-dot {
  position: absolute; left: 10px; top: 8px; width: 24px; height: 24px;
  border-radius: 50%; background: #fff; border: 2px solid var(--tint-400);
  display: grid; place-items: center;
  transition: border-color 420ms var(--ease-out), background 420ms var(--ease-out);
}
.stop-dot::after {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  background: var(--tint-400); transition: background 420ms var(--ease-out);
}
.stop.is-in .stop-dot { border-color: var(--brand-900, #1B2966); }
.stop.is-in .stop-dot::after { background: var(--brand-900, #1B2966); }
.stop.is-now .stop-dot { background: var(--brand-900, #1B2966); border-color: var(--brand-900, #1B2966); }
.stop.is-now .stop-dot::after { background: var(--tint-300); }
.stop.is-now .stop-dot { animation: pulseDot 2.4s ease-out infinite; }
@keyframes pulseDot {
  0%   { box-shadow: 0 0 0 0 rgb(27 41 102 / .35); }
  70%  { box-shadow: 0 0 0 14px rgb(27 41 102 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(27 41 102 / 0); }
}

.stop-year {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  letter-spacing: .2em; text-transform: uppercase; color: var(--brand-900, #1B2966);
  display: inline-block; margin-bottom: 10px;
}
.stop-card {
  border: 1px solid var(--border-default); border-radius: 24px; background: #fff;
  padding: clamp(22px, 2.8vw, 32px); position: relative; overflow: hidden;
  transition: transform 520ms var(--ease-out), box-shadow 520ms var(--ease-out),
              border-color 520ms var(--ease-out);
}
.stop.is-in .stop-card { box-shadow: 0 20px 50px -34px rgb(27 41 102 / .5); }
.stop-card:hover { transform: translateY(-3px); border-color: rgb(27 41 102 / .3); }
.stop-card h3 { font-size: var(--text-xl); margin: 0 0 10px; }
.stop-card p { color: var(--text-secondary); font-size: var(--text-sm);
  line-height: var(--leading-normal); margin: 0; }
.stop-ghost {
  position: absolute; right: 14px; top: -14px; font-family: var(--font-display);
  font-weight: 700; font-size: clamp(3.4rem, 7vw, 5.6rem); line-height: 1;
  color: var(--brand-900, #1B2966); opacity: .07; pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.stop-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--space-5, 20px); }
.stop-tags span {
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .04em;
  color: var(--brand-900, #1B2966); background: var(--tint-200);
  border-radius: 999px; padding: 6px 12px;
}

@media (min-width: 900px) {
  .stop { width: 50%; padding: 0 0 var(--space-16) 0; }
  .stop:nth-child(odd)  { margin-left: 0;   padding-right: 62px; text-align: right; }
  .stop:nth-child(even) { margin-left: 50%; padding-left: 62px; }
  .stop:nth-child(odd) .stop-dot  { left: auto; right: -12px; }
  .stop:nth-child(even) .stop-dot { left: -12px; }
  .stop:nth-child(odd) .stop-tags { justify-content: flex-end; }
  .stop:nth-child(odd) .stop-ghost { right: auto; left: 14px; }
}

/* ==========================================================================
   Blog — magazine layout
   ========================================================================== */

.blog-split { display: grid; gap: clamp(36px, 4vw, 64px); align-items: start; }
@media (min-width: 1040px) { .blog-split { grid-template-columns: minmax(0,1fr) 320px; } }

/* the featured post */
.feature-post {
  position: relative; display: grid; gap: 0; overflow: hidden;
  border-radius: var(--panel-radius); border: 1px solid var(--border-default);
  background: #fff; text-decoration: none; color: inherit;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
/* The art column carries the photo, so it gets the larger share. At .92fr it
   was narrower than the text beside it and a landscape photo ended up as a tall
   thin crop. */
@media (min-width: 720px) { .feature-post { grid-template-columns: minmax(0,1.12fr) minmax(0,.88fr); } }
.feature-post:hover { transform: translateY(-4px); box-shadow: 0 26px 60px -36px rgb(27 41 102 / .55); }
.feature-art {
  position: relative; overflow: hidden;
  background: var(--brand-900, #1B2966);
}
.feature-art svg { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.feature-body { padding: clamp(26px, 3.4vw, 44px); display: flex;
  flex-direction: column; gap: var(--space-4); }
.feature-body h2 { font-size: clamp(1.5rem, 1.1rem + 1.1vw, 1.95rem); line-height: 1.12; margin: 0; }
.feature-body p { color: var(--text-secondary); font-size: var(--text-base, 1rem); margin: 0; }
.flag-feature {
  position: absolute; left: 18px; top: 18px; z-index: 2;
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--tint-300); color: var(--brand-900, #1B2966);
  border-radius: 999px; padding: 7px 14px;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}

/* the post list */
.post-list { list-style: none; margin: var(--space-10, 40px) 0 0; padding: 0;
  display: grid; gap: var(--space-6); }
.post-row {
  display: grid; gap: var(--space-6); align-items: center;
  border-bottom: 1px solid var(--border-default); padding-bottom: var(--space-6);
}
@media (min-width: 620px)  { .post-row { grid-template-columns: 240px 1fr; } }
@media (min-width: 900px)  { .post-row { grid-template-columns: 300px 1fr; } }
@media (min-width: 1200px) { .post-row { grid-template-columns: 340px 1fr; } }
.post-row:last-child { border-bottom: none; }
.row-art {
  /* No fixed ratio: the box takes its height from the picture so the whole
     image is visible. A crop that hides part of a screenshot or a logo strip
     is worse than a card of uneven height. */
  position: relative; border-radius: 18px; overflow: hidden;
  background: var(--brand-900, #1B2966);
}
.row-art svg { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.row-art::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(140deg, rgb(27 41 102 / 0), rgb(27 41 102 / .55));
  opacity: 0; transition: opacity var(--duration-fast) var(--ease-out);
}
.post-row:hover .row-art::after { opacity: 1; }
.post-row h3 { font-size: var(--text-xl); line-height: 1.2; margin: 8px 0 8px; }
.post-row h3 a { color: inherit; text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size 360ms var(--ease-out); }
.post-row:hover h3 a { background-size: 100% 1px; }
.post-row p { color: var(--text-secondary); font-size: var(--text-sm); margin: 0; }
.row-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  font-size: var(--text-xs); letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted);
}
.row-meta .cat {
  color: var(--brand-900, #1B2966); background: var(--tint-200);
  border-radius: 999px; padding: 5px 11px; font-weight: 700; letter-spacing: .08em;
}

/* pagination */
.pager { display: flex; gap: 8px; align-items: center; margin-top: var(--space-12); }
.pager a, .pager span {
  min-width: 42px; height: 42px; padding: 0 12px; border-radius: 12px;
  display: inline-grid; place-items: center; font-size: var(--text-sm); font-weight: 700;
  border: 1px solid var(--border-default); color: var(--text-secondary); text-decoration: none;
  transition: all var(--duration-fast) var(--ease-out);
}
.pager a:hover { border-color: var(--brand-900, #1B2966); color: var(--brand-900, #1B2966); }
.pager .is-here { background: var(--brand-900, #1B2966); border-color: var(--brand-900, #1B2966); color: #fff; }
.pager .gap { border: none; color: var(--text-muted); }

/* sidebar */
.side { display: grid; gap: var(--space-6); position: sticky; top: 104px; }
@media (max-width: 1039px) { .side { position: static; } }
.side-card {
  border: 1px solid var(--border-default); border-radius: 24px;
  padding: var(--space-6); background: #fff;
}
.side-card h4 {
  font-family: var(--font-display); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-muted);
  margin: 0 0 var(--space-5, 20px);
}
.side-search { display: flex; gap: 8px; }
.side-search input {
  flex: 1 1 auto; min-width: 0; font-size: 16px; padding: 12px 14px;
  border: 1px solid var(--border-default); border-radius: 12px; background: #fff;
  font-family: var(--font-ui); color: var(--text-primary);
}
.side-search input:focus-visible { outline: none; border-color: var(--brand-900, #1B2966);
  box-shadow: 0 0 0 3px var(--tint-400); }
.side-search button {
  flex: 0 0 auto; width: 46px; border-radius: 12px; border: none; cursor: pointer;
  background: var(--brand-900, #1B2966); color: var(--tint-300); display: grid; place-items: center;
}
.side-search svg { width: 18px; height: 18px; fill: currentColor; }

.cat-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.cat-list a {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-4);
  padding: 11px 12px; border-radius: 12px; text-decoration: none;
  color: var(--text-primary); font-size: var(--text-sm); font-weight: 700;
  transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.cat-list a:hover { background: var(--tint-100); color: var(--brand-900, #1B2966); }
.cat-list em {
  font-style: normal; font-size: var(--text-xs); font-weight: 700; color: var(--text-muted);
  background: var(--tint-200); border-radius: 999px; padding: 3px 9px;
  font-variant-numeric: tabular-nums;
}

.pop-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-5, 20px); }
/* Single column now the numeral is gone; the items are separated by a rule
   instead, which is what was carrying the "these are a list" reading anyway. */
.pop-list li { display: block; padding-bottom: var(--space-4); border-bottom: 1px solid var(--border-default); }
.pop-list li:last-child { padding-bottom: 0; border-bottom: none; }
.pop-list b {
  font-family: var(--font-display); font-size: var(--text-lg, 1.2rem); line-height: 1;
  /* tint-500 fails on white (1.38:1) — this is the same family two steps
     darker, 3.61:1, which clears the large-bold-text bar with room. */
  color: #6E86BE; font-variant-numeric: tabular-nums;
}
.pop-list a { text-decoration: none; color: var(--text-primary); font-weight: 700;
  font-size: var(--text-sm); line-height: 1.35; display: block; }
.pop-list a:hover { color: var(--brand-900, #1B2966); text-decoration: underline; }
.pop-list span { display: block; margin-top: 5px; font-size: var(--text-xs);
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }

.side-card.is-ink {
  background: var(--brand-900, #1B2966); border-color: var(--brand-900, #1B2966);
  position: relative; overflow: hidden;
}
.side-card.is-ink > :not(svg) { position: relative; z-index: 1; }
.side-card.is-ink h4 { color: rgb(216 242 255 / .7); }
.side-card.is-ink strong {
  display: block; font-family: var(--font-display); font-size: var(--text-xl);
  line-height: 1.15; color: #fff; margin-bottom: 10px;
}
.side-card.is-ink p { font-size: var(--text-sm); color: var(--tint-300); margin: 0 0 var(--space-5, 20px); }
.side-card.is-ink input {
  width: 100%; font-size: 16px; padding: 12px 14px; border-radius: 12px;
  border: 1px solid rgb(216 242 255 / .34); background: rgb(216 242 255 / .1);
  color: #fff; font-family: var(--font-ui); margin-bottom: 10px;
}
.side-card.is-ink input::placeholder { color: rgb(216 242 255 / .6); }
.side-card.is-ink input:focus-visible { outline: none; border-color: var(--tint-300);
  box-shadow: 0 0 0 3px rgb(216 242 255 / .25); }
.side-card.is-ink .btn { width: 100%; justify-content: center; }
.side-card.is-ink .form-note { color: rgb(216 242 255 / .72); }
.side-card.is-ink .form-status { color: var(--tint-300); }

.tool-cloud { display: flex; flex-wrap: wrap; gap: 8px; }
.tool-cloud span {
  font-size: var(--text-xs); font-weight: 700; color: var(--brand-900, #1B2966);
  border: 1px solid rgb(27 41 102 / .18); border-radius: 999px; padding: 7px 12px;
  transition: all var(--duration-fast) var(--ease-out);
}
.tool-cloud span:hover { background: var(--brand-900, #1B2966); color: #fff;
  border-color: var(--brand-900, #1B2966); }

/* author strip under the blog hero */
.author-strip {
  display: grid; gap: var(--space-6); align-items: center;
  border: 1px solid var(--border-default); border-radius: 26px;
  padding: clamp(20px, 2.6vw, 28px); background: #fff;
}
@media (min-width: 720px) { .author-strip { grid-template-columns: auto 1fr auto; } }
/* The strip sat flush against the first post card. It is an introduction to
   the list, not the first item in it, so it needs its own breathing room. */
.author-strip { margin-bottom: clamp(38px, 4.6vw, 64px); }
.author-face {
  width: 66px; height: 66px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-900, #1B2966); color: var(--tint-300); flex: 0 0 auto;
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; letter-spacing: .04em;
}
.author-strip p { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.author-strip strong { display: block; font-family: var(--font-display);
  font-size: var(--text-lg, 1.2rem); color: var(--text-primary); margin-bottom: 4px; }

/* visually-hidden label — used by the blog search and newsletter fields */
.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;
}

/* The Calendly button's label is long. On a narrow panel its nowrap width
   exceeds the panel's content box, and the panel's overflow:hidden clips it.
   Let it wrap to two lines instead. */
@media (max-width: 560px) {
  .booking .btn, .booking .btn > span { white-space: normal; text-align: center; }
  .booking .btn { line-height: 1.25; }
}

/* ==========================================================================
   Section background art

   Several art pieces are drawn deliberately wider than their container so the
   strokes leave the frame rather than stopping at a hard edge. A plain
   <section> has no overflow rule, so that bleed became real page width and put
   a horizontal scrollbar on the whole document. This wrapper clips it without
   changing how any of the art is drawn.
   ========================================================================== */

.sec-art {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  border-radius: inherit;
}
.sec-art > svg { max-width: none; }

/* Sections carrying art need a positioning context and their own clip. */
section:has(> .sec-art) { position: relative; overflow: hidden; }

/* Fallback for browsers without :has() — the wrapper is still clipped, the
   section just does not clip a second time. Safe either way. */
@supports not selector(:has(*)) {
  .sec-art { inset: 0; }
}

/* ==========================================================================
   Muted text on the pale-blue band

   .band-ice sits on --surface-sunken (#C6EBFF), which is a step darker than
   the ice the tint ladder was validated against. --text-muted lands at 4.26:1
   there — under AA for body-size text. The design system already says to use
   --text-secondary on the darker tints; this is that rule, applied to the two
   places that actually hit it. Caught by the rendered-pixel audit on the
   WordPress build, not by any palette check.
   ========================================================================== */

.band-ice .lbl,
.band-ice .stat span,
.band-ice .post-meta,
.band-ice .row-meta,
.band-ice .form-note,
.band-ice .stat-suffix {
  color: var(--text-secondary);
}

/* ==========================================================================
   Forms — Contact Form 7 and the comment form

   Both get .wps-form so one set of rules dresses them. CF7's own stylesheet is
   dequeued on pages with no form (see inc/enqueue.php), so nothing here is
   fighting it.

   The 16px minimum on text inputs is not a style choice: Safari on iOS zooms
   the whole viewport when you focus a field smaller than that, and the page
   never zooms back out. Caught by the verification sweep on the comment form,
   which was inheriting the browser default of 13px.
   ========================================================================== */

.wps-form { display: grid; gap: var(--space-5, 20px); max-width: 100%; }

.wps-form p { margin: 0; }

.wps-form label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.wps-form input[type="text"],
.wps-form input[type="email"],
.wps-form input[type="url"],
.wps-form input[type="tel"],
.wps-form input[type="date"],
.wps-form input[type="number"],
.wps-form select,
.wps-form textarea {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  font-family: var(--font-ui);
  font-size: 16px;              /* never lower — see the note above */
  line-height: 1.5;
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border-strong, #B7C4D8);
  border-radius: 0;
  padding: 10px 2px;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.wps-form textarea { min-height: 130px; resize: vertical; }

.wps-form input:focus-visible,
.wps-form select:focus-visible,
.wps-form textarea:focus-visible {
  outline: none;
  border-bottom-color: var(--brand-900, #1B2966);
  box-shadow: 0 1px 0 0 var(--brand-900, #1B2966);
}

.wps-form input[type="submit"],
.wps-form button[type="submit"] {
  justify-self: start;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #fff;
  background: var(--brand-900, #1B2966);
  border: 1px solid var(--brand-900, #1B2966);
  border-radius: 999px;
  padding: 14px 28px;
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.wps-form input[type="submit"]:hover,
.wps-form button[type="submit"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -16px rgb(27 41 102 / .7);
}

/* CF7's own response messages */
.wpcf7-not-valid-tip {
  display: block;
  margin-top: 6px;
  font-size: var(--text-sm);
  color: #A6402C;
}
.wpcf7-response-output {
  margin: var(--space-4) 0 0 !important;
  padding: 14px 18px !important;
  border: 1px solid var(--border-default) !important;
  border-radius: 12px;
  font-size: var(--text-sm);
}
.wpcf7 form.sent .wpcf7-response-output { border-color: #2F6B45 !important; color: #245B3B; }
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output { border-color: #A6402C !important; color: #A6402C; }
.wpcf7-spinner { margin-left: 10px; }

/* On the navy panels the same form needs the light-on-dark treatment. */
.ink .wps-form label { color: var(--text-muted); }
.ink .wps-form input,
.ink .wps-form select,
.ink .wps-form textarea {
  color: var(--text-primary);
  border-bottom-color: rgb(216 242 255 / .34);
}
.ink .wps-form input:focus-visible,
.ink .wps-form textarea:focus-visible {
  border-bottom-color: var(--tint-300);
  box-shadow: 0 1px 0 0 var(--tint-300);
}
.ink .wps-form input[type="submit"],
.ink .wps-form button[type="submit"] {
  background: var(--tint-300);
  border-color: var(--tint-300);
  color: var(--brand-900, #1B2966);
}

/* ==========================================================================
   Single post: body, hero image, breadcrumbs, comments
   ========================================================================== */

.post-hero {
  /* The whole picture, never a crop.
     This used to be a fixed 16/9 frame with object-fit:cover, which sliced the
     top and bottom off anything that was not widescreen — on a tall graphic it
     cut the content out entirely. The frame now takes its height from the
     image. */
  position: relative;
  width: 100%;
  max-width: 1080px;
  margin-inline: auto;
  border-radius: var(--panel-radius);
  overflow: hidden;
  line-height: 0;
}
/* The image fills the frame and is cropped, rather than being stretched to the
   column width — a 960px photo blown up to 1150px is visibly soft, and that is
   what "the image is not working" looked like. */
.post-hero img {
  position: static;
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
}

.article-body { max-width: 68ch; margin-inline: auto; }
.article-body > * + * { margin-top: 1.1em; }
.article-body h2 { margin-top: 1.9em; font-size: var(--text-2xl); }
.article-body h3 { margin-top: 1.6em; font-size: var(--text-xl); }
.article-body img { max-width: 100%; height: auto; border-radius: 16px; }
.article-body blockquote {
  border-left: 3px solid var(--tint-400);
  padding-left: var(--space-6);
  margin-left: 0;
  color: var(--text-secondary);
}
.article-body pre {
  background: var(--tint-100);
  border-radius: 12px;
  padding: var(--space-5, 20px);
  overflow-x: auto;
}

.crumbs {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  font-size: var(--text-xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted);
}
.crumbs a { color: inherit; }
.crumbs .sep { opacity: .5; }

.comments { max-width: 68ch; margin-inline: auto; }
.comments-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin-bottom: var(--space-8);
}
.comment-list { list-style: none; margin: 0 0 var(--space-12); padding: 0; display: grid; gap: var(--space-8); }
.comment-list ol { list-style: none; margin: var(--space-6) 0 0 var(--space-8); padding: 0; display: grid; gap: var(--space-6); }
.comment-body {
  border: 1px solid var(--border-default);
  border-radius: 18px;
  padding: var(--space-6);
}
.comment-body .avatar { border-radius: 50%; margin-right: 10px; vertical-align: middle; }
.comment-meta { font-size: var(--text-xs); color: var(--text-muted); margin-bottom: var(--space-4); }
.comment-body p { font-size: var(--text-sm); }
.comment-respond { margin-top: var(--space-10, 40px); }
.comment-reply-title { font-family: var(--font-display); font-size: var(--text-xl); margin-bottom: var(--space-6); }

/* The post meta row sits on the hero gradient, which is a shade darker than
   white at the point the text lands — --text-muted measures 4.35:1 there.
   Same rule as the ice band: use --text-secondary on the tinted grounds. */
.hero-light .row-meta { color: var(--text-secondary); }
.hero-light .row-meta .cat { color: var(--brand-900, #1B2966); }

/* ---- quiz: progress bar, back links, weak-point list ------------------ */

/* Every colour in this block was picked when the quiz sat on a navy band, so
   each one is an ice tint. On the white panel the band now uses, ice is
   1.1:1 — the progress bar, the weak-point rules and their headings were all
   painted in a colour that is not there. Navy is the light-ground equivalent;
   the ink variants are kept below so a section still toned ink still works.

   Worth naming why the automated audit did not catch this: it measures the
   page as loaded, and the result screen only exists after seven answers. The
   check now drives the quiz to the end before measuring. */
.quiz-bar {
  height: 3px; border-radius: 3px; overflow: hidden;
  background: rgb(27 41 102 / .12); margin-bottom: var(--space-8);
}
.quiz-bar i {
  display: block; height: 100%; width: 0;
  background: var(--brand-900, #1B2966);
  transition: width 420ms var(--ease-out);
}
.ink .quiz-bar { background: rgb(216 242 255 / .18); }
.ink .quiz-bar i { background: var(--tint-300); }

.quiz-back {
  margin-top: var(--space-6);
  background: none; border: none; cursor: pointer;
  font-family: var(--font-ui); font-size: var(--text-sm); font-weight: 700;
  color: var(--text-muted); padding: 6px 0;
}
.quiz-back:hover { color: var(--brand-900, #1B2966); text-decoration: underline; }
.quiz-back:focus-visible { outline: 2px solid var(--brand-500, #535EA1); outline-offset: 3px; border-radius: 4px; }
.ink .quiz-back:hover { color: var(--tint-300); }
.ink .quiz-back:focus-visible { outline-color: var(--tint-300); }

.quiz-weak { list-style: none; padding: 0; margin: var(--space-8) 0 0; display: grid; gap: var(--space-5, 20px); }
.quiz-weak li {
  border-left: 2px solid var(--brand-900, #1B2966);
  padding-left: var(--space-5, 20px);
}
.quiz-weak b {
  display: block; font-family: var(--font-display);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--brand-900, #1B2966); margin-bottom: 6px;
}
.ink .quiz-weak li { border-left-color: var(--tint-300); }
.ink .quiz-weak b { color: var(--tint-300); }
.quiz-weak span { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-normal); }

/* ==========================================================================
   Featured images in the post cards

   The card art slots were built around inline SVG, which is absolutely
   positioned by .art-lines. A real uploaded image has no such rule, so it
   rendered at its natural size in the flow — a 960x780 photo turned the blog
   listing's feature card into a 780px-tall column. Same treatment for both.
   ========================================================================== */

.row-art img,
.feature-art img,
.post-thumb img {
  position: static;
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
}
/* Bento tiles are a fixed mosaic — those genuinely do need to fill. */
.bento-art img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; max-width: none;
}

/* Images inside the article body: never wider than the column, always with the
   figure caption tucked underneath rather than floating loose. */
.article-body figure { margin: 1.8em 0; }
.article-body figure img { width: 100%; height: auto; }
.article-body figcaption {
  margin-top: 10px; font-size: var(--text-sm);
  color: var(--text-secondary); text-align: center;
}

/* A feature section showing generated art rather than a photograph: no crop
   frame, no floating badges — the drawing sits in the column at its own size. */
.photo-wrap.is-art { display: grid; place-items: center; }
.photo-wrap.is-art > svg { width: 100%; height: auto; max-width: 460px; }

/* The avatar initials were losing their colour to a later `.quote-who span`
   rule with higher specificity, leaving muted grey on navy at about 1.9:1 —
   effectively invisible. The rendered-pixel audit missed it because quote
   cards were not in its zone list; they are now. */
.quote-who .quote-avatar { color: #FFFFFF; }

/* ==========================================================================
   Quiz result list

   An earlier rule lays .quiz-weak li out as `grid-template-columns: 24px 1fr`
   with an arrow in the first cell. The result list now carries its own label
   and body, so those land in the wrong cells — the advice was flowing into a
   24px column, one word per line. This resets the layout for the current
   markup rather than fighting it cell by cell.
   ========================================================================== */

.quiz-weak li {
  display: block;
  grid-template-columns: none;
  border-top: none;
  padding-block: 0;
}
.quiz-weak li::before { content: none; }

/* Belt and braces on the answer buttons: whatever ends up inside one, keep it
   above the sliding highlight. */
.quiz-option > *,
.quiz-option span { position: relative; z-index: 1; }

/* Tag chips are links in the sidebar and on single posts; the cloud was only
   ever styled for plain spans. */
.tool-cloud a { text-decoration: none; display: inline-block; }
.tool-cloud a:focus-visible { outline: 2px solid var(--brand-900, #1B2966); outline-offset: 2px; border-radius: 999px; }

/* ==========================================================================
   Checklist offer — the lead magnet band
   ========================================================================== */

.nl-split { display: grid; gap: clamp(34px, 4vw, 64px); align-items: center; }
@media (min-width: 960px) { .nl-split { grid-template-columns: 1.05fr .95fr; } }

.nl-copy h2 { margin: 0 0 var(--space-4); }
.nl-items {
  list-style: none; margin: var(--space-8) 0 0; padding: 0;
  display: grid; gap: var(--space-4);
}
.nl-items li {
  position: relative; padding-left: 34px;
  font-size: var(--text-base, 1rem); line-height: 1.5;
}
/* A drawn tick rather than a bullet — the list is a checklist, so it should
   look like one before anyone reads a word of it. */
.nl-items li::before {
  content: ''; position: absolute; left: 0; top: .12em;
  width: 21px; height: 21px; border-radius: 7px;
  background: var(--brand-900, #1B2966);
}
.nl-items li::after {
  content: ''; position: absolute; left: 6px; top: .42em;
  width: 9px; height: 5px;
  border-left: 2px solid var(--tint-300); border-bottom: 2px solid var(--tint-300);
  transform: rotate(-45deg);
}
.nl-direct { margin-top: var(--space-8); }

.nl-panel {
  position: relative;
  background: linear-gradient(158deg, var(--brand-900) 0%, #24316F 55%, #2C3F82 100%);
  color: #fff;
  border-radius: var(--panel-radius);
  padding: clamp(28px, 3.4vw, 46px);
  overflow: hidden;
}
.nl-sheet {
  position: absolute; right: -30px; top: -22px;
  width: 186px; opacity: .3; color: var(--tint-300); pointer-events: none;
  transform: rotate(6deg);
}
/* The sheet's own page must not be solid white — at panel opacity it turned
   into a flat pale block and the ticks drawn on it disappeared. */
.nl-sheet svg > rect:first-child { fill: rgb(255 255 255 / .1); }
.nl-sheet svg { width: 100%; height: auto; display: block; }
.nl-badge {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--tint-300); color: var(--brand-900, #1B2966);
  border-radius: 999px; padding: 7px 15px; margin-bottom: var(--space-6);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.nl-panel .wps-form, .nl-panel form { position: relative; z-index: 1; }
.nl-panel label { color: #fff; }
.nl-panel input[type="email"], .nl-panel input[type="text"] {
  background: rgb(255 255 255 / .12);
  border-color: rgb(216 242 255 / .34);
  color: #fff;
}
.nl-panel input::placeholder { color: rgb(216 242 255 / .66); }
.nl-panel input:focus { background: rgb(255 255 255 / .18); }
/* Contrast on the navy panel: the muted grey the note normally uses drops to
   about 2:1 here, so it is lifted to the ice tint. */
.nl-panel .form-note { color: rgb(216 242 255 / .78); margin-top: var(--space-5, 20px); }
.nl-panel .wpcf7-response-output { color: #fff; border-color: rgb(216 242 255 / .5); }

@media (max-width: 620px) { .nl-sheet { width: 140px; right: -26px; } }

/* ---- social rail under the contact routes ------------------------------- */

.social-rail {
  margin-top: clamp(34px, 4vw, 56px);
  padding-top: clamp(28px, 3vw, 40px);
  border-top: 1px solid var(--border-default);
}
.social-rail h3 {
  margin: 0 0 var(--space-5, 20px);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-secondary);
}
.social-rail-links { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.social-rail-links a {
  display: inline-flex; align-items: center; gap: 11px;
  padding: 12px 18px; border-radius: 999px;
  border: 1px solid var(--border-default); background: #fff;
  text-decoration: none; color: var(--brand-900, #1B2966);
  font-size: var(--text-sm); font-weight: 700;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.social-rail-links a svg { width: 19px; height: 19px; fill: currentColor; flex: 0 0 auto; }
.social-rail-links a .arw { font-size: .9em; transition: transform var(--duration-fast) var(--ease-out); }
.social-rail-links a:hover {
  background: var(--brand-900, #1B2966); color: #fff;
  border-color: var(--brand-900, #1B2966); transform: translateY(-2px);
}
.social-rail-links a:hover .arw { transform: translate(3px, -3px); }
/* On the dark band the white pill would be a set of glaring chips; invert it. */
.ink .social-rail { border-top-color: rgb(216 242 255 / .22); }
.ink .social-rail h3 { color: var(--tint-300); }
.ink .social-rail-links a {
  background: rgb(255 255 255 / .08); border-color: rgb(216 242 255 / .28); color: #fff;
}
.ink .social-rail-links a:hover { background: var(--tint-300); color: var(--brand-900, #1B2966); }

/* ---- the detailed services list (one-off work, with prices) -------------- */

.card .svc-price {
  font-size: var(--text-2xl);
  margin: 4px 0 var(--space-3);
  color: var(--brand-900, #1B2966);
}
.card .svc-price small { display: block; margin-top: 4px; }

/* .tick-list was used by the services list but never had a rule, so the
   "what's included" lines fell back to plain browser bullets. */
.tick-list {
  list-style: none; padding: 0; margin: var(--space-4) 0 0;
  display: grid; gap: var(--space-3);
}
.tick-list li {
  position: relative; padding-left: 26px;
  font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--text-secondary);
}
.tick-list li::before {
  content: ''; position: absolute; left: 2px; top: .34em;
  width: 9px; height: 5px;
  border-left: 2px solid var(--brand-900, #1B2966);
  border-bottom: 2px solid var(--brand-900, #1B2966);
  transform: rotate(-45deg);
}
.ink .tick-list li { color: var(--tint-300); }
.ink .tick-list li::before { border-color: var(--tint-300); }
.card .arrow-link { margin-top: auto; padding-top: var(--space-4); }

/* ---- the plate shown when a post has no featured image ------------------ */

.thumb-plate {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: var(--brand-900, #1B2966);
  overflow: hidden;
}
.thumb-plate svg { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.plate-mark {
  position: relative;
  font-family: var(--font-display);
  font-weight: 700; letter-spacing: -.02em; line-height: 1;
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  /* Outlined rather than filled: at this size a solid block of ice would fight
     the headline sitting next to it. */
  color: transparent;
  -webkit-text-stroke: 1.5px rgb(216 242 255 / .58);
  text-stroke: 1.5px rgb(216 242 255 / .58);
}
.plate-cat {
  position: absolute;
  font-size: 11px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: rgb(216 242 255 / .82);
}
.plate-cat { left: 16px; bottom: 14px; max-width: calc(100% - 60px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* On the big featured card there is room to let it breathe. */
.feature-art .plate-mark { font-size: clamp(3.4rem, 7vw, 6rem); -webkit-text-stroke-width: 2px; }
.feature-art .plate-cat { font-size: var(--text-xs); left: 24px; bottom: 22px; }


.nl-split.is-solo { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
.nl-panel-title {
  position: relative; z-index: 1;
  margin: 0 0 var(--space-5, 20px);
  font-size: var(--text-xl); color: #fff;
}
.nl-fallback {
  position: relative; z-index: 1;
  margin: 0 0 var(--space-6);
  color: var(--tint-300); font-size: var(--text-sm);
}
.nl-panel .magnet { position: relative; z-index: 1; }
.nl-panel .btn-primary { background: var(--tint-300); color: var(--brand-900, #1B2966); }
.nl-panel .btn-primary::before { background: #fff; }

/* ---- the eyebrow rule, without its numeral ------------------------------ */
/* The 01/02/03 index is no longer printed. Without it the short leading rule
   has nothing to sit beside, so it shrinks to a tick and the label carries the
   line on its own. */
.rule-num.is-plain { gap: var(--space-3); }
.rule-num.is-plain .line { flex: 0 0 clamp(20px, 3vw, 34px); }

/* An image pulled from the post's own content rather than from an attachment.
   Same treatment as a featured image — the slots are absolutely positioned. */
/* An image pulled from the post's own content rather than an attachment.
   Same treatment as a featured image: natural height, never cropped. With the
   slots now auto-height, an absolutely positioned height:100% resolved to
   zero and the picture vanished. */
.row-art .wps-content-thumb,
.feature-art .wps-content-thumb,
.post-thumb .wps-content-thumb {
  position: static;
  display: block;
  width: 100%; height: auto;
  max-width: 100%;
  object-fit: contain;
}

/* ---- the running numbers are gone -------------------------------------- */
/* Every 01/02/03 index has been removed from the site. Three of them carried
   layout on their shoulders, so those rules are replaced rather than deleted. */

/* The "what happens next" rail: the disc stays as a station on the line, but
   holds a dot rather than a digit. */
.next-rail li > b { width: 18px; height: 18px; top: 4px; }
.next-rail li > b::after {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--tint-300);
}
.next-rail::before { left: 8px; }
.next-rail li { padding-left: 38px; }

/* Service tiles no longer open with a numeral, so the card starts at its title. */
.svc-tile { padding-top: clamp(24px, 3vw, 34px); }

/* ---- spacing between the post banner and the article -------------------- */
/* The banner sat in a section with its own bottom padding, and the article
   below added a section top padding plus --space-12 on top of that. Three
   stacked gaps read as a hole in the page. One gap, set here. */
.post-hero-band { padding-top: 0; padding-bottom: 0; }
.post-body-band { padding-top: clamp(32px, 4vw, 56px); }
/* The article's first element brings its own top margin (h2 carries 1.9em),
   which stacks on the band padding above it. Nothing should push the first
   line of an article away from the banner. */
.article-body > *:first-child { margin-top: 0; }

/* A feature section with no image is one column, not two with a hole in it. */
.feature.is-solo { grid-template-columns: minmax(0, 1fr); max-width: 760px; }

/* The generated plate (no featured image) still needs a shape of its own,
   now that the slot no longer carries one. */
.row-art:has(.thumb-plate),
.feature-art:has(.thumb-plate) { aspect-ratio: 4 / 3; }
.row-art .thumb-plate,
.feature-art .thumb-plate { position: absolute; inset: 0; }
/* Uncropped art decides the featured card's height, so the text centres. */
.feature-post { align-items: center; }

/* ==========================================================================
   v1.10.0 — post images, and the figures strip under the hero

   Three separate reports of "the images are cropped" all traced back to the
   same idea: a card slot with a fixed shape and object-fit:cover. Two of the
   three slots now shrink to the picture instead; the third — the featured
   card — genuinely wants to be filled, because it sits beside a text column
   and any letterboxing there reads as a mistake.
   ========================================================================== */

/* ---- 1. list cards: narrower column, whole picture ----------------------- */
/* Reducing the column is what makes an uncropped picture sit sensibly beside
   the text. At 340px an uncropped portrait ran taller than its own excerpt. */
@media (min-width: 620px)  { .post-row { grid-template-columns: 190px 1fr; } }
@media (min-width: 900px)  { .post-row { grid-template-columns: 220px 1fr; } }
@media (min-width: 1200px) { .post-row { grid-template-columns: 240px 1fr; } }

.row-art,
.post-thumb {
  aspect-ratio: auto;
  min-height: 0;
  height: auto;
  align-self: start;
}
.row-art img,
.post-thumb img,
.post-hero img,
.row-art .wps-content-thumb,
.post-thumb .wps-content-thumb {
  position: static;
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
  inset: auto;
}

/* ---- 2. the featured card fills its half ------------------------------- */
/* Contained, it left white bands above and below inside a card whose height
   is set by the text beside it. Filled, the card reads as one object. */
.feature-post { align-items: stretch; }
.feature-art {
  position: relative;
  aspect-ratio: auto;
  min-height: 100%;
  height: auto;
  overflow: hidden;
}
.feature-art img,
.feature-art .wps-content-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
}
/* Stacked on a phone there is no half to fill, and min-height:100% resolves
   against an auto-height parent — i.e. to nothing. Give it a shape instead. */
@media (max-width: 767px) {
  .feature-art { aspect-ratio: 16 / 10; min-height: 0; }
}

/* ---- 3. the single-post banner ----------------------------------------- */
.post-hero {
  width: 100%;
  max-width: 1080px;
  margin-inline: auto;
  aspect-ratio: auto;
  max-height: none;
  line-height: 0;
}
.post-body-band { padding-top: clamp(28px, 3vw, 48px); }

/* ---- 4. the figures strip under the hero -------------------------------- */
/* A band, not a section: the numbers moved off the light hero, where they
   competed with the headline, onto a slim dark rule directly beneath it.
   #figures is the anchor set on that section; the sibling selector is the
   belt to its braces, so the rule survives the anchor being cleared.
   Number and label share a line — that is what keeps the band shallow. */
#figures,
.hero-light + section.ink { padding-block: 20px; }
@media (min-width: 900px) {
  #figures,
  .hero-light + section.ink { padding-block: 26px; }
}
#figures .stat-row,
.hero-light + section.ink .stat-row {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
  gap: 14px clamp(20px, 4vw, 64px);
  justify-content: space-between;
  align-items: baseline;
}
#figures .stat,
.hero-light + section.ink .stat {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
#figures .stat b,
.hero-light + section.ink .stat b {
  display: inline-block;
  font-size: clamp(1.3rem, 1.05rem + .8vw, 1.9rem);
  line-height: 1.05;
}
#figures .stat span,
.hero-light + section.ink .stat span {
  display: inline-block;
  margin-top: 0;
  letter-spacing: .12em;
}
#figures .section-head,
.hero-light + section.ink .section-head { display: none; }
/* Below the desktop breakpoint four figures on one flex line wrap 3+1, which
   reads as a mistake. A two-up grid wraps evenly at every narrow width. */
@media (max-width: 899px) {
  #figures .stat-row,
  .hero-light + section.ink .stat-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 20px;
  }
}

/* The quiz intro button is a bare <button>, not a .btn-row, so it inherited
   none of that row's top margin and sat hard against the last line of the
   lede — measured gap: 0px. */
.quiz-step > .btn { margin-top: clamp(22px, 2.4vw, 32px); }

/* ==========================================================================
   v1.11.0 — the health-check intro reads as a split, not a tall text block

   The page hero already asks "is your site at risk?", so the quiz opened with
   a second headline block of near-identical copy and nothing beside it: tall,
   flat and wordy. The static design answered that with a gauge next to the
   copy, and this restores it.

   The dial is drawn on the section's own pseudo-elements rather than as SVG,
   for two reasons. It has to work on whatever theme version is installed, so
   it cannot depend on the markup of the art wrapper. And the theme offers
   "Speed gauge" in the Art field while wps_art() had no 'gauge' key at all —
   picking it rendered nothing (fixed in inc/art.php in this version).

   No clipping is involved: the conic gradient runs 0–180deg and is transparent
   after that, so only the top half of the ring is ever painted.
   ========================================================================== */

@media (min-width: 1000px) {
  /* The band's line art has done its job; the dial replaces it. Both forms of
     the wrapper are matched so this holds across theme versions. */
  section:has(.quiz-panel) > .sec-art,
  section:has(.quiz-panel) > svg { display: none; }

  /* The real gauge — the one wps_gauge() draws: ticks, track, and an arc that
     stops at 88%. It rides in as a background image because the installed
     theme cannot render it: wps_art() has no 'gauge' key, so the Art field's
     "Speed gauge" option produces nothing. A CSS approximation was tried and
     it was exactly that, an approximation. This is the drawing itself. */
  /* Two gauges, because the band can be either tone. The dark-stroke drawing
     is the default now that the quiz sits on an ice band; the light-stroke one
     below is kept for any section still toned ink, where navy strokes on navy
     would be invisible. */
  section:has(.quiz-panel)::before {
    content: '';
    position: absolute;
    z-index: 0;
    pointer-events: none;
    /* Anchored to the shell's left content edge, not the section's: the shell
       is 1200px wide with 24px of padding, hence 50% - 576px. Anchored to the
       section, the dial drifts toward the window edge on a wide screen, a long
       way from the panel it belongs to. */
    left: max(24px, calc(50% - 576px));
    top: 50%;
    transform: translateY(-50%);
    width: min(26vw, 340px);
    aspect-ratio: 300 / 210;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 210'%3E%3Cdefs%3E%3ClinearGradient id='c' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%234A5B96'/%3E%3Cstop offset='1' stop-color='%2318306F'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cline x1='48.0' y1='158.0' x2='38.0' y2='158.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cline x1='53.0' y1='126.5' x2='48.2' y2='124.9' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='67.5' y1='98.0' x2='63.4' y2='95.1' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='90.0' y1='75.5' x2='87.1' y2='71.4' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='118.5' y1='61.0' x2='116.9' y2='56.2' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='150.0' y1='56.0' x2='150.0' y2='46.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cline x1='181.5' y1='61.0' x2='183.1' y2='56.2' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='210.0' y1='75.5' x2='212.9' y2='71.4' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='232.5' y1='98.0' x2='236.6' y2='95.1' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='247.0' y1='126.5' x2='251.8' y2='124.9' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='252.0' y1='158.0' x2='262.0' y2='158.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='%231B2966' stroke-opacity='.12' stroke-width='14' stroke-linecap='round'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='url(%23c)' stroke-width='14' stroke-linecap='round' stroke-dasharray='289.0' stroke-dashoffset='34.7'/%3E%3C/svg%3E") center / contain no-repeat;
  }

  section.ink:has(.quiz-panel)::before {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 210'%3E%3Cdefs%3E%3ClinearGradient id='b' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%236E86BE'/%3E%3Cstop offset='1' stop-color='%23FFFFFF'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cline x1='48.0' y1='158.0' x2='38.0' y2='158.0' stroke='%23D8F2FF' stroke-width='2' opacity='.5'/%3E%3Cline x1='53.0' y1='126.5' x2='48.2' y2='124.9' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='67.5' y1='98.0' x2='63.4' y2='95.1' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='90.0' y1='75.5' x2='87.1' y2='71.4' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='118.5' y1='61.0' x2='116.9' y2='56.2' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='150.0' y1='56.0' x2='150.0' y2='46.0' stroke='%23D8F2FF' stroke-width='2' opacity='.5'/%3E%3Cline x1='181.5' y1='61.0' x2='183.1' y2='56.2' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='210.0' y1='75.5' x2='212.9' y2='71.4' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='232.5' y1='98.0' x2='236.6' y2='95.1' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='247.0' y1='126.5' x2='251.8' y2='124.9' stroke='%23D8F2FF' stroke-width='1' opacity='.25'/%3E%3Cline x1='252.0' y1='158.0' x2='262.0' y2='158.0' stroke='%23D8F2FF' stroke-width='2' opacity='.5'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='%23D8F2FF' stroke-opacity='.12' stroke-width='14' stroke-linecap='round'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='url(%23b)' stroke-width='14' stroke-linecap='round' stroke-dasharray='289.0' stroke-dashoffset='34.7'/%3E%3C/svg%3E") center / contain no-repeat;
  }

  /* The panel gives up the space the dial now occupies and sits against the
     shell's right edge. A percentage rather than a flat 700px: at 1000px the
     flat value left the dial and the panel almost touching. */
  section:has(.quiz-panel) .quiz-panel {
    margin-inline: auto 0;
    max-width: min(700px, 64%);
  }
}

/* Height: the band was 88px of section padding wrapped around 64px of panel
   padding wrapped around two lines of headline. Same words, less air. */
section:has(.quiz-panel) { padding-block: clamp(44px, 5vw, 64px); }
@media (min-width: 720px) {
  .quiz-panel { padding: clamp(28px, 3.4vw, 44px); }
}

/* ==========================================================================
   v1.11.0 — the homepage health-check band, and shorter "why me" tiles
   ========================================================================== */

/* ---- the dial beside the health-check copy ------------------------------
   The section is a feature section whose Art field is set to "Speed gauge",
   but nothing ever drew it: feature.php reads feature_image only, and
   wps_art() had no 'gauge' key either. The band was therefore a column of
   copy with an empty half beside it.

   Drawn here on the grid's own pseudo-elements rather than as markup, so it
   does not depend on which theme version is installed — every version of
   this section has a .feature grid, whatever it puts inside it. Both layers
   sit in the same grid cell and overlap: one is the track, one the reading.

   No clipping is needed. Both the gradient and the ring mask are centred on
   the bottom edge of a 2:1 box, so the circle they describe is exactly the
   half that fits. */

#health-check { background: var(--tint-50); }

@media (min-width: 900px) {
  #health-check .feature {
    grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
    gap: clamp(32px, 5vw, 72px);
    align-items: center;
    max-width: none;
  }
  /* Everything the template renders goes in the right column; whatever art
     wrapper a given version emits is dropped, since the dial replaces it. */
  #health-check .feature > * { grid-area: 1 / 2; }
  #health-check .feature > .photo-wrap { display: none; }

  #health-check .feature::before {
    content: '';
    grid-area: 1 / 1;
    justify-self: center;
    width: min(100%, 360px);
    aspect-ratio: 300 / 210;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 210'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%234A5B96'/%3E%3Cstop offset='1' stop-color='%23D8F2FF'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cline x1='48.0' y1='158.0' x2='38.0' y2='158.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cline x1='53.0' y1='126.5' x2='48.2' y2='124.9' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='67.5' y1='98.0' x2='63.4' y2='95.1' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='90.0' y1='75.5' x2='87.1' y2='71.4' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='118.5' y1='61.0' x2='116.9' y2='56.2' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='150.0' y1='56.0' x2='150.0' y2='46.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cline x1='181.5' y1='61.0' x2='183.1' y2='56.2' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='210.0' y1='75.5' x2='212.9' y2='71.4' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='232.5' y1='98.0' x2='236.6' y2='95.1' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='247.0' y1='126.5' x2='251.8' y2='124.9' stroke='%231B2966' stroke-width='1' opacity='.25'/%3E%3Cline x1='252.0' y1='158.0' x2='262.0' y2='158.0' stroke='%231B2966' stroke-width='2' opacity='.5'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='%231B2966' stroke-opacity='.12' stroke-width='14' stroke-linecap='round'/%3E%3Cpath d='M58.0 158.0 A 92 92 0 0 1 242.0 158.0' fill='none' stroke='url(%23a)' stroke-width='14' stroke-linecap='round' stroke-dasharray='289.0' stroke-dashoffset='34.7'/%3E%3C/svg%3E") center / contain no-repeat;
  }
}

/* ---- "why me" tiles ----------------------------------------------------
   180px minimum rows meant the tall tile was 380px before a word was set,
   and 32px of padding on top of that. The copy in these tiles is two or
   three lines; the boxes were sized for far more. */
@media (min-width: 860px) {
  .bento { grid-auto-rows: minmax(146px, auto); }
}
.bento-tile { padding: clamp(20px, 2.2vw, 26px); gap: var(--space-2); }
.bento-tile h4 { font-size: var(--text-lg); }
.bento-tile.is-feature h4 { font-size: var(--text-xl); }
.bento-tile.is-feature p { font-size: var(--text-sm); }
.bento-tile .stat-num { font-size: clamp(1.9rem, 2.4vw, 2.4rem); }

/* The real reason the tiles were tall. `.bento-tile > *` sets position:relative
   to lift content above the hover wash; at (0,2,0) it outranks `.bento-art`'s
   own position:absolute, so the decorative art was laid out in flow and added
   210-260px to every tile carrying it. The same trap as the booking panel:
   a `> *` rule quietly taking over a child that had positioned itself. */
.bento-tile > .bento-art { position: absolute; }

/* ==========================================================================
   v1.12.0 — one pass over vertical space, site-wide

   The rhythm was set for a magazine with far more copy per band than this
   site has. Every band opened with 64px under its heading, closed with 88px
   of section padding, and then the next band added its own 88px — so short
   sections were mostly gap. Nothing here changes a layout; it changes how
   much air surrounds it.
   ========================================================================== */

section { padding-block: 40px; }
@media (min-width: 900px) { section { padding-block: 56px; } }

/* The hero was a fifth of a laptop screen before the headline started. */
.hero-light { padding-block: clamp(84px, 10vh, 118px) clamp(48px, 6.5vh, 76px); }
/* The fade at its foot has to shrink with it or it washes over the buttons. */
.hero-light::after { height: 90px; }

/* 64px between a heading and the thing it introduces reads as a missing
   paragraph rather than as breathing room. */
.section-head { margin-bottom: clamp(26px, 3vw, 40px); }

@media (min-width: 900px) { .feature { gap: clamp(36px, 4.5vw, 64px); } }
.feature + .feature { margin-top: clamp(40px, 5vw, 64px); }

.case { padding-block: clamp(36px, 4vw, 56px); }
@media (min-width: 940px) { .case { gap: clamp(32px, 4vw, 52px); } }

.hero-split { gap: clamp(36px, 4.5vw, 56px); }
.stat-row { margin-top: clamp(24px, 3vw, 32px); }
.author-strip { margin-bottom: clamp(26px, 3vw, 40px); }

.journey { margin-top: clamp(28px, 3vw, 40px); }
@media (min-width: 900px) { .stop { padding-bottom: clamp(28px, 3.5vw, 44px); } }

.site-footer { padding-block: 56px 28px; }

/* ==========================================================================
   v1.14.0 — social icons under the contact form

   The icon rail lives in routes.php, and that section is hidden, so the rail
   went with it. Rather than move template code the installed theme will not
   have, the links go in the form section's Note field — which allows <a> and
   <span class> and nothing else — and are dressed as icon buttons here. The
   label of each link stays in the accessibility tree via .sr-only, so a
   screen reader still announces "LinkedIn" rather than "link".

   Order matters: the nth-of-type rules below assume LinkedIn, Instagram,
   Facebook, in that order, in the Note field.
   ========================================================================== */

.form-note:has(a[rel~="me"]) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: clamp(20px, 2.4vw, 28px);
}
.form-note:has(a[rel~="me"]) > strong {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-right: 4px;
}
.form-note a[rel~="me"] {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  background: var(--tint-100, #EFF9FF);
  text-decoration: none;
  transition: background 220ms var(--ease-out), border-color 220ms var(--ease-out),
              transform 220ms var(--ease-out);
}
.form-note a[rel~="me"]::before {
  content: '';
  width: 19px;
  height: 19px;
  background: var(--brand-900, #1B2966);
  -webkit-mask: var(--wps-ico) center / contain no-repeat;
          mask: var(--wps-ico) center / contain no-repeat;
}
.form-note a[rel~="me"]:hover,
.form-note a[rel~="me"]:focus-visible {
  background: var(--brand-900, #1B2966);
  border-color: var(--brand-900, #1B2966);
  transform: translateY(-2px);
}
.form-note a[rel~="me"]:hover::before,
.form-note a[rel~="me"]:focus-visible::before { background: #fff; }

.form-note a[rel~="me"]:nth-of-type(1) { --wps-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4.98 3.5a2.5 2.5 0 11-.02 5 2.5 2.5 0 01.02-5zM3 8.98h4v12H3v-12zM9 8.98h3.8v1.64h.06c.53-1 1.83-2.06 3.76-2.06 4.02 0 4.76 2.65 4.76 6.09v6.33h-4v-5.61c0-1.34-.02-3.06-1.87-3.06-1.87 0-2.15 1.46-2.15 2.96v5.71H9v-12z'/%3E%3C/svg%3E"); }
.form-note a[rel~="me"]:nth-of-type(2) { --wps-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 2.2c3.2 0 3.58.01 4.85.07 3.25.15 4.77 1.69 4.92 4.92.06 1.27.07 1.65.07 4.85s-.01 3.58-.07 4.85c-.15 3.23-1.66 4.77-4.92 4.92-1.27.06-1.65.07-4.85.07s-3.58-.01-4.85-.07c-3.26-.15-4.77-1.7-4.92-4.92C2.17 15.62 2.16 15.24 2.16 12s.01-3.58.07-4.85C2.38 3.92 3.9 2.38 7.15 2.23 8.42 2.18 8.8 2.2 12 2.2zm0 1.8c-3.14 0-3.5.01-4.74.07-2.28.1-3.1.96-3.2 3.2C4 8.5 4 8.86 4 12s.01 3.5.07 4.74c.1 2.24.92 3.1 3.2 3.2 1.23.06 1.6.07 4.73.07s3.5-.01 4.74-.07c2.28-.1 3.1-.96 3.2-3.2.06-1.24.07-1.6.07-4.74s-.01-3.5-.07-4.73c-.1-2.24-.92-3.1-3.2-3.2C15.5 4.01 15.14 4 12 4zm0 3.06A4.94 4.94 0 1112 17a4.94 4.94 0 010-9.88zm0 8.15A3.21 3.21 0 1012 8.8a3.21 3.21 0 000 6.42zm6.29-8.35a1.15 1.15 0 11-2.3 0 1.15 1.15 0 012.3 0z'/%3E%3C/svg%3E"); }
.form-note a[rel~="me"]:nth-of-type(3) { --wps-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M13.5 21v-8h2.7l.4-3.1h-3.1V7.9c0-.9.25-1.5 1.53-1.5h1.64V3.63A22 22 0 0014.28 3.5c-2.37 0-4 1.45-4 4.1v2.3H7.6V13h2.68v8h3.22z'/%3E%3C/svg%3E"); }

/* ==========================================================================
   v1.15.0 — three fixes
   ========================================================================== */

/* ---- 1. the hero has to clear the fixed nav ----------------------------
   .site-header is position:fixed and .nav is min-height:96px, so the hero's
   top padding is the only thing keeping the headline off it. The v1.12
   spacing pass took the minimum down to 84px, which is less than the nav —
   at short viewport heights the headline ran under it. The nav height is now
   part of the sum rather than something the clamp has to be trusted to
   exceed. */
.hero-light {
  padding-block: calc(96px + clamp(28px, 4vh, 56px)) clamp(48px, 6.5vh, 76px);
}

/* ---- 2. the initials in the testimonial circles ------------------------
   .quote-avatar is a <span>, and `.quote-who span` — set for the name and
   role lines — is (0,1,1) against the avatar's (0,1,0). It was winning, so
   display:grid became display:block and the centring went with it. The
   colour half of this collision was patched earlier; this is the rest of it.
   The lesson is the same one the booking panel taught: never style a slot's
   children with a bare element selector. */
.quote-who .quote-avatar {
  display: grid;
  place-items: center;
  font-size: var(--text-sm);
  line-height: 1;
  text-align: center;
}

/* ---- 3. the link on the dark feature tile ------------------------------
   .arrow-link is coloured var(--brand). On the .ink bands that token flips to
   ice, but the bento feature tile is not an .ink band — it paints its own
   navy gradient — so --brand stayed navy and the link was navy on navy.
   Not merely hard to read: invisible. */
.bento-tile.is-feature .arrow-link {
  color: #FFFFFF;
  background-image: linear-gradient(#FFFFFF, #FFFFFF);
}
.bento-tile.is-feature .arrow-link:hover { color: #FFFFFF; }

/* ==========================================================================
   v1.17.0 — service tile icons, and ice bands that touch on mobile
   ========================================================================== */

/* ---- the icon on a services tile --------------------------------------
   Inline SVG taking currentColor, so it is sharp on any display, costs no
   extra request, and inverts correctly if the band tone changes. */
/* The icon sits on a round plate, centred over centred text. display:block
   alone does not centre a fixed-width box — it was hugging the left edge
   while the label under it was centred, which is what made the tiles look
   broken rather than merely plain. */
.svc-ico {
  width: clamp(56px, 5.4vw, 66px);
  aspect-ratio: 1;
  margin: 0 auto clamp(14px, 1.7vw, 18px);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--tint-200);
  color: var(--brand-900, #1B2966);
  transition: background 420ms var(--ease-out), color 420ms var(--ease-out),
              transform 420ms var(--ease-out);
}
.svc-ico svg {
  width: 54%;
  height: 54%;
  display: block;
  fill: none;          /* line icons: the geometry is stroked, not filled */
  overflow: visible;
}

/* On a dark band the plate inverts rather than disappearing. */
.ink .svc-ico { background: rgb(216 242 255 / .12); color: var(--tint-300); }

.svc-tile:hover .svc-ico,
.svc-tile:focus-within .svc-ico {
  background: var(--brand-900, #1B2966);
  color: #fff;
  transform: translateY(-3px);
}
.ink .svc-tile:hover .svc-ico { background: var(--tint-300); color: var(--brand-900, #1B2966); }

/* A short press-in on hover. Short enough to read as feedback, not decoration. */
.svc-tile:hover .svc-ico svg { animation: wps-ico-pop 520ms var(--ease-out); }
@keyframes wps-ico-pop {
  0%   { transform: scale(1) rotate(0); }
  40%  { transform: scale(.86) rotate(-7deg); }
  100% { transform: scale(1) rotate(0); }
}

/* The tiles arrive one after another rather than all at once. */
.svc-tile:nth-child(2) { transition-delay: 60ms; }
.svc-tile:nth-child(3) { transition-delay: 120ms; }
.svc-tile:nth-child(4) { transition-delay: 180ms; }
.svc-tile:nth-child(5) { transition-delay: 60ms; }
.svc-tile:nth-child(6) { transition-delay: 120ms; }
.svc-tile:nth-child(7) { transition-delay: 180ms; }
.svc-tile:nth-child(8) { transition-delay: 240ms; }

/* ---- Principles (About) ------------------------------------------------
   Was four blocks separated by hairlines, which read as a table of contents.
   Cards, with an accent that draws down the edge on hover and a soft wash in
   the corner. No numerals — those were removed from the site deliberately. */
.props { gap: clamp(16px, 2vw, 24px); }
.prop {
  position: relative;
  overflow: hidden;
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 34px);
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out),
              border-color 420ms var(--ease-out);
}
@media (min-width: 800px) { .prop:nth-child(odd) { padding-right: clamp(24px, 3vw, 34px); } }
.prop::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(var(--brand-900, #1B2966), var(--tint-400));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 560ms var(--ease-out);
}
.prop::after {
  content: '';
  position: absolute;
  right: -46px; top: -46px;
  width: 150px; height: 150px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--tint-200), transparent 70%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 520ms var(--ease-out);
}
.prop > * { position: relative; z-index: 1; }
.prop:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px rgb(27 41 102 / .10);
  border-color: var(--brand-300);
}
.prop:hover::before { transform: scaleY(1); }
.prop:hover::after  { opacity: 1; }
.prop:nth-child(2) { transition-delay: 70ms; }
.prop:nth-child(3) { transition-delay: 140ms; }
.prop:nth-child(4) { transition-delay: 210ms; }

@media (prefers-reduced-motion: reduce) {
  .svc-ico, .prop, .prop::before, .prop::after { transition: none; }
  .svc-tile:hover .svc-ico svg { animation: none; }
  .svc-tile:hover .svc-ico, .prop:hover { transform: none; }
}

/* ---- two tinted bands in a row ----------------------------------------
   Above 900px .ink and .band-ice are inset rounded panels, so two in a row
   read as two panels. Below that they are full-bleed, and two ice sections
   touching became one 2,200px block of the same colour with no seam. A
   hairline is enough — anything heavier competes with the section padding. */
@media (max-width: 899px) {
  .band-ice + .band-ice { border-top: 1px solid rgb(27 41 102 / .12); }
  .ink + .ink { border-top: 1px solid rgb(216 242 255 / .18); }
}

/* NOTE: no desktop equivalent of the rule above, deliberately. Above 899px the
   bands are inset panels with rounded corners and a real gap between them —
   three ice sections in a row already read as three. A hairline there draws
   across an edge that is not touching anything. Checked at 1440px before
   assuming otherwise. */

/* The read-more follows the excerpt directly.
   It was pinned to the foot of the card with margin-top:auto so the actions
   would line up across a row — but a grid stretches every card to the tallest,
   and the card's height comes from the image, not the text. The result was a
   97-238px hole between the excerpt and the link. Ragged link positions are a
   far smaller problem than holes, so the cards now size to their own content
   and the link sits where the reader's eye already is. */
.grid-3:has(.post-card) { align-items: start; }
.post-card { display: flex; flex-direction: column; }
.post-card .post-body { display: flex; flex-direction: column; }
.post-card .post-body > p:last-of-type { margin-bottom: clamp(14px, 1.6vw, 20px); }
.post-card .arrow-link { align-self: flex-start; }

/* A centred heading should not be followed by a left-aligned button. */
.section-head.center ~ .btn-row { justify-content: center; }

/* Mailchimp for WordPress lays its fields out in a wrapper of its own, and
   puts the submit inside it. The theme's grid handles the rest. */
.mc4wp-form .mc4wp-form-fields { display: grid; gap: var(--space-4); }
@media (min-width: 520px) {
  .mc4wp-form .mc4wp-form-fields { grid-template-columns: 1fr auto; align-items: end; }
}
.mc4wp-form .mc4wp-response { font-size: var(--text-sm); color: var(--text-secondary); }
.mc4wp-form .mc4wp-alert.mc4wp-success { color: var(--success, #2E7D4F); }
.mc4wp-form .mc4wp-alert.mc4wp-error { color: var(--danger, #B3261E); }

/* ==========================================================================
   v1.21.0 — the checklist offer, rebuilt around the reason it exists
   ========================================================================== */

/* The story carries this section. It is body copy, not a lede, so it gets a
   readable measure and real paragraph spacing rather than one long line. */
.nl-story {
  color: var(--text-secondary);
  line-height: var(--leading-normal);
  max-width: 56ch;
  margin: 0 0 var(--space-5, 20px);
}
/* The section lead sits directly above and carries no bottom margin of its own,
   so without this the first story paragraph reads as a runaway fourth line of
   the lede rather than the start of a new thought. */
.nl-story:first-of-type { margin-top: var(--space-5, 20px); }
.nl-story:last-of-type { margin-bottom: var(--space-8); }
.nl-story strong { color: var(--text-primary); }

.nl-kicker {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 var(--space-5, 20px);
}

/* A peek at the document itself: four real rows, ticked, then the count of
   what is left. This is the thing being traded for an address, so showing it
   beats describing it. */
.nl-preview {
  list-style: none;
  margin: 0 0 var(--space-6);
  padding: var(--space-5, 20px);
  display: grid;
  gap: 10px;
  border-radius: var(--radius-lg);
  background: rgb(255 255 255 / .06);
  border: 1px solid rgb(216 242 255 / .16);
}
.nl-preview li {
  position: relative;
  padding-left: 30px;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--tint-300);
}
.nl-preview li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .12em;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--tint-300);
  /* the tick, as a mask so it takes the plate's colour hole-punched out */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' d='M5 12.5 10 17.5 19 7'/%3E%3C/svg%3E") center / 74% no-repeat,
               linear-gradient(#000, #000);
  -webkit-mask-composite: xor;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' d='M5 12.5 10 17.5 19 7'/%3E%3C/svg%3E") center / 74% no-repeat,
               linear-gradient(#000, #000);
          mask-composite: exclude;
}
/* .62 measured 3.85–4.84:1 against the panel gradient depending on where the
   row lands in it — under AA at the dark end. .78 holds 5.0:1 at the worst
   point and still reads as secondary next to the ticked rows. */
.nl-preview li.is-note {
  padding-left: 0;
  color: rgb(216 242 255 / .78);
  font-style: italic;
}
.nl-preview li.is-note::before { display: none; }

.nl-panel-sub {
  font-size: var(--text-sm);
  color: rgb(216 242 255 / .78);
  margin: calc(var(--space-3) * -1) 0 var(--space-5, 20px);
  line-height: var(--leading-normal);
}

/* ==========================================================================
   v1.22.0 — the native checklist signup (Mailchimp API, no plugin)
   ========================================================================== */

/* Field and button on one line where there is room. They wrap to two rows
   below 480px rather than shrinking the input to something unusable. */
.nl-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: stretch;
}
.nl-row input[type="email"] {
  flex: 1 1 200px;
  min-width: 0;
}
.nl-row .btn { flex: 0 0 auto; }
.nl-form .btn[disabled] { opacity: .6; cursor: progress; }

/* The honeypot. Hidden from people without display:none, because some bots
   skip fields they can tell are not rendered. */
.nl-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.nl-msg {
  margin: var(--space-4, 16px) 0 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  min-height: 1px;
}
.nl-msg:empty { margin: 0; }
/* On the navy panel: white reads as success, and the warm error red used
   elsewhere drops to about 2.6:1 here, so failures use the ice tint plus the
   word itself to carry the meaning rather than colour alone. */
.nl-msg.is-ok  { color: #fff; }
.nl-msg.is-err { color: rgb(216 242 255 / .92); }
.nl-msg-link {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 700;
}
.nl-msg-link:hover { text-decoration-thickness: 2px; }

/* ==========================================================================
   v1.22.0 — plain content pages, and the checklist document
   ========================================================================== */

/* A page with no sections starts with its own <section>, which carries no top
   padding — so its first line rendered underneath the fixed 96px nav. Same
   family of bug as the hero-under-nav one, and it affects every plain page
   (privacy policy, terms, the checklist), not just this one. */
main > section:first-child:not(.hero):not(.hero-light):not([class*="hero"]) {
  padding-top: calc(96px + clamp(28px, 4vh, 56px));
}

/* Prose measure is ~68ch on a 1200px shell, which left the text hugging the
   left edge with a third of the page empty beside it. Centred, it reads as a
   document rather than as a column that failed to fill. */
.prose { margin-inline: auto; }
.prose > h2 { margin-top: var(--space-9, 44px); }
.prose > h2:first-child { margin-top: 0; }

/* The checklist itself: real tick boxes, because a bulleted list does not read
   as something you work through and cross off. */
.cl-list {
  list-style: none;
  margin: var(--space-5, 20px) 0 var(--space-7, 32px);
  padding: 0;
  display: grid;
  gap: var(--space-5, 20px);
}
.cl-list li {
  position: relative;
  padding-left: 40px;
  line-height: var(--leading-normal);
  color: var(--text-secondary);
}
.cl-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .1em;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border: 2px solid rgb(27 41 102 / .3);
  background: #fff;
}
.cl-list li > strong {
  color: var(--text-primary);
  font-size: var(--text-lg, 18px);
}
/* strong + em are one line together; the description starts the next one. */
.cl-list li > br { line-height: 2.1; }
/* The priority label. It is a SIBLING of the strong, not a child — the first
   pass used `strong em`, matched nothing, and the word fell out unstyled onto
   its own line. Colour alone never carries it; the word is the label. */
.cl-list li > em {
  display: inline-block;
  font-style: normal;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  vertical-align: 2px;
  margin-left: 8px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--tint-300, #D8F2FF);
  color: var(--brand, #1B2966);
}

/* A tip, not a pull quote. The default blockquote here is display-sized and
   swallowed the page. */
.prose blockquote {
  margin: var(--space-6) 0 var(--space-8);
  padding: var(--space-5, 20px) var(--space-6, 24px);
  border-left: 3px solid var(--brand, #1B2966);
  border-radius: 0 var(--radius-md, 10px) var(--radius-md, 10px) 0;
  background: var(--tint-300, #D8F2FF);
}
.prose blockquote p {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: var(--leading-normal);
  color: var(--text-primary);
}
.prose blockquote p::before, .prose blockquote p::after { content: none; }

/* A plain page's own H1 was inheriting a body-copy scale, so the document
   title read smaller than the H2s beneath it. */
.prose > h1 {
  font-family: var(--font-display);
  font-size: var(--text-4xl, clamp(34px, 4.4vw, 54px));
  line-height: 1.05;
  letter-spacing: -.01em;
  text-transform: uppercase;
  color: var(--text-primary);
  margin: 0 0 var(--space-6, 24px);
}

/* The signup button sits on the navy panel, where .btn-primary's navy fill is
   invisible and its white label disappears into the white hover wash the
   moment ::before expands. Inverted: white plate, navy label, ice on hover. */
/* Specificity, not just order. `.wps-form button[type="submit"]` is (0,2,1)
   and paints the button navy; `.nl-panel .btn-primary` is (0,2,0) and loses,
   which is why the button was navy-on-navy with its white label vanishing into
   the hover wash. Matching the form rule's own shape is what actually wins. */
.nl-panel .wps-form button[type="submit"],
.nl-panel .wps-form input[type="submit"] {
  background: #fff;
  color: var(--brand-900, #1B2966);
  border-color: #fff;
}
.nl-panel .wps-form button[type="submit"]:hover {
  background: var(--tint-300, #D8F2FF);
  border-color: var(--tint-300, #D8F2FF);
  color: var(--brand-900, #1B2966);
}
/* The .btn hover wash would paint over the plate; the plate is the hover. */
.nl-panel .wps-form button[type="submit"]::before { content: none; }

/* Field and button share a height so the row does not look assembled from
   two unrelated controls. */
.nl-row input[type="email"] { min-height: 54px; }

/* ==========================================================================
   v1.26.0 — the checklist panel in white, to match every other card

   It was navy on ice, which made it the only card on the site painted in the
   band colour of a different section. White on ice is what "how this works",
   the post cards and the quiz panel all do, so this now lines up with them.
   Every child that was written for a dark ground has to be turned over with
   it — a panel that changes colour and leaves its contents behind is how you
   get ice-on-white text.
   ========================================================================== */

.nl-panel {
  background: var(--surface-raised, #fff);
  border: 1px solid var(--border-default);
  box-shadow: var(--elevation-4);
  color: var(--text-primary);
}

/* The drawn sheet was a light tint meant to read against navy. */
.nl-sheet { color: var(--brand-900, #1B2966); opacity: .12; }

.nl-badge {
  background: var(--tint-300, #D8F2FF);
  color: var(--brand-900, #1B2966);
}

.nl-preview {
  background: var(--tint-50, #F8FDFF);
  border-color: rgb(27 41 102 / .12);
}
.nl-preview li { color: var(--text-secondary); }
.nl-preview li::before { background: var(--brand-900, #1B2966); }
.nl-preview li.is-note { color: var(--text-muted); }

.nl-panel-title { color: var(--text-primary); }
.nl-panel-sub { color: var(--text-secondary); }
.nl-panel .form-note { color: var(--text-secondary); }

.nl-panel label { color: var(--text-primary); }
.nl-panel input[type="email"],
.nl-panel input[type="text"] {
  background: #fff;
  border-color: var(--border-default);
  color: var(--text-primary);
  /* The placeholder was sitting hard against the left border. */
  padding-inline: var(--space-5, 20px);
}
.nl-panel input::placeholder { color: var(--text-muted); }
.nl-panel input:focus { background: #fff; }

/* Back to the site's normal primary button now that the ground is white. */
.nl-panel .wps-form button[type="submit"],
.nl-panel .wps-form input[type="submit"] {
  background: var(--brand-900, #1B2966);
  color: #fff;
  border-color: var(--brand-900, #1B2966);
}
.nl-panel .wps-form button[type="submit"]:hover {
  background: var(--brand-700, #313A7A);
  border-color: var(--brand-700, #313A7A);
  color: #fff;
}

.nl-msg.is-ok  { color: var(--text-primary); }
.nl-msg.is-err { color: var(--text-primary); }
