/* ─────────────────────────────────────────────────────────────────────────
   /partners-v6b — the document's journey across the whole hero.

   Layers on partners.css. The hero keeps v3's single-column copy, and the
   picture sits behind it across the full width of the hero, the way v3's
   conduit field did. partners-journey-v6b.js draws into
   .partners-journey-canvas: one bright path with six waypoints, a ball that
   travels it, and a lattice of dimmer pathways behind.

   Two layers, kept apart. .hero-atmosphere holds the lagoon mesh, the orbs,
   at full strength as v1 had them, and always sits behind the copy.
   .hero-journey holds the canvas, its own scrim over the canvas, and the
   waypoint labels above the scrim so the type stays crisp; the script
   positions them and toggles .is-lit. On a desktop .hero-journey covers the
   hero on top of the orbs, and its scrim quiets the half where the copy is.

   Under 1025px the copy spans the width, so .hero-journey leaves the
   background and becomes a band of its own under the button. The orbs stay
   behind the copy, where they were.

   The palette the script draws with is read from the custom properties on the
   canvas, so line and step colours are tuned here, not in JS.

   The b pass: the canvas fades in from the left, from nothing behind the
   copy to full strength where the ball travels, the same move the homepage
   makes over its orbs but firmer, so the coloured ribbon never fights the
   headline. The script writes --jn-safe-left (where the copy ends, desktop)
   on the section, and the mask below keys off it. The labels are larger and carry an icon for their step.
   ───────────────────────────────────────────────────────────────────────── */

/* ───────── 01 layout ─────────
   The copy is wrapped so the script can measure where it ends: to the right
   of it on a desktop is where the ball travels and the labels may sit. */
.partners-hero .hero-copy { max-width: 850px; }

/* Desktop: the orbs are v1's, untouched. The atmosphere keeps
   microsite.css's mask (full to 68%, gone by the edge), .hero::after its
   gradient into the page colour, and .hero::before its glow, so the orbs
   melt into the black the way v1's did. Overriding those ran the orbs to
   the hero's edge and left a hard line where the next section starts. The
   journey sits above all of it (below), so the fade dims the orbs, not the
   path. Stacked, the hero ends on the journey band on plain black, so the
   gradient and the glow have nothing to fade and stay off. */
@media (max-width: 1024px) {
  .partners-hero--v6b::before,
  .partners-hero--v6b::after { display: none; }
}

/* Stacked: the journey is its own band under the button, in the page's
   flow, on plain black. The orbs stay behind the copy only: the atmosphere
   stops halfway down the gap under the button and fades out over its last
   stretch, so the band below sits on the page colour. The gap between the
   button and the band is twice --space-3xl, so the orbs have room to fade
   before the path starts; --space-3xl again sits between the band and the
   next section. The band fades its own top and bottom edges (section 02),
   so the path melts into the black rather than stopping at a line. */
@media (max-width: 1024px) {
  .partners-hero--v6b { --jn-band: clamp(15rem, 56vw, 21rem); }
  .partners-hero--v6b .hero-stack { margin-bottom: calc(var(--space-3xl) * 2); }
  .partners-hero--v6b .hero-atmosphere {
    bottom: calc(var(--jn-band) + var(--space-3xl) * 2);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 78%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0%, #000 78%, transparent 100%);
  }
  .partners-hero--v6b .hero-journey {
    position: relative;
    z-index: 1;
    height: var(--jn-band);
    margin-bottom: var(--space-3xl);
    overflow: hidden;
    pointer-events: none;
  }
}

/* Desktop: the journey covers the hero, over the orbs and their fade into
   black, and under the copy. It sits above .hero::after (z-index 0), so the
   bottom fade dims the orbs but not the path; the copy moves up to 2 to stay
   on top. The lines soften over their own last 12% so the lattice does not
   stop dead at the hero's edge. */
@media (min-width: 1025px) {
  .partners-hero--v6b .hero-content-and-logo-bar { z-index: 2; }
  .partners-hero--v6b .hero-journey {
    position: absolute;
    z-index: 1;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 88%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0%, #000 88%, transparent 100%);
  }
}

