/* =========================================================================
   Sidus Strategic Solutions — visual system  (V0.4 "Daylight", paper & ink)
   Cool paper ground · dark polished-graphite accent · editorial-luxe.
   Committed single (light) world, the exact mirror of V0.3's committed dark one.

   V0.4 = V0.3.2's exact build with the dark world inverted to a light one, so the
   client can settle light-vs-dark the same way V0.3 settled gold-vs-silver:
   by direct comparison, with colour as the ONLY variable. Structure, copy,
   type ramp, motion and the jewel's geometry are untouched.

   --- Why light is not just "dark with the values flipped" ---
   V0.3's header note explains why silver is not gold-with-a-grey-hue. Inverting
   that build runs into the mirror image of the same trap, and the same two rules
   fix it. Both are load-bearing; don't "simplify" either away:

     1. HUE still does the separating. A neutral graphite accent on paper lands on
        the same value as the body text and the page collapses into grey mush all
        over again — exactly as a neutral silver did on black. So the accent keeps
        V0.3's deliberate COOL BLUE cast, just carried to the dark end of the ramp
        (#33496F), and the neutrals stay cool so the gap stays open.

     2. Accents are still METAL, not flat colour — but the TRICK INVERTS. On black,
        a light ramp reads as polished metal because of the DARK band running
        through it. On paper the metal is dark, so what sells it is the LIGHT band:
        a specular streak (#4E6B93) through an otherwise deep ramp. That streak is
        what makes this graphite rather than navy.

   --- The third inversion: light stops emitting and starts falling ---
   On a dark ground every accent GLOWS: text-shadows, 0-blur box-shadows, SVG
   drop-shadow halos. Paper does not emit light, it receives it — so every glow
   here became a cast SHADOW, and the hero's vignettes, which DARKENED on black to
   give the headline its contrast, LIGHTEN on paper to do the same job. A glow left
   in place on paper doesn't read as light; it reads as dirt around the type.
   V0.3's --glow-accent also existed to rescue small silver labels, which had no
   hue to spend at 12px. That problem is dark-only: a dark blue label separates
   from muted body text on paper by hue AND value, so the glow is simply gone.

   --- Token rename, deliberate ---
   V0.3's accent tokens were --silver / --silver-bright / --silver-deep. Inverted,
   those names lie: "bright" is now the DARKEST end. They are renamed here rather
   than left to mislead a future reader. The mapping, if you're comparing to V0.3.2:
       --silver        -> --accent          --platinum    -> --body
       --silver-bright -> --accent-strong   --ink         -> --paper
       --silver-deep   -> --accent-soft     --ink-2       -> --paper-2
       --silver-accent -> --accent-label    --silver-soft -> --accent-wash
   ========================================================================= */

