/* ==========================================================================
   Advanced Sales Training. Site stylesheet, v2.
   BUILD: v2-r2-2026-08-31 (Rron's round 2: the whole page on the wide grid).
   Identity: "THE LASER MEETS THE ZINE". The stage is cold and obeys the light
   budget; the stickers are warm, matte, printed OBJECTS pasted onto it.

   COLOUR LAW, two halves:
     1. Everything that is LIGHT (beams, glows, the cursor, the motes, the CTA
        aura) stays in the locked cold palette. --live-wire and --sky-glow are
        NEVER text colours: beams, glows, icon accents, borders and rings only.
     2. Everything WARM lives INSIDE sticker artwork and nowhere else. There is
        not one warm hex value in this file, and there must never be one.

   LIGHT BUDGET (enforced here and in the beam controller):
     - one animated beam per viewport at a time
     - the glowing word ceiling is two; this page spends one, on the hero's
       "bloody". Nothing else on the page glows as type.
     - bloom never wider than 6x its stroke
     - the CTA is always the brightest object on screen: exactly one filled
       call button exists per viewport, and below the hero that is the
       final CTA. The nav's shortcut is a ghost.
     - nothing loops forever except the laser cursor, the one ticker band, and
       the CTA's aura breath (an opacity oscillation, no movement at all).

   CONTRAST NOTE: --slate passes AA on --deep-space (5.1:1) and --deep-field
   (4.9:1) but NOT on --panel (4.2:1). On panels use --silver (6.5:1).

   STILL MODE: html.still is set before first paint by ?still=1. Every
   entrance is authored at its end state, every loop is paused, and the cursor
   canvas is never built, so gate screenshots are reproducible.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  --deep-space: #060708;
  --deep-field: #0B0D10;
  --panel: #1B1F26;
  --live-wire: #2E6BFF;
  --sky-glow: #9DC4FF;
  --white-heat: #F4F6F9;
  /* LIFTED one step (client round 1, 2026-09-04: "the grey smaller text is a
     little harder to read on the black background"). Silver 9BA3AF to B4BBC6
     takes body copy from 7.9:1 to 10.4:1 against deep space; slate 778193 to
     939DAE takes the small mono lines from 5.2:1 to 7.4:1. White heat stays
     where it is, so the ladder still has three rungs. The small sizes went up
     a step in the same round; see the mono atoms. */
  --silver: #B4BBC6;
  --slate: #939DAE;

  --hairline: rgba(155, 163, 175, 0.13);
  --edge: rgba(46, 107, 255, 0.16);
  --edge-hot: rgba(46, 107, 255, 0.42);

  --font-display: "Clash Display", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Switzer", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  /* THE STAGE AND THE READING GRID ARE TWO DIFFERENT WIDTHS.

     They used to be one number, which is why the villain band was the only
     part of the page that breathed: widening the wrap would have widened
     every paragraph with it, and a 1560px stage sets body copy at about 150
     characters a line. So the two jobs are now separate tokens.

       --wrap     the STAGE. The nav, every section's content column, every
                  grid (JOLT, traits, the FAQ's twelve, the footer's twelve)
                  and the sticker anchor --half all measure against it.
       --measure  the READING GRID the column ladder below is cut from. It
                  does not move when the stage does, so --m3 to --m11 are the
                  same pixel values at a 1560 stage as they were at 1180 and
                  not one line of body copy got longer.

     Every measure on this page is still a whole number of these columns; no
     orphan ch or px measures survive. */
  --wrap: 1560px;
  --measure: 1180px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --col-gap: 24px;
  --colw: calc((var(--measure) - 11 * var(--col-gap)) / 12);
  --m3: calc(3 * var(--colw) + 2 * var(--col-gap));
  --m4: calc(4 * var(--colw) + 3 * var(--col-gap));
  --m5: calc(5 * var(--colw) + 4 * var(--col-gap));
  --m6: calc(6 * var(--colw) + 5 * var(--col-gap));
  --m7: calc(7 * var(--colw) + 6 * var(--col-gap));
  --m8: calc(8 * var(--colw) + 7 * var(--col-gap));
  --m9: calc(9 * var(--colw) + 8 * var(--col-gap));
  --m10: calc(10 * var(--colw) + 9 * var(--col-gap));
  --m11: calc(11 * var(--colw) + 10 * var(--col-gap));

  /* THE WRAP-RELATIVE ANCHOR. Distance from the centre of a full-width box to
     the content column's edge. Every sticker outside the content column is
     positioned against this rather than against a percentage of the section,
     so the collage is the SAME composition at 1440, 1920 and 2560 instead of
     scattering outward as the viewport grows. (Rron's round 1, note 1.)

     It carries a percentage, so it is only ever valid in a HORIZONTAL
     property: in `top` or `bottom` the percentage would resolve against the
     containing block's height and the number would be nonsense. */
  --half: calc(min(var(--wrap), 100%) / 2 - var(--gutter));

  --pad-y: clamp(4.5rem, 9vw, 8.5rem);
  --pad-top: clamp(5.5rem, 10vw, 9.5rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-slap: cubic-bezier(0.34, 1.42, 0.52, 1);
  --dur: 180ms;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--deep-space);
  color: var(--silver);
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.97rem + 0.16vw, 1.0625rem);
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* The sticker collage deliberately hangs past section edges. Sections clip
     sideways themselves; this is the last line of defence so no sticker can
     ever hand the document a horizontal scrollbar. */
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
ul, ol { margin: 0; padding: 0; list-style: none; }
p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  color: var(--white-heat);
  text-transform: uppercase;
  line-height: 0.98;
  letter-spacing: -0.015em;
  overflow-wrap: break-word;
}

a { color: inherit; }

::selection { background: rgba(46, 107, 255, 0.35); color: var(--white-heat); }

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

/* Positioning context for a sticker that belongs to one specific block of
   copy. Stickers are never inside a .reveal: a reveal owns opacity and a
   transform, and a sticker owns its own. */
.stage { position: relative; }

/* Parked above the viewport rather than at a large negative left: a box at
   x = -9999 is a horizontal overflow gate's problem for no benefit. */
.skip-link {
  position: absolute;
  left: 0.75rem;
  top: 0.75rem;
  z-index: 200;
  background: var(--white-heat);
  color: var(--deep-space);
  padding: 0.75rem 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-decoration: none;
  transform: translateY(-250%);
}
.skip-link:focus { transform: none; }

/* Available to assistive tech, invisible on screen. Carries the J O L T
   letters so the visible display letters can stay decorative. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 2px solid var(--live-wire);
  outline-offset: 3px;
  border-radius: 2px;
}

/* TOUCH TARGETS. On a coarse pointer nothing on this page may be smaller than
   a fingertip, and three things were: the footer's link row at 22px, which
   fails even the 24px minimum, and the wordmark and the nav button, both one
   pixel short of 44. The padding is scoped to coarse pointers so the desktop
   composition, which is measured and signed off, does not move by a pixel.
   The mailto link is left alone at 27px: it already clears the minimum, and
   padding under it would push its underline off the word. */
@media (pointer: coarse) {
  .footer__nav a { display: inline-block; padding-block: 0.7rem; }
  .nav__logo { padding-block: 2px; }
  .nav .btn--nav { padding-block: 0.65rem; }
}

/* --------------------------------------------------------------------------
   3. Shared type atoms
   -------------------------------------------------------------------------- */
/* No eyebrows, kickers or overlines anywhere. What survives in mono is DATA,
   not decoration: stat labels and sources, the attribution blocks, the
   footer's confirm tag, button microcopy, the delivery labels, the ticker,
   and the placeholder build tag. */

/* Build state tag on the placeholder testimonials. */
.warn-tag {
  margin: 1.1rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--silver);
}
.warn-tag::before {
  content: "";
  display: inline-block;
  width: 6px; height: 6px;
  margin-right: 0.6em;
  vertical-align: 0.1em;
  background: var(--live-wire);
}

.lede {
  max-width: var(--m5);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem);
  line-height: 1.6;
  color: var(--silver);
}
.lede p + p { margin-top: 0; }

/* Six columns is the page's default reading measure; sections step it
   between five and eight so the text edge never lands on the same x twice
   in a row. */
.prose { max-width: var(--m6); }
.prose--m5 { max-width: var(--m5); }
.prose--m6 { max-width: var(--m6); }
.prose--m7 { max-width: var(--m7); }
.prose--m8 { max-width: var(--m8); }
.prose--centre { max-width: var(--m6); margin-inline: auto; text-align: center; }

/* The villain's three blocks. Short, big, and set with a lot of air between
   them, because none of them is longer than a breath. */
.blocks {
  max-width: var(--m6);
  display: grid;
  gap: clamp(1.35rem, 2.6vw, 2.1rem);
}
.blocks--wide { max-width: var(--m7); }
.blocks p {
  margin: 0;
  font-size: clamp(1.0625rem, 0.98rem + 0.62vw, 1.4375rem);
  line-height: 1.5;
  color: var(--silver);
}

.microcopy {
  margin-top: 1.4rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.03em;
  color: var(--slate);
}

.attribution {
  max-width: var(--m7);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.85;
  letter-spacing: 0.02em;
  color: var(--slate);
  padding-left: 1.1rem;
  /* Grey: this is a margin rule holding fine print, not a laser. */
  border-left: 1px solid var(--hairline);
}

/* The one source line the proof band must ship with. */
.source-line {
  margin: clamp(1.6rem, 3vw, 2.4rem) 0 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--slate);
}

.pull {
  /* Eight columns, not six. At six the closing line of the loud section
     broke onto three lines and stopped at the stage's midpoint, so it read as
     a paragraph that ran out rather than as the band's last word. At eight it
     holds two lines and crosses into the right half of the stage. */
  max-width: var(--m8);
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.35rem, 1.05rem + 1.35vw, 2.25rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--white-heat);
  text-transform: none;
}
.pull--tight { margin-top: clamp(2rem, 4vw, 3rem); }

