/* ==========================================================
   MAIN STREET FITNESS — SERVICE ORBIT
   Static hub-and-spoke selector. NO continuous rotation, NO autoplay,
   no timed state change. Nodes never change position; only the ACTIVE
   selection moves between them (amendment B18).

   Pattern adapted from CodeFronts "Responsive Dashboard Radial Hub"
   (mission-hub, demo 06). CodeFronts demos are MIT licensed and free for
   commercial use. Trigonometric/vector positioning is mathematics and
   carries no restriction. No CodeFronts branding, colour (#7c3aed),
   copy or icon artwork is reused — icons here are a local SVG set.

   Index tokens, per-node unit vectors, active/focus selectors and panel
   reveal selectors are GENERATED into this file by the build from
   src/data/capabilities.json. Never inline style attributes: the deployed
   CSP is style-src 'self' (amendment B3).
   ========================================================== */

.msf-orb {
  position: relative;
  padding-block: clamp(1.25rem, 3.5vw, 2.5rem);

  /* ONE TOKEN DRIVES THE WHOLE CONSTELLATION (amendment B5's intent).
     Container-query units were the first choice, but on this page the
     cqi-sized stage produced a zero-size layout box in Chrome (measured:
     0 client rects, offsetParent null, checkVisibility() false) while the
     same declarations rendered correctly in isolation. An explicit length
     removes the whole class of resolution problem and stays deterministic. */
  /* PURE LENGTH — no percentage. A percentage inside a custom property
     resolves at the USE site, so `width: var(--x)` would resolve against the
     containing block's width while `height: var(--x)` resolved against its
     (auto) height, collapsing the stage to zero. vw has no such ambiguity. */
  --stage-size: min(34rem, calc(100vw - 3rem));
}

/* The query container is the STAGE WRAPPER, not the full-width section.
   Radius must be bounded by the stage's own box or the ring overflows it
   vertically and collides with the header and the panel below. */
.msf-orb__stagewrap {
  width: var(--stage-size);
  margin-inline: auto;
}

.msf-orb__group {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}

/* The fieldset's flow content is wrapped in a plain div. All radios live inside
   this wrapper too, so the generated "#cap-N:checked ~ ..." sibling selectors
   remain valid. (This wrapper was first added while chasing the zero-size stage;
   that turned out to be a container-query resolution failure, not a fieldset
   issue — see --stage-size above. The wrapper is kept because it makes the
   sibling-selector scope explicit.) */
.msf-orb__inner { display: block; }

/* ---------- ring stage ---------- */
.msf-orb__stage {
  position: relative;
  width: var(--stage-size);
  height: var(--stage-size);          /* square: the ring stays circular */
  /* r + node radius must stay inside half the stage:
     0.36 + ~0.095 = 0.455 < 0.5 */
  --r: calc(var(--stage-size) * 0.350);
}

/* ---------- central hub ---------- */
.msf-orb__hub {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  width: calc(var(--stage-size) * 0.320);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid rgba(226, 232, 238, .92);
  box-shadow:
    0 0 0 6px rgba(24, 26, 30, .95),
    0 0 0 7px rgba(196, 206, 216, .42),
    0 0 90px -16px rgba(200, 16, 46, .5),   /* the ONE glow in the composition */
    var(--elev-3);
  z-index: 3;
  display: grid;
}
.msf-orb__hub > * { grid-area: 1 / 1; }
.msf-orb__hub picture, .msf-orb__hub img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 58%;
}
.msf-orb__hubveil {
  background:
    radial-gradient(circle at 50% 28%, rgba(9, 9, 10, 0), rgba(9, 9, 10, .30) 66%),
    linear-gradient(180deg,
      rgba(9, 9, 10, 0) 30%, rgba(9, 9, 10, .70) 52%, rgba(9, 9, 10, .96) 74%);
}
.msf-orb__hubtext {
  align-self: end; justify-self: center; text-align: center;
  padding: var(--space-2) var(--space-4) var(--space-3);
  margin-bottom: var(--space-4);
  z-index: 2;
  /* C1: near-solid plate, not a dimmed photograph. One elevation, no glow. */
  background: rgba(9, 9, 10, .93);
  border-top: 1px solid rgba(196, 206, 216, .22);
  border-bottom: 1px solid rgba(196, 206, 216, .22);
  /* the plate must sit inside the circle's chord, not the bounding box,
     or the hub's overflow:hidden clips the text (measured at 2x) */
  width: 82%;
}
.msf-orb__hubname {
  display: block; font-family: var(--msf-font-display); font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; line-height: 1.05;
  font-size: var(--text-md);
  background: rgba(9, 9, 10, .94);   /* C1 plate, measured at worst pixel */
  padding: var(--space-1) var(--space-2);
  overflow-wrap: break-word;
}
.msf-orb__hubsub {
  display: block; margin-top: 0;
  font-size: var(--text-xs);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--msf-white);
  background: rgba(9, 9, 10, .94);   /* C1 plate */
  padding: var(--space-1) var(--space-2);
  white-space: normal;
  white-space: normal;
}