/* ───────── 02 the canvas ───────── */
.partners-journey-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.4s ease .2s;

  /* The fade-in from the left. Nothing at the page edge, a trace across the
     lead copy, and full strength from the copy's right edge on, where the
     ball and its labels live. The script keeps --jn-safe-left at the copy's
     edge; the fallback is where that lands on a wide desktop. The
     configurator moves the ramp with --jn-lf-at (px past the copy's edge
     where lines reach full strength), --jn-lf-len (px the ramp takes) and
     --jn-lf-floor (how much shows behind the copy), all set on the section. */
  --jn-safe-left: 64%;
  -webkit-mask-image: linear-gradient(to right,
    transparent 0%,
    rgb(0 0 0 / calc(.04 * var(--jn-lf-floor))) 16%,
    rgb(0 0 0 / calc(.18 * var(--jn-lf-floor))) calc(var(--jn-safe-left) + var(--jn-lf-at) - var(--jn-lf-len)),
    rgb(0 0 0 / .5) calc(var(--jn-safe-left) + var(--jn-lf-at) - var(--jn-lf-len) * .43),
    #000 calc(var(--jn-safe-left) + var(--jn-lf-at)));
  mask-image: linear-gradient(to right,
    transparent 0%,
    rgb(0 0 0 / calc(.04 * var(--jn-lf-floor))) 16%,
    rgb(0 0 0 / calc(.18 * var(--jn-lf-floor))) calc(var(--jn-safe-left) + var(--jn-lf-at) - var(--jn-lf-len)),
    rgb(0 0 0 / .5) calc(var(--jn-safe-left) + var(--jn-lf-at) - var(--jn-lf-len) * .43),
    #000 calc(var(--jn-safe-left) + var(--jn-lf-at)));

  /* the pathways behind: a wide body and a brighter rim */
  --jn-tube: rgba(205, 222, 238, .14);
  --jn-rim: rgba(215, 230, 245, .34);
  --jn-node: rgba(225, 236, 248, .5);
  /* the document's own path, ahead of the ball: a step brighter */
  --jn-main: rgba(215, 230, 245, .22);
  --jn-main-rim: rgba(225, 236, 248, .55);
  /* one colour per step, in order: trigger, generated, reviewed, sent,
     signed, synced. The ball carries a step's colour until the next one. */
  --jn-c0: #FF7A59;
  --jn-c1: #F1B734;
  --jn-c2: #71ADE2;
  --jn-c3: #91BC70;
  --jn-c4: #9180C8;
  --jn-c5: #37ACD9;
}
.partners-hero--v6b.is-journey-ready .partners-journey-canvas { opacity: 1; }

/* Stacked, the path has its own band under the button, so nothing needs
   hiding behind copy: the band just fades in at its top edge and out at its
   bottom, into the orbs above and the next section below. */
@media (max-width: 1024px) {
  .partners-journey-canvas {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 80%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 18%, #000 80%, transparent 100%);
  }
}

/* The orbs run at full strength, as v1 had them (partners.css), under
   v1's own lighter veil. The journey's scrim over them is kept light
   (below), so the orbs still read as the hero's picture. */
/* The journey's scrim: a light extra veil over the copy side, clear past
   it. It belongs to .hero-journey, over its canvas and the orbs below. It
   used to reach 72% dark, which on top of v1's own veil buried the orbs on
   the left half. The canvas's own mask already keeps lines out from behind
   the headline, so the scrim only has to take the edge off. Desktop only:
   stacked, the band has no copy over it. */
/* The configurator scales and stretches it: --jn-fade (darkness),
   --jn-fade-hold and --jn-fade-end (where it starts to lift and where it is
   gone, % of width), --jn-shade (the top and bottom bands). The stops keep
   the original curve between hold and end. */
.partners-hero--v6b {
  --jn-lf-at: 0px;
  --jn-lf-len: 280px;
  --jn-lf-floor: 1;
  --jn-fade: 1;
  --jn-fade-hold: 0%;
  --jn-fade-end: 100%;
  --jn-shade: 1;
}
@media (min-width: 1025px) {
  .partners-hero--v6b .hero-journey::after {
    content: '';
    position: absolute;
    z-index: 2;
    inset: 0;
    pointer-events: none;
    --jn-span: calc(var(--jn-fade-end) - var(--jn-fade-hold));
    background:
      linear-gradient(to right,
        color-mix(in oklab, var(--bg) calc(30% * var(--jn-fade)), transparent) var(--jn-fade-hold),
        color-mix(in oklab, var(--bg) calc(24% * var(--jn-fade)), transparent) calc(var(--jn-fade-hold) + var(--jn-span) * .26),
        color-mix(in oklab, var(--bg) calc(12% * var(--jn-fade)), transparent) calc(var(--jn-fade-hold) + var(--jn-span) * .48),
        transparent calc(var(--jn-fade-hold) + var(--jn-span) * .66)),
      linear-gradient(to bottom,
        color-mix(in oklab, var(--bg) calc(8% * var(--jn-shade)), transparent),
        transparent 26%);
  }
}

/* ───────── 03 the waypoint cards ─────────
   A small card over each waypoint: the step's icon in the step's colour and
   its number, then the step's name in a heavier weight and a one-line
   subline saying what happens there. Centred over its waypoint with a short
   stem the canvas draws. The script sets --jn-color, left and top, and
   --jn-edge: 1 in the open, falling to 0 as the waypoint drifts toward the
   copy, so a card is gone before it would pass behind the headline. Hidden
   until the ball arrives; pops up on the site's motion curve. */
.jn-labels {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: visible;
  pointer-events: none;
}
.jn-label {
  --jn-color: #fff;
  --jn-edge: 1;
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  gap: .3em;
  min-width: 13.5em;
  padding: 1em 1.25em 1.05em;
  border-radius: 16px;
  font-family: var(--font-body);
  font-size: calc(16px * var(--jn-card, 1));
  line-height: 1.2;
  white-space: nowrap;
  color: var(--text-primary);
  background: color-mix(in oklab, #1f1f23 94%, transparent);
  border: 1px solid color-mix(in oklab, var(--text-primary) 10%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--text-primary) 6%, transparent),
    0 0 0 1px color-mix(in oklab, var(--bg) 60%, transparent),
    0 18px 40px -14px rgba(0, 0, 0, .7),
    0 16px 42px -18px color-mix(in oklab, var(--jn-color) 55%, transparent);
  opacity: 0;
  transform: translateY(10px) scale(.96);
  transition: opacity .35s ease, transform .6s var(--ease-motion);
  will-change: opacity, transform;
}
.jn-label.is-lit {
  opacity: var(--jn-edge);
  transform: none;
}
/* past its "visible for" time (cardLife): fade out ahead of the waypoint */
.jn-label.is-lit.is-done {
  opacity: 0;
  transform: translateY(-6px) scale(.98);
}
.jn-label-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: .45em;
}
.jn-label-icon {
  width: 1.4em;
  height: 1.4em;
  color: var(--jn-color);
  filter: drop-shadow(0 0 8px color-mix(in oklab, var(--jn-color) 55%, transparent));
}
.jn-label-n {
  font-family: var(--font-display);
  font-size: .7em;
  letter-spacing: .1em;
  color: color-mix(in oklab, var(--jn-color) 70%, var(--text-secondary));
}
.jn-label-text {
  font-size: 1.06em;
  font-weight: 600;
  letter-spacing: -.005em;
}
.jn-label-sub {
  font-size: .8em;
  font-weight: 400;
  color: color-mix(in oklab, var(--text-primary) 72%, var(--text-secondary));
}
.jn-labels.is-no-sub .jn-label-sub { display: none; }
@media (max-width: 480px) {
  .jn-label { min-width: 0; padding: .7em .9em .75em; border-radius: 12px; }
  .jn-label-icon { width: 1.1em; height: 1.1em; }
  .jn-label-top { margin-bottom: .25em; }
  .jn-label-text { font-size: .9em; }
  .jn-label-sub { font-size: .72em; }
}