/* ---- Self-hosted variable fonts (offline, no CDN) ---- */
@font-face {
  font-family: "Fraunces";
  src: url("fonts/fraunces.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("fonts/fraunces-italic.woff2") format("woff2");
  font-weight: 100 900; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/hanken.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

/* ---- Tokens ---- */
:root {
  --paper:      #F7F8FB;   /* page ground — cool paper, so the accent has a ground */
  --paper-2:    #EDF1F7;   /* alternating band — sinks BELOW the ground (on black it rose) */
  --surface:    #FFFFFF;   /* cards, panels — lift toward white */
  --surface-2:  #FFFFFF;   /* raised / hover — white is the ceiling, so hover lifts
                              by SHADOW instead of by value; see --shadow-lift */
  --hair:         rgba(51, 73, 111, 0.13);
  --hair-2:       rgba(51, 73, 111, 0.20);
  --hair-accent:  rgba(51, 73, 111, 0.34);

  /* neutrals stay cool, for the same reason V0.3's did: to keep a gap the accent
     can live in. Warm greys here would close it and mute the blue cast. */
  --text:       #0D1420;
  --body:       #48566E;
  /* --muted sits noticeably DARKER than the dark build's #78828F, and has to.
     "Muted" on black means stepping down from a near-white body toward the
     ground, which costs little contrast; on paper it means stepping toward the
     ground from a mid-ink body, which costs a lot. A visually-equivalent grey
     (#7C8899) measured 3.2-3.6:1 here against 4.6-5.0:1 for its dark counterpart
     — same apparent softness, quietly failing AA. This value restores parity on
     all three grounds (paper 5.0, paper-2 4.6, white 5.3). */
  --muted:      #616D7C;

  --accent:        #33496F;  /* cool cast is deliberate — see header note */
  --accent-strong: #16233A;  /* the emphatic end — DARKEST on paper */
  --accent-soft:   #93A2BC;  /* the faint end — lightest */
  --accent-wash:   rgba(51, 73, 111, 0.10);
  --accent-rgb:    51, 73, 111;

  /* Small labels (eyebrows, chapter indices, card numbers). On black these needed
     a specular halo to stop them flattening into the surrounding greys. On paper
     they don't: a dark blue label separates from --muted body text by hue AND by
     value at once. So the halo is removed outright rather than inverted — a glow
     on paper reads as smudge, not as light. --glow-accent is kept (as `none`) so
     the rules that used it stay structurally identical to V0.3.2. */
  --accent-label:  #2C4068;
  --glow-accent:   none;

  /* The button metal ramp — dark, with a LIGHT specular streak at 72%. That streak
     is the inverted counterpart of V0.3's dark band: on paper the metal is dark, so
     what sells it as polished is the highlight, not the shadow. The streak is held
     at #4E6B93 rather than anything brighter so the button's own label still clears
     4.5:1 against the lightest point of its background. The harder-edged ramp lives
     in the SVG #metal gradient used by the jewel heart, not here. */
  --metal: linear-gradient(178deg, #43608A 0%, #1F3050 42%, #4E6B93 72%, #1A2740 100%);

  /* Paper needs elevation that black didn't: a white card on a near-white ground
     reads as unfinished with only a hairline. Soft and layered, never a hard edge. */
  --shadow-card: 0 1px 2px rgba(16, 24, 40, 0.04), 0 8px 24px rgba(31, 41, 89, 0.05);
  --shadow-lift: 0 2px 6px rgba(16, 24, 40, 0.06), 0 16px 40px rgba(31, 41, 89, 0.10);

  --serif: "Fraunces", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* --- Type ramp. One size per role, one weight per role. Every serif display
         element picks from this list — nothing sets an ad-hoc size or weight. --- */
  --fs-display:   clamp(2.3rem, 5.2vw, 3.85rem);   /* hero headline only */
  --fs-promise:   clamp(1.32rem, 2.4vw, 1.82rem);  /* hero promise line */
  --fs-statement: clamp(2rem, 3.9vw, 3rem);        /* h2 · gap quote · about statement */
  --fs-vm:        clamp(1.15rem, 2vw, 1.5rem);     /* vision / mission cards */
  --fs-h3:        clamp(1.2rem, 2vw, 1.4rem);      /* card + step headings */
  --fs-lead:      clamp(1.05rem, 1.6vw, 1.22rem);
  --fs-body:      0.95rem;
  --fs-micro:     0.72rem;                          /* eyebrows, labels, step nums */

  --w-display: 620;   /* hero only — deliberately the boldest thing on the page */
  --w-head:    500;   /* every other serif display element */
  --w-body:    400;

  --wrap: 1160px;
  --gap: clamp(1.5rem, 4vw, 3rem);
  --section-y: clamp(4.75rem, 10vw, 8.5rem);
  --radius: 14px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---- Reset / base ---- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.7;
  color: var(--body);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
::selection { background: rgba(var(--accent-rgb), 0.18); color: var(--text); }

:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 3px; border-radius: 4px; }

/* ---- Filmic grain (fixed, whole page) ----
   `overlay` is a dark-ground blend: on paper it barely registers, and what does
   register reads as grey dirt. `multiply` at a lower opacity darkens only, which
   is what paper tooth actually does to light. */
.grain {
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  opacity: 0.035; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* ---- Typography ---- */
h1, h2, h3, h4 {
  font-family: var(--serif); color: var(--text);
  font-weight: var(--w-head); line-height: 1.08; letter-spacing: -0.015em;
  text-wrap: balance; margin: 0;
}
h2 { font-size: var(--fs-statement); }
h3 { font-size: var(--fs-h3); letter-spacing: -0.01em; }
p { margin: 0; }
em { font-style: italic; }

.eyebrow {
  font-family: var(--sans); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent-label);
  text-shadow: var(--glow-accent);
  display: inline-flex; align-items: center; gap: 0.6rem;
}
.eyebrow::before {
  content: ""; width: 6px; height: 6px; background: var(--accent);
  transform: rotate(45deg); box-shadow: 0 1px 3px rgba(var(--accent-rgb), 0.35);
}

/* chapter kicker: faint serif index + eyebrow */
.kicker { display: flex; align-items: baseline; gap: 0.9rem; }
.kicker__idx {
  font-family: var(--serif); font-size: 0.95rem; font-weight: var(--w-head);
  color: var(--accent-label); text-shadow: var(--glow-accent);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
  position: relative; padding-right: 0.9rem;
}
.kicker__idx::after {
  content: ""; position: absolute; right: 0; top: 50%; width: 0.5rem; height: 1px;
  background: var(--hair-accent);
}
.kicker--center { justify-content: center; }

.lead { color: var(--body); font-size: var(--fs-lead); line-height: 1.65; }
.measure { max-width: 62ch; }

/* ---- Layout ---- */
.wrap { width: min(var(--wrap), 100% - 2.5rem); margin-inline: auto; }
.section { padding-block: var(--section-y); position: relative; scroll-margin-top: 92px; }
.section--alt { background: var(--paper-2); }
.section__head { max-width: 64ch; margin-bottom: clamp(2.4rem, 5vw, 3.6rem); }
.section__head h2 { margin-top: 1rem; }
.section__head .lead { margin-top: 1.1rem; max-width: 58ch; }

/* Divider with a diamond node */
.starrule { display: flex; align-items: center; gap: 1rem; color: var(--hair-accent); }
.starrule::before, .starrule::after {
  content: ""; height: 1px; flex: 1;
  background: linear-gradient(90deg, transparent, var(--hair-2), transparent);
}
.starrule i {
  width: 7px; height: 7px; background: var(--accent); transform: rotate(45deg); flex: none;
  box-shadow: 0 2px 6px rgba(var(--accent-rgb), 0.32);
}

/* ---- Navigation ---- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 70;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem clamp(1.25rem, 4vw, 2.5rem);
  transition: background 0.4s var(--ease), padding 0.4s var(--ease), border-color 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  background: rgba(247, 248, 251, 0.85);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom-color: var(--hair);
  padding-block: 0.65rem;
}
.nav.is-stuck .nav__logo img { height: 34px; }
.nav__logo img { height: 40px; width: auto; transition: height 0.4s var(--ease); }
.nav__links { display: flex; align-items: center; gap: clamp(1.25rem, 2.4vw, 2.2rem); }
.nav__links a.link { font-size: 0.9rem; color: var(--body); position: relative; transition: color 0.25s var(--ease); }
.nav__links a.link::after {
  content: ""; position: absolute; left: 0; bottom: -6px; height: 1px; width: 0;
  background: var(--accent); transition: width 0.3s var(--ease);
}
.nav__links a.link:hover { color: var(--text); }
.nav__links a.link:hover::after { width: 100%; }
.nav__links a.link.is-active { color: var(--text); }
.nav__links a.link.is-active::after { width: 100%; background: var(--accent); opacity: 0.8; }

@media (max-width: 720px) { .nav__links .link { display: none; } }

/* ---- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--sans); font-size: 0.86rem; font-weight: 600;
  letter-spacing: 0.01em; padding: 0.66rem 1.2rem; border-radius: 999px;
  cursor: pointer; border: 1px solid transparent;
  transition: transform 0.25s var(--ease), background 0.25s var(--ease),
              border-color 0.25s var(--ease), color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.btn svg { width: 14px; height: 14px; transition: transform 0.25s var(--ease); }
/* the primary button is the dark metal on paper — the inverse of V0.3, where it
   was the light metal on black. Same object, same ramp logic, opposite ground.
   Class name kept as .btn--silver so the markup stays identical across versions. */
.btn--silver {
  background: var(--metal);
  color: #F6F9FF; box-shadow: 0 6px 18px -10px rgba(var(--accent-rgb), 0.55);
}
.btn--silver:hover { transform: translateY(-2px); box-shadow: 0 12px 26px -12px rgba(var(--accent-rgb), 0.62); }
.btn--silver:hover svg { transform: translateX(3px); }
.btn--ghost { border-color: var(--hair-2); color: var(--text); background: transparent; }
.btn--ghost:hover { border-color: var(--accent); color: var(--accent-strong); transform: translateY(-2px); }

/* ============================ HERO ============================ */
.hero {
  position: relative; min-height: 100svh;
  display: flex; align-items: center;
  padding-block: 7rem 6rem; overflow: hidden;
}
#stars { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
/* V0.4 — the same six-layer lighting rig as V0.3.2, inverted. Every layer that
   ADDED light on black now ADDS PAPER, and the two vignettes that DARKENED to
   give the headline its contrast now LIGHTEN to do exactly the same job. Only
   the jewel's own halo stays a tint rather than flipping, because the jewel is
   the one dark object in the frame and it should sit in a faint cool aura. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    /* tight bright key hotspot just off the jewel's upper edge */
    radial-gradient(20% 24% at 76% 34%, rgba(255, 255, 255, 0.80), transparent 60%),
    /* jewel halo — a cool tint pooling around the dark mark */
    radial-gradient(38% 46% at 72% 49%, rgba(var(--accent-rgb), 0.07), transparent 66%),
    /* cool key light raking from upper right */
    radial-gradient(56% 60% at 86% 20%, rgba(var(--accent-rgb), 0.05), transparent 62%),
    /* faint lower-left fill so the frame isn't one-sided */
    radial-gradient(60% 50% at 6% 112%, rgba(var(--accent-rgb), 0.04), transparent 60%),
    /* left "vignette" — LIGHTENS on paper; this is what gives the headline punch */
    radial-gradient(82% 96% at -2% 55%, rgba(255, 255, 255, 0.88), transparent 56%),
    /* centering wash, settling into the paper ground */
    radial-gradient(115% 100% at 34% 50%, rgba(255, 255, 255, 0.34), var(--paper) 80%);
}
.hero .wrap { position: relative; z-index: 3; }
.hero__inner { max-width: 48rem; }
.hero__eyebrow { margin-bottom: 1.6rem; }

/* The headline — the boldest, clearest thing on the page, by request. */
.hero__title {
  font-size: var(--fs-display);
  font-weight: var(--w-display);
  line-height: 1.03; letter-spacing: -0.028em;
  max-width: 20ch;
}
.hero__title span { display: block; }

.hero__rule { display: flex; align-items: center; gap: 0.8rem; margin-top: 1.7rem; max-width: 20rem; }
.hero__rule i {
  width: 6px; height: 6px; background: var(--accent); transform: rotate(45deg); flex: none;
  box-shadow: 0 1px 4px rgba(var(--accent-rgb), 0.35);
}
.hero__rule::after {
  content: ""; height: 1px; flex: 1;
  background: linear-gradient(90deg, var(--hair-accent), transparent);
}

/* The promise line kept from V0.1, demoted below the tagline but still large. */
.hero__promise {
  margin-top: 1.1rem; max-width: 30ch;
  font-family: var(--serif); font-style: italic; font-weight: var(--w-body);
  font-size: var(--fs-promise); line-height: 1.3;
  color: var(--accent);
}
.hero__promise em { color: var(--accent-strong); font-style: italic; }

.hero__sub {
  margin-top: 1.5rem; max-width: 50ch;
  font-size: var(--fs-lead); line-height: 1.62; color: var(--body);
}
.hero__cta { margin-top: 2.4rem; display: flex; flex-wrap: wrap; gap: 1rem; }

/* proof strip */
.hero__proof {
  position: absolute; left: 0; right: 0; bottom: 2.4rem; z-index: 3;
  width: min(var(--wrap), 100% - 2.5rem); margin-inline: auto;
  display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  color: var(--muted); font-size: 0.74rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.hero__proof i { width: 5px; height: 5px; background: var(--accent); transform: rotate(45deg); opacity: 0.7; }
.hero__scroll {
  position: absolute; right: clamp(1.25rem, 4vw, 2.5rem); bottom: 2.1rem; z-index: 3;
  color: var(--muted); font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
}
.hero__scroll span { width: 1px; height: 42px; background: linear-gradient(var(--accent), transparent); }

/* ---------------- Diamond constellation (hero focal) ---------------- */
.facets {
  position: absolute; z-index: 2; pointer-events: none;
  right: 2vw; top: 49%;
  transform: translate(0, calc(-50% + var(--py, 0px)));
  will-change: transform;
  width: clamp(500px, 55vw, 880px); aspect-ratio: 1;
}
.facets__stage { position: relative; width: 100%; height: 100%; }
.facets svg { position: relative; z-index: 1; width: 100%; height: 100%; overflow: visible; }

/* A pulsing bloom behind the jewel. On black this was a halo of emitted light; on
   paper the jewel is the dark object, so the same element becomes a soft cool
   shadow pooling under it. Same motion, opposite physics. */
.jewel-aura {
  position: absolute; inset: 6%; pointer-events: none; border-radius: 50%;
  background: radial-gradient(closest-side,
    rgba(var(--accent-rgb), 0.10), rgba(var(--accent-rgb), 0.035) 46%, transparent 72%);
  filter: blur(14px);
  animation: aura-pulse 11s ease-in-out infinite;
}
@keyframes aura-pulse {
  0%, 100% { opacity: 0.62; transform: scale(0.98); }
  50%      { opacity: 1;    transform: scale(1.06); }
}

/* Entrance (unchanged from V0.3.2): the stage fades up crisply while the ring
   OUTLINES draw themselves from the core outward. stroke-dashoffset is the only
   property the draw touches, so it never fights ring-breathe or parallax. */
.js .facets__stage { opacity: 0; transform: scale(0.94); transform-origin: center; will-change: transform, opacity; }
.js body.is-ready .facets__stage { animation: jewel-in 1s var(--ease) forwards; }
@keyframes jewel-in { to { opacity: 1; transform: scale(1); } }

.js .fx-facet { stroke-dasharray: 1; stroke-dashoffset: 1; }
.js body.is-ready .fx-facet { animation: draw-in 1.5s var(--ease) forwards; }
@keyframes draw-in { to { stroke-dashoffset: 0; } }
.js body.is-ready .fx--r1 { animation-delay: 0.15s; }
.js body.is-ready .fx--r2 { animation-delay: 0.40s; }
.js body.is-ready .fx--r3 { animation-delay: 0.65s; }
.js body.is-ready .fx--r4 { animation-delay: 0.90s; }

/* the heart's gleam — a four-point sparkle that flashes once per cycle. It stays
   WHITE: it sits on top of the heart, which is the darkest metal in the frame, so
   white is the one thing that still reads as a glint here. Its halo drops to a
   tight white one, since a wide silver bloom would only erase the paper around it. */
.fx-spark {
  fill: #FFFFFF; opacity: 0; transform-box: fill-box; transform-origin: center;
  filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.9));
  animation: spark-flash 6s ease-in-out infinite;
}
@keyframes spark-flash {
  0%, 70%, 100% { opacity: 0;    transform: scale(0.5); }
  82%           { opacity: 0.95; transform: scale(1.15); }
  92%           { opacity: 0;    transform: scale(0.7); }
}

/* Raking sheen — a soft light source turning slowly behind the jewel. On paper it
   turns into a raking SHADOW instead, which reads the same way: the surface looks
   lit from a moving source rather than painted. Still the one thing here allowed
   to rotate — it is a formless blur, not a diamond, so spinning it costs nothing. */
.facets::before {
  content: ""; position: absolute; inset: 8%; z-index: 0;
  border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 0deg,
    transparent 0deg,
    rgba(var(--accent-rgb), 0.07) 38deg,
    transparent 96deg,
    transparent 200deg,
    rgba(var(--accent-rgb), 0.045) 250deg,
    transparent 312deg);
  filter: blur(26px);
  animation: sheen-turn 26s linear infinite;
}
@keyframes sheen-turn { to { transform: rotate(360deg); } }