/* ---------- radios: visually hidden, still focusable and operable ---------- */
.msf-orb__radio {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; /* optical: standard clip-hide idiom */
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- nodes ---------- */
.msf-orb__node {
  position: absolute;
  top: 50%;
  left: 50%;
  /* --x/--y are UNIT VECTORS generated per node from capabilities.json
     (amendment B16 fallback). Number x length in calc() — no runtime
     trigonometry, so no engine can discard the declaration as invalid.
     -50% on each axis centres the node on its own midpoint. */
  translate:
    calc(var(--x) * var(--r) - 50%)
    calc(var(--y) * var(--r) - 50%);
  scale: var(--node-scale, 1);
  z-index: 2;

  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--space-1);
  width: calc(var(--stage-size) * 0.280);
  min-width: 44px; min-height: 44px;
  aspect-ratio: 1;
  padding: var(--space-2) var(--space-1);
  border-radius: 50%;

  background: var(--msf-surface-raised);
  border: 1px solid rgba(226, 232, 238, .38);
  color: var(--msf-white);
  text-align: center;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: scale var(--motion-base) var(--ease-out),
              border-color var(--motion-fast) var(--ease-out);
}

/* Faint spoke back to the hub. Decorative; --spoke-rot is generated. */
.msf-orb__node::before {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: var(--r); height: 3px;
  margin-top: -1.5px; /* optical: centres a 3px bar on the radius */
  transform-origin: 0 50%;
  rotate: var(--spoke-rot);
  border-radius: 2px;
  /* felt, not seen: one steel gradient, no red, no glow */
  background: linear-gradient(90deg,
    rgba(196,206,216,.34), rgba(196,206,216,.10) 68%, transparent);
  z-index: -1; pointer-events: none;
}

/* ---------- medallion artwork ---------- */
.msf-orb__art {
  position: absolute; inset: 0; border-radius: 50%;
  overflow: hidden; z-index: -2; display: block;
}
.msf-orb__art img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: brightness(1.02) saturate(1.0);
}
.msf-orb__scrim {
  position: absolute; inset: 0; border-radius: 50%; z-index: -1;
  background:
    radial-gradient(circle at 50% 26%, rgba(9,9,10,0), rgba(9,9,10,.22) 58%),
    /* text band: opaque enough to carry a 4.5:1 label over any photo beneath */
    linear-gradient(180deg,
      rgba(9,9,10,0) 34%, rgba(9,9,10,.72) 58%, rgba(9,9,10,.94) 78%);
}

