/* ==========================================================================
   Winter Revenue Operations
   Design direction: near-black with a cold blue cast, lit by one cold
   light source above the hero. Every glow, gradient and rule on the page
   derives from that single light. Pass 2 (Three.js snowfall) plugs into it.
   ========================================================================== */

:root {
  /* Surfaces, coldest to warmest */
  --ink-950: #060910;
  --ink-900: #0a1018;
  --ink-850: #101823;
  --ink-800: #16202d;

  /* Hairlines */
  --line: #1c2836;
  --line-lit: #2e4a5e;

  /* Ice */
  --frost-100: #e8f4fa;
  --frost-300: #9bd7ee;
  --frost-500: #4a9fc8;

  /* Type */
  --text: #dce6f0;
  --muted: #8a9cb0;

  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Type scale */
  --t-h1: clamp(2.35rem, 6.2vw, 4.6rem);
  --t-h2: clamp(1.8rem, 3.6vw, 2.85rem);
  --t-h3: clamp(1.06rem, 1.5vw, 1.22rem);
  --t-metric: clamp(1.55rem, 2.9vw, 2.05rem);
  --t-body: clamp(1rem, 1.05vw, 1.0625rem);
  --t-lead: clamp(1.06rem, 1.7vw, 1.31rem);
  --t-small: 0.8125rem;

  --wrap: 1140px;
  --gutter: clamp(1.25rem, 5vw, 2.5rem);
  --nav-h: 68px;
  --radius: 14px;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { max-width: 100%; display: block; }
a { color: inherit; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 18px);
}

body {
  background: var(--ink-950);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- Focus / skip ---------- */
:focus-visible {
  outline: 2px solid var(--frost-300);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--frost-300);
  color: var(--ink-950);
  padding: .6rem 1rem;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 12px; top: 12px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  font-family: var(--font-body);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .005em;
  text-decoration: none;
  padding: .82rem 1.5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: transform .18s var(--ease), background-color .18s var(--ease),
              border-color .18s var(--ease), box-shadow .18s var(--ease), color .18s var(--ease);
  white-space: nowrap;
}

.btn--primary {
  background: linear-gradient(180deg, var(--frost-100), var(--frost-300));
  color: #04202e;
  box-shadow: 0 0 0 1px rgba(155,215,238,.35), 0 10px 34px -14px rgba(155,215,238,.65);
}
.btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(155,215,238,.55), 0 16px 40px -14px rgba(155,215,238,.8);
}

.btn--ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line-lit);
}
.btn--ghost:hover {
  border-color: var(--frost-500);
  color: var(--frost-100);
  background: rgba(155,215,238,.05);
}

.btn--sm { padding: .55rem 1.1rem; font-size: .875rem; }
.btn--lg { padding: 1rem 2rem; font-size: 1.02rem; }

/* ---------- Nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: rgba(6,9,16,.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.nav.is-stuck {
  border-bottom-color: var(--line);
  background: rgba(6,9,16,.9);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: -.015em;
  text-decoration: none;
  margin-right: auto;
}
.wordmark__a { color: var(--frost-100); }
.wordmark__b { color: var(--frost-300); }

.nav__links {
  display: flex;
  gap: 1.9rem;
}
.nav__links a {
  font-size: .9rem;
  color: var(--muted);
  text-decoration: none;
  position: relative;
  padding-block: .25rem;
  transition: color .18s var(--ease);
}
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--frost-300);
  transform: scaleX(0);
  transition: transform .22s var(--ease);
}
.nav__links a:hover { color: var(--frost-100); }
.nav__links a:hover::after { transform: scaleX(1); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  isolation: isolate;
  padding-top: clamp(4.5rem, 11vw, 8.5rem);
  padding-bottom: clamp(4rem, 9vw, 7rem);
  overflow: hidden;
}

/* The one cold light source. Everything else on the page reads as fall-off from it. */
.hero__light {
  position: absolute;
  inset: -30% -10% auto -10%;
  height: 130%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58% 46% at 50% 0%, rgba(155,215,238,.16), transparent 68%),
    radial-gradient(38% 32% at 22% 8%, rgba(74,159,200,.14), transparent 70%),
    radial-gradient(46% 40% at 82% 16%, rgba(74,159,200,.10), transparent 72%);
}
/* hero-scene.js mounts here: same stacking context, above the gradient,
   behind the text. Starts at opacity 0 and fades in once the first frame
   has rendered, so the hero never flashes an empty canvas. */
