diff --git a/src/components/cycle/cycle-ring-tile.tsx b/src/components/cycle/cycle-ring-tile.tsx index 2e20b4761..b7363c57e 100644 --- a/src/components/cycle/cycle-ring-tile.tsx +++ b/src/components/cycle/cycle-ring-tile.tsx @@ -92,23 +92,28 @@ export function CycleRingTile({ className }: { className?: string }) { const hue = PHASE_HUE[wheel.phase]; return ( - + // `data-revealed` must sit on an ANCESTOR of `.wellness-tile-rise` — the + // keyframe selector is `[data-revealed="true"] .wellness-tile-rise` + // (descendant combinator). Both on the same node never matched, leaving the + // tile stuck at the rise rule's `opacity: 0`. The `contents` wrapper carries + // the flag without adding a layout box. +
+
- + +
); } diff --git a/src/components/cycle/cycle-view.tsx b/src/components/cycle/cycle-view.tsx index 7f3b9b103..9f3d155e3 100644 --- a/src/components/cycle/cycle-view.tsx +++ b/src/components/cycle/cycle-view.tsx @@ -159,20 +159,29 @@ export function CycleView() {
{/* Wheel + compact phase card — grouped so they stick together. */}
- {/* Wheel — the signature ring on the premium wellness-tile surface. */} + {/* Wheel — the signature ring on the premium wellness-tile surface. + `data-revealed` must sit on an ANCESTOR of `.wellness-tile-rise` + — the keyframe selector is `[data-revealed="true"] + .wellness-tile-rise` (descendant combinator). Both on the same + node never matched, leaving the tile stuck at the rise rule's + `opacity: 0` (invisible but still boxed). The `contents` wrapper + carries the flag without adding a layout box. */}
+
{loading ? (
@@ -216,6 +225,7 @@ export function CycleView() { {t("cycle.ring.firstPeriodCta")} ) : null} +
{/* Phase-education card beneath the wheel — the single instance, diff --git a/src/components/cycle/phase-education-card.tsx b/src/components/cycle/phase-education-card.tsx index 681e2d9ed..eb8e65bcd 100644 --- a/src/components/cycle/phase-education-card.tsx +++ b/src/components/cycle/phase-education-card.tsx @@ -107,18 +107,23 @@ export function PhaseEducationCard({ const phaseName = phase ? t(`cycle.phase.${phase}`) : null; return ( -
+ // `data-revealed` must sit on an ANCESTOR of `.wellness-tile-rise` — the + // keyframe selector is `[data-revealed="true"] .wellness-tile-rise` + // (descendant combinator). Both on the same node never matched, leaving the + // tile stuck at the rise rule's `opacity: 0`. The `contents` wrapper carries + // the flag without adding a layout box. +
+
{/* Zone 1 — eyebrow + phase name with a hue dot (never colour-only). */}
)} -
+
+
); }