/* --------------------------------------------------------------------------
   3aa. THE CLOSING PLATE. The last word of the loudest section.

   ROUND 4 (Rron: "can we put this text in the middle, inside a boxout of some
   sort? it looks off on the right there"). The sentence used to be a
   seven-column pull set flush left in a 1560px stage, so it stopped 700px
   short of the right edge and read as a paragraph that had run out rather
   than as a closing statement. It is now a centred set piece, and everything
   about the frame is borrowed from what the page already speaks:

     the frame   one hairline, the same --hairline the attribution's margin
                 rule uses. Grey, because this is structure and not a laser.
     the corners four laser ticks, the JOLT card's tick vocabulary exactly:
                 34px, 2px, live wire at the corner falling away along both
                 arms. Eight background layers on ONE pseudo element, so the
                 reticle costs no markup and no extra box.
     the ground  deep space at 55%, a shade under the alt section's field, so
                 the plate sits into the stage. The mote canvas still reads
                 through it.

   No glow, no hot point, no warm value, no drop shadow: the rim and the ground
   do the lifting, which is the identity law. Nothing here animates beyond the
   reveal it shares with its siblings.
   -------------------------------------------------------------------------- */
.closer,
.walkout {
  position: relative;
  max-width: var(--m9);
  margin: clamp(3.5rem, 7vw, 5.5rem) auto 0;
  /* The side padding tracks the viewport faster than the vertical does: at
     tablet the plate is already as wide as the content column, so a padding
     cut from the same 3.6vw as the desktop one left the type running almost
     into the frame. 5vw holds a real margin inside the rim at 768 without
     crushing the measure at 390. */
  padding: clamp(2.4rem, 4.6vw, 3.9rem) clamp(1.5rem, 5vw, 3.4rem);
  border: 1px solid var(--hairline);
  background: rgba(6, 7, 8, 0.55);
}
/* The reticle. Brightest exactly on each corner, gone within 34px, on both
   axes: the same falloff as .card::before, which is where the device is from. */
.closer::after,
.walkout::after {
  content: "";
  position: absolute;
  /* Outside the border box by a pixel, so the ticks sit ON the hairline
     rather than inside it and the corner reads as one mark. */
  inset: -1px;
  pointer-events: none;
  --tick: 34px;
  --tick-out: rgba(46, 107, 255, 0.18);
  background:
    linear-gradient(90deg,  var(--live-wire), var(--tick-out)) left top / var(--tick) 2px no-repeat,
    linear-gradient(180deg, var(--live-wire), var(--tick-out)) left top / 2px var(--tick) no-repeat,
    linear-gradient(270deg, var(--live-wire), var(--tick-out)) right top / var(--tick) 2px no-repeat,
    linear-gradient(180deg, var(--live-wire), var(--tick-out)) right top / 2px var(--tick) no-repeat,
    linear-gradient(90deg,  var(--live-wire), var(--tick-out)) left bottom / var(--tick) 2px no-repeat,
    linear-gradient(0deg,   var(--live-wire), var(--tick-out)) left bottom / 2px var(--tick) no-repeat,
    linear-gradient(270deg, var(--live-wire), var(--tick-out)) right bottom / var(--tick) 2px no-repeat,
    linear-gradient(0deg,   var(--live-wire), var(--tick-out)) right bottom / 2px var(--tick) no-repeat;
}
/* Clash 500, one notch up on the pull it replaces, centred and held to a
   readable measure inside the plate whatever the plate is doing. */
.closer__text {
  position: relative;
  max-width: var(--m7);
  margin: 0 auto;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.55rem, 1.05rem + 2.1vw, 2.8rem);
  line-height: 1.14;
  letter-spacing: -0.01em;
  text-align: center;
  text-wrap: balance;
  color: var(--white-heat);
  text-transform: none;
}
@media (max-width: 560px) {
  /* At phone width a 34px arm is a quarter of the plate's edge. */
  .closer::after { --tick: 22px; }
}

.lead-line {
  max-width: var(--m6);
  margin: 0 0 clamp(2rem, 4vw, 3rem);
  font-size: clamp(1rem, 0.97rem + 0.3vw, 1.125rem);
  color: var(--silver);
}


/* --------------------------------------------------------------------------
   3b. Headline line splits. Headlines were five left-set blocks of the same
   shape; they are now split deliberately, and the second line of most of them
   is offset so the page's heads stop being one rectangle repeated.
   -------------------------------------------------------------------------- */
.hl-line { display: block; }
.hl-line--in { padding-left: 0.62em; }
@media (max-width: 700px) { .hl-line--in { padding-left: 0.3em; } }

/* The lit words. Flat white heat where the rest of the head runs the silver
   gradient, under a bloom that stays under 6x the stroke weight of the
   glyph. Spent three times (Rron, 2026-09-08): "bloody sales" in the hero,
   and the villain's quoted phrase, so the two loudest lines on the page
   share one light. */
.glow {
  color: var(--white-heat);
  -webkit-text-fill-color: var(--white-heat);
  background-image: none;
  text-shadow:
    0 0 5px rgba(244, 246, 249, 0.30),
    0 0 14px rgba(157, 196, 255, 0.20),
    0 0 30px rgba(46, 107, 255, 0.18);
}

/* --------------------------------------------------------------------------
   4. Beams. The structural spine of the page.
   -------------------------------------------------------------------------- */
.beam {
  position: relative;
  height: 3px;
  margin-top: clamp(1.4rem, 2.5vw, 2rem);
  width: 100%;
  max-width: 100%;
  overflow: visible;
}
/* Pre measurement fallback. The script narrows these to the width of the
   heading's last line, so the rule underlines the claim, not the column. */
.beam--rule { max-width: min(100%, 420px); }

/* THE HERO LASER. One line, not two. It leaves the headline, crosses the
   stage and hands over to the streak baked into the lighting plate, which
   carries the only terminus. The script writes the exact width; this is the
   no script fallback, and the hero clips whatever runs past its edge. */
.beam--hero {
  max-width: none;
  width: calc(100% + 18vw);
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
}

/* The villain's full-band rule used to be declared here. It is gone (Rron's
   round 5): the bubble was crashing into it, and a bigger bubble in the space
   it was wasting is a better section than a beam and an object fighting over
   the same 40 pixels. The band keeps its ground, its type and its object. */

/* The hero beam runs all the way into the object now (Rron, 2026-09-04: "the
   laser doesn't light up to the end, it kind of stops"). It used to keep a
   flat live wire value and stop 70px short, trusting the plate's painted
   streak to carry the last stretch; the streak is too faint for that at
   1440, so the line looked cut. It now brightens toward white heat over its
   last tenth, the way the section rules do, and the script runs it 12px past
   the terminus so the join is under the object's own light. */
.beam--hero .beam__line {
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 16%, var(--live-wire) 88%, #DCE8FF 100%);
}

.beam__line {
  position: absolute;
  inset: 0 auto 0 0;
  display: block;
  width: 100%;
  height: 2px;
  top: 50%;
  transform: translateY(-50%);
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 22%, var(--live-wire) 78%, #DCE8FF 100%);
}
/* HOT POINTS: exactly two on the page, and they are declared by exception.
   A white point is the loudest thing a line can do, so it is spent only where
   something actually lands: the CTA beam under the button, and the strike
   that fires when the second stat finishes counting. Every other beam simply
   ends. (The hero's terminus is not a hot point at all: it is painted into
   the lighting plate's artwork.) */
.beam__tip { display: none; }
.beam--cta .beam__tip,
.beam--strike .beam__tip { display: block; }

.beam__tip {
  position: absolute;
  right: -2px;
  top: 50%;
  width: 6px;
  height: 6px;
  transform: translateY(-50%);
  border-radius: 50%;
  background: var(--white-heat);
  box-shadow:
    0 0 5px 1px rgba(244, 246, 249, 0.85),
    0 0 11px 2px rgba(157, 196, 255, 0.55);
}

.js .beam__line { width: 0; }
.js .is-drawn > .beam__line {
  width: var(--beam-len, 100%);
  transition: width 900ms var(--ease);
}
.js .is-instant > .beam__line { width: var(--beam-len, 100%); transition: none; }
/* The hero rule is beat two of a three beat opening, so it draws faster than
   a section rule: the whole sequence has to land inside 1.6s. */
.js .beam--hero.is-drawn > .beam__line { transition-duration: 620ms; }

/* Section boundaries. Every ground change on this page is a discharge that
   draws itself on scroll, never a grey rule. */
.boundary {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 2 * var(--gutter));
  max-width: calc(var(--wrap) - 2 * var(--gutter));
  height: 2px;
  margin: 0;
  pointer-events: none;
  z-index: 3;
}
.boundary--quiet { --beam-len: 34%; height: 1px; }
.boundary--quiet .beam__line {
  height: 1px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0.62) 0%, rgba(46, 107, 255, 0.30) 48%, rgba(46, 107, 255, 0) 100%);
}
/* A quiet boundary fades out; it does not land. Only the hot boundaries and
   the measured rules are allowed a white hot point, or the page would carry
   half a dozen bright specks competing with the CTA. */