.hero canvas {
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  transition: opacity 1.1s var(--ease);
}
.hero canvas.is-ready { opacity: 1; }

.hero__inner { position: relative; }

.hero__title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--t-h1);
  line-height: 1.03;
  letter-spacing: -.028em;
  max-width: 17ch;
  /* Top-lit: brightest at cap height, cooling toward the baseline. */
  background: linear-gradient(178deg, var(--frost-100) 8%, #cfe3f0 46%, #8fa9bd 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-wrap: balance;
}

.hero__sub {
  margin-top: 1.6rem;
  max-width: 58ch;
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--muted);
}

.hero__cta {
  margin-top: 2.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: .85rem;
}

.hero__trust {
  margin-top: 2.2rem;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: .02em;
  color: var(--muted);
  width: fit-content;
  max-width: 100%;
}

/* Credentials use the same separator handling as the tool line below. */
.hero__trust .stack__item { white-space: nowrap; }

/* ---------- Sections ---------- */
.section {
  padding-block: clamp(4rem, 8vw, 7rem);
  position: relative;
  background: var(--ink-950);
}

/* Alternating bands carry the separation now that the divider rules are gone.
   nth-of-type counts the hero as the first section, so the run reads
   hero, band, base, band, base, band down the page. */
.section:nth-of-type(even) { background: var(--ink-900); }

.section__head {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--t-h2);
  line-height: 1.1;
  letter-spacing: -.022em;
  color: var(--frost-100);
  max-width: 20ch;
  margin-bottom: clamp(2rem, 4vw, 3rem);
  text-wrap: balance;
}

/* ---------- Grid + cards ---------- */
.grid {
  display: grid;
  gap: clamp(1rem, 1.8vw, 1.4rem);
}
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.card {
  position: relative;
  background: linear-gradient(180deg, var(--ink-850), var(--ink-900));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
  transition: border-color .25s var(--ease), transform .25s var(--ease), background-color .25s var(--ease);
}
/* Single hairline top-edge highlight, never a full glowing border. */
.card::before {
  content: "";
  position: absolute;
  top: -1px; left: 12%; right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(155,215,238,.42), transparent);
  opacity: .5;
  transition: opacity .25s var(--ease);
}
.card:hover { border-color: var(--line-lit); transform: translateY(-2px); }
.card:hover::before { opacity: 1; }

.card h3 {
  font-family: var(--font-body);
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -.005em;
  color: var(--frost-100);
  margin-bottom: .6rem;
}
.card p { color: var(--muted); }

/* Fifth service card spans the grid. Custom builds is the differentiator,
   and a full-width row gives it weight while keeping the 2x2 above intact. */
.card--wide { grid-column: 1 / -1; }

/* Pain + services */
/* The mono category tag sits opposite the service numeral. */
.service__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.service__tag {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--frost-500);
}

/* Same top-lit numeral treatment as the About stat card, scaled down so it
   marks the card without competing with the copy inside it. */
