/* =========================================================================
   CobWebZ — component styles
   Tokens come from variables.css. A small reset sits in the `base` layer;
   everything else lives in `components`.
   ========================================================================= */

@layer base, components;

@layer base {
  *, ::before, ::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0 solid;
  }
  h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
  a { color: inherit; text-decoration: inherit; }
  b, strong { font-weight: bolder; }
  small { font-size: 80%; }
  ol, ul, menu { list-style: none; }
  img, svg, video, canvas { display: block; vertical-align: middle; }
  img, video { max-width: 100%; height: auto; }
  button, input, select, textarea {
    font: inherit;
    letter-spacing: inherit;
    color: inherit;
    border-radius: 0;
    background-color: transparent;
  }
  button { cursor: pointer; }
  ::placeholder { opacity: 1; }
  textarea { resize: vertical; }
}

@layer components {
  [hidden] { display: none !important; }

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

  html {
    scroll-behavior: smooth;
    scroll-padding-top: var(--header-h);
    -webkit-text-size-adjust: 100%;
  }

  body {
    margin: 0;
    background: var(--color-canvas);
    color: var(--color-body);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: clip;
  }

  h1, h2, h3 {
    color: var(--color-ink);
    font-weight: 500;
    letter-spacing: var(--tracking-tight);
    text-wrap: balance;
  }

  ::selection { background: rgba(143, 165, 198, 0.35); color: var(--color-ink); }

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

  .skip-link {
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 101; /* above the fixed header */
    padding: 10px 16px;
    background: var(--color-ink);
    color: var(--color-on-ink);
    font-size: 14px;
    font-weight: 500;
    border-radius: var(--radius-pill);
    transform: translateY(-200%);
    transition: transform 0.3s var(--ease-out);
  }
  .skip-link:focus { transform: none; }

  .container-cube {
    width: min(var(--page-max-width), 100% - 32px);
    margin-inline: auto;
  }
  @media (min-width: 640px) {
    .container-cube { width: min(var(--page-max-width), 100% - 80px); }
  }

  /* ---------- Buttons ---------- */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 40px;
    padding: 0 18px;
    border-radius: var(--radius-pill);
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.01em;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), transform 0.2s var(--ease-out), translate 0.35s var(--ease-out);
  }
  .btn span[aria-hidden] { transition: transform 0.2s var(--ease-out); }
  .btn:hover span[aria-hidden] { transform: translateX(3px); }
  .btn:active { transform: scale(0.98); }
  .btn--lg { height: 46px; padding: 0 22px; font-size: 15px; }
  .btn--block { width: 100%; }

  .btn--primary { background: var(--color-ink); color: var(--color-on-ink); box-shadow: var(--shadow-button); }
  .btn--primary:hover { background: var(--color-black-hover); }

  .btn--light { background: var(--color-surface); color: var(--color-ink); box-shadow: 0 0 0 1px var(--color-line), var(--shadow-pill); }
  .btn--light:hover { background: var(--color-surface-soft); }

  .btn[disabled] { opacity: 0.6; cursor: progress; }

  .link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-ink);
  }
  .link-arrow span { transition: transform 0.2s var(--ease-out); }
  .link-arrow:hover span { transform: translateX(3px); }

  /* ---------- Header: the logo and three floating buttons, no bar ---------- */
  .site-header {
    position: fixed;
    inset: 0 0 auto;
    z-index: 100;
    padding: 24px 0;
    pointer-events: none;
    transition: padding 0.3s var(--ease-out);
  }
  .site-header.is-scrolled { padding: 14px 0; }

  .site-header__inner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: min(1320px, 100% - 48px);
    margin-inline: auto;
  }
  @media (max-width: 640px) {
    .site-header__inner { width: min(1320px, 100% - 28px); }
  }
  .site-header__inner > * { pointer-events: auto; }

  /* Brand / Logo. Over a dark section (script.js sets is-on-dark) it sits on a pill like the
     buttons; the pill's padding is always there, cancelled by the margin, so nothing moves. */
  .site-header__brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    z-index: 2;
    margin: -7px -14px;
    padding: 7px 14px;
    border-radius: var(--radius-pill);
    color: var(--color-ink);
    text-decoration: none;
    transition: opacity 0.2s var(--ease-out), background-color 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
  }
  .site-header__brand:hover { opacity: 0.85; }
  .site-header.is-on-dark .site-header__brand {
    background-color: var(--color-surface);
    box-shadow: var(--shadow-pill);
  }
  .site-header__brand-logo {
    width: 24px;
    height: 24px;
    object-fit: contain;
    transition: transform 0.35s var(--ease-out);
  }
  [data-theme="dark"] .site-header__brand-logo {
    filter: invert(1);
  }
  .site-header__brand:hover .site-header__brand-logo {
    transform: rotate(-10deg) scale(1.08);
  }
  .site-header__brand-name {
    font-family: var(--font-sans);
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--color-ink);
    user-select: none;
  }

  /* Center Navigation Links */
  .site-nav {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    pointer-events: auto;
  }
  .site-nav__list {
    display: flex;
    align-items: center;
    gap: 32px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .site-nav__link {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    padding: 6px 2px;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-nav);
    text-decoration: none;
    letter-spacing: -0.01em;
    transition: color 0.2s var(--ease-out);
  }
  .site-nav__link:hover {
    color: var(--color-ink);
  }
  .site-nav__link.is-active {
    color: var(--color-ink);
    font-weight: 600;
  }
  /* Active black dot indicator underneath link */
  .site-nav__link::after {
    content: '';
    position: absolute;
    bottom: -6px;
    left: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: var(--color-ink);
    transform: translateX(-50%) scale(0);
    opacity: 0;
    transition: transform 0.2s var(--ease-out), opacity 0.2s var(--ease-out);
  }
  .site-nav__link.is-active::after {
    transform: translateX(-50%) scale(1);
    opacity: 1;
  }
  /* The links need about 1100px to sit clear of the logo and buttons; below that the
     menu button stands in for them. From 1100px up they show at the top of the page, and
     scrolling down (.is-folded, from script.js) slides them off to the right one after
     another as the menu button spins in beside the theme button. Scrolling back up runs
     it in reverse, wherever you are, and away from the top the links sit on a pill so
     they read over the page. --i is each link's position, --n the count (script.js). */
  @media (max-width: 1099px) {
    .site-nav { display: none; }
  }
  @media (min-width: 1100px) {
    .site-nav { transition: visibility 0s; }
    /* The pill's padding is always there, cancelled by the margin, so nothing moves */
    .site-nav__list {
      margin: -7px -22px;
      padding: 7px 22px;
      border-radius: var(--radius-pill);
      transition: background-color 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out);
    }
    .site-header.is-scrolled:not(.is-folded) .site-nav__list {
      background-color: var(--color-surface);
      box-shadow: var(--shadow-pill);
    }
    .site-nav__list > li {
      transition: opacity 0.35s var(--ease-out), translate 0.5s var(--ease-out), filter 0.35s var(--ease-out);
      transition-delay: calc(var(--i, 0) * 40ms); /* back in from the left */
    }
    .site-header.is-folded .site-nav {
      visibility: hidden; /* once the links have gone, so they can't be tabbed to */
      transition: visibility 0s 0.6s;
    }
    .site-header.is-folded .site-nav__list > li {
      opacity: 0;
      translate: 56px 0;
      filter: blur(6px);
      transition-delay: calc((var(--n, 7) - 1 - var(--i, 0)) * 40ms); /* out from the right */
    }

    /* The button keeps its place at the top too, just hidden, so nothing shifts when it comes */
    .site-header .menu {
      opacity: 0;
      visibility: hidden;
      transform: scale(0.4) rotate(-90deg);
      transition: opacity 0.2s var(--ease-out), transform 0.35s var(--ease-out), visibility 0s 0.35s;
    }
    .site-header.is-folded .menu {
      opacity: 1;
      visibility: visible;
      transform: none;
      transition: opacity 0.3s var(--ease-out) 0.2s, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s, visibility 0s;
    }
    /* …and its bars draw in one after another as it lands */
    .site-header .menu .hamburger-icon span {
      scale: 0 1;
      transition: transform 0.25s var(--ease-out), opacity 0.2s, scale 0.2s var(--ease-out);
    }
    .site-header.is-folded .menu .hamburger-icon span {
      scale: 1;
      transition: transform 0.25s var(--ease-out), opacity 0.2s, scale 0.35s var(--ease-out) calc(0.4s + var(--b, 0) * 70ms);
    }
    .hamburger-icon span:nth-child(2) { --b: 1; }
    .hamburger-icon span:nth-child(3) { --b: 2; }
  }

  /* Right-side Action Buttons */
  .site-header__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    margin-left: auto;
    z-index: 2;
  }

  /* Circular Icon Buttons (Sun and Hamburger) */
  .site-header__icon-btn {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--color-surface);
    color: var(--color-ink);
    border: 1px solid var(--color-line);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.04);
    cursor: pointer;
    transition: transform 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), background-color 0.2s;
  }
  .site-header__icon-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  }
  .site-header__icon-btn:active {
    transform: scale(0.96);
  }
  .site-header__icon-btn svg {
    display: block;
    pointer-events: none;
  }

  /* Hamburger icon (three bars) */
  .hamburger-icon {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 3.5px;
    width: 14px;
    height: 14px;
  }
  .hamburger-icon span {
    display: block;
    width: 14px;
    height: 1.5px;
    background-color: currentColor;
    border-radius: 1px;
    transition: transform 0.25s var(--ease-out), opacity 0.2s;
  }
  .site-header__icon-btn[aria-expanded="true"] .hamburger-icon span:nth-child(1) {
    transform: translateY(5px) rotate(45deg);
  }
  .site-header__icon-btn[aria-expanded="true"] .hamburger-icon span:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
  }
  .site-header__icon-btn[aria-expanded="true"] .hamburger-icon span:nth-child(3) {
    transform: translateY(-5px) rotate(-45deg);
  }

  /* Dropdown Menu Panel */
  .menu { position: static; } /* the panel below lines up with the header's right edge */
  .menu__panel {
    position: absolute;
    top: calc(100% + 12px);
    right: 0;
    left: auto;
    width: 220px;
    padding: 8px;
    border-radius: 20px;
    background: var(--color-surface);
    box-shadow: 0 0 0 1px var(--color-line), 0 20px 40px -10px rgba(0, 0, 0, 0.16);
    transform-origin: top right;
    opacity: 0;
    transform: translateY(-6px) scale(0.96);
    transition: opacity 0.2s var(--ease-out), transform 0.25s var(--ease-out);
    z-index: 100;
  }
  .menu__panel.is-open {
    opacity: 1;
    transform: none;
  }
  .menu__panel a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    border-radius: 12px;
    font-size: 14.5px;
    font-weight: 500;
    color: var(--color-ink);
    transition: background-color 0.2s var(--ease-out);
  }
  .menu__panel a:hover {
    background: var(--color-canvas);
  }
  .menu__panel a.is-active::after {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-ink);
  }

  /* Phones: the header keeps only the menu button, and the theme toggle and the CTA move
     to the foot of the menu (.menu__extras, hidden on wider screens) */
  .menu__extras { display: none; }
  @media (max-width: 640px) {
    .site-header__actions > .theme-btn,
    .site-header__actions > .site-header__cta-btn { display: none; }
    .menu__extras {
      display: grid;
      gap: 8px;
      margin-top: 8px;
      padding-top: 8px;
      border-top: 1px solid var(--color-line);
    }
  }
  .menu__theme {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 10px 14px;
    border-radius: 12px;
    font-size: 14.5px;
    font-weight: 500;
    color: var(--color-ink);
    text-align: left;
    transition: background-color 0.2s var(--ease-out);
  }
  .menu__theme:hover { background: var(--color-canvas); }
  .menu__switch {
    position: relative;
    flex-shrink: 0;
    width: 34px;
    height: 20px;
    border-radius: var(--radius-pill);
    background: var(--color-line-strong);
    transition: background-color 0.25s var(--ease-out);
  }
  .menu__switch::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--color-surface);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    transition: transform 0.25s var(--ease-out);
  }
  .menu__theme[aria-checked="true"] .menu__switch { background: var(--color-ink); }
  .menu__theme[aria-checked="true"] .menu__switch::after { transform: translateX(14px); }
  /* Same look as the header's pill CTA; :hover listed so the panel's link hover doesn't win */
  .menu__panel .menu__cta,
  .menu__panel .menu__cta:hover {
    gap: 10px;
    height: 44px;
    padding: 0 6px 0 18px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: var(--color-on-ink);
    font-size: 14px;
  }
  .menu__cta:hover .site-header__cta-arrow { transform: translate(1px, -1px); }

  /* Pill CTA Button ("Explore Now" with white circular ↗ arrow) */
  .site-header__cta-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    padding: 0 6px 0 18px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: #ffffff;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1;
    text-decoration: none;
    letter-spacing: -0.01em;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
    transition: transform 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), background-color 0.2s;
  }
  [data-theme="dark"] .site-header__cta-btn {
    background: #ffffff;
    color: #0a0a0a;
    box-shadow: 0 2px 8px rgba(255, 255, 255, 0.15);
  }
  .site-header__cta-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  }
  .site-header__cta-btn:active {
    transform: scale(0.98);
  }
  .site-header__cta-arrow {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #ffffff;
    color: #0a0a0a;
    transition: transform 0.2s var(--ease-out);
  }
  [data-theme="dark"] .site-header__cta-arrow {
    background: #0a0a0a;
    color: #ffffff;
  }
  .site-header__cta-btn:hover .site-header__cta-arrow {
    transform: translate(1px, -1px);
  }

  /* ---------- Small elements ---------- */
  .badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 30px;
    padding: 0 13px;
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    box-shadow: var(--shadow-pill);
    font-size: 13px;
    font-weight: 500;
    color: var(--color-ink);
  }
  .badge__dot {
    position: relative;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--color-dusty-blue-deep), var(--color-rose-gold));
  }
  .badge__dot::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: inherit;
    animation: pulse 2.4s var(--ease-out) infinite;
  }
  @keyframes pulse {
    0% { transform: scale(1); opacity: 0.55; }
    70%, 100% { transform: scale(2.6); opacity: 0; }
  }

  /* Particle ribbons, drawn by initParticles() in script.js. It sizes and places each canvas
     to cover just its ribbons, so these are only the starting box. */
  .particles {
    position: absolute;
    inset: 0;
    z-index: -1;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
  /* Our Services holds still while you scroll through it, so its ribbons do too: their
     canvas sits in a screen-high box that sticks to the top of the section */
  .particles-pin {
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
  }
  .particles-pin__view {
    position: sticky;
    top: 0;
    height: min(100svh, 100%);
  }

  /* ---------- Hero ---------- */
  .hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    min-height: clamp(640px, 100svh, 1000px);
    padding: calc(var(--header-h) + 48px) 0 clamp(96px, 14vh, 160px);
    background: radial-gradient(70% 55% at 50% 0%, var(--hero-glow), transparent 70%);
    text-align: center;
  }
  .hero .particles {
    -webkit-mask-image: linear-gradient(#000 88%, transparent);
    mask-image: linear-gradient(#000 88%, transparent);
  }
  .hero__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .hero__title {
    margin-top: 28px;
    font-size: clamp(46px, 6.6vw, 84px);
    line-height: 1.02;
    letter-spacing: -0.045em;
  }
  .hero__title .accent { display: block; }

  /* Homepage: the name is the headline and the tagline sits underneath it */
  .hero__brand {
    display: block;
    font-size: clamp(76px, 15vw, 216px);
    font-weight: 500;
    line-height: 0.9;
    letter-spacing: -0.065em;
    /* Masks the letters as they rise in; extended so the p's descender isn't cut */
    clip-path: inset(-0.2em -0.1em -0.18em);
  }
  .js .hero__brand .char {
    transform: translateY(130%);
    transition: transform 1.1s var(--ease-out) calc(var(--i) * 45ms + 60ms);
  }
  .js .is-loaded .hero__brand .char { transform: none; }
  .hero__tagline {
    --split-delay: 450ms; /* after the name's letters */
    display: block;
    margin-top: 0.6em;
    font-size: clamp(24px, 3vw, 40px);
    line-height: 1.2;
    letter-spacing: -0.035em;
  }
  .hero__tagline .accent { display: inline; }
  .hero__lead {
    margin-top: 28px;
    max-width: 31em;
    font-size: 16px;
    line-height: 1.65;
    text-wrap: pretty;
  }
  .hero__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    margin-top: 36px;
  }
  .hero__note {
    font-size: 13px;
    color: var(--color-body);
    transition: color 0.2s var(--ease-out);
  }
  .hero__note:hover { color: var(--color-ink); }

  .scroll-cue {
    position: absolute;
    left: 50%;
    bottom: clamp(20px, 4vh, 40px);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-body);
    translate: -50% 0;
  }
  .scroll-cue i {
    position: relative;
    width: 1px;
    height: 40px;
    overflow: hidden;
    background: var(--color-line);
  }
  .scroll-cue i::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--color-ink);
    animation: cue 2.2s var(--ease-out) infinite;
  }
  @keyframes cue {
    0% { transform: translateY(-100%); }
    60%, 100% { transform: translateY(100%); }
  }

  /* ---------- Type accents ---------- */
  /* Second, quieter tone for part of a heading */
  .accent { color: var(--color-muted); }

  /* Headings split into words by script.js: each word fades up in turn.
     Hero titles play on load; other headings when their section is revealed. */
  .word, .char { display: inline-block; }
  .js [data-split-words] .word {
    opacity: 0;
    transform: translateY(0.35em);
    transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
    transition-delay: calc(var(--i) * 55ms + var(--split-delay, 120ms));
  }
  .js .is-visible [data-split-words] .word,
  .js .is-loaded .hero [data-split-words] .word { opacity: 1; transform: none; }

  /* ---------- Sections ---------- */
  .section {
    position: relative;
    isolation: isolate;
    padding-block: clamp(88px, 10vw, 144px);
  }

  .section-head {
    max-width: 640px;
    margin: 0 auto clamp(40px, 5vw, 64px);
    text-align: center;
  }
  .h-section {
    font-size: clamp(34px, 4.2vw, 52px);
    line-height: 1.08;
  }
  .section-lead {
    margin-top: 16px;
    max-width: 32em;
    font-size: 16px;
    line-height: 1.65;
    text-wrap: pretty;
  }
  .section-head .section-lead { margin-inline: auto; }

  .card {
    background: var(--color-surface);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
  }

  /* ---------- Cobwebs in the page corners ---------- */
  /* script.js draws each web for the top-left corner (viewBox 0–100, corner at 0 0) and the
     modifier mirrors it into place. On screen, the spokes spin out and then the threads are
     laid inner to outer; after that it sways in the draught and shivers when brushed. */
  .cobweb {
    position: absolute;
    z-index: -1;
    width: clamp(130px, 16vw, 250px);
    aspect-ratio: 1;
    color: color-mix(in srgb, var(--color-ink) 26%, transparent); /* follows the light/dark theme */
    pointer-events: none;
  }
  /* Above the hero content, or its box would cover the spider's hover area at laptop widths */
  .cobweb[data-cobweb="spider"] { z-index: 1; }
  .cobweb--tr { top: 0; right: 0; width: clamp(100px, 12vw, 190px); }
  .cobweb--br { bottom: 0; right: 0; }
  .cobweb__web {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
  }
  .cobweb--tr .cobweb__web { transform: scaleX(-1); }
  .cobweb--br .cobweb__web { transform: scale(-1); }
  .cobweb__web path {
    fill: none;
    stroke: currentColor;
    stroke-width: var(--sw, 0.5); /* script.js keeps this at about 1px */
    stroke-linecap: round;
  }
  .cobweb .cobweb__hit { fill: transparent; stroke: none; pointer-events: all; }
  .cobweb__shake,
  .cobweb__sway { transform-origin: 0 0; }
  /* Scaling from the corner keeps the threads pinned to both walls */
  .cobweb__sway {
    animation: cobweb-sway 7s ease-in-out infinite alternate;
    animation-delay: calc(var(--w, 0) * -2.6s);
  }
  @keyframes cobweb-sway {
    to { transform: scale(1.03, 0.97); }
  }
  .js .cobweb__spoke,
  .js .cobweb__ring {
    stroke-dasharray: 1 2;
    stroke-dashoffset: 1.02;
    transition: stroke-dashoffset 1s var(--ease-out) calc(var(--i) * 70ms);
  }
  .js .cobweb__ring { transition: stroke-dashoffset 1.4s var(--ease-out) calc(350ms + var(--i) * 130ms); }
  .js .cobweb.is-visible path { stroke-dashoffset: 0; }

  /* A small spider on a thread: it bobs, and climbs out of reach while the pointer is near.
     The box is the hover area and stays put, so the climb can't take it out from under the
     pointer. --bob and --lift are registered at the end of this file so they can animate. */
  .cobweb__drop {
    --len: 74; /* thread length in px */
    --l: calc((var(--len) + var(--bob)) * (1 - 0.8 * var(--lift)));
    position: absolute;
    width: 44px;
    height: calc(var(--len) * 1px + 40px);
    translate: -50% 0;
    transform-origin: 50% 0;
    color: var(--color-ink);
    pointer-events: auto;
    animation: cobweb-bob 3.4s ease-in-out infinite alternate;
    transition: --lift 1.8s cubic-bezier(0.45, 0, 0.2, 1);
  }
  .cobweb__drop:hover { --lift: 1; transition-duration: 0.5s; }
  @media (max-width: 639px) {
    .cobweb__drop { --len: 48; }
  }
  @keyframes cobweb-bob {
    from { rotate: -2deg; }
    to { rotate: 2deg; --bob: 12; }
  }
  .cobweb__silk {
    position: absolute;
    top: 0;
    left: calc(50% - 0.5px);
    width: 1px;
    height: 1px;
    background: currentColor;
    opacity: 0.45;
    transform-origin: top;
    transform: scaleY(var(--l));
  }
  .cobweb__spider {
    position: absolute;
    top: 0;
    left: 50%;
    width: 20px;
    overflow: visible;
    translate: -50% calc(var(--l) * 1px - 6px); /* the thread meets the top of the body */
  }
  .cobweb__spider path { fill: none; stroke: currentColor; stroke-width: 22; stroke-linecap: round; }
  .cobweb__spider .cobweb__body { fill: currentColor; stroke: none; }
  .cobweb__leg { transform-origin: var(--o); }
  .cobweb__drop:hover .cobweb__leg { animation: spider-scuttle 0.16s ease-in-out infinite alternate; }

  /* ---------- About ---------- */
  .about__body {
    display: grid;
    align-items: center;
    gap: 40px;
  }
  @media (min-width: 900px) {
    .about__body {
      grid-template-columns: minmax(0, 1fr) clamp(220px, 24vw, 340px);
      gap: clamp(56px, 7vw, 120px);
    }
  }
  .about__statement {
    font-size: clamp(26px, 3.3vw, 46px);
    font-weight: 500;
    line-height: 1.28;
    letter-spacing: -0.035em;
    color: var(--color-ink);
    text-wrap: pretty;
  }
  /* Words start soft, gently blurred (2.8px) and resting 5px lower. As you scroll,
     each word focuses with optical clarity, fades to solid ink, and glides
     up into place. Hovering gives an elastic ripple like touching a web thread. */
  .js .about__statement .word {
    opacity: clamp(0.22, calc((var(--p, 0) * (var(--n) + 8) - var(--i)) / 3), 1);
    transform: translateY(clamp(0px, calc(1px * (var(--i) - var(--p, 0) * (var(--n) + 8)) * 0.9), 5px));
    filter: blur(clamp(0px, calc(1px * (var(--i) - var(--p, 0) * (var(--n) + 8)) * 0.5), 2.8px));
    transition: color 0.25s var(--ease-out), opacity 0.25s var(--ease-out), filter 0.25s var(--ease-out);
  }

  .js .about__statement .word:hover {
    color: var(--color-ink);
    opacity: 1 !important;
    filter: blur(0px) !important;
    transform: translateY(-2.5px) !important;
    transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.15s, filter 0.15s;
  }

  /* The spider mark spins itself in while the section scrolls past: the W's outer threads
     (--p 0 → .35), then the back legs, which are threads too (.28 → .50), then the body
     drops in (.40 → .56) and the legs reach out (.50 → .70). Lengths are pathLength="1";
     the 1.05 keeps the round caps hidden until a stroke starts drawing. */
  .about__mark {
    width: min(100%, 340px);
    justify-self: center;
  }
  @media (max-width: 899px) {
    .about__mark { width: 200px; }
  }
  .spider {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
  }
  .spider path {
    fill: none;
    stroke: var(--color-ink);
    stroke-linecap: round;
  }
  .spider__thread { stroke-width: 27; }
  .spider__leg { stroke-width: 20; transform-origin: var(--o); transition: scale 0.3s var(--ease-out); }
  .spider .spider__body {
    fill: var(--color-ink);
    stroke: none;
    transform-origin: 387.5px 281px;
    transition: scale 0.3s var(--ease-out);
  }
  .spider .spider__hit { fill: transparent; pointer-events: all; }
  .spider__bug { transform-origin: 387.5px 281px; }

  .js .spider path { stroke-dasharray: 1 2; }
  .js .spider__thread { stroke-dashoffset: calc(1.05 * (1 - clamp(0, var(--p, 0) * 2.8, 1))); }
  .js .spider__arm { stroke-dashoffset: calc(1.05 * (1 - clamp(0, (var(--p, 0) - 0.28) * 4.5, 1))); }
  .js .spider__leg { stroke-dashoffset: calc(1.05 * (1 - clamp(0, (var(--p, 0) - 0.50) * 5, 1))); }
  .js .spider .spider__body {
    opacity: clamp(0, (var(--p, 0) - 0.40) * 6, 1);
    transform: scale(clamp(0.3, (var(--p, 0) - 0.40) * 3.5 + 0.3, 1));
  }

  /* Once it has landed, script.js lets the spider be dragged (it springs back on release)
     and the W's outer threads be plucked */
  .about__mark.is-live .spider__bug { cursor: grab; touch-action: none; }
  .about__mark.is-dragging .spider__bug { cursor: grabbing; }
  .about__mark.is-live .spider__thread:not(.spider__arm) { cursor: pointer; }
  /* A fast swipe past startles it: it hunches and pulls its legs in */
  .about__mark.is-startled .spider__leg { scale: 0.7; transition-duration: 0.12s; }
  .about__mark.is-startled .spider__body { scale: 0.92; transition-duration: 0.12s; }
  .about__mark.is-scuttling .spider__leg {
    animation: spider-scuttle 0.16s ease-in-out infinite alternate;
    animation-delay: calc(var(--i) * -55ms);
  }
  @keyframes spider-scuttle {
    from { transform: rotate(calc(var(--s) * -1)); }
    to { transform: rotate(var(--s)); }
  }
  .about__hint {
    display: none;
    margin-top: 18px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-align: center;
    text-transform: uppercase;
    color: var(--color-subtle);
    opacity: 0;
    transition: opacity 0.4s var(--ease-out);
  }
  .js .about__hint { display: block; }
  .js .about__mark.is-live .about__hint { opacity: 1; }
  .js .about__mark.is-live.is-hint-off .about__hint { opacity: 0; }

  /* Snapping the spider back from far out shakes the web, words included: the tremor runs
     from the last word (nearest the spider) back to the first; script.js sets --tremor */
  .about__statement.is-trembling .word {
    animation: word-tremor 0.55s var(--ease-out) calc((var(--n) - var(--i)) * 12ms);
  }
  @keyframes word-tremor {
    0%, 100% { translate: 0 0; }
    25% { translate: 0 calc(var(--tremor, 3px) * -1); }
    55% { translate: 0 calc(var(--tremor, 3px) * 0.5); }
    80% { translate: 0 calc(var(--tremor, 3px) * -0.2); }
  }

  /* ---------- Our Services: four services hung on a web ---------- */
  /* script.js (initServices) draws the web into .services__silk: 12 spokes, 8 rings, the
     ring the spider walks (.s-path, radius 195 of the 600-unit viewBox) and its thread
     (.services__trail). The service points sit on that ring at angle --a, which is why they
     are 32.5% (195 / 600) out from the centre. */
  .services {
    position: relative;
    overflow-x: clip;
    padding-block: clamp(48px, 6vw, 96px) clamp(80px, 9vw, 130px);
  }
  .services__head {
    max-width: 680px;
    margin-inline: auto;
    margin-bottom: clamp(32px, 4vw, 56px);
    text-align: center;
  }
  .services__stage {
    display: grid;
    align-items: center;
    gap: clamp(28px, 5vw, 88px);
  }
  @media (min-width: 960px) {
    .services__stage { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
  }

  /* The web, its points and the spider tilt together toward the pointer (--rx / --ry) */
  .services__web {
    position: relative;
    width: min(100%, 560px);
    aspect-ratio: 1;
    margin-inline: auto;
    color: color-mix(in srgb, var(--color-ink) 22%, transparent);
    container-type: size;
    transform: perspective(1100px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
    transition: transform 0.6s var(--ease-out);
  }
  .services__silk {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
  }
  .services__silk :is(path, circle, line) {
    fill: none;
    stroke: currentColor;
    stroke-width: var(--sw, 1); /* script.js keeps this at about a pixel */
    stroke-linecap: round;
  }
  .services__silk .s-path,
  .services__silk .s-hub { stroke-width: calc(var(--sw, 1) * 1.6); }
  .services__silk .services__trail {
    stroke: var(--color-ink);
    stroke-width: calc(var(--sw, 1) * 2.2);
    stroke-dasharray: 0 1;
    opacity: 0;
    transition: opacity 1.2s var(--ease-out);
  }
  .services__silk .services__trail.is-on { opacity: 1; transition: none; }
  .services__silk .services__drop { stroke: var(--color-ink); opacity: 0.55; transition: opacity 0.6s var(--ease-out); }
  .services__silk .services__drop.is-gone { opacity: 0; }

  /* Spun in when the section arrives: spokes out from the hub, then the rings inner to outer */
  .js .services__silk :is(.s-hub, .s-spoke, .s-ring) {
    stroke-dasharray: 1 2;
    stroke-dashoffset: 1.02;
    transition: stroke-dashoffset 1s var(--ease-out) calc(var(--i, 0) * 50ms);
  }
  .js .services__silk .s-ring { transition: stroke-dashoffset 1.3s var(--ease-out) calc(450ms + var(--i, 0) * 100ms); }
  .js .services__stage.is-visible .services__silk :is(.s-hub, .s-spoke, .s-ring) { stroke-dashoffset: 0; }

  /* The current service's number in the hub; it rolls up to the next one (script.js) */
  .services__count {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    margin: 0;
    clip-path: circle(9.5% at 50% 50%);
    font-size: 9cqw;
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.06em;
    color: var(--color-ink);
    pointer-events: none;
  }
  .services__count span {
    display: block;
    transition: translate 0.45s var(--ease-out), opacity 0.45s var(--ease-out);
  }
  .services__count span.is-out { translate: 0 -60%; opacity: 0; }
  .services__count span.is-in { translate: 0 60%; opacity: 0; transition: none; }
  .js .services__stage:not(.is-visible) .services__count span { opacity: 0; }

  /* Service points: a 44px target centred on the ring, its label to the outside */
  .services__node {
    position: absolute;
    left: calc(50% + cos(var(--a)) * 32.5%);
    top: calc(50% + sin(var(--a)) * 32.5%);
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    translate: -50% -50%;
    color: var(--color-muted);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .services__dot {
    position: relative;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--color-canvas);
    box-shadow: inset 0 0 0 1.5px currentColor;
    transition: background-color 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out), scale 0.3s var(--ease-out);
  }
  /* A ripple keeps going out from the chosen point */
  .services__dot::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 1px solid var(--color-ink);
    opacity: 0;
  }
  .services__node.is-active .services__dot::after { animation: services-ripple 2.4s var(--ease-out) infinite; }
  @keyframes services-ripple {
    0% { opacity: 0.6; scale: 1; }
    100% { opacity: 0; scale: 3.4; }
  }
  .services__label {
    position: absolute;
    top: 50%;
    left: calc(100% + 4px); /* clear of the spider's legs when it sits on the point */
    display: flex;
    align-items: baseline;
    gap: 8px;
    translate: 0 -50%;
    font-size: clamp(13px, 3.1cqw, 16px);
    font-weight: 500;
    letter-spacing: -0.02em;
    white-space: nowrap;
    transition: color 0.3s var(--ease-out);
  }
  .services__node--left .services__label { left: auto; right: calc(100% + 4px); flex-direction: row-reverse; }
  .services__num {
    font-family: var(--font-mono);
    font-size: 0.7em;
    letter-spacing: 0.06em;
    color: var(--color-subtle);
  }
  .services__node:hover,
  .services__node.is-active { color: var(--color-ink); }
  .services__node:hover .services__dot { scale: 1.25; }
  .services__node.is-active .services__dot { background: var(--color-ink); box-shadow: inset 0 0 0 1.5px var(--color-ink); }
  .services__node:focus-visible { outline: 2px solid var(--color-ink); outline-offset: 2px; }
  /* The points pop on once the web has spun */
  .js .services__node { scale: 0; opacity: 0; transition: scale 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s var(--ease-out); }
  .js .services__stage.is-visible .services__node {
    scale: 1;
    opacity: 1;
    transition-delay: calc(1.1s + var(--n, 0) * 0.12s);
  }
  .services__node:nth-child(2) { --n: 1; }
  .services__node:nth-child(3) { --n: 2; }
  .services__node:nth-child(4) { --n: 3; }

  /* The logo's spider, walking the web (moved and turned by script.js) */
  .services__spider {
    position: absolute;
    top: 0;
    left: 0;
    width: 6.4cqw;
    min-width: 22px;
    color: var(--color-ink);
    translate: -50% -52%;
    rotate: var(--h, 0deg);
    opacity: 0;
    pointer-events: none;
  }
  .services__spider.is-ready { opacity: 1; }
  .services__spider svg { display: block; width: 100%; height: auto; overflow: visible; }
  .services__spider path { fill: none; stroke: currentColor; stroke-width: 22; stroke-linecap: round; }
  .services__spider .services__body { fill: currentColor; stroke: none; }
  .services__leg { transform-origin: var(--o); }
  .services__spider.is-walking .services__leg { animation: spider-scuttle 0.14s ease-in-out infinite alternate; }

  /* Scrolling moves through the services (script.js picks the one to show).
     Wide, tall screens (.is-pinned): the section holds still while you scroll through it,
     each service getting 60% of a screen of scrolling (--steps = how many), and the four
     panels share one grid cell so switching never shifts anything.
     Otherwise: the web rides along at the top while the panels scroll past beneath it, and
     the one in view is in focus. Without script, the panels simply stack. */
  .services.is-pinned {
    height: calc(100svh + var(--steps, 4) * 60svh);
    padding-block: 0;
  }
  .services.is-pinned > .container-cube {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 100svh;
    /* The extra room underneath lifts the content a little above the true centre */
    padding-block: calc(var(--header-h) + 4px) clamp(56px, 10vh, 112px);
  }
  .services.is-pinned .services__head { margin-bottom: clamp(16px, 3.5vh, 40px); }
  .services.is-pinned .services__web { width: min(100%, 560px, 100svh - 370px); }

  .js .services:not(.is-pinned) .services__web {
    position: sticky;
    top: calc(var(--header-h) + 4px);
    z-index: 2;
    width: min(100%, 300px, 42svh);
  }
  /* A band of page colour behind the web, so the panels pass out of sight under it */
  .js .services:not(.is-pinned) .services__web::before {
    content: '';
    position: absolute;
    inset: -12px -50vw -36px;
    z-index: -1;
    background: linear-gradient(var(--color-canvas) 80%, transparent);
  }

  .services__panels {
    width: 100%;
    max-width: 520px;
    margin-inline: auto;
  }
  .services__item + .services__item { margin-top: 64px; }
  .services.is-pinned .services__panels { display: grid; }
  .services.is-pinned .services__item { grid-area: 1 / 1; margin-top: 0; }
  .services.is-pinned .services__item:not(.is-active) { visibility: hidden; }
  .js .services:not(.is-pinned) .services__item { opacity: 0.3; transition: opacity 0.4s var(--ease-out); }
  .js .services:not(.is-pinned) .services__item.is-active { opacity: 1; }
  .services__icon {
    display: block;
    width: 46px;
    height: 46px;
    color: var(--color-ink);
  }
  .services__icon :is(path, circle) {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .services__meta {
    margin-top: 22px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-subtle);
  }
  .services__title {
    margin-top: 10px;
    font-size: clamp(46px, 5.8vw, 80px);
    font-weight: 500;
    line-height: 0.95;
    letter-spacing: -0.05em;
    color: var(--color-ink);
  }
  .services__lead {
    margin-top: 12px;
    font-size: clamp(19px, 1.9vw, 24px);
    letter-spacing: -0.03em;
    color: var(--color-muted);
  }
  .services__text {
    margin-top: 18px;
    max-width: 32em;
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--color-body);
    text-wrap: pretty;
  }
  .services__list {
    margin-top: 26px;
    border-top: 1px solid var(--color-line);
  }
  .services__list li {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 0;
    border-bottom: 1px solid var(--color-line);
    font-size: 14.5px;
    color: var(--color-ink);
  }
  /* Each bullet is a little web point */
  .services__list li::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1.5px currentColor;
  }
  /* When pinned, the panel's lines rise in one after another; its icon draws itself */
  .services.is-pinned .services__item.is-active > *,
  .services.is-pinned .services__item.is-active li {
    animation: services-rise 0.7s var(--ease-out) both;
    animation-delay: calc(var(--d, 0) * 70ms);
  }
  .services__item > :nth-child(2) { --d: 1; }
  .services__item > :nth-child(3) { --d: 2; }
  .services__item > :nth-child(4) { --d: 3; }
  .services__item > :nth-child(5) { --d: 4; }
  .services__item > :nth-child(6) { --d: 5; }
  .services__list li:nth-child(1) { --d: 6; }
  .services__list li:nth-child(2) { --d: 7; }
  .services__list li:nth-child(3) { --d: 8; }
  @keyframes services-rise {
    from { opacity: 0; translate: 0 16px; }
  }
  .js .services__item.is-active .services__icon :is(path, circle) {
    stroke-dasharray: 1 2;
    animation: services-draw 1.2s var(--ease-out) 0.15s both;
  }
  @keyframes services-draw {
    from { stroke-dashoffset: 1.02; }
    to { stroke-dashoffset: 0; }
  }

  /* ---------- Our Work: 16:9 video cards ---------- */
  .card-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 24px;
  }
  .work-card {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: var(--radius-card);
    background: var(--color-surface);
    box-shadow: var(--shadow-soft);
    transition-property: transform, opacity, box-shadow;
    transition-duration: 0.5s;
    transition-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
  }
  .work-card__media {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-canvas);
    container-type: size; /* 100cqh = the frame's height, for the scroll preview below */
  }

  /* Scroll-down preview: a tall screenshot of the whole site, top-aligned in the 16:9 frame,
     scrolled at an even pace (--frames, set on each image, is its height in frames).
     The home cards scroll by themselves while on screen (.is-inview, from script.js), each a
     beat after the one before, and hold still while hovered. The work page's frames scroll
     on hover, or by themselves on touch screens, which have no hover. */
  .work-card__scroll,
  .project__scroll {
    position: absolute;
    inset: 0 0 auto;
    display: block;
    width: 100%;
    height: auto;
    transform-origin: 50% 0;
    transition: translate 0.9s var(--ease-out), scale 1.6s var(--ease-out) calc(var(--i, 0) * 140ms + 150ms);
  }
  .is-inview > .work-card__scroll {
    animation: preview-scroll calc(var(--frames, 10) * 1s) ease-in-out calc(0.8s + var(--i, 0) * 0.5s) infinite alternate;
  }
  .work-card:is(:hover, :focus-visible) .work-card__scroll { animation-play-state: paused; }
  .project__media:hover .project__scroll {
    translate: 0 calc(-100% + 100cqh);
    transition: translate calc(var(--frames, 10) * 0.75s) cubic-bezier(0.45, 0.05, 0.55, 0.95) 0.2s;
  }
  @media (hover: none) {
    .is-inview > .project__scroll {
      animation: preview-scroll calc(var(--frames, 10) * 1.4s) ease-in-out 0.8s infinite alternate;
    }
  }
  @keyframes preview-scroll {
    to { translate: 0 calc(-100% + 100cqh); }
  }
  .work-card__body {
    display: flex;
    flex: 1;
    flex-direction: column;
    padding: 26px 30px 24px;
  }
  .work-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }
  .work-card__title {
    font-size: 22px;
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: var(--tracking-tight);
    color: var(--color-ink);
  }
  .work-card__arrow {
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    box-shadow: 0 0 0 1px var(--color-line);
    font-size: 15px;
    color: var(--color-ink);
    transition-property: transform, color, background-color, box-shadow;
    transition-duration: 0.5s;
    transition-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
  }
  .work-card__text {
    margin-top: 8px;
    font-size: 14px;
    line-height: 1.55;
    text-wrap: pretty;
  }

  @media (min-width: 900px) {
    .card-container { flex-direction: row; }
    .work-card { flex: 1 1 0; min-width: 0; }
  }

  /* Focus state: hovered card scales up over its neighbours; siblings shrink, dim and
     drift away from it. Only with a real pointer and room for the three cards in a row. */
  @media (min-width: 900px) and (hover: hover) and (pointer: fine) {
    .work-card:is(:hover, :focus-visible) {
      z-index: 2;
      transform: scale(1.15);
      box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.2);
    }
    .work-card:is(:hover, :focus-visible) .work-card__arrow {
      background: var(--color-ink);
      box-shadow: none;
      color: var(--color-on-ink);
      transform: rotate(-45deg);
    }

    .card-container:has(.work-card:is(:hover, :focus-visible)) .work-card:not(:hover, :focus-visible) {
      opacity: 0.6;
      transform: scale(0.95);
    }
    /* Cards before the focused one drift left, cards after it drift right */
    .card-container .work-card:not(:hover, :focus-visible):has(~ .work-card:is(:hover, :focus-visible)) {
      transform: translateX(-16px) scale(0.95);
    }
    .card-container .work-card:is(:hover, :focus-visible) ~ .work-card:not(:hover, :focus-visible) {
      transform: translateX(16px) scale(0.95);
    }
  }

  .work__more {
    display: flex;
    justify-content: center;
    margin-top: clamp(32px, 4vw, 48px);
  }

  /* Screenshots wipe up into view one after another (--i from data-stagger) and settle from a slight zoom */
  .js .card-container .work-card__media,
  .js .project .project__media {
    clip-path: inset(100% -2px -2px -2px);
    transition: clip-path 1.2s var(--ease-out) calc(var(--i, 0) * 140ms + 150ms);
  }
  .js .card-container.is-visible .work-card__media,
  .js .project.is-visible .project__media { clip-path: inset(-2px); }
  .js .card-container .work-card__scroll { scale: 1.15; } /* timing: .work-card__scroll's transition */
  .js .card-container.is-visible .work-card__scroll { scale: none; }

  /* "View" bubble that trails the pointer over [data-cursor] elements (created by script.js) */
  .cursor-badge {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 70;
    display: grid;
    place-items: center;
    width: 84px;
    height: 84px;
    margin: -42px 0 0 -42px;
    border-radius: 50%;
    background: var(--color-ink);
    box-shadow: var(--shadow-button);
    font-size: 13px;
    font-weight: 500;
    color: var(--color-on-ink);
    pointer-events: none;
    scale: 0;
    transition: scale 0.35s var(--ease-out);
  }
  .cursor-badge.is-active { scale: 1; }
  .has-cursor-badge [data-cursor] { cursor: none; }

  /* ---------- Tech stack: two drifting rows (moved by script.js) ---------- */
  .stack { overflow: hidden; }
  .marquee { overflow: hidden; }
  .marquee__track {
    display: flex;
    width: max-content;
  }
  /* Plain type, no boxes. Each item carries its own separator, so one copy of the items is
     exactly one loop long. */
  .marquee__track li {
    flex: none;
    font-size: clamp(30px, 4.2vw, 60px);
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -0.04em;
    color: var(--color-ink);
    white-space: nowrap;
  }
  .marquee__track li::after {
    content: '/';
    margin-inline: 0.45em;
    font-weight: 300;
    color: var(--color-subtle);
  }
  .marquee[data-marquee='reverse'] li { color: var(--color-muted); }

  /* ---------- Our Work page (work.html): one card per live site ---------- */
  .hero--page {
    min-height: 0;
    padding-bottom: clamp(64px, 8vw, 112px);
  }

  .showcase { padding-top: 0; }
  .showcase__list { display: grid; gap: clamp(24px, 3vw, 40px); }

  .project {
    display: grid;
    padding: 10px;
    border-radius: var(--radius-card);
    background: var(--color-surface);
    box-shadow: var(--shadow-card);
  }

  /* Screenshot in a browser-window frame; the whole frame opens the site */
  .project__media {
    display: block;
    overflow: hidden;
    border-radius: 16px;
    background: var(--color-canvas);
    box-shadow: 0 0 0 1px var(--color-line);
  }
  .project__bar {
    display: flex;
    align-items: center;
    gap: 14px;
    height: 34px;
    padding: 0 14px;
    border-bottom: 1px solid var(--color-line);
    background: var(--color-surface-soft);
    font-size: 12px;
  }
  .win__dots { display: flex; gap: 0.45em; }
  .win__dots i { width: 0.7em; height: 0.7em; border-radius: 50%; }
  .win__dots i:nth-child(1) { background: #ff5f57; }
  .win__dots i:nth-child(2) { background: #febc2e; }
  .win__dots i:nth-child(3) { background: #28c840; }
  .project__tab {
    min-width: 0;
    overflow: hidden;
    font-family: var(--font-mono);
    color: var(--color-subtle);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .project__screen {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    container-type: size; /* for .project__scroll, styled with .work-card__scroll above */
  }

  .project__body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 24px 18px 18px;
  }
  .project__label { font-size: 13px; }
  .project__title {
    margin-top: 4px;
    font-size: clamp(26px, 3vw, 34px);
    line-height: 1.1;
  }
  .project__text {
    margin-top: 12px;
    font-size: 15px;
    line-height: 1.6;
    text-wrap: pretty;
  }
  .project__list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 20px;
    font-size: 14px;
  }
  .project__tags {
    margin-top: 20px;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.6;
    color: var(--color-subtle);
  }
  .project__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 24px;
    margin-top: 28px;
  }

  @media (min-width: 900px) {
    .project {
      grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
      align-items: center;
    }
    .project__body { padding: 32px 36px; }
    /* Alternate the screenshot from side to side down the page */
    .project:nth-child(even) .project__media { order: 2; }
  }

  /* ---------- Pricing ---------- */
  .price-grid {
    display: grid;
    gap: 16px;
    max-width: 1120px;
    margin-inline: auto;
  }
  @media (min-width: 900px) {
    .price-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
  }
  .price {
    display: flex;
    flex-direction: column;
    padding: 32px;
    transition: box-shadow 0.3s var(--ease-out);
  }
  .price__name { font-size: 17px; letter-spacing: -0.01em; }
  .price__desc { margin-top: 6px; font-size: 14px; line-height: 1.55; }
  @media (min-width: 900px) {
    .price__desc { min-height: 3.1em; }
  }
  .price__price {
    display: flex;
    align-items: flex-start;
    gap: 4px;
    margin-top: 28px;
    color: var(--color-ink);
  }
  .price__currency { margin-top: 0.45em; font-size: 14px; font-weight: 500; }
  .price__amount {
    font-size: 52px;
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.04em;
  }
  .price__note { margin-top: 10px; font-size: 13px; }
  .price__list {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 12px;
    margin: 32px 0 36px;
    font-size: 14px;
  }
  .price__list li,
  .project__list li { position: relative; padding-left: 26px; line-height: 1.5; }
  .price__list li::before,
  .project__list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.2em;
    width: 15px;
    height: 15px;
    /* The tick is a mask filled with the ink colour, so it flips with the theme */
    background: var(--color-ink);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    opacity: 0.55;
  }
  .price.is-selected { box-shadow: 0 0 0 2px var(--color-ink), var(--shadow-card); }

  /* Optional Enhancements: same width, cards and gaps as .price-grid, one column on phones */
  .addons {
    max-width: 1120px;
    margin: clamp(64px, 8vw, 104px) auto 0;
  }
  .addons__head {
    max-width: 520px;
    margin: 0 auto clamp(28px, 4vw, 44px);
    text-align: center;
  }
  .addons__eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-subtle);
  }
  .addons__title {
    margin-top: 10px;
    font-size: clamp(26px, 2.8vw, 34px);
    line-height: 1.12;
  }
  .addons__lead {
    margin-top: 12px;
    font-size: 15px;
    line-height: 1.6;
    text-wrap: pretty;
  }
  .addons__grid {
    display: grid;
    gap: 16px;
  }
  @media (min-width: 900px) {
    .addons__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
  }
  /* The cards follow each other in, in the order data-stagger numbers them */
  .addons__grid > .reveal { --delay: calc(var(--i, 0) * 90ms); }
  .addons__group { padding: 32px; }
  .addons__name {
    font-size: 17px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--color-ink);
    text-wrap: balance;
  }
  .addons__list { margin-top: 20px; }
  .addons__list li {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-block: 14px;
    border-top: 1px solid var(--color-line);
  }
  .addons__list li:last-child { padding-bottom: 0; }
  .addons__item {
    font-size: 14px;
    line-height: 1.5;
    color: var(--color-ink);
  }
  .addons__price {
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--color-body);
  }
  @media (max-width: 479px) {
    .addons__group { padding: 28px 24px; }
  }

  /* script.js wraps each add-on in a label with a tick box: box on the left, text beside it */
  .addon {
    position: relative;
    display: grid;
    grid-template-columns: 18px minmax(0, 1fr);
    column-gap: 12px;
    row-gap: 4px;
    cursor: pointer;
  }
  .addon__check {
    position: absolute;
    top: 2px;
    left: 0;
    width: 18px;
    height: 18px;
    margin: 0;
    opacity: 0;
    cursor: pointer;
  }
  .addon__box {
    position: relative;
    grid-row: 1 / 3;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    border: 1px solid var(--color-line-strong);
    border-radius: 6px;
    background: var(--color-surface);
    transition: background-color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
  }
  /* The tick is a mask filled with the on-ink colour, so it flips with the theme */
  .addon__box::before {
    content: '';
    position: absolute;
    inset: 2px;
    background: var(--color-on-ink);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    opacity: 0;
    scale: 0.6;
    transition: opacity 0.2s var(--ease-out), scale 0.2s var(--ease-out);
  }
  .addon:hover .addon__box { border-color: var(--color-ink); }
  .addon__check:checked + .addon__box { background: var(--color-ink); border-color: var(--color-ink); }
  .addon__check:checked + .addon__box::before { opacity: 1; scale: 1; }
  .addon__check:focus-visible + .addon__box { outline: 2px solid var(--color-dusty-blue-deep); outline-offset: 2px; }
  .addon__check:checked ~ .addons__price { color: var(--color-ink); }

  /* Quantity add-ons (data-addon-qty): the tick box and text, with a − n + picker beside them */
  .addons__list li.has-qty { flex-direction: row; align-items: center; gap: 12px; }
  .has-qty .addon { flex: 1 1 auto; min-width: 0; }
  .qty {
    display: inline-flex;
    flex: none;
    align-items: center;
    padding: 2px;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
  }
  .qty__btn {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    font: inherit;
    font-size: 16px;
    line-height: 1;
    color: var(--color-ink);
    cursor: pointer;
    transition: background-color 0.2s var(--ease-out);
  }
  .qty__btn:hover { background: var(--color-surface-soft); }
  .qty__input {
    width: 32px;
    padding: 0;
    border: 0;
    background: none;
    font-family: var(--font-mono);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    text-align: center;
    color: var(--color-ink);
    -moz-appearance: textfield;
    appearance: textfield;
  }
  .qty__input::-webkit-outer-spin-button,
  .qty__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  .qty__btn:focus-visible,
  .qty__input:focus-visible { outline: 2px solid var(--color-dusty-blue-deep); outline-offset: 1px; border-radius: 8px; }
  .qty__btn:focus-visible { border-radius: 50%; }

  /* Running estimate: pinned to the bottom of the screen while the add-ons are in view,
     then it settles under them */
  .estimate {
    position: sticky;
    bottom: 16px;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 14px 24px;
    margin-top: 20px;
    padding: 18px 24px;
    box-shadow: 0 0 0 1px var(--color-line), var(--shadow-card);
  }
  .estimate[hidden] { display: none; }
  .estimate__body { flex: 1 1 260px; min-width: 0; }
  .estimate__figure {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 10px;
    margin-top: 6px;
    font-size: 13px;
  }
  .estimate__figure b {
    font-size: clamp(24px, 2.6vw, 30px);
    font-weight: 400;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--color-ink);
    font-variant-numeric: tabular-nums;
  }
  .estimate__plan { margin-top: 4px; font-size: 13px; }
  @media (max-width: 639px) {
    .estimate { bottom: 10px; padding: 16px 18px; }
    .estimate__btn { flex: 1 1 100%; }
  }

  .fine-print {
    margin-top: 32px;
    font-size: 13px;
    text-align: center;
  }

  /* ---------- Why Choose Us: a dark panel with a web the pointer lights up ---------- */
  /* The panel keeps its own night palette (--w-*) in both themes. initWhyChooseUs() draws
     the web into both .why-us__web layers: faint everywhere, bright only in a circle round
     the pointer (--mx / --my). Each card tilts toward the pointer (--rx / --ry) and its edge
     lights up nearest it (--mouse-x / --mouse-y). */
  .why-us { padding-block: clamp(56px, 7vw, 112px); }
  /* Wider than the other sections: up to 1440px, with slimmer side margins */
  .why-us > .container-cube { width: min(1440px, 100% - 16px); }
  @media (min-width: 640px) {
    .why-us > .container-cube { width: min(1440px, 100% - 40px); }
  }
  .why-us__panel {
    --w-bg: #0b0c0f;
    --w-fg: #f4f5f7;
    --w-body: #a0a3ab;
    --w-muted: #80838b;
    --w-line: rgba(255, 255, 255, 0.08);
    --w-line-strong: rgba(255, 255, 255, 0.16);
    --w-good: #7fc8a0;
    --w-radius: clamp(26px, 3vw, 40px);
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: clamp(32px, 5.5vw, 76px) clamp(16px, 4.5vw, 64px) clamp(16px, 4.5vw, 64px);
    border-radius: var(--w-radius);
    background: radial-gradient(120% 60% at 50% 0%, #181a21 0%, var(--w-bg) 62%);
    color: var(--w-body);
  }
  [data-theme="dark"] .why-us__panel {
    --w-bg: #0f1115;
    box-shadow: inset 0 0 0 1px var(--w-line);
  }
  .why-us__panel :focus-visible { outline-color: var(--w-fg); }
  .why-us__panel h2,
  .why-us__panel h3 { color: var(--w-fg); }

  /* The panel opens out to full width as it scrolls in (where scroll-driven animations exist) */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .why-us__panel {
        animation: why-open linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 90%;
      }
    }
  }
  @keyframes why-open {
    from { clip-path: inset(0 8% round 72px); }
    to { clip-path: inset(0 0 round var(--w-radius)); }
  }

  /* The web, centred on the panel and spun in once it's on screen */
  .why-us__web {
    position: absolute;
    inset: 0;
    z-index: -2;
    color: var(--w-fg);
    opacity: 0.07;
    pointer-events: none;
  }
  .why-us__web svg {
    position: absolute;
    top: 46%;
    left: 50%;
    width: max(150%, 1300px);
    height: auto;
    translate: -50% -50%;
    overflow: visible;
  }
  .why-us__web path {
    fill: none;
    stroke: currentColor;
    stroke-width: var(--sw, 1); /* script.js keeps this at about a pixel */
    stroke-linecap: round;
  }
  .why-us__web--lit {
    opacity: 0;
    -webkit-mask-image: radial-gradient(300px circle at var(--mx, -999px) var(--my, -999px), #000, transparent);
    mask-image: radial-gradient(300px circle at var(--mx, -999px) var(--my, -999px), #000, transparent);
    transition: opacity 0.5s var(--ease-out);
  }
  .why-us__panel.is-lit .why-us__web--lit { opacity: 0.6; }
  .js .why-us__web path {
    stroke-dasharray: 1 2;
    stroke-dashoffset: 1.02;
    transition: stroke-dashoffset 1.8s var(--ease-out) calc(var(--i, 0) * 90ms);
  }
  .js .why-us__panel.is-visible .why-us__web path { stroke-dashoffset: 0; }
  @media (hover: none) {
    .why-us__web { opacity: 0.11; }
  }

  /* A soft coloured light that trails the pointer behind the cards */
  .why-us__glow {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    width: 560px;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(143, 165, 198, 0.2), rgba(217, 167, 150, 0.08) 55%, transparent);
    translate: calc(var(--mx, -999px) - 50%) calc(var(--my, -999px) - 50%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.6s var(--ease-out);
  }
  .why-us__panel.is-lit .why-us__glow { opacity: 1; }

  /* Heading */
  .why-us__head {
    display: grid;
    align-items: end;
    gap: 20px 56px;
    margin-bottom: clamp(32px, 4vw, 52px);
  }
  @media (min-width: 900px) {
    .why-us__head { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
  }
  .why-us__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 30px;
    margin-bottom: 22px;
    padding: 0 13px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.05);
    box-shadow: inset 0 0 0 1px var(--w-line-strong);
    font-size: 13px;
    font-weight: 500;
    color: var(--w-fg);
  }
  .why-us__title {
    font-size: clamp(36px, 5vw, 64px);
    line-height: 1.02;
    letter-spacing: -0.045em;
  }
  .why-us__title .accent .word {
    background: linear-gradient(100deg, var(--color-dusty-blue) 10%, var(--color-rose-gold) 90%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
  .why-us__lead {
    max-width: 30em;
    font-size: 16px;
    line-height: 1.65;
    text-wrap: pretty;
  }

  /* Stats: a row of numbers between hairlines, counted up by script.js */
  .why-us__stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-bottom: clamp(20px, 3vw, 32px);
    border-block: 1px solid var(--w-line);
  }
  .why-us__stats li {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: clamp(18px, 2.4vw, 26px) 12px clamp(18px, 2.4vw, 26px) clamp(14px, 2vw, 24px);
  }
  .why-us__stats li:nth-child(even) { border-left: 1px solid var(--w-line); }
  .why-us__stats li:nth-child(n + 3) { border-top: 1px solid var(--w-line); }
  @media (min-width: 760px) {
    .why-us__stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .why-us__stats li + li { border-left: 1px solid var(--w-line); }
    .why-us__stats li:nth-child(n + 3) { border-top: 0; }
    .why-us__stats li:first-child { padding-left: 4px; }
  }
  .why-us__stats b {
    font-size: clamp(32px, 3.8vw, 50px);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.045em;
    font-variant-numeric: tabular-nums;
    color: var(--w-fg);
  }
  .why-us__stats span {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--w-muted);
  }

  /* Bento grid: two wide cards, two narrow, interlocking */
  .why-us__grid {
    display: grid;
    gap: clamp(12px, 1.6vw, 20px);
  }
  @media (min-width: 640px) {
    .why-us__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .why-card--wide { grid-column: span 2; }
  }
  @media (min-width: 1000px) {
    .why-us__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  /* The cards rise in one after another instead of the grid fading as a whole */
  .js .why-us__grid.reveal { opacity: 1; transform: none; }
  .js .why-us__grid:not(.is-visible) .why-card { opacity: 0; translate: 0 56px; scale: 0.94; }

  .why-card {
    --rd: calc(var(--i, 0) * 120ms);
    position: relative;
    isolation: isolate;
    overflow: hidden;
    border-radius: 24px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.015));
    box-shadow: inset 0 0 0 1px var(--w-line);
    transform: perspective(1100px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
    transition: opacity 0.9s var(--ease-out) var(--rd), translate 1.1s var(--ease-out) var(--rd),
      scale 1.1s var(--ease-out) var(--rd), transform 0.5s var(--ease-out), background-color 0.4s var(--ease-out);
  }
  .why-card:hover { background-color: rgba(255, 255, 255, 0.02); }
  /* Its edge, lit where the pointer is nearest (cards near the pointer catch some too) */
  .why-card::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: 1px;
    border-radius: inherit;
    background: radial-gradient(300px circle at var(--mouse-x, -999px) var(--mouse-y, -999px),
      rgba(255, 255, 255, 0.75), rgba(217, 167, 150, 0.4) 35%, transparent 70%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s var(--ease-out);
  }
  /* and a soft light on its face */
  .why-card::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: radial-gradient(420px circle at var(--mouse-x, -999px) var(--mouse-y, -999px),
      rgba(255, 255, 255, 0.06), transparent 65%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s var(--ease-out);
  }
  .why-us__panel.is-lit .why-card::before,
  .why-card:hover::after { opacity: 1; }

  /* The big outlined number in the corner fills with colour on hover */
  .why-card__num {
    position: absolute;
    right: 0.06em;
    bottom: -0.22em;
    z-index: -1;
    font-size: clamp(120px, 13vw, 190px);
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.07em;
    color: transparent;
    -webkit-text-stroke: 1px rgba(255, 255, 255, 0.1);
    pointer-events: none;
    user-select: none;
    transition: color 0.6s var(--ease-out), -webkit-text-stroke-color 0.6s var(--ease-out), translate 0.8s var(--ease-out);
  }
  .why-card:hover .why-card__num {
    color: rgba(217, 167, 150, 0.06);
    -webkit-text-stroke-color: rgba(217, 167, 150, 0.45);
    translate: 0 -8px;
  }

  .why-card__inner {
    display: flex;
    flex-direction: column;
    gap: 24px;
    height: 100%;
    padding: clamp(16px, 2.4vw, 28px);
  }
  @media (min-width: 640px) {
    .why-card--wide .why-card__inner {
      display: grid;
      grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
      align-items: center;
      gap: clamp(20px, 3vw, 44px);
    }
  }
  .why-card__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 4px;
  }
  .why-card:not(.why-card--wide) .why-card__content { margin-top: auto; }
  .why-card__tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    padding: 5px 12px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.05);
    box-shadow: inset 0 0 0 1px var(--w-line-strong);
    font-size: 11.5px;
    font-weight: 500;
    color: var(--w-fg);
  }
  .why-card__title {
    font-size: clamp(22px, 2.4vw, 30px);
    line-height: 1.1;
    letter-spacing: -0.035em;
  }
  .why-card__text {
    max-width: 30em;
    font-size: 15px;
    line-height: 1.6;
  }
  .why-card__pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
  }
  .why-card__pills li {
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    box-shadow: inset 0 0 0 1px var(--w-line-strong);
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--w-body);
  }

  /* Each card's little demo sits in an inset screen */
  .why-card__stage {
    position: relative;
    overflow: hidden;
    border-radius: 16px;
    background: rgba(4, 5, 7, 0.55);
    box-shadow: inset 0 0 0 1px var(--w-line), inset 0 20px 40px -24px rgba(0, 0, 0, 0.8);
  }

  /* 01 — pen tool: dotted artboard, gradient curve, mirrored handles, live path data */
  .pen {
    padding: 14px 14px 0;
    background-image: radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1.3px);
    background-size: 18px 18px;
    background-position: 9px 9px;
    cursor: crosshair;
  }
  .pen__svg { width: 100%; height: auto; overflow: visible; }
  .pen__fill { fill: url(#why-pen-fill); transition: opacity 1s var(--ease-out) 0.9s; }
  .pen__curve {
    fill: none;
    stroke: url(#why-pen-stroke);
    stroke-width: 5;
    stroke-linecap: round;
    filter: drop-shadow(0 0 8px rgba(217, 167, 150, 0.35));
  }
  .js .pen__curve {
    stroke-dasharray: 1 2;
    stroke-dashoffset: 1.02;
    transition: stroke-dashoffset 1.6s var(--ease-out) 0.4s;
  }
  .js .why-us__grid:not(.is-visible) .pen__fill { opacity: 0; }
  .js .why-us__grid.is-visible .pen__curve { stroke-dashoffset: 0; }
  .pen__handle {
    fill: none;
    stroke: rgba(255, 255, 255, 0.5);
    stroke-width: 1.8;
    stroke-dasharray: 6 6;
  }
  .pen__knob { fill: var(--w-bg); stroke: var(--w-fg); stroke-width: 3; }
  .pen__anchor { fill: var(--w-bg); stroke: rgba(255, 255, 255, 0.65); stroke-width: 2.5; }
  .pen__anchor--on { fill: var(--w-fg); stroke: var(--w-fg); }
  .pen__cursor { transition: opacity 0.3s var(--ease-out); }
  .pen__cursor path { fill: var(--w-fg); stroke: var(--w-bg); stroke-width: 1.5; }
  .pen__cursor rect { fill: var(--color-rose-gold); }
  .pen__cursor text {
    font-family: var(--font-mono);
    font-size: 19px;
    font-weight: 500;
    text-anchor: middle;
    fill: #1a1210;
  }
  .pen:hover .pen__cursor { opacity: 0; }
  .pen__code {
    display: block;
    margin: 8px -14px 0;
    padding: 10px 16px;
    overflow: hidden;
    border-top: 1px solid var(--w-line);
    background: rgba(255, 255, 255, 0.025);
    font-family: var(--font-mono);
    font-size: 11.5px;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--w-body);
  }
  .pen__code::before { content: 'd = '; color: var(--color-rose-gold); }

  /* 02 — speed gauge */
  .gauge {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 16px 20px;
    padding: 18px;
  }
  .gauge__dial { position: relative; width: clamp(100px, 9vw, 120px); aspect-ratio: 1; }
  .gauge__dial svg { width: 100%; height: 100%; rotate: -90deg; overflow: visible; }
  .gauge__track,
  .gauge__ring { fill: none; stroke-width: 8; }
  .gauge__track { stroke: rgba(255, 255, 255, 0.07); }
  .gauge__ring {
    stroke: url(#why-gauge-grad);
    stroke-linecap: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 0;
    filter: drop-shadow(0 0 6px rgba(217, 167, 150, 0.5));
  }
  .gauge__score {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    text-align: center;
  }
  .gauge__score b {
    font-size: clamp(28px, 2.8vw, 36px);
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.05em;
    font-variant-numeric: tabular-nums;
    color: var(--w-fg);
  }
  .gauge__score small { font-family: var(--font-mono); font-size: 10px; color: var(--w-muted); }
  .gauge__metrics { display: grid; gap: 9px; }
  .gauge__metrics div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding-bottom: 7px;
    border-bottom: 1px dashed var(--w-line-strong);
  }
  .gauge__metrics dt {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.08em;
    color: var(--w-muted);
  }
  .gauge__metrics dd {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--w-fg);
  }
  .gauge__btn {
    grid-column: 1 / -1;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 15px;
    border-radius: var(--radius-pill);
    background: var(--w-fg);
    font-size: 12px;
    font-weight: 600;
    color: var(--w-bg);
    transition: translate 0.25s var(--ease-out), background-color 0.25s var(--ease-out), opacity 0.25s;
  }
  .gauge__btn:hover { translate: 0 -1px; background-color: #ffffff; }
  .gauge__btn:disabled { opacity: 0.6; cursor: progress; translate: none; }
  .gauge__btn.is-done { background-color: var(--w-good); }

  /* 03 — search results: yours climbs from third to first */
  .serp {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px;
  }
  .serp__search {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 36px;
    padding: 0 14px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.05);
    box-shadow: inset 0 0 0 1px var(--w-line);
    font-size: 12.5px;
    color: var(--w-muted);
  }
  .serp__query { color: var(--w-fg); }
  .serp__query::after {
    content: '';
    display: inline-block;
    width: 1px;
    height: 1.05em;
    margin-left: 2px;
    vertical-align: -0.18em;
    background: currentColor;
    animation: serp-caret 1s steps(1) infinite;
  }
  @keyframes serp-caret {
    50% { opacity: 0; }
  }
  .serp__list {
    --row: 48px;
    position: relative;
    height: calc(var(--row) * 3 - 6px);
  }
  .serp__row {
    position: absolute;
    inset: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    height: calc(var(--row) - 6px);
    padding: 0 12px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.03);
    box-shadow: inset 0 0 0 1px var(--w-line);
    translate: 0 calc(var(--r) * var(--row));
  }
  .serp__row--a { --r: 1; }
  .serp__row--b { --r: 2; }
  .serp__row--you {
    --r: 0;
    z-index: 1;
    background: linear-gradient(90deg, rgba(143, 165, 198, 0.2), rgba(217, 167, 150, 0.14)), var(--w-bg);
    box-shadow: inset 0 0 0 1px rgba(217, 167, 150, 0.5), 0 10px 24px -10px rgba(217, 167, 150, 0.35);
  }
  .serp__row i {
    flex: none;
    width: 22px;
    height: 22px;
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.08);
  }
  .serp__row--you i { background: linear-gradient(135deg, var(--color-dusty-blue), var(--color-rose-gold)); }
  .serp__row span {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
  }
  .serp__row b,
  .serp__row em { display: block; font-style: normal; }
  .serp__row:not(.serp__row--you) b { width: 64%; height: 7px; border-radius: 4px; background: rgba(255, 255, 255, 0.14); }
  .serp__row:not(.serp__row--you) em { width: 40%; height: 5px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); }
  .serp__row--you b { font-size: 13px; font-weight: 600; line-height: 1.1; color: var(--w-fg); }
  .serp__row--you em { font-family: var(--font-mono); font-size: 10.5px; line-height: 1; color: var(--w-good); }
  .serp__rank {
    padding: 3px 8px;
    border-radius: 7px;
    background: var(--w-fg);
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--w-bg);
  }
  /* script.js adds is-climbing (paused with is-held until the card is in view) */
  .serp.is-climbing .serp__row { animation: 2.8s var(--ease-out) both; }
  .serp.is-climbing .serp__row--a { animation-name: serp-a; }
  .serp.is-climbing .serp__row--b { animation-name: serp-b; }
  .serp.is-climbing .serp__row--you { animation-name: serp-you; }
  .serp.is-climbing .serp__rank { animation: serp-rank 2.8s var(--ease-out) both; }
  .serp.is-held :is(.serp__row, .serp__rank) { animation-play-state: paused; }
  @keyframes serp-you {
    0%, 22% { translate: 0 calc(2 * var(--row)); }
    42%, 60% { translate: 0 var(--row); }
    80%, 100% { translate: 0 0; }
  }
  @keyframes serp-b {
    0%, 22% { translate: 0 var(--row); }
    42%, 100% { translate: 0 calc(2 * var(--row)); }
  }
  @keyframes serp-a {
    0%, 60% { translate: 0 0; }
    80%, 100% { translate: 0 var(--row); }
  }
  @keyframes serp-rank {
    0%, 76% { opacity: 0; scale: 0.5; }
    90% { opacity: 1; scale: 1.15; }
    100% { opacity: 1; scale: 1; }
  }

  /* 04 — radar and status page */
  .status {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 18px;
    padding: 16px;
  }
  @media (max-width: 479px) {
    .status { grid-template-columns: 1fr; }
    .status__radar { justify-self: center; }
  }
  .status__radar {
    position: relative;
    width: clamp(110px, 11vw, 140px);
    aspect-ratio: 1;
    overflow: hidden;
    border-radius: 50%;
    background: repeating-radial-gradient(circle, transparent 0 19px, rgba(127, 200, 160, 0.14) 19px 20px), rgba(127, 200, 160, 0.03);
    box-shadow: inset 0 0 0 1px rgba(127, 200, 160, 0.3);
  }
  .status__radar::before,
  .status__radar::after {
    content: '';
    position: absolute;
    background: rgba(127, 200, 160, 0.14);
  }
  .status__radar::before { inset: 50% 0 auto; height: 1px; }
  .status__radar::after { inset: 0 auto 0 50%; width: 1px; }
  .status__sweep {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(transparent 280deg, rgba(127, 200, 160, 0.45));
    animation: status-sweep 4s linear infinite;
  }
  @keyframes status-sweep {
    to { rotate: 1turn; }
  }
  .status__shield {
    position: absolute;
    inset: 31%;
    z-index: 1;
    overflow: visible;
  }
  .status__shield path {
    fill: none;
    stroke: var(--w-fg);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .status__shield path + path { stroke: var(--w-good); }
  .status__blip {
    position: absolute;
    top: var(--y);
    left: var(--x);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--w-good);
    box-shadow: 0 0 10px var(--w-good);
    opacity: 0;
    animation: status-blip 4s ease-out var(--d) infinite;
  }
  @keyframes status-blip {
    0% { opacity: 1; scale: 1.3; }
    70%, 100% { opacity: 0; scale: 0.5; }
  }
  .status__board {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
  }
  .status__head {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 13px;
    font-weight: 500;
    color: var(--w-fg);
  }
  .status__dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--w-good);
    animation: status-ping 2s var(--ease-out) infinite;
  }
  @keyframes status-ping {
    from { box-shadow: 0 0 0 0 rgba(127, 200, 160, 0.6); }
    to { box-shadow: 0 0 0 9px rgba(127, 200, 160, 0); }
  }
  .status__pct {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--w-good);
  }
  .status__bars {
    display: flex;
    gap: 3px;
    height: 30px;
  }
  .status__bars i {
    flex: 1;
    border-radius: 2px;
    background: var(--w-good);
    opacity: 0.8;
    transform-origin: bottom;
    transition: scale 0.6s var(--ease-out) calc(var(--i) * 20ms + 500ms), opacity 0.2s;
  }
  .status__bars i:hover { opacity: 1; scale: 1 1.15; transition-delay: 0s; }
  .js .why-us__grid:not(.is-visible) .status__bars i { scale: 1 0; }
  .status__ecg { width: 100%; height: auto; overflow: visible; }
  .status__ecg path {
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .status__ecg-track { stroke: rgba(127, 200, 160, 0.18); }
  .status__ecg-pulse {
    stroke: var(--w-good);
    stroke-width: 2.2;
    stroke-dasharray: 16 84;
    filter: drop-shadow(0 0 5px rgba(127, 200, 160, 0.8));
    animation: status-ecg 2.6s linear infinite;
  }
  @keyframes status-ecg {
    from { stroke-dashoffset: 16; }
    to { stroke-dashoffset: -84; }
  }
  .status__regions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .status__regions li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px 3px 8px;
    border-radius: var(--radius-pill);
    box-shadow: inset 0 0 0 1px var(--w-line);
    font-family: var(--font-mono);
    font-size: 10.5px;
    color: var(--w-body);
  }
  .status__regions li::before {
    content: '';
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--w-good);
    box-shadow: 0 0 6px var(--w-good);
  }

  /* ---------- Contact ---------- */
  .enquiry {
    max-width: 760px;
    margin-inline: auto;
    padding: clamp(20px, 4vw, 40px);
  }
  .enquiry__grid { display: grid; gap: 20px; }
  @media (min-width: 640px) {
    .enquiry__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .field--full { grid-column: 1 / -1; }
  }
  .field { display: flex; flex-direction: column; gap: 8px; }
  .field label,
  .field__label {
    display: flex;
    gap: 4px;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-ink);
  }
  .field__opt { margin-left: auto; font-weight: 400; color: var(--color-body); }
  .field input,
  .field select,
  .field textarea {
    width: 100%;
    height: 44px;
    padding: 0 14px;
    background: var(--color-surface-soft);
    border: 1px solid var(--color-line);
    border-radius: 12px;
    font: inherit;
    font-size: 15px;
    color: var(--color-ink);
    transition: border-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), background-color 0.2s var(--ease-out);
  }
  .field textarea {
    height: auto;
    min-height: 140px;
    padding: 12px 14px;
    line-height: 1.5;
    resize: vertical;
  }
  .field input::placeholder,
  .field textarea::placeholder { color: var(--color-body); }
  .field select {
    appearance: none;
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%23696b70' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 8px;
    cursor: pointer;
  }
  .field input:hover,
  .field select:hover,
  .field textarea:hover { border-color: var(--color-line-strong); }
  .field input:focus,
  .field select:focus,
  .field textarea:focus {
    /* transparent outline still shows in forced-colors mode */
    outline: 2px solid transparent;
    background-color: var(--color-surface);
    border-color: var(--color-dusty-blue-deep);
    box-shadow: 0 0 0 4px rgba(143, 165, 198, 0.25);
  }
  .field [aria-invalid='true'] { border-color: var(--color-danger); }
  .field [aria-invalid='true']:focus { border-color: var(--color-danger); box-shadow: 0 0 0 4px rgba(180, 83, 63, 0.14); }
  .field__hint { font-size: 13px; }
  .field__error { display: none; font-size: 13px; color: var(--color-danger); }
  .field__error:not(:empty) { display: block; }
  .field.is-flash select,
  .field.is-flash .estimate-box { animation: flash 1.2s var(--ease-out); }

  /* The estimate carried over from Pricing: one row per item, total underneath */
  .field[data-estimate-field][hidden] { display: none; }
  .estimate-box {
    padding: 14px 16px;
    background: var(--color-surface-soft);
    border: 1px solid var(--color-line);
    border-radius: 12px;
    font-size: 14px;
  }
  .estimate-box__lines { display: grid; gap: 8px; }
  .estimate-box__lines li,
  .estimate-box__total {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 2px 16px;
    line-height: 1.5;
  }
  .estimate-box__lines li > :first-child { color: var(--color-ink); }
  .estimate-box__lines li > :last-child {
    font-family: var(--font-mono);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
  }
  .estimate-box__total {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--color-line);
    color: var(--color-ink);
  }
  .estimate-box__total b { font-weight: 500; font-variant-numeric: tabular-nums; }
  .estimate-box__edit {
    color: var(--color-ink);
    text-decoration: underline;
    text-decoration-color: var(--color-line-strong);
    text-underline-offset: 3px;
  }
  @keyframes flash {
    0%, 30% { border-color: var(--color-dusty-blue-deep); box-shadow: 0 0 0 4px rgba(143, 165, 198, 0.35); }
    100% { border-color: var(--color-line); box-shadow: 0 0 0 0 rgba(143, 165, 198, 0); }
  }
  .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

  .enquiry__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 28px;
  }

  .form-status {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin-top: 20px;
    padding: 14px 16px;
    border: 1px solid var(--color-line);
    border-radius: 14px;
    background: var(--color-surface-soft);
    font-size: 14px;
    color: var(--color-ink);
  }
  .form-status::before {
    content: '';
    flex: none;
    width: 8px;
    height: 8px;
    margin-top: 7px;
    border-radius: 50%;
    background: var(--color-body);
  }
  .form-status--success { background: rgba(79, 122, 97, 0.07); border-color: rgba(79, 122, 97, 0.28); }
  .form-status--success::before { background: var(--color-good); }
  .form-status--error { background: rgba(180, 83, 63, 0.05); border-color: rgba(180, 83, 63, 0.25); }
  .form-status--error::before { background: var(--color-danger); }
  .form-status--info { background: rgba(143, 165, 198, 0.12); border-color: rgba(143, 165, 198, 0.4); }
  .form-status--info::before { background: var(--color-dusty-blue-deep); }
  .form-status strong { display: block; font-weight: 500; }
  .form-status p { margin-top: 2px; color: var(--color-body); }
  .form-status a { text-decoration: underline; text-underline-offset: 2px; }

  .contact-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 32px;
    margin-top: 32px;
    font-size: 15px;
  }
  .contact-list li { display: flex; gap: 8px; }
  .contact-list a {
    font-weight: 500;
    color: var(--color-ink);
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: 3px;
    transition: text-decoration-color 0.2s var(--ease-out);
  }
  .contact-list a:hover { text-decoration-color: currentColor; }

  /* ---------- Footer ---------- */
  .footer {
    position: relative;
    isolation: isolate; /* keeps the corner cobweb (z-index: -1) inside the footer */
    overflow: hidden;
    padding-top: clamp(56px, 7vw, 88px);
  }
  .footer__inner { display: grid; gap: 48px; }
  @media (min-width: 900px) {
    .footer__inner { grid-template-columns: 1fr auto; }
  }
  .footer__brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }
  .footer__logo img { display: block; width: 104px; height: auto; }
  [data-theme="dark"] .footer__logo img { filter: invert(1); } /* the logo artwork is black */
  .footer__tagline { font-size: 14px; }
  .footer__brand .btn { margin-top: 10px; }

  .footer__nav { display: flex; flex-wrap: wrap; gap: 40px clamp(48px, 6vw, 88px); }
  .footer__h {
    font-size: 14px;
    line-height: 1.4;
    letter-spacing: -0.01em;
  }
  .footer__col ul { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
  .footer__col a {
    font-size: 14px;
    color: var(--color-body);
    transition: color 0.2s var(--ease-out);
  }
  .footer__col a:hover { color: var(--color-ink); }
  .footer__copy { grid-column: 1 / -1; padding-top: 24px; font-size: 13px; }

  /* Oversized wordmark fading into the page. Lowercase letters start about a quarter
     of the way down the line, so the fade starts there too. */
  .footer__word {
    margin: clamp(24px, 4vw, 48px) 0 -0.16em;
    font-size: clamp(80px, 22vw, 360px);
    font-weight: 500;
    line-height: 0.8;
    letter-spacing: -0.05em;
    text-align: center;
    color: transparent;
    background: linear-gradient(180deg, var(--color-word) 25%, transparent 90%);
    -webkit-background-clip: text;
    background-clip: text;
    user-select: none;
  }
  /* Split into letters by script.js: they rise out of the page edge one after another
     when the footer comes into view, and each letter carries the fade itself */
  .footer__word.is-split { background: none; }
  .footer__word.is-split .char {
    background: linear-gradient(180deg, var(--color-word) 25%, transparent 90%);
    -webkit-background-clip: text;
    background-clip: text;
    transition: transform 1.2s var(--ease-out) calc(var(--i) * 55ms), translate 0.5s var(--ease-out);
  }
  .js .footer__word.is-split:not(.is-visible) .char { transform: translateY(110%); }
  .footer__word.is-split .char:hover { translate: 0 -0.07em; }

  /* ---------- Motion ---------- */
  /* Looping decorations stop while they're off screen (script.js toggles is-offscreen) */
  .is-offscreen,
  .is-offscreen * { animation-play-state: paused !important; }

  .js .reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
    transition-delay: var(--delay, 0ms);
  }
  .js .reveal.is-visible { opacity: 1; transform: none; }

  /* The badge leads; the lead text and buttons follow the title */
  .js [data-hero-step] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
    transition-delay: calc(var(--i, 0) * 400ms + 60ms);
  }
  .js .is-loaded [data-hero-step] { opacity: 1; transform: none; }

  /* Reduced motion: everything shows in its finished state and nothing drifts */
  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      transition-delay: 0ms !important;
    }
    .js .reveal, .js [data-hero-step] { opacity: 1; transform: none; }
    .js [data-split-words] .word,
    .js .hero__brand .char { opacity: 1; transform: none; }
    .js .about__body { --p: 1 !important; }
    .about__mark.is-scuttling .spider__leg { animation: none; }
    .js .card-container .work-card__media,
    .js .project .project__media { clip-path: none; }
    .js .card-container .work-card__scroll { scale: none; }
    .work-card__scroll,
    .project__scroll { translate: none !important; animation: none !important; }
    .js .footer__word.is-split:not(.is-visible) .char { transform: none; }
    .js .why-us__grid:not(.is-visible) .why-card { opacity: 1; translate: none; scale: none; }
    .why-card { transform: none; }
    .marquee__track {
      flex-wrap: wrap;
      justify-content: center;
      row-gap: 12px;
      width: auto;
      padding-inline: 16px;
    }
    .marquee__track .is-clone { display: none; }
  }
}

/* Registered (at the top level, outside the layers) so the cobweb spider's thread can
   animate and transition: --bob drives the bobbing, --lift the climb (see .cobweb__drop) */
@property --bob {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}
@property --lift {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}