.boundary--quiet .beam__tip { display: none; }
.boundary--hot .beam__line {
  height: 2px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 20%, var(--live-wire) 72%, #DCE8FF 100%);
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.005em;
  text-decoration: none;
  padding: 0.9rem 1.6rem;
  border-radius: 2px;
  border: 1px solid transparent;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.btn:active { transform: translateY(0) scale(0.985); }

/* THE CALL BUTTON, CHARGED (Rron, 2026-09-22: "make the book a call button a
   bit more prominent on both versions, a blue gradient and an outer glow").
   The filled buttons are now the laser itself: live wire lit from above and
   deepening below, a hairline of light along the top edge, and a blue bloom
   around the box. White type holds AA across the whole face: 4.7:1 on the
   lightest stop at rest, 4.6:1 on hover, 5.2:1 or more under the label. The
   same treatment works on both grounds: the bloom is light on the dark page and a
   blue haze on the silver one. Still one filled button per viewport. */
.btn--solid,
.btn--hero {
  background: linear-gradient(180deg, #3068F6 0%, #2658E6 48%, #1B3FC6 100%);
  color: #FFFFFF;
  border-color: rgba(157, 196, 255, 0.35);
  text-shadow: 0 1px 1px rgba(8, 20, 70, 0.35);
}
.btn--solid {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 0 0 1px rgba(46, 107, 255, 0.35),
    0 0 22px rgba(46, 107, 255, 0.45),
    0 10px 30px -8px rgba(46, 107, 255, 0.55);
}
.btn--solid:hover {
  transform: translateY(-1px);
  background: linear-gradient(180deg, #336BF8 0%, #2C60EE 48%, #1F45D0 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.34),
    0 0 0 1px rgba(157, 196, 255, 0.55),
    0 0 30px rgba(46, 107, 255, 0.6),
    0 14px 38px -8px rgba(46, 107, 255, 0.65);
}

.btn--ghost {
  background: transparent;
  color: var(--white-heat);
  border-color: var(--edge);
}
.btn--ghost:hover { border-color: var(--edge-hot); background: rgba(46, 107, 255, 0.06); transform: translateY(-1px); }

/* The nav shortcut. It was a ghost, so the page never showed two filled
   buttons at once. CHARGED TOO (Rron, 2026-09-22: "book a call in the nav
   bar hasn't changed, give that a full blue gradient and outer glow"): it
   is now the same laser as the page's call buttons, with a bloom scaled to
   its size so it does not outshout the hero's. */
.btn--nav {
  background: linear-gradient(180deg, #3068F6 0%, #2658E6 48%, #1B3FC6 100%);
  color: #FFFFFF;
  border-color: rgba(157, 196, 255, 0.35);
  padding: 0.6rem 1.05rem;
  font-size: 0.8125rem;
  text-shadow: 0 1px 1px rgba(8, 20, 70, 0.35);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.26),
    0 0 0 1px rgba(46, 107, 255, 0.3),
    0 0 16px rgba(46, 107, 255, 0.4),
    0 6px 20px -6px rgba(46, 107, 255, 0.5);
}
.btn--nav:hover {
  background: linear-gradient(180deg, #336BF8 0%, #2C60EE 48%, #1F45D0 100%);
  border-color: rgba(157, 196, 255, 0.55);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.32),
    0 0 0 1px rgba(157, 196, 255, 0.5),
    0 0 22px rgba(46, 107, 255, 0.55),
    0 10px 26px -6px rgba(46, 107, 255, 0.6);
}

/* The page's brightest object. Its aura is a separate layer so the breath is
   an opacity change on a pseudo element and never a box-shadow animation. */
.btn--hero {
  position: relative;
  font-size: 1.0625rem;
  padding: 1.15rem 2.6rem;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    0 0 0 1px rgba(157, 196, 255, 0.5);
}
.btn--hero::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 2px;
  pointer-events: none;
  box-shadow:
    0 0 26px rgba(46, 107, 255, 0.5),
    0 0 62px rgba(46, 107, 255, 0.22);
  opacity: 0.82;
  animation: aura 4s ease-in-out infinite alternate;
}
@keyframes aura { from { opacity: 0.82; } to { opacity: 1; } }
.btn--hero:hover {
  transform: translateY(-2px);
  background: linear-gradient(180deg, #336BF8 0%, #2C60EE 48%, #1F45D0 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.36),
    0 0 0 1px rgba(220, 232, 255, 0.75);
}
.btn--hero:hover::after {
  box-shadow:
    0 0 34px rgba(46, 107, 255, 0.66),
    0 0 82px rgba(46, 107, 255, 0.3);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: clamp(2rem, 4vw, 2.75rem);
}

/* THE MID JOURNEY DOOR (Rron's round 4: "find a couple of good places to add
   more CTAs during the user journey please"). Two of these exist, one closing
   the method and one closing how it works, and they are the hero's own
   composition unit repeated rather than a new component: the same filled
   button, the same microcopy line, on the same left axis as the copy above
   them. No rule, no panel, no badge. Air is what makes it read as a moment.

   White filled is a measured privilege, not a default. The page's law is one
   filled call button per viewport window and it must be the brightest thing
   in that window; the gate report's button window table proves that the four
   solid buttons on this page are far enough apart that no 900px window ever
   holds two of them at any gated width. The final CTA keeps .btn--hero, which
   is a step brighter again and the only one that breathes, so the hierarchy
   between a door and the door survives. */
.mid-cta { margin-top: clamp(3rem, 5.5vw, 4.5rem); }
.mid-cta .microcopy { margin-top: 1.15rem; }

/* --------------------------------------------------------------------------
   6. Navigation
   -------------------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(6, 7, 8, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 220ms var(--ease), background-color 220ms var(--ease);
}
.nav.is-stuck {
  border-bottom-color: var(--hairline);
  background: rgba(6, 7, 8, 0.9);
}
.nav__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 4vw, 3rem);
}
.nav__logo {
  display: flex;
  align-items: center;
  gap: clamp(0.7rem, 1.3vw, 1rem);
  flex: none;
  line-height: 0;
  text-decoration: none;
}
.nav__logo img { width: clamp(84px, 12vw, 108px); height: auto; }
/* The full name beside the mark. The locked lockup's type, Clash Display 400
   tracked wide in silver, but set at a size a nav can carry, behind a
   hairline so the mark keeps its own silhouette. Hovering the link brings the
   name up to white heat with the rest of the nav's vocabulary. */
.nav__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(0.6875rem, 0.55rem + 0.45vw, 0.875rem);
  line-height: 1.15;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--silver);
  padding-left: clamp(0.7rem, 1.3vw, 1rem);
  border-left: 1px solid var(--hairline);
  white-space: nowrap;
  transition: color var(--dur) var(--ease);
}
.nav__logo:hover .nav__name { color: var(--white-heat); }
/* On a phone the name takes two lines beside the mark ("ADVANCED SALES" over
   "TRAINING"), never three: the measure is sized so the first break can only
   fall before the last word. */
@media (max-width: 600px) {
  .nav__name {
    white-space: normal;
    display: inline-block;
    max-width: 8.6rem;
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    line-height: 1.25;
  }
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.4vw, 2.1rem);
  margin-left: auto;
}
.nav__links a {
  position: relative;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--slate);
  text-decoration: none;
  padding-block: 0.4rem;
  white-space: nowrap;
  transition: color var(--dur) var(--ease);
}
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; right: 100%; bottom: 0;
  height: 1px;
  background: var(--live-wire);
  transition: right 240ms var(--ease);
}
.nav__links a:hover { color: var(--white-heat); }
.nav__links a:hover::after { right: 0; }
/* The section under the reading line owns its link: the underline the hover
   draws, held. Set by an IntersectionObserver in js/main.js, never by a
   scroll listener. */
.nav__links a.is-current { color: var(--white-heat); }
.nav__links a.is-current::after { right: 0; }

.nav .btn--nav { flex: none; }

/* THE THEME SWITCH (2026-09-22). Cold UI on the ticker control's pattern: the
   live wire edge, a silver glyph, no fill, the page's 2px radius. It sits
   hard against the nav button, so the nav's wide gap is taken back on its
   right. The glyph shows the destination: a sun here, a moon on light. */
.theme-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin: 0 calc(0.6rem - clamp(1rem, 4vw, 3rem)) 0 0;
  padding: 0;
  background: transparent;
  border: 1px solid var(--edge);
  border-radius: 2px;
  color: var(--silver);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.theme-toggle:hover {
  color: var(--white-heat);
  border-color: var(--edge-hot);
  background: rgba(46, 107, 255, 0.06);
}
.theme-toggle svg { display: block; }
.theme-toggle__moon { display: none !important; }
@media (pointer: coarse) {
  .theme-toggle { width: 44px; height: 44px; }
}

/* Scroll progress hairline. A scroll driven CSS animation: it runs on the
   compositor and there is no scroll listener anywhere near it. Where the
   timeline is unsupported the hairline is simply not drawn. */
.nav__progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  display: none;
  width: 100%;
  height: 2px;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--live-wire) 0%, #DCE8FF 100%);
  opacity: 0.9;
  pointer-events: none;
}
@supports (animation-timeline: scroll(root block)) {
  .nav__progress {
    display: block;
    animation: navgrow linear both;
    animation-timeline: scroll(root block);
  }
}
@keyframes navgrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav .theme-toggle { margin-left: auto; }
}
/* THE PHONE BAR WITH THE SWITCH IN IT. Mark, two-line name, switch and
   button came to about 440px against a 390px phone, and the button was cut
   off at the edge. Every part gives a little rather than one part going:
   the mark, the name's type and air, the gap and the button's padding. The
   switch keeps its full 44px target. */
@media (max-width: 460px) {
  .nav__inner { gap: 0.75rem; }
  .nav__logo { gap: 0.5rem; }
  .nav__logo img { width: 68px; }
  .nav__name {
    padding-left: 0.5rem;
    max-width: 7.4rem;
    font-size: 0.625rem;
    letter-spacing: 0.1em;
  }
  .theme-toggle { margin-right: -0.3rem; }
  .nav .btn--nav { padding-inline: 0.8rem; }
}
/* The 360 class of phone needs one more step, measured with the switch at
   its touch size. */
@media (max-width: 380px) {
  .nav__inner { gap: 0.5rem; }
  .nav__logo img { width: 58px; }
  .nav .btn--nav { padding-inline: 0.6rem; }
}

/* --------------------------------------------------------------------------
   7. Hero. Three beats: the words rise, the rule draws, the plate settles.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: calc(100svh - 68px);
  display: flex;
  align-items: center;
  padding: clamp(4rem, 10vh, 7rem) 0 clamp(4rem, 8vh, 6rem);
  overflow: hidden;
}
/* The right half of the stage is lit. Static, so it costs nothing against
   the one discharge per viewport law, and it stays far below the CTA
   button in luminance. */
.hero__field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 6% 46%, rgba(11, 13, 16, 0.92) 0%, rgba(6, 7, 8, 0) 58%),
    radial-gradient(46% 42% at 68% 46%, rgba(46, 107, 255, 0.22) 0%, rgba(46, 107, 255, 0.07) 46%, rgba(6, 7, 8, 0) 74%),
    radial-gradient(20% 17% at 70% 44%, rgba(157, 196, 255, 0.09) 0%, rgba(6, 7, 8, 0) 72%);
}
/* Stage lighting plate. A CSS background, so a missing file paints nothing at
   all and the radial field above remains the fallback: there is no <img> to
   break. Screen blend keeps it additive light, never a flat rectangle.

   ONE LASER: the streak painted into this file is not a second line, it is
   the far half of the hero beam. The script measures the beam and writes a
   background position that puts the streak on the beam's exact y and its
   terminus just short of the mouth, so the eye reads one line with one end.
   The mask now reaches full strength early, because a streak that fades in
   halfway across would show the join.

   WIDE VIEWPORTS. The plate used to be 64% of the viewport, anchored to the
   viewport's right edge, and at 1920 the artwork ran out 114px before that
   edge: a measurable hard cut in the room light (12.5 to 9.9 luminance over
   twelve pixels), which is the seam Rron saw. The box is now anchored to the
   CONTENT COLUMN and ends just past the mouth, so it stops growing with the
   window; the script then sizes the artwork so it covers this box on all four
   edges at any width, and fades the last stretch out rather than cutting it. */
