/* ============================
   SCORITZ — single-page styles
   ============================ */

:root {
  --bg: #0e1422;
  --bg-2: #131a2c;
  --card: #1a2235;
  --card-2: #232c44;
  --line: rgba(255, 255, 255, 0.06);
  --ink: #ffffff;
  --ink-mute: rgba(255, 255, 255, 0.65);
  --ink-dim: rgba(255, 255, 255, 0.45);

  --yellow: #d4ff3a;
  /* Unified to the single brand highlighter lime — no slightly-different shade.
     Button hover feedback comes from the translateY lift, not a colour shift. */
  --yellow-hi: #d4ff3a;
  --green: #b4ff7f;
  --green-2: #6fe0a0;
  --pink: #ff8aa0;
  --blue: #6ee0ff;
  --purple: #a394ff;

  --cream: #f1ede2;
  --cream-2: #ece7d8;
  --ink-dark: #0e1422;

  --container: 1240px;
  --radius: 22px;
  --radius-sm: 14px;
  --radius-pill: 999px;

  --font: 'Golos Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  --font-serif: 'Golos Text', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, sans-serif;

  /* Let height transitions tween to/from `auto` (e.g. the "Something else" detail
     field opening). Modern browsers animate it; the rest fall back to an instant
     show/hide. */
  interpolate-size: allow-keywords;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  /* Clip the horizontal bleed of the full-bleed bands (e.g. .work__heading::before
     uses width:100vw, which includes the vertical-scrollbar gutter and otherwise
     pushes a ~15px horizontal scrollbar in browsers with classic scrollbars).
     `clip` (not `hidden`) clips without creating a scroll container, so the deck's
     position:sticky keeps resolving against the viewport. */
  overflow-x: clip;
}

/* Sticky .nav (~68px) overlaps the top of anchor targets — offset in-page jumps
   (native + scrollIntoView) so section headings clear it instead of tucking under. */
html {
  scroll-padding-top: 84px;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 18px;
  line-height: 1.65;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img {
  max-width: 100%;
  display: block;
  /* Images aren't draggable — no ghost-image drag in WebKit/Blink. Firefox
     ignores user-drag, so a global dragstart guard in script.js covers it there. */
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

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

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
}

/* Visually hidden but available to screen readers (e.g. "opens in a new tab"). */
.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;
}

/* ============ Buttons ============ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 18px 36px;
  border-radius: 40px;
  font-weight: 600;
  font-size: 18px;
  line-height: 1;
  letter-spacing: 0;
  /* 2px so outlined variants (.btn--ghost, .btn--ghost-yellow) match the 2px
     service pills and stay crisp on curves at fractional display scaling.
     Solid buttons keep this border transparent — it only equalises the box so
     ghost + solid buttons sitting in the same row line up to the pixel. */
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
  text-decoration: none;
  font-family: var(--font);
}

.btn:hover {
  transform: translateY(-1px);
}

.btn--yellow {
  background: var(--yellow);
  color: var(--ink-dark);
}

.btn--yellow:hover {
  background: var(--yellow-hi);
}

.btn--dark {
  background: var(--ink-dark);
  color: var(--ink);
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: rgba(255, 255, 255, 0.18);
}

.btn--ghost:hover {
  border-color: rgba(255, 255, 255, 0.45);
}

.btn--ghost-yellow {
  background: transparent;
  color: var(--yellow);
  border: 2px solid var(--yellow);   /* match base + pills (was 1.5px, pixely on the curve) */
}

.btn--ghost-yellow:hover {
  background: var(--yellow);
  color: var(--ink-dark);
}

.btn--sm {
  padding: 14px 26px;
  font-size: 16px;
}

.arrow {
  display: inline-block;
  font-weight: 500;
  user-select: none;
  -webkit-user-select: none;
}

/* ============ NAV ============ */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(14, 20, 34, 0.78);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: 28px;
  padding-top: 14px;
  padding-bottom: 14px;
}

.logo {
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.logo__dot {
  color: var(--yellow);
}

.nav__links {
  display: flex;
  gap: 26px;
  margin-left: 18px;
  flex: 1;
}

.nav__links a {
  color: var(--ink-mute);
  font-size: 15px;
  font-weight: 500;
  transition: color 0.15s;
}

.nav__links a:hover {
  color: var(--ink);
}

.nav__toggle {
  display: none;
  background: transparent;
  border: 0;
  width: 36px;
  height: 36px;
  cursor: pointer;
  position: relative;
}

.nav__toggle span {
  display: block;
  width: 24px;
  height: 2px;
  margin: 5px auto;
  background: #fff;
}

/* ============ HERO ============ */
.hero {
  position: relative;
  padding: 64px 0 71px;
  /* Fill the viewport (minus the sticky nav) so the white landing extends down
     and the navy "New & featured web design work" section stays below the fold
     on load. The tall navy logos strip below keeps the heading well off-screen. */
  min-height: calc(100vh - 60px);
  overflow: hidden;
  /* Isolate the hero's blend group. The fluid canvas uses mix-blend-mode:multiply
     and the navy .hero__shape (curved bottom) is promoted to its own GPU layer by
     will-change:transform. Without isolation, a multiply element blending across a
     sibling that lives on a separate composited layer renders wrong on real GPUs —
     the dye leaks past the navy curve at the bottom (software rendering composites
     in one pass, so it only shows on hardware). Isolating forces the navy layer to
     composite reliably on top, so the liquid's edge follows the curve. */
  isolation: isolate;
  color: var(--ink-dark);
  background:
    radial-gradient(ellipse 60% 50% at 15% 20%, rgba(255, 196, 220, 0.55), transparent 60%),
    radial-gradient(ellipse 50% 50% at 85% 25%, rgba(178, 208, 255, 0.55), transparent 60%),
    radial-gradient(ellipse 65% 45% at 50% 90%, rgba(255, 232, 180, 0.5), transparent 60%),
    radial-gradient(ellipse 40% 40% at 80% 80%, rgba(208, 232, 255, 0.45), transparent 60%),
    #f4f1ec;
}

.hero__fluid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  display: block;
  opacity: 0.8;
  mix-blend-mode: multiply;
  pointer-events: auto;
}

/* Hero wordmark canvas — sits behind the fluid canvas and reveals the giant
   "scoritz" text only where the pointer/fluid trail has built up. JS-driven.
   The default visual state is fully transparent (canvas is empty). */
.hero__wordmark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  display: block;
}

/* Clip both hero canvases to the same curved bottom as .hero__shape, so the
   fluid dye (and wordmark reveal) can never paint past the curve. The navy
   .hero__shape already sits on top and hides the overflow, but some GPUs let a
   ~1px dye halo bleed along the mix-blend-mode edge, so the border reads as not
   lining up with the curve — this masks the source instead of relying on the
   overlay. Geometry mirrors .hero__shape exactly: bottom-anchored, 110px band
   (810px tall shape − 700px offset), curve in that band's top 97px. The path is
   the shape's own top edge; the second layer keeps everything above the band
   visible. */
.hero__fluid,
.hero__wordmark {
  -webkit-mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 110' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0,0 L1000,0 L1000,1 C1000,19.4 873.3,97.8 500,97 C126.7,96.3 0.8,19.8 0,0 Z'/%3E%3C/svg%3E") left bottom / 100% 110px no-repeat,
    linear-gradient(#fff, #fff) left top / 100% calc(100% - 110px) no-repeat;
  mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 110' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0,0 L1000,0 L1000,1 C1000,19.4 873.3,97.8 500,97 C126.7,96.3 0.8,19.8 0,0 Z'/%3E%3C/svg%3E") left bottom / 100% 110px no-repeat,
    linear-gradient(#fff, #fff) left top / 100% calc(100% - 110px) no-repeat;
}

/* Rotator word slide/fade animation — each swap replaces the .word DOM node
   with a fresh one, guaranteeing the animation plays. */
.hero__title .word {
  display: inline-block;
  opacity: 1;
  transition: opacity 0.26s ease;
  will-change: opacity;
  background-image: linear-gradient(
    90deg,
    transparent 0.4%,
    rgba(212, 255, 58, 0.85) 0.8%,
    rgba(212, 255, 58, 0.85) 99.2%,
    transparent 99.6%
  );
  background-repeat: no-repeat;
  background-size: 102% 93%;
  background-position: -1% 100%;
  padding: 0.01em 0.18em 0.12em;
  color: var(--ink-dark);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Rotator slot: the visible .word and a hidden ghost (holding the widest word)
   share one inline-grid cell, so the slot's width is fixed to the widest word
   from first paint. No JS width measurement means the centred hero line never
   reflows/jumps on load, and the slot survives 200% zoom + font-size overrides. */
.rotator {
  display: inline-grid;
  justify-items: start;
  align-items: baseline;
}
.rotator > * {
  grid-area: 1 / 1;
  white-space: nowrap;
}
/* Same box as .word (matching horizontal padding) so it reserves the exact width,
   just invisible. */
.rotator__ghost {
  visibility: hidden;
  padding: 0.01em 0.18em 0.12em;
}
@media (max-width: 640px) {
  .rotator { justify-items: center; }
}

/* ----- Curved bottom + 700px navy tail in one SVG (Elementor-pattern, monolithic).
   The SVG is 810px tall and sticks 700px below the hero so initially only the top
   ~110px (the curve) shows. When transform:translateY(-700px) is applied on scroll,
   the whole element slides up as one piece — no SVG↔tail seam, no gap. ----- */
.hero__shape {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -700px;
  width: 100%;
  height: 810px;
  pointer-events: none;
  z-index: 3;
  transition: transform 0.9s ease-in-out;
  will-change: transform;
}

.hero__shape svg {
  display: block;
  width: 100%;
  height: 100%;
}

.hero__shape-fill {
  fill: var(--bg);
}

.hero .container {
  text-align: center;
  position: relative;
  z-index: 2;
  pointer-events: none;
}

.hero .container .btn,
.hero .container a,
.hero__brand {
  pointer-events: auto;
}

.hero__pills {
  position: relative;
  height: 0;
  z-index: 2;
}

.pill {
  position: absolute;
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-dark);
  border: 1.5px solid var(--ink-dark);
  white-space: nowrap;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.35);
}

.pill--blue {
  background: var(--blue);
  top: 30px;
  left: 7%;
  transform: rotate(-4deg);
}

.pill--yellow {
  background: var(--yellow);
  top: 14px;
  right: 8%;
  transform: rotate(3deg);
}

.pill--green {
  background: var(--green);
  top: 250px;
  left: 4%;
  transform: rotate(4deg);
}

.pill--pink {
  background: var(--pink);
  top: 220px;
  right: 3%;
  transform: rotate(-2deg);
}

.pill--purple {
  background: var(--purple);
  top: 470px;
  right: 10%;
  transform: rotate(2deg);
}

.hero__brand {
  font-weight: 800;
  font-size: 26px;
  letter-spacing: -0.02em;
  padding-top: 18px;
}

.hero__title {
  font-size: clamp(38px, 5.2vw, 74px);
  line-height: 1.15em;
  letter-spacing: -0.04em;
  font-weight: 600;
  margin: 34vh auto 0;
  max-width: 1100px;
}

.grad {
  background: linear-gradient(90deg, #a3d800 0%, #2ea974 55%, #1d8a8e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lede {
  max-width: 640px;
  margin: 28px auto 0;
  color: rgba(14, 20, 34, 0.72);
  font-size: 18px;
  line-height: 1.65em;
  font-weight: 400;
}

/* Light-hero variants of buttons + brand wordmark */
.hero .btn--ghost {
  color: var(--ink-dark);
  border-color: rgba(14, 20, 34, 0.22);
}

.hero .btn--ghost:hover {
  border-color: rgba(14, 20, 34, 0.45);
  background: rgba(14, 20, 34, 0.04);
}

.hero .logo__dot {
  color: var(--ink-dark);
}

.hero__cta {
  display: flex;
  gap: 14px;
  justify-content: center;
  margin-top: 28px;
  flex-wrap: wrap;
}

/* ----- mosaic ----- */
.mosaic {
  position: relative;
  margin: 70px auto 0;
  max-width: 1500px;
  height: 720px;
  perspective: 1600px;
}

.mosaic__tilt {
  transform: rotateX(28deg) rotateZ(-3deg);
  transform-origin: top center;
}

.mosaic__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 18px;
  padding: 0 40px;
}

.thumb {
  aspect-ratio: 16 / 11;
  border-radius: 18px;
  background: linear-gradient(135deg, #5b4cd0 0%, #8a3fff 100%);
  position: relative;
  overflow: hidden;
  color: rgba(255, 255, 255, 0.92);
  font-weight: 700;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.6);
}

.thumb span {
  font-family: var(--font-serif);
  font-size: 22px;
  letter-spacing: 0.02em;
}

.thumb::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.25), transparent 50%),
    radial-gradient(circle at 80% 80%, rgba(0, 0, 0, 0.25), transparent 50%);
  pointer-events: none;
}

