/*
 * How this site colours a vote.
 *
 * ⚠️ THE PLATFORM DECIDES WHAT A CARD IS. THIS DECIDES WHAT IT LOOKS LIKE.
 *
 * `oview-bricks` builds the card, owns the class names `votes.js` binds to, and
 * gives every control a shape that clears the accessibility floor. None of that
 * belongs to a site. Which colour longevity is, and whether a chosen answer
 * fills or outlines, is design, and `oview-site-two` over the same fragrances
 * would answer differently (D103).
 *
 * ⚠️ KEYED ON `data-metric`, WHICH IS DATA THE CARD ALREADY CARRIES.
 *
 * The engine writes `data-metric="longevity"` because the endpoint needs it, so
 * a colour per metric costs no new markup and no new class. It also means a
 * dataset that adds a metric gets the default until somebody chooses a colour,
 * rather than getting nothing.
 *
 * ⚠️ NOTHING HERE NAMES A FRAGRANCE COLUMN'S MEANING. `longevity` is a metric
 * key this site happens to style; the platform never learns that it exists.
 */

/* --- the answer somebody chose ------------------------------------------- */

/*
 * ⚠️ One rule per metric, and the LAST one wins for a metric nobody listed.
 * A default first, so an unstyled metric is accent-coloured rather than
 * invisible, which is what an unset `background` would give.
 */
.oview-vote__step[aria-checked="true"],
.oview-vote__button[aria-checked="true"] {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-surface);
}

.oview-vote__step[data-metric="longevity"][aria-checked="true"] {
	/* White, like the default rule. A per-metric rule that sets only the
	   background inherits the muted text the unchosen state uses, and grey
	   on a saturated fill is the one pairing in the card that fails. */
	color: var(--color-surface);
	background: var(--color-success);
	border-color: var(--color-success);
}

.oview-vote__step[data-metric="sillage"][aria-checked="true"] {
	/* White, like the default rule. A per-metric rule that sets only the
	   background inherits the muted text the unchosen state uses, and grey
	   on a saturated fill is the one pairing in the card that fails. */
	color: var(--color-surface);
	background: var(--color-tier-mid);
	border-color: var(--color-tier-mid);
}

.oview-vote__step[data-metric="price_value"][aria-checked="true"] {
	/* White, like the default rule. A per-metric rule that sets only the
	   background inherits the muted text the unchosen state uses, and grey
	   on a saturated fill is the one pairing in the card that fails. */
	color: var(--color-surface);
	background: var(--color-warning);
	border-color: var(--color-warning);
}

/* --- the bar that goes with it ------------------------------------------- */

/*
 * ⚠️ FOUR CLASSES DEEP ON PURPOSE. An imported design's promoted rule is
 * `.ov-card .oview-vote__meter .oview-vote__fill`, which is three, and it loads
 * after this file: matched at three these lose on order and every meter paints
 * the one colour the design happened to draw its sample with. All three bars
 * came out green.
 *
 * ⚠️ AND A COMPARISON OF TWO RECORDS IS THE SAME MEASURE, SO THE SAME COLOUR
 * (D189). Its rows carry the same `data-metric`, and they are named on these
 * rules rather than given rules of their own, because "longevity is green" is
 * one decision and a second copy of it is how winter becomes two blues.
 */

.oview-vote--meters .oview-vote__meter[data-metric="longevity"] .oview-vote__fill,
.oview-compare__row[data-metric="longevity"] .oview-compare__fill {
	background: var(--color-success);
}

.oview-vote--meters .oview-vote__meter[data-metric="sillage"] .oview-vote__fill,
.oview-compare__row[data-metric="sillage"] .oview-compare__fill {
	background: var(--color-tier-mid);
}

.oview-vote--meters .oview-vote__meter[data-metric="price_value"] .oview-vote__fill,
.oview-compare__row[data-metric="price_value"] .oview-compare__fill {
	background: var(--color-warning);
}

