/* The site's look: the Night palette, depth, glow and scroll reveals.
   <html> carries data-theme="night" (or "dusk", from the header switch; see
   layouts/partials/theme-head.html) and data-look="glow": dark pages with
   coloured light around the 3D elements. Nothing here applies without
   data-look. */

@property --glow { syntax: "<color>"; inherits: true; initial-value: #4FD6A0; }
@property --ring { syntax: "<color>"; inherits: false; initial-value: transparent; }

/* Switching between Night and Dusk (static/js/looks.js): a slow cross-fade,
   or where the browser cannot cross-fade, colours that ease across. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .7s; animation-timing-function: ease; }
:root.theme-fading, :root.theme-fading * {
  transition: background-color .6s ease, color .6s ease, border-color .6s ease, fill .6s ease, stroke .6s ease,
    box-shadow .6s ease, --ring .6s ease !important;
}

/* ── Night palette ──────────────────────────────────── */
:root[data-theme="night"] {
  --paper: #0C1216; --band-alt: #0F171C; --surface: #141F26;
  --ink: #EAF2F3; --ink-2: #B4C3C9; --ink-3: #8D9FA8;
  --rule: #22313A; --rule-strong: #384B56;
  --l-recon: #4FD6A0; --l-comp: #82B2FF; --l-support: #F5B94E; --l-contract: #F28CC2; --l-campaign: #4DD3E0; --l-report: #EAF2F3;
  --night: #080C0F; --btn-hover: #FFFFFF; --focus: #8FC2FF; --strike: #F08F6E;
  --deco-dot: rgba(234, 242, 243, .05); --deco-opacity: .28;
}
:root[data-theme="night"] .copy .code { color: #0C1216; }
:root[data-theme="night"] .screen .pill-open { color: #7C4600; }
:root[data-theme="night"] .screen .pill-ok { color: #0B6446; }
:root[data-theme="night"] .screen {
  --surface: #CDD6DF; --screen-top: #C1CBD5; --rule: #ABB8C5; --rule-strong: #8E9DAD;
  --ink-2: #3C4856; --ink-3: #4F5C6A;
  --l-recon: #0E6E4F; --l-support: #A86500; --l-campaign: #0A6B78;
  border-color: #22313A;
}
/* The route map is drawn in the night palette itself: bright lines on a dark
   panel read better here than a light island. */
:root[data-theme="night"] .rm-frame {
  --paper: #0C1216; --surface: #111B21; --ink: #EAF2F3; --ink-2: #B4C3C9; --ink-3: #8D9FA8;
  --rule: #22313A; --rule-strong: #384B56;
  --l-recon: #4FD6A0; --l-comp: #82B2FF; --l-support: #F5B94E; --l-contract: #F28CC2; --l-campaign: #4DD3E0; --l-report: #EAF2F3;
  border-color: #22313A;
}
:root[data-theme="night"] body {
  background:
    radial-gradient(1100px 680px at 88% -8%, rgba(79, 214, 160, .11), transparent 62%),
    radial-gradient(900px 640px at -6% 38%, rgba(130, 178, 255, .06), transparent 60%),
    var(--paper);
  background-attachment: fixed;
}
:root[data-look="glow"] .band-white { background-color: color-mix(in srgb, var(--band-alt) 72%, transparent); }
:root[data-look="glow"] .band-ink { background: color-mix(in srgb, var(--night) 88%, transparent); }
:root[data-look="glow"] .rm-line { filter: drop-shadow(0 0 6px color-mix(in srgb, currentColor 70%, transparent)); }
:root[data-look="glow"] .rm-bar-level.is-on { filter: drop-shadow(0 0 5px currentColor); }
:root[data-look="glow"] .btn:not(.btn-quiet):hover { box-shadow: 0 0 0 1px var(--ink), 0 0 28px -4px color-mix(in srgb, var(--ink) 55%, transparent); }

/* ── Scroll reveal ──────────────────────────────────── */
/* The head script sets .rv-on only with motion allowed, and takes it away
   again if looks.js has not started within 3 s, so nothing stays hidden.
   Reveals use translate and opacity, leaving transform free for the tilt. */
.rv-on :where(.band .section-head, .line-section .copy, .replace-item, .side, .tier, .principles li,
  .roadmap li, .steps li, .trust-big, .closing > *, .shots-under, .split > div:first-child, .form-panel) {
  opacity: 0; translate: 0 28px;
  transition: opacity .7s cubic-bezier(.2, .7, .2, 1), translate .8s cubic-bezier(.2, .7, .2, 1), filter .7s ease,
    transform .5s cubic-bezier(.2, .7, .2, 1), box-shadow .3s, border-color .3s;
  transition-delay: calc(var(--rv-i, 0) * 90ms);
}
.rv-on[data-look="glow"] :where(.band .section-head, .line-section .copy, .replace-item, .side, .tier, .principles li,
  .roadmap li, .steps li, .trust-big, .closing > *, .shots-under, .split > div:first-child, .form-panel) { filter: blur(6px); }
/* Only what blurred in loses its filter: the screens and the map keep their glow. */
.rv-on[data-look="glow"] :where(.band .section-head, .line-section .copy, .replace-item, .side, .tier, .principles li,
  .roadmap li, .steps li, .trust-big, .closing > *, .shots-under, .split > div:first-child, .form-panel).is-in { filter: none; }
@supports not (animation-timeline: view()) {
  .rv-on :where(.panel-shot, .shots-stage, .rm-frame) { opacity: 0; translate: 0 28px; transition: opacity .8s, translate .9s cubic-bezier(.2, .7, .2, 1); }
}
.rv-on .is-in.is-in.is-in { opacity: 1; translate: 0 0; }
@media print { .rv-on * { opacity: 1 !important; translate: none !important; filter: none !important; } }

/* ── Pointer tilt ───────────────────────────────────── */
.tilt {
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .5s cubic-bezier(.2, .7, .2, 1), box-shadow .3s, border-color .3s, --ring .3s,
    opacity .7s cubic-bezier(.2, .7, .2, 1), translate .8s cubic-bezier(.2, .7, .2, 1), filter .7s ease;
  will-change: transform;
}
/* While looks.js eases the angle frame by frame, the transform has no transition of its own. */
.tilt.is-easing { transition: box-shadow .3s, border-color .3s, --ring .3s, opacity .7s, translate .8s, filter .7s; }
/* A sheen that follows the pointer, like light on glass. */
.tilt.has-sheen { position: relative; }
.tilt.has-sheen::after {
  content: ""; position: absolute; inset: 0; border-radius: calc(var(--radius-panel) - 1px); pointer-events: none;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%), rgba(255, 255, 255, var(--sheen, .07)), transparent 55%);
  opacity: 0; transition: opacity .3s;
}
.tilt.has-sheen.is-tracking::after { opacity: 1; }

/* ── Screens stage: the current screen in front, its neighbours fanned out
   behind it, lit in the colour of the screen's line ─────────────────── */
/* No preserve-3d: the tilted front screen would cut through the glow behind it. */
.shots-stage { position: relative; perspective: 2000px; }
.shots-stage .shots-frame { position: relative; z-index: 2; transition: filter .8s, --ring .8s, --glow .8s; }
/* The tilted screens have no border of their own: the ring is an outline
   laid over the clipped picture, and no glow spreads past the corner radius.
   Under the tilt Firefox otherwise draws seams along the edges, and the
   softened image clip lets a border behind it show thicker at the corners.
   Their glows are drop-shadow filters, not box-shadows: Firefox draws a
   blurred box-shadow in pieces, and tilted, the joins show as ticks on the
   edge. The route map below does the same. */
[data-look] :is(.shots-stage .shots-frame, .line-section .panel-shot) { --ring: var(--rule); position: relative; border: 0; }
[data-look] :is(.shots-stage .shots-frame, .line-section .panel-shot)::after {
  content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none;
  --ring: inherit; box-shadow: inset 0 0 0 1px var(--ring);
}
/* The slider's light on the glass: ::after holds the outline, so it goes on ::before. */
[data-look] .shots-stage .shots-frame.has-sheen::after { opacity: 1; background: none; }
[data-look] .shots-stage .shots-frame.has-sheen::before {
  content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; pointer-events: none;
  background: radial-gradient(640px circle at var(--mx, 50%) var(--my, 0%), rgba(255, 255, 255, var(--sheen, .07)), transparent 55%);
  opacity: 0; transition: opacity .3s;
}
[data-look] .shots-stage .shots-frame.has-sheen.is-tracking::before { opacity: 1; }
.shots-stage::before {
  content: ""; position: absolute; inset: 6% 10%; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow) 70%, transparent), transparent);
  filter: blur(60px); opacity: .55; transition: --glow .8s;
}
[data-look="glow"] .shots-stage .shots-frame {
  --ring: color-mix(in srgb, var(--glow) 55%, var(--rule));
  box-shadow: none;
  filter: drop-shadow(0 0 26px color-mix(in srgb, var(--glow) 45%, transparent))
          drop-shadow(0 24px 28px rgba(0, 0, 0, .45));
}
.shots-ghost {
  position: absolute; z-index: 1; top: 9%; width: 62%; pointer-events: none;
  border-radius: var(--radius-panel); overflow: hidden; background: #0B0F16;
  border: 1px solid color-mix(in srgb, var(--gc) 50%, var(--rule));
  transition: opacity .6s, --glow .8s;
}
.shots-ghost img { display: block; width: 100%; height: auto; }
.shots-ghost .shot-bar { color: #8D9FA8; background: #141C24; border-bottom-color: #22313A; }
.shots-ghost[data-side="-1"] { left: -15%; transform: rotateY(24deg) translateZ(-260px); transform-origin: left center; }
.shots-ghost[data-side="1"] { right: -15%; transform: rotateY(-24deg) translateZ(-260px); transform-origin: right center; }
[data-look="glow"] .shots-ghost { box-shadow: 0 0 60px -10px color-mix(in srgb, var(--gc) 55%, transparent); filter: brightness(.55) saturate(.9); }
@media (max-width: 1000px) { .shots-ghost { display: none; } }

/* Coming into view, the stage tips up from lying back and straightens. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .shots-stage { animation: stage-rise linear both; animation-timeline: view(); animation-range: entry 0% cover 45%; }
    @keyframes stage-rise {
      from { rotate: x 22deg; scale: .9; opacity: .2; }
      to   { rotate: x 0deg; scale: 1; opacity: 1; }
    }
    .line-section .panel-shot { animation: panel-turn linear both; animation-timeline: view(); animation-range: entry 0% cover 50%; }
    .line-section:nth-of-type(even) .panel-shot { animation-name: panel-turn-back; }
    .routemap .rm-frame { animation: stage-rise linear both; animation-timeline: view(); animation-range: entry 0% cover 45%; }
    @keyframes panel-turn      { from { rotate: y -26deg; scale: .92; opacity: 0; } to { rotate: y 0deg; scale: 1; opacity: 1; } }
    @keyframes panel-turn-back { from { rotate: y 26deg;  scale: .92; opacity: 0; } to { rotate: y 0deg; scale: 1; opacity: 1; } }
  }
}
.line-section > div:last-child { perspective: 1400px; }
[data-look="glow"] .line-section .panel-shot {
  --ring: color-mix(in srgb, var(--c) 45%, var(--rule));
  box-shadow: none;
  filter: drop-shadow(0 0 22px color-mix(in srgb, var(--c) 38%, transparent))
          drop-shadow(0 20px 24px rgba(0, 0, 0, .45));
}

/* The route map: tipped up like the screens stage and lit from both ends,
   operator side in the first line's colour, provider side in the second's. */
.routemap { perspective: 1800px; }
/* Border as a background layer, as on the glass cards, and glows as
   drop-shadow filters, as on the screens: Firefox otherwise shows seams at
   the tilted edges. */
:root[data-look] .rm-frame {
  --ring: var(--rule);
  border-color: transparent;
  background: linear-gradient(var(--surface), var(--surface)) padding-box, linear-gradient(var(--ring), var(--ring)) border-box;
}
:root[data-look="glow"] .rm-frame {
  --ring: color-mix(in srgb, var(--l-recon) 30%, var(--rule));
  box-shadow: none;
  filter: drop-shadow(-14px 0 24px color-mix(in srgb, var(--l-recon) 30%, transparent))
          drop-shadow(14px 0 24px color-mix(in srgb, var(--l-comp) 30%, transparent))
          drop-shadow(0 22px 26px rgba(0, 0, 0, .4));
}

/* ── Floating route tokens: glossy stops and interchanges in the line
   colours, drifting at three depths behind the screens ───────────────── */
/* The parallax carries tokens past the band's edges: the mask fades them out
   there instead of slicing them flat. */
.tokens {
  position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden;
  -webkit-mask: linear-gradient(transparent, #000 140px, #000 calc(100% - 140px), transparent);
  mask: linear-gradient(transparent, #000 140px, #000 calc(100% - 140px), transparent);
}
.token {
  position: absolute; left: var(--x); top: var(--y); width: var(--s); aspect-ratio: 1;
  translate: 0 calc(var(--p, 0) * var(--d) * -140px);
  animation: token-drift var(--t, 9s) ease-in-out infinite alternate;
  animation-delay: var(--dl, 0s);
}
.token i {
  position: absolute; inset: 0; border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, .85), rgba(255, 255, 255, 0) 22%),
    radial-gradient(circle at 60% 70%, color-mix(in srgb, var(--c) 55%, #000) 0, transparent 70%),
    linear-gradient(150deg, color-mix(in srgb, var(--c) 55%, #fff), var(--c) 45%, color-mix(in srgb, var(--c) 45%, #000));
  box-shadow: inset -6px -9px 16px rgba(0, 0, 0, .45), inset 5px 6px 10px rgba(255, 255, 255, .35);
  -webkit-mask: radial-gradient(circle, transparent 0 34%, #000 35.5%); mask: radial-gradient(circle, transparent 0 34%, #000 35.5%);
  transform: rotateX(var(--tx, 30deg)) rotateY(var(--ty, -20deg));
}
/* An interchange: a capsule with two stops. */
.token.is-pill { aspect-ratio: 2.3; }
.token.is-pill i { border-radius: 999px; -webkit-mask: none; mask: none; }
.token.is-pill b {
  position: absolute; inset: 0; transform: rotateX(var(--tx, 30deg)) rotateY(var(--ty, -20deg));
  background:
    radial-gradient(circle calc(var(--s) * .13) at 26% 50%, #0C1216 0 52%, rgba(255, 255, 255, .92) 56% 92%, transparent 96%),
    radial-gradient(circle calc(var(--s) * .13) at 74% 50%, #0C1216 0 52%, rgba(255, 255, 255, .92) 56% 92%, transparent 96%);
}
.token::after {
  content: ""; position: absolute; left: 10%; right: 10%; bottom: -26%; height: 18%; border-radius: 50%;
  background: rgba(0, 0, 0, .45); filter: blur(10px);
}
[data-look="glow"] .token i { filter: drop-shadow(0 0 18px color-mix(in srgb, var(--c) 50%, transparent)); }
.token.is-far { filter: blur(2.5px); opacity: .6; }
.token.is-mid { opacity: .9; }
@keyframes token-drift {
  from { transform: translate3d(0, -10px, 0) rotate(-6deg); }
  to   { transform: translate3d(6px, 12px, 0) rotate(8deg); }
}
@media (max-width: 760px) { .token.is-far, .token.is-mid { display: none; } .token { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .token { animation: none; translate: none; } }

/* ── Glass cards ────────────────────────────────────── */
/* What the back office replaces, the two sides and the tiers become cards
   with a number in the corner and a line colour on hover. */
[data-look] .replace-grid { border-top: 0; gap: 16px; counter-reset: card; }
/* The card's border is painted as a background layer (--ring) behind a
   transparent border. Firefox draws a real rounded border as separate corner
   and edge pieces, and under the tilt their joins show as short ticks. */
[data-look] :is(.replace-item, .side, .tier) {
  border-color: transparent;
  background: var(--card-bg) padding-box, linear-gradient(var(--ring), var(--ring)) border-box;
}
[data-look] .replace-item {
  counter-increment: card; position: relative; padding: 56px 24px 26px;
  border: 1px solid transparent; border-radius: var(--radius-panel);
  --ring: var(--rule);
  --card-bg: linear-gradient(160deg, color-mix(in srgb, var(--surface) 92%, var(--paper)), color-mix(in srgb, var(--surface) 40%, var(--paper)));
}
[data-look] .replace-item::before {
  content: counter(card, decimal-leading-zero); position: absolute; top: 20px; left: 24px;
  font: 600 .8rem/1 ui-monospace, "SF Mono", Menlo, monospace; color: var(--ink-3); letter-spacing: .04em;
}
[data-look] .replace-item:nth-child(6n+1) { --c: var(--l-recon); }
[data-look] .replace-item:nth-child(6n+2) { --c: var(--l-comp); }
[data-look] .replace-item:nth-child(6n+3) { --c: var(--l-support); }
[data-look] .replace-item:nth-child(6n+4) { --c: var(--l-contract); }
[data-look] .replace-item:nth-child(6n+5) { --c: var(--l-campaign); }
[data-look] .replace-item:nth-child(6n+6) { --c: var(--l-report); }
/* A short stretch of the card's line next to its number. */
[data-look] .replace-item h3::before {
  content: ""; position: absolute; top: 24px; left: 56px; width: 34px; height: 5px; border-radius: 3px;
  background: var(--c); opacity: .85;
}
[data-look="glow"] .replace-item:hover, [data-look="glow"] .side:hover, [data-look="glow"] .tier:hover {
  --ring: color-mix(in srgb, var(--c, var(--l-recon)) 55%, var(--rule));
  /* Keep a glow's negative spread smaller than the corner radius (14px): past
     it the shadow turns square, and Firefox draws its blurred corners with
     thin seams. */
  box-shadow: 0 0 46px -12px color-mix(in srgb, var(--c, var(--l-recon)) 52%, transparent);
}

[data-look] .sides { border: 0; background: none; gap: 16px; overflow: visible; }
[data-look] .side, [data-look] .side + .side {
  border: 1px solid transparent; border-radius: var(--radius-panel);
  --ring: var(--rule);
  --card-bg: linear-gradient(160deg, color-mix(in srgb, var(--surface) 95%, var(--paper)), color-mix(in srgb, var(--surface) 45%, var(--paper)));
}
[data-look] .side:first-child { --c: var(--l-recon); }
[data-look] .side:last-child { --c: var(--l-comp); }
[data-look] .tier { --c: var(--l-campaign); --ring: var(--rule-strong); --card-bg: linear-gradient(var(--surface), var(--surface)); }
[data-look] .tier-premium { --ring: var(--ink); }
[data-look] .tier-premium { --c: var(--l-recon); }
[data-look="glow"] .tier-premium { --ring: color-mix(in srgb, var(--l-recon) 60%, var(--rule)); box-shadow: 0 0 52px -12px color-mix(in srgb, var(--l-recon) 50%, transparent); }

/* The workflow code chip glows like a lit sign. */
[data-look="glow"] .line-name .code { box-shadow: 0 0 18px -2px color-mix(in srgb, var(--c) 70%, transparent); }
[data-look="glow"] .line-section .copy::before { box-shadow: 0 0 16px 0 color-mix(in srgb, var(--c) 60%, transparent); }

/* ── Preview switcher ───────────────────────────────── */

/* On dark pages the slider's address bar matches the dark screenshots. */
:root[data-look="glow"] .shots-frame.screen { --screen-top: #141C24; --rule: #22313A; --ink-2: #B4C3C9; --l-report: #EAF2F3; }
