@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@800&family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400&display=swap");

/* ==========================================================================
   Newegg Skills LP — base.css
   Design system: Newegg 2026 Guidelines
   · Content   1500px max content width, applied to every container
   · Type      Montserrat ExtraBold (display) / Open Sans (all else)
   · Buttons   pill 40px radius, DS size tokens, DS colors, fa-caret-right
   · Spacing   strict 8px rhythm
   · Floor     no type below 12px
   · Contrast  WCAG AAA (7:1 normal, 4.5:1 large)
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root {
  /* Brand */
  --ne-blue: #002d6a;          /* BL13 */
  --ne-yellow: #fa9d28;        /* DS primary button default */
  --ne-yellow-hover: #ffb25d;  /* DS primary button hover  */
  --ne-yellow-active: #ff8500; /* DS primary button active */
  --ne-btn-txt: #212121;       /* DS primary button label  */
  --ne-blue-btn: #1061cd;      /* BL10 — DS secondary default */
  --ne-blue-btn-hover: #4d86e5;
  --ne-blue-btn-active: #084ba6;

  /* Surfaces */
  --navy-base: #030a2e;
  --navy-deep: #01061f;
  --hairline: rgba(150, 176, 230, 0.18);
  --hairline-strong: rgba(150, 176, 230, 0.34);

  /* Text on dark — all verified ≥7:1 */
  --text-hi: #ffffff;
  --text-body: #ccd5e6;
  --text-muted: #aab7d1;
  --text-accent: var(--ne-yellow);

  /* Type scale — Newegg DS, desktop */
  --fs-display: 56px;
  --fs-h2: 28px;        --lh-h2: 36px;
  --fs-t1: 24px;        --lh-t1: 32px;
  --fs-t2: 20px;        --lh-t2: 24px;
  --fs-t3: 18px;        --lh-t3: 24px;
  --fs-t4: 16px;        --lh-t4: 22px;
  --fs-b1: 16px;        --lh-b1: 22px;
  --fs-b2: 14px;        --lh-b2: 20px;
  --fs-b3: 12px;        --lh-b3: 16px;   /* floor */

  /* Spacing — 8px rhythm */
  --s1: 8px;   --s2: 16px;  --s3: 24px;  --s4: 32px;
  --s5: 40px;  --s6: 48px;  --s7: 64px;  --s8: 80px;
  --s9: 96px;  --s10: 120px;

  /* Content width — 1500px across the whole page */
  --wrap: 1500px;
  --wrap-mid: 1100px;
  --wrap-narrow: 900px;

  --radius-btn: 40px;   /* DS: pill on every button size/variant */
  --radius-card: 16px;
  --radius-sm: 8px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--navy-base);
  color: var(--text-body);
  font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: var(--fs-b1);
  line-height: var(--lh-b1);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }

h1, h2, h3, h4 { margin: 0; color: var(--text-hi); font-weight: 700; }

.display {
  font-family: "Montserrat", "Open Sans", sans-serif;
  font-weight: 800;
  letter-spacing: -0.015em;
}

/* every container on the page runs to the same 1500px measure */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--s3);
}

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

:focus-visible {
  outline: 3px solid var(--ne-yellow);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ---------- 3. Buttons — Newegg DS §5 ----------
   Pill radius 40px on every variant and size.
   Primary #FA9D28 with the DS #212121 label → 7.6:1
   Arrow is the Newegg fa-caret-right, 4px gap per DS §5.7           */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  cursor: pointer;
  overflow: hidden;
  border-radius: var(--radius-btn);
  font-family: inherit;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
    border-color 0.2s var(--ease);
}
.btn .fa { font-size: 0.9em; line-height: 1; }

/* DS size tokens */
.btn--xxxl { height: 48px; padding-inline: 40px; font-size: 16px; line-height: 22px; }
.btn--l    { height: 40px; padding-inline: 36px; font-size: 15px; line-height: 20px; }
.btn--s    { height: 32px; padding-inline: 32px; font-size: 14px; line-height: 20px; }

.btn--primary { background: var(--ne-yellow); color: var(--ne-btn-txt); }
.btn--primary:hover { background: var(--ne-yellow-hover); }
.btn--primary:active { background: var(--ne-yellow-active); }

/* --- Shiny primary CTA ---------------------------------------------------
   The reference effect on a Newegg-orange fill. The reference sits on a
   near-black button, so its near-white interior washes (dots, shimmer, inner
   glow) read as light on dark. Dropped straight onto orange those same layers
   just desaturate the fill, which is what made the hover look wrong — so the
   ring is now the hero, the interior washes are dialled right back, and the
   hover glow moved OUTSIDE the button as an orange halo.
   Every layer still only lightens, so the #212121 label's 7.6:1 on #FA9D28
   remains the floor.
   @property registration is what makes the conic angle animatable; the same
   values are declared inline so unsupported engines get a static orange pill. */