/* --- when to wear: a bar per season, and the count after it ---------------- */

/*
 * ⚠️ THE COUNT GOES AFTER THE BAR, WHICH THE DOM ORDER DOES NOT SAY.
 *
 * The platform emits label, count, track, because that is the order they are
 * useful in when a bar is short and a screen is narrow: the number is next to
 * the name. This design reads bar-then-number, which is easier to compare down
 * a column, so the site places them with grid areas instead of asking the
 * platform to re-order its markup for one site's taste.
 *
 * ⚠️ Areas, not `order`. `order` moves the box and leaves the DOM alone, which
 * is exactly the mismatch between reading order and tab order that makes a
 * keyboard walk a list backwards.
 */
.oview-vote--bars .oview-vote__row {
	grid-template-columns: minmax(7rem, 10rem) 1fr minmax(5rem, auto);
	grid-template-areas: "label track count";
	gap: var(--space-m);
}

.oview-vote--bars .oview-vote__row-label {
	grid-area: label;
}

.oview-vote--bars .oview-vote__row .oview-vote__track {
	grid-area: track;
	/* Taller than the platform default: this is the card's main content rather
	   than a hint beside a number, and a 6px bar cannot carry a colour. */
	block-size: 2.4rem;
	border-radius: var(--radius-full);
}

.oview-vote--bars .oview-vote__row-count {
	grid-area: count;
	text-align: end;
}

/*
 * ⚠️ TWO QUESTIONS, SO A BREAK BETWEEN THEM (D190). The seasons add up to 100%
 * and so do day and night; run together as six rows, "day 50%" read as a
 * season beside "winter 37%".
 *
 * `data-question-start` is the platform's mark for it, which a card built by
 * `lib-vote-card.php` carries on any dataset. This site's card came from a
 * drawing before the mark existed, so its first time-of-day row is named too.
 */
.oview-vote--bars .oview-vote__row[data-question-start],
.oview-vote--bars .oview-vote__row[data-metric="day"] {
	margin-top: var(--space-m);
}

/*
 * ⚠️ A COLOUR PER SEASON, and they are not decoration.
 *
 * Six bars of one colour are read by length alone; six colours are read at a
 * glance and remembered between fragrances, which is the comparison this card
 * exists for. Winter cold, summer warm, night deep: the mapping is meant to be
 * guessable rather than arbitrary.
 */
.oview-vote--bars .oview-vote__row[data-metric="winter"] .oview-vote__fill,
.oview-compare__row[data-metric="winter"] .oview-compare__fill {
	background: var(--color-accent);
}

.oview-vote--bars .oview-vote__row[data-metric="spring"] .oview-vote__fill,
.oview-compare__row[data-metric="spring"] .oview-compare__fill {
	background: var(--color-success);
}

.oview-vote--bars .oview-vote__row[data-metric="summer"] .oview-vote__fill,
.oview-compare__row[data-metric="summer"] .oview-compare__fill {
	background: var(--color-tier-top);
}

.oview-vote--bars .oview-vote__row[data-metric="autumn"] .oview-vote__fill,
.oview-compare__row[data-metric="autumn"] .oview-compare__fill {
	background: var(--color-warning);
}

.oview-vote--bars .oview-vote__row[data-metric="day"] .oview-vote__fill,
.oview-compare__row[data-metric="day"] .oview-compare__fill {
	/* Teal, not `check`: that is a green a few points from `success`, and Spring
	   and Day came out indistinguishable. `--color-teal` is this site's own, in
	   tokens.css. */
	background: var(--color-teal);
}

.oview-vote--bars .oview-vote__row[data-metric="night"] .oview-vote__fill,
.oview-compare__row[data-metric="night"] .oview-compare__fill {
	background: var(--color-tier-mid);
}