/* The heart scales about its OWN centre; the rings turn about the shared centre of
   the viewBox. Two different transform-boxes — don't collapse them into one rule. */
.fx { transform-box: fill-box; transform-origin: center; }
.ring { transform-box: view-box; transform-origin: 320px 320px; }

/* Ring strokes read as dark lines on paper at the same alphas that read as light
   lines on black — the alpha ramp carries over unchanged, only the colour flips. */
.fx-facet { fill: none; stroke: rgba(var(--accent-rgb), 0.38); stroke-width: 1.1; }
.fx--r1 { stroke: rgba(var(--accent-rgb), 0.60); stroke-width: 1.4; }
.fx--r2 { stroke: rgba(var(--accent-rgb), 0.46); stroke-width: 1.2; }
.fx--r3 { stroke: rgba(var(--accent-rgb), 0.32); }
.fx--r4 { stroke: rgba(var(--accent-rgb), 0.20); }
.fx-core-fill { fill: rgba(var(--accent-rgb), 0.055); stroke: none; }

/* a soft bloom under the whole jewel. On paper this is what gives it WEIGHT —
   the dark mark casts onto the page instead of glowing off it. */
.fx-halo {
  fill: rgba(var(--accent-rgb), 0.05); stroke: none;
  filter: blur(26px);
}