.pain__num,
.service__num {
  display: block;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 500;
  font-size: clamp(2.3rem, 4.2vw, 3rem);
  line-height: 1;
  letter-spacing: -.05em;
  background: linear-gradient(176deg, var(--frost-100) 4%, var(--frost-300) 55%, var(--frost-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* room for the Fraunces foot serifs, same as .stat__num */
  padding-bottom: .06em;
  margin-bottom: .9rem;
}

.service__num {
  font-size: clamp(1.9rem, 3.2vw, 2.4rem);
  margin-bottom: .5rem;
}

/* The pain numeral only marks the card; it sits below the service numerals
   rather than above them, so three short cards do not shout at the reader. */
.pain__num {
  font-size: clamp(1.5rem, 2.5vw, 1.85rem);
  margin-bottom: .55rem;
}

.pain .card p { color: var(--text); font-size: 1.02rem; line-height: 1.55; }

/* The problem itself, lifted out of the sentence around it. Underline rather
   than a highlight block, so it stays quiet on a dark ground. */
.mark {
  color: var(--frost-100);
  text-decoration: underline;
  text-decoration-color: var(--frost-500);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
/* Section closers: a mono lead-in over the statement, borrowing the label
   device from the case study cards so the setup and the payoff are visibly
   two different registers rather than one long sentence. */
.section__close {
  margin-top: clamp(2.4rem, 4vw, 3.2rem);

  /* Not ch: this wrapper inherits the body font, so ch would measure against
     16px sans while the statement inside is nearly twice that size. */
  max-width: 48rem;
}

/* Both halves share a size. At display scale the lead competed with the
   section header above it and the section read as having two headlines.
   Separating them by weight and colour instead keeps one statement with
   emphasis, which is what it is. */
.section__close-lead,
.section__close-line {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem);
  line-height: 1.42;
  letter-spacing: -.012em;
  text-wrap: pretty;
}

.section__close-lead {
  font-weight: 400;
  color: var(--frost-100);
  margin-bottom: .2rem;
}

.section__close-line {
  font-weight: 300;
  color: var(--frost-300);
}

/* Tool line under the services grid. Answers "can you work in my stack"
   at the moment someone is judging what you do. Text, never logos: a logo
   wall reads as an implementer's site, not a builder's. */
.stack {
  margin-top: clamp(1.6rem, 3vw, 2.2rem);

  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: .02em;
  line-height: 1.9;
  color: var(--muted);
  width: fit-content;
  max-width: 100%;
}
.stack__item { white-space: nowrap; }
/* Separator belongs to the item before it, so a wrap can never leave a
   stray middot at the start of a line. */
.stack__item:not(:last-child)::after {
  content: "\00B7";
  color: var(--line-lit);
  margin-left: .34rem;
}
.stack__label {
  color: var(--frost-500);
  margin-right: .35rem;
}

/* ---------- Case studies ---------- */

.card--case { display: flex; flex-direction: column; }

.case__metric {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--t-metric);
  line-height: 1.08;
  letter-spacing: -.03em;
  /* Same top-lit gradient as the H1: light striking ice. */
  background: linear-gradient(176deg, var(--frost-100) 6%, var(--frost-300) 52%, var(--frost-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: 1.15rem;
  text-wrap: balance;
}
/* Side by side, the three metrics wrap to different depths, which pushed the
   labels and bodies out of line across the row. Reserve the tallest one's
   height (four lines at the metric size) so every card's label starts on the
   same baseline. Dropped once the cards stop sharing a row. */
@media (min-width: 701px) {
  .case__metric { min-height: calc(var(--t-metric) * 3.3); }
}

.case__label {
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--frost-500);
  margin-bottom: .7rem;
}

.case__title {
  font-family: var(--font-body);
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--frost-100);
  margin-bottom: .55rem;
}

.case__body { color: var(--muted); font-size: .97rem; }

.case__link {
  margin-top: auto;
  padding-top: 1.4rem;
  align-self: flex-start;
  font-size: .9rem;
  font-weight: 500;
  color: var(--frost-300);
  text-decoration: none;
  transition: color .18s var(--ease);
}
.case__link span { display: inline-block; transition: transform .2s var(--ease); }
.case__link:hover { color: var(--frost-100); }
.case__link:hover span { transform: translateX(4px); }

/* ---------- About ---------- */
.about {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 3.5vw, 3.2rem);
  align-items: start;
}
.about__copy p + p { margin-top: 1.15rem; }
.about__copy p { color: var(--muted); font-size: 1.03rem; }

/* The face sits beside the personal promise, so the claim that you get
   Shane himself is made literal at the exact line that makes it. */
.about__promise {
  display: flex;
  align-items: center;
  gap: 1.15rem;
  margin-top: 1.8rem;
}

.about__portrait {
  flex: 0 0 auto;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  /* Same cooling as the OG card so a bright office backdrop sits in the
     page's light instead of reading as a warm cutout on cold ground. */
  filter: saturate(.9) contrast(1.04) brightness(.97);
  box-shadow: 0 0 0 1px var(--line-lit), 0 0 34px -10px rgba(155,215,238,.45);
}

.about__emph {
  font-family: var(--font-display);
  font-size: clamp(1.18rem, 2.2vw, 1.55rem) !important;
  font-weight: 300;
  line-height: 1.36;
  letter-spacing: -.014em;
  color: var(--frost-100) !important;
  padding-left: 1.15rem;
  border-left: 2px solid var(--frost-500);
  margin: 0 !important;
}

