/* ============================================================
   ALBERT DUNGLISON DESIGN — styles.css
   Brand: Black / Lime (#CCFF00) / White
   Fonts: Provicali (display) · Readfine (UI) · Manrope (body) · Fraunces (italic accent)
============================================================ */

/* ── READFINE (UI / display sans) ───────────────────────── */
@font-face {
  font-family: 'Readfine';
  src: url('assets/fonts/readfine/ReadfineDemo.ttf') format('truetype');
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

/* ── PROVICALI (display headline) ───────────────────────── */
@font-face {
  font-family: 'Provicali';
  src: url('assets/fonts/provicali/Provicali.otf') format('opentype');
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

/* ── CUSTOM PROPERTIES ──────────────────────────────────── */
:root {
  --black:       #000000;
  --white:       #ffffff;
  --lime:        #CCFF00;
  --surface:     #0d0d0d;
  --surface-2:   #141414;
  --border:      #222222;

  /* WCAG AA-compliant text colors (all ≥ 4.5:1 on #000) */
  --text-primary:    #ffffff;                /* 21:1 */
  --text-secondary:  rgba(255,255,255,0.72); /* ≈ 9.4:1 */
  --text-tertiary:   rgba(255,255,255,0.55); /* ≈ 5.9:1 */
  --text-muted:      rgba(255,255,255,0.50); /* ≈ 5.0:1 */

  --font-head:   'Provicali', 'Anton', 'Bebas Neue', sans-serif;
  --font-ui:     'Readfine', 'Manrope', sans-serif;
  --font-body:   'Manrope', sans-serif;
  /* Fourth voice — a refined display serif (Fraunces) reserved for italic
     editorial moments only: the "Real design." accent + the lead drop cap.
     Used sparingly so it stays a punctuation mark in the type system. */
  --font-serif:  'Fraunces', 'GT Sectra', 'Bodoni Moda', 'Georgia', serif;

  /* Shadow scale (warning fix) */
  --shadow-sm:  0 2px 8px   rgba(0,0,0,0.35);
  --shadow-md:  0 6px 20px  rgba(0,0,0,0.45);
  --shadow-lg:  0 20px 50px rgba(0,0,0,0.55);
  --shadow-glow-sm: 0 6px 22px rgba(204,255,0,0.10);
  --shadow-glow-md: 0 18px 45px rgba(204,255,0,0.12);

  --nav-h:       170px;
  --nav-h-sm:    112px;

  --max-w:       1200px;
  --pad:         clamp(1.25rem, 5vw, 4rem);
  --section-py:  clamp(5rem, 12vw, 9rem);

  --radius:      3px;
  --radius-pill: 999px;
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-out:    cubic-bezier(0.4, 0, 0.2, 1);
  --dur:         0.28s;

  /* Shared focus ring */
  --focus-ring:  0 0 0 2px var(--black), 0 0 0 4px var(--lime);
}

/* Skip link — keyboard-only escape to main content */
.skip-link {
  position: absolute;
  left: 1rem;
  top: 1rem;
  z-index: 10000;
  padding: 0.875rem 1.5rem;
  background: var(--lime);
  color: var(--black);
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 1.0625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  border-radius: var(--radius);
  transform: translateY(-150%);
  transition: transform var(--dur) var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

/* ── RESET ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* overflow-x: clip on the root clips decorative stars that bleed past the
   viewport edge without creating a scroll context (unlike overflow: hidden,
   which can break sticky/anchor scroll behaviours). */
html {
  scroll-behavior: auto; /* Lenis owns smooth scroll */
  overflow-x: clip;
}
body {
  font-family: var(--font-body);
  background: var(--black);
  color: var(--white);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Brand-coloured form controls (checkboxes, radios, scroll markers). One
     CSS line, but every native control now picks up lime instead of the
     OS-default purple-blue. */
  accent-color: var(--lime);
}

/* Lime text selection — a small, memorable detail every visitor will see
   the first time they highlight a price or copy an email. Generic AI
   defaults leave this as the OS blue; we lean into the brand. */
::selection      { background: var(--lime); color: var(--black); text-shadow: none; }
::-moz-selection { background: var(--lime); color: var(--black); text-shadow: none; }

/* Page scrollbar (WebKit) — narrow, transparent track, lime-on-hover
   thumb. Matches the work-strip's scrollbar treatment so the whole
   product feels lit by the same accent. */
@supports selector(::-webkit-scrollbar) {
  html { scrollbar-color: rgba(204,255,0,0.25) transparent; scrollbar-width: thin; }
  html::-webkit-scrollbar          { width: 10px; }
  html::-webkit-scrollbar-track    { background: var(--black); }
  html::-webkit-scrollbar-thumb    {
    background: rgba(204,255,0,0.18);
    border: 2px solid var(--black);
    border-radius: var(--radius-pill);
    transition: background var(--dur) var(--ease-out);
  }
  html::-webkit-scrollbar-thumb:hover { background: rgba(204,255,0,0.40); }
}
/* Subtle film-grain noise overlay — barely visible, adds tactile depth */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 300px 300px;
}

/* Cosmic edge vignette — the corners darken just enough that the eye is
   gently steered toward the centre of every page section. Sits over the
   starfield but under content (z: 1, content is z: 1+). */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 110% 80% at 50% 50%, transparent 55%, rgba(0,0,0,0.55) 100%);
}
img { display: block; max-width: 100%; }
a   { text-decoration: none; color: inherit; }
button { cursor: pointer; border: none; background: none; font: inherit; }
ul  { list-style: none; }

/* ── TYPOGRAPHY ─────────────────────────────────────────── */
/* Anton is a tall condensed display sans with proper lowercase.
   Use natural sentence case in markup, no text-transform here. */
.section-heading {
  font-family: var(--font-head);
  /* Magazine-scale headlines: clamp pushes the top end to ~136px on a
     desktop so the type becomes the spatial event of each section. */
  font-size: clamp(3.25rem, 10vw, 8.5rem);
  line-height: 1.0;
  letter-spacing: 0.005em;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
  /* Heavier shadow on the big type so the headline still sits above the
     starfield at this size. Two layered shadows = ambient + contact. */
  text-shadow:
    0 1px 0 rgba(255,255,255,0.04),
    0 18px 36px rgba(0,0,0,0.55),
    0 6px 12px rgba(0,0,0,0.45);
}

/* Editorial section kicker — small lime label sitting above the headline
   like a magazine running-header: "01 · Identity". The hairline rule
   between them is a single 1px element that grows on intersect. */
.section-kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: clamp(1.25rem, 2.4vw, 1.75rem);
  font-family: var(--font-ui);
  font-size: clamp(0.875rem, 1.05vw, 1rem);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--lime);
  /* Tabular nums so 01 / 02 / 03 / 04 always sit on the same axis. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.kicker-num   { font-weight: 400; }
.kicker-rule  { display: inline-block; width: 38px; height: 1px; background: var(--lime); opacity: 0.65; }
.kicker-label { color: var(--text-secondary); letter-spacing: 0.28em; }
.contact-header { text-align: left; }
.contact-header .section-kicker { margin-bottom: 0.875rem; }

/* ── LAYOUT ─────────────────────────────────────────────── */
.container {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* ── BUTTONS ────────────────────────────────────────────── */
/* Slim hug-the-text padding so the lime fill sits close to the wordmark
   — text size is unchanged, only the chrome around it shrinks. Asymmetric
   vertical padding (top > bottom) compensates for uppercase Readfine
   sitting visually high inside its line-box. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 1.35rem 0.45rem;
  font-family: var(--font-ui);
  font-size: 1.75rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  border-radius: var(--radius);
  transition:
    transform 0.22s var(--ease-spring),
    box-shadow var(--dur) var(--ease-out);
}

.btn--lime {
  background: var(--lime);
  color: var(--black);
  /* Layered depth so the button reads as a lit chip sitting above the page,
     not a flat fill. Inner highlight (top) + soft drop-shadow (bottom). */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.45),
    inset 0 -1px 0 rgba(0,0,0,0.18),
    0 10px 22px rgba(204,255,0,0.10),
    0 2px 6px rgba(0,0,0,0.30);
}