.fx-node { fill: var(--accent-strong); filter: drop-shadow(0 1px 2px rgba(var(--accent-rgb), 0.45)); }
.fx-heart {
  fill: url(#metal);   /* not a flat fill — the ramp is what makes it metal */
  filter: drop-shadow(0 8px 20px rgba(var(--accent-rgb), 0.32)) drop-shadow(0 2px 5px rgba(16, 24, 40, 0.20));
}

/* --- Orbiting satellites (reclaimed from V0.1) ---
   .orbiter turns about the jewel's centre; .orbiter__upright cancels that turn
   about the satellite's own centre, so it travels the orbit without ever
   tilting. Durations and directions MUST match within a pair — mismatch them
   and the satellite slowly rolls, which is exactly the rectangle problem that
   killed rotation in V0.2. */
.orbiter { transform-box: view-box; transform-origin: 320px 320px; }
.orbiter__upright { transform-box: fill-box; transform-origin: center; }
@keyframes orbit-run     { to { transform: rotate(360deg); } }
@keyframes orbit-upright { to { transform: rotate(-360deg); } }

.orbiter--a                    { animation: orbit-run     44s linear infinite; }
.orbiter--a .orbiter__upright  { animation: orbit-upright 44s linear infinite; }
.orbiter--b                    { animation: orbit-run     66s linear infinite reverse; }
.orbiter--b .orbiter__upright  { animation: orbit-upright 66s linear infinite reverse; }
.orbiter--c                    { animation: orbit-run     88s linear infinite; }
.orbiter--c .orbiter__upright  { animation: orbit-upright 88s linear infinite; }

/* --- motion. The rings must NOT rotate: these diamonds are taller than wide, so
       any rotation turns them into tilted rectangles and the diamond read — the
       whole point of the motif — is lost. Instead each ring breathes about the
       shared centre on its own non-harmonic clock, so the jewel pulses like light
       moving through a gem and the silhouette stays a diamond at every frame. --- */
@keyframes ring-breathe {
  0%, 100% { transform: scale(1);     opacity: 0.72; }
  50%      { transform: scale(1.045); opacity: 1; }
}
@keyframes fx-twinkle {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}
@keyframes fx-pulse {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.14); }
}
@keyframes fx-drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-12px); }
}