.about__proof {
  margin-top: 1.8rem !important;
  font-size: .93rem !important;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  align-items: baseline;
}
.about__links { display: inline-flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; }
.about__links a {
  color: var(--frost-300);
  text-decoration: none;
  border-bottom: 1px solid rgba(155,215,238,.3);
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.about__links a:hover { color: var(--frost-100); border-bottom-color: var(--frost-100); }
.about__proof .dot { color: var(--line-lit); }

.card--stat { padding: clamp(1.6rem, 2.8vw, 2.2rem); }
.stat__num {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 500;
  font-size: clamp(4.2rem, 9vw, 6.2rem);
  line-height: 1;
  /* room for the Fraunces foot serifs so background-clip does not shear them */
  padding-bottom: .06em;
  letter-spacing: -.05em;
  background: linear-gradient(176deg, var(--frost-100) 4%, var(--frost-300) 55%, var(--frost-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent !important;
  margin-bottom: .9rem;
}
.stat__cap {
  color: var(--text) !important;
  font-size: 1.02rem;
  line-height: 1.42;
  max-width: 24ch;
}
.stat__sub {
  margin-top: 1.15rem;

  font-size: .9rem;
  line-height: 1.55;
}

/* ---------- Final CTA ---------- */
.section--cta { text-align: center; }
.cta { max-width: 46rem; }
.cta__head {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: var(--t-h2);
  line-height: 1.1;
  letter-spacing: -.022em;
  background: linear-gradient(178deg, var(--frost-100) 10%, #b9d3e2 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-wrap: balance;
}
.cta__sub {
  margin-top: 1.1rem;
  margin-bottom: 2.2rem;
  font-size: var(--t-lead);
  color: var(--muted);
}
.cta__fine {
  margin-top: 2rem;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: .02em;
  color: var(--muted);
}

/* ---------- Footer ---------- */
/* Four columns of quiet mono: who, where to go, how to reach him, where else
   to check him out. No rules anywhere; the gap does the separating. */
.footer {
  padding-block: clamp(2.6rem, 5vw, 3.6rem);
}
.footer__inner {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: clamp(1.8rem, 3.5vw, 3rem);
  align-items: start;
}
.footer p,
.footer a {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: .02em;
  color: var(--muted);
}
.footer__pitch {
  margin-top: .9rem;
  max-width: 32ch;
  line-height: 1.7;
}
.footer__col {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.footer__head {
  color: var(--frost-500);
  text-transform: uppercase;
  letter-spacing: .13em;
  margin-bottom: .2rem;
}
.footer__col a {
  text-decoration: none;
  width: fit-content;
  transition: color .18s var(--ease);
}
.footer__col a:hover { color: var(--frost-100); }
.footer__note { color: var(--muted); }

.footer__base {
  margin-top: clamp(2.2rem, 4vw, 3rem);
}
.footer__base p { color: #5d6f83; }

@media (max-width: 860px) {
  .footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 460px) {
  .footer__inner { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Scroll reveals ---------- */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }
/* Never let JS gate readability: if the observer never runs, show everything. */
.no-js .reveal { opacity: 1; transform: none; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cases { grid-template-columns: repeat(1, minmax(0, 1fr)); }
  .about { grid-template-columns: minmax(0, 1fr); }
  .card--stat { max-width: 30rem; }
}

@media (max-width: 700px) {
  .grid--2, .grid--3 { grid-template-columns: minmax(0, 1fr); }
  .hero__title { max-width: none; }
  /* Portrait above the promise rather than beside it, so neither gets
     squeezed to an unreadable column. */
  .about__promise { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .about__portrait { width: 80px; height: 80px; }
}

@media (max-width: 640px) {
  /* Mobile nav: logo + Book a call only. No hamburger. */
  .nav__links { display: none; }
  .hero__cta .btn { flex: 1 1 auto; }
}

@media (max-width: 380px) {
  :root { --nav-h: 62px; }
  .btn { padding-inline: 1.15rem; }
  .btn--sm { padding-inline: .9rem; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  /* hero-scene.js never initializes here. The static gradient is the background. */
}