.btn--lime:hover  {
  transform: translateY(-2px) scale(1.035);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.5),
    inset 0 -1px 0 rgba(0,0,0,0.22),
    0 18px 32px rgba(204,255,0,0.18),
    0 6px 14px rgba(0,0,0,0.35);
}
.btn--lime:active { transform: translateY(0) scale(0.97); }
.btn--lime:focus-visible { outline: none; box-shadow: var(--focus-ring); }


/* ════════════════════════════════════════════════════════
   NAVIGATION — separated floating glass pills
   (No full-width header block; each element is its own surface)
════════════════════════════════════════════════════════ */
#nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 200;
  height: var(--nav-h);
  pointer-events: none; /* let the page receive events; pills opt back in */
  transition: height var(--dur) var(--ease-out);
}

#nav.scrolled { height: var(--nav-h-sm); }

.nav-inner {
  padding: 1.25rem var(--pad) 0;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
}

/* Each pill cluster opts back into pointer events */
.nav-pill, .nav-logo, .nav-burger { pointer-events: auto; }

/* Glass-pill — used for both link clusters.
   Slim vertical padding; align-items: center keeps the link text
   dead-centred on the pill's vertical axis. */
.nav-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.75rem, 3.5vw, 3rem);
  padding: 0.5rem 1.75rem;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-pill);
  background: rgba(8,8,8,0.32);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  transition:
    border-color var(--dur) var(--ease-out),
    background var(--dur) var(--ease-out);
}

#nav.scrolled .nav-pill {
  border-color: rgba(255,255,255,0.12);
  background: rgba(8,8,8,0.45);
}

.nav-pill--left  { justify-self: start; }
.nav-pill--right { justify-self: end;   }

/* Logo — bare floating element with a thin shape-tracing outline */
/* drop-shadow filters cast from the PNG's alpha, so the outline follows */
/* the actual silhouette of the star + wordmark, not a circle/pill. */
.nav-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  transition: filter 0.35s var(--ease-out);
}
/* Defocused state: applied by JS while the user is hovering ANY other
   interactive element on the page. The logo eases out of focus instead
   of disappearing, reinforcing that the hovered element is the subject. */
.nav-logo.is-defocused .nav-logo-img {
  filter:
    blur(2.5px)
    drop-shadow( 1px  0   0 rgba(255,255,255,0.10))
    drop-shadow(-1px  0   0 rgba(255,255,255,0.10))
    drop-shadow( 0    1px 0 rgba(255,255,255,0.10))
    drop-shadow( 0   -1px 0 rgba(255,255,255,0.10));
  opacity: 0.55;
}
.nav-logo-img {
  height: 132px;
  width: auto;
  transition:
    height var(--dur) var(--ease-out),
    filter 0.35s var(--ease-out),
    opacity 0.35s var(--ease-out);
  /* 1px white silhouette + a layered drop-shadow underneath gives the
     logo gentle lift off the page — same atmospheric depth as the cards. */
  filter:
    drop-shadow( 1px  0   0 rgba(255,255,255,0.20))
    drop-shadow(-1px  0   0 rgba(255,255,255,0.20))
    drop-shadow( 0    1px 0 rgba(255,255,255,0.20))
    drop-shadow( 0   -1px 0 rgba(255,255,255,0.20))
    drop-shadow( 0   18px 22px rgba(0,0,0,0.45))
    drop-shadow( 0    4px  8px rgba(0,0,0,0.35));
}
#nav.scrolled .nav-logo-img {
  height: 84px;
  filter:
    drop-shadow( 1px  0   0 rgba(255,255,255,0.28))
    drop-shadow(-1px  0   0 rgba(255,255,255,0.28))
    drop-shadow( 0    1px 0 rgba(255,255,255,0.28))
    drop-shadow( 0   -1px 0 rgba(255,255,255,0.28))
    drop-shadow( 0   10px 18px rgba(0,0,0,0.45));
}
.nav-logo:focus-visible {
  outline: none;
}
.nav-logo:focus-visible .nav-logo-img {
  filter:
    drop-shadow( 1px  0   0 var(--lime))
    drop-shadow(-1px  0   0 var(--lime))
    drop-shadow( 0    1px 0 var(--lime))
    drop-shadow( 0   -1px 0 var(--lime));
}

/* Nav links inside the pill — bumped for readability */
.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(1.75rem, 3.5vw, 3.25rem);
}

.nav-links a {
  font-family: var(--font-ui);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary);
  transition: color var(--dur) var(--ease-out);
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0;
  line-height: 1;
}

.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -3px;
  left: 0;
  width: 0;
  height: 1px;
  background: var(--lime);
  transition: width var(--dur) var(--ease-out);
}

.nav-links a:hover,
.nav-links a[aria-current="page"] { color: var(--text-primary); }
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after { width: 100%; }
.nav-links a:focus-visible {
  outline: none;
  color: var(--lime);
  box-shadow: 0 2px 0 0 var(--lime);
  border-radius: 1px;
}

/* Right cluster — sits in the third grid column */
.nav-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  justify-self: end;
}

/* Hamburger — 44×44 touch target, own pill on scroll */
.nav-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255,255,255,0.08);
  background: rgba(8,8,8,0.32);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: border-color var(--dur) var(--ease-out);
}
.nav-burger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.nav-burger span {
  display: block;
  width: 20px;
  height: 1.5px;
  background: var(--white);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur);
  transform-origin: center;
}
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { transform: translateY(-6.5px) rotate(-45deg); }

/* Mobile menu */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: var(--black);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-out);
}
.mobile-menu.open { opacity: 1; pointer-events: all; }
.mobile-menu ul { display: flex; flex-direction: column; align-items: center; gap: 1.75rem; }

.mobile-link {
  font-family: var(--font-head);
  font-size: clamp(2.75rem, 11vw, 4.5rem);
  letter-spacing: 0.012em;
  line-height: 1.1;
  transition: color var(--dur) var(--ease-out);
}
.mobile-link:hover { color: var(--lime); }
.mobile-link:focus-visible {
  outline: none;
  color: var(--lime);
  text-shadow: 0 0 24px rgba(204,255,0,0.4);
}

@media (max-width: 719px) {
  :root { --nav-h: 114px; --nav-h-sm: 84px; }
  .nav-pill             { display: none; }
  .nav-burger           { display: flex; }
  .nav-right            { justify-content: flex-end; }
  .nav-logo-img         { height: 86px; }
  #nav.scrolled .nav-logo-img { height: 62px; }
}


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

   Layout intent:
     • The hero is the full svh.
     • The marquee pins to the bottom (fixed offset).
     • The nav sits in the top --nav-h band.
     • hero-content must visually sit centred *between the bottom edge
       of the logo and the top edge of the marquee*. We do that by giving
       the hero matching top padding (= --nav-h) and bottom padding (=
       marquee-h ~120px), then justify-content: center on a flex column.
     • The tagline, sub, and CTA are evenly distributed inside that
       column via flex + a single shared gap value.