@property --shiny-angle   { syntax: "<angle>";      initial-value: 0deg; inherits: false; }
@property --shiny-offset  { syntax: "<angle>";      initial-value: 0deg; inherits: false; }
@property --shiny-percent { syntax: "<percentage>"; initial-value: 8%;   inherits: false; }
@property --shiny-shine   { syntax: "<color>";      initial-value: #fff; inherits: false; }

.btn--shiny {
  /* fallbacks for engines without @property */
  --shiny-angle: 0deg;
  --shiny-offset: 0deg;
  --shiny-percent: 8%;
  --shiny-shine: #fff;

  --shiny-bg: var(--ne-yellow);
  --shiny-ring: #ffd9a0;
  --shiny-ring-hot: #ffffff;
  --shiny-duration: 4s;
  --shiny-transition: 500ms cubic-bezier(0.25, 1, 0.5, 1);

  position: relative;
  isolation: isolate;
  overflow: hidden;
  outline-offset: 4px;
  border: 2px solid transparent;
  color: var(--ne-btn-txt);
  background:
    linear-gradient(var(--shiny-bg), var(--shiny-bg)) padding-box,
    conic-gradient(
      from calc(var(--shiny-angle) - var(--shiny-offset)),
      transparent,
      var(--shiny-ring) var(--shiny-percent),
      var(--shiny-shine) calc(var(--shiny-percent) * 2),
      var(--shiny-ring) calc(var(--shiny-percent) * 3),
      transparent calc(var(--shiny-percent) * 4)
    ) border-box;
  background-color: var(--shiny-bg);
  box-shadow: 0 0 0 0 rgba(250, 157, 40, 0);
  transition: var(--shiny-transition);
  transition-property: --shiny-offset, --shiny-percent, --shiny-shine, box-shadow;
  animation: shiny-angle var(--shiny-duration) linear infinite;
}

.btn--shiny::before,
.btn--shiny::after {
  content: "";
  pointer-events: none;
  position: absolute;
  inset-inline-start: 50%;
  inset-block-start: 50%;
  translate: -50% -50%;
  z-index: -1;
}

/* fine sparkle texture — subtle enough not to grey the orange */
.btn--shiny::before {
  --position: 2px;
  --space: calc(var(--position) * 2);
  width: calc(100% - 6px);
  height: calc(100% - 6px);
  background: radial-gradient(circle at var(--position) var(--position),
    #fff calc(var(--position) / 4), transparent 0) padding-box;
  background-size: var(--space) var(--space);
  background-repeat: space;
  -webkit-mask-image: conic-gradient(from calc(var(--shiny-angle) + 45deg), #000, transparent 12% 88%, #000);
  mask-image: conic-gradient(from calc(var(--shiny-angle) + 45deg), #000, transparent 12% 88%, #000);
  border-radius: inherit;
  opacity: 0.16;
  animation: shiny-angle var(--shiny-duration) linear infinite;
}

/* slow sweeping highlight across the fill */
.btn--shiny::after {
  width: 100%;
  aspect-ratio: 1;
  background: linear-gradient(-50deg, transparent, #fff, transparent);
  -webkit-mask-image: radial-gradient(circle at bottom, transparent 42%, #000);
  mask-image: radial-gradient(circle at bottom, transparent 42%, #000);
  opacity: 0.18;
  animation: shiny-shimmer calc(var(--shiny-duration) * 2.5) linear infinite;
}

.btn--shiny > span { position: relative; z-index: 1; }

/* hover: the ring widens and goes white, and the glow sits OUTSIDE the
   button so the fill itself stays a clean Newegg orange */
.btn--shiny:is(:hover, :focus-visible) {
  --shiny-percent: 26%;
  --shiny-offset: 95deg;
  --shiny-shine: var(--shiny-ring-hot);
  box-shadow: 0 6px 28px rgba(250, 157, 40, 0.45);
}
.btn--shiny:active { --shiny-bg: var(--ne-yellow-active); translate: 0 1px; }

@keyframes shiny-angle   { to { --shiny-angle: 360deg; } }
@keyframes shiny-shimmer { to { rotate: 360deg; } }

/* Outline — DS outline is white-on-light; adapted for the dark canvas,
   keeping the 2px border weight and pill radius. */
.btn--white { background: #fff; color: var(--ne-btn-txt); }   /* 15.9:1 */
.btn--white:hover { background: #f2f2f2; }   /* GY2 */

.btn--outline {
  background: transparent;
  color: var(--text-hi);
  border: 2px solid var(--hairline-strong);
}
.btn--outline:hover { border-color: var(--ne-yellow); color: var(--ne-yellow); }

/* Reveal on scroll */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--d, 0s);
}
.reveal.is-visible { opacity: 1; transform: none; }

/* Opacity-only reveal — for elements that carry their own transform
   (the fanned hero cards), where 'transform: none' would flatten them. */
.fade-in {
  opacity: 0;
  transition: opacity 0.7s var(--ease);
  transition-delay: var(--d, 0s);
}
.fade-in.is-visible { opacity: 1; }

/* ---------- 4. Section rhythm ---------- */
.section { position: relative; padding-block: var(--s9); }

.section__head {
  text-align: center;
  max-width: var(--wrap-mid);
  margin: 0 auto var(--s6);
}
.section__head h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); }
.section__head p {
  margin: var(--s2) auto 0;
  max-width: min(1300px, 100%);   /* spans the section like the hero sub */
  color: var(--text-muted);
  font-size: var(--fs-b1);
  line-height: 24px;
}

.eyebrow {
  font-size: var(--fs-b3);
  line-height: var(--lh-b3);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-accent);
  margin: 0 0 var(--s2);
}

/* ---------- 5. Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--navy-deep);
  padding-block: var(--s9) var(--s8);
}

/* (background plate and ring shader removed — the tilted tile wall is now the hero background) */

/* the open hand the cards sit in — clean cut-out, no mask needed */
.hero__hand {
  display: none;   /* hidden per direction — art now carried by the tile wall */
  position: absolute;
  z-index: 1;
  left: 50%;
  top: clamp(110px, 13vw, 212px);
  width: clamp(430px, 45vw, 700px);
  aspect-ratio: 537 / 398;
  transform: translateX(-50%);
  background: url("assets/hero-hand.webp") center / contain no-repeat;
  filter: drop-shadow(0 30px 60px rgba(0, 3, 20, 0.55));
  pointer-events: none;
}

/* Tilted tiles: a wall of real builds from the Newegg Gallery, tipped back in
   3D and scrolling past in columns at different speeds (alternate columns run
   the other way). Each column holds its tile list twice and slides exactly
   one list length per cycle, so the loop is seamless. The wall is sized well
   past the hero so the tilt never exposes an edge. It is art: non-interactive,
   independent of the content height, and paused when the hero is off-screen. */
.hero__tiles {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
  perspective: 1500px;
  perspective-origin: 50% 40%;
}
.tiles__wall {
  --tile-w: 440px;          /* column width; the JS reads this to decide how many columns */
  --tile-gap: 16px;
  position: absolute;
  left: 50%;
  top: 50%;
  width: 190%;
  height: 230%;
  display: flex;
  gap: var(--tile-gap);
  justify-content: center;
  transform: translate(-50%, -50%) rotateX(24deg) rotateZ(-14deg);
  transform-style: preserve-3d;
  backface-visibility: hidden;
}
.tiles__col {
  flex: 0 0 var(--tile-w);
  width: var(--tile-w);
  height: 100%;
  overflow: hidden;
  transform: translateZ(0);
}
.tiles__track {
  display: flex;
  flex-direction: column;
  gap: var(--tile-gap);
  will-change: transform;
  animation: tiles-scroll var(--dur, 80s) linear infinite;
}
.tiles__col--rev .tiles__track { animation-direction: reverse; }
.hero__tiles.is-idle .tiles__track { animation-play-state: paused; }
.tiles__track img {
  display: block;
  width: 100%;
  height: auto;              /* the height attribute must not pin the box */
  aspect-ratio: 560 / 420;   /* landscape tiles, wider than tall */
  object-fit: cover;
  border-radius: 10px;
  opacity: 0.9;
  background: var(--navy-base);
}
@keyframes tiles-scroll {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }   /* one full copy of the list */
}
/* A navy veil keeps the wall in the background and the copy readable. The
   worst case the photos can reach under it is about rgb(47,51,69); the band
   behind the headline (see .hero__copy::before) goes darker still. The last
   layer fades the wall into rgb(2,8,31): what the vortex field below shows
   at its top edge (navy-base under its scrim), so the hero hands off to the
   content below without a visible seam. */
.tiles__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, transparent calc(100% - 300px), rgb(2, 8, 31) 100%),
    linear-gradient(180deg, rgba(1, 6, 31, 0.82) 0%, rgba(1, 6, 31, 0.70) 35%, rgba(1, 6, 31, 0.74) 100%),
    radial-gradient(ellipse 60% 55% at 50% 60%, rgba(1, 6, 31, 0.38), transparent 70%);
}

/* floating components */
.hero__part {
  position: absolute;
  z-index: 2;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
  filter: drop-shadow(0 18px 34px rgba(0, 3, 20, 0.6));
}
.hero__part--gpu { left: 22%;  top: 92px; width: clamp(126px, 12.5vw, 224px); aspect-ratio: 728 / 696; background-image: url("assets/part-gpu.webp"); animation: float 9s ease-in-out infinite; }
.hero__part--fan { left: 36%;  top: 56px; width: clamp(60px,  5.8vw, 104px);  aspect-ratio: 770 / 785; background-image: url("assets/part-fan.webp"); animation: float 7.5s ease-in-out infinite 0.6s; }
.hero__part--cpu { right: 35%; top: 96px; width: clamp(66px,  6.6vw, 118px);  aspect-ratio: 817 / 753; background-image: url("assets/part-cpu.webp"); animation: float 8.4s ease-in-out infinite 1.2s; }
.hero__part--aio { right: 20%; top: 50px; width: clamp(76px,  7.4vw, 136px);  aspect-ratio: 548 / 920; background-image: url("assets/part-aio.webp"); animation: float 10s ease-in-out infinite 0.3s; }

@keyframes float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-14px) rotate(-1.2deg); }
}