.facets svg { animation: fx-drift 28s ease-in-out infinite; }

/* durations are deliberately non-harmonic — the four rings never resync, so the
   pulse never reads as a repeating sonar ping */
.ring--1 { animation: ring-breathe 9s   ease-in-out infinite; }
.ring--2 { animation: ring-breathe 11.5s ease-in-out infinite; animation-delay: -2.2s; }
.ring--3 { animation: ring-breathe 14s   ease-in-out infinite; animation-delay: -5.1s; }
.ring--4 { animation: ring-breathe 17.5s ease-in-out infinite; animation-delay: -8.4s; }

.fx-node { animation: fx-twinkle 6s ease-in-out infinite; }
.nd--a { animation-delay: -0.4s } .nd--b { animation-delay: -1.9s }
.nd--c { animation-delay: -3.1s } .nd--d { animation-delay: -4.6s }
.nd--e { animation-delay: -2.3s } .nd--f { animation-delay: -5.2s }
.nd--g { animation-delay: -1.1s } .nd--h { animation-delay: -3.8s }
.nd--i { animation-delay: -0.9s } .nd--j { animation-delay: -4.1s }
.nd--k { animation-delay: -2.7s } .nd--l { animation-delay: -5.6s }
.nd--m { animation-delay: -1.5s } .nd--n { animation-delay: -3.4s }
.nd--o { animation-delay: -5.9s } .nd--p { animation-delay: -2.1s }

.fx-heart { animation: fx-pulse 7s ease-in-out infinite; }