════════════════════════════════════════════════════════ */
#hero {
  position: relative;
  height: 100svh;
  min-height: 600px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Top pad = full nav band so content starts below the logo.
     Bottom pad = marquee strip (~30px tall) + its 48px offset + a touch
     of breathing room. Together they centre the inner group between
     logo and marquee. */
  padding-top: var(--nav-h);
  padding-bottom: 120px;
  /* Clip horizontally only — page width stays tight, but the big
     .hero-star is free to bleed vertically without a hard cut edge. */
  overflow-x: clip;
}

/* Subtle radial glow behind tagline */
#hero::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 70vw;
  max-width: 800px;
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(204,255,0,0.04) 0%, transparent 70%);
  pointer-events: none;
}

.hero-content {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 0 var(--pad);
  /* Inner stack: each element is its own flex item, gap controls the
     even rhythm between tagline → sub → CTA. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 3.2vw, 2.5rem);
}

.hero-tagline {
  font-family: var(--font-head);
  font-size: clamp(2.8rem, 7vw, 5.8rem);
  /* Per skill: tight tracking on large display headlines. Pulled in from
     1.1 → 1.04 line-height and 0.012em → -0.005em tracking. Subtle, but
     gives the headline more density and confidence. Easy to revert. */
  line-height: 1.04;
  letter-spacing: -0.005em;
  margin: 0;
  /* Subtle depth on the headline so it sits above the starfield, not
     painted onto it. Two stacked drop-shadows = soft ambient + crisper
     contact shadow. */
  text-shadow:
    0 1px 0 rgba(255,255,255,0.04),
    0 14px 28px rgba(0,0,0,0.55),
    0 4px 10px rgba(0,0,0,0.45);
}

.hero-tagline .tl { display: block; }
.hero-tagline .accent { color: var(--lime); }
/* Fraunces italic for the "Real design." line — a refined serif as a
   single punctuation voice against the chunky Provicali. Sized slightly
   larger because serifs read smaller at the same px value. */
.hero-tagline .accent--italic {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-size: 1.06em;       /* compensate for serif x-height vs Provicali */
  font-feature-settings: "ss01" 1, "ss02" 1; /* Fraunces stylistic alts (curly g, etc.) */
}

.hero-sub {
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: clamp(1.25rem, 2vw, 1.625rem);
  line-height: 1.45;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
  margin: 0;
  text-shadow: 0 6px 14px rgba(0,0,0,0.40);
}
/* Lime-tinted closing words — same brand lime, slight opacity drop so
   it harmonises with the surrounding muted text instead of shouting. */
.hero-sub-accent {
  color: var(--lime);
  opacity: 0.82;
}
@media (max-width: 540px) {
  .hero-sub { white-space: normal; max-width: 26ch; }
}

.hero-cta { margin: 0; }

/* Marquee */
.marquee-wrap {
  position: absolute;
  bottom: 48px;
  left: 0;
  right: 0;
  overflow: hidden;
  padding: 0.65rem 0;
}

.marquee-track {
  display: flex;
  width: max-content;
  will-change: transform;
}

.marquee-set {
  display: inline-flex;
  align-items: center;
  gap: 2.25rem;
  padding-right: 2.25rem;
  flex-shrink: 0;
  font-family: var(--font-ui);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary);
  /* Reset line-height to 1 so the flex line-box equals the cap-height —
     stars then align to true optical centre rather than the baseline+descender. */
  line-height: 1;
}

.marquee-set > span {
  /* Hold spans on the same line-box and lift them so the visual centre
     of the lowercase x-height matches the centre of the lime star icons. */
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

/* Stars sit on uppercase Readfine — uppercase has no descenders, so the
   visible cap-height centre is ~2px ABOVE the flex-box centre. Translate
   up by 2px so the star lands on the optical centre of the caps, not the
   line-box centre. (Measured: align-items:center alone put star ~1px
   below cap-mid; -2px overshoots into perfect mid.) */
.marquee-star {
  flex-shrink: 0;
  opacity: 0.92;
  align-self: center;
  transform: translateY(-2px);
  filter: drop-shadow(0 2px 4px rgba(204,255,0,0.25));
}


/* Scroll cue */
.scroll-cue {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  color: var(--text-muted);
  animation: cue-bounce 2.2s ease-in-out infinite;
}

@keyframes cue-bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%       { transform: translateX(-50%) translateY(7px); }
}

/* Faint outline star — bottom-left background accent */
.hero-star {
  position: absolute;
  bottom: -80px;
  left: -60px;
  width: 600px;
  will-change: transform;
  height: 600px;
  opacity: 0.11;
  z-index: 0;
  pointer-events: none;
}


/* ════════════════════════════════════════════════════════
   ABOUT
════════════════════════════════════════════════════════ */
#about {
  position: relative;
  padding: var(--section-py) 0;
  /* Clip horizontally only — keeps section width tight so no page scroll,
     but lets decorative stars bleed VERTICALLY into adjacent sections
     instead of being hard-cut at the section boundary. */
  overflow-x: clip;
}

.about-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  align-items: center;
}

@media (min-width: 768px) {
  .about-grid {
    grid-template-columns: 1fr 1fr;
    gap: clamp(3rem, 6vw, 5rem);
  }
}

.about-text .section-heading { margin-bottom: 1.5rem; }

.about-body {
  font-size: clamp(1rem, 1.5vw, 1.125rem);
  line-height: 1.8;
  color: var(--text-secondary);
  max-width: 540px;
}
.about-text .about-body + .about-body { margin-top: 1.25rem; }

.about-subheading {
  font-family: var(--font-ui);
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--lime);
  margin-top: 2.5rem;
  margin-bottom: 1.25rem;
  position: relative;
  padding-left: 1.25rem;
}
.about-subheading::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--lime);
  transform: translateY(-50%) rotate(45deg);
}

/* On wider screens, give the text column more breathing room
   so the longer About Me copy doesn't feel crowded by the photo */
@media (min-width: 900px) {
  .about-grid {
    grid-template-columns: 1.4fr 1fr;
    align-items: start;
    gap: clamp(3rem, 6vw, 5rem);
  }
  .about-text { padding-top: 0.25rem; }
}

/* Photo placeholder — parallax target */
.about-photo {
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.about-photo-img {
  display: block;
  width: 100%;
  aspect-ratio: 4/5;
  object-fit: cover;
  object-position: center;
}


/* ════════════════════════════════════════════════════════
   SERVICES
════════════════════════════════════════════════════════ */
#services {
  position: relative;
  padding: var(--section-py) 0;
  /* Clip horizontally only — keeps section width tight so no page scroll,
     but lets decorative stars bleed VERTICALLY into adjacent sections
     instead of being hard-cut at the section boundary. */
  overflow-x: clip;
}

.services-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}

