/* ============================================================
   Forensic Intelligence — product showcase bands
   Two scroll-scrubbed narrative strips that sit between .scene-main
   and .scene-footer:
     .scene-band--pipe   Belego "Ledger Line"
     .scene-band--atlas  CompanyInfo "Live Register Atlas"

   One inherited scalar --p in [0,1] drives everything, so the CSS
   view() timeline and the rAF fallback in motion.js produce identical
   output. --p defaults to 1: the UNANIMATED state is the FINISHED
   state, so no-JS / reduced-motion / mobile / print all read correctly.
   ============================================================ */

@property --p {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@keyframes band-scrub {
  from { --p: 0; }
  to   { --p: 1; }
}

/* ---------- Band shell ---------- */

.scene-band {
  /* z-index:1 keeps the band above .scene-num (z-index:0) — matches
     .scene-header / .scene-main / .scene-footer. */
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.25rem);
  margin-top: clamp(2rem, 4vh, 3.5rem);
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1.25rem, 3vw, 2.5rem);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: linear-gradient(135deg, var(--surface-1), var(--surface-2));
}

/* Isolate style/paint invalidation: --p changes every frame while scrubbing.
   Safe here — .scene-band has no sticky descendants. */
html.js .scene-band { contain: layout paint style; }

.band-head {
  display: grid;
  gap: var(--space-2);
}

.band-title {
  margin: 0;
  max-width: 40ch;
  font-size: clamp(1.05rem, 0.8vw + 0.85rem, 1.375rem);
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  text-wrap: balance;
}

/* ---------- Shared stat row ---------- */

.band-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
  padding-top: clamp(1.1rem, 2.5vw, 1.6rem);
}

.band-stats--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.band-stat {
  display: grid;
  gap: var(--space-1);
  align-content: start;
}

.band-stat .stat-num {
  font-size: clamp(1.6rem, 2.2vw + 0.9rem, 2.6rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.band-stat .stat-label {
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* ============================================================
   BELEGO — "The Ledger Line"
   ============================================================ */

.pipe {
  container-type: inline-size;
  position: relative;
  padding-block: 3.6rem 0.5rem;
}

/* Rail the token travels along */
.pipe-rail {
  position: absolute;
  top: 2.35rem;
  left: 0;
  right: 0;
  height: 2px;
  border-radius: var(--radius-full);
  background: var(--border-strong);
  overflow: hidden;
}

.pipe-rail-fill {
  display: block;
  height: 100%;
  transform-origin: left center;
  transform: scaleX(var(--p));
  background: var(--gradient-brand);
}

/* The travelling receipt */
.pipe-token {
  --tok: 3.4rem;
  position: absolute;
  top: 0;
  left: 0;
  width: var(--tok);
  height: 3.4rem;
  display: grid;
  place-items: center;
}

@supports (width: 1cqi) {
  .pipe-token {
    transform:
      translate3d(calc(var(--p) * (100cqi - var(--tok))), 0, 0)
      rotate(calc((1 - var(--p)) * -5deg));
  }
}

/* No container-query units: dock the token at the finished position. */
@supports not (width: 1cqi) {
  .pipe-token { left: auto; right: 0; }
}

.token-face {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: var(--bg-raised);
  box-shadow: var(--shadow-card);
}

.token-face svg {
  width: 1.6rem;
  height: 1.6rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Three cross-fading faces: photo → extracted fields → finished PDF */
.token-face--photo  { opacity: clamp(0, calc((0.34 - var(--p)) * 10), 1); }
.token-face--fields { opacity: clamp(0, min(calc((var(--p) - 0.26) * 10), calc((0.80 - var(--p)) * 10)), 1); }
.token-face--pdf    { opacity: clamp(0, calc((var(--p) - 0.74) * 10), 1); }

/* Extracted field bars "type in" one after another */
.token-face--fields .bar {
  transform-origin: left center;
  transform: scaleX(clamp(0, calc((var(--p) - 0.30 - var(--l) * 0.035) * 14), 1));
}

/* Padlock clips on BEFORE the AI stage and never leaves — the whole
   zero-knowledge argument, in one element. */
.token-lock {
  position: absolute;
  top: -0.45rem;
  right: -0.45rem;
  width: 1.35rem;
  height: 1.35rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background: var(--accent);
  opacity: clamp(0, calc((var(--p) - 0.08) * 14), 1);
}

.token-lock svg {
  width: 0.8rem;
  height: 0.8rem;
  fill: none;
  stroke: var(--accent-contrast);
  stroke-width: 2;
}

/* Approval stamp slams down at station 4 */
.token-seal {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: clamp(0, min(calc((var(--p) - 0.70) * 12), calc((1.06 - var(--p)) * 12)), 1);
  transform:
    rotate(-9deg)
    scale(clamp(1, calc(2.4 - (var(--p) - 0.70) * 8), 2.4));
}

.token-seal svg {
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Stations */
.pipe-stages {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pipe-stage {
  --lit: clamp(0, calc((var(--p) - var(--at)) * 7), 1);
  display: grid;
  justify-items: start;
  gap: 0.3rem;
}

.stage-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin-top: -3.05rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-strong);
  background: var(--bg-raised);
}

.stage-dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 1px solid var(--accent);
  opacity: var(--lit);
  transform: scale(calc(0.72 + 0.28 * var(--lit)));
}

.stage-dot svg {
  width: 0.9rem;
  height: 0.9rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.stage-name {
  position: relative;
  font-size: var(--text-sm);
  font-weight: 620;
  color: var(--text);
}

.stage-name::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1.5px;
  border-radius: var(--radius-full);
  background: var(--gradient-brand);
  transform-origin: left center;
  transform: scaleX(var(--lit));
}

.stage-sub {
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--text-muted);
  /* Decorative reinforcement — the same facts appear in the feature cards,
     so the low-opacity floor never hides essential text. */
  opacity: calc(0.45 + 0.55 * var(--lit));
}

/* Card Cockpit feeder lane */
.pipe-feed {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
}

.feed-label {
  font-weight: 640;
  color: var(--text);
}

.feed-line {
  position: relative;
  flex: 1 1 3rem;
  min-width: 3rem;
  height: 1px;
  background: repeating-linear-gradient(
    to right,
    var(--border-strong) 0 6px,
    transparent 6px 12px
  );
}

.feed-pip {
  position: absolute;
  top: 50%;
  left: 0;
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  border-radius: var(--radius-full);
  background: var(--accent);
  opacity: 0;
}

.scene-band.is-live .feed-pip {
  animation: feed-travel 4s linear infinite;
}

@keyframes feed-travel {
  0%   { left: 0;    opacity: 0; }
  12%  {             opacity: 1; }
  88%  {             opacity: 1; }
  100% { left: 100%; opacity: 0; }
}

.pipe-feed .chip {
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface-1);
  color: var(--text-muted);
  white-space: nowrap;
}

.pipe-feed .chip--accent {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-soft);
  color: var(--accent);
}

