/* Radar hub: copied from experiences-page/gesda-graphics/radar-hub-v2.html.
   v4 changes: core colours (--hub-c1..5); three segmented rings instead of four,
   coloured and turning with the core; dotted orbits moved in to match. */
/* =========================================================================
   COMPONENT: .hub  (copy from here to "END COMPONENT")
   radial-radar in the centre, radial-graphic sectors around it, orbit-rings
   around both.
   v2: equal core sections (5 x 72deg); labels leave their rings to the left.

   §0  Surface: Class A (Experiences landing), decorative hero figure.
       Theme: light. Analytical claim: none, so §3.3 / §10.8 / §15 do not bind.
   Colours come from tokens.css only (mixed with transparent where needed).
   Geometry: 1000 x 1000 grid, centre (500,500); 1 unit = --u.

   Sync: the core and the sectors share one rotation (--rotor), so each
   sector always points along its colour section. The sweep inside the core
   runs on --scan; each sector's flash and band pulses repeat on that same
   period, delayed by (sector angle / 360), so light leaves a section the
   moment the sweep crosses it.
   ========================================================================= */

@property --hub-draw { syntax: '<angle>'; inherits: false; initial-value: 360deg; }

.hub {
  --speed: 1;                              /* 2 = half as fast */
  --scan: calc(7s * var(--speed));         /* radar sweep period */
  --rotor: calc(120s * var(--speed));      /* core + sectors rotation */
  --u: calc(100cqw / 1000);
  --type-diagram-label: 0.8125rem;         /* §4.2, not in tokens.css */

  /* core sections, clockwise from 12 o'clock (5 x 72deg) */
  /* v4: the Radar's five platform colours, in the Radar's clockwise order */
  --hub-c1: var(--radar-ahp);
  --hub-c2: var(--radar-ebs);
  --hub-c3: var(--radar-cpf);
  --hub-c4: var(--radar-esw);
  --hub-c5: var(--radar-dmr);

  --hub-orbit: color-mix(in srgb, var(--graphic-violet) 45%, var(--purple-300));
  --hub-pill: color-mix(in srgb, var(--purple-100) 50%, var(--purple-050));

  container: hub / inline-size;
  position: relative;
  isolation: isolate;
  width: 100%;
}
.hub__stage { position: relative; aspect-ratio: 1; overflow: hidden; }

/* ---------- orbit rings (outer) ---------- */
.hub__orbits { position: absolute; inset: 0; z-index: 2; pointer-events: none; }

.hub__halo {
  position: absolute; inset: 0;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--hub-orbit) 10%, transparent) 0,
    color-mix(in srgb, var(--hub-orbit) 5%, transparent) 45%, transparent 70%);
}