/* ───────── 04 copy that steps back ─────────
   Same as v4 and v5: the commission line under the button and the one-line
   subs under the section headlines sit a step dimmer so the headline and
   button lead. */
.partners-hero .hero-commission { color: color-mix(in oklab, var(--text-primary) 45%, var(--text-secondary)); font-weight: 400; }
.partners-page .split-head-sub { color: color-mix(in oklab, var(--text-primary) 30%, var(--text-secondary)); }

/* ───────── 05 the offer note ─────────
   The asterisk note sits under the partner program's three bullets, next to
   the claims it qualifies, instead of down in the footer, and runs the
   column's full width. */
.partners-offer .offer-terms {
  max-width: none;                 /* the column's full width, not a measure cap */
  margin: var(--space-m) 0 0;
  font-size: var(--fs-cap);
  line-height: 1.5;
  color: var(--text-tertiary);
}

/* ───────── 06 the hero configurator (dev only) ─────────
   Press C on the page. The same panel the homepage hero has, restyled under
   .jn-tuner. Delete this block and buildTuner() in partners-journey-v6b.js
   once the numbers are locked in. */
/* ───────── tuning panel (dev only — delete this block and the panel code
   in partners-journey-v6b.js once the numbers are locked in) ───────── */

.jn-tuner {
  position: fixed;
  z-index: 90;
  top: calc(var(--nav-h, 64px) + 14px);
  right: 14px;
  width: 268px;
  max-height: calc(100vh - var(--nav-h, 64px) - 28px);
  padding: 12px 14px 14px;
  border-radius: 12px;
  border: 1px solid color-mix(in oklab, var(--text-primary) 16%, transparent);
  background: color-mix(in oklab, #0a0a0c 88%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
  font-family: 'Work Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  font-size: 10px;
  line-height: 1.4;
  color: var(--text-secondary);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.jn-tuner-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid color-mix(in oklab, var(--text-primary) 12%, transparent);
}

.jn-tuner-title {
  color: var(--text-primary);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.jn-tuner-fps { color: var(--accent); font-variant-numeric: tabular-nums; }

/* ── collapsible groups ── */

.jn-tuner-section { margin: 6px 0 2px; }

.jn-tuner-group {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin: 0 0 6px;
  padding: 5px 0 5px;
  border: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--text-primary) 8%, transparent);
  background: transparent;
  color: color-mix(in oklab, var(--text-secondary) 85%, transparent);
  font-family: inherit;
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
}