/* ============================================================
   COMPANYINFO — "Live Register Atlas"
   ============================================================ */

.atlas {
  container-type: inline-size;
  position: relative;
  display: grid;
  gap: clamp(0.9rem, 2vw, 1.4rem);
}

.atlas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(2.75rem, 1fr));
  gap: 0.35rem;
}

.atlas-cell {
  position: relative;
  display: grid;
  place-items: center;
  padding-block: 0.4rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  font-size: 0.6875rem;
  font-weight: 620;
  letter-spacing: 0.04em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: border-color var(--dur-1) ease, background-color var(--dur-1) ease,
    color var(--dur-1) ease;
}

a.atlas-cell:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
}

/* Country-name tooltip. The name is written to data-name by motion.js via
   Intl.DisplayNames, so it is localized without shipping a name table. */
.atlas-cell[data-name]::after {
  content: attr(data-name);
  position: absolute;
  bottom: calc(100% + 0.4rem);
  left: 50%;
  z-index: 5;
  translate: -50% 0;
  padding: 0.3rem 0.55rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--bg-raised);
  box-shadow: var(--shadow-card);
  color: var(--text);
  font-size: var(--text-xs);
  font-weight: 560;
  letter-spacing: 0;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-1) ease;
}

.atlas-cell[data-name]:hover::after,
.atlas-cell[data-name]:focus-visible::after { opacity: 1; }

/* Focusable link to the live status page, sitting with the legend */
.atlas-status a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.atlas-status a:hover { border-bottom-color: currentColor; }

.atlas-status svg {
  width: 0.7rem;
  height: 0.7rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
}

/* GLEIF tier reads as the lighter-weight source */
.atlas-cell--gleif {
  border-style: dashed;
  border-color: var(--border);
  background: transparent;
  color: var(--text-faint);
}

/* State-register tier carries the accent ring */
.atlas-cell--state {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Overflow counter: only meaningful where the grid is truncated (< 48rem). */
.atlas-cell--more {
  display: none;
  border-style: dashed;
  color: var(--text-muted);
}

/* One-shot ripple on reveal — 128 cells, so this is a transition, never
   a per-frame scrub. --i is assigned once by motion.js. */
html.js .scene-band--atlas .atlas-cell {
  opacity: 0;
  transform: scale(0.86);
}

html.js .scene-band--atlas.in-view .atlas-cell {
  opacity: 1;
  transform: none;
  transition:
    opacity 420ms var(--ease-out-expo),
    transform 420ms var(--ease-out-back);
  transition-delay: calc(var(--i, 0) * 4.5ms);
}

.scene-band.is-live .atlas-cell--live {
  animation: atlas-ping 3.2s var(--ease-out-expo) infinite;
}

.atlas-cell--live:nth-of-type(3n) { animation-delay: 0.9s; }
.atlas-cell--live:nth-of-type(3n + 1) { animation-delay: 1.8s; }

@keyframes atlas-ping {
  0%, 70%, 100% { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }
  35%           { box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 3px var(--accent-soft); }
}

/* The live-fetch scan line */
.atlas-scan {
  position: absolute;
  top: 0;
  left: 0;
  width: 3rem;
  height: 100%;
  pointer-events: none;
  border-radius: var(--radius-full);
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--grad-blue) 55%, transparent),
    color-mix(in srgb, var(--grad-teal) 55%, transparent),
    transparent
  );
  filter: blur(10px);
  opacity: clamp(0, min(calc(var(--p) * 8), calc((1 - var(--p)) * 8)), 0.55);
  transform: translate3d(calc(var(--p) * (100cqi + 6rem) - 3rem), 0, 0);
}