/* status marker — shape carries the meaning, not colour alone */
.msf-orb__mark {
  position: absolute; top: 12%; right: 16%;
  width: .46rem; height: .46rem; border-radius: 50%;
  border: 2px solid currentColor;
}
.msf-orb__mark--now { color: #6FE39B; background: currentColor; }   /* solid */
.msf-orb__mark--approval { color: var(--msf-steel); }                /* hollow */
.msf-orb__mark--confirm { color: var(--msf-steel); border-style: dashed; }

.msf-orb__node { box-shadow: var(--elev-2); }
@media (hover: hover) {
  .msf-orb__node:hover { border-color: rgba(226,232,238,.72); }
}
.msf-orb__node:active { transform: scale(.985); }

.msf-orb__nodeicon { width: 22px; height: 22px; color: var(--msf-steel); flex: none; }
.msf-orb__nodelabel {
  font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .06em;
  line-height: 1.15; font-weight: 700;
  /* C1: the label carries its own plate so it never sits on bare photo */
  background: rgba(9, 9, 10, .90);
  padding: var(--space-1) var(--space-2);
  border-radius: 2px;
  max-width: 96%;
}

/* ACTIVE + FOCUS + PANEL REVEAL selectors are GENERATED (see end of file). */

/* ---------- information panels (pre-rendered, one per capability) ---------- */
.msf-orb__details { margin-top: clamp(1.1rem, 3vw, 1.8rem); }

.msf-orb__panel {
  display: none;                     /* generated :checked rule reveals one */
  background: var(--msf-surface);
  border: 1px solid var(--msf-border);
  border-radius: var(--msf-radius);
  padding: clamp(1.1rem, 3vw, 1.8rem);
  min-height: 15.5rem;               /* fixed floor: content swap shifts nothing */
  flex-direction: column;
  gap: var(--space-3);
}
/* generated rule sets display:flex on the selected panel */

.msf-orb__status {
  display: inline-flex; align-items: center; gap: var(--space-2); align-self: flex-start;
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .17em;
  font-weight: 700; padding: var(--space-1) var(--space-3); border-radius: 999px;
  border: 1px solid currentColor;
}
/* Status is carried by TEXT and by the marker SHAPE, never colour alone. */
.msf-orb__status::before {
  content: ""; width: .5rem; height: .5rem; border-radius: 50%;
  border: 2px solid currentColor; flex: none;
}
.msf-orb__status--now { color: #6FE39B; }
.msf-orb__status--now::before { background: currentColor; }       /* solid */
.msf-orb__status--approval { color: var(--msf-steel); }           /* hollow */
.msf-orb__status--confirm { color: var(--msf-steel); border-style: dashed; }
.msf-orb__status--confirm::before { border-style: dashed; }

.msf-orb__title {
  font-family: var(--msf-font-display); font-weight: 800; text-transform: uppercase;
  font-size: var(--text-lg); line-height: 1.1;
}
.msf-orb__desc { color: var(--msf-white); }
.msf-orb__benefit { color: var(--msf-muted); font-size: var(--text-sm); }
.msf-orb__act { margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ---------- controls ---------- */
.msf-orb__controls {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-2); margin-top: var(--space-4); flex-wrap: wrap;
}
.msf-orb__ctrl {
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--msf-white);
  border: 1px solid var(--msf-border); border-radius: var(--msf-radius);
  cursor: pointer;
}
.msf-orb__ctrl:hover { border-color: var(--msf-red); color: var(--msf-red); }
.msf-orb__ctrl:focus-visible { outline: 3px solid var(--msf-white); outline-offset: 3px; }
.msf-orb__ctrl svg { width: 18px; height: 18px; }
.msf-orb__hint {
  font-size: var(--text-xs); color: var(--msf-steel);
  letter-spacing: .09em; text-transform: uppercase;
}

/* ---------- preview dialog ---------- */
.msf-orb__preview {
  border: 1px solid var(--msf-border); background: var(--msf-surface);
  color: var(--msf-white); border-radius: var(--msf-radius);
  padding: clamp(1.2rem, 3vw, 2rem); max-width: 34rem; width: calc(100% - 2rem);
}
.msf-orb__preview::backdrop { background: rgba(9, 9, 10, .82); }
.msf-orb__preview h3 { margin-bottom: var(--space-2); }
.msf-orb__notice {
  margin-top: var(--space-4); padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--msf-red); color: var(--msf-white);
  font-weight: 700; font-size: var(--text-xs); border-radius: var(--msf-radius);
}
.msf-orb__illus { margin-top: var(--space-4); }

/* ---------- MOBILE: leave the ring, become a grid (amendment B6) ---------- */
@media (max-width: 560px) {
  .msf-orb__stage {
    width: 100%; height: auto;  /* square stage is for the ring only */
    display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  }
  .msf-orb__hub { position: static; translate: none; width: min(42vw, 10.5rem); }
  .msf-orb__nodes {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); width: 100%;
  }
  .msf-orb__nodelabel { padding: 0; background: none; }  /* grid tiles already sit on a solid surface */
  .msf-orb__node {
    position: static;
    translate: none;
    scale: 1 !important;             /* beats the generated id-specificity rule */
    width: 100%; aspect-ratio: auto; border-radius: var(--msf-radius);
    flex-direction: row; justify-content: flex-start; gap: var(--space-2);
    padding: var(--space-2) var(--space-3); min-height: 44px; text-align: left;
  }
  .msf-orb__node::before { display: none; }
  .msf-orb__nodelabel { font-size: var(--text-xs); }
}