.hero__inner { position: relative; z-index: 3; display: flex; flex-direction: column; }

/* --- 5a. Skill cards: fanned, overlapping, portrait --- */
.skillcards {
  position: relative;
  z-index: 1;   /* above the headline band, whose feather starts under the card bottoms */
  display: flex;
  justify-content: center;
  align-items: flex-start;
  perspective: 1800px;
  margin-top: clamp(72px, 7.5vw, 120px);
  /* the dropped, rotated side cards reach ~50px below the row box; this
     keeps their lowest corner clear of the headline at every width */
  margin-bottom: clamp(64px, 5.5vw, 88px);
}

.skillcard {
  position: relative;
  flex: none;
  width: clamp(270px, 19.8vw, 380px);      /* 380px on a 1920 screen */
  min-height: clamp(240px, 17vw, 324px);   /* portrait */
  display: flex;
  flex-direction: column;
  padding: var(--s3);
  border-radius: var(--radius-card);
  text-align: left;
  isolation: isolate;
  background: linear-gradient(158deg, rgba(11, 30, 88, 0.97) 0%, rgba(6, 18, 62, 0.98) 55%, rgba(3, 11, 42, 0.98) 100%);
  border: 1px solid rgba(120, 150, 210, 0.16);
  overflow: visible;
  box-shadow:
    0 2px 4px rgba(0, 3, 20, 0.5),
    0 14px 28px rgba(0, 3, 20, 0.55),
    0 34px 66px rgba(0, 3, 20, 0.5),
    inset 0 -1px 0 rgba(0, 0, 0, 0.4);
}