/* hero line-reveal on load (only hidden when JS is present to reveal it) */
.js .reveal-line { opacity: 0; transform: translateY(18px); }
.js body.is-ready .reveal-line {
  animation: line-in 0.9s var(--ease) forwards;
}
.hero__eyebrow.reveal-line { animation-delay: 0.05s; }
.hero__title .reveal-line:nth-child(1) { animation-delay: 0.16s; }
.hero__title .reveal-line:nth-child(2) { animation-delay: 0.28s; }
.hero__rule.reveal-line { animation-delay: 0.40s; }
.hero__promise.reveal-line { animation-delay: 0.48s; }
.hero__sub.reveal-line { animation-delay: 0.60s; }
.hero__cta.reveal-line { animation-delay: 0.72s; }
.hero__proof.reveal-line { animation-delay: 0.88s; }
/* No filter on the hero lines: a lingering filter layer (even blur(0)) disables
   subpixel AA and softens the text vs. the other versions. Rise + fade only.
   This matters MORE on paper than it did on black — dark-on-light is exactly
   where subpixel AA does its most visible work. */
@keyframes line-in { to { opacity: 1; transform: none; } }

/* ---- 01 · About / two-column ---- */
.about__grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.about__statement { margin-top: 1.3rem; line-height: 1.22; }
.about__statement em { color: var(--accent); }
.about__body .lead { margin-bottom: 1.1rem; }
.about__body p + p { margin-top: 1.1rem; }

/* ============================ 02 · THE GAP ============================ */
.gap { text-align: center; overflow: hidden; }
.gap .kicker { margin-bottom: 2rem; }
.gap__quote {
  margin: 0 auto; max-width: 22ch; font-family: var(--serif);
  font-size: var(--fs-statement); line-height: 1.18; color: var(--text);
  font-weight: var(--w-head); letter-spacing: -0.015em;
}
.gap__quote em { color: var(--accent); }
.gap__resolve {
  margin: 1.8rem auto 0; max-width: 40ch; color: var(--body);
  font-size: var(--fs-lead);
}
.gap__rule { max-width: 220px; margin: 2.8rem auto 0; }

/* ---- Vision / Mission (north star band) ---- */
.northstar__rule { max-width: 260px; margin: 0 auto clamp(2.6rem, 5vw, 3.6rem); }
.vm { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
.vm__card {
  background: var(--surface); border: 1px solid var(--hair);
  border-radius: var(--radius); padding: clamp(1.8rem, 3vw, 2.6rem);
  position: relative; overflow: hidden;
  box-shadow: var(--shadow-card);
}
.vm__card::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 2px;
  background: linear-gradient(var(--accent), transparent);
}
.vm__card .eyebrow { margin-bottom: 1rem; }
.vm__text {
  font-family: var(--serif); font-size: var(--fs-vm);
  line-height: 1.35; color: var(--text); font-weight: var(--w-head);
  letter-spacing: -0.01em;
}

/* ---- Values ---- */
.values { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }
.value { padding: 1.75rem 0 0; border-top: 1px solid var(--hair-2); position: relative; }
.value::before {
  content: ""; position: absolute; top: -1px; left: 0; width: 42px; height: 2px;
  background: var(--accent); transition: width 0.35s var(--ease);
}
.value:hover::before { width: 100%; }
.value h3 { margin-bottom: 0.6rem; }
.value p { font-size: var(--fs-body); color: var(--muted); }

/* ---- Services / The S ---- */
.svc { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.svc__card {
  background: var(--surface); border: 1px solid var(--hair);
  border-radius: var(--radius); padding: clamp(1.8rem, 2.8vw, 2.3rem);
  min-height: 15rem;
  box-shadow: var(--shadow-card);
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease), box-shadow 0.35s var(--ease);
  position: relative; overflow: hidden;
}
.svc__card::before { /* ghosted big index — a faint DARK ghost on paper */
  content: attr(data-n); position: absolute; right: 0.4rem; bottom: -1.2rem;
  /* 0.025, not the dark build's 0.02: ink-on-white at equal alpha reads slightly
     heavier than white-on-ink, so matching the NUMBER would overshoot the ghost */
  font-family: var(--serif); font-size: 8rem; line-height: 1; color: rgba(13, 20, 32, 0.025);
  pointer-events: none;
}
.svc__card::after { /* top accent sweep on hover */
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: 0; transition: opacity 0.35s var(--ease);
}
/* white is the ceiling, so the hover lift is carried by the SHADOW rather than by
   a step up in surface value the way it was on black */