/* On the ring, .msf-orb__nodes is a transparent positioning wrapper. */
.msf-orb__nodes { display: contents; }
@media (max-width: 560px) { .msf-orb__nodes { display: grid; } }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .msf-orb__node, .msf-orb__hub, .msf-orb__panel { transition: none !important; }
  .msf-orb__node { scale: 1 !important; }
}

/* ==========================================================
   GENERATED BLOCK — appended by build_msf.py. Do not hand-edit.
   ========================================================== */

/* GENERATED — visitor-task spinner, 5 destinations. */
.msf-orb__stage { --n: 5; }
.msf-orb__node--0 { --i: 0; --x: 0; --y: -1; --spoke-rot: 90.0deg; }
.msf-orb__node--1 { --i: 1; --x: 0.95105652; --y: -0.30901699; --spoke-rot: 162.0deg; }
.msf-orb__node--2 { --i: 2; --x: 0.58778525; --y: 0.80901699; --spoke-rot: 234.0deg; }
.msf-orb__node--3 { --i: 3; --x: -0.58778525; --y: 0.80901699; --spoke-rot: 306.0deg; }
.msf-orb__node--4 { --i: 4; --x: -0.95105652; --y: -0.30901699; --spoke-rot: 378.0deg; }
#dst-0:checked ~ .msf-orb__stagewrap .msf-orb__node--0,
#dst-1:checked ~ .msf-orb__stagewrap .msf-orb__node--1,
#dst-2:checked ~ .msf-orb__stagewrap .msf-orb__node--2,
#dst-3:checked ~ .msf-orb__stagewrap .msf-orb__node--3,
#dst-4:checked ~ .msf-orb__stagewrap .msf-orb__node--4 {
  border-color: var(--msf-red);
  --node-scale: 1.06;
  z-index: 4;
  box-shadow: 0 0 0 2px var(--msf-red), 0 0 46px -8px rgba(200,16,46,.8);
}
#dst-0:checked ~ .msf-orb__stagewrap .msf-orb__node--0 .msf-orb__art img,
#dst-1:checked ~ .msf-orb__stagewrap .msf-orb__node--1 .msf-orb__art img,
#dst-2:checked ~ .msf-orb__stagewrap .msf-orb__node--2 .msf-orb__art img,
#dst-3:checked ~ .msf-orb__stagewrap .msf-orb__node--3 .msf-orb__art img,
#dst-4:checked ~ .msf-orb__stagewrap .msf-orb__node--4 .msf-orb__art img { filter: brightness(1.06) saturate(1.05); }
#dst-0:focus-visible ~ .msf-orb__stagewrap .msf-orb__node--0,
#dst-1:focus-visible ~ .msf-orb__stagewrap .msf-orb__node--1,
#dst-2:focus-visible ~ .msf-orb__stagewrap .msf-orb__node--2,
#dst-3:focus-visible ~ .msf-orb__stagewrap .msf-orb__node--3,
#dst-4:focus-visible ~ .msf-orb__stagewrap .msf-orb__node--4 {
  outline: 3px solid var(--msf-white);
  outline-offset: 4px;
  box-shadow: 0 0 0 7px rgba(9,9,10,.95), 0 0 0 9px var(--msf-white);
}
.msf-cap-line, .msf-act, .msf-count { display: none; }
#dst-0:checked ~ .msf-cap-caption .msf-cap-line--0,
#dst-1:checked ~ .msf-cap-caption .msf-cap-line--1,
#dst-2:checked ~ .msf-cap-caption .msf-cap-line--2,
#dst-3:checked ~ .msf-cap-caption .msf-cap-line--3,
#dst-4:checked ~ .msf-cap-caption .msf-cap-line--4 { display: inline; }
#dst-0:checked ~ .msf-cap-actions .msf-act--0,
#dst-1:checked ~ .msf-cap-actions .msf-act--1,
#dst-2:checked ~ .msf-cap-actions .msf-act--2,
#dst-3:checked ~ .msf-cap-actions .msf-act--3,
#dst-4:checked ~ .msf-cap-actions .msf-act--4 { display: inline-flex; }
#dst-0:checked ~ .msf-home__controls .msf-count--0,
#dst-1:checked ~ .msf-home__controls .msf-count--1,
#dst-2:checked ~ .msf-home__controls .msf-count--2,
#dst-3:checked ~ .msf-home__controls .msf-count--3,
#dst-4:checked ~ .msf-home__controls .msf-count--4 { display: inline; }