/* the fan: side cards rotate out and drop, centre card sits forward */
.skillcard--l { transform: rotate(-7deg) translateY(40px); margin-right: -20px; z-index: 1; transform-origin: bottom right; }
.skillcard--c { transform: translateY(-8px) scale(1.03); z-index: 3; }
.skillcard--r { transform: rotate(7deg) translateY(40px);  margin-left: -20px;  z-index: 1; transform-origin: bottom left; }



.skillcard__stars { position: absolute; inset: -18px; pointer-events: none; z-index: 3; }

.spark {
  position: absolute;
  width: var(--s, 16px);
  height: var(--s, 16px);
  transform: translate(-50%, -50%) scale(0.4);
  opacity: 0;
  background: #fff;
  clip-path: polygon(50% 0%, 59% 36%, 96% 44%, 62% 55%, 50% 100%, 38% 55%, 4% 44%, 41% 36%);
  filter: drop-shadow(0 0 6px rgba(255, 214, 150, 0.95));
  animation: twinkle var(--dur, 3.4s) ease-in-out infinite var(--delay, 0s);
}
.spark--gold { background: #ffd08a; }

@keyframes twinkle {
  0%, 100% { opacity: 0;    transform: translate(-50%, -50%) scale(0.35) rotate(0deg); }
  40%      { opacity: 1;    transform: translate(-50%, -50%) scale(1)    rotate(35deg); }
  62%      { opacity: 0.55; transform: translate(-50%, -50%) scale(0.78) rotate(60deg); }
}

/* badge sits at the top, copy anchors to the bottom (per the reference) */
.skillcard__label {
  align-self: center;
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-b3);
  line-height: var(--lh-b3);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  gap: 10px;
  color: var(--ne-yellow);
  /* No chip, border or pill: the cards are not clickable and the label must
     not read as a button. A short amber rule on each side marks it instead. */
  padding: 2px 0;
}
.skillcard__label::before,
.skillcard__label::after {
  content: "";
  width: 18px;
  height: 2px;
  border-radius: 1px;
  background: var(--ne-yellow);
  opacity: 0.8;
}

.skillcard__body { padding-top: var(--s2); position: relative; z-index: 1; }
.skillcard__label { position: relative; z-index: 1; }
.skillcard { padding-bottom: clamp(176px, 16vw, 234px); }

/* Hero cards carry a real photo across the bottom. The strip is cropped
   (object-fit: cover) so it always reads as a cut-off frame, and a gradient
   in the card's own colour dissolves its top edge into the panel. */
.skillcards .skillcard { --photo-h: clamp(150px, 12.5vw, 220px); padding-bottom: calc(var(--photo-h) + 14px); }