.hero__media {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(50% - 0.32 * var(--half));
  right: 0;
  pointer-events: none;
  /* V4: a WebGL canvas mounts here (js/hero-scene.js). Transparent. The
     artwork is independent of the hero rule beside it. */
}
.hero__canvas { display: block; width: 100%; height: 100%; }
@media (max-width: 900px) {
  /* There is no right half to light at tablet and below. */
  .hero__media { display: none; }
}

.hero__inner { position: relative; z-index: 2; }

/* Three lines, bigger than v1, with the break points authored so no line can
   collide with the mouth sticker on its right. Ten columns rather than eight,
   because the stage is 1560 now: the breaks are authored with <br> so a wider
   cap cannot rewrap the headline, it only stops it reading as a narrow block
   in the left half of a wide room. */
.hero__title {
  font-weight: 600;
  font-size: clamp(2.05rem, 7.6vw, 6.25rem);
  line-height: 0.88;
  letter-spacing: -0.03em;
  max-width: var(--m10);
}
.hero__title .w { display: inline-block; }
.hero__title .w > i {
  display: inline-block;
  font-style: normal;
  /* Silver gradient per word. Each word box is one line box tall, so every
     line still runs white heat to silver exactly as the wordmark does. */
  background-image: linear-gradient(180deg, #F4F6F9 0%, #B9C1CE 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
@supports not (background-clip: text) {
  .hero__title .w > i { color: var(--white-heat); -webkit-text-fill-color: var(--white-heat); }
}

/* Beat one. Five words rise in sequence, 70ms apart; the last one lands at
   about 800ms and the whole opening is finished inside 1.5s. */
.js .hero__title .w > i { opacity: 0; transform: translateY(0.42em); }
.js .hero__title.is-in .w > i {
  opacity: 1;
  transform: none;
  transition:
    transform 520ms var(--ease-out) calc(var(--wi, 0) * 70ms),
    opacity 380ms linear calc(var(--wi, 0) * 70ms);
}
.hero__title .w:nth-of-type(1) { --wi: 0; }
.hero__title .w:nth-of-type(2) { --wi: 1; }
.hero__title .w:nth-of-type(3) { --wi: 2; }
.hero__title .w:nth-of-type(4) { --wi: 3; }
.hero__title .w:nth-of-type(5) { --wi: 4; }

.hero .lede { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }

/* --------------------------------------------------------------------------
   8. Sections and their heads
   -------------------------------------------------------------------------- */
.section {
  position: relative;
  padding: var(--pad-top) 0 var(--pad-y);
  /* Clip only sideways, so a sticker may hang past a section edge for the
     pasted on feel without ever giving the document horizontal scroll. */
  overflow-x: clip;
}
/* The alt ground is painted by a layer underneath the section rather than on
   it, so the reactive background can sit between the ground and the content
   instead of being switched off by opaque slabs. */
.section--alt { background: transparent; }
.section--alt::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--deep-field);
  pointer-events: none;
}


.sec-head { margin-bottom: clamp(2.5rem, 4.4vw, 3.5rem); }
.sec-head h2 {
  font-weight: 500;
  font-size: clamp(1.7rem, 1.15rem + 2.1vw, 2.75rem);
  max-width: var(--m7);
}

/* Three display steps. The villain and the method carry the argument, so
   they take the largest heads on the page below the hero.

   NINE COLUMNS, NOT EIGHT. A display measure is not a reading measure: at
   72px a nine-column head is still four or five words to the line, and on the
   wider stage an eight-column head had started to read as a block parked in
   the left half rather than as a headline. */
.sec-head--major h2 {
  font-weight: 500;
  font-size: clamp(2.1rem, 1.2rem + 3.6vw, 4.5rem);
  max-width: var(--m9);
  letter-spacing: -0.025em;
  line-height: 0.94;
}
.sec-head--light h2 { font-size: clamp(1.7rem, 1.15rem + 2.1vw, 2.75rem); max-width: var(--m7); }

/* The head that carries the fusion is a stage in its own right: the bubble is
   positioned against it, so the rule and the object cannot drift apart when
   the headline rewraps. */
.sec-head--fuse { position: relative; }

/* Copy led sections start talking sooner; card led sections get air. */
.sec-head--tight { margin-bottom: clamp(1.9rem, 3.2vw, 2.75rem); }
.sec-head--airy { margin-bottom: clamp(3.25rem, 6vw, 5rem); }

/* THE TYPE LADDER, and it only reads as a ladder if the biggest type is on
   the page's argument. Villain 112px > hero 100px > stat figure and CTA 80px
   at 1440. The villain's coefficient is steeper than the hero's, so it stays
   the largest type at every width, not just where a clamp happens to cap.

   THE BAND IS NO LONGER THE ONLY WIDE ONE. The villain used to run a 1560
   stage of its own while the rest of the page sat on 1180, which is the thing
   Rron saw: one band breathing and eight not. The stage is 1560 everywhere
   now and this section is FLUSH with it. What still makes this the loud band
   is the type and the object beside the blocks, not a
   private width. */
.section--villain .sec-head--major h2 {
  font-size: clamp(2.4rem, 0.9rem + 7.8vw, 7rem);
  max-width: none;
  letter-spacing: -0.035em;
}

/* THE FLAGSHIP HEADLINE. The quoted phrase is gone from the type: the bubble
   is the quotation. What is left is two white lines with a deliberate split,
   the second one offset, and the object where the words were.

   ROUND 5 (Rron: "the bubble still crashes with the line below, maybe just
   remove the line completely and make the bubble bigger, so it takes up more
   of the empty space on the right?"). Both things happened. The rule is gone
   from the markup and from this stylesheet, and with nothing left to ride the
   object is placed for composition alone: x off the end of line two, so it is
   still the phrase's next word, and y on the optical centre of the whole
   headline block rather than of one line of it. The cap moves 370 to 460,
   which at 1920 fills the 600px of open stage that sat right of "COMPETITOR
   IS" instead of leaving two thirds of it empty.

   The coefficient moves only from 26vw to 27vw, and that restraint is
   measured, not cautious: the headline's own font-size clamp caps at 112px
   from 1280 up, so "COMPETITOR IS" ends at the same x on a 1280 stage as on a
   2560 one while the stage itself is 400px narrower. At 30vw the object was
   384px at 1280, the stage ran out, and the placement clamp pushed it back
   onto the last word of the headline. Growth belongs at the top of the
   ladder, where the empty space actually is. */
.vhead__l1,
.vhead__l2,
.vhead__l3 { display: block; }
.vhead__l2 { padding-left: 0.5em; }
.vhead__l3 { padding-left: 0.25em; }
/* THE PHRASE, LIT (Rron, 2026-09-08). Two solid lines name the villain; the
   villain itself is one weight up and carries the hero's own light, the
   .glow bloom on flat white heat, so "bloody sales" and this phrase are
   the same lamp. A blue gradient and a hollow outline were both tried here
   first; Rron wanted the hero's effect, not a third one.
   600, not 700: the heaviest cut runs so wide the line breaks at 1440
   unless the tracking closes to a slab. 600 with the head's own tracking
   and a line set four percent smaller holds one row at 1440. */
.vhead__hot {
  display: inline;
  font-weight: 600;
  font-size: 0.96em;
  letter-spacing: -0.032em;
}
/* The two lines above it take the hero's silver gradient, for the same
   reason the hero's other words do: a lit word only reads as lit against
   type that is a step cooler. Same gradient, same clip, same fallback. */
.vhead__l1,
.vhead__l2 {
  background-image: linear-gradient(180deg, #F4F6F9 0%, #B9C1CE 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
@supports not (background-clip: text) {
  .vhead__l1, .vhead__l2 { color: var(--white-heat); -webkit-text-fill-color: var(--white-heat); }
}
}
/* THE SPACE THE RULE OCCUPIED IS KEPT, not reclaimed. The beam contributed its
   own top margin plus its 2px to the head's height, and the band's rhythm was
   tuned around that: dropping ~100px would have pulled the copy up under the
   headline and made the loud section the tightest one on the page. The sum is
   written out rather than rounded into one clamp so it stays exactly what it
   replaced at every width. */
.sec-head--fuse {
  margin-bottom: calc(clamp(1.9rem, 3.2vw, 2.75rem) + clamp(2rem, 3.4vw, 3.4rem) + 2px);
}
@media (max-width: 900px) {
  .vhead__l2 { padding-left: 0; }
}
/* The method's head is short, so it is held to a narrower measure and breaks
   onto two lines rather than running under the dartboard. */
#method .sec-head--major h2 { max-width: var(--m7); }
/* Below the widest stage the display measure comes in a column, so a headline
   line can never reach the column the stickers occupy. */
@media (max-width: 1140px) {
  .sec-head--major h2 { max-width: var(--m7); }
  .sec-head--light h2 { max-width: var(--m6); }
}

.sub-block { margin-top: clamp(3rem, 6vw, 5rem); }
.sub-block h3 {
  font-weight: 500;
  font-size: clamp(1.25rem, 1rem + 1.1vw, 1.75rem);
  margin-bottom: 1.5rem;
  color: var(--white-heat);
}

/* The sentence that names the framework and carries the legal position.
   Promoted by weight and size, never by colour. */
.key-line {
  font-size: clamp(1.0625rem, 1rem + 0.45vw, 1.3125rem);
  font-weight: 500;
  line-height: 1.55;
  color: var(--silver);
}

/* --------------------------------------------------------------------------
   10. Cards. The JOLT four are the only panel grid on the page.
   -------------------------------------------------------------------------- */
/* Without panels the gap is the only thing separating one card from the next,
   so it has to be a real interval rather than a border's worth of air. */
.cards {
  display: grid;
  gap: clamp(2rem, 3.2vw, 3rem);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1020px) {
  .cards--jolt { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cards--proof { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.cards--jolt { margin-top: clamp(3.25rem, 6vw, 5rem); }

/* UNBOXED. There is no panel and no border here: a 68px letter is already the
   strongest structure a card can have, and four rectangles around four letters
   only made them look like a table. What remains is one laser tick above each
   card, the letter, and the type. */
.card {
  position: relative;
  padding: 1.35rem 0 0;
  transition: transform 200ms var(--ease);
}
.card::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 34px;
  height: 2px;
  background: linear-gradient(90deg, var(--live-wire) 0%, rgba(46, 107, 255, 0.25) 100%);
  transition: width 260ms var(--ease);
}
.card:hover { transform: translateY(-3px); }
.card:hover::before { width: 58px; }

.card__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.9375rem;
  line-height: 1.3;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--white-heat);
  margin-bottom: 0.7rem;
}
/* Two line floor so the four bodies start on the same line, whatever the
   title does. lh is the line box itself; the em fallback is close enough on
   an engine that does not have it. */
@media (min-width: 640px) {
  .card__title { min-height: 2.6em; min-height: 2lh; }
}
.card__body {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--silver);
  margin: 0;
}