.jn-tuner-group:hover { color: var(--text-primary); }

.jn-tuner-caret {
  display: inline-block;
  color: var(--accent);
  transition: transform .15s ease;
}

.jn-tuner-section.is-collapsed .jn-tuner-caret { transform: rotate(-90deg); }
.jn-tuner-section.is-collapsed .jn-tuner-body { display: none; }

/* the ⓘ after a label that has a tooltip (the tooltip itself is the native
   title, so it works on the checkbox rows and the dropdowns too) */
.jn-tuner-name { display: inline-flex; align-items: center; gap: 5px; }

.jn-tuner-info {
  display: inline-grid;
  place-items: center;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--text-secondary) 55%, transparent);
  color: color-mix(in oklab, var(--text-secondary) 80%, transparent);
  font-size: 7px;
  font-style: normal;
  line-height: 1;
  cursor: help;
}

.jn-tuner-row:hover .jn-tuner-info,
.jn-tuner-toggles label:hover .jn-tuner-info {
  border-color: var(--accent);
  color: var(--accent);
}

.jn-tuner-row { margin-bottom: 9px; }

.jn-tuner-row label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 3px;
  cursor: default;
}

.jn-tuner-row output {
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.jn-tuner input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 3px;
  margin: 0;
  border-radius: 3px;
  background: color-mix(in oklab, var(--text-primary) 20%, transparent);
  cursor: ew-resize;
}

.jn-tuner input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 0;
  background: var(--accent);
}

.jn-tuner input[type="range"]::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 0;
  background: var(--accent);
}