@media (min-width: 768px) {
  .services-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Card */
.service-card {
  position: relative;
  /* Slight vertical gradient + inner top highlight + cast shadow gives
     each card a subtle "lit from above, sitting above the page" feel.
     The cards still sit close to the surface — not floating — just enough
     depth that they don't read as flat decals on the starfield. */
  background:
    linear-gradient(180deg, #121212 0%, #050505 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2.25rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 22px 40px rgba(0,0,0,0.45),
    0 4px 10px rgba(0,0,0,0.35);
  transition:
    border-color var(--dur) var(--ease-out),
    transform 0.26s var(--ease-spring),
    box-shadow var(--dur) var(--ease-out);
}

.service-card:hover {
  border-color: var(--lime);
  transform: translateY(-8px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    var(--shadow-glow-md),
    0 30px 50px rgba(0,0,0,0.55),
    0 8px 14px rgba(0,0,0,0.45);
}

.service-card--featured { border-color: rgba(204,255,0,0.25); }

.card-badge {
  position: absolute;
  top: -12px;
  left: 2rem;
  background: var(--lime);
  color: var(--black);
  font-family: var(--font-ui);
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: 2px;
}

.card-top {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  padding-bottom: 1.125rem;
  border-bottom: 1px solid var(--border);
}

.card-name {
  font-family: var(--font-head);
  font-size: clamp(1.375rem, 1.5vw, 1.625rem);
  letter-spacing: 0.015em;
  line-height: 1.15;
}

.card-price {
  font-family: var(--font-head);
  font-size: 1.5rem;
  color: var(--lime);
  white-space: nowrap;
  line-height: 1;
  /* Tabular figures so prices align by column when stacked side-by-side.
     Subtle typographic precision — most pages don't bother. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.card-freq {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
}

.card-desc {
  font-size: 0.9375rem;
  line-height: 1.72;
  color: var(--text-secondary);
  flex: 1;
}

.card-link {
  font-family: var(--font-ui);
  font-size: 1.125rem;
  font-weight: 400;
  color: var(--lime);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  transition: letter-spacing var(--dur) var(--ease-out), opacity var(--dur);
  align-self: flex-start;
  /* 12px top + ~20px line-height + 12px bottom = ~44px hit area, matching
     the WCAG / Apple HIG / Material minimum for touch targets on phones. */
  padding: 0.75rem 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  line-height: 1;
}

/* Trailing arrow on the card-link gets its own transition target so it
   nudges right when the link is hovered/focused — a tiny, high-craft
   motion cue that costs nothing visually but signals "go". */
.card-link .arrow {
  display: inline-block;
  transition: transform 0.22s var(--ease-spring);
  will-change: transform;
}

.card-link:hover                 { letter-spacing: 0.16em; }
.card-link:hover .arrow          { transform: translateX(4px); }
.card-link:focus-visible {
  outline: none;
  box-shadow: 0 2px 0 0 var(--lime);
  letter-spacing: 0.16em;
}
.card-link:focus-visible .arrow  { transform: translateX(4px); }

/* Lift card whenever a focusable child receives focus */
.service-card:focus-within {
  border-color: var(--lime);
  transform: translateY(-8px);
  box-shadow: var(--shadow-glow-md), var(--shadow-md);
}


/* ════════════════════════════════════════════════════════
   SELECTED WORK — horizontally scrolling Instagram-style strip
════════════════════════════════════════════════════════ */
#work {
  position: relative;
  padding: var(--section-py) 0;
  /* Clip horizontally only — keeps section width tight so no page scroll,
     but lets decorative stars bleed VERTICALLY into adjacent sections
     instead of being hard-cut at the section boundary. */
  overflow-x: clip;
}


.work-strip {
  position: relative;
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 1rem 0;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--pad);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(204,255,0,0.35) transparent;
}
.work-strip::-webkit-scrollbar { height: 6px; }
.work-strip::-webkit-scrollbar-track { background: transparent; }
.work-strip::-webkit-scrollbar-thumb {
  background: rgba(204,255,0,0.25);
  border-radius: var(--radius-pill);
}
.work-strip::-webkit-scrollbar-thumb:hover { background: rgba(204,255,0,0.45); }

.work-strip-inner {
  display: flex;
  gap: clamp(0.875rem, 1.5vw, 1.25rem);
  padding: 0 var(--pad);
  width: max-content;
}

.work-tile {
  position: relative;
  flex-shrink: 0;
  width: clamp(220px, 28vw, 320px);
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 1rem;
  background:
    radial-gradient(circle at 28% 22%, rgba(204,255,0,0.05) 0%, transparent 60%),
    linear-gradient(180deg, #161616 0%, #0a0a0a 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  scroll-snap-align: start;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 14px 28px rgba(0,0,0,0.45),
    0 3px 6px rgba(0,0,0,0.30);
  transition:
    transform 0.32s var(--ease-spring),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

/* When a real image is dropped in:
   set background-image: url('brand_assets/work/<slot>.jpg') via inline style
   or extend this rule per-slot. Hint text auto-hides via the empty-state below. */

/* Hover */
.work-tile:hover {
  transform: translateY(-4px);
  border-color: rgba(204,255,0,0.30);
  box-shadow: var(--shadow-glow-sm), var(--shadow-md);
}
.work-tile:focus-visible {
  outline: none;
  border-color: var(--lime);
  box-shadow: var(--focus-ring);
}

/* Lime ribbon overlay reveals on hover */
.work-tile::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(0,0,0,0.7) 100%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}
.work-tile:hover::before { opacity: 1; }

.work-tile-label {
  position: relative;
  z-index: 2;
  font-family: var(--font-ui);
  font-size: 1.125rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-primary);
  line-height: 1.15;
}
.work-tile-label em {
  color: var(--lime);
  font-style: normal;
  margin: 0 0.4em;
}

.work-tile-hint {
  position: relative;
  z-index: 2;
  margin-top: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-tertiary);
  opacity: 0.85;
}

/* Edge fades so tiles bleed off-screen rather than cut hard */
.work-strip-edge {
  position: absolute;
  top: 0; bottom: 0;
  width: clamp(2rem, 6vw, 5rem);
  pointer-events: none;
  z-index: 3;
}
.work-strip-edge--left  { left: 0;  background: linear-gradient(90deg, var(--black), transparent); }
.work-strip-edge--right { right: 0; background: linear-gradient(-90deg, var(--black), transparent); }


/* ════════════════════════════════════════════════════════
   CONTACT
════════════════════════════════════════════════════════ */
#contact {
  position: relative;
  padding: var(--section-py) 0;
  /* Clip horizontally only — keeps section width tight so no page scroll,
     but lets decorative stars bleed VERTICALLY into adjacent sections
     instead of being hard-cut at the section boundary. */
  overflow-x: clip;
}

.contact-wrap {
  max-width: 700px;
  margin: 0 auto;
}

.contact-header { margin-bottom: 2.75rem; }
.contact-header .section-heading { margin-bottom: 0.875rem; }

.contact-sub {
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--text-tertiary);
}
.contact-direct {
  margin-top: 0.9rem;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: var(--text-tertiary);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
}
.contact-direct a {
  color: var(--lime);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
  transition: opacity var(--dur) var(--ease-out);
}
.contact-direct a:hover { opacity: 0.75; }
.contact-direct-sep {
  color: var(--text-tertiary);
  opacity: 0.5;
}

/* Form */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
  margin-bottom: 2.75rem;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.125rem;
}

@media (min-width: 540px) {
  .form-row { grid-template-columns: 1fr 1fr; }
}

.field-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.field-group label {
  font-family: var(--font-ui);
  font-size: 1.125rem;
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary);
  line-height: 1;
}
.field-group label .req {
  color: var(--lime);
  margin-left: 0.15em;
}