.t1 { background: linear-gradient(140deg, #ffb56b, #ff7a59); }
.t2 { background: linear-gradient(140deg, #ff96c6, #c45ad8); }
.t3 { background: linear-gradient(140deg, #6ee0ff, #4a8cff); }
.t4 { background: linear-gradient(140deg, #1f2a44, #2c3e6a); }
.t5 { background: linear-gradient(140deg, #b4ff7f, #5dd49a); }
.t6 { background: linear-gradient(140deg, #f0c87a, #b3733a); }
.t7 { background: linear-gradient(140deg, #5b4cd0 0%, #8a3fff 100%); }
.t8 { background: linear-gradient(140deg, #1a3a2a, #2f6b48); }
.t9 { background: linear-gradient(140deg, #f9efd2, #e0b878); color: #2a2010; }
.t10 { background: linear-gradient(140deg, #ff8aa0, #d44872); }
.t11 { background: linear-gradient(140deg, #2c2052, #4a3aa3); }
.t12 { background: linear-gradient(140deg, #f8d889, #ec9e3a); color: #3a2710; }
.t13 { background: linear-gradient(140deg, #d9c1f5, #8460c8); }
.t14 { background: linear-gradient(140deg, #1a2235, #354064); }
.t15 { background: linear-gradient(140deg, #5d4a32, #a07a44); }

.thumb--feature {
  background: var(--yellow);
  color: var(--ink-dark);
}

.thumb--feature::before {
  display: none;
}

.thumb__big {
  font-family: var(--font) !important;
  font-size: 26px !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  text-align: center;
  line-height: 1.05;
}

/* ============ LOGOS ============ */
.logos {
  background: var(--bg);
  padding: 100px 0 80px;
  text-align: center;
}

.logos__label {
  color: var(--ink-dim);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 36px;
}

.marquee {
  width: 100%;
  overflow: hidden;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0%,
    #000 8%,
    #000 92%,
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0%,
    #000 8%,
    #000 92%,
    transparent 100%
  );
}

.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee-scroll 45s linear infinite;
}

.marquee__row {
  display: flex;
  align-items: center;
  gap: 110px;
  padding-right: 110px;
  flex-shrink: 0;
}

.marquee__row img {
  height: 56px;
  width: auto;
  max-width: 240px;
  object-fit: contain;
  flex-shrink: 0;
  -webkit-user-drag: none;
  user-drag: none;
  filter: grayscale(100%) brightness(0) invert(1);
  opacity: 0.55;
  transition: opacity 0.2s;
}

.marquee__row img[src*="waracle"] {
  height: 210px;
  max-width: 780px;
}

.marquee__row img[src*="stanleybet"] {
  height: 160px;
  max-width: 580px;
  /* PNG has ~40px transparent padding each side (≈32px at this scale) — cancel
     it so its visible content sits flush and the gaps stay even. */
  margin: 0 -32px;
}

.marquee__row img[src*="expian"] {
  margin: 0 -3px;
}

.marquee__row img[src*="vertar"] {
  height: 44px;
  max-width: 190px;
}

.marquee__row img[src*="estee"] {
  height: 70px;
  max-width: 300px;
}

.marquee__row img[src*="sainsburys"] {
  height: 64px;
  max-width: 280px;
  transform: translateY(12px);
}

.marquee__row img[src*="thomson"] {
  transform: translateY(6px);
}


/* Pause only while the cursor is actually over a logo — not the whole full-width
   strip (its hover band is as tall as the biggest logo, which felt too generous). */
.marquee__track:has(img:hover) {
  animation-play-state: paused;
}

.marquee__row img:hover {
  opacity: 1;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

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

/* Phones: the per-logo sizes above are tuned for desktop and render as one giant
   wordmark filling a narrow screen. Scale every logo down (~half) and tighten the
   gap so several brands are visible at once while the strip still scrolls. */
@media (max-width: 640px) {
  .marquee__row { gap: 40px; padding-right: 40px; }
  .marquee__row img { height: 30px; max-width: 130px; }
  .marquee__row img[src*="waracle"]    { height: 100px; max-width: 380px; }
  .marquee__row img[src*="stanleybet"] { height: 80px;  max-width: 290px; margin: 0 -16px; }
  .marquee__row img[src*="estee"]      { height: 38px;  max-width: 160px; }
  .marquee__row img[src*="vertar"]     { height: 24px;  max-width: 100px; }
  .marquee__row img[src*="sainsburys"] { height: 34px;  max-width: 150px; transform: translateY(6px); }
}

/* ============ A11Y: skip link, focus, reduced motion ============ */

.skip-link {
  position: absolute;
  left: 16px;
  top: 16px;
  z-index: 1000;
  padding: 10px 14px;
  background: var(--ink-dark);
  color: var(--yellow);
  border: 2px solid var(--yellow);
  border-radius: var(--radius-sm);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform 0.18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: none;
}

/* Visible keyboard focus ring across all interactive elements. Yellow on
   navy is high-contrast; the outer dark halo keeps it visible on cream
   surfaces too. */
:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--ink-dark);
  border-radius: 2px;
}
.btn:focus-visible,
.faq__q:focus-visible,
.circle-btn:focus-visible,
.swatch:focus-visible,
.nav__toggle:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 3px;
  box-shadow: none;
}

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

/* ============ WORK ============ */
.work {
  background: var(--bg);
  padding: 90px 0 100px;
}

/* Recent Projects breaks a little wider than the standard 1240 container so the
   stacked cards read large and prominent. */
.work .container {
  max-width: 1440px;
}

.work__heading {
  font-size: clamp(36px, 4.2vw, 60px);
  text-align: center;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.2em;
  margin: 0 0 60px;
}

.underlined {
  background-image: linear-gradient(
    90deg,
    transparent 0.4%,
    rgba(212, 255, 58, 0.85) 0.8%,
    rgba(212, 255, 58, 0.85) 99.2%,
    transparent 99.6%
  );
  background-repeat: no-repeat;
  background-size: 102% 93%;
  background-position: -1% 100%;
  padding: 0.01em 0.18em 0.12em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  color: var(--ink-dark);
}

.work__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}

.card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  transition: transform 0.2s ease, background 0.2s ease;
  overflow: hidden;
  border: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
}

.card:hover {
  transform: translateY(-3px);
  background: var(--card-2);
}

.card header h3 {
  margin: 6px 0 0;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.card__tag {
  font-size: 13px;
  color: var(--yellow);
  font-weight: 600;
}

.card--lg {
  grid-column: span 2;
}

/* ---- Recent Projects: sticky stacking cards ----------------------------
   Every card pins at the SAME sticky top, so they all pin and unpin together
   and the finished stack scrolls away as one rigid block. position: sticky owns
   ALL the motion — the pin, the per-card --peek offset (a constant transform)
   and the leave — so it's compositor-driven and never jitters against scroll.
   script.js only paints the depth gradient (shrink + darken/blur as a card is
   covered). Later cards sit later in the DOM + higher z-index, so they paint on
   top.

   Under prefers-reduced-motion the sticky + transform rules drop and the cards
   fall back to a plain, fully readable vertical list. */
.work__deck-stage {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.deck-card .card__visual {
  min-height: 400px;
}

@media (prefers-reduced-motion: no-preference) {
  /* Keep the "Recent Projects" label pinned at the top through the whole section
     — it releases with .work .container once you've scrolled past — so it stays
     visible while you read the deck. The cards pin just below it (see --stick). */
  .work__heading {
    position: sticky;
    top: 134px;                             /* gap below the ~75px sticky nav — roomy breathing space above the label (keep in sync with --stick below) */
    z-index: 20;                            /* above the deck cards (z 1–4), below the nav (z 50) */
    background: var(--bg);                  /* solid label band so rising cards never show through the text */
  }

  /* The deck cards sit in their own GPU layers (will-change + transforms), so the
     heading's container-width band composited a shade darker than the section
     behind it — a faint rectangle framing the label — plus the top card's shadow
     bled into the gap just beneath it. A full-bleed opaque fill behind the label
     erases both: edge-to-edge so there are no side edges, and reaching down to the
     first card's top (stopping above its tag) to swallow the shadow. */
  .work__heading::before {
    content: "";
    position: absolute;
    left: 50%;
    width: 100vw;
    transform: translateX(-50%);
    top: -44px;
    bottom: -66px;                         /* reach down the full 60px pinned gap to the first card's top (+6px over it) so the card's shadow is swallowed and its top clips behind the label as it rises (keep in sync with --stick gap) */
    background: var(--bg);
    z-index: -1;                            /* behind the label text, still above the cards (heading is z 20) */
  }

  .work__deck-stage {
    --stick: calc(134px + clamp(36px, 4.2vw, 60px) * 1.25 + 60px);  /* pin cards below the pinned heading: heading top (134) + heading line-height + gap. Gap = the heading's natural margin-bottom (60px) so the pinned spacing matches the normal-flow spacing and never collapses on scroll (keep in sync with .work__heading margin + ::before bottom). */
    --peek: 64px;                           /* sliver of each card behind that stays visible — enough to keep its tag + title legible (cards scale from top, so content compresses up into it) */
    gap: clamp(40px, 6vh, 88px);            /* a light beat between cards — kept modest so the deck scrolls casually rather than holding each card pinned for ages */
    padding-bottom: clamp(48px, 8vh, 120px); /* brief frozen hold on the finished stack before it scrolls on (the stack still leaves as one block regardless) */
  }

  .deck-card {
    position: sticky;
    /* Same sticky top for every card → all pin and unpin together, so the stack
       leaves as one block. The FIRST card pins right here under the nav (no big
       gap below the heading); script.js offsets the later cards down one --peek
       each so they sit below it in the stack. */
    top: var(--stick);
    height: clamp(540px, 86vh, 760px);      /* EQUAL height (not just min) so every card unpins at the exact same scroll point and the stack leaves together; the flex visual absorbs the slack */
    transform-origin: center top;           /* scale-down (script.js) recedes from the top edge, anchoring the peeking sliver */
    transition: background 0.2s ease;       /* override .card's transform transition: script.js rewrites transform every frame, so transitioning it makes the rendered position/scale lag the scroll (cards desync → seams) */
    will-change: transform;
    box-shadow: 0 -6px 28px -14px rgba(0, 0, 0, 0.55),
                0 22px 50px -16px rgba(0, 0, 0, 0.55);
  }

  /* Ascending z-index so the front (last) card paints on top of the ones behind. */
  .deck-card:nth-child(1) { z-index: 1; }
  .deck-card:nth-child(2) { z-index: 2; }
  .deck-card:nth-child(3) { z-index: 3; }
  .deck-card:nth-child(4) { z-index: 4; }
}

.card__visual {
  margin-top: auto;
  flex: 1 1 auto;
  min-height: 220px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, #4a3eb0, #8245d4);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-serif);
  color: rgba(255, 255, 255, 0.9);
  font-size: 28px;
}

.card--lg .card__visual {
  min-height: 320px;
}

.card__name {
  font-family: var(--font-serif);
  font-size: 30px;
  letter-spacing: 0.02em;
}

.visual--gradient-1 { background: linear-gradient(135deg, #1a3a2a, #2f6b48); }
.visual--gradient-2 { background: linear-gradient(135deg, #6ee0ff, #4a8cff); }
.visual--gradient-3 { background: linear-gradient(135deg, #f9efd2, #c8a35a); color: #2a2010; }
.visual--gradient-4 { background: linear-gradient(135deg, #ff96c6, #c45ad8); }
.visual--gradient-host { background: linear-gradient(135deg, #243250, #111b33); }
.visual--gradient-5 { background: linear-gradient(135deg, #232035, #38356b); }
.visual--gradient-6 { background: linear-gradient(135deg, #f0c87a, #b3733a); }
.visual--gradient-7 { background: linear-gradient(135deg, #cfd7e6, #8ea1c3); color: #1a2235; }
.visual--gradient-8 { background: linear-gradient(135deg, #1c2050, #3a3f9d); }
.visual--gradient-9 { background: linear-gradient(135deg, #5b3fff, #b14bff); }
.visual--gradient-10 { background: linear-gradient(135deg, #2a1a1a, #6b2a2a); }
.visual--gradient-11 { background: linear-gradient(135deg, #18324e, #2a5a8a); }
.visual--gradient-12 { background: linear-gradient(135deg, #fffdfa, #d8d3c4); color: #1a2235; }
.visual--gradient-13 { background: linear-gradient(135deg, #2c5042, #5ea185); }
.visual--gradient-14 { background: linear-gradient(135deg, #2d1c10, #6f4520); }

.visual--photo-1 {
  background: url('img/logos/superjolt-example.png') center top / cover no-repeat #c0b8a8;
  color: #fff;
}

.visual--photo-vertar {
  background: url('img/logos/vertar-example.png') center top / cover no-repeat #1a2235;
  color: #fff;
}

/* The superjolt.com / vertar.com card visuals show a one-off screenshot of each
   live site (visual--photo-*) — a flat image so it scales smoothly as the card
   recedes (a live <iframe> here re-rasterised on every scale step, which
   shimmered). Re-capture manually with scripts/screenshots.mjs if a site
   changes. Clicking the card still opens the real site. */
.visual--photo-2 { background: linear-gradient(135deg, #d8c4a1 0%, #a08660 100%); color: #2a2010; }
.visual--photo-3 { background: linear-gradient(135deg, #214a44 0%, #305b53 100%); }
.visual--photo-4 { background: linear-gradient(135deg, #b58a5c 0%, #6b4628 100%); color: #fef6e8; }
.visual--photo-5 {
  background:
    linear-gradient(rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.42)),
    linear-gradient(135deg, #1a1a22 0%, #443a55 100%);
}

.visual__caption {
  font-family: var(--font-serif);
  font-size: 36px;
  color: #fff;
  background: rgba(255, 255, 255, 0.15);
  padding: 14px 26px;
  border-radius: 8px;
  letter-spacing: -0.01em;
}

.visual__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.visual__quote {
  font-family: var(--font-serif);
  font-size: 30px;
  text-align: center;
  letter-spacing: 0.04em;
  color: #fff;
  margin: 0;
  padding: 24px;
  line-height: 1.15;
}

.visual__quote strong {
  font-weight: 400;
  color: var(--yellow);
}

.visual__quote-sm {
  font-family: var(--font-serif);
  font-size: 22px;
  letter-spacing: 0.18em;
  text-align: center;
  color: #fef6e8;
  margin: 0;
}

.card--cta {
  background: var(--yellow);
  color: var(--ink-dark);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 16px;
  padding: 28px;
}

/* The CTA stays lime on hover — the generic .card:hover grey would wash it out.
   Keep just the lift (inherited) for feedback. */
.card--cta:hover {
  background: var(--yellow);
}

.card--cta .card__tag {
  color: var(--ink-dark);
  opacity: 0.72;
}

.card--cta h3 {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.03em;
  margin: 0;
  line-height: 1.2em;
}

.card--cta .btn {
  align-self: flex-start;
  margin-top: 4px;
}

/* ---- CTA card: website "skeleton" wireframe -----------------------------
   A flat mock of a site we'd build, sitting in a little browser frame. Purely
   decorative (aria-hidden in the markup); the loading shimmer is gated to
   prefers-reduced-motion below. */
.site-skel {
  margin-top: 0;
  background: #111726;                 /* browser shell */
  border-radius: var(--radius-sm);
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden;
}

.site-skel__bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 11px 14px;
  background: #1a2235;
}

.site-skel__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
}

.site-skel__addr {
  flex: 1;
  height: 14px;
  margin-left: 8px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.1);
}

.site-skel__page {
  position: relative;
  flex: 1;
  background: var(--cream);
  padding: 18px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}

.site-skel__nav {
  display: flex;
  align-items: center;
  gap: 12px;
}

.site-skel__logo {
  width: 64px;
  height: 16px;
  border-radius: 5px;
  background: #c7c1b1;
}

.site-skel__links {
  margin-left: auto;
  display: flex;
  gap: 10px;
}

.site-skel__links span {
  width: 38px;
  height: 10px;
  border-radius: 5px;
  background: #d7d2c4;
}

.site-skel__hero {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0 4px;
}

.site-skel__h {
  height: 22px;
  border-radius: 6px;
  background: #bdb7a6;
}

.site-skel__h--1 { width: 78%; }
.site-skel__h--2 { width: 56%; }

.site-skel__cta {
  margin-top: 6px;
  width: 132px;
  height: 34px;
  border-radius: 9px;
  background: var(--yellow);          /* a lime CTA button — brand echo */
}

.site-skel__grid {
  margin-top: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.site-skel__grid span {
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  background: #dcd7c9;
}

@media (prefers-reduced-motion: no-preference) {
  /* loading shimmer sweeping across the page */
  .site-skel__page::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(
      100deg,
      transparent 30%,
      rgba(255, 255, 255, 0.55) 50%,
      transparent 70%
    );
    transform: translateX(-100%);
    animation: skel-shimmer 2.8s ease-in-out infinite;
  }

  @keyframes skel-shimmer {
    0% { transform: translateX(-100%); }
    60%, 100% { transform: translateX(100%); }
  }
}

/* ============ ROOTED ============ */
.rooted {
  background: var(--bg);
  padding: 0 0 80px;
  /* Lands a touch low under the global 84px scroll offset — nudge the cream
     panel down so its top edge sits cleanly below the nav on a #process jump. */
  scroll-margin-top: 12px;
}

.rooted__panel {
  background: var(--cream);
  color: var(--ink-dark);
  border-radius: 40px;
  padding: 60px 0 80px;
  position: relative;
}

.rooted__grid {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 60px;
  align-items: start;
}

.rooted__side {
  background: #fff;
  border-radius: var(--radius);
  padding: 28px;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.rooted__side h3 {
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}

.rooted__side p {
  font-size: 14px;
  color: #4a4f5c;
  margin: 0 0 24px;
  line-height: 1.55;
}

.rooted__side-visual {
  background: #f5f1e3;
  border-radius: 14px;
  padding: 20px;
}

.mini-card {
  background: #fff;
  border-radius: 12px;
  padding: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
}

.mini-card__bar {
  height: 8px;
  background: #e6e1d2;
  border-radius: 4px;
  margin-bottom: 8px;
}

.mini-card__bar--short {
  width: 70%;
  margin-bottom: 18px;
}

.mini-card__btn {
  display: inline-block;
  background: var(--yellow);
  color: var(--ink-dark);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  user-select: none;
  -webkit-user-select: none;
}

.rooted__main h2 {
  font-size: clamp(36px, 4.2vw, 60px);
  letter-spacing: -0.04em;
  font-weight: 600;
  line-height: 1.2em;
  margin: 0 0 24px;
}

.rooted__lede {
  font-size: 16px;
  color: #4a4f5c;
  line-height: 1.6;
  margin: 0 0 36px;
  max-width: 640px;
}

.stats {
  display: flex;
  gap: 36px;
  margin: 0 0 36px;
  flex-wrap: wrap;
}

.proc-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  margin: 0 0 36px;
}

.proc-card {
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: var(--radius);
  padding: 24px 24px 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.proc-card:hover {
  border-color: rgba(14, 20, 34, 0.16);
  transform: translateY(-2px);
}

/* ---- Scroll reveal -------------------------------------------------------
   [data-reveal] fades + rises once when scrolled into view; [data-reveal-group]
   staggers its direct children (script.js adds .is-revealed and per-child
   delays). Gated on .js (set in <head>) + no-preference, so everything stays
   visible without JS or when the user prefers reduced motion. `backwards` fill
   holds the start state through each stagger delay and leaves no forwards fill,
   so element :hover transforms still work afterwards. Only opacity/transform
   change — no layout reflow, so this adds no cumulative layout shift. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal],
  .js [data-reveal-group] > * {
    opacity: 0;
  }
  .js [data-reveal].is-revealed,
  .js [data-reveal-group] > .is-revealed {
    opacity: 1;
    animation: reveal-rise 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  }
}

@keyframes reveal-rise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Recent Projects deck pops UP into frame as it scrolls in — a bigger, more
   deliberate rise than the default reveal, echoing the hero shape lifting up
   out of frame. The wrapper animates, not the sticky cards, so it composes with
   projectStack()'s per-card transforms: the whole stack rises in as one block.
   `backwards` fill leaves no forwards transform, so sticky resumes cleanly once
   it lands. Overrides the default reveal-rise above (equal specificity, later
   in source). Hidden start + this whole rule are gated on .js + no-preference,
   so the deck stays put and visible without JS or under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .js .work__deck.is-revealed {
    animation: deck-pop-in 0.85s cubic-bezier(0.16, 1, 0.3, 1) backwards;
  }
}

@keyframes deck-pop-in {
  from { opacity: 0; transform: translateY(140px); }
  to   { opacity: 1; transform: translateY(0); }
}

.proc-card__ico {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: rgba(212, 255, 58, 0.35);
  color: var(--ink-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 6px;
}

.proc-card__num {
  font-family: var(--mono, ui-monospace, SFMono-Regular, monospace);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: #2ea974;
  font-weight: 700;
  text-transform: uppercase;
}

.proc-card h4 {
  font-size: 19px;
  font-weight: 700;
  margin: 2px 0 4px;
  letter-spacing: -0.01em;
  color: var(--ink-dark);
}

.proc-card p {
  font-size: 14.5px;
  color: #4a4f5c;
  line-height: 1.55;
  margin: 0;
}

@media (max-width: 820px) {
  .proc-cards { grid-template-columns: 1fr; }
}

.stat__num {
  font-size: 64px;
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
}

.stat__num span {
  color: var(--green-2);
}

.stat__lbl {
  font-size: 14px;
  color: #4a4f5c;
  margin-top: 6px;
}

.rooted__cta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.circle-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid rgba(0, 0, 0, 0.18);
  background: transparent;
  font-size: 18px;
  cursor: pointer;
  color: inherit;
  user-select: none;
  -webkit-user-select: none;
  transition: background 0.15s, border-color 0.15s;
}

.circle-btn:hover {
  background: rgba(0, 0, 0, 0.05);
}

.picks__nav .circle-btn,
.reviews .circle-btn {
  border-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}

.picks__nav .circle-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* ============ JOURNEY ============ */
.journey {
  background: var(--bg);
  padding: 100px 0;
}

.eyebrow {
  text-align: center;
  color: var(--yellow);
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 12px;
  font-weight: 600;
  margin: 0 0 12px;
}

.journey__title {
  text-align: center;
  font-size: clamp(36px, 4.2vw, 60px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.2em;
  margin: 0 0 10px;
}

.journey__sub {
  text-align: center;
  color: var(--ink-mute);
  margin: 0 0 40px;
}

.journey__tabs {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 6px;
  background: var(--card);
  border-radius: 999px;
  max-width: 920px;
  margin: 0 auto 40px;
}

.tab {
  background: transparent;
  color: var(--ink-mute);
  border: 0;
  padding: 10px 20px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
  font-family: inherit;
}

.tab.is-active {
  background: var(--yellow);
  color: var(--ink-dark);
}

.tab:not(.is-active):hover {
  color: var(--ink);
}

.journey__panes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 50px;
  max-width: 1100px;
  margin: 0 auto;
  align-items: start;
  position: relative;
}

.pane {
  display: none;
  grid-column: span 2;
  grid-template-columns: 1fr 1fr;
  gap: 50px;
}

.pane.is-active {
  display: grid;
}

.pane__card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px;
}

.pane__card h3 {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.3em;
  margin: 0 0 14px;
}

.pane__card p {
  color: var(--ink-mute);
  font-size: 15px;
  line-height: 1.6;
  margin: 0;
}

.pane__list {
  margin: 0;
  padding: 30px 0 0;
  list-style: none;
}

.pane__list li {
  padding: 10px 0 10px 28px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  color: var(--ink);
  position: relative;
}

.pane__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18px;
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: var(--yellow);
}

.pane__list li:last-child {
  border-bottom: 0;
}

/* ============ REVIEWS ============ */
.reviews {
  background: var(--bg);
  padding: 0 0 100px;
}

.reviews .container {
  background: var(--cream);
  color: var(--ink-dark);
  border-radius: 40px;
  padding: 80px 60px;
}

.reviews__title {
  text-align: center;
  font-size: clamp(28px, 3.2vw, 46px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.2em;
  margin: 0 0 56px;
}

.google {
  background: linear-gradient(90deg, #4285F4 0%, #EA4335 30%, #FBBC05 60%, #34A853 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 700;
}

.reviews__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 18px;
}

.review {
  background: #fff;
  border-radius: 18px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 14px;
  color: #2a2f3c;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

.stars {
  color: #f5b800;
  font-size: 16px;
  letter-spacing: 0.05em;
}

.review p {
  margin: 0;
  line-height: 1.5;
  flex: 1;
}

.review footer {
  font-size: 12px;
  color: #6b7180;
  display: flex;
  flex-direction: column;
}

.review footer strong {
  color: var(--ink-dark);
  font-size: 13px;
  margin-bottom: 2px;
}

/* ============ SERVICES ============ */
.services {
  background: var(--bg);
  padding: 50px 0 100px;
  position: relative;
  overflow: hidden;
}

.services__icons {
  display: flex;
  gap: 14px;
  justify-content: center;
  margin: 0 0 24px;
}

.shape {
  display: inline-block;
  width: 16px;
  height: 16px;
}

.shape--tri {
  width: 0;
  height: 0;
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-bottom: 16px solid var(--yellow);
}

.shape--square {
  background: var(--blue);
}

.shape--circle {
  border-radius: 50%;
  background: var(--green);
}

.services__title {
  text-align: center;
  font-size: clamp(38px, 4.2vw, 60px);
  font-weight: 600;
  letter-spacing: -0.04em;
  /* 1.45 (was 1.2): when the lime-highlighted span wraps to two lines on narrow
     screens, the cloned background bands need this much line spacing or they
     overlap. Harmless on desktop where the title is a single line. */
  line-height: 1.45;
  margin: 0 0 70px;
}

.service {
  background: var(--card);
  border-radius: 28px;
  padding: 36px;
  border: 1px solid var(--line);
  display: grid;
  gap: 30px;
  margin-bottom: 22px;
  position: relative;
}

.service--main {
  grid-template-columns: 1fr 1.2fr;
  align-items: center;
}

/* Flipped main card (Software Solutions): illustration on the left, copy on the
   right. Source order stays copy-first (heading before the decorative image) for
   screen readers — only `order` moves the visual — and the wider 1.2fr column
   sits left so the image keeps the same generous size as the Web Design panel. */
.service--flip {
  grid-template-columns: 1.2fr 1fr;
}
.service--flip .service__visual {
  order: -1;
}

.service__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  /* Keep the 22px stacking rhythm below the row so a following full-width card
     (Software Solutions) doesn't butt straight against it. The row's own
     children have margin-bottom:0, so this margin lives on the row itself. */
  margin-bottom: 22px;
}

.service__row .service {
  grid-template-columns: 1fr;
  align-items: stretch;
  margin-bottom: 0;
}

.service__copy h3 {
  font-size: 36px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.3em;
  margin: 0 0 16px;
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.service__copy p {
  color: var(--ink-mute);
  margin: 0 0 24px;
  font-size: 15px;
  line-height: 1.6;
}

/* 'Brand' link (moved out of the nav) as an outlined secondary pill sitting as
   an eyebrow above the Web Design heading. Block-level flex + width:fit-content
   so it breaks onto its own line (the h3 below is inline-flex, so an inline-flex
   pill would sit ON THE SAME LINE as the heading) while still hugging its label.
   The 2px yellow border matches the site's outlined-pill weight and
   yellow-on-navy keeps it high-contrast against the section background. */
.brand-pill {
  margin: 0 0 28px;
  display: flex;
  width: -moz-fit-content;
  width: fit-content;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  color: var(--yellow);
  background: transparent;
  border: 2px solid var(--yellow);
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.brand-pill:hover {
  background: var(--yellow);
  color: var(--ink-dark);
  transform: translateY(-1px);
}

.dot {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
}

.dot--yellow { background: var(--yellow); }
.dot--green { background: var(--green); }
.dot--pink { background: var(--pink); }
.dot--blue { background: var(--blue); }

.service__visual {
  border-radius: 18px;
  aspect-ratio: 16 / 10;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Dark navy fallback behind the illustration. Kept dark (not the old bright
     purple) so the ~1px subpixel seam a hover-scaled cover image can expose at
     an edge reads as the SVG's own navy, not a magenta line. */
  background: linear-gradient(135deg, #243250, #111b33);
  position: relative;
  overflow: hidden;
}

.service--main .service__visual {
  aspect-ratio: 16 / 9;
}

/* Service illustration panels (Social Media / Hosting / Software): the artwork
   gently zooms while the card is hovered — same restraint as the proc-card
   lift. Gated on hover-capable pointers + no-preference so touch devices and
   reduced-motion users never see it; only transform animates (composited, no
   reflow), and .service__visual clips the overflow. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .service__visual .visual__img {
    transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .service:hover .visual__img {
    transform: scale(1.045);
  }
}

/* ---- Web Design panel: live "creative canvas" --------------------------
   An animated composition (glow orbs, a faint grid, a vector pen-curve, a
   type specimen with selection handles, a colour palette, a cursor). The
   whole block is decorative: aria-hidden + user-select:none + pointer-events
   :none, so the "Aa" specimen is never read as page text or selectable.
   The palette auto-cycles (JS in index.astro, gated on reduced-motion) and
   repaints --art-accent across the curve, selection box, handles and glow,
   re-theming the panel on each colour. Under reduced motion the JS bails and
   the global motion reset freezes the transitions, leaving the resting lime
   theme. */
.service__visual--art {
  background: radial-gradient(120% 140% at 80% 8%, #1b2742 0%, #0f1626 55%, #0b1120 100%);
}

/* Registered as <color> so the theme swap interpolates. Inside a gradient /
   color-mix a plain custom property is non-interpolable, so the orbs would
   jump instantly; registered, every var() that reads them re-resolves each
   frame and the whole panel re-themes over one shared duration. */
@property --art-accent { syntax: "<color>"; inherits: true; initial-value: #d4ff3a; }
@property --orb-tr     { syntax: "<color>"; inherits: true; initial-value: #d4ff3a; }
@property --orb-bl     { syntax: "<color>"; inherits: true; initial-value: #ff8aa0; }
@property --art-bg     { syntax: "<color>"; inherits: true; initial-value: #d4ff3a; }

.design-art {
  --art-accent: var(--yellow);          /* line work — curve, box, handles */
  --orb-tr: var(--yellow);              /* top-right glow  (repainted per theme) */
  --orb-bl: var(--pink);                /* bottom-left glow (repainted per theme) */
  --art-bg: var(--yellow);              /* faint panel wash (repainted per theme) */
  /* one timing for the whole re-theme; children read the animating vars.
     Reduced motion never reaches here — the JS cycle is gated, so the vars
     never change and nothing transitions. */
  transition: --art-accent 0.9s ease, --orb-tr 0.9s ease, --orb-bl 0.9s ease,
              --art-bg 0.9s ease;
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* subtle theme wash over the parent navy — brightest at the top-right light
     source, fading out, so it reads as a tint not a fill. */
  background: radial-gradient(135% 135% at 78% 10%,
    color-mix(in srgb, var(--art-bg) 15%, transparent),
    transparent 62%);
  container-type: inline-size;          /* cqw below resolves against the panel */
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}
.design-art::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1.6px);
  background-size: 22px 22px;
}

/* Holds the composition (orbs, pen-curve, type specimen, cursor). On hover it
   scales a touch so the Web Design card pops like the sibling cards' zoom. Only
   the palette sits OUTSIDE this wrapper — the click-to-pick swatches must not
   move. Same 1.045 / timing / gating as .service:hover .visual__img above — off
   for touch and reduced-motion. .design-art clips the overflow. */
.design-art__stage {
  position: absolute;
  inset: 0;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .design-art__stage {
    transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .service--main:hover .design-art__stage {
    transform: scale(1.045);
  }

  /* The specimen rides the zoom's TRANSLATION (it moves with the pop) but keeps
     its own size: 1.045 × 0.9569 ≈ 1, so the dashed marquee + letters travel
     without their weight/size changing. Same timing as the stage so the two
     scales stay cancelled through the whole transition, not just at the ends. */
  .design-art__type {
    transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .service--main:hover .design-art__type {
    transform: scale(0.9569);
  }
}
.design-art__orb {
  position: absolute;
  width: 42%;
  aspect-ratio: 1;
  top: -12%;
  right: -6%;
  border-radius: 50%;
  filter: blur(10px);
  background: radial-gradient(circle at 40% 40%,
    color-mix(in srgb, var(--orb-tr) 50%, transparent),
    transparent 68%);
}
.design-art__orb--2 {
  top: auto;
  right: auto;
  bottom: -16%;
  left: -8%;
  width: 38%;
  /* bottom-left glow — its own per-theme colour (see swatch data-orb-bl) */
  background: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--orb-bl) 42%, transparent),
    transparent 70%);
}
.design-art__curve {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.design-art__curve path {
  fill: none;
  stroke: var(--art-accent);
  /* non-scaling-stroke: the SVG uses preserveAspectRatio="none", so the panel
     stretches the curve anisotropically and the stroke's edges alias (pixely).
     This pins the pen to a uniform device-pixel width, immune to that stretch,
     so the line stays crisp at any panel size. 4 reads as a clean, bolder line. */
  stroke-width: 4;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
}
.design-art__node {
  fill: #0b1120;
  stroke: var(--art-accent);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;   /* same crisp stroke as the curve */
}
.design-art__type {
  position: absolute;
  left: 8%;
  top: 20%;
  padding: 3cqw;
  border: 1.5px dashed color-mix(in srgb, var(--art-accent) 85%, transparent);
  border-radius: 3px;
}
.design-art__aa {
  display: block;
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 22cqw;
  line-height: 0.82;
  letter-spacing: -0.03em;
  color: var(--cream);
  margin-top: -6px;                     /* nudge glyphs up in the tight line box */
}
.design-art__handle {
  position: absolute;
  width: 9px;
  height: 9px;
  background: var(--ink-dark);
  border: 1.5px solid var(--art-accent);
  border-radius: 2px;
}
.design-art__handle--tl { top: -5px; left: -5px; }
.design-art__handle--tr { top: -5px; right: -5px; }
.design-art__handle--bl { bottom: -5px; left: -5px; }
.design-art__handle--br { bottom: -5px; right: -5px; }
.design-art__palette {
  position: absolute;
  right: 6%;
  bottom: 9%;
  display: flex;
  gap: 1.6cqw;
  padding: 1.6cqw 2.2cqw;
  border-radius: 999px;
  background: rgba(11, 17, 32, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.design-art__swatch {
  width: 4.5cqw;
  height: 4.5cqw;
  min-width: 14px;
  min-height: 14px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
  /* Click-to-pick. The panel is decorative (aria-hidden + pointer-events:none),
     so this is a pointer-only affordance — no tab stops are added, and no
     functionality is keyboard-gated because the palette also auto-cycles. */
  pointer-events: auto;
  cursor: pointer;
}
@media (hover: hover) {
  .design-art__swatch:hover { transform: scale(1.12); }
}
.design-art__swatch--y { background: var(--yellow); }
.design-art__swatch--p { background: var(--pink); }
.design-art__swatch--b { background: var(--blue); }
.design-art__swatch--c { background: var(--cream); }
/* the chosen colour: lifts and gains an accent ring, as if just clicked */
.design-art__swatch.is-active {
  transform: scale(1.12);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25),
              0 0 0 1.5px rgba(11, 17, 32, 0.9),
              0 0 0 3px var(--art-accent);
}
.design-art__cursor {
  position: absolute;
  left: 45%;
  top: 56%;
  width: 24px;
  height: 24px;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45));
}
.design-art__cursor path {
  fill: #fff;
  stroke: #0b1120;
  stroke-width: 1.2;
  stroke-linejoin: round;
}

/* ============ FAQs ============ */
.faqs {
  background: var(--bg);
  padding: 100px 0;
}

.faqs__title {
  font-size: clamp(40px, 4.2vw, 60px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.2em;
  margin: 0 0 40px;
}

/* Always-visible price answer above the FAQ accordion — surfaces the figure
   that otherwise sits inside the collapsed "How much does it cost?" item. Pulls
   up under the title; public-safe floor only (from £59/mo / £800, ex VAT). */
.faq-price {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin: -20px 0 36px;
  padding: 16px 20px;
  border-radius: 16px;
  background: rgba(212, 255, 58, 0.06);
  border: 1px solid rgba(212, 255, 58, 0.22);
}
.faq-price__badge {
  flex: 0 0 auto;
  align-self: flex-start;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-dark);
  background: var(--yellow);
  /* Uppercase caps sit optically high in the pill; weight the padding slightly
     to the top so the text drops to visual centre (same total height). */
  padding: 5px 11px 4px;
  border-radius: 999px;
}
.faq-price__text {
  flex: 1 1 320px;
  margin: 0;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
}
.faq-price__text strong {
  color: var(--yellow);
  font-weight: 700;
  white-space: nowrap;
}

.faq-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--line);
}

.faq {
  border-bottom: 1px solid var(--line);
}

.faq__q {
  width: 100%;
  background: transparent;
  border: 0;
  color: var(--ink);
  text-align: left;
  font-size: 17px;
  font-weight: 500;
  padding: 24px 0;
  display: flex;
  align-items: center;
  gap: 22px;
  cursor: pointer;
  font-family: inherit;
}

.faq__icon {
  font-size: 24px;
  color: var(--green);
  font-weight: 300;
  transition: transform 0.2s;
  width: 18px;
  display: inline-block;
}

.faq.is-open .faq__icon {
  transform: rotate(45deg);
}

.faq__a {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.faq.is-open .faq__a {
  max-height: 400px;
}

.faq__a p {
  margin: 0 0 24px 40px;
  color: var(--ink-mute);
  font-size: 15px;
  line-height: 1.6;
  max-width: 800px;
}

.faq__a a {
  color: var(--yellow);
  text-decoration: underline;
}

/* ============ PICKS ============ */
.picks {
  background: var(--bg);
  padding: 30px 0 100px;
}

.picks__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 36px;
  flex-wrap: wrap;
  gap: 16px;
}

.picks__head h2 {
  font-size: clamp(28px, 3.2vw, 44px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.2em;
  margin: 0;
}

.picks__nav {
  display: flex;
  align-items: center;
  gap: 10px;
}

.picks__scroller {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  padding: 0 28px 4px;
  max-width: var(--container);
  margin: 0 auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* Native scrollbar hidden — replaced by the custom .picks__track slider below. */
.picks__scroller::-webkit-scrollbar {
  display: none;
}

.picks__track-wrap {
  max-width: var(--container);
  margin: 16px auto 0;
  padding: 0 28px;
}

.picks__track {
  position: relative;
  height: 5px;
  background: rgba(255, 255, 255, 0.10);
  border-radius: 999px;
  cursor: pointer;
}

.picks__thumb {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 30%;
  background: var(--yellow);
  border-radius: 999px;
  cursor: grab;
  touch-action: none;
}

.picks__thumb:active {
  cursor: grabbing;
}

.pick {
  flex: 0 0 260px;
  background: var(--card);
  border-radius: 18px;
  padding: 16px;
  scroll-snap-align: start;
  border: 1px solid var(--line);
}

.pick__visual {
  border-radius: 12px;
  height: 160px;
  position: relative;
  margin-bottom: 14px;
  overflow: hidden;
  padding: 12px;
  display: flex;
  flex-direction: column;
}

.pick__visual--yellow {
  background:
    radial-gradient(circle at 70% 80%, rgba(0, 0, 0, 0.1), transparent 50%),
    var(--yellow);
  color: var(--ink-dark);
}

.pick__visual--green {
  background: linear-gradient(135deg, #b4ff7f, #5dd49a);
  color: var(--ink-dark);
}

.pick__visual--photo-a { background: linear-gradient(135deg, #5d4f3c, #2c2418); }
.pick__visual--photo-b { background: linear-gradient(135deg, #3a3a3a, #5e2a2a); }

.pick__tag {
  display: inline-block;
  background: rgba(0, 0, 0, 0.12);
  color: inherit;
  font-size: 11px;
  padding: 4px 9px;
  border-radius: 999px;
  font-weight: 600;
  align-self: flex-start;
  width: fit-content;
}

.pick__visual--photo-a .pick__tag,
.pick__visual--photo-b .pick__tag {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.pick__time {
  font-size: 11px;
  margin-top: auto;
  align-self: flex-start;
  font-weight: 600;
  background: rgba(0, 0, 0, 0.12);
  padding: 4px 9px;
  border-radius: 999px;
}

.pick__visual--photo-a .pick__time,
.pick__visual--photo-b .pick__time {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.pick__title-lg {
  font-family: var(--font-serif);
  font-size: 34px;
  position: absolute;
  right: 14px;
  bottom: 14px;
  line-height: 1;
  text-align: right;
  font-weight: 400;
}

.pick h3 {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  margin: 4px 4px 8px;
  letter-spacing: -0.005em;
}

/* ============ CONTACT ============ */
.contact {
  background: var(--bg);
  padding: 60px 0 100px;
}

.contact__grid {
  display: grid;
  grid-template-columns: 340px auto;
  gap: 36px;
  /* Hug the content (still centred by the shared .container margins) so the card
     is only as wide as the CTA + the current wizard step. Everything past its
     right edge is plain section background, not card. The panel grows/shrinks as
     the wizard steps change width — the script tweens the form, the auto column
     and this card follow. */
  width: fit-content;
  background: var(--card);
  border-radius: 28px;
  padding: 30px;
  border: 1px solid var(--line);
}

.contact__cta {
  position: relative;
  background: var(--yellow);
  border-radius: var(--radius);
  padding: 34px;
  color: var(--ink-dark);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  /* A floor so the CTA still reads as a substantial card, but low enough that a
     short step (step 1) no longer forces a tall empty form beside it. It grows
     to match the form on the taller steps. */
  min-height: 300px;
}

.contact__logo {
  display: block;
  font-weight: 800;
  font-size: 26px;
  letter-spacing: -0.02em;
  color: var(--ink-dark);
}

.contact__logo .logo__dot {
  color: var(--ink-dark);
}

.contact__cta h2 {
  font-size: clamp(40px, 4vw, 52px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.08;
  margin: 0;
}

.contact__cta-foot {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
}

.contact__methods {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.contact__method-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dark);
  opacity: 0.65;
  margin-bottom: 2px;
}

.contact__methods a {
  color: var(--ink-dark);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s;
}

.contact__methods a:hover {
  border-bottom-color: var(--ink-dark);
}

.contact__badge {
  flex: 0 0 auto;
  user-select: none;
  -webkit-user-select: none;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--ink-dark);
  color: var(--yellow);
  display: grid;
  place-items: center;
  font-size: 24px;
  line-height: 1;
  transition: transform 0.2s ease;
}

.contact__cta:hover .contact__badge {
  transform: translate(3px, -3px);
}

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

.contact__form {
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}

.contact__form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--ink-mute);
}

.contact__form input,
.contact__form select,
.contact__form textarea {
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  padding: 8px 0 10px;
  color: var(--ink);
  font-size: 15px;
  font-family: inherit;
  transition: border-color 0.15s;
}

.contact__form input:focus,
.contact__form select:focus,
.contact__form textarea:focus {
  /* The underline going yellow IS the focus indicator for these fields, so the
     global :focus-visible ring (styles.css ~693) is redundant here and reads as
     an unexpected box when you click in. Suppress it on :focus directly — a text
     field reports :focus-visible even on mouse click, so the old
     :not(:focus-visible) override never actually caught the click case. Keyboard
     focus still shows the yellow underline, so this stays WCAG 2.4.7 AA. */
  border-bottom-color: var(--yellow);
  outline: none;
  box-shadow: none;   /* the :focus-visible rule also adds a dark halo box-shadow — kill it too */
}

/* Autofill: Chromium/Safari paint a pale background + dark text on autofilled
   fields, which flashes a white box on the dark card. The background paint can't
   be set directly, so hold it off with a ~forever background-color transition
   (keeps the field transparent) and force the light text/caret to match --ink.
   Underline border is preserved by the base rule. */
.contact__form input:-webkit-autofill,
.contact__form input:-webkit-autofill:hover,
.contact__form input:-webkit-autofill:focus,
.contact__form input:-webkit-autofill:active,
.contact__form input:autofill {
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  -webkit-background-clip: text;   /* clip the pale fill to the glyphs, not the box */
  transition: background-color 6000s ease-in-out 0s, border-color 0.15s;
}

/* Honeypot: kept in the layout but off-screen and out of the tab/AT order.
   Visually hidden (not display:none) so bots still find and fill it. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Submit-status live region. Inherits the panel's light --ink so it stays
   legible on the dark card; error/success are conveyed by an icon + wording in
   the message text, never by colour alone. */
.contact__status {
  margin: 0;
  font-size: 14px;
  color: var(--ink);
}
.contact__status:empty {
  display: none;
}

/* Per-field required asterisk. Yellow so it reads as an accent, but the required
   state is also conveyed by the `required`/aria-required attrs and the inline
   error text, never by the asterisk colour alone. */
.req {
  color: var(--yellow);
  font-weight: 700;
  /* An asterisk at the 13px label size sits high and small, reading like a stray
     dot. Enlarge it and drop it onto the text line so it clearly looks like `*`. */
  font-size: 1.2em;
  line-height: 1;
  vertical-align: -0.2em;
}

/* Inline field error. Error is signalled by the ⚠ icon + wording as well as
   colour; the warm text sits ~7.8:1 on the --card panel, comfortably AA. */
.field-error {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 13px;
  color: #ff9c8a;
}
.field-error::before {
  content: '⚠';
  font-size: 13px;
  line-height: 1;
}
.field-error[hidden] {
  display: none;
}

/* Invalid field: the underline turns to match the error text (not the yellow
   focus colour), so an errored field stays distinct even while focused. */
.contact__form input.is-invalid {
  border-bottom-color: #ff9c8a;
}

/* A focused invalid field shows the yellow focus underline — the same focus
   indicator as any other field — rather than a box ring. That keeps a visible
   keyboard focus indicator (WCAG 2.4.7) without the outline the previous rule
   drew. The error stays conveyed by the inline ⚠ message + aria-invalid while
   focused, and the pink error underline returns the moment focus leaves. */
.contact__form input.is-invalid:focus,
.contact__form input.is-invalid:focus-visible {
  outline: none;
  border-bottom-color: var(--yellow);
}

.contact__done h3 {
  margin: 0 0 8px;
}
.contact__done p {
  margin: 0;
  color: var(--ink-mute);
}

/* On submit the form is swapped for this confirmation. Author display:flex on
   .contact__form otherwise beats the [hidden] attribute, so force the hide; and
   pin the confirmation into the form's grid cell so the card + lime panel keep
   the same height they had at submit (no resize jump). */
.contact__form[hidden] { display: none; }
.contact__done { grid-column: 2; }
.contact__done:not([hidden]) {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}

.btn:disabled,
.btn[aria-busy='true'] {
  opacity: 0.6;
  cursor: progress;
}

fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

fieldset legend {
  font-size: 13px;
  color: var(--ink-mute);
  margin-bottom: 14px;
}

/* Reassurance note under the service pills — a friendly aside, NOT a selectable
   option, so it's visually distinct (tinted callout + badge, no pill border). */
.service-hint {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 16px 0 0;
  padding: 11px 14px;
  border-radius: 14px;
  background: rgba(212, 255, 58, 0.06);
  border: 1px solid rgba(212, 255, 58, 0.18);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-mute);
}

.service-hint strong {
  color: var(--yellow);
  font-weight: 600;
}

.service-hint > span:last-child {
  margin-top: 2px;
}

.service-hint__icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--yellow);
  color: var(--ink-dark);
  font-weight: 800;
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.radios {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

.service-other-detail {
  margin-top: 14px;
}
.service-other-detail[hidden] {
  display: none;
}

/* Enhanced path: animate the reveal by tweening height (and its margin) so the
   card — and the CTA beside it, which stretches to the card height — grows
   smoothly instead of snapping taller and shoving "Let's chat" down. Gated on
   .is-ready; the script drives .is-collapsed instead of the [hidden] attribute
   so the box stays in the layout and can tween. */
.contact__wizard.is-ready .service-other-detail {
  /* Keep the label's column layout (label above input) — a bare `display: block`
     here dropped the flex layout, so the "Tell us more" label and its input
     collapsed onto one line at their two different sizes. */
  display: flex;
  flex-direction: column;
  overflow: clip;
  height: auto;
  opacity: 1;
  transition:
    height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    margin-top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.25s ease;
}
.contact__wizard.is-ready .service-other-detail.is-collapsed {
  height: 0;
  margin-top: 0;
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .contact__wizard.is-ready .service-other-detail {
    transition: none;
  }
}

.radio {
  display: inline-flex;
  position: relative;   /* contains the visually-hidden input below */
  align-items: center;
  gap: 8px;
  background: transparent;
  /* 2px (not 1px): a hairline curved border at fractional display scaling
     (e.g. Windows 125%) can't align to the pixel grid, so the pill's rounded
     ends stair-step / look pixely. A thicker stroke has more coverage to
     anti-alias the curve across, so it reads smooth. Width lives here (not on
     the :checked rule) so ticking only swaps colour — no 1px layout shift. */
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  padding: 10px 16px;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink);
  transition: border-color 0.15s, background 0.15s;
}

.radio:has(input:checked) {
  border-color: var(--yellow);
  background: rgba(222, 252, 58, 0.06);
}

.radio input {
  /* Visually hidden but still focusable and in the accessibility tree — was
     display:none, which dropped the checkbox from the tab order and screen
     readers, so keyboard users couldn't pick a service. The pill reflects state
     via :has(:checked) and draws its focus ring via :has(:focus-visible) below. */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.radio:has(input:focus-visible) {
  outline: 2px solid var(--yellow);
  outline-offset: 2px;
}

.radio__shape {
  display: inline-block;
}

.shape--tri-sm {
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 10px solid var(--yellow);
}

.shape--square-sm {
  width: 10px;
  height: 10px;
  background: var(--blue);
}

.shape--circle-sm {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--green);
}

.checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--ink-mute);
  cursor: pointer;
}

.checkbox input {
  width: 16px;
  height: 16px;
  accent-color: var(--yellow);
}

.contact__form .btn {
  align-self: flex-start;
}

/* ---- Contact wizard (stepped ContactCard) --------------------------------
   Each question is its own card in the form column. Without JS every step shows
   (a plain long form) and the wizard chrome is hidden; the `.js` rules below
   collapse it to one step at a time (`.js` is set in <head> before paint, so no
   flash). The step transition + entrance slide are gated on no-preference, so
   reduced-motion users get instant swaps. */

.wizard__head {
  display: none;                 /* JS-off: no step chrome */
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.wizard__count {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.wizard__dots {
  display: flex;
  gap: 8px;
}

.wizard__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.2s ease;
}

.wizard__dot.is-active {
  background: var(--yellow);
}

/* A step is a card floating in the form column. display:flex here (not the UA
   default) intentionally beats the [hidden] attribute on later steps — the same
   author-display-vs-[hidden] trick used by .contact__form[hidden] above — so
   without JS all steps are visible and the single Submit posts the whole form.
   The `.js` rules below re-hide them and show one at a time. */
.contact-step {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 24px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.04);
}

.contact-step:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 3px;
}

.contact-step__q {
  margin: 0;
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
}

.contact-step__lead {
  margin: -8px 0 0;
  font-size: 14px;
  color: var(--ink-mute);
  /* Wrap long lead lines rather than letting them stretch the (content-hugging)
     card to one wide line — the card width should come from the fields. */
  max-width: 340px;
}

/* A lone short field (the name step) — cap the width so it doesn't stretch the
   whole column; shrinks to fit on narrow screens. */
.field-narrow {
  max-width: 340px;
}

/* Step 1/2 field labels read at the service-tile weight and brightness (500,
   full ink) rather than the muted 400 default, so "Your name / Email address /
   Phone number" match the "Something else" tile. */
.contact__wizard .field-narrow > span:first-child,
.contact__wizard .row--or label > span:first-child {
  font-weight: 500;
  color: var(--ink);
}

/* Wrapper around the steps (a plain grouping element; the sizing tween lives on
   the form itself, below). */
.wizard__steps {
  position: relative;
}

/* 2 -> 3 forward: the new step drops down — the box grows taller and clips the
   not-yet-revealed lower part, so the step unfolds downward (panel + CTA follow
   the animating height set by the script). No sideways motion. */
.wizard__steps.is-dropping {
  overflow: hidden;
}

.wizard__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 4px;
}

.wizard__actions .btn {
  align-self: flex-start;
}

/* JS-off nav buttons need the script to do anything — hide them so only the
   final Submit shows. */
.contact-step [data-next],
.contact-step [data-back] {
  display: none;
}

/* --- Enhanced path: one step at a time + wizard chrome --------------------
   Gated on `.is-ready`, which contactWizard() adds to the form only after it has
   wired everything up — NOT on the head-set `.js`. So if the script is present
   but never runs (blocked, CSP, an earlier IIFE throws), the form stays the full
   usable long form + Submit instead of collapsing to a dead single step.
   script.js is a render-blocking end-of-body include, so `.is-ready` lands
   before first paint — no flash of all the steps. */
.contact__wizard.is-ready {
  /* The form just fills its grid column. On step 1 that column is `auto`, so the
     panel hugs the content; from step 2 the panel is .is-wide (column 1fr) and
     the form spreads across it. The panel is what grows — tweened by the script. */
  align-self: start;
  justify-self: stretch;
  width: 100%;
}

/* Step 2 onwards: the panel expands to the full container width and the form
   column becomes 1fr, so step 1 -> 2 grows horizontally into the section
   background (the panel stays centred by the shared .container margins) and
   2 -> 3 only grows taller. */
.contact__grid.is-wide {
  grid-template-columns: 340px 1fr;
  width: 100%;
}

.contact__grid.is-animating {
  overflow: hidden;   /* clip the reflow + slide only while the panel tweens */
}

/* While the panel is pinned shorter than the incoming (taller) step, its columns
   overflow it. A grid child taller than the mid-transition container height gets
   mis-placed *above* the panel's top edge (a Blink quirk while `height` is
   animating), so the CTA card and its "scoritz." heading jumped up into the
   margin above on 2 -> 3, then dropped back as the panel grew. Capping each
   column to the panel's current height (and clipping the excess) keeps them no
   taller than the container, so they stay top-anchored and only clip at the
   bottom. The columns still stretch to the panel's height (grid default), so the
   CTA card grows and shrinks in step with the panel both ways. Scoped to
   `.is-animating`, so columns revert to natural full height the moment the tween
   ends. */
.contact__grid.is-animating > * {
  max-height: 100%;
  overflow: hidden;
}

@media (prefers-reduced-motion: no-preference) {
  .contact__grid {
    /* Smooth ease-in-out (not a fast-out ease) so the big vertical growth on
       2 -> 3 eases in rather than snapping open — the fast-out curve read as a
       jumpy "drop". Matches the step-entrance easing below so the content and
       the panel grow in sync. Both axes share one duration so the JS
       transitionend cleanup can't fire early on the shorter one and snap the
       other. */
    transition:
      width 0.4s cubic-bezier(0.4, 0, 0.2, 1),
      height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  }
}

/* On mobile the grid is a single column — the panel fills the width on every
   step (see the .contact__grid override in the max-width:1024px block), so the
   form just stretches as usual. */
@media (max-width: 1024px) {
  .contact__wizard.is-ready {
    width: auto;
    justify-self: stretch;
  }
}

.contact__wizard.is-ready .wizard__head {
  display: flex;
}

.contact__wizard.is-ready .contact-step [data-next],
.contact__wizard.is-ready .contact-step [data-back] {
  display: inline-flex;
}

.contact__wizard.is-ready .contact-step {
  display: none;
}

.contact__wizard.is-ready .contact-step.is-active {
  display: flex;
}

/* Not enhanced (no JS / script didn't run): reveal the "Other" detail field,
   which otherwise only un-hides via the script, so it can be filled in the plain
   long-form fallback. */
.contact__wizard:not(.is-ready) .service-other-detail[hidden] {
  display: flex;
}

/* Entrance drop when a step is navigated to: a short vertical rise + fade that
   matches the page's reveal-rise, so the step no longer swipes in sideways. Not
   applied on first paint (the section reveal owns that); the script only adds
   .is-entering on nav. Forward and --back use the same vertical motion. */
@media (prefers-reduced-motion: no-preference) {
  /* `backwards` fill applies the from-state (opacity:0) the instant the class
     lands, so the step never paints at full opacity for a frame before the
     fade-in starts. */
  .contact__wizard.is-ready .contact-step.is-active.is-entering {
    animation: wizardStepIn 0.4s cubic-bezier(0.4, 0, 0.2, 1) backwards;
  }
  .contact__wizard.is-ready .contact-step.is-active.is-entering--back {
    animation: wizardStepInBack 0.4s cubic-bezier(0.4, 0, 0.2, 1) backwards;
  }
}

@keyframes wizardStepIn {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes wizardStepInBack {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Step 2 — email / or / phone. Three columns on desktop with a centred "or"
   between; collapses to one column on mobile via the shared `.row` rule below,
   where the "or" simply stacks between the two fields. */
.row--or {
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
}

.or-divider {
  padding-bottom: 9px;   /* drop the word onto the input line, not the label */
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: center;
}

/* Step 3 — service picker. Selectable tiles (icon + label + tick) that read as
   cards; the visually-hidden checkbox stays keyboard-focusable and the tile
   shows its state via :has(:checked)/:has(:focus-visible). */
.service-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.service-tile {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 2px solid rgba(255, 255, 255, 0.14);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.02);
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.service-tile--wide {
  grid-column: 1 / -1;   /* "Something else" spans the full row */
}

.service-tile:hover {
  border-color: rgba(255, 255, 255, 0.34);
  transform: translateY(-1px);
}

.service-tile input {
  /* Visually hidden but focusable + in the a11y tree (see .radio input above). */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.service-tile:has(input:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.service-tile:has(input:checked) {
  border-color: var(--yellow);
  background: rgba(222, 252, 58, 0.08);
}

.service-tile__icon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  transition: color 0.15s ease;
}

.service-tile:has(input:checked) .service-tile__icon {
  color: var(--yellow);
}

.service-tile__icon svg {
  width: 100%;
  height: 100%;
}

.service-tile__label {
  flex: 1 1 auto;
  line-height: 1.2;
}

/* Empty ring by default (clearly toggleable), fills yellow with a check when on. */
.service-tile__tick {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.22);
  color: var(--ink-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.service-tile__tick svg {
  width: 12px;
  height: 12px;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.service-tile:has(input:checked) .service-tile__tick {
  background: var(--yellow);
  border-color: var(--yellow);
}

.service-tile:has(input:checked) .service-tile__tick svg {
  opacity: 1;
}

@media (max-width: 480px) {
  .service-grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .service-tile { transition: none; }
  .service-tile:hover { transform: none; }
}

/* ============ FOOTER ============ */
.footer {
  background: var(--bg);
  padding: 60px 0 0;
  border-top: 1px solid var(--line);
  position: relative;
  overflow: hidden;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 40px;
  margin-bottom: 60px;
}

.footer h4 {
  font-size: 13px;
  letter-spacing: 0.18em;
  color: var(--yellow);
  text-transform: uppercase;
  margin: 0 0 18px;
  font-weight: 600;
}

.footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer li {
  padding: 6px 0;
}

.footer a {
  color: var(--ink-mute);
  font-size: 14px;
  transition: color 0.15s;
}

.footer a:hover {
  color: var(--ink);
}

.footer__shapes {
  display: flex;
  gap: 10px;
  margin-bottom: 22px;
}

.footer__phone {
  font-weight: 700;
  font-size: 18px;
  margin: 0 0 14px;
}

.footer__addr {
  color: var(--ink-mute);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 20px;
}

.footer__copy {
  color: var(--ink-dim);
  font-size: 13px;
}

.footer__strap {
  padding: 22px 28px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-mute);
  max-width: var(--container);
  margin: 0 auto;
}

.footer__strap strong {
  color: var(--yellow);
  font-weight: 600;
}

.footer__legal {
  max-width: var(--container);
  margin: 0 auto;
  padding: 16px 28px 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--ink-mute);
}

.footer__legal p {
  margin: 0;
}

.footer__wordmark {
  /* "scoritz." renders 3.29× the font-size wide in Golos Text 800 (measured). The
     footer clips overflow, so the floor must scale with the viewport or the word
     gets cut off on phones — 27vw keeps it ~89% of the screen width down to the
     smallest phones (the 64px floor only engages below ~237px, narrower than any
     phone). Cap unchanged at 280px, so desktop is identical. */
  font-size: clamp(64px, 27vw, 280px);
  font-weight: 800;
  letter-spacing: -0.05em;
  text-align: center;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.04);
  line-height: 0.9;
  margin-top: 30px;
  user-select: none;
  pointer-events: none;
}

/* ============ RESPONSIVE ============ */
@media (max-width: 1024px) {
  .work__grid { grid-template-columns: repeat(2, 1fr); }
  .card--lg { grid-column: span 2; }
  .reviews__grid { grid-template-columns: repeat(2, 1fr); }
  .rooted__grid { grid-template-columns: 1fr; }
  .service--main { grid-template-columns: 1fr; }
  .service--flip .service__visual { order: 0; }
  .service__row { grid-template-columns: 1fr; }
  .contact__grid,
  .contact__grid.is-wide { grid-template-columns: 1fr; width: auto; }
  .contact__done { grid-column: auto; }
  .pane.is-active { grid-template-columns: 1fr; }
  .mosaic__grid { grid-template-columns: repeat(4, 1fr); }
  .mosaic { height: 560px; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 720px) {
  .nav__links { display: none; }
  .nav__toggle { display: inline-block; }
  .nav__inner > .btn { display: none; }
  .nav.is-open .nav__links {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    background: var(--bg);
    padding: 20px 28px;
    border-bottom: 1px solid var(--line);
    gap: 14px;
  }

  .pill { display: none; }
  .pill--yellow, .pill--blue { display: inline-flex; }
  .pill--yellow { top: 0; right: 4%; }
  .pill--blue { top: 0; left: 4%; }

  .hero { padding-top: 80px; }
  .hero__title { font-size: 44px; }

  .mosaic { height: 280px; }
  .mosaic__grid { grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 0 14px; }
  .thumb:nth-child(n+10) { display: none; }

  .work__grid { grid-template-columns: 1fr; }
  .card--lg { grid-column: span 1; }
  .reviews__grid { grid-template-columns: 1fr; }
  .reviews .container { padding: 50px 28px; }
  .rooted__panel { padding: 60px 0; }

  .footer__grid { grid-template-columns: 1fr; }
  .row { grid-template-columns: 1fr; }

  .journey__tabs { font-size: 12px; }
  .tab { padding: 8px 12px; font-size: 12px; }
}

/* ============ COMPARE ============ */
.compare {
  background: var(--bg);
  padding: 0 0 80px;
}
.compare__panel {
  background: var(--cream);
  color: var(--ink-dark);
  /* Light-mode token overrides so the comparison table reads on the cream panel
     (the .cmp rules were authored against the dark theme's white tokens). */
  --ink: var(--ink-dark);
  --ink-mute: rgba(14, 20, 34, 0.6);
  --ink-dim: rgba(14, 20, 34, 0.45);
  --line: rgba(14, 20, 34, 0.12);
  border-radius: 40px;
  padding: 90px 0 90px;
  position: relative;
}
.compare .container {
  text-align: center;
}
.compare__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #2ea974;
  margin-bottom: 18px;
}
.compare__title {
  font-size: clamp(34px, 4vw, 56px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-bottom: 18px;
  color: var(--ink-dark);
}
.compare__title em {
  font-style: normal;
  background-image: linear-gradient(
    90deg,
    transparent 0.4%,
    rgba(212, 255, 58, 0.85) 0.8%,
    rgba(212, 255, 58, 0.85) 99.2%,
    transparent 99.6%
  );
  background-repeat: no-repeat;
  background-size: 102% 93%;
  background-position: -1% 100%;
  padding: 0.01em 0.18em 0.12em;
  color: var(--ink-dark);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.compare__lede {
  max-width: 720px;
  margin: 0 auto 56px;
  color: rgba(14, 20, 34, 0.65);
  font-size: 18px;
  line-height: 1.6;
}

.cmp {
  position: relative;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: #fff;
  color: var(--ink-dark);
  text-align: left;
  max-width: 1100px;
  margin: 0 auto;
  box-shadow: 0 18px 50px rgba(14, 20, 34, 0.18);
}
.cmp__hd {
  padding: 28px 22px 22px;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cmp__hd > span {
  font-weight: 700;
  font-size: 16px;
  color: var(--ink);
}
.cmp__hd small {
  color: var(--ink-dim);
  font-size: 12px;
  letter-spacing: 0.04em;
}
.cmp__hd--rl > span {
  color: var(--ink-dim);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.cmp__hd--sc {
  background: rgba(212, 255, 58, 0.2);
}
.cmp__hd--sc > span {
  color: var(--ink-dark);
}
.cmp__rl {
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  font-weight: 500;
  font-size: 15px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.015);
  display: flex;
  align-items: center;
}
.cmp__c {
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--ink-mute);
}
.cmp__c--sc {
  background: rgba(212, 255, 58, 0.2);
}
.cmp__c--sc .cmp__ct {
  color: var(--ink);
}
.cmp__m {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  flex-shrink: 0;
}
.cmp__m--yes {
  background: var(--yellow);
  color: var(--ink-dark);
}
.cmp__m--no {
  background: rgba(210, 74, 99, 0.14);
  color: #cf4a63;
}
.cmp__m--mid {
  background: rgba(14, 20, 34, 0.06);
  color: var(--ink-mute);
}
.cmp__ct {
  font-weight: 500;
}

/* ---- OLD mobile comparison layout — kept for quick revert. To restore: delete
   the "Tidied" block below and uncomment this one. (Inner comments stripped so
   this whole block can be commented out without nesting.) ----
@media (max-width: 820px) {
  .compare { padding: 0 0 60px; }
  .compare__panel { padding: 60px 0; border-radius: 28px; }
  .cmp {
    grid-template-columns: repeat(3, 1fr);
    font-size: 13px;
  }
  .cmp > * { min-width: 0; }
  .cmp__hd--rl { display: none; }
  .cmp__rl, .cmp__c, .cmp__hd { padding: 14px 10px; }
  .cmp__hd { align-items: center; text-align: center; }
  .cmp__hd > span { font-size: 13px; }
  .cmp__hd small { font-size: 10px; }
  .cmp__rl { font-size: 13px; grid-column: 1 / -1; }
  .cmp__c { flex-direction: column; align-items: center; text-align: center; gap: 6px; }
}
---- end OLD ---- */

/* ---- Tidied mobile comparison layout ----
   Each criterion is a full-width band; its three options sit in clean, divided
   columns beneath it. Header subtitles drop and the Scoritz column keeps its lime
   tint throughout, so the right-hand "us" column is always easy to find. */
@media (max-width: 820px) {
  .compare { padding: 0 0 60px; }
  .compare__panel { padding: 60px 0; border-radius: 28px; }

  .cmp {
    grid-template-columns: repeat(3, 1fr);
    font-size: 13px;
  }
  .cmp > * { min-width: 0; }

  /* drop the redundant top-left "How they compare" cell */
  .cmp__hd--rl { display: none; }

  /* option headers: compact + centred, subtitle hidden to declutter */
  .cmp__hd {
    padding: 16px 8px;
    gap: 0;
    align-items: center;
    text-align: center;
  }
  .cmp__hd > span { font-size: 13px; line-height: 1.25; }
  .cmp__hd small { display: none; }

  /* criterion = full-width labelled band above its three values */
  .cmp__rl {
    grid-column: 1 / -1;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-dark);
    background: rgba(14, 20, 34, 0.04);
    padding: 13px 14px;
    border-top: 1px solid var(--line);
    border-bottom: 0;
  }

  /* three centred columns under each criterion, split by dividers */
  .cmp__c {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 7px;
    padding: 14px 8px 18px;
    border-top: 0;
    border-bottom: 0;
    border-left: 1px solid var(--line);
  }
  .cmp__rl + .cmp__c { border-left: 0; }   /* first (DIY) value cell: no divider */
}

/* Recent Projects deck — phones: shorter, more banner-shaped cards so each project
   preview reads as the top of the real site rather than a tall, zoomed-in centre
   slice, and a card no longer fills the whole screen. (script.js re-measures card
   heights, so the sticky stacking still pins/unpins together.) */
@media (max-width: 640px) {
  /* Card height follows its content (header + a monitor-shaped preview) instead of
     a fixed near-square that zoom-cropped the screenshot. The visual holds a
     standard 16:10 monitor ratio so each project reads like a real site, and the
     whole card is shorter. (script.js re-measures heights → stacking still syncs.) */
  .deck-card { height: auto; }
  .deck-card .card__visual {
    min-height: 0;
    flex: 0 0 auto;          /* hold the ratio rather than stretch to fill the card */
    aspect-ratio: 16 / 10;
  }
}

/* ===========================================================
   BRAND GUIDE PAGE (brand.html) + page template (template.html)
   Self-contained components for the standalone brand pages. They
   reuse the site tokens (:root) so the brand stays in sync.
   =========================================================== */

/* Current-page marker in the shared nav */
.nav__links a[aria-current="page"],
.nav__links a[aria-current="location"] {   /* "page" = on that page (Brand); "location" = scroll-spy on the in-view section */
  color: var(--yellow);
}

/* ----- Page header (shared by brand + template) ----- */
.page-head {
  position: relative;
  overflow: hidden;
  padding: 80px 0 64px;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse 50% 60% at 12% 18%, rgba(212, 255, 58, 0.10), transparent 60%),
    radial-gradient(ellipse 46% 55% at 88% 30%, rgba(110, 224, 255, 0.10), transparent 60%),
    var(--bg);
}
.page-head__eyebrow {
  color: var(--yellow);
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 12px;
  font-weight: 600;
  margin: 0 0 16px;
}
.page-head__title {
  font-size: clamp(40px, 6vw, 84px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.05;
  margin: 0 0 18px;
}
.page-head__lead {
  max-width: 620px;
  color: var(--ink-mute);
  font-size: 19px;
  margin: 0;
}

/* ----- Guide sections ----- */
.guide {
  padding: 72px 0;
  border-bottom: 1px solid var(--line);
}
.guide:nth-of-type(even) {
  background: var(--bg-2);
}
.guide__head {
  margin: 0 0 36px;
}
.guide__num {
  color: var(--yellow);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.16em;
}
.guide__title {
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.1;
  margin: 8px 0 10px;
}
.guide__desc {
  color: var(--ink-mute);
  max-width: 640px;
  margin: 0;
}

/* ----- Colour swatches ----- */
.swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
}
.swatch {
  border: 0;
  padding: 0;
  text-align: left;
  font-family: inherit;
  background: var(--card);
  border-radius: var(--radius-sm);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s ease;
}
.swatch:hover { transform: translateY(-3px); }
.swatch__chip {
  display: block;
  height: 120px;
  width: 100%;
  /* inset hairline so pale chips read against the card */
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}
.swatch__meta {
  display: block;
  padding: 14px 16px 16px;
}
.swatch__name {
  display: block;
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
}
.swatch__token {
  display: block;
  font-size: 12px;
  color: var(--ink-mute);
  margin-top: 2px;
}
.swatch__hex {
  display: block;
  font-size: 13px;
  color: var(--ink-mute);
  margin-top: 8px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.swatch__hint {
  font-size: 11px;
  color: var(--ink-mute);
  opacity: 0;
  transition: opacity 0.15s;
}
.swatch:hover .swatch__hint { opacity: 1; }

/* copy toast */
.copy-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--yellow);
  color: var(--ink-dark);
  font-weight: 600;
  font-size: 14px;
  padding: 12px 22px;
  border-radius: var(--radius-pill);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 200;
}
.copy-toast.is-shown {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ----- Cookie consent banner ----- */
.consent {
  position: fixed;
  left: 12px;
  right: 12px;
  /* Mobile: sit just below the sticky ~60px header so it covers little of the
     page. Desktop pins it bottom-right (see media query below). */
  top: 68px;
  z-index: 120; /* over content + nav(50), under copy-toast(200) */
}
/* Explicit: .consent (class) and [hidden] (attribute) have equal specificity,
   so spell out the hidden state to be safe. */
.consent[hidden] { display: none; }
@media (min-width: 680px) {
  .consent { left: auto; right: 24px; top: auto; bottom: 24px; max-width: 420px; }
}
.consent__inner {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
}
@media (min-width: 680px) {
  .consent__inner { padding: 20px 22px; }
}
.consent__text {
  margin: 0 0 12px;
  color: var(--ink-mute);
  font-size: 13.5px;
  line-height: 1.5;
}
@media (min-width: 680px) {
  .consent__text { margin: 0 0 16px; font-size: 14.5px; line-height: 1.55; }
}
.consent__text a { color: var(--yellow); }
.consent__actions {
  display: flex;
  flex-wrap: wrap; /* never let the buttons spill past the card edge → no h-scroll */
  gap: 10px;
}
.consent__actions .btn {
  flex: 1 1 auto;
  min-width: 0; /* allow shrink below intrinsic button width before wrapping */
  justify-content: center;
}
/* Reject must clear the 3:1 UI-component contrast bar on --card and read as
   equal in weight to Accept — the default ghost border (0.18 alpha) is too
   faint on this background. */
.consent .btn--ghost { border-color: rgba(255, 255, 255, 0.45); }
.consent__link {
  display: inline-block;
  margin-top: 12px;
  color: var(--ink-dim);
  font-size: 13px;
}
@media (prefers-reduced-motion: no-preference) {
  .consent { animation: consentIn 0.25s cubic-bezier(0.22, 0.61, 0.36, 1); }
  @keyframes consentIn {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

/* ----- Logo lockups ----- */
.lockups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
}
.lockup {
  border-radius: var(--radius);
  padding: 48px 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 200px;
}
.lockup--dark { background: var(--bg); border: 1px solid var(--line); }
.lockup--light { background: var(--cream); }
.lockup--lime  { background: var(--yellow); }
.lockup__mark {
  font-weight: 800;
  font-size: clamp(36px, 5vw, 56px);
  letter-spacing: -0.04em;
  line-height: 1;
}
.lockup--dark .lockup__mark { color: var(--ink); }
.lockup--light .lockup__mark,
.lockup--lime .lockup__mark { color: var(--ink-dark); }
.lockup--dark .lockup__mark .logo__dot { color: var(--yellow); }
.lockup--light .lockup__mark .logo__dot { color: var(--green-2); }
.lockup--lime .lockup__mark .logo__dot { color: var(--ink-dark); }
.lockup__cap {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.lockup--dark .lockup__cap { color: var(--ink-mute); }
.lockup--light .lockup__cap,
.lockup--lime .lockup__cap { color: rgba(14, 20, 34, 0.66); }

.clearspace {
  margin-top: 18px;
  background: var(--card);
  border-radius: var(--radius);
  padding: 40px;
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}
.clearspace__box {
  position: relative;
  padding: 40px;
  border: 1px dashed rgba(212, 255, 58, 0.5);
  border-radius: var(--radius-sm);
}
.clearspace__box .lockup__mark { font-size: 44px; color: var(--ink); }
.clearspace__box .logo__dot { color: var(--yellow); }
.clearspace__note { color: var(--ink-mute); max-width: 360px; }
.clearspace__note strong { color: var(--ink); }

/* ----- Typography specimens ----- */
.typeface {
  background: var(--card);
  border-radius: var(--radius);
  padding: 36px;
  margin-bottom: 28px;
}
.typeface__name {
  font-size: clamp(56px, 9vw, 120px);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  margin: 0 0 4px;
}
.typeface__glyphs {
  font-size: 22px;
  color: var(--ink-mute);
  letter-spacing: 0.02em;
  word-spacing: 4px;
  margin: 18px 0 0;
}
.weights {
  display: grid;
  gap: 2px;
}
.weight-row {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 14px 0;
  border-top: 1px solid var(--line);
  font-size: 28px;
  letter-spacing: -0.02em;
}
.weight-row span {
  font-size: 13px;
  color: var(--ink-mute);
  width: 130px;
  flex-shrink: 0;
  letter-spacing: 0;
}
.type-scale {
  display: grid;
  gap: 4px;
}
.type-row {
  display: flex;
  align-items: baseline;
  gap: 24px;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}
.type-row__label {
  width: 130px;
  flex-shrink: 0;
  font-size: 12px;
  color: var(--ink-mute);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.type-row__sample {
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--ink);
}
.type-row__spec {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-mute);
  text-align: right;
  flex-shrink: 0;
}

/* ----- Component board (buttons, pills, cards) ----- */
.board {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  background: var(--card);
  border-radius: var(--radius);
  padding: 32px;
  margin-bottom: 20px;
}
.board--light { background: var(--cream); }
.board__label {
  width: 100%;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 4px;
}
.board--light .board__label { color: rgba(14, 20, 34, 0.62); }
/* .tag (not .pill — .pill is the hero's absolutely-positioned floating chips) */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: 600;
  background: var(--card-2);
  color: var(--ink);
}
.tag--lime { background: var(--yellow); color: var(--ink-dark); }
.tag--ghost { background: transparent; border: 1px solid var(--line); color: var(--ink-mute); }

/* ----- Token / spec list ----- */
.tokens {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.token-card {
  background: var(--card);
  border-radius: var(--radius-sm);
  padding: 22px;
}
.token-card__demo {
  height: 64px;
  background: var(--card-2);
  margin-bottom: 16px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}
.token-card__name { font-weight: 600; font-size: 15px; }
.token-card__val { font-size: 13px; color: var(--ink-mute); margin-top: 2px; }

/* ----- Do / Don't ----- */
.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
.principle {
  border-radius: var(--radius-sm);
  padding: 24px;
  background: var(--card);
  border-left: 3px solid var(--line);
}
.principle--do { border-left-color: var(--yellow); }
.principle--dont { border-left-color: #cf4a63; }
.principle__tag {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0 0 8px;
}
.principle--do .principle__tag { color: var(--yellow); }
.principle--dont .principle__tag { color: #ff8aa0; }
.principle p { margin: 0; color: var(--ink-mute); font-size: 15px; }

/* ----- Template page helpers ----- */
.tpl-note {
  background: rgba(212, 255, 58, 0.06);
  border: 1px solid rgba(212, 255, 58, 0.22);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
  margin: 0 0 40px;
  color: var(--ink-mute);
  font-size: 14px;
}
.tpl-note strong { color: var(--yellow); }
.tpl-section { padding: 72px 0; border-bottom: 1px solid var(--line); }
.tpl-section h2 {
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 600;
  letter-spacing: -0.04em;
  margin: 0 0 16px;
}
.tpl-section p { color: var(--ink-mute); max-width: 640px; }
.tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px;
  margin-top: 36px;
}
.tpl-cta {
  text-align: center;
  padding: 80px 0;
}
.tpl-cta h2 {
  font-size: clamp(32px, 4.4vw, 56px);
  font-weight: 600;
  letter-spacing: -0.04em;
  margin: 0 0 24px;
}

@media (max-width: 720px) {
  .weight-row span,
  .type-row__label { width: 92px; }
  .type-row__spec { display: none; }
  .clearspace { flex-direction: column; align-items: flex-start; }
}