/* The JOLT letter is real type in the card's flow, at full size and never
   clipped. On hover the laser sweeps an underline beneath it, once. */
.card__letter {
  position: relative;
  display: block;
  margin-bottom: clamp(1.1rem, 2vw, 1.6rem);
  padding-bottom: 0.1em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(3rem, 2rem + 3vw, 4.25rem);
  line-height: 0.86;
  letter-spacing: -0.04em;
  background-image: linear-gradient(180deg, #EDF1F6 0%, #39414D 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  user-select: none;
}
@supports not (background-clip: text) {
  .card__letter { color: #7C8695; -webkit-text-fill-color: #7C8695; }
}
.card__letter::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 34%, #DCE8FF 100%);
  transition: width 420ms var(--ease);
}
.card:hover .card__letter::after,
.card:focus-within .card__letter::after { width: 100%; }

/* --------------------------------------------------------------------------
   11. The proof band. Two figures and one shared laser strike.
   -------------------------------------------------------------------------- */
.stats {
  position: relative;
  --fig: clamp(3.25rem, 1.9rem + 6.6vw, 5rem);
  display: grid;
  gap: clamp(2.5rem, 5vw, 3.5rem);
  grid-template-columns: 1fr;
  /* Ten columns on the wide stage, not eight. Eight was right when the page
     ran on 1180; on 1560 it left the evidence huddled in the left half of the
     room while the band around it breathed. Ten still stops short of the
     stage edge, which is what the figures need. */
  max-width: var(--m10);
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
}
@media (min-width: 860px) { .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.stat { margin: 0; }
/* 80px, not 112px: the figures are the page's evidence, not its argument, and
   they sat above the hero and the villain in the old ladder. At this size both
   read on ONE line, which is why nothing here is allowed to wrap. */
.stat__figure {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fig, clamp(3.25rem, 1.9rem + 6.6vw, 5rem));
  line-height: 0.92;
  letter-spacing: -0.04em;
  color: var(--white-heat);
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  flex-wrap: nowrap;
  white-space: nowrap;
}
.stat__unit { font-size: 0.42em; letter-spacing: -0.01em; }
.stat__label {
  margin-top: 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  line-height: 1.6;
  color: var(--silver);
  max-width: var(--m4);
}

/* The strike. It is the viewport's one discharge, fired by the beam
   controller the moment the second count lands.

   ROUND 2 (Rron: "the line is crashing with the 2.5 million and 40 to 60%").
   It used to be written two pixels ABOVE the figures' shared baseline, which
   is inside the digits: at his width the beam ran straight through the ink of
   both numbers. Digits sit ON the baseline and neither figure has a
   descender, so "on the baseline" and "through the glyphs" were the same
   place. The script now writes three custom properties measured off the
   figures' INK rather than off their boxes: --strike-y clears the deepest ink
   by a fixed margin, and --strike-x and --strike-w run the line from the
   first figure's left ink to just past the second's right ink, so it
   underlines the evidence instead of ruling off the grid it sits in. */
.beam--strike {
  position: absolute;
  left: var(--strike-x, 0px);
  right: auto;
  top: var(--strike-y, calc(var(--fig) * 1.06));
  width: var(--strike-w, 100%);
  margin: 0;
}
.beam--strike .beam__line {
  height: 2px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 16%, var(--live-wire) 62%, #DCE8FF 100%);
}

/* --------------------------------------------------------------------------
   12. (The two delivery plates are gone. A stock render of a video call and a
   stock skyline said nothing the two mono lines beneath them did not, and two
   bordered rectangles in the calmest band on the page were the loudest thing
   in it. The image files stay in assets\img\ rather than being deleted.)
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   13. The NO list. Four struck negatives, set large.
   -------------------------------------------------------------------------- */
.no-list {
  display: grid;
  gap: clamp(0.9rem, 1.8vw, 1.35rem);
  max-width: var(--m7);
  margin-top: clamp(2.75rem, 5.5vw, 4rem);
}
.no-list__text {
  position: relative;
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.0625rem, 0.95rem + 0.7vw, 1.5rem);
  line-height: 1.28;
  letter-spacing: 0.005em;
  text-transform: none;
  color: var(--silver);
}
/* The strike belongs to the sentence, not to the row. Without the script
   it is a single rule across the text box; with it, the script measures
   every rendered line and strikes each one, landing the white hot tip on
   the full stop rather than on the far edge of the column. */
.no-list__strike {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0.62) 0%, rgba(46, 107, 255, 0.5) 55%, rgba(157, 196, 255, 0.9) 100%);
  pointer-events: none;
}
.js .no-list__strike { inset: 0; top: 0; width: auto; height: auto; background: none; }
.js .no-list__strike i {
  position: absolute;
  height: 1.5px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0.62) 0%, rgba(46, 107, 255, 0.5) 55%, rgba(157, 196, 255, 0.9) 100%);
}
/* No hot point on the end of these. Four struck sentences with four white
   points is four terminals competing with the two the page actually spends. */

/* --------------------------------------------------------------------------
   14. Traits. Five one line promises on the open stage: typography ruled by
   beams, never a fifth bordered rectangle.
   -------------------------------------------------------------------------- */
/* NO RULES IN THIS GRID (Rron's round 2: "we need to remove the divider
   lines from this section, they crash with the stickers"). Every trait used
   to open with a grey hairline that its object straddled, and three of the
   five objects crossed their own line: the fist's bolt, the camera's zzz and
   the handshake all had a rule running through them. The hairlines, their
   varied widths and the reserved band that existed to hold an icon over them
   are all gone. What carries the grid now is what should have carried it: the
   five objects, the five headings, and a row rhythm big enough to be read as
   deliberate rather than as a list that lost its rules. */
.traits {
  display: grid;
  grid-template-columns: 1fr;
  /* The rows were separated by rules and 0 gap; they are separated by air
     now, and the air has to be a real interval or five headings in a column
     read as one block. */
  row-gap: clamp(2.4rem, 4.2vw, 3.4rem);
  margin-top: clamp(2rem, 4vw, 3.4rem);
  /* ONE size for all five objects, and one gap under them. Both live here so
     the trait's reserved band and the object that sits in it can never drift
     apart: the band is derived from the object, not typed out twice. */
  --icon-size: 44px;
  --icon-gap: 1.1rem;
}
/* THE THREE-PLUS-TWO, CENTRED. Five items into three columns leaves a short
   last row, and a short row flush left reads as a grid that ran out. The
   track count is doubled and every card spans two of them, so the last row
   can be offset by exactly half a column and sit under the middle of the row
   above. One rule per breakpoint, no per-item widths. */
@media (min-width: 760px) {
  .traits {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: clamp(2rem, 4vw, 3.5rem);
  }
  .trait { grid-column: span 2; }
  .trait:nth-child(5) { grid-column: 2 / span 2; }
}
@media (min-width: 1100px) {
  .traits { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .trait:nth-child(4) { grid-column: 2 / span 2; }
  .trait:nth-child(5) { grid-column: 4 / span 2; }
}

/* The band above each heading is exactly the object plus its gap, so all five
   headings share a row baseline and all five objects share a top edge. */
.trait {
  position: relative;
  padding: calc(var(--icon-size) + var(--icon-gap)) 0 0;
}

.trait__icon {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--icon-size);
  height: var(--icon-size);
  color: var(--white-heat);
}
.trait__icon svg { display: block; width: 100%; height: 100%; }

.trait__title {
  font-weight: 500;
  font-size: clamp(1.15rem, 0.95rem + 0.8vw, 1.5rem);
  letter-spacing: 0.02em;
  color: var(--white-heat);
  margin-bottom: 0.6rem;
}
.trait__body { margin: 0; color: var(--silver); font-size: 0.9375rem; line-height: 1.6; }

/* --------------------------------------------------------------------------
   15. The ticker. The page's one loop besides the cursor and the CTA breath.
   Mono type, a constant slow scroll, laser ticks between the phrases, paused
   on hover and on focus, and replaced by a static line under reduced motion.
   -------------------------------------------------------------------------- */
/* A kinetic type moment has to be typographic. At mono caption scale between
   two hairlines this band was a stock news ticker; at display scale, in white
   heat, with no borders at all, it is the page saying its list out loud. The
   loop is slower to match, because the words are three times the size and the
   distance travelled per second should not be. */
.ticker {
  position: relative;
  /* The right gutter is reserved for the pause control, so the band's own
     padding is what keeps the scrolling type clear of it. Nothing here is a
     magic number: the gutter is the control plus its inset on both sides. */
  --tk-ctl: 44px;
  --tk-inset: clamp(0.75rem, 2.2vw, 1.75rem);
  padding: clamp(1.6rem, 3.2vw, 2.6rem) calc(var(--tk-ctl) + 2 * var(--tk-inset)) clamp(1.6rem, 3.2vw, 2.6rem) 0;
  /* NO GROUND OF ITS OWN (Rron's round 2: "this section seems like it's on a
     dark grey background, any chance we don't have a background there at all,
     just let the text run through the normal background?"). The band used to
     paint --deep-field across the full bleed, which made a slab the reactive
     light and the motes could not cross: the one loop on the page was sitting
     in a grey box. It is transparent now, so the room light, the motes and
     the page's own --deep-space run straight through behind the type. The
     right-hand fade was already a true alpha mask rather than a gradient
     matched to the old fill, so it needed nothing: it fades the TYPE out, not
     the ground, and still does. */
  overflow: hidden;
}
/* The type is clipped by the reserved gutter, and faded out over the last
   stretch before it so the band reads as running past the control rather than
   stopping dead at an invisible wall. */