.skillcard__photo {
  position: absolute;
  inset: auto 0 0 0;
  height: var(--photo-h);
  overflow: hidden;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  z-index: 0;
  pointer-events: none;
}
.skillcard__photo img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 205%;
  height: 205%;
  object-fit: cover;
  object-position: 50% 45%;
  /* Oversized so the rotated rectangle always overshoots the strip and its
     own edges are clipped away — nothing left for a gradient to hide.
     205% is set by the worst case (the wide, short strip on phones, which
     needs 1.92x); desktop only needs ~1.70x. */
  transform: translate(-50%, -50%) rotate(-25deg);
}


/* product icon anchored to the bottom, copy stacked above it */
/* clips the icon to the card without clipping the sparkle layer */
/* label sits flush left over the title, no rules */
.trust__card .skillcard__label { align-self: flex-start; text-align: left; }
.trust__card .skillcard__label::before,
.trust__card .skillcard__label::after { display: none; }

.trust__card .skillcard__iconwrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
}

.trust__card .skillcard__icon {
  position: absolute;
  /* The source art carries ~21% transparent padding each side and ~13%
     top/bottom. The box is sized in px (--icon-w, set on .trust__card) and
     offset by fractions of that same size, so the visible glyph always
     lands in the space the card reserves for it (see .trust__card
     padding-bottom) no matter how wide the grid makes the card. */
  left: calc(var(--icon-w) * -0.24);
  bottom: calc(var(--icon-w) * -0.28);
  width: var(--icon-w);
  max-width: none;   /* the global img cap would shrink it below the reserved band */
  height: auto;
  transform: rotate(-25deg);
  transform-origin: 50% 50%;
  filter: drop-shadow(0 14px 26px rgba(0, 3, 20, 0.6));
}
.skillcard h3 { font-size: var(--fs-t2); line-height: var(--lh-t2); margin-bottom: var(--s1); }
.skillcard p  { margin: 0; font-size: var(--fs-b2); line-height: var(--lh-b2); color: var(--text-body); }

/* --- 5b. Headline block, below the cards --- */
.hero__copy { position: relative; text-align: center; isolation: isolate; }
/* Soft navy glow centred on the headline block. It is sized to the copy
   (plus a margin on every side) and falls off radially, so the tile wall
   stays visible around and below it instead of being blanked out across the
   bottom of the hero. The seam into the next section is handled by the
   tile scrim's bottom fade, not by this glow. Under the glow's core the
   photos stay dark enough for the gradient phrase (>=5:1) and the white
   copy (>=15:1). */
.hero__copy::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -12vw;
  right: -12vw;
  top: -72px;
  bottom: -72px;
  /* same navy the tile fade and the vortex field use */
  background: radial-gradient(ellipse farthest-corner at 50% 50%,
    rgba(2, 8, 31, 0.9) 0%,
    rgba(2, 8, 31, 0.84) 42%,
    rgba(2, 8, 31, 0.5) 72%,
    rgba(2, 8, 31, 0) 100%);
  /* The ellipse only reaches zero at the box corners, so on its own it
     would still be about half opaque at the edge midpoints and print a
     hard line there. The mask feathers every edge to nothing. */
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 30%, #000 70%, transparent),
    linear-gradient(90deg,  transparent, #000 16%, #000 84%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(180deg, transparent, #000 30%, #000 70%, transparent),
    linear-gradient(90deg,  transparent, #000 16%, #000 84%, transparent);
  mask-composite: intersect;
  pointer-events: none;
}

.hero h1 {
  font-size: clamp(28px, 3.6vw, var(--fs-display));
  line-height: 1.14;
  max-width: min(1300px, 100%);
  margin-inline: auto;
  /* drop-shadow, not text-shadow — the gradient span is painted through
     transparent glyphs and a text-shadow would bleed through them */
  filter: drop-shadow(0 2px 14px rgba(0, 4, 26, 0.9));
}
.hero h1 em {
  font-style: normal;
  white-space: nowrap;
  font-size: 1.2em;   /* 20% larger than the rest of the headline */
  line-height: 1;   /* the phrase never breaks across lines */
  background: linear-gradient(122deg, #ffd08a 0%, var(--ne-yellow-active) 52%, #ff5b3d 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__sub {
  margin: var(--s3) auto 0;
  max-width: min(1300px, 100%);   /* >=1300px on a 1920 screen */
  font-size: var(--fs-b1);
  line-height: 24px;
  color: var(--text-body);
}

.hero__cta { margin-top: var(--s4); display: flex; flex-direction: column; align-items: center; gap: var(--s2); }
.hero__hint { font-size: var(--fs-b2); line-height: var(--lh-b2); color: var(--text-muted); }

/* ---------- 6. Install (+ neural vortex backdrop) ---------- */
.install {
  position: relative;
  /* The vortex can reach rgb(51,55,77) at its brightest. Measured over a full
     animation sweep, --text-muted only reaches 5.8:1 against that, so muted
     text is promoted to --text-body inside this section (9.5:1). */
  --text-muted: var(--text-body);
  background: transparent;
}

/* WebGL vortex — decorative, non-interactive, drifts on its own */
/* One continuous field spanning install → FAQ, on a deeper blue base */
.vortex-field {
  position: relative;
  isolation: isolate;
  /* Measured ceiling of the field is rgb(43,48,66): white 13.1:1 and
     --text-body 8.9:1 clear AAA, but --text-muted only reaches 6.5:1, so
     muted is promoted for every section sitting on the field. */
  --text-muted: var(--text-body);
  background:
    linear-gradient(180deg, #030a2e 0%, #04102f 18%, #050f2a 52%, #040c24 82%, var(--navy-base) 100%);
}

.vortex {
  /* Sticky + viewport height means the buffer never depends on how tall the
     field is, so opening a dropdown or an FAQ row cannot disturb it.
     The negative margin keeps it out of the field's height calculation. */
  position: sticky;
  top: 0;
  display: block;
  width: 100%;
  height: 100vh;
  margin-bottom: -100vh;
  z-index: 0;
  pointer-events: none;
  opacity: 0.62;
}

/* keeps text contrast deterministic over the animated field */
.vortex-scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* The first layer starts the field on the exact colour the hero tile wall
     fades to, then lets the vortex emerge over 200px: no seam at the join. */
  background:
    linear-gradient(180deg, rgb(2, 8, 31) 0, rgb(2, 8, 31) 24px, rgba(2, 8, 31, 0) 360px),
    linear-gradient(180deg,
    rgba(2, 7, 28, 0.82) 0%, rgba(2, 7, 28, 0.74) 30%,
    rgba(2, 7, 28, 0.74) 70%, rgba(2, 7, 28, 0.84) 100%);
}

.install > .wrap,
#faq > .wrap { position: relative; }

.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s6);
  margin-bottom: var(--s7);
}

