/* product-cycle.css
 *
 * The Product page hero picture (/product/): Policy, Claims and Billing as
 * three independent modules around the Genasys platform. Each module has its
 * own activity on its own timetable; every change travels to the hub and out
 * to the other two, which pick up the shared policy record. Nothing waits on
 * anything else, so it reads as one platform, not a pipeline.
 *
 * A PICTURE OF THE PRODUCT, not the website. Every rule is scoped under the
 * container, data-platform-demo="product-cycle", which is also what makes the
 * theme load this file and product-cycle.js. Colours are palette tokens only.
 *
 * Everything is sized in cqw (container width) with px floors, and the
 * container reserves its height through aspect-ratio before anything loads:
 * no layout shift. product-cycle.js draws the links and moves the pulses;
 * under prefers-reduced-motion the picture is complete and still.
 *
 * NOTHING CLIPS. No element here has overflow hidden. Cards sit at least
 * --gpc-edge from the container's edges, which is more than their shadow's
 * reach (blur 2.4cqw, offset 0.8cqw), so the whole shadow is always drawn.
 * The card header rounds its own top corners instead of relying on a clip.
 */

[data-platform-demo="product-cycle"] {
	--gpc-policy: var(--wp--preset--color--accent);
	--gpc-claims: var(--wp--preset--color--primary);
	--gpc-billing: var(--wp--preset--color--purple);
	--gpc-card: var(--wp--preset--color--white);
	--gpc-ink: var(--genasys-space-blue);
	--gpc-line: var(--neutral-100);
	--gpc-muted: var(--neutral-500);
	--gpc-ease: cubic-bezier(0.4, 0, 0.2, 1);
	--gpc-r: 2.2cqw;           /* card corner */
	--gpc-edge: 4cqw;          /* card to container edge, more than the shadow's reach */
	--gpc-cw: 40cqw;           /* card width */
	--gpc-hub: 26cqw;          /* hub diameter */
	--gpc-hub-y: 50%;          /* hub centre, from the top */
	--gpc-shadow: 0 0.8cqw 2.4cqw var(--shadow-strong);
	container-type: inline-size;
	position: relative;
	width: 100%;
	max-width: 560px;
	margin-inline: auto;
	aspect-ratio: 1 / 1;
	font-family: var(--font-body);
	color: var(--gpc-ink);
	text-align: left; /* the hero centres its text on tablets and phones */
	user-select: none;
}
[data-platform-demo="product-cycle"] * { box-sizing: border-box; margin: 0; padding: 0; }

/* ---- the links: one from the hub to each module, drawn by product-cycle.js in container pixels ---- */
[data-platform-demo="product-cycle"] .gpc-links { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; z-index: 1; pointer-events: none; }
[data-platform-demo="product-cycle"] .gpc-link { stroke: rgb(from var(--genasys-white) r g b / 0.32); stroke-width: 1.5; stroke-dasharray: 2 5; stroke-linecap: round; transition: stroke 0.4s ease; }
[data-platform-demo="product-cycle"] .gpc-link.gpc-hot { stroke: rgb(from var(--genasys-white) r g b / 0.7); }
[data-platform-demo="product-cycle"] .gpc-pulse-core { fill: var(--wp--preset--color--white); }
[data-platform-demo="product-cycle"] .gpc-pulse-halo { opacity: 0.45; }
[data-platform-demo="product-cycle"] .gpc-pulse--policy .gpc-pulse-halo { fill: var(--gpc-policy); }
[data-platform-demo="product-cycle"] .gpc-pulse--claims .gpc-pulse-halo { fill: var(--wp--preset--color--steel); } /* Sapphire vanishes on the Sapphire hero ground */
[data-platform-demo="product-cycle"] .gpc-pulse--billing .gpc-pulse-halo { fill: var(--gpc-billing); }