.svc__card:hover {
  transform: translateY(-4px); border-color: var(--hair-accent);
  background: var(--surface-2); box-shadow: var(--shadow-lift);
}
.svc__card:hover::after { opacity: 1; }
.svc__num {
  font-family: var(--serif); font-size: 0.95rem; color: var(--accent-label);
  text-shadow: var(--glow-accent);
  font-variant-numeric: tabular-nums; letter-spacing: 0.05em;
  display: inline-block; margin-bottom: 1.1rem;
}
.svc__card h3 { margin-bottom: 0.7rem; position: relative; }
.svc__card p { font-size: var(--fs-body); color: var(--muted); position: relative; }
.svc__go {
  margin-top: 1.2rem; display: inline-flex; align-items: center; color: var(--accent);
  opacity: 0; transform: translateX(-6px); transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.svc__go svg { width: 20px; height: 20px; }
.svc__card:hover .svc__go { opacity: 1; transform: none; }

/* ---- Approach — connected diamond path ---- */
.approach { position: relative; }
.path { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; position: relative; }
.path::before {
  content: ""; position: absolute; top: 9px; left: 6%; right: 6%; height: 1px;
  background: linear-gradient(90deg, var(--hair-accent), var(--accent), var(--hair-accent)); opacity: 0.6;
}
.step { position: relative; padding-top: 2.6rem; }
.step__node {
  position: absolute; top: 3px; left: 0; width: 14px; height: 14px;
  background: var(--accent); transform: rotate(45deg);
  box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.10), 0 2px 8px rgba(var(--accent-rgb), 0.30);
}
.step__num { font-size: var(--fs-micro); letter-spacing: 0.2em; color: var(--accent-label);
  text-transform: uppercase; font-weight: 600; margin-bottom: 0.5rem; display: block;
  text-shadow: var(--glow-accent); }
.step h3 { margin-bottom: 0.55rem; }
.step p { font-size: var(--fs-body); color: var(--muted); }

/* ---- Contact ---- */
.contact { text-align: center; }
.contact__inner {
  max-width: 760px; margin-inline: auto;
  background: var(--surface); border: 1px solid var(--hair-accent);
  border-radius: 20px; padding: clamp(2.6rem, 6vw, 4.5rem);
  position: relative; overflow: hidden;
  box-shadow: var(--shadow-card);
}
.contact__inner::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(60% 60% at 50% 0%, rgba(var(--accent-rgb), 0.07), transparent 70%);
}
.contact__inner > * { position: relative; }
.contact__eyebrow { justify-content: center; }
.contact h2 { margin: 1rem 0; }
.contact .lead { max-width: 46ch; margin: 0 auto 2rem; }
.contact__cta { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; }
.contact__meta { margin-top: 2.2rem; color: var(--muted); font-size: 0.9rem;
  display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap; }
.contact__meta a { color: var(--body); border-bottom: 1px solid var(--hair-accent); }
.contact__meta a:hover { color: var(--accent-strong); }

/* ---- Footer ---- */
.footer { border-top: 1px solid var(--hair); padding-block: 3.5rem 2.5rem; }
.footer__grid { display: flex; justify-content: space-between; align-items: flex-start; gap: 2rem; flex-wrap: wrap; }
.footer__logo img { height: 42px; width: auto; margin-bottom: 1rem; }
.footer__tag { color: var(--muted); font-size: 0.92rem; max-width: 30ch; }
.footer__keys { display: flex; gap: 0.75rem; flex-wrap: wrap; color: var(--body);
  font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase; margin-top: 1.2rem; }
.footer__keys span { color: var(--accent-label); }
.footer__col h4 { font-family: var(--sans); font-size: var(--fs-micro); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 0.9rem; }
.footer__col a { display: block; color: var(--body); font-size: 0.92rem; margin-bottom: 0.4rem; }
.footer__col a:hover { color: var(--accent-strong); }
.footer__bottom { margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--hair);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; color: var(--muted); font-size: 0.82rem; }

/* ---- Scroll reveal ---- (initial hidden state applies ONLY when JS is active) */
.reveal { transition: opacity 0.8s var(--ease), transform 0.8s var(--ease), filter 0.8s var(--ease); }
.js .reveal { opacity: 0; transform: translateY(24px); filter: blur(4px); }
.reveal.is-in { opacity: 1; transform: none; filter: none; }
.reveal[data-delay="1"] { transition-delay: 0.08s; }
.reveal[data-delay="2"] { transition-delay: 0.16s; }
.reveal[data-delay="3"] { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; filter: none; transition: none; }
  .js .reveal-line { opacity: 1; transform: none; filter: none; animation: none !important; }
  .js .facets__stage { opacity: 1; transform: none; filter: none; animation: none !important; }
  .hero__scroll span { display: none; }
  /* jewel holds its finished pose: rings unrotated, nodes fully visible.
     Orbiters freeze as a pair, so they stop upright rather than mid-roll. */
  .facets svg, .ring, .fx-node, .fx-heart,
  .facets::before, .orbiter, .orbiter__upright,
  .jewel-aura, .fx-spark { animation: none !important; }
  .fx-node { opacity: 1; }
  .js .fx-facet { stroke-dashoffset: 0; animation: none !important; }
  .fx-spark { opacity: 0; }
}

/* ---- Responsive ---- */
@media (max-width: 1040px) {
  .facets { right: -20vw; opacity: 0.55; }
}
@media (max-width: 940px) {
  .about__grid { grid-template-columns: 1fr; }
  .svc { grid-template-columns: repeat(2, 1fr); }
  .values { grid-template-columns: repeat(2, 1fr); }
  .path { grid-template-columns: 1fr 1fr; }
  .path::before { display: none; }
  .hero__scroll { display: none; }
  /* keep the diamonds on small screens — they're the motif now — but drop them
     behind the type and well down in contrast so the headline still wins */
  .facets {
    right: -26vw; top: 40%; z-index: 1; opacity: 0.42;
    width: clamp(420px, 95vw, 620px);
  }
}
@media (max-width: 620px) {
  .vm { grid-template-columns: 1fr; }
  .svc { grid-template-columns: 1fr; }
  .values { grid-template-columns: 1fr; }
  .path { grid-template-columns: 1fr; }
  .footer__grid { flex-direction: column; }
  .hero__proof { display: none; }
  .facets { opacity: 0.34; }
}