.atlas-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.atlas-legend li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.atlas-legend .key {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 3px;
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
}

.atlas-legend .key--gleif {
  border-style: dashed;
  border-color: var(--border);
  background: transparent;
}

.atlas-legend .key--state {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}

.atlas-legend .key--live {
  border-color: var(--accent);
  background: var(--accent);
  opacity: calc(0.4 + 0.6 * var(--p));
}

/* "No database" proof: the server glyph dissolves into a hard 0 */
.atlas-proof {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(1rem, 3vw, 2.25rem);
}

.zero-vault {
  position: relative;
  display: grid;
  place-items: center;
  width: 5.5rem;
  height: 5.5rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-1);
}

/* Ring that closes around the zero as the server dissolves. Deliberately not a
   strike-through: a line across the "0" reads as cancelling it, which is the
   opposite of the claim. */
.zero-vault::after {
  content: "";
  position: absolute;
  inset: 0.55rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--accent);
  opacity: clamp(0, calc((var(--p) - 0.45) * 5), 0.55);
  transform: scale(clamp(0.9, calc(0.9 + (var(--p) - 0.45) * 0.2), 1));
}

.vault-server {
  position: absolute;
  display: grid;
  place-items: center;
  opacity: clamp(0, calc((0.55 - var(--p)) * 5), 1);
  transform: scale(calc(1 - 0.12 * var(--p)));
}

.vault-server svg {
  width: 2.1rem;
  height: 2.1rem;
  fill: none;
  stroke: var(--text-faint);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.vault-zero {
  position: absolute;
  font-size: 3rem;
  font-weight: 750;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: clamp(0, calc((var(--p) - 0.45) * 5), 1);
  transform: scale(clamp(0.86, calc(0.86 + (var(--p) - 0.45) * 0.4), 1));
}

.atlas-proof .band-stats {
  border-top: 0;
  padding-top: 0;
}

/* Add-on authorities ticker */
.atlas-sources {
  display: grid;
  gap: var(--space-2);
  border-top: 1px solid var(--border);
  padding-top: clamp(1rem, 2vw, 1.4rem);
}

.atlas-sources .sources-label {
  font-size: var(--text-xs);
  font-weight: 640;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.sources-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sources-list li {
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

/* ============================================================
   Theme nuance
   ============================================================ */

[data-theme="dark"] .atlas-scan {
  opacity: clamp(0, min(calc(var(--p) * 8), calc((1 - var(--p)) * 8)), 0.85);
}

[data-theme="dark"] .token-face {
  background: var(--surface-2);
}

/* ============================================================
   Scroll scrub — desktop only.
   Deliberately NOT gated on (pointer: fine): touch laptops and iPads
   should scrub too. The JS gate in motion.js matches this exactly.
   ============================================================ */

@media (min-width: 64rem) {
  @supports (animation-timeline: view()) {
    html.js .scene-band[data-band] {
      animation: band-scrub both linear;
      animation-timeline: view();
      animation-range: entry 25% cover 40%;
    }
  }
}

/* ============================================================
   Responsive
   ============================================================ */

@media (max-width: 63.99rem) {
  /* --p stays 1 below this width (no scrub is registered), so every band
     renders in its finished state. */
  .atlas-scan { display: none; }
  .band-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .band-stats--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 47.99rem) {
  /* Pipeline goes vertical: rail becomes a left spine, token is pure
     decoration and is dropped. */
  .pipe { padding-block: 0; }
  .pipe-token { display: none; }

  .pipe-rail {
    top: 1rem;
    bottom: 1rem;
    left: 1rem;
    right: auto;
    width: 2px;
    height: auto;
  }

  .pipe-rail-fill {
    width: 100%;
    transform-origin: top center;
    transform: scaleY(var(--p));
  }

  .pipe-stages {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }

  .pipe-stage {
    grid-template-columns: 2rem minmax(0, 1fr);
    grid-template-areas:
      "dot name"
      "dot sub";
    align-items: center;
    column-gap: var(--space-3);
    row-gap: 0;
  }

  .stage-dot { grid-area: dot; margin-top: 0; }
  .stage-name { grid-area: name; }
  .stage-sub { grid-area: sub; }

  .atlas-proof {
    grid-template-columns: 1fr;
    justify-items: start;
  }

  .band-stats,
  .band-stats--4 { grid-template-columns: 1fr; }

  /* 128 cells would be ~22 rows tall on a phone. The grid is aria-hidden
     decoration; the claim itself lives in the stat tile and the tagline. */
  .atlas-cell:nth-child(n + 61) { display: none; }
  .atlas-cell--more { display: grid !important; }
}