.ticker__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - clamp(2.5rem, 6vw, 5rem)), rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - clamp(2.5rem, 6vw, 5rem)), rgba(0, 0, 0, 0) 100%);
}
.ticker__track {
  display: flex;
  width: max-content;
  animation: tickroll 96s linear infinite;
}
@keyframes tickroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
/* Hover and focus courtesies, scoped to the type itself. They must not fire
   from the control, or pressing the control would look like it did nothing:
   the button's own state is the only thing that decides whether the band is
   stopped, and .is-paused is what says so. */
.ticker__viewport:hover .ticker__track,
.ticker__viewport:focus-within .ticker__track,
.ticker.is-paused .ticker__track { animation-play-state: paused; }

/* THE PAUSE CONTROL (WCAG 2.2.2). Cold UI, borrowed straight off the ghost
   button: the live wire edge that every outline control on this page uses, a
   silver glyph, and no fill. It emits nothing, so it spends none of the light
   budget and carries no warm value. Square at the page's 2px radius, not a
   pill, because nothing else here is round. */
.ticker__ctl {
  position: absolute;
  right: var(--tk-inset);
  top: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--tk-ctl);
  height: var(--tk-ctl);
  margin: 0;
  padding: 0;
  transform: translateY(-50%);
  background: transparent;
  border: 1px solid var(--edge);
  border-radius: 2px;
  color: var(--silver);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.ticker__ctl:hover {
  color: var(--white-heat);
  border-color: var(--edge-hot);
  background: rgba(46, 107, 255, 0.06);
}
.ticker__glyph { pointer-events: none; }
/* One glyph at a time, and the pair swaps on the pressed state, so the button
   always shows the action it will take. */
.ticker__ctl .ticker__glyph--play,
.ticker__ctl[aria-pressed="true"] .ticker__glyph--pause { display: none; }
.ticker__ctl[aria-pressed="true"] .ticker__glyph--play { display: block; }

.ticker__set { display: flex; align-items: center; flex: none; }
.ticker__word {
  flex: none;
  padding-inline: clamp(1.25rem, 2.4vw, 2.25rem);
  font-family: var(--font-display);
  font-weight: 600;
  /* ROUND 5 (Rron: "the moving strip has a few words in sticker format, then a
     few words in just normal text, choose one, whichever is cleaner, and make
     the text slightly smaller, it's too big right now"). Down from
     clamp(1.75rem, 4vw, 3.5rem), and every phrase is now plain white heat: the
     two sticker-word phrases came out of the band. In a headline the device is
     obviously deliberate because it happens once and stays put; sliding past
     at a constant speed, two treated phrases in seven read as an inconsistency
     rather than as a choice, and treating all seven would have been the page
     shouting its quietest section. */
  font-size: clamp(1.35rem, 3vw, 2.6rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--white-heat);
}
/* A laser tick between the phrases: a live wire dash, long enough to read as
   a beam at this type size. No hot point: the page spends its two elsewhere. */
.ticker__tick {
  flex: none;
  /* Follows the type down (round 5). At 64px against a 56px phrase the tick
     read as a beam between words; at 64px against a 41.6px phrase it would
     read as the point of the band. 48px holds the same ratio to the cap
     height that was signed off at the larger size. */
  width: 48px;
  height: 2px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0) 0%, var(--live-wire) 45%, var(--live-wire) 100%);
}
.ticker__still {
  display: none;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.9;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--silver);
}

/* --------------------------------------------------------------------------
   16. How it works: the rail and the chip row
   -------------------------------------------------------------------------- */
.rail { position: relative; margin-top: clamp(2.75rem, 5vw, 4rem); }
/* Runs off the right edge of the stage, not to a tidy stop inside it. */
.rail__beam {
  position: absolute;
  left: 0;
  right: calc(50% - 50vw);
  top: 6px;
  height: 1px;
  background: linear-gradient(90deg, rgba(46, 107, 255, 0.6) 0%, rgba(46, 107, 255, 0.34) 50%, rgba(46, 107, 255, 0.12) 82%, rgba(46, 107, 255, 0) 100%);
}
.rail__steps {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 760px) { .rail__steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.step { position: relative; padding-top: 2.1rem; }
/* Live wire, not white heat: these are two markers on a rail, not the end of
   a discharge. The page carries exactly two white points and neither is here. */
.step__node {
  position: absolute;
  top: 2px;
  left: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--live-wire);
  box-shadow: 0 0 6px 1px rgba(46, 107, 255, 0.45);
}
.step__label {
  margin: 0 0 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--white-heat);
}
/* Held to four columns so the swoosh has clear air on the rail beside it, and
   held tighter still where the two columns close up. */
.step__body { margin: 0; max-width: var(--m4); color: var(--silver); font-size: 0.9375rem; }
@media (max-width: 1140px) { .step__body { max-width: min(var(--m4), 74%); } }

/* Two mono lines with their icons, sitting on the rail's ground. */
.delivery {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem clamp(1.75rem, 4vw, 3rem);
  margin-top: clamp(2.25rem, 4vw, 3rem);
}
.delivery__item { display: block; }
.delivery__label {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  color: var(--slate);
}
.delivery__icon { flex: none; color: var(--silver); opacity: 0.8; }
.delivery__icon svg { width: 20px; height: 20px; }

/* What the team walks out with. Tags, not bullets: seven short outcomes that
   read as a set rather than as a list of demands. */
/* THE TWO SESSIONS (2026-09-08). The rail read as a footnote; the sessions
   are the product, so they take the JOLT cards' language: a laser tick, an
   oversized numeral in the same silver-to-slate gradient, a display title,
   the hour as a mono line. Unboxed, like the cards. */
.sessions {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 4vw, 4rem);
  margin: clamp(3rem, 5.5vw, 4.5rem) 0 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 760px) { .sessions { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.session {
  position: relative;
  padding: 1.5rem 0 0;
}
.session::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 34px;
  height: 2px;
  background: linear-gradient(90deg, var(--live-wire) 0%, rgba(46, 107, 255, 0.25) 100%);
}
.session__num {
  display: block;
  margin-bottom: clamp(1rem, 1.8vw, 1.4rem);
  padding-bottom: 0.08em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(4rem, 3rem + 4vw, 6.5rem);
  line-height: 0.86;
  letter-spacing: -0.04em;
  background-image: linear-gradient(180deg, #EDF1F6 0%, #39414D 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
@supports not (background-clip: text) { .session__num { color: var(--white-heat); -webkit-text-fill-color: var(--white-heat); } }
.session__title {
  max-width: 18ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.4rem, 1.05rem + 1.2vw, 2.1rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--white-heat);
  margin: 0 0 0.85rem;
}
.session__meta {
  margin: 0 0 1rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sky-glow);
}
.session__body {
  margin: 0;
  max-width: 34ch;
  color: var(--silver);
  font-size: 1rem;
  line-height: 1.6;
}

/* WHAT YOUR TEAM WALKS OUT WITH (2026-09-08). A framed set piece in the
   closing box's frame: the lead (heading and payoff) holds the left third,
   the seven outcomes run as a numbered two-column list on the right. The
   numbers are mono and Live Wire; the items are display statements. No
   borders between rows, no boxes, nothing that reads as a control. */
.walkout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: clamp(2.5rem, 5vw, 5rem);
  row-gap: 2rem;
  align-items: start;
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}
.walkout__lead { position: relative; }
.walkout__title {
  margin: 0 0 1.1rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.6rem, 1.15rem + 1.6vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--white-heat);
  text-wrap: balance;
}
.walkout__pull {
  margin: 0;
  max-width: 26ch;
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem);
  line-height: 1.5;
  color: var(--silver);
}
.walkout__list {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.75rem, 3vw, 3rem);
  row-gap: 1.35rem;
  margin: 0.35rem 0 0;
  padding: 0;
  list-style: none;
}
.walkout__item {
  position: relative;
  padding-left: 2.4rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.05rem, 0.92rem + 0.55vw, 1.35rem);
  line-height: 1.25;
  color: var(--white-heat);
}
.walkout__n {
  position: absolute;
  left: 0;
  top: 0.32em;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--live-wire);
}
@media (max-width: 900px) {
  .walkout { grid-template-columns: 1fr; row-gap: 1.75rem; }
  .walkout__list { grid-template-columns: 1fr; row-gap: 1rem; }
}

/* --------------------------------------------------------------------------
   17. Testimonials (placeholder component)
   -------------------------------------------------------------------------- */
/* NO TERMINAL CHROME. These were panels with a fake filename bar and a status
   pill on top, which is a screenshot of an app, not a quotation. What a quote
   needs is to be set like one: display type on the bare ground, and the person
   who said it in small mono underneath. */
.quote {
  display: flex;
  flex-direction: column;
}
.quote__body {
  margin: 0;
  padding: 0;
  flex: 1;
}
.quote__body p {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.1rem, 0.95rem + 0.55vw, 1.375rem);
  line-height: 1.28;
  letter-spacing: -0.005em;
  text-transform: none;
  color: var(--white-heat);
}
.quote__attr {
  margin: 1.15rem 0 0;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 0.6563rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--silver);
}

/* --------------------------------------------------------------------------
   18. FAQ. <details> stays semantic and keyboard native; the panel opens on
   a measured height so both directions animate and nothing jumps.
   -------------------------------------------------------------------------- */
/* Two columns from the widest layout down to 1020: the headline holds the
   left four columns and stays put while the answers move, so the band reads
   as a conversation rather than as a 780px block adrift in a 1180 stage. */
@media (min-width: 1020px) {
  #faq > .wrap {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--col-gap);
    align-items: start;
  }
  #faq .sec-head {
    grid-column: 1 / span 4;
    position: sticky;
    top: 7rem;
    margin-bottom: 0;
  }
  #faq .sec-head h2 { max-width: none; }
  #faq .faq { grid-column: 6 / span 7; max-width: none; }
}

.faq { max-width: var(--m8); border-top: 1px solid var(--hairline); }
.faq__item { border-bottom: 1px solid var(--hairline); }
.faq__item > summary {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 1.35rem 0;
  cursor: pointer;
  list-style: none;
  transition: color var(--dur) var(--ease);
}
.faq__item > summary::-webkit-details-marker { display: none; }
.faq__q {
  flex: 1;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  letter-spacing: 0.005em;
  color: var(--white-heat);
  text-transform: none;
}