.field-group input,
.field-group textarea {
  background: var(--black);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.875rem 1rem;
  font-family: var(--font-body);
  font-size: 1rem; /* 16px — prevents iOS Safari auto-zoom on focus */
  color: var(--white);
  /* Lime caret — tiny brand touch that surprises the moment a user clicks
     into a field. Falls back gracefully where caret-color isn't supported. */
  caret-color: var(--lime);
  width: 100%;
  outline: none;
  resize: vertical;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.field-group input::placeholder,
.field-group textarea::placeholder { color: var(--text-muted); }

.field-group input:focus-visible,
.field-group textarea:focus-visible {
  border-color: var(--lime);
  box-shadow: 0 0 0 3px rgba(204,255,0,0.15);
}

.field-group input.invalid,
.field-group textarea.invalid {
  border-color: rgba(255,100,100,0.85);
}

.field-err {
  font-family: var(--font-ui);
  font-size: 1rem;
  line-height: 1.3;
  letter-spacing: 0.08em;
  color: rgba(255,140,140,1);
  min-height: 1.2rem;
}

.req-legend {
  font-family: var(--font-ui);
  font-size: 1rem;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.req-legend .req { color: var(--lime); margin-right: 0.4em; }

/* Privacy reassurance sentence shown right after the submit button so
   GDPR/PECR signal is visible at the point of data collection, not just
   buried in a footer. Body font (not UI) so it reads as a human aside
   rather than UI chrome. */
.form-privacy {
  margin-top: 0.875rem;
  font-family: var(--font-body);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-tertiary);
  max-width: 56ch;
}

.form-footer {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.form-success {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--lime);
}

/* hidden attribute handled by JS — override display */
.form-success[hidden] { display: none !important; }

/* Disabled button state */
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}


/* ════════════════════════════════════════════════════════
   FOOTER — Observatory-plate social cards
   (Lime L-corner brackets like a viewfinder reticle)
════════════════════════════════════════════════════════ */
#footer {
  padding: 5rem var(--pad) 2.75rem;
  text-align: center;
  background: var(--black);
  position: relative;
  overflow: clip;
}

.footer-socials {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  /* Widened so the longest social card (Instagram / Email with the full
     handle) has room to breathe and the @ string never collides with the
     card edge. */
  max-width: 1360px;
  margin: 0 auto 2.75rem;
}
@media (min-width: 640px)  { .footer-socials { grid-template-columns: 1fr 1fr; gap: 1.75rem; } }
@media (min-width: 1000px) { .footer-socials { grid-template-columns: repeat(3, 1fr); } }

/* Observatory plate — telescope-viewfinder card */
.observatory-card {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.25rem;
  align-items: center;
  padding: 1.5rem 1.75rem 1.5rem 1.5rem;
  background:
    radial-gradient(ellipse at top left, rgba(204,255,0,0.05) 0%, transparent 60%),
    linear-gradient(180deg, rgba(20,20,20,0.65) 0%, rgba(5,5,5,0.65) 100%);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 4px;
  text-align: left;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.04),
    0 18px 36px rgba(0,0,0,0.45),
    0 4px 8px rgba(0,0,0,0.30);
  transition:
    border-color var(--dur) var(--ease-out),
    transform 0.26s var(--ease-spring),
    box-shadow var(--dur) var(--ease-out);
}

/* L-corner viewfinder brackets — lime */
.observatory-card::before,
.observatory-card::after,
.observatory-card .corner-bl,
.observatory-card .corner-br {
  content: '';
  position: absolute;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--lime);
  transition: border-color var(--dur) var(--ease-out), width var(--dur) var(--ease-out), height var(--dur) var(--ease-out);
  pointer-events: none;
}
.observatory-card::before { top: 8px;    left: 8px;    border-right: none; border-bottom: none; }
.observatory-card::after  { top: 8px;    right: 8px;   border-left:  none; border-bottom: none; }
.observatory-card .corner-bl { bottom: 8px; left: 8px; border-right: none; border-top: none; }
.observatory-card .corner-br { bottom: 8px; right: 8px; border-left:  none; border-top: none; }

.observatory-card:hover {
  border-color: rgba(204,255,0,0.30);
  transform: translateY(-4px);
  box-shadow: var(--shadow-glow-md), var(--shadow-md);
}
.observatory-card:hover::before,
.observatory-card:hover::after,
.observatory-card:hover .corner-bl,
.observatory-card:hover .corner-br {
  width: 20px;
  height: 20px;
}
.observatory-card:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* Profile media (QR code) */
.observatory-qr {
  width: 84px;
  height: 84px;
  border-radius: 3px;
  background: var(--black);
  opacity: 0.92;
  display: block;
  flex-shrink: 0;
}

/* On phones the card is single-column / full-width, so the QR can shrink
   a touch and give the body more room — keeps the @ handle on one line
   instead of truncating mid-word. */
@media (max-width: 480px) {
  .observatory-card { padding: 1.25rem 1.25rem 1.25rem 1.25rem; gap: 1rem; }
  .observatory-qr   { width: 68px; height: 68px; }
  .observatory-name { font-size: 1.0625rem; letter-spacing: 0.005em; }
}

.observatory-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  width: 100%;
  overflow: hidden;
}

.observatory-platform {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-ui);
  font-size: 1.0625rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime);
  /* Match the flex line-box height to the SVG so center alignment lands
     true. Without this, the line-box pads beyond the cap-height and the
     icon visually drifts to the top of the line. */
  line-height: 1.1;
}
.observatory-platform svg {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  display: block;        /* removes baseline gap */
  align-self: center;
}

/* Per-platform optical sizing.
   Email's icon paints inside (4–20) of its 24-viewBox = 67% area = 13.2px
   at an 18px render. The other two paint inside (2–22) = 83% area.
   For LinkedIn/Instagram to also paint ~13.2px we need: 13.2 / 0.83 ≈ 16px box.
   Now all three icons paint at the same effective size on the line and read
   as a single visual family — no more "one icon larger than the others". */
[data-platform="linkedin"]  .observatory-platform svg,
[data-platform="instagram"] .observatory-platform svg {
  width: 16px;
  height: 16px;
  transform: none;
}
[data-platform="email"]     .observatory-platform svg {
  width: 18px;
  height: 18px;
  transform: none;
}

/* Sized so the longest handle (@albertdunglisondesign, 22 chars) fits on
   one line at any viewport. Cards are widened in the grid so we can use
   a slightly larger range here and still keep the full handle visible
   instead of falling back to an ellipsis. */
.observatory-name {
  font-family: var(--font-head);
  font-size: clamp(1.125rem, 1.25vw, 1.45rem);
  line-height: 1.15;
  letter-spacing: 0.015em;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.observatory-handle {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  word-break: break-word;
  line-height: 1.4;
}

.observatory-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.4rem;
  font-family: var(--font-ui);
  font-size: 1.0625rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lime);
  line-height: 1;
  transition: letter-spacing var(--dur) var(--ease-out);
}
.observatory-card:hover .observatory-cta { letter-spacing: 0.18em; }

.footer-copy {
  font-family: var(--font-ui);
  font-size: 1rem;
  color: var(--text-tertiary);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-top: 1rem;
}
.footer-sep {
  margin: 0 0.5em;
  opacity: 0.5;
}
.footer-link {
  color: var(--text-tertiary);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  padding-bottom: 1px;
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.footer-link:hover {
  color: var(--lime);
  border-bottom-color: var(--lime);
}



/* ════════════════════════════════════════════════════════
   STARFIELD CANVAS
════════════════════════════════════════════════════════ */
#starfield {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  width: 100%;
  height: 100%;
}

/* ════════════════════════════════════════════════════════
   DECORATIVE OUTLINE STARS (section accents)
════════════════════════════════════════════════════════ */
.section-star {
  position: absolute;
  pointer-events: none;
  opacity: 0.10;
  z-index: 0;
  will-change: transform;
}

.section-star--about {
  width: 520px;
  height: 520px;
  top: -100px;
  right: -140px;
}

.section-star--services {
  width: 400px;
  height: 400px;
  bottom: -80px;
  left: -120px;
}