/* ---- the Genasys hub: the ecosystem wheel's hub, with the real logo ---- */
[data-platform-demo="product-cycle"] .gpc-hub { position: absolute; left: 50%; top: var(--gpc-hub-y); width: var(--gpc-hub); aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: radial-gradient(circle at 50% 30%, var(--wp--preset--color--steel) 0%, var(--wp--preset--color--primary) 55%, var(--ink-deep) 100%); box-shadow: 0 1cqw 3cqw var(--shadow-strong); display: grid; place-items: center; z-index: 2; }
[data-platform-demo="product-cycle"] .gpc-hub::before { content: ""; position: absolute; inset: -1.6cqw; border-radius: 50%; border: 1px solid rgb(from var(--genasys-white) r g b / 0.22); background: rgb(from var(--genasys-white) r g b / 0.05); z-index: -1; }
[data-platform-demo="product-cycle"] .gpc-hub-ring { position: absolute; inset: -2px; border-radius: 50%; padding: 3px; background: conic-gradient(var(--wp--preset--color--accent), var(--wp--preset--color--cta-hover), var(--wp--preset--color--cta), var(--wp--preset--color--purple), var(--wp--preset--color--steel), var(--wp--preset--color--accent)); mask: linear-gradient(var(--wp--preset--color--white) 0 0) content-box, linear-gradient(var(--wp--preset--color--white) 0 0); mask-composite: exclude; }
[data-platform-demo="product-cycle"] .gpc-hub-pulse { position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgb(from var(--genasys-white) r g b / 0.7); opacity: 0; pointer-events: none; }
/* .gpc-hub img.gpc-hub-logo outranks the hero's own `.gn-product-hero-graphic img { width: 100% }` */
[data-platform-demo="product-cycle"] .gpc-hub img.gpc-hub-logo { position: relative; display: block; width: 72%; max-width: none; height: auto; border-radius: 0; }

/* ---- the three module cards ---- */
[data-platform-demo="product-cycle"] .gpc-card { --gpc-mod: var(--gpc-policy); position: absolute; width: var(--gpc-cw); background: var(--gpc-card); border-radius: var(--gpc-r); box-shadow: var(--gpc-shadow); z-index: 3; transition: translate 0.45s var(--gpc-ease); }
[data-platform-demo="product-cycle"] .gpc-card--policy { left: calc(50% - var(--gpc-cw) / 2); top: var(--gpc-edge); }
[data-platform-demo="product-cycle"] .gpc-card--claims { --gpc-mod: var(--gpc-claims); left: var(--gpc-edge); bottom: var(--gpc-edge); }
[data-platform-demo="product-cycle"] .gpc-card--billing { --gpc-mod: var(--gpc-billing); right: var(--gpc-edge); bottom: var(--gpc-edge); }
[data-platform-demo="product-cycle"] .gpc-card.gpc-fire { translate: 0 -0.6cqw; }

/* the header tints with the module colour and rounds its own top corners, so nothing has to clip it */
[data-platform-demo="product-cycle"] .gpc-hd { display: flex; align-items: center; gap: 1.6cqw; padding: 1.8cqw 2.4cqw; border-radius: var(--gpc-r) var(--gpc-r) 0 0; background: rgb(from var(--gpc-mod) r g b / 0.12); transition: background-color 0.5s ease; }
[data-platform-demo="product-cycle"] .gpc-ico { flex: none; display: grid; place-items: center; width: max(20px, 4.4cqw); height: max(20px, 4.4cqw); border-radius: max(5px, 1.1cqw); background: var(--gpc-mod); color: var(--wp--preset--color--white); }
[data-platform-demo="product-cycle"] .gpc-card--policy .gpc-ico { color: var(--gpc-ink); }
[data-platform-demo="product-cycle"] .gpc-ico svg { width: 66%; height: 66%; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
[data-platform-demo="product-cycle"] .gpc-name { flex: 1; font-family: var(--font-display); font-weight: 700; font-size: max(13px, 3.1cqw); line-height: 1.2; color: var(--gpc-ink); }
/* the live light: pings when this module does something */
[data-platform-demo="product-cycle"] .gpc-live { position: relative; flex: none; width: max(7px, 1.4cqw); height: max(7px, 1.4cqw); border-radius: 50%; background: var(--gpc-mod); }
[data-platform-demo="product-cycle"] .gpc-live::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--gpc-mod); opacity: 0; }