.jn-tuner-toggles {
  display: grid;
  gap: 2px;
  margin: 4px 0 8px;
}

.jn-tuner-toggles label {
  display: flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  /* The row is the hit area, not the 13px box inside it. WCAG 2.2 asks for a
     24x24 target; the checkbox alone was 13x13 and failed. min-height plus the
     label wrapping the input gets there without making the box look bigger. */
  min-height: 24px;
}

.jn-tuner-toggles input {
  accent-color: var(--accent);
  margin: 0;
  /* Was the browser default, ~13px square, which failed the same 24px rule.
     Sizing the control itself is the one approach Chrome renders reliably —
     border and padding are ignored on a native checkbox. */
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
}

.jn-tuner-actions { display: flex; gap: 6px; margin-top: 12px; }

.jn-tuner-actions button,
.jn-preset-tools button {
  flex: 1;
  padding: 6px 4px;
  border-radius: 6px;
  border: 1px solid color-mix(in oklab, var(--text-primary) 22%, transparent);
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 10px;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}

.jn-tuner-actions button:hover,
.jn-preset-tools button:hover {
  background: color-mix(in oklab, var(--text-primary) 12%, transparent);
  border-color: var(--text-primary);
}

/* ── tabs ── */

.jn-tuner-tabs {
  display: flex;
  gap: 2px;
  margin: -2px 0 8px;
  border-bottom: 1px solid color-mix(in oklab, var(--text-primary) 12%, transparent);
}

.jn-tuner-tab {
  flex: 1;
  padding: 6px 4px 7px;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: transparent;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}

.jn-tuner-tab:hover { color: var(--text-primary); }
.jn-tuner-tab.is-active { color: var(--text-primary); border-bottom-color: var(--accent); }

/* ── background dropdown ── */

.jn-tuner-select {
  display: block;
  width: 100%;
  margin: 2px 0 6px;
  padding: 5px 6px;
  border-radius: 6px;
  border: 1px solid color-mix(in oklab, var(--text-primary) 22%, transparent);
  background: color-mix(in oklab, #0a0a0c 70%, transparent);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 10px;
  cursor: pointer;
}

.jn-tuner-select:hover { border-color: var(--text-primary); }
.jn-tuner-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── presets ── */

.jn-tuner-presets { display: grid; gap: 2px; }

.jn-tuner-empty {
  margin: 6px 0 10px;
  color: color-mix(in oklab, var(--text-secondary) 80%, transparent);
  line-height: 1.5;
}

.jn-preset {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 4px 8px;
  padding: 7px 0 8px 8px;
  border-left: 2px solid transparent;
  border-bottom: 1px solid color-mix(in oklab, var(--text-primary) 8%, transparent);
  transition: border-color .15s ease, background .15s ease;
}

.jn-preset.is-active {
  border-left-color: var(--accent);
  background: color-mix(in oklab, var(--accent) 7%, transparent);
}

.jn-preset-name {
  min-width: 0;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 11px;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.jn-preset-name:hover { color: var(--accent); }

.jn-preset-meta {
  color: color-mix(in oklab, var(--text-secondary) 70%, transparent);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.jn-preset-input {
  grid-column: 1;
  min-width: 0;
  padding: 2px 4px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  background: color-mix(in oklab, var(--text-primary) 8%, transparent);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 11px;
  outline: none;
}

.jn-preset-tools {
  grid-column: 1 / -1;
  display: flex;
  gap: 4px;
}

.jn-preset-tools button {
  flex: 0 0 auto;
  padding: 3px 7px;
  font-size: 9px;
}

.jn-preset-delete.is-armed {
  border-color: var(--accent);
  color: var(--accent);
}

.jn-tuner-hint {
  margin-top: 9px;
  color: color-mix(in oklab, var(--text-secondary) 70%, transparent);
  font-size: 9px;
}

/* .jn-tuner-toggle (the "C" pill) was removed: the configurator is
   keyboard-only now. See the note in partners-journey-v6b.js. */

@media (max-width: 900px) {
  .jn-tuner { display: none !important; }
}