.step { display: grid; grid-template-columns: auto 1fr; gap: var(--s3); align-items: start; }

.step__num {
  font-family: "Montserrat", sans-serif;
  font-weight: 800;
  font-size: 48px;
  line-height: 40px;
  color: var(--text-hi);
  opacity: 0.85;
}

.step h3 { font-size: var(--fs-t1); line-height: var(--lh-t1); margin-bottom: var(--s1); }
.step p  { margin: 0 0 var(--s3); font-size: var(--fs-b2); line-height: var(--lh-b2); color: var(--text-body); }

.step__meta {
  display: block;
  margin-top: var(--s2);
  font-size: var(--fs-b3);
  line-height: var(--lh-b3);
  color: var(--text-muted);
}

.step__path {
  font-weight: 700;
  color: var(--text-hi);
  background: rgba(150, 176, 230, 0.16);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  white-space: nowrap;
}

.moreways {
  max-width: var(--wrap-mid);
  margin-inline: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  background: rgba(5, 14, 48, 0.7);
}

.moreways summary {
  cursor: pointer;
  list-style: none;
  padding: var(--s3);
  font-size: var(--fs-b2);
  line-height: var(--lh-b2);
  font-weight: 700;
  color: var(--text-hi);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
}
.moreways summary::-webkit-details-marker { display: none; }
.moreways summary:hover { color: var(--ne-yellow); }
.moreways summary::after { content: "⌄"; font-size: var(--fs-b1); transition: transform 0.25s var(--ease); }
.moreways[open] summary::after { transform: rotate(180deg); }

.moreways__body { padding: 0 var(--s3) var(--s3); }

.way {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding-block: var(--s3);
  border-top: 1px solid var(--hairline);
}

.way__text { font-size: var(--fs-b2); line-height: var(--lh-b2); color: var(--text-body); }
.way__text strong { color: var(--text-hi); display: block; margin-bottom: 4px; }

code, .code {
  display: inline-block;
  margin-top: 6px;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: var(--fs-b3);
  line-height: var(--lh-b3);
  background: rgba(150, 176, 230, 0.14);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  color: #e7edfa;
}

/* ---------- 7. Ask — scrolling question rows ---------- */
.ask {
  position: relative;
  overflow: hidden;
  /* Same measured vortex ceiling as .install — muted text is promoted to
     --text-body so nothing sits below 7:1 over the animated field. */
  --text-muted: var(--text-body);
  padding-block: var(--s9);
  background: transparent;
}

.ask > .wrap { position: relative; }

.ask__rows {
  position: relative;
  display: grid;
  gap: var(--s2);
  margin-top: var(--s6);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.qrow { overflow: hidden; }
.qrow__track { display: flex; gap: var(--s2); width: max-content; will-change: transform; }

/* rows drift in alternating directions */
.qrow--a .qrow__track { animation: qscroll-l 150s linear infinite; }
.qrow--b .qrow__track { animation: qscroll-r 175s linear infinite; }

@keyframes qscroll-l { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes qscroll-r { from { transform: translateX(-50%); } to { transform: translateX(0); } }

.qpill {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  flex: none;
  border-radius: var(--radius-btn);
  background: rgba(4, 8, 24, 0.92);
  border: 1px solid var(--hairline);
  padding: 12px 24px 12px 18px;
  font-size: var(--fs-b1);
  line-height: var(--lh-b1);
  color: var(--text-body);
  white-space: nowrap;
}
.qpill__icon {
  flex: none;
  width: 22px;
  text-align: center;
  font-size: 15px;
  color: var(--text-hi);
}

/* ---------- 8. Works-with logos ---------- */
.workswith { padding-block: var(--s8); background: transparent; }



.logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s8);
}

