/* orb.css — Vitals Orb, Training Pulse gauge and skeleton. Companion to /js/orb.js; load only on pages that
   carry an orb or gauge, after styles.css.
   Tokens read from styles.css (C1/C2), each with a fallback so the sheet also renders standalone:
     --on-surface --on-surface-muted --surface-container-high --hairline-strong
     --readiness-high --readiness-moderate --readiness-low          (set on --orb-color by orb.js)
     --acwr-under --acwr-sweet --acwr-caution --acwr-high            (set on --gauge-zone by orb.js)
     --fs-body-lg --fs-body-sm --fs-label-sm --fs-headline-lg --radius-xs --space-sm --space-md --ease-emphasized
   Custom properties owned by orb.js: --orb-color, --orb-size, --gauge-zone, --gauge-size, --reveal (0→1). */

/* ---------- Vitals Orb ---------- */
.orb {
  --orb-color: var(--on-surface, #E8ECF2);
  position: relative;
  width: var(--orb-size, 320px);
  max-width: 100%;
  aspect-ratio: 1;
  container-type: inline-size;
  color: var(--on-surface, #E8ECF2);
}

.orb > svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Accessible / no-JS content. orb.js keeps these nodes and drives the count-up and phrase fade on them. */
.orb__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25cqi;
  border-radius: 50%;
  text-align: center;
  pointer-events: none;
}

/* No-JS ring: 1px hairline at the data-ring radius (r 83.2 of 160 → inset 24%) with the core glow inside it.
   This is the one place the design system allows a radial-gradient. */
.orb__fallback::before {
  content: "";
  position: absolute;
  inset: 24%;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong, rgba(232, 236, 242, .16));
  background: radial-gradient(circle,
    color-mix(in srgb, var(--orb-color) 22%, transparent) 0%,
    color-mix(in srgb, var(--orb-color) 7%, transparent) 50%,
    transparent 100%);
}

.orb--js .orb__fallback::before { display: none; }

.orb__score,
.orb__phrase {
  position: relative;
  margin: 0;
}

.orb__score {
  font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 20cqi;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--orb-color);
}

.orb__phrase {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: clamp(11px, 6cqi, var(--fs-body-lg, 16px));
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .15px;
  color: var(--on-surface-muted, #9BA4AE);
  /* Keep long phrases (the skeleton's "Collecting your first 7 days", data-label overrides) inside the ring's inner
     diameter (~48cqi) by wrapping; band labels are short and stay on one line. */
  max-width: 48cqi;
  text-wrap: balance;
}

/* Below 160px the ring cannot hold a phrase next to the number (11px text over a ~56px inner diameter); the band
   label stays in the element's aria-label. */
@container (max-width: 159px) {
  .orb__phrase { display: none; }
}

/* ---------- Skeleton (data-state="skeleton") ---------- */
.orb[data-state="skeleton"] .orb__score {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1em;
}

/* 44×16 at the 320 size; styles.css `.skeleton` adds the sweep. */
.orb__skeleton {
  display: block;
  width: 13.75cqi;
  height: 5cqi;
  border-radius: var(--radius-xs, 4px);
  background: var(--surface-container-high, #1C2128);
}

@keyframes orb-skeleton-pulse {
  from { opacity: .6; }
  to   { opacity: 1; }
}

.orb[data-state="skeleton"] .orb__ring {
  animation: orb-skeleton-pulse 1.5s var(--ease-emphasized, ease-in-out) infinite alternate;
}

/* ---------- Training Pulse (ACWR gauge) ---------- */
.gauge {
  --gauge-zone: var(--on-surface, #E8ECF2);
  position: relative;
  width: var(--gauge-size, 320px);
  max-width: 100%;
  aspect-ratio: 320 / 200;
  container-type: inline-size;
}

.gauge > svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* No-JS: hairline semicircle at the arc radius (C=(160,164), r=112.32 in a 320×200 box). The box is the upper
   half only (height = r), with the bottom border dropped, so nothing overhangs the gauge and adds scroll overflow. */
.gauge::before {
  content: "";
  position: absolute;
  left: 14.9%;
  top: 25.84%;
  width: 70.2%;
  height: 56.16%;
  border: 1px solid var(--hairline-strong, rgba(232, 236, 242, .16));
  border-bottom: 0;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  pointer-events: none;
}

.gauge--js::before { display: none; }

/* Readout below the arc — page HTML, siblings of `.gauge` inside one wrapper. orb.js sets --reveal on that
   wrapper so the number (t .35–.65) and details (t .60–.90) fade in with the app's stagger; without JS
   --reveal is unset and everything is visible. */
.gauge__readout {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.gauge__value,
.gauge__unit {
  display: block;
  opacity: clamp(0, calc((var(--reveal, 1) - .35) / .3), 1);
}

.gauge__value {
  font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-headline-lg, 2rem);
  font-weight: 700;
  line-height: 1.25;
  color: var(--gauge-zone-color, var(--on-surface, #E8ECF2));
  transform: translateY(calc((1 - clamp(0, calc((var(--reveal, 1) - .35) / .3), 1)) * 4px));
}

.gauge__unit {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-label-sm, 11px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 1.5px;
  color: var(--on-surface-muted, #9BA4AE);
}

.gauge__details {
  display: flex;
  justify-content: center;
  gap: var(--space-md, 16px);
  margin-top: var(--space-sm, 8px);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-body-sm, 12px);
  line-height: 1.33;
  letter-spacing: .4px;
  color: var(--on-surface-muted, #9BA4AE);
  opacity: clamp(0, calc((var(--reveal, 1) - .6) / .3), 1);
}

.gauge[data-zone="under"]   ~ .gauge__readout { --gauge-zone-color: var(--acwr-under, #38BDF8); }
.gauge[data-zone="sweet"]   ~ .gauge__readout { --gauge-zone-color: var(--acwr-sweet, #34D399); }
.gauge[data-zone="caution"] ~ .gauge__readout { --gauge-zone-color: var(--acwr-caution, #FBBF24); }
.gauge[data-zone="high"]    ~ .gauge__readout { --gauge-zone-color: var(--acwr-high, #F87171); }

/* ---------- Reduced motion: the reveal is skipped in JS; keep the skeleton still too. ---------- */
@media (prefers-reduced-motion: reduce) {
  .orb[data-state="skeleton"] .orb__ring {
    animation: none;
    opacity: .8;
  }
}