.hub__orbit {
  --hub-draw: 360deg;
  --band: calc(var(--t) * var(--u));
  position: absolute;
  width: calc(var(--r) * 2 * var(--u));
  aspect-ratio: 1;
  left: calc((500 - var(--r)) * var(--u));
  top:  calc((500 - var(--r)) * var(--u));
  border-radius: var(--radius-full);
  background: linear-gradient(270deg,
      color-mix(in srgb, var(--hub-orbit) calc(var(--a) * 100%), transparent) 0%,
      color-mix(in srgb, var(--purple-300) calc(var(--a) * 55%), transparent) 40%,
      color-mix(in srgb, var(--purple-100) 30%, transparent) 58%,
      transparent 80%);
  /* layer 1 cuts the circle into a band, layer 2 is the draw-on sweep */
  -webkit-mask:
      radial-gradient(closest-side, transparent calc(100% - var(--band)), #000 calc(100% - var(--band) + 1px)),
      conic-gradient(transparent calc(360deg - var(--hub-draw)), #000 0);
  -webkit-mask-composite: source-in;
          mask:
      radial-gradient(closest-side, transparent calc(100% - var(--band)), #000 calc(100% - var(--band) + 1px)),
      conic-gradient(transparent calc(360deg - var(--hub-draw)), #000 0);
          mask-composite: intersect;
  transition: opacity var(--motion-slow), filter var(--motion-slow);
}

/* light streak travelling along each band (clipped by the ring mask) */
.hub__comet {
  position: absolute; inset: 0;
  border-radius: var(--radius-full);
  background: conic-gradient(transparent 0deg,
    color-mix(in srgb, var(--color-white) 80%, transparent) 6deg,
    color-mix(in srgb, var(--color-white) 0%, transparent) 60deg, transparent);
  opacity: 0;
}

/* ---------- labels on the orbit rings ---------- */
.hub__pills { list-style: none; margin: 0; padding: 0; }

.hub__pill {
  position: absolute;
  z-index: 1;
  height: calc(var(--h) * var(--u));
  top:   calc((500 - var(--r) + var(--t) / 2 - var(--h) / 2) * var(--u));
  left:  calc(var(--start) * var(--u));
  right: calc(490 * var(--u));
  display: flex; align-items: center; justify-content: flex-start;
  padding-left: calc(20 * var(--u));
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  background: linear-gradient(270deg,
    color-mix(in srgb, var(--hub-pill) 0%, transparent) 0%,
    color-mix(in srgb, var(--hub-pill) 85%, transparent) 55%, var(--hub-pill) 100%);
  color: var(--color-action-primary);
  font: 600 max(var(--type-diagram-label), calc(var(--fs) * var(--u))) / 1 var(--font-body);
  letter-spacing: .01em;
  text-decoration: none;
  cursor: default;
  transition: transform var(--motion-medium);
}
.hub__pill:hover,
.hub__pill:focus-visible { transform: translateX(calc(-8 * var(--u))); }
.hub__pill:focus-visible { outline: 3px solid var(--color-focus-ring); outline-offset: 2px; }

/* hovering or focusing a label spotlights its ring */
.hub:has(.hub__pill:is(:hover, :focus-visible)) .hub__orbit { opacity: .3; }
.hub:has(li:nth-child(1) > .hub__pill:is(:hover, :focus-visible)) .hub__orbit:nth-of-type(1),
.hub:has(li:nth-child(2) > .hub__pill:is(:hover, :focus-visible)) .hub__orbit:nth-of-type(2),
.hub:has(li:nth-child(3) > .hub__pill:is(:hover, :focus-visible)) .hub__orbit:nth-of-type(3),
.hub:has(li:nth-child(4) > .hub__pill:is(:hover, :focus-visible)) .hub__orbit:nth-of-type(4) {
  opacity: 1; filter: saturate(1.3) brightness(1.05);
}

/* ---------- radial sectors (SVG) ---------- */
.hub__svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 3;
  overflow: visible;
  pointer-events: none;
}
.hub__guide { fill: none; stroke: var(--color-hairline-soft); stroke-width: 1; }
.hub__guide--dashed { stroke: var(--color-hairline); stroke-dasharray: 2 6; }
.hub__guides { animation: hub-spin calc(90s * var(--speed)) linear infinite; }
.hub__guide--dashed { animation: hub-spin calc(40s * var(--speed)) linear infinite reverse; }

.hub__rotor { animation: hub-spin var(--rotor) linear infinite; }

/* entrance: sectors unfold one by one; interaction: a sector slides out along its axis */
.hub__sector {
  animation: hub-unfold .9s cubic-bezier(.2, .8, .2, 1) calc(.4s + var(--s) * 120ms) backwards;
  transition: transform var(--motion-slow);
}
.hub__sector:hover { transform: translateY(-16px); }
.hub__band { pointer-events: auto; }
.hub__beam,
.hub__flash { pointer-events: none; }

.hub__beam { animation: hub-breathe calc(6s * var(--speed)) ease-in-out calc(var(--s) * -1.2s) infinite; }

/* the pulse fired when the sweep crosses the sector, and the bands it lights on the way out */
.hub__flash {
  opacity: 0;
  animation: hub-flash var(--scan) linear calc(var(--scan) * var(--a) / 360) infinite;
}
.hub__band {
  animation: hub-pulse var(--scan) ease-out calc(var(--scan) * (var(--a) / 360 + .1 + var(--i) * .02)) infinite;
}

/* ---------- radar (centre) ---------- */
.hub__radar {
  --sway: 9deg;
  /* v4: the core's five sections, with a 2deg gap after each */
  --stops:
    var(--hub-c1)   0deg  70deg, transparent  70deg  72deg,
    var(--hub-c2)  72deg 142deg, transparent 142deg 144deg,
    var(--hub-c3) 144deg 214deg, transparent 214deg 216deg,
    var(--hub-c4) 216deg 286deg, transparent 286deg 288deg,
    var(--hub-c5) 288deg 358deg, transparent 358deg 360deg;

  position: absolute;
  z-index: 4;
  width: 44%;
  left: 28%; top: 28%;
  aspect-ratio: 1;
  isolation: isolate;
  pointer-events: none;
}
.hub__radar > * { position: absolute; border-radius: var(--radius-full); }

/* segmented rings */
.hub__radar-ring {
  inset: var(--inset);
  opacity: var(--o);
  background:
    radial-gradient(farthest-side,
      color-mix(in srgb, var(--color-white) 70%, transparent) calc(100% - var(--w)),
      color-mix(in srgb, var(--color-white) 0%, transparent) 100%),
    conic-gradient(var(--stops));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--w) - .5%), #000 calc(100% - var(--w)), #000 99%, transparent 100%);
          mask: radial-gradient(farthest-side, transparent calc(100% - var(--w) - .5%), #000 calc(100% - var(--w)), #000 99%, transparent 100%);
  animation:
    hub-bloom 1.6s cubic-bezier(.2, .75, .2, 1) var(--delay) backwards,
    hub-sway calc(var(--dur) * var(--speed)) ease-in-out var(--delay) infinite alternate,
    hub-spin var(--rotor) linear infinite;   /* v4: turns with the core, so its sections stay on the core's (the sway rides on top) */
}
/* v4: three rings. The innermost is dropped and the other three move one slot
   in (taking that slot's inset, width and entrance delay), so the outermost
   slot at 5% is left empty. The 4th stays in the markup, hidden, because
   removing it would shift the nth-of-type numbering of the orbits below. */
.hub__radar-ring:nth-of-type(1) { --inset: 13%; --w: 20%; --o: .85; --dur: 14s; --delay: .3s; }
.hub__radar-ring:nth-of-type(2) { --inset: 21%; --w: 24%; --o: .6;  --dur: 11s; --delay: .15s; animation-direction: normal, alternate-reverse; }
.hub__radar-ring:nth-of-type(3) { --inset: 28%; --w: 26%; --o: .5;  --dur: 17s; --delay: 0s; }
.hub__radar-ring:nth-of-type(4) { display: none; }

/* faint trail of the sweep across the rings, locked to the core's sweep */
.hub__sweep { inset: 13%; animation: hub-spin var(--rotor) linear infinite; }
.hub__sweep::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: var(--radius-full);
  background: conic-gradient(from 290deg, transparent 0deg,
    color-mix(in srgb, var(--purple-300) 30%, transparent) 70deg, transparent 70deg);
  animation: hub-spin var(--scan) linear infinite;
}

/* thin orbit lines with travelling dots */
.hub__radar-orbit {
  inset: var(--inset);
  border: 1px solid color-mix(in srgb, var(--purple-300) 35%, transparent);
  animation: hub-spin calc(var(--dur) * var(--speed)) linear infinite;
}
.hub__radar-orbit::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  width: 11px; height: 11px;
  translate: -50% -50%;
  border-radius: var(--radius-full);
  background: radial-gradient(circle at 35% 35%, var(--color-white), var(--purple-100) 55%, var(--purple-300));
  box-shadow: 0 0 10px 2px color-mix(in srgb, var(--purple-300) 45%, transparent);
}
/* v4: all three dotted orbits ride inside the ring band (13% to 34%), so no
   dot runs outside it: one just inside its outer edge, one in each seam
   between rings (ring 1 ends at 20.4%, ring 2 at 28%). */