/* normalised to a single monochrome weight so the row reads as one weight */
.logos__mark {
  height: 116px;   /* glyph marks (ChatGPT) */
  width: auto;
  opacity: 0.86;
  filter: brightness(0) invert(1);
}
.logos__mark--wide { height: 30px; }   /* wordmark lockups */

/* Claude Code = Claude glyph + Claude Code wordmark */
.logos__lockup { display: inline-flex; align-items: center; gap: 10px; }
.logos__glyph { height: 30px; width: auto; opacity: 0.86; }

/* ---------- 10. Security ---------- */
.security { background: transparent; --text-muted: var(--text-body); }

.trust { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s3); align-items: stretch; }

/* same card as the hero, minus the fan rotation */
.trust__card {
  /* icon box size; measured from the art's alpha bounds, the rotated glyph
     tops out 0.63–0.68 of this above the card's bottom edge, so the band
     below the copy reserves 0.70 of it plus a small gap */
  --icon-w: clamp(232px, 24vw, 320px);
  padding-bottom: calc(var(--icon-w) * 0.70 + 8px);
  width: auto;
  flex: initial;
  min-height: clamp(228px, 18vw, 280px);
  transform: none;
  /* same translucency as the FAQ rows */
  background: rgba(5, 14, 48, 0.7);
}

.faq { max-width: var(--wrap-mid); margin-inline: auto; }

.faq__item {
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: rgba(5, 14, 48, 0.7);
  margin-bottom: var(--s1);
  overflow: hidden;
  transition: border-color 0.2s var(--ease);
}
.faq__item:hover,
.faq__item.is-open { border-color: var(--hairline-strong); }

.faq__q {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  text-align: left;
  background: none; border: 0; cursor: pointer;
  color: var(--text-hi);              /* stays white when open — no accent shift */
  font-size: var(--fs-t4); line-height: var(--lh-t4); font-weight: 700;
  padding: var(--s3);
}

.faq__icon { flex: none; transition: transform 0.25s var(--ease); font-size: var(--fs-b1); color: var(--text-muted); }
.faq__item.is-open .faq__icon { transform: rotate(180deg); }

.faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.28s var(--ease); }
.faq__item.is-open .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }
.faq__a p {
  margin: 0;
  padding: 0 var(--s3) var(--s3);
  font-size: var(--fs-b2); line-height: var(--lh-b2);
  color: var(--text-body);
}
.faq__a a { color: #9fc2ff; text-decoration: underline; text-underline-offset: 2px; }

/* ---------- 12. Closing CTA (exploded build as the backdrop) ---------- */
.closer {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding-block: var(--s9) clamp(200px, 22vw, 320px);
  background: radial-gradient(58% 96% at 50% 0%, rgba(8, 24, 78, 0.62), rgba(1, 5, 22, 0) 70%), #01061c;
  border-top: 1px solid var(--hairline);
}

.closer__pc {
  position: absolute;
  z-index: 0;
  left: 50%;
  bottom: clamp(-190px, -14vw, -90px);
  width: min(1180px, 74%);
  aspect-ratio: 4096 / 3106;
  transform: translateX(-50%);
  background: url("assets/pc-exploded.webp") center bottom / contain no-repeat;
  opacity: 0.5;
  pointer-events: none;
}

/* the exploded build carries bright highlights — scrim keeps the
   tagline and sub-tagline deterministic (see audit notes) */
.closer__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(70% 62% at 50% 34%, rgba(3, 10, 46, 0.92) 0%, rgba(3, 10, 46, 0.82) 52%, rgba(3, 10, 46, 0.7) 100%);
}

.closer > .wrap { position: relative; z-index: 2; }
.closer h2 { font-size: clamp(26px, 3.4vw, 40px); line-height: 1.16; max-width: min(1300px, 100%); margin-inline: auto; }
.closer p { margin: var(--s3) auto 0; max-width: min(1300px, 100%); color: var(--text-body); line-height: 24px; }
.closer__actions { margin-top: var(--s5); display: flex; flex-wrap: wrap; gap: var(--s2); justify-content: center; align-items: center; }

/* ---------- 13. Scroll progress ---------- */
#progress {
  position: fixed; inset: 0 auto auto 0;
  height: 3px; width: 0; z-index: 100;
  background: linear-gradient(90deg, var(--ne-yellow-active), var(--ne-yellow));
}

/* ---------- 14. Responsive ---------- */
@media (max-width: 1199px) {
  .skillcard--l { margin-right: -12px; }
  .skillcard--r { margin-left: -12px; }
}