/* =========================================================================
   PREVIEW HARNESS — not part of the Sidus design system.
   Two things that belong to the preview rather than to the brand:
     1. .vswitch — fixed version switcher, so a reviewer can reach the chooser
        or a sibling version from anywhere without using the Back button.
     2. .powered — the maker's credit in the footer.
   Both stay quiet on purpose: this must read as Naledi's site with NexusIQ as
   the enabler behind it, never as a co-brand.
   Delete this block (and its markup) when a version is promoted to production.
   ========================================================================= */

/* ---- Version switcher ---- */
.vswitch {
  position: fixed; z-index: 80;
  left: 50%; bottom: 1rem; transform: translateX(-50%);
  display: flex; align-items: center; gap: 0.2rem;
  padding: 0.32rem 0.38rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.88);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  backdrop-filter: saturate(140%) blur(14px);
  border: 1px solid var(--hair-2);
  box-shadow: 0 10px 30px -12px rgba(16, 24, 40, 0.30);
  font-family: var(--sans); font-size: 0.73rem; line-height: 1;
}
.vswitch__all {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.42rem 0.72rem; border-radius: 999px;
  color: var(--body); letter-spacing: 0.02em; white-space: nowrap;
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.vswitch__all::before {
  content: ""; width: 6px; height: 6px; background: var(--accent);
  transform: rotate(45deg); flex: none;
}
.vswitch__all:hover { color: var(--text); background: rgba(13, 20, 32, 0.06); }
.vswitch__rule { width: 1px; height: 15px; background: var(--hair-2); margin-inline: 0.18rem; flex: none; }
.vswitch__v {
  padding: 0.42rem 0.6rem; border-radius: 999px;
  color: var(--muted); font-weight: 600; letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.vswitch__v:hover { color: var(--text); background: rgba(13, 20, 32, 0.06); }
.vswitch__v.is-current {
  color: #F6F9FF; background: linear-gradient(180deg, var(--accent), var(--accent-strong));
}
.vswitch__v.is-soon { opacity: 0.38; cursor: default; }
.vswitch__v.is-soon:hover { background: none; color: var(--muted); }

/* ---- Maker's credit ----
   The NexusIQ lockup is used exactly as supplied: its own brand guide forbids
   recolouring or restyling it. Because THIS version is a light ground, the
   correct supplied asset is the LIGHT-background lockup (nexusiq-apex-ink.png,
   rendered from the guide's logos/nexusiq-logo-full.svg) — not the white one the
   dark versions use, which would be invisible here. Same rule, opposite asset:
   it fits by being SMALL and well spaced, never by being recoloured to her palette.
   Height 30px keeps it above the guide's 120px minimum lockup width. */
.powered {
  margin-top: 2.4rem; padding-top: 1.8rem;
  border-top: 1px solid var(--hair);
  display: flex; flex-direction: column; align-items: center; gap: 0.9rem;
  text-align: center;
}
.powered__label {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--muted); opacity: 0.75;
}
.powered__logo { display: inline-block; }
.powered__logo img { height: 30px; width: auto; }
.powered__legal {
  font-size: 0.7rem; color: var(--muted); opacity: 0.6; letter-spacing: 0.01em;
  max-width: 68ch; line-height: 1.5;
}

/* The switcher is position:fixed, so it floats over whatever is at the bottom of
   the page — without this it sits on top of the last line of her footer (the
   company registration number). Reserve its height plus breathing room. */
.footer { padding-bottom: 5.5rem; }

/* Same problem at the top of the page: the hero's decorative proof strip lives
   bottom-centre too, and the pill lands squarely on "Botswana & beyond". Lift
   the strip clear while the harness is present — it goes back when this block
   is deleted. Must clear the strip's wrapped two-line height at ~700px wide. */
.hero__proof { bottom: 5.2rem; }

@media (max-width: 620px) {
  /* The pill row grows every time a version is added. At seven pills it already
     overran a 390px viewport — SILENTLY, because body{overflow-x:hidden} clips it
     instead of scrolling, so the outermost version just vanished off the edge.
     Two fixes, belt and braces: tighten the pills so the common 390px case still
     fits outright, and cap the bar to the viewport with a scroll so no version is
     ever unreachable however many get added later.
     flex:none is load-bearing — flex items shrink by default, so without it the
     pills squash to fit instead of scrolling. */
  .vswitch {
    font-size: 0.68rem; gap: 0.1rem;
    max-width: calc(100vw - 1.5rem);
    overflow-x: auto;
    scrollbar-width: none;
    justify-content: flex-start;
  }
  .vswitch::-webkit-scrollbar { display: none; }
  .vswitch__all span { display: none; }  /* diamond only, keep the pill narrow */
  .vswitch__all { padding-inline: 0.6rem; flex: none; }
  .vswitch__v { padding-inline: 0.42rem; flex: none; }
  .vswitch__rule { margin-inline: 0.1rem; }
}