.section-star--work {
  width: 650px;
  height: 650px;
  top: -160px;
  right: -180px;
}

/* Scattered smaller outline stars — sprinkled across sections so the
   star motif lives throughout the page, not just at section edges. */
.scatter-star {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  top: var(--star-top, 50%);
  left: var(--star-left, 50%);
  transform: translate(-50%, -50%) rotate(var(--star-rot, 0deg));
  opacity: var(--star-opacity, 0.12);
}
.scatter-star--xs { width:  60px; height:  60px; }
.scatter-star--sm { width: 100px; height: 100px; }
.scatter-star--md { width: 170px; height: 170px; }
.scatter-star--lg { width: 260px; height: 260px; }

/* Mobile: shrink all decorative stars so they stop bunching/overlapping
   on narrow viewports. Positions (the % values inline on each star) stay
   the same, so the constellation polygon still connects the hero stars
   correctly — only the visual footprint of each star shrinks. */
@media (max-width: 719px) {
  .scatter-star--xs { width:  36px; height:  36px; }
  .scatter-star--sm { width:  56px; height:  56px; }
  .scatter-star--md { width:  90px; height:  90px; }
  .scatter-star--lg { width: 140px; height: 140px; }

  .hero-star               { width: 360px; height: 360px; }
  .section-star--about     { width: 280px; height: 280px; }
  .section-star--services  { width: 220px; height: 220px; }
  .section-star--work      { width: 340px; height: 340px; }
}


/* ════════════════════════════════════════════════════════
   SCROLL ANIMATION INITIAL STATES
   (GSAP sets these to their final values on scroll)
════════════════════════════════════════════════════════ */
.reveal-up,
.reveal-card,
.reveal-work {
  opacity: 0;
  transform: translateY(32px);
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .reveal-up,
  .reveal-card,
  .reveal-work {
    opacity: 1;
    transform: none;
  }
  .scroll-cue { animation: none; }
  .cursor-dot, .cursor-ring { display: none !important; }
  .side-rail { display: none !important; }
  .constellation { display: none !important; }
}


/* ════════════════════════════════════════════════════════
   UNCAGED PASS — editorial-cosmic brutalism
   New layer of magazine-style detail layered on top of the
   existing system. Each rule is opt-in via class so removing
   them does not break the base styles.
════════════════════════════════════════════════════════ */

/* ── DROP CAP ────────────────────────────────────────────
   The first letter of the lead About paragraph becomes a
   four-line lime initial in Fraunces italic — the serif
   voice making its second appearance. Pure editorial. */
.about-body--lead::first-letter {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(4rem, 7vw, 6rem);
  line-height: 0.85;
  float: left;
  color: var(--lime);
  /* The ::first-letter pseudo also captures the apostrophe in "I'm", so
     the visible drop cap is the unit "I'". The apostrophe has no native
     right-side bearing, so without extra room the following "m" collides
     into it. Bumped right-padding 0.12em → 0.32em + margin 0.05em → 0.1em
     so the body text starts on a clearly separate column. */
  padding: 0.1em 0.32em 0 0;
  margin-right: 0.1em;
  letter-spacing: -0.04em;
  text-shadow: 0 8px 18px rgba(204,255,0,0.18);
}

/* ── CONSTELLATION HAIRLINES ─────────────────────────────
   Covers the entire hero so the SVG coord system (0–100)
   maps 1:1 to the scatter-star --star-top/--star-left
   percent values. The lines literally connect those visible
   stars. Slow stroke-dash drift gives them a "navigating" feel. */
.constellation {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
  /* Opacity tuned to match the surrounding scatter stars (~0.13–0.18) so
     the lines read as the same visual layer as the stars themselves, not
     a louder secondary element. */
  opacity: 0.18;
}
.constellation polygon {
  /* Faster dash drift — was 26s/-36 (~1.4 units/s), now 5s/-54
     (~10.8 units/s). The lines visibly "travel" around the polygon
     like a signal tracing the constellation. -54 is 6 full dash
     periods (dasharray 3+6=9) so the loop stays seamless. */
  animation: constellation-draw 5s linear infinite;
}
@keyframes constellation-draw {
  from { stroke-dashoffset: 0;   }
  to   { stroke-dashoffset: -54; }
}

/* ── ASYMMETRIC SERVICES GRID ────────────────────────────
   Middle (featured) card lifts up by 28px on desktop to
   break the row line. Recovers to a flat row on tablets so
   it never looks broken. */
@media (min-width: 920px) {
  .service-card--featured { transform: translateY(-28px); }
  .service-card--featured:hover { transform: translateY(-40px); }
  /* Lift card whenever a focusable child receives focus inside featured */
  .service-card--featured:focus-within { transform: translateY(-40px); }
}

/* ── 3D CARD TILT ────────────────────────────────────────
   Subtle perspective rotation on hover. The card itself
   carries the rotation; .card-tilt-wrap on the grid sets
   perspective so the rotation reads as 3D depth. */
.services-grid,
.footer-socials { perspective: 1400px; }
.service-card,
.observatory-card {
  transform-style: preserve-3d;
  will-change: transform;
}
@media (hover: hover) {
  .service-card:hover {
    transform: translateY(-8px) rotateX(2deg) rotateY(-1.5deg);
  }
  .service-card--featured:hover {
    transform: translateY(-40px) rotateX(2deg) rotateY(-1.5deg);
  }
  .observatory-card:hover {
    transform: translateY(-4px) rotateX(2deg) rotateY(-1.5deg);
  }
}

/* ── CUSTOM CURSOR ───────────────────────────────────────
   Small lime dot tracks the cursor 1:1. A larger lime ring
   lags behind via JS easing. Hidden on coarse pointers and
   when prefers-reduced-motion is on. */
@media (hover: hover) and (pointer: fine) {
  /* Hide the default cursor on the body so our lime cursor reads as the
     primary cursor. Text fields keep their native I-beam (override below). */
  html, body { cursor: none; }
  a, button, .service-card, .observatory-card, .work-tile, label { cursor: none; }
  input, textarea { cursor: text; }

  .cursor-dot,
  .cursor-ring {
    position: fixed;
    top: 0; left: 0;
    pointer-events: none;
    z-index: 10001;
    border-radius: 50%;
    will-change: transform;
    mix-blend-mode: difference;
  }
  .cursor-dot {
    width: 6px; height: 6px;
    background: var(--lime);
    transform: translate3d(-100px, -100px, 0);
  }
  .cursor-ring {
    width: 32px; height: 32px;
    border: 1px solid rgba(204,255,0,0.55);
    transform: translate3d(-100px, -100px, 0);
    transition: width 0.22s var(--ease-spring), height 0.22s var(--ease-spring), border-color 0.22s var(--ease-out);
  }
  /* Class toggled by JS when cursor is over an interactive element */
  .cursor-ring.is-hover {
    width: 52px; height: 52px;
    border-color: rgba(204,255,0,0.85);
  }
}
@media (hover: none), (pointer: coarse) {
  .cursor-dot, .cursor-ring { display: none; }
}

/* ── SIDE RAIL — vertical magazine running-header ────────
   Fixed on the right edge of desktop viewports, rotated 90°.
   Updates as the user scrolls through sections (set by JS). */