.faq__mark {
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
}
.faq__mark::before,
.faq__mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: var(--live-wire);
  transition: transform 240ms var(--ease);
}
.faq__mark::before { width: 14px; height: 1.5px; transform: translate(-50%, -50%); }
.faq__mark::after { width: 1.5px; height: 14px; transform: translate(-50%, -50%); }
.faq__item[open] .faq__mark::before,
.faq__item[open] .faq__mark::after { transform: translate(-50%, -50%) rotate(45deg); }
.faq__item > summary:hover .faq__mark::before,
.faq__item > summary:hover .faq__mark::after { background: var(--sky-glow); }

/* The script writes a measured height onto the wrapper for the length of the
   open and close, then hands the height back to the content. */
.faq__wrap { overflow: hidden; }
.faq__a { padding: 0 3rem 1.6rem 0; max-width: var(--m7); }
.faq__a p { margin: 0; color: var(--silver); font-size: 1rem; }

/* The door under the head. A text link with the laser's hairline under it,
   which is the nav link's vocabulary: no fill, no glow, no light spent. */
.faq__ask {
  max-width: var(--m4);
  margin: 1.5rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--silver);
}
.faq__ask a {
  color: var(--white-heat);
  text-decoration: none;
  border-bottom: 1px solid var(--live-wire);
  padding-bottom: 1px;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.faq__ask a:hover { border-bottom-color: var(--sky-glow); }
@media (max-width: 1019px) {
  .faq__ask { margin-top: 1.1rem; }
}

/* --------------------------------------------------------------------------
   19. Final CTA. The brightest moment on the page.
   -------------------------------------------------------------------------- */
.cta {
  position: relative;
  padding: clamp(5.5rem, 11vw, 10rem) 0;
  text-align: center;
  overflow: hidden;
}
.cta__field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(62% 60% at 50% 62%, rgba(46, 107, 255, 0.14) 0%, rgba(6, 7, 8, 0) 72%);
}
.cta__inner { position: relative; z-index: 2; }
.cta__title {
  font-weight: 600;
  font-size: clamp(1.9rem, 1.1rem + 4.4vw, 5rem);
  line-height: 1.0;
  letter-spacing: -0.02em;
  /* Ten columns, not eight: the split is authored line by line here and the
     two white lines have to hold without rewrapping under the sticker word. */
  max-width: var(--m10);
  margin-inline: auto;
}
/* More air under the CTA head than v2 shipped with, for two reasons: the last
   line is now a sticker word and a pasted object needs room around it, and the
   phone is 380px rather than 320px. The cord can only land on the beam if the
   object clears the headline's ink without being pushed down; measured, that
   needs about 40px more between the two than the head used to have. */
.cta .prose--centre { margin-top: clamp(2.6rem, 5vw, 5.5rem); position: relative; }
/* The copy pool (Rron, 2026-09-09: the two paragraphs sat on the handset's
   brightest chrome and lost). A soft ellipse of the page ground behind the
   prose, feathered to nothing well outside the measure, so it reads as
   depth in the scene rather than a box on it. Wide layouts only: on phones
   the plate lives in its own band under the copy. */
@media (min-width: 901px) {
  .cta .prose--centre::before {
    content: "";
    position: absolute;
    inset: -4rem -12rem;
    z-index: -1;
    pointer-events: none;
    /* Radii in the box's own terms: the text box ends at about 0.6 of the
       ellipse on its corners, still inside the dense core. */
    background: radial-gradient(ellipse 64% 80% at 50% 50%,
      rgba(6, 7, 8, 0.96) 0%,
      rgba(6, 7, 8, 0.92) 45%,
      rgba(6, 7, 8, 0.7) 70%,
      rgba(6, 7, 8, 0) 100%);
  }
  .cta .prose--centre p { text-shadow: 0 1px 14px rgba(6, 7, 8, 0.95), 0 0 2px rgba(6, 7, 8, 0.8); }
}
.cta .btn--hero { margin-top: clamp(2.25rem, 4vw, 3rem); }
.cta .microcopy { margin-top: 1.2rem; }

/* Symmetric: the beam grows out of the button's centre axis in both
   directions and its hot point sits on that axis. */
/* Long enough for the phone's cord to reach it. The cord's laser tip lands on
   this line's left end and the line carries that light to the hot point under
   the button, so the left end starts lit rather than fading in from nothing:
   the beam is being FED, and it dissipates rightwards after it has landed. */
.beam--cta {
  max-width: min(74%, 800px);
  margin: clamp(1.5rem, 2.8vw, 2.1rem) auto 0;
}
.beam--cta .beam__line {
  left: 50%;
  right: auto;
  transform: translate(-50%, -50%);
  background: linear-gradient(90deg, var(--live-wire) 0%, var(--live-wire) 34%, #EAF1FF 50%, var(--live-wire) 72%, rgba(46, 107, 255, 0) 100%);
}
.beam--cta .beam__tip {
  left: 50%;
  right: auto;
  transform: translate(-50%, -50%);
}

/* --------------------------------------------------------------------------
   20. Footer
   -------------------------------------------------------------------------- */
.footer {
  position: relative;
  border-top: 1px solid var(--hairline);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0 clamp(2.5rem, 5vw, 3.5rem);
}
.footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--deep-field);
  pointer-events: none;
}
.footer__grid {
  display: grid;
  gap: clamp(1.75rem, 3.5vw, 2.5rem) var(--col-gap);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .footer__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: center; }
  .footer__brand { grid-column: 1 / span 3; }
  .footer__nav { grid-column: 4 / span 6; }
  .footer__contact { grid-column: 10 / span 3; }
}
.footer__brand img { width: clamp(132px, 15vw, 176px); height: auto; opacity: 0.92; }
/* The full name under the mark's rule, which is where the locked lockup puts
   it; the footer is the one place on the page with the room to set it there. */
.footer__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.55rem; }
.footer__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--silver);
  padding-left: 0.3rem;
}

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
/* MONO CULL. Mono is for data on this page: stat labels, the source line, the
   session labels, the delivery line, the nav, the button microcopy, the build
   tag, the quote attributions. A footer set entirely in a typewriter face is
   not data, it is a costume, and it made the legal type harder to read at the
   one place a reader might actually need it. The whole footer is Switzer. */