/*
 * ⚠️ A VOTED ROW WEARS ITS OWN COLOUR, not one blue for all six.
 *
 * The mark is saying "this one is yours", and saying it in the accent put a
 * blue tick beside an orange bar. It belongs to the row, so it takes the row's
 * colour and the card stays readable as six things rather than six things and
 * a highlight.
 *
 * ⚠️ THE NUMBER AND THE TICK CARRY IT, NOT A BORDER. An outline around
 * the whole row drew a second rectangle inside a card already made of
 * rectangles, and at 2px it read as a focus ring on something not focused.
 * Recolouring the two elements at the end of the row says the same thing in
 * the space they already occupy.
 */
.oview-vote--bars .oview-vote__row[aria-checked="true"] .oview-vote__row-count {
	color: inherit;
	font-weight: 700;
}

.oview-vote--bars .oview-vote__row[data-metric="winter"][aria-checked="true"] { color: var(--color-accent); }
.oview-vote--bars .oview-vote__row[data-metric="spring"][aria-checked="true"] { color: var(--color-success); }
.oview-vote--bars .oview-vote__row[data-metric="summer"][aria-checked="true"] { color: var(--color-tier-top); }
.oview-vote--bars .oview-vote__row[data-metric="autumn"][aria-checked="true"] { color: var(--color-warning); }
.oview-vote--bars .oview-vote__row[data-metric="day"][aria-checked="true"] { color: var(--color-teal); }
.oview-vote--bars .oview-vote__row[data-metric="night"][aria-checked="true"] { color: var(--color-tier-mid); }

/*
 * ⚠️ The label keeps its own ink. `currentColor` is carrying the number and
 * the tick, so anything that inherits it without being told otherwise turns
 * the row's colour too, and a season's name in orange reads as a link.
 *
 * ⚠️ AND THE NUMBER IS NOT PINNED BACK TO MUTED. It was, three rules below the
 * one that colours it and at the same specificity, so the later rule won and
 * every voted count stayed grey while the CSS above it said otherwise. Two
 * rules setting one property on one selector is the bug; deleting one is the
 * fix.
 */
.oview-vote--bars .oview-vote__row[aria-checked="true"] .oview-vote__row-label {
	color: var(--color-text);
}

/* --- the collection, which is three answers to one question --------------- */

/*
 * ⚠️ These are the only three buttons on the site whose colour means something
 * rather than decorating something: owning, wanting and having owned are
 * different relationships, and a reader scanning their own collection reads the
 * colour before the words.
 */
/*
 * ⚠️ THE ICON SITS IN ITS OWN BADGE, which is what makes these read as chips
 * rather than as text with a character in front of it.
 *
 * The badge is tinted per metric and the chip stays white until it is chosen,
 * so an unanswered card still tells you which button is which at a glance.
 */
.oview-vote__button-icon {
	inline-size: 2.2rem;
	block-size: 2.2rem;
	border-radius: var(--radius-s);
	background: var(--color-surface-sunk);
	color: var(--color-text-muted);
	font-weight: 700;
}

.oview-vote__button[data-metric="have"] .oview-vote__button-icon {
	background: var(--color-success-soft);
	color: var(--color-on-success-soft);
}

.oview-vote__button[data-metric="want"] .oview-vote__button-icon {
	background: var(--color-error-soft);
	color: var(--color-on-error-soft);
}

.oview-vote__button[data-metric="had"] .oview-vote__button-icon {
	background: var(--color-accent-soft);
	color: var(--color-on-accent-soft);
}

/*
 * ⚠️ The count is quieter than the words, and it is a NUMBER, so it gets
 * tabular figures: 42,527 becoming 42,528 must not move the label beside it.
 */
.oview-vote__button-label {
	font-weight: 600;
}

.oview-vote__button-count {
	color: var(--color-text-muted);
	font-variant-numeric: tabular-nums;
}

/*
 * ⚠️ Chosen, everything inside goes white together, INCLUDING the badge, which
 * otherwise keeps its pale tint and reads as a hole punched in the fill.
 */