.side-rail {
  position: fixed;
  right: 1.5rem;
  top: 50%;
  z-index: 180;
  display: none; /* hidden by default; shown at ≥1100px */
  flex-direction: row;
  align-items: center;
  gap: 0.65rem;
  transform: translateY(-50%) rotate(90deg);
  transform-origin: right center;
  white-space: nowrap;
  pointer-events: none;
  font-family: var(--font-ui);
  font-size: 0.875rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--lime);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  transition: opacity 0.35s var(--ease-out);
}
@media (min-width: 1100px) {
  .side-rail { display: inline-flex; }
}
.side-rail-num   { font-weight: 400; }
.side-rail-rule  { display: inline-block; width: 42px; height: 1px; background: var(--lime); opacity: 0.65; }
.side-rail-label { color: var(--text-secondary); letter-spacing: 0.28em; }


/* ============================================================
   POST-PIVOT ADDITIONS (web-design positioning, 2026-05-27)
   - hero CTA row + ghost button
   - service card features + "From" price prefix
   - services custom-quote CTA line
   - "How I work" disclosure section
   - example work cards (replaces old work-strip layout)
============================================================ */

/* ── Hero CTA row ───────────────────────────────────────── */
.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  margin-top: clamp(1.5rem, 4vw, 2rem);
}
.hero-cta-row .hero-cta { margin-top: 0; }

.btn--ghost {
  background: transparent;
  color: var(--white);
  border: 1px solid rgba(255,255,255,0.35);
}
.btn--ghost:hover,
.btn--ghost:focus-visible {
  border-color: var(--lime);
  color: var(--lime);
  background: transparent;
}

/* ── Service card additions ────────────────────────────── */
.card-from {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 0.42em;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-right: 0.4em;
  vertical-align: middle;
  transform: translateY(-0.45em);
}
.card-features {
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.card-features li {
  position: relative;
  padding-left: 1.4rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--text-secondary);
}
.card-features li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  background: var(--lime);
  transform: rotate(45deg);
}
.services-custom-cta {
  margin-top: clamp(2rem, 5vw, 3rem);
  text-align: center;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  color: var(--text-secondary);
}
.services-custom-cta a {
  color: var(--lime);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
  margin-left: 0.25em;
  transition: opacity var(--dur) var(--ease-out);
}
.services-custom-cta a:hover { opacity: 0.75; }

/* ── Bespoke Build callout ─────────────────────────────── */
.bespoke-callout {
  margin-top: clamp(2rem, 5vw, 3.25rem);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  border: 1px dashed rgba(204, 255, 0, 0.55);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(204, 255, 0, 0.04) 0%, rgba(255, 255, 255, 0.02) 100%);
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: start;
}
@media (min-width: 900px) {
  .bespoke-callout {
    grid-template-columns: 5fr 7fr;
    gap: clamp(2rem, 4vw, 3rem);
  }
}
.bespoke-lead { display: flex; flex-direction: column; align-items: flex-start; }
.bespoke-eyebrow {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime);
  margin: 0 0 0.75rem;
}
.bespoke-name {
  font-family: var(--font-head);
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  font-weight: 400;
  letter-spacing: 0.005em;
  margin: 0 0 0.6rem;
  color: var(--text-primary);
}
.bespoke-price {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.125rem;
  color: var(--text-primary);
  margin: 0;
}
.bespoke-freq {
  font-weight: 400;
  color: var(--text-secondary);
  margin-left: 0.35em;
  font-size: 0.9375rem;
}
.bespoke-price-note {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--text-tertiary);
  margin: 0.35rem 0 0;
}
.bespoke-desc {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-secondary);
  margin: 1rem 0 1.25rem;
}
.bespoke-link {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lime);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding-bottom: 3px;
  border-bottom: 1px solid currentColor;
  transition: opacity var(--dur) var(--ease-out);
}
.bespoke-link:hover { opacity: 0.75; }
.bespoke-link .arrow { transition: transform var(--dur) var(--ease-out); }
.bespoke-link:hover .arrow { transform: translateX(4px); }

.bespoke-body-label {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 0.9rem;
}
.bespoke-features {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.65rem;
}
.bespoke-features li {
  position: relative;
  padding-left: 1.4rem;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text-secondary);
}
.bespoke-features li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55rem;
  width: 6px;
  height: 6px;
  background: var(--lime);
  transform: rotate(45deg);
}

/* ── Services pricing philosophy caption ───────────────── */
.services-philosophy {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  text-align: center;
  font-family: var(--font-body);
  font-style: italic;
  font-size: 0.9375rem;
  color: var(--text-tertiary);
  letter-spacing: 0.005em;
}

/* ── How I work (AI-assisted disclosure) ───────────────── */
.how-i-work {
  position: relative;
  padding: clamp(3rem, 8vw, 5rem) 0;
}
.how-i-work-inner {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
  padding: clamp(2rem, 5vw, 3rem) clamp(1.5rem, 5vw, 3rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.how-i-work-kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--lime);
  margin: 0 0 1rem 0;
}
.how-i-work-kicker .kicker-rule {
  display: inline-block;
  width: 28px;
  height: 1px;
  background: var(--lime);
  opacity: 0.7;
}
.how-i-work-heading {
  font-family: var(--font-head);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: var(--white);
  margin: 0 0 1.5rem 0;
}
.how-i-work-heading .accent--italic {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--lime);
  font-weight: 400;
  letter-spacing: -0.005em;
}
.how-i-work-body {
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text-secondary);
  margin: 0 0 1rem 0;
}
.how-i-work-body:last-child { margin-bottom: 0; }

/* ── Section subheading (sits under .section-heading) ──── */
.section-sub {
  max-width: 60ch;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--text-secondary);
  margin: 1rem 0 clamp(2rem, 5vw, 3rem) 0;
}

/* ── Example work cards (3-up demo grid) ──────────────── */
.work-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.25rem, 3vw, 2rem);
  margin-top: 1rem;
}
@media (min-width: 780px) {
  .work-cards { grid-template-columns: repeat(3, 1fr); }
}
.work-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring);
}
.work-card:hover { border-color: var(--lime); transform: translateY(-3px); }
.work-card:focus-visible {
  border-color: var(--lime);
  outline: none;
  box-shadow: var(--focus-ring);
}
.work-card-preview {
  position: relative;
  aspect-ratio: 4 / 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.25rem;
  background: #222;
  overflow: hidden;
  border-bottom: 1px solid var(--border);
  text-align: center;
}
.work-card-preview-logo {
  width: clamp(64px, 13vw, 88px);
  height: clamp(64px, 13vw, 88px);
  display: block;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,0.25));
}
.work-card-preview-label {
  font-family: var(--font-head);
  font-size: 1.5rem;
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: rgba(255,255,255,0.95);
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
  position: relative;
  z-index: 1;
}