.hub__radar-orbit:nth-of-type(6) { --inset: 14%;   --dur: 48s; }
.hub__radar-orbit:nth-of-type(7) { --inset: 20.5%; --dur: 34s; animation-direction: reverse; }
.hub__radar-orbit:nth-of-type(8) { --inset: 28%;   --dur: 26s; }
.hub__radar-orbit:nth-of-type(7)::before { top: 50%; left: 0; }

/* five-section core: turns with the sectors, sweep turns inside it */
.hub__core {
  inset: 34%;
  background: conic-gradient(
    var(--hub-c1)   0deg  72deg,
    var(--hub-c2)  72deg 144deg,
    var(--hub-c3) 144deg 216deg,
    var(--hub-c4) 216deg 288deg,
    var(--hub-c5) 288deg 360deg);
  box-shadow:
    0 0 0 7px color-mix(in srgb, var(--color-white) 55%, transparent),
    0 0 0 8px color-mix(in srgb, var(--purple-300) 30%, transparent),
    0 0 50px color-mix(in srgb, var(--graphic-violet) 22%, transparent);
  overflow: hidden;
  animation:
    hub-bloom 1.2s cubic-bezier(.2, .75, .2, 1) backwards,
    hub-spin var(--rotor) linear infinite;
}
/* leading edge bright, trail behind it */
.hub__core::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: var(--radius-full);
  background: conic-gradient(from 290deg, transparent 0deg,
    color-mix(in srgb, var(--color-white) 60%, transparent) 70deg, transparent 70deg);
  animation: hub-spin var(--scan) linear infinite;
}