/*
 * ⚠️ AND THE SAME FOR A CHOSEN ONE. It is white on a saturated fill, and an
 * anchor hovering back to a link colour there is white text turning blue on
 * green - the exact failure `tokens.css` describes for buttons, arriving by a
 * different route.
 */
.oview-vote__button:not([aria-checked="true"]):hover {
	color: var(--color-text);
}

.oview-vote__button[aria-checked="true"]:hover {
	color: var(--color-surface);
}

.oview-vote__button[aria-checked="true"] .oview-vote__button-icon {
	background: rgb(255 255 255 / 25%);
	color: var(--color-surface);
}

.oview-vote__button[data-metric="have"][aria-checked="true"] {
	color: var(--color-surface);
	background: var(--color-success);
	border-color: var(--color-success);
}

.oview-vote__button[data-metric="want"][aria-checked="true"] {
	color: var(--color-surface);
	background: var(--color-error);
	border-color: var(--color-error);
}

.oview-vote__button[data-metric="had"][aria-checked="true"] {
	color: var(--color-surface);
	background: var(--color-accent);
	border-color: var(--color-accent);
}

/*
 * ⚠️ The count inside a chosen button inherits, and without this it keeps the
 * muted grey it has when the button is white: grey on green, which is the one
 * pairing in the card that fails contrast.
 */
.oview-vote__button[aria-checked="true"] * {
	color: inherit;
}

/* --- the stars -------------------------------------------------------------- */

/*
 * ⚠️ THE CHOSEN STARS, WHICH A BRIDGED DESIGN CANNOT SUPPLY.
 *
 * A design that draws its stars as a loop expresses the filled state as loop
 * DATA - `{star.bg}

` per star - not as a CSS state. So the bridge carries its
 * OFF look across and there is nothing to carry for ON, and every star renders
 * unchosen no matter what the viewer picked.
 *
 * ⚠️ Two classes plus the attribute, because the bridged rule is two classes
 * and loads after this file. Matching its specificity would lose on order.
 */
.oview-vote--stars .oview-vote__star[data-fill="on"] {
	background: var(--color-tier-top);
	color: var(--color-surface);
}

/* --- what the viewer themselves said -------------------------------------- */

.oview-vote__mine {
	font-weight: 600;
}

.oview-vote__meter[data-metric="longevity"] .oview-vote__mine {
	color: var(--color-success);
}

.oview-vote__meter[data-metric="sillage"] .oview-vote__mine {
	color: var(--color-tier-mid);
}

.oview-vote__meter[data-metric="price_value"] .oview-vote__mine {
	color: var(--color-warning);
}

/* ==========================================================================
 * THE VOTE CARDS AS DRAWN, ADOPTED 2026-08-30.
 *
 * ⚠️ HERE AND NOT IN modules.css, BECAUSE THIS FILE LOADS AFTER IT.
 *
 * The site loads tokens, header, footer, pages, modules, votes, then the
 * promoted parts. These came from parts, so a copy adopted into modules.css
 * would sit BEFORE votes.css and lose to it: the mock4 star went back to the
 * platform default, a 14px grey glyph where the design had a 15px filled
 * chip, and nothing else on eleven pages moved at all.
 *
 * ⚠️ They are kept even though .oview-vote only appears on /mockup-mock4/
 * today. The fragrance page these belong to has not been built yet; a
 * platform class is reusable by definition and will turn up on a page
 * nobody has written.
 * ========================================================================== */

.oview-vote__meter {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: baseline;
	column-gap: var(--space-m);
}

.oview-vote__meter-label {
	grid-column: 1;
	font-size: var(--text-l);
	font-weight: 600;
	margin: 0 0 var(--space-s);
}

.oview-vote__meter-value {
	grid-column: 2;
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	color: var(--color-text-quiet);
	margin: 0 0 var(--space-s);
	text-align: right;
}

.oview-vote__meter .oview-vote__track {
	grid-column: 1 / -1;
	height: var(--space-m);
	border-radius: var(--radius-full);
	background: var(--color-track);
	overflow: hidden;
	margin-bottom: var(--space-m);
}

