/**
 * Category card block.
 *
 * Figma: 320x474, image fills the card, dark navy panel over the lower area,
 * the "more details" pill appears on hover. Structural + the parts of the visual
 * that are unambiguous from the design.
 */

.gboneai-category-card {
	--gboneai-card-radius: var(--gboneai-radius-card, 20px);

	block-size: 100%;
	/* The block can be dropped into any column width, so type scales with the
	 * CARD, not the viewport. cqi units below are calibrated so a 320px card -
	 * the width drawn in Figma - lands exactly on the designed 32px / 18px. */
	container-type: inline-size;
}

.gboneai-category-card__inner {
	position: relative;
	display: block;
	block-size: 100%;
	min-block-size: 474px;
	border-radius: var(--gboneai-card-radius);
	overflow: hidden;
	color: var(--wp--preset--color--white, #fff);
	text-decoration: none;
	isolation: isolate;
	/* Figma: drop shadow 0 0 20px #0000001A, spread 0. */
	box-shadow: var(--gboneai-shadow-card, 0 0 20px rgba(0, 0, 0, 0.1));
}

.gboneai-category-card__figure {
	margin: 0;
	block-size: 100%;
}

.gboneai-category-card__image {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	display: block;
	transform: scale(1);
	transition: transform var(--gboneai-duration-slow, 420ms) var(--gboneai-ease, ease-out);
}

/* A slow, small zoom. Large enough to feel responsive, small enough that the
 * photo does not visibly crop. */
.gboneai-category-card__inner:hover .gboneai-category-card__image,
.gboneai-category-card__inner:focus-visible .gboneai-category-card__image {
	transform: scale(1.05);
}

/* Figma 59:227 — flat #1b2b50 at 96% opacity, occupying the bottom 28.27% of the
 * card, 20px/25px padding, 5px gap, bottom corners matching the card radius.
 *
 * The 96% is deliberate in the design and worth keeping: it lets a trace of the
 * photograph read through the panel so the card feels like one image rather than
 * a caption pasted onto it. It is NOT the gradient that was tried and rejected -
 * a flat 4% is uniform, so the text contrast is identical everywhere. */
.gboneai-category-card__panel {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	min-block-size: 28.27%;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	padding: 20px 25px;
	background: var(--gboneai-color-dark, #1b2b50);
	opacity: 0.96;
	border-end-start-radius: var(--gboneai-card-radius);
	border-end-end-radius: var(--gboneai-card-radius);
}

.gboneai-category-card__title {
	margin: 0;
	color: var(--wp--preset--color--white, #fff);
	font-size: clamp(1.25rem, 10cqi, 2rem); /* 32px at a 320px card */
	font-weight: 700;
	line-height: 0.9;
	letter-spacing: 0.32px;
	text-wrap: balance;
}

.gboneai-category-card__description {
	margin: 0;
	font-size: clamp(0.875rem, 5.6cqi, 1.125rem); /* 18px at a 320px card */
	font-weight: 400;
	line-height: 1.1;
}

/* The pill is hidden until hover or keyboard focus. Focus matters as much as
 * hover: a keyboard user must see the same affordance. */
.gboneai-category-card__action {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	/*
	 * IT HUGS ITS LABEL AND SITS AT THE PANEL'S START EDGE.
	 *
	 * 59:205, the button inside the card's hover variant 67:190, is 110 x 28 at
	 * x=185 in a 320 panel whose content box runs 25..295 - so it ends on the
	 * panel's start edge, which in RTL is the right. `align-self` was never set,
	 * a flex column stretches by default, and the pill came out 270 wide: the
	 * whole panel, corner to corner. Measured 270 x 34 against a drawn 110 x 28.
	 */
	align-self: flex-start;

	/*
	 * NO HEIGHT AT REST. It was min-block-size: 34px with opacity: 0, so an
	 * invisible pill took 34px of the panel and the resting panel was never the
	 * drawn 28.27%: it came out 134 where the description ran to one line and
	 * 152 where it ran to two. 59:259 holds a title and a description and nothing
	 * else - the pill, 59:280, is a component of its own and is not placed in the
	 * resting card at all.
	 *
	 * The panel is absolute against the bottom of the card, so growing on hover
	 * expands it upward over the photograph and moves nothing outside the card.
	 *
	 * The shorthand comes FIRST. Written the other way round, `border: 1px` reset
	 * the `border-width: 0` above it and the resting pill was 2px tall, not 0 -
	 * two pixels plus the panel's 5px gap, on every card, for nothing.
	 */
	border: 1px solid var(--wp--preset--color--white, #fff);
	border-radius: var(--gboneai-radius-pill, 999px);
	min-block-size: 0;
	block-size: 0;
	border-width: 0;
	padding-block: 0;
	overflow: hidden;

	/*
	 * 5 and 11, where 59:280 says 6 and 12.
	 *
	 * Figma centres a stroke on the frame boundary, so half of the 1px sits
	 * outside the 110 x 28 and the frame is 6 + 16 + 6. CSS counts the whole
	 * border inside the box, so 6/12 with a 1px border makes 112 x 30. One less
	 * each way puts the outer box on the drawn numbers exactly, which is what a
	 * reader compares.
	 */
	padding-inline: 11px;
	font-size: 1rem;
	line-height: 1;

	/*
	 * AND IT CANCELS THE PANEL'S OWN GAP WHILE IT IS COLLAPSED.
	 *
	 * `gap` reserves space between every pair of in-flow items, whatever their
	 * size - so a pill of no height still costs 5px, and the resting panel is
	 * 5 taller than 59:259, which holds a title and a description and nothing
	 * else. Measured 118 of content where the parts come to 113.
	 *
	 * It does not show today only because the panel's floor - 28.27% of a 474
	 * card, 134 - is higher than either number. The drawn description runs to
	 * three lines where the demo copy runs to two; at three the content is 139
	 * and the floor stops hiding it. A fault waiting for real copy.
	 */
	margin-block-start: -5px;
	opacity: 0;
	transform: translateY(0.5rem);
	transition:
		opacity var(--gboneai-duration, 280ms) var(--gboneai-ease, ease-out),
		transform var(--gboneai-duration, 280ms) var(--gboneai-ease, ease-out),
		margin-block-start var(--gboneai-duration, 280ms) var(--gboneai-ease, ease-out),
		background-color var(--gboneai-duration, 280ms) var(--gboneai-ease, ease-out),
		color var(--gboneai-duration, 280ms) var(--gboneai-ease, ease-out);
}

/* Two separate states on purpose:
 *   hovering the CARD   -> the pill is revealed
 *   hovering the PILL   -> the pill fills
 * The pill is a span inside the card link, so it still gets its own :hover when
 * the pointer is actually over it. Filling it from the card hover would make the
 * pill look pressed the moment the card was touched anywhere. */
.gboneai-category-card__action:hover {
	background-color: var(--wp--preset--color--white, #fff);
	color: var(--gboneai-color-dark, #1b2b50);
}

/*
 * 28 tall, and NO margin above it. 67:200, the hover panel, is 167 tall and
 * spaced 20 / 29 / 5 / 60 / 5 / 28 / 20 - the same 5px the panel already sets
 * between every part of itself. `margin-block-start: 1rem` put 21 there.
 */
.gboneai-category-card__inner:hover .gboneai-category-card__action,
.gboneai-category-card__inner:focus-visible .gboneai-category-card__action {
	min-block-size: 28px;
	block-size: auto;
	border-width: 1px;
	padding-block: 5px;
	margin-block-start: 0;
	opacity: 1;
	transform: translateY(0);
}

.gboneai-category-card__inner:focus-visible {
	outline: var(--gboneai-focus, 3px solid #fcac0b);
	outline-offset: 3px;
}

/*
 * Touch devices have no hover, so the pill would never appear. Show it always.
 *
 * AND GIVE IT A HEIGHT. This set opacity, margin and transform and nothing else,
 * which was enough back when the resting pill was 34px tall and merely
 * transparent. It is 0 tall now, so on every phone and tablet this rule turned
 * an invisible pill into a visible pill of no height - which is still nothing.
 * It has to restore the same four properties the hover state does.
 */
@media (hover: none) {
	.gboneai-category-card__action {
		min-block-size: 28px;
		block-size: auto;
		border-width: 1px;
		padding-block: 5px;
		margin-block-start: 0;
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.gboneai-category-card__action {
		transition: none;
	}
}

/* --- stacked variant: the benefit card from the personal area ------------ */

/* Same parts as the overlay card, but the panel sits BELOW the photograph and
 * the action is a real button rather than a pill revealed on hover - on this
 * card it is the whole point, so hiding it until hover would be wrong. */
.gboneai-category-card--stacked .gboneai-category-card__inner {
	display: flex;
	flex-direction: column;
	min-block-size: 0;
	background: var(--wp--preset--color--white, #fff);
}

.gboneai-category-card--stacked .gboneai-category-card__figure {
	block-size: auto;
	flex: 0 0 auto;
}

/* The ratio has to sit on the IMG, not the figure.
 *
 * On the figure it loses to the image's own intrinsic height, because the figure
 * is a flex item sized from its content - so the crop silently did nothing and
 * the cards came out 480px tall instead of 200. Computed style still reported
 * `aspect-ratio: 320 / 200`, which is why this only showed up in a screenshot. */
.gboneai-category-card--stacked .gboneai-category-card__image {
	block-size: auto;
	aspect-ratio: 320 / 200;
	object-fit: cover;
}

.gboneai-category-card--stacked .gboneai-category-card__panel {
	position: static;
	min-block-size: 0;
	opacity: 1;
	border-radius: 0;
	padding: 16px 20px 20px;
	gap: 10px;
	align-items: center;
	text-align: center;
	flex: 1 1 auto;
}

.gboneai-category-card--stacked .gboneai-category-card__title {
	font-size: clamp(1rem, 5.6cqi, 1.25rem);
	line-height: 1.2;
}

/* Always visible here, and full width, so it reads as the card's action. */
/*
 * AND IT NEEDS A HEIGHT, for the third time in this file.
 *
 * This set inline-size, margin, opacity, transform and two colours - everything
 * except the four properties that give the pill a box. The resting pill is 0
 * tall, so all of that painted a blue button of no height: measured 292 x 0,
 * four times, on /benefits-page/. The comment above says the button is the
 * whole point of this card, and it has not been visible since the resting
 * height was removed.
 */
.gboneai-category-card--stacked .gboneai-category-card__action {
	inline-size: 100%;
	min-block-size: 28px;
	block-size: auto;
	border-width: 1px;
	padding-block: 5px;
	margin-block-start: 4px;
	opacity: 1;
	transform: none;
	border-color: transparent;
	background-color: var(--gboneai-color-primary, #1043ff);
	color: var(--wp--preset--color--white, #fff);
}

/*
 * The overlay card's reveal rule matches inside a stacked card too - same
 * `__inner` and `__action`, one extra ancestor class - and it sets the same
 * 28 / 1 / 5 this variant already carries, so today the two agree. Checked
 * rather than assumed, and this rule restates the margin so a change to the
 * reveal's sizing cannot quietly move a button that is never revealed.
 */
.gboneai-category-card--stacked .gboneai-category-card__inner:hover .gboneai-category-card__action,
.gboneai-category-card--stacked .gboneai-category-card__inner:focus-visible .gboneai-category-card__action {
	margin-block-start: 4px;
	background-color: var(--gboneai-color-accent, #fcac0b);
	color: var(--gboneai-color-dark, #1b2b50);
}

/* The overlay card zooms its photo on hover; a stacked card with a static panel
 * underneath would just look like the image was slipping. */
.gboneai-category-card--stacked .gboneai-category-card__inner:hover .gboneai-category-card__image,
.gboneai-category-card--stacked .gboneai-category-card__inner:focus-visible .gboneai-category-card__image {
	transform: none;
}

/*
 * The panel colours. `222:688` runs four across the row — navy, blue, yellow,
 * turquoise from the start edge — and every card had been navy.
 *
 * The drawing sets the blue one at `#0137fc`, which is not the site's blue. The
 * Figma file carries duplicate token collections and the canonical palette is
 * the one in CLAUDE.md, so this takes `--blue` and the two-point difference goes
 * with it. Same reasoning as the shadow.
 */
.gboneai-category-card--panel-dark .gboneai-category-card__panel {
	background: var(--gboneai-color-dark, #1b2b50);
}

.gboneai-category-card--panel-blue .gboneai-category-card__panel {
	background: var(--wp--preset--color--primary, #1043ff);
}

.gboneai-category-card--panel-yellow .gboneai-category-card__panel {
	background: var(--wp--preset--color--accent, #fcac0b);
}

.gboneai-category-card--panel-turquoise .gboneai-category-card__panel {
	background: var(--wp--preset--color--turquoise, #1fa9ab);
}

/*
 * The rings. 222:688 puts one or two coloured arcs behind the cut-out subject on
 * every card, in that card's own colour.
 *
 * Behind: the card's white background is the card's, not the photograph's — the
 * card images are cut-outs with their alpha intact, which is what lets a ring
 * show through at all. They were being flattened onto white until 27/08, which
 * is why this could not be built.
 *
 * Placed by centre rather than by corner, so a rotation does not move it: the
 * inline style gives left/top as the centre and width/height as the SVG's own
 * size, both as percentages of the card, and the translate puts the centre where
 * left/top say.
 */
.gboneai-category-card__ring {
	position: absolute;
	display: block;
	color: var(--gboneai-color-dark, #1b2b50);
	pointer-events: none;
	transform: translate(-50%, -50%) rotate(var(--gboneai-ring-rotate, 0deg));
	transform-origin: center;
}

.gboneai-category-card__ring svg {
	display: block;
	inline-size: 100%;
	block-size: 100%;
}

/* The ring takes the panel's colour. One declaration per colour, so a card that
   changes colour changes both without anything being kept in step. */
.gboneai-category-card--panel-blue .gboneai-category-card__ring {
	color: var(--wp--preset--color--primary, #1043ff);
}

.gboneai-category-card--panel-yellow .gboneai-category-card__ring {
	color: var(--wp--preset--color--accent, #fcac0b);
}

.gboneai-category-card--panel-turquoise .gboneai-category-card__ring {
	color: var(--wp--preset--color--turquoise, #1fa9ab);
}

/* 59:255 — a white rounded rectangle under everything. It was the photograph
   carrying the white until 27/08; now the card does, which is what lets the
   cut-outs be cut-outs. */
.gboneai-category-card--overlay .gboneai-category-card__inner {
	background: var(--wp--preset--color--white, #fff);
}