@media (max-width: 999px) {
  :root {
    --fs-display: 34px; --fs-h2: 24px;
    --fs-t1: 22px; --fs-t2: 19px; --fs-t3: 17px; --fs-t4: 15px;
    --fs-b1: 14px; --lh-b1: 20px;
    --s9: 64px; --s10: 80px;
  }
  /* The fan unwinds into a horizontal snap row that bleeds to the right
     edge. Tablets show two and a half cards, phones one and a half, so the
     cut-off card tells the reader there is more to swipe. The cards keep
     leading the hero, under a taller top margin that lets the tile wall
     show through before the content starts. */
  .tiles__wall { --tile-w: 230px; --tile-gap: 10px; }
  .skillcards {
    --card-gap: 10px;
    flex-direction: row;
    justify-content: flex-start;   /* centred content would clip the first card */
    align-items: stretch;
    gap: var(--card-gap);
    perspective: none;
    margin-top: var(--s2);
    margin-bottom: var(--s5);
    margin-inline: calc(-1 * var(--s3));
    padding-inline: var(--s3);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--s3);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .skillcards::-webkit-scrollbar { display: none; }
  .hero__hand { top: clamp(300px, 74vw, 520px); }
  /* the floating cut-outs would sit behind the card row here; hide them */
  .hero__part { display: none; }
  .skillcard {
    flex: 0 0 calc((100vw - var(--s3) - 2 * var(--card-gap)) / 2.5);
    width: auto;
    min-height: 0;
    scroll-snap-align: start;
  }
  .skillcard--l, .skillcard--c, .skillcard--r { transform: none; margin: 0; }
  .skillcard__body { padding-top: var(--s3); }
  .steps { grid-template-columns: 1fr; gap: var(--s4); }
  .trust { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .step__num { font-size: 40px; line-height: 34px; }
  .qpill { font-size: var(--fs-b2); line-height: var(--lh-b2); padding: 10px 20px 10px 14px; }
  .hero__hand { width: clamp(420px, 88vw, 640px); top: clamp(230px, 40vw, 380px); }
  .logos { gap: var(--s5); }
}

@media (max-width: 579px) {
  :root {
    --fs-display: 28px; --fs-h2: 19px;
    --fs-t1: 17px; --fs-t2: 17px; --fs-t3: 15px; --fs-t4: 14px;
    --fs-b1: 16px; --lh-b1: 22px;
    --s9: 56px;
  }
  .trust { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .trust__card { --icon-w: clamp(140px, 42vw, 232px); padding-top: var(--s2); padding-inline: var(--s2); }
  /* Phones: one and a half cards (~227px wide), full card text kept. */
  .skillcards .skillcard { flex-basis: calc((100vw - var(--s3) - var(--card-gap)) / 1.5); --photo-h: 96px; }
  .skillcards .skillcard__body { padding-top: var(--s2); }
  .skillcards .skillcard h3 { font-size: 16px; line-height: 21px; }
  .skillcards .skillcard p { font-size: 13px; line-height: 18px; }
  /* the amber rules do not fit beside the longest label at this width */
  .skillcards .skillcard__label { letter-spacing: 0.06em; text-align: center; justify-content: center; }
  .skillcards .skillcard__label::before,
  .skillcards .skillcard__label::after { display: none; }
  /* room above the row so the tile wall reads before the cards begin */
  .hero { padding-top: 72px; }
  .skillcards { margin-top: 0; margin-bottom: var(--s3); }
  .hero__sub { font-size: 14px; line-height: 20px; margin-top: var(--s2); }
  .hero__cta { margin-top: var(--s3); }
  .way { flex-direction: column; align-items: flex-start; }
  .btn--xxxl { height: 44px; padding-inline: 28px; font-size: 15px; line-height: 20px; }
  /* keep the four cut-outs from colliding on a narrow canvas */
  .hero__part--gpu { left: 1%;  top: 44px; width: 33vw; }
  .hero__part--fan { left: 37%; top: 16px; width: 15vw; }
  .hero__part--cpu { right: 30%; top: 62px; width: 16vw; }
  .hero__part--aio { right: 1%; top: 8px;  width: 19vw; }
  /* the gradient phrase is nowrap at 1.2em on desktop; on a phone that is
     wider than the headline itself and gets clipped — let it wrap here */
  .hero h1 em { white-space: normal; font-size: 1.06em; line-height: 1.1; }
  .logos { gap: var(--s4); }
  .logos__mark { height: 48px; }
  .logos__mark--wide { height: 22px; }
}

/* ---------- 15. Motion safety ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .spark { opacity: 0.85; transform: translate(-50%, -50%) scale(1); }
}
/*-------code fix from gavin--------*/
.closer {
  margin-bottom: -40px;
  max-height: 200px;
  padding-bottom: calc(clamp(200px, 22vw, 220px) + 120px);
}