.oview-vote__meter .oview-vote__fill {
	height: 100%;
	border-radius: var(--radius-full);
	width: var(--sample-w-perf);
	background: var(--color-success);
}

.oview-vote__steps {
	grid-column: 1 / -1;
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--space-xs);
}

.oview-vote__step {
	flex: 1 1 auto;
	font-family: var(--font-sans);
	font-size: var(--text-xs);
	font-weight: 600;
	min-height: var(--tap-min);
	min-width: var(--tap-min);
	padding: var(--space-xs) var(--space-2xs);
	border-radius: var(--radius-m);
	cursor: pointer;
	border: var(--border-hair) solid var(--color-border);
	background: var(--color-surface);
	color: var(--color-text-quiet);
	text-align: center;
	box-sizing: border-box;
	display: inline-flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
}

.oview-vote__step:hover {
	border-color: var(--color-border-strong);
	color: var(--color-text);
}

.oview-vote__row {
	display: grid;
	grid-template-columns: 6.2rem minmax(6rem, 1fr) 5.2rem;
	align-items: center;
	gap: var(--space-m);
}

.oview-vote__row-label {
	font-size: var(--text-l);
	font-weight: 600;
	margin: 0;
}

.oview-vote__row-count {
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	text-align: right;
	margin: 0;
}

.oview-vote__row .oview-vote__track {
	/* ⚠️ A TRACK'S HEIGHT, NOT A SPACE, and the same in all three places. It
	 * borrowed a spacing step from the old importer and would have gone fluid. */
	height: 2.2rem;
	border-radius: var(--radius-s);
	background: var(--color-track-soft);
	overflow: hidden;
	display: block;
}

.oview-vote__row .oview-vote__fill {
	display: block;
	height: 100%;
	border-radius: var(--radius-s);
	width: var(--sample-w-season);
	background: var(--color-accent);
}

/*
 * ⚠️ SCOPED TO THE CONTROL, NOT TO WHERE IT WAS DRAWN.
 *
 * These two were keyed on `[data-ov-part="engine:vote/collection"]`, which is
 * the MOCKUP'S provenance attribute - a note saying which drawn block this came
 * out of. Nothing about how a collection button looks depends on that: it is
 * how this site draws that control, full stop. The scope only meant the same
 * control anywhere else fell back to the platform's floor, which is what
 * happened the moment the account page reused it - identical colours, half the
 * height, a quarter of the gap and the wrong radius.
 *
 * `.oview-vote__button` appears only in a buttons-display card, so this reaches
 * exactly the set it always described.
 */
.oview-vote__buttons {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-xs);
}

.oview-vote__button {
	font-family: var(--font-sans);
	cursor: pointer;
	border: var(--border-thick) solid var(--color-border);
	background: var(--color-surface);
	color: var(--color-text);
	border-radius: var(--radius-m-4);
	min-height: var(--tap-min);
	padding: var(--space-m) var(--space-l) var(--space-m) var(--space-m);
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: var(--space-m);
	box-sizing: border-box;
}

.ov-card--vote-occasion .oview-vote__meter .oview-vote__track {
	grid-column: 1 / -1;
	height: var(--space-m);
	border-radius: var(--radius-full);
	background: var(--color-track);
	overflow: hidden;
	margin-bottom: var(--space-m);
}

.ov-card--vote-occasion .oview-vote__meter .oview-vote__fill {
	height: 100%;
	border-radius: var(--radius-full);
	width: var(--sample-w-perf);
	background: var(--color-success);
}

.ov-card--vote-occasion .oview-vote__row {
	display: grid;
	grid-template-columns: 6.2rem minmax(6rem, 1fr) 5.2rem;
	align-items: center;
	gap: var(--space-m);
}

.ov-card--vote-occasion .oview-vote__row-count {
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	text-align: right;
	margin: 0;
}