/* Per-demo preview backgrounds — placeholders until real screenshots drop in */
.work-card[data-demo="cafe"] .work-card-preview {
  background:
    radial-gradient(circle at 20% 80%, rgba(255,236,210,0.25), transparent 50%),
    linear-gradient(135deg, #d4a373 0%, #8b5a3c 55%, #4a2c1c 100%);
}
.work-card[data-demo="cafe"] .work-card-preview-label {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.7rem;
}

.work-card[data-demo="landscaper"] .work-card-preview {
  background:
    radial-gradient(circle at 70% 30%, rgba(180,210,140,0.20), transparent 50%),
    linear-gradient(160deg, #2d4a2b 0%, #4a6b3e 50%, #1a2e1c 100%);
}
.work-card[data-demo="landscaper"] .work-card-preview-label {
  font-family: var(--font-head);
  font-weight: 500;
  letter-spacing: 0.04em;
}

.work-card[data-demo="plumber"] .work-card-preview {
  background:
    radial-gradient(circle at 80% 80%, rgba(255,140,0,0.20), transparent 50%),
    linear-gradient(135deg, #0f2540 0%, #1a3a6c 60%, #0a1a30 100%);
}
.work-card[data-demo="plumber"] .work-card-preview-label {
  font-family: var(--font-ui);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 1.25rem;
}

.work-card-body {
  padding: 1.25rem 1.25rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
}
.work-card-name {
  font-family: var(--font-head);
  font-size: 1.4rem;
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--white);
  margin: 0;
}
.work-card-meta {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0;
}
.work-card-desc {
  font-family: var(--font-body);
  font-size: 0.97rem;
  line-height: 1.5;
  color: var(--text-secondary);
  margin: 0;
}
.work-card-cta {
  margin-top: auto;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lime);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding-top: 0.5rem;
}
.work-card-cta .arrow { transition: transform var(--dur) var(--ease-spring); }
.work-card:hover .work-card-cta .arrow,
.work-card:focus-visible .work-card-cta .arrow { transform: translateX(4px); }


/* ============================================================
   REVIEW FIXES (2026-05-27, post first homepage screenshot pass)
   - hero CTAs: matched height + true alignment
   - how-i-work: bumped scale (a tad)
   - service cards: equalize description box so bullets line up
   - footer observatory cards: icon centered vertically with text
============================================================ */

/* Hero CTAs - brute force identical sizing.
   The base .btn has asymmetric vertical padding (0.7 top / 0.45 bottom)
   for optical centering of the display font; that meant lime and ghost
   sat at different rendered heights once their visible borders differed.
   Here we override with explicit height + zeroed vertical padding +
   identical 1px border on BOTH buttons, then use flex to center text.
   Pixel-perfect match guaranteed regardless of border color. */
.hero-cta-row { align-items: stretch; }
.hero-cta-row > .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 3.15rem;
  min-height: 3.15rem;
  padding-top: 0;
  padding-bottom: 0;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  border-width: 1px;
  border-style: solid;
  border-color: transparent;
  box-sizing: border-box;
  line-height: 1;
  font-size: 1.1rem;
}
.hero-cta-row > .btn--lime  { border-color: var(--lime); }
.hero-cta-row > .btn--ghost { border-color: rgba(255,255,255,0.35); }

/* How I work — bigger bump (previous was too modest) */
.how-i-work-inner {
  max-width: 900px;
  padding: clamp(3rem, 7vw, 5rem) clamp(2.5rem, 7vw, 5rem);
}
.how-i-work-heading {
  font-size: clamp(2.85rem, 6vw, 4.25rem);
  margin-bottom: 2rem;
  line-height: 1.05;
}
.how-i-work-body {
  font-size: 1.3rem;
  line-height: 1.65;
}

/* Kicker: scale up, with symmetric rules either side.
   inline-flex + equal-width .kicker-rule spans keeps it centred. */
.how-i-work-kicker {
  font-size: 1rem;
  letter-spacing: 0.32em;
  gap: 0.95rem;
  margin-bottom: 1.5rem;
}
.how-i-work-kicker .kicker-rule {
  width: 52px;
  height: 1px;
}

/* Service cards: existing .card-desc has flex:1 which makes shorter
   descriptions expand and push bullets down. Kill the flex-grow so
   bullets sit right after the description across all three cards,
   then push the "Get started" link to the bottom. */
.service-card .card-desc {
  flex: 0 0 auto;
  min-height: 3.5em;
  margin-bottom: 0.25rem;
}
.service-card .card-features { flex: 1 0 auto; }
.service-card .card-link { margin-top: auto; }

/* Secondary line under the headline price (e.g. "+ £40/mo from month 2"). */
.card-price-note {
  display: block;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-tertiary);
  letter-spacing: 0.01em;
  margin-top: 0.25rem;
  white-space: normal;
}

/* Non-clickable variant of .card-link for the Ongoing Care card. */
.card-link--static {
  color: var(--text-tertiary);
  cursor: default;
}
.card-link--static:hover { letter-spacing: 0.10em; }

/* Footer observatory icons: bump to text-cap-height size + small upward
   optical nudge. The previous 16/18px sizes left them visually small and
   slightly low against the platform-name caps; matching them to the
   x-height of the surrounding label reads as truly "in line". */
[data-platform="linkedin"]  .observatory-platform svg,
[data-platform="instagram"] .observatory-platform svg,
[data-platform="email"]     .observatory-platform svg {
  width: 22px;
  height: 22px;
  transform: translateY(-1px);
}


/* ════════════════════════════════════════════════════════
   PROCESS SECTION
   Four-step buyer's-eye walk-through. Card grid matches the
   services grid rhythm but each step leads with a big lime
   number because the sequence is the point.
════════════════════════════════════════════════════════ */
#process {
  position: relative;
  padding-block: var(--section-py);
  overflow-x: clip;
}

.process-lead {
  font-family: var(--font-body);
  font-size: clamp(1rem, 1.2vw, 1.125rem);
  line-height: 1.65;
  color: var(--text-secondary);
  max-width: 62ch;
  margin-top: -1.25rem;
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}

.process-steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

@media (min-width: 640px)  { .process-steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .process-steps { grid-template-columns: repeat(4, 1fr); } }

.process-step {
  position: relative;
  background: linear-gradient(180deg, #121212 0%, #050505 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.85rem 1.6rem 1.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 22px 40px rgba(0,0,0,0.4),
    0 4px 10px rgba(0,0,0,0.3);
  transition:
    border-color var(--dur) var(--ease-out),
    transform 0.26s var(--ease-spring),
    box-shadow var(--dur) var(--ease-out);
}

.process-step:hover {
  border-color: rgba(204,255,0,0.4);
  transform: translateY(-4px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    var(--shadow-glow-sm),
    0 26px 44px rgba(0,0,0,0.5);
}

.process-num {
  font-family: var(--font-head);
  font-size: 2.5rem;
  color: var(--lime);
  line-height: 1;
  letter-spacing: 0.015em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  margin-bottom: 0.35rem;
}

.process-label {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 0.35rem;
}

.process-title {
  font-family: var(--font-head);
  font-size: clamp(1.25rem, 1.5vw, 1.5rem);
  letter-spacing: 0.015em;
  line-height: 1.15;
  color: var(--text-primary);
}

.process-body {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--text-secondary);
  margin: 0;
}


/* ════════════════════════════════════════════════════════
   COPY CALLOUT
   Considered aside between process and services. Not a full
   section — deliberately compact vertical padding so it reads
   as a flagged note, not a new act. Soft lime-tinted border
   + faint gradient wash to lift it off the page.
════════════════════════════════════════════════════════ */
.copy-callout {
  display: block;
  padding-block: clamp(2rem, 4vw, 3.25rem);
}

.copy-callout-inner {
  max-width: 780px;
  margin: 0 auto;
  padding: clamp(1.75rem, 3.2vw, 2.5rem) clamp(1.5rem, 3.2vw, 2.5rem);
  background:
    radial-gradient(120% 220% at 100% 0%, rgba(204,255,0,0.07) 0%, transparent 55%),
    linear-gradient(180deg, #121212 0%, #0a0a0a 100%);
  border: 1px solid rgba(204,255,0,0.24);
  border-radius: var(--radius);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.04),
    0 18px 40px rgba(0,0,0,0.35);
}

.copy-callout-eyebrow {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--lime);
  margin-bottom: 0.85rem;
}

.copy-callout-heading {
  font-family: var(--font-head);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  margin-bottom: 1rem;
}

.copy-callout-body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text-secondary);
  margin: 0;
  max-width: 62ch;
}