/* ---------- orbit entrance (only when JS arms it, so no-JS shows the static graphic) ---------- */
.hub.is-armed .hub__orbit { --hub-draw: 0deg; }
.hub.is-armed .hub__pill { clip-path: inset(0 0 0 100%); }
.hub.is-visible .hub__orbit {
  animation: hub-draw 1.6s cubic-bezier(.65, 0, .35, 1) calc(.3s + var(--i) * .15s) both;
}
.hub.is-visible .hub__pill {
  animation: hub-pill .9s cubic-bezier(.22, 1, .36, 1) calc(1.9s + var(--i) * .15s) both;
}
.hub.is-visible .hub__comet {
  animation: hub-comet calc((7s + var(--i) * 1.3s) * var(--speed)) ease-in-out calc(2.1s + var(--i) * .8s) infinite;
}

@keyframes hub-spin    { to { transform: rotate(360deg); } }
@keyframes hub-sway    { from { rotate: calc(var(--sway) * -1); } to { rotate: var(--sway); } }
@keyframes hub-bloom   { from { scale: .55; opacity: 0; } }
@keyframes hub-draw    { from { --hub-draw: 0deg; } to { --hub-draw: 360deg; } }
@keyframes hub-pill    { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes hub-unfold  { from { transform: scale(.2) rotate(-25deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes hub-breathe { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.06); opacity: .75; } }
@keyframes hub-flash {
  0%   { transform: scale(.15); opacity: 0; }
  3%   { opacity: 1; }
  20%  { opacity: .9; }
  28%  { transform: scale(1); opacity: 0; }
  100% { transform: scale(1); opacity: 0; }
}
@keyframes hub-pulse {
  0%, 16%, 100% { filter: brightness(1); }
  4%            { filter: brightness(1.18); }
}
@keyframes hub-comet {
  0%   { transform: rotate(15deg);   opacity: 0; }
  10%  { opacity: .9; }
  55%  { opacity: .9; }
  70%  { transform: rotate(-200deg); opacity: 0; }
  100% { transform: rotate(-200deg); opacity: 0; }
}

/* narrow containers: labels would drop below 13px on the rings, so they
   leave the figure and sit underneath it as a row (§13.1 recompose) */
@container hub (max-width: 560px) {
  .hub__pills {
    display: flex; flex-wrap: wrap; justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-4);
  }
  .hub__pill {
    position: static;
    height: auto;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--hub-pill);
    font-size: var(--type-label);
  }
  .hub__pill:hover,
  .hub__pill:focus-visible { transform: none; }
}

/* §8.3: everything renders in its final state */
@media (prefers-reduced-motion: reduce) {
  .hub *, .hub *::before, .hub *::after { animation: none !important; transition: none !important; }
  .hub__comet, .hub__flash { display: none; }
}
/* ======================= END COMPONENT ======================= */