.ov-card--vote-occasion .oview-vote__row .oview-vote__track {
	height: 2.2rem;
	border-radius: var(--radius-s);
	background: var(--color-track-soft);
	overflow: hidden;
	display: block;
}

.ov-card--vote-occasion .oview-vote__row .oview-vote__fill {
	display: block;
	height: 100%;
	border-radius: var(--radius-s);
	width: var(--sample-w-season);
	background: var(--color-accent);
}

.ov-card--vote-performance .oview-vote__meter .oview-vote__track {
	grid-column: 1 / -1;
	height: var(--space-m);
	border-radius: var(--radius-full);
	background: var(--color-track);
	overflow: hidden;
	margin-bottom: var(--space-m);
}

.ov-card--vote-performance .oview-vote__meter .oview-vote__fill {
	height: 100%;
	border-radius: var(--radius-full);
	width: var(--sample-w-perf);
	background: var(--color-success);
}

.ov-card--vote-performance .oview-vote__step:hover {
	border-color: var(--color-border-strong);
	color: var(--color-text);
}

.ov-card--vote-performance .oview-vote__row .oview-vote__track {
	height: 2.2rem;
	border-radius: var(--radius-s);
	background: var(--color-track-soft);
	overflow: hidden;
	display: block;
}

.ov-card--vote-performance .oview-vote__row .oview-vote__fill {
	display: block;
	height: 100%;
	border-radius: var(--radius-s);
	width: var(--sample-w-season);
	background: var(--color-accent);
}

.ov-rating .oview-vote__options {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: var(--space-2xs);
}

.ov-rating .oview-vote__star {
	width: var(--control-h);
	height: var(--control-h);
	min-width: var(--tap-min);
	min-height: var(--tap-min);
	border-radius: var(--radius-m);
	cursor: pointer;
	font-size: var(--text-l);
	line-height: 1;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	font-family: var(--font-sans);
	background: var(--color-star-off);
	color: var(--color-star-glyph-off);
	transition: transform 0.12s ease;
}

.ov-rating .oview-vote__star:hover {
	color: var(--color-on-accent);
	background: var(--color-yellow);
	transform: scale(1.08);
}

.oview-vote__mine {
	font-size: var(--text-m);
	font-weight: 600;
	color: var(--color-text-muted);
	margin: 0;
}

@container (max-width: 30rem) {
	.oview-vote__row {
		grid-template-columns: 5.6rem minmax(3rem, 1fr) 4.6rem;
		gap: var(--space-s);
	}

	.ov-card--vote-occasion .oview-vote__row {
		grid-template-columns: 5.6rem minmax(3rem, 1fr) 4.6rem;
		gap: var(--space-s);
	}
}

/*
 * ⚠️ A MARK THAT IS NOT A CONTROL MUST NOT ANSWER THE MOUSE.
 *
 * The dashboard draws `oview-vote__star` to SHOW a score, and the star carries
 * a hover and a focus state because on a fragrance page it is a button. Left
 * alone the read-only version lit up and scaled under the cursor, which is a
 * page promising something it will not do - and the promise is the part that
 * misleads, not the click that never happens.
 */
.oview-vote--static .oview-vote__star,
.oview-vote--static {
	pointer-events: none;
	cursor: default;
}

/*
 * The viewer's own answer takes its metric's colour, which is what
 * `.oview-vote__mine` already does on the fragrance page. Here the answer sits
 * in the value slot, so the same three colours land there instead: reading
 * "Eternal" in the green of the bar beside it makes three rows scan as three
 * measurements rather than as a table of words.
 */
.oview-vote--row .oview-vote__meter[data-metric="longevity"] .oview-vote__meter-value {
	color: var(--color-success);
}

.oview-vote--row .oview-vote__meter[data-metric="sillage"] .oview-vote__meter-value {
	color: var(--color-tier-mid);
}

.oview-vote--row .oview-vote__meter[data-metric="price_value"] .oview-vote__meter-value {
	color: var(--color-warning);
}