[data-platform-demo="product-cycle"] .gpc-ref { display: flex; justify-content: space-between; align-items: center; gap: 1.4cqw; padding: 1.3cqw 2.4cqw; border-bottom: 1px solid var(--gpc-line); font-size: max(10.5px, 2.25cqw); line-height: 1.3; white-space: nowrap; }
[data-platform-demo="product-cycle"] .gpc-ref span { color: var(--gpc-muted); }
[data-platform-demo="product-cycle"] .gpc-ref b { font-weight: 700; color: var(--gpc-ink); }
/* the shared policy number: the same record, seen from Claims and from Billing */
[data-platform-demo="product-cycle"] .gpc-shared { padding: 0.2cqw 1.2cqw; border-radius: var(--radius-pill); background: rgb(from var(--wp--preset--color--primary) r g b / 0.08); color: var(--wp--preset--color--primary) !important; transition: background-color 0.5s ease; }
/* a change arriving from another module: the header deepens and the shared reference lights up */
[data-platform-demo="product-cycle"] .gpc-card.gpc-sync .gpc-hd { background: rgb(from var(--gpc-mod) r g b / 0.22); }
[data-platform-demo="product-cycle"] .gpc-card.gpc-sync .gpc-shared { background: rgb(from var(--wp--preset--color--primary) r g b / 0.16); }

/* the activity: one item at a time, all stacked in one grid cell so the card never changes height */
[data-platform-demo="product-cycle"] .gpc-feed { display: grid; padding: 1.6cqw 2.4cqw 1.9cqw; }
[data-platform-demo="product-cycle"] .gpc-item { grid-area: 1 / 1; display: flex; flex-direction: column; gap: 0.2cqw; white-space: nowrap; opacity: 0; translate: 0 0.7cqw; transition: opacity 0.2s ease, translate 0.2s ease; }
/* the old line leaves quickly, the new one arrives just after it, so the two never overlap */
[data-platform-demo="product-cycle"] .gpc-item.gpc-on { opacity: 1; translate: none; transition: opacity 0.4s ease 0.18s, translate 0.4s var(--gpc-ease) 0.18s; }
[data-platform-demo="product-cycle"] .gpc-item b { font-weight: 700; font-size: max(11.5px, 2.55cqw); line-height: 1.25; color: var(--gpc-ink); }
[data-platform-demo="product-cycle"] .gpc-item span { font-size: max(10.5px, 2.25cqw); line-height: 1.3; color: var(--gpc-muted); }

/* ---- motion that only plays when allowed ---- */
@media (prefers-reduced-motion: no-preference) {
	[data-platform-demo="product-cycle"] .gpc-hub.gpc-recv .gpc-hub-pulse { animation: gpc-hub-pulse 1.1s ease-out; }
	[data-platform-demo="product-cycle"] .gpc-card.gpc-fire .gpc-live::after { animation: gpc-ping 1.1s ease-out; }
}
@keyframes gpc-hub-pulse { 0% { opacity: 0.8; scale: 1; } 100% { opacity: 0; scale: 1.35; } }
@keyframes gpc-ping { 0% { opacity: 0.6; scale: 1; } 100% { opacity: 0; scale: 2.4; } }
@media (prefers-reduced-motion: reduce) {
	[data-platform-demo="product-cycle"] *,
	[data-platform-demo="product-cycle"] *::before,
	[data-platform-demo="product-cycle"] *::after { transition: none !important; animation: none !important; }
}

/* ---- phones: wider cards so the text stays readable, a taller picture so
   the hub sits clear between them, and a smaller edge (the cards' shadow is
   smaller in pixels too) ---- */
@media (max-width: 600px) {
	[data-platform-demo="product-cycle"] { --gpc-cw: 45.5cqw; --gpc-edge: 3.4cqw; --gpc-hub: 36cqw; --gpc-hub-y: 50%; --gpc-r: 3cqw; aspect-ratio: 100 / 126; }
	[data-platform-demo="product-cycle"] .gpc-hd { padding: 1.8cqw 2.6cqw; }
	[data-platform-demo="product-cycle"] .gpc-ref,
	[data-platform-demo="product-cycle"] .gpc-feed { padding-inline: 2.6cqw; }
}

/* phones: take most of the screen width, like the other hero demos; inside the
   hero's wide side insets the picture would be too small to read */
@media (max-width: 600px) {
	.gn-product-hero-graphic > [data-platform-demo="product-cycle"] { flex: none; width: calc(100% + 2 * var(--gn-hero-inset, 48px) - 24px); max-width: none; margin-inline: calc(12px - var(--gn-hero-inset, 48px)); }
}