.footer__nav a {
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  /* 22.1px of line box is under the 24px target minimum. On an inline box
     vertical padding grows the hit area without moving a single line, so the
     row looks identical and the target clears. Coarse pointers get much more
     than this, up in the base sheet. */
  padding-block: 2px;
  color: var(--slate);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.footer__nav a:hover { color: var(--white-heat); }
.footer__sep { color: var(--slate); opacity: 0.5; }

.footer__contact { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.6rem; }
.footer__contact a {
  font-size: 0.875rem;
  letter-spacing: 0.01em;
  color: var(--silver);
  text-decoration: none;
  border-bottom: 1px solid var(--edge);
  padding-bottom: 2px;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.footer__contact a:hover { color: var(--white-heat); border-bottom-color: var(--edge-hot); }
.footer__note {
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  color: var(--slate);
}

.footer__legal {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(1.75rem, 3vw, 2.25rem);
  border-top: 1px solid var(--hairline);
}
.footer__legal p {
  font-size: 0.875rem;
  line-height: 1.7;
  letter-spacing: 0.005em;
  color: var(--slate);
  max-width: var(--m8);
}
.attribution--footer {
  margin-top: 0.9rem;
  padding-left: 0;
  border-left: 0;
  max-width: var(--m8);
  font-family: var(--font-body);
  letter-spacing: 0.005em;
}
.footer__copy { margin-top: 1.5rem; margin-bottom: 0; }

/* --------------------------------------------------------------------------
   21. (The laser cursor is gone: client round 1, 2026-09-04, "a bit much and
   confusing on computers, especially for the target audience". The native
   pointer is never replaced or hidden. The room light and the motes below
   still follow it.)
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   22. Reactive background. A soft pointer light field and a canvas of
   drifting charge motes, both BUILT BY THE SCRIPT and only after it has
   cleared the same two gates as the cursor, so on a touch device or under
   reduced motion neither element exists in the document at all.

   STACKING. The wrapper sits at z-index -1, above the page ground and below
   every scrap of content. Opaque section grounds live on a -2 layer (and the
   halftone section's flat ground on -3) so the room light is not switched off
   for half the page.

   LIGHT BUDGET. Ambient texture, not a discharge: nothing here draws, strikes
   or travels along a line, and it comes nowhere near the CTA button.
   -------------------------------------------------------------------------- */
.ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
.ambient__motes {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.ambient__field {
  position: absolute;
  top: 0;
  left: 0;
  width: 760px;
  height: 760px;
  margin: -380px 0 0 -380px;
  will-change: transform;
  background: radial-gradient(closest-side,
    rgba(46, 107, 255, 0.068) 0%,
    rgba(46, 107, 255, 0.032) 38%,
    rgba(46, 107, 255, 0.010) 68%,
    rgba(46, 107, 255, 0) 100%);
}

/* --------------------------------------------------------------------------
   V3 PLATES (2026-09-06). Photographic still lifes of unfinished business.
   Full-bleed plates, never cut-outs: their unoccupied edges are already
   Blackout, and a mask fades the last few percent so no rectangle can show
   against the page ground on any monitor. The beam segment painted into each
   plate is the plate's own; the page's beams stay where they were.
   -------------------------------------------------------------------------- */
.plate {
  position: relative;
  margin: 0;
  pointer-events: none;
  overflow: hidden;
}
.plate img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Beside the copy: the copy runs seven columns, the plate takes the rest. A
   grid, not an overlay: the plate is opaque Blackout to its edges, so if it
   floated over the row it would paint out whatever it overlapped (it did:
   the villain headline's last line, first pass). As a grid item it sizes the
   row and the copy centres beside it. */
.stage--side {
  position: relative;
  display: grid;
  grid-template-columns: var(--m7) minmax(0, 1fr);
  column-gap: var(--col-gap);
  align-items: center;
}
.stage--side > .blocks,
.stage--side > .prose { max-width: none; }
.plate--side {
  aspect-ratio: 4 / 3;
  width: 100%;
  align-self: center;
}
.plate--how,
.plate--us { aspect-ratio: 16 / 9; }
/* The head inside the copy column: the section's h2 stacks over its prose
   so the plate has one block to centre against, not a stranded headline
   above the grid and two lines adrift beside it. The head's own bottom
   margin is the gap to the prose, tightened, since nothing else reads here. */
.stage--side-headed > .stage__copy { min-width: 0; }
.stage--side-headed .sec-head { margin-bottom: clamp(1.25rem, 2vw, 1.75rem); }
.stage--side-headed .prose { max-width: none; }
/* The stopwatch render holds its subject at a third of the frame; the plate
   crops in so the watches carry the tile instead of the black around them.
   Its beam row stays on the horizontal centre line, so the crop is centred. */
.plate--how img {
  transform: scale(1.36);
  transform-origin: 50% 50%;
}
/* The desk render keeps its left two fifths black. The crop anchors on the
   desk itself, so the phone, screen and tie fill the tile instead of a
   void beside them. */
.plate--us img {
  transform: scale(1.22);
  transform-origin: 64% 60%;
}
/* The section's own rhythm (Rron, 2026-09-08: too much air above, too
   close to the traits below). The plate's masked top edge already reads as
   air, so the section opens tighter than the page default, and the traits
   sub-block stands further off the copy. */
#us { padding-top: clamp(3.5rem, 6vw, 5.5rem); }
#us .sub-block { margin-top: clamp(4.5rem, 8.5vw, 7.5rem); }
/* Every plate fades its last stretch on all four sides, so its Blackout
   ground can never draw a rectangle on the page's darker deep-space ground. */
.plate--side,
.plate--band {
  -webkit-mask-image:
    linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, #000 12%, #000 88%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 14%, #000 86%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, #000 12%, #000 88%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000 14%, #000 86%, rgba(0, 0, 0, 0) 100%);
  mask-composite: intersect;
}
/* The wide band: one beam through four plates, above the four moves. */
.plate--band {
  aspect-ratio: 3 / 1;
  margin: clamp(2.5rem, 4.5vw, 4rem) 0 clamp(2rem, 3.5vw, 3rem);
}
.plate--band img { object-position: 50% 50%; }
/* Phone hero band: hidden until the media query below. */
.hero__scene-m { display: none; }
/* Book a call: the receiver at rest under the copy, painted as a background
   so a missing file paints nothing. Anchored to the bottom, faded in from a
   third of the way down, under the field's own blue breath. */
.cta__plate {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: url("../assets/img/v4-call-handset.webp");
  background-repeat: no-repeat;
  /* Cover by default; the script re-sizes and slides it so the plate's
     painted beam row (0.7803 of the image) sits on the button's beam, the
     same one-line law the hero obeys. */
  background-position: 50% 100%;
  background-size: cover;
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 22%, #000 55%);
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 22%, #000 55%);
}
/* The plate settles: a slow fade with a touch of scale, no slap. */
.js .reveal--plate { transform: scale(1.035); }
.js .reveal--plate.is-in { transition: opacity 900ms var(--ease-out), transform 1200ms var(--ease-out); }

@media (max-width: 900px) {
  /* One column: the plates sit under their copy, full width. */
  .stage--side { display: block; }
  .plate--side {
    aspect-ratio: 3 / 2;
    margin-top: 2rem;
  }
  .plate--band { aspect-ratio: 2 / 1; }
  /* The whole handset, smaller, in a band the section reserves under the
     microcopy, so no line of type sits on the photograph. */
  .cta { padding-bottom: calc(2rem + 48vw); }
  .cta__plate {
    background-size: 100% auto !important;
    background-position: 50% 100% !important;
  }
  /* THE PHONE POCKET (Rron, 2026-09-07: the piece sat alone under the copy;
     it now lives in the empty space beside the headline). Positioned by the
     host script against the measured headline block; behind the type. */
  .hero__scene-m {
    display: block;
    position: absolute;
    right: -3vw;
    top: 0;
    width: 50vw;
    height: 240px;
    z-index: 0;
    pointer-events: none;
  }
  .hero__title, .hero .lede, .hero .beam--hero { position: relative; z-index: 1; }
}

/* --------------------------------------------------------------------------
   23. Scroll reveals, with variety so the page does not metronome. Four
   flavours, assigned by what the element is rather than at random.
   -------------------------------------------------------------------------- */
.js .reveal { opacity: 0; transform: translateY(14px); }
.js .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}

/* Headlines arrive out of a clip rather than by sliding: the claim wipes on. */
.js .reveal--clip {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 105% 0);
}
.js .reveal--clip.is-in {
  clip-path: inset(-25% -25% -25% -25%);
  transition: clip-path 760ms var(--ease-out);
}

/* Blocks that carry weight rise further and settle slower. */
.js .reveal--lift { transform: translateY(26px); }
.js .reveal--lift.is-in { transition: opacity 720ms var(--ease-out), transform 720ms var(--ease-out); }

/* Sets of siblings enter as a set, one beat apart, and inside the JOLT cards
   the oversized letter follows its own card by another beat. */
.js .reveal--group { opacity: 1; transform: none; }
.js .reveal--group > * {
  opacity: 0;
  transform: translateY(18px) rotate(-0.9deg);
}
.js .reveal--group.is-in > * {
  opacity: 1;
  transform: none;
  transition:
    opacity 540ms var(--ease-out) calc(var(--i, 0) * 70ms),
    transform 540ms var(--ease-out) calc(var(--i, 0) * 70ms);
}
.js .reveal--group .card__letter { opacity: 0; transform: translateY(16px) scale(0.94); }
.js .reveal--group.is-in .card__letter {
  opacity: 1;
  transform: none;
  transition:
    opacity 500ms var(--ease-out) calc(160ms + var(--i, 0) * 90ms),
    transform 500ms var(--ease-out) calc(160ms + var(--i, 0) * 90ms);
}

/* THE MEASUREMENT PASS READS THROUGH THE ENTRANCES.

   An entrance on this page is a transform, and a transform moves the INK
   without moving the layout. Anything the script places against ink (the
   proof band's strike, the bubble in the villain headline, the cord under the
   CTA button, the fitted rules) therefore has to be measured against where
   the ink is going to be, not against where an unplayed entrance is holding
   it. The proof band is `.reveal--lift`: measured before it entered, its
   figures read 26px low and the strike landed on the caption underneath them,
   which is exactly the first-load bug.

   `is-measuring` is set on the root for the length of ONE synchronous read in
   js/main.js and taken off before the frame is painted. It can only reach
   entrances that have not landed yet, and those are at opacity 0 with no
   transition declared, so there is nothing on screen for it to move and
   nothing in flight for it to interrupt. An entrance that IS in flight books
   its own re-measure for when it settles.
   -------------------------------------------------------------------------- */
html.is-measuring .reveal:not(.is-in),
html.is-measuring .reveal--group:not(.is-in) > *,
html.is-measuring .reveal--group:not(.is-in) .card__letter,
html.is-measuring .hero__title:not(.is-in) .w > i {
  transform: none !important;
}

/* --------------------------------------------------------------------------
   23a. Narrow stages. Below the widest layout the display measures come in a
   column, and below 900 the side plates leave their column and sit under the
   copy they belong to.

   This block is last on purpose. A padding declared in a component section
   above would be overridden by that component's own later rule.
   -------------------------------------------------------------------------- */
@media (max-width: 1140px) {
  .cta__title { max-width: var(--m9); }
}
@media (max-width: 900px) {
  /* V3: no reserved bands. Every plate sits in the flow under its own copy,
     so the phone hero goes back to plain padding and the stage bands to air. */
  .hero {
    padding-top: clamp(3.5rem, 7vh, 5rem);
    padding-bottom: clamp(2.5rem, 6vh, 4rem);
  }
  #how .stage--band { padding-top: 2rem; }
  .section--villain { padding-bottom: 4.5rem; }
}

/* --------------------------------------------------------------------------
   24. Still mode. ?still=1 freezes the page at its end state so the gates can
   photograph something deterministic. Entrances land instantly, every loop is
   paused at frame zero, and the script never builds the cursor canvas.
   -------------------------------------------------------------------------- */
html.still .hero__title .w > i,
html.still .reveal,
html.still .reveal--group > *,
html.still .reveal--group .card__letter { transition: none !important; }
html.still .ticker__track { animation-play-state: paused !important; }
html.still .btn--hero::after { animation: none !important; opacity: 0.92 !important; }
html.still .beam__line { transition: none !important; }
html.still .card__letter::after { transition: none !important; }

/* --------------------------------------------------------------------------
   25. Reduced motion. Every animated behaviour switches off here and the page
   stays completely readable: the plates simply sit there, fully visible.
   -------------------------------------------------------------------------- */
@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;
  }
  .js .reveal { opacity: 1; transform: none; }
  .js .reveal--clip { clip-path: none; }
  .js .reveal--group > * { opacity: 1; transform: none; }
  .js .reveal--group .card__letter { opacity: 1; transform: none; }
  .js .hero__title .w > i { opacity: 1; transform: none; }
  .js .beam__line { width: var(--beam-len, 100%); }

  /* Stickers are visible objects, not an effect: no entrance, no float, no
     tilt, and the artwork is simply there. */

  /* The one loop on the page becomes one static line of the same words. There
     is then nothing to pause, so the control goes with it and the band takes
     its reserved gutter back. */
  .ticker__viewport { display: none; }
  .ticker__ctl { display: none; }
  .ticker { padding-right: 0; }
  .ticker__still { display: block; }
  .btn--hero::after { animation: none !important; opacity: 1; }

  /* The script never builds the reactive background under this preference.
     This makes it unpaintable even if one were somehow put in the page. */
  .ambient { display: none !important; }
}

/* --------------------------------------------------------------------------
   25. The finale's head on a phone. The three authored lines are a desktop
   composition: at 390 "Ready to give your" and "team training they" each
   wrap, leaving "YOUR" and "THEY" alone on their own lines and a five line
   stack with two orphans. Below 600 the two white lines flow as one run of
   text and wrap where the column says; only the sticker word keeps its own
   line. The clip reveal is on the h2, so inline lines cost it nothing.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
  .cta__title .hl-line:not(:last-child) { display: inline; }
  .cta__title .hl-line:not(:last-child)::after { content: " "; }
  .cta__title .hl-line:last-child { display: block; margin-top: 0.12em; }
}
