/*
 * Vote cards.
 *
 * Every value here is a design token. Structural only: nothing about colour,
 * size or spacing is invented in this file, so a theme-style change moves the
 * vote card with everything else.
 *
 * ⚠️ Classes, never element settings. A Bricks style control emits as
 * `#brxe-{id}

`, which is ID specificity - it cannot be overridden by this file
 * OR by the next person editing the card in the builder. That is what made the
 * card grid unstylable until it moved to a class (rules/design.md).
 */

.oview-vote {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	align-items: flex-start;
}

.oview-vote__label {
	font-family: var(--label-font);
	font-size: var(--label-size);
	font-weight: var(--label-weight);
	letter-spacing: var(--label-tracking);
	text-transform: var(--label-case);
	color: var(--label-color);
}

.oview-vote__options {
	display: flex;
	gap: var(--space-2xs);
	align-items: center;
}

/*
 * ⚠️ 28px, and the floor is not arbitrary. check-mobile.js fails anything
 * interactive under 24px, which is WCAG 2.5.8, and a five-star row is the
 * classic place that gets missed because the glyph looks big enough while its
 * box is not.
 */
.oview-vote__star {
	display: grid;
	place-items: center;
	/* A tile, the look fragrance's rating has, as every site's default (D222):
	   bare glyphs read as unstyled on the first site that did not restyle them. */
	inline-size: max(var(--vote-star-size, 4rem), var(--tap-min));
	block-size: max(var(--vote-star-size, 4rem), var(--tap-min));
	/* A narrow card squeezed five stars to 23px, under the 24px tap target. */
	flex-shrink: 0;
	border-radius: var(--vote-choice-radius);
	cursor: pointer;
	font-size: var(--text-l);
	line-height: 1;
	color: var(--color-star-glyph-off);
	background: var(--color-star-off);
	transition: color 120ms ease, background-color 120ms ease, transform 120ms ease;
	-webkit-user-select: none;
	user-select: none;
}

/*
 * The glyph is drawn here rather than put in the element's text.
 *
 * ⚠️ Content in the tree would be five literal stars a builder edit could
 * change to four, or to something that is not a star at all, with nothing to
 * notice. The number of stars is the DECLARATION's to decide - it is
 * `VoteSpec::values()` - so the element carries the value and CSS carries the
 * shape.
 */
.oview-vote__star::before {
	content: "\2605";
}

.oview-vote__star:hover,
.oview-vote__star:focus-visible {
	color: var(--color-on-rating);
	background: var(--color-rating);
	transform: scale(1.08);
}

.oview-vote__star:focus-visible {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

/*
 * Filled up to and including the hovered or chosen one.
 *
 * `--fill` is set by votes.js on the group, so the whole row restyles with one
 * property change rather than five class writes - and a hover that leaves the
 * row restores the chosen state by clearing one value.
 */
.oview-vote__star[data-fill="on"] {
	color: var(--color-on-rating);
	background: var(--color-rating);
}

.oview-vote__readout {
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	min-block-size: 1.6em;
}

/*
 * While a vote is in flight.
 *
 * ⚠️ The row is NOT disabled and the stars do not empty. The click already
 * showed the new state optimistically; taking it away for the length of a round
 * trip reads as the click having failed, and putting it back reads as a bug.
 */
.oview-vote[data-busy] .oview-vote__options {
	opacity: 0.6;
	pointer-events: none;
}

.oview-vote__error {
	font-size: var(--text-xs);
	/*
	 * ⚠️ `--color-error`, WHICH THIS SITE ACTUALLY DEFINES. `--color-danger`
	 * is defined by nobody, so every vote error on this site has been that
	 * hard-coded red and no palette could ever have reached it. Found by the
	 * token gate the day it stopped skipping anything with a fallback.
	 */
	color: var(--color-error, #b3261e);
}

/*
 * The sign-in prompt, in place.
 *
 * ⚠️ Never a redirect to wp-login.php. Sending someone away mid-click loses the
 * vote, the scroll position and the page, and returns them to a screen that
 * looks nothing like the site.
 */
.oview-vote__signin {
	font-size: var(--text-xs);
}

/* --------------------------------------------------------------------------
 * bars - several metrics, each a yes you can toggle
 *
 * The whole row is the control, not a checkbox beside it. A row is a wide,
 * obvious target and it means the label, the count and the bar all respond
 * together rather than one small square doing the work.
 * -------------------------------------------------------------------------- */

.oview-vote__rows,
.oview-vote__meters {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	inline-size: 100%;
}

.oview-vote__row {
	display: grid;
	grid-template-columns: minmax(6rem, 8rem) minmax(4rem, auto) 1fr;
	align-items: center;
	gap: var(--space-s);
	padding: var(--space-2xs) var(--space-xs);
	border-radius: var(--radius-s);
	cursor: pointer;
	/* ⚠️ 24px is the WCAG 2.5.8 floor check-mobile.js enforces. A row is taller
	   than this in practice; the minimum is here so a density change cannot
	   quietly drop it under. */
	min-block-size: 2.8rem;
	transition: background-color 120ms ease;
}

.oview-vote__row:hover,
.oview-vote__row:focus-visible {
	background: var(--color-surface-sunk);
}

.oview-vote__row:focus-visible,
.oview-vote__button:focus-visible,
.oview-vote__step:focus-visible {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

.oview-vote__row-label {
	font-size: var(--text-xs);
}

.oview-vote__row-count {
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.oview-vote__track {
	block-size: 0.6rem;
	inline-size: 100%;
	border-radius: var(--radius-full);
	background: var(--color-surface-sunk);
	overflow: hidden;
}

.oview-vote__fill {
	block-size: 100%;
	border-radius: var(--radius-full);
	background: var(--color-border-strong);
	transition: width 200ms ease, background-color 120ms ease;
}

/*
 * Your own answer, on top of everyone else's.
 *
 * ⚠️ The bar keeps showing the crowd and only the ROW changes. Filling the bar
 * to show your vote would overwrite the one number on the row that is not about
 * you, and there would be nothing left saying what everybody else thought.
 */
/*
 * ⚠️ A ROW YOU VOTED ON HAS TO SAY SO, and a bar that got longer does not.
 *
 * Clicking a season grew its pill and moved its number, both of which are the
 * aggregate changing and neither of which is about you. With six rows sharing
 * one look there was no way to see which one you had picked, so the only
 * feedback for having voted was a number you did not know the old value of.
 *
 * A lifted surface and a bolder label are the state; the check is the
 * confirmation. Both survive a site that styles nothing, and neither is a
 * colour, which is what 1.4.1 asks of a state worth reading.
 *
 * ⚠️ NO RING HERE. A 2px inset border is a look, it names the accent, and the
 * accent is a decision a site makes. It also drew a second rectangle inside a
 * card already made of rectangles and read as a focus ring on something that
 * was not focused. A site that wants one adds it; the floor does not need it.
 */
.oview-vote__row[aria-checked="true"] {
	background: var(--color-surface-sunk);
}

.oview-vote__row[aria-checked="true"] .oview-vote__row-label {
	font-weight: 700;
}

/*
 * ⚠️ AFTER THE NUMBER, NOT AFTER THE LABEL.
 *
 * Between the word and the bar it sat in the middle of the row, pushed the bar
 * along by a character, and made the labels of voted and unvoted rows fail to
 * line up. At the end it is a column of its own that is empty until you vote.
 *
 * ⚠️ A mark rather than a colour alone, because 1.4.1 says colour is never the
 * only carrier of information, and six coloured bars where one is "yours" is
 * exactly that.
 */
.oview-vote__row-count::after {
	content: "✓";
	margin-inline-start: var(--space-2xs);
	font-weight: 700;
	/* Present but invisible, so the number does not shift when you vote. */
	visibility: hidden;
}

.oview-vote__row[aria-checked="true"] .oview-vote__row-count::after {
	visibility: visible;
}

/*
 * ⚠️ A PREVIEWED ANSWER IS NOT AN ANSWER, and has to look like it is not.
 *
 * `votes.js` lets the caption follow the pointer so the stars and the word
 * beside them agree. That is only honest while the two states are told apart,
 * so the platform makes the preview quieter here rather than trusting every
 * site to remember. A site may restyle it; it should not have to invent it.
 */
.oview-vote__mine[data-preview] {
	opacity: 0.6;
}

.oview-vote__row:not([aria-checked="true"]):hover {
	background: var(--color-surface-sunk);
}

.oview-vote__row[aria-checked="true"] .oview-vote__fill,
.oview-vote__meter[data-mine] .oview-vote__fill {
	background: var(--color-accent);
}

/* --------------------------------------------------------------------------
 * buttons - one answer out of a few
 * -------------------------------------------------------------------------- */

/*
 * ⚠️ AN ICON IS DECORATION AND TAKES NO SPACE FROM THE LABEL.
 *
 * Structure only: a size that clears nothing, a shrink-guard so a long label
 * cannot squeeze it to a sliver, and the alignment that puts it beside words
 * rather than above them. What it looks like is the site's.
 */
.oview-vote__meter-icon {
	grid-area: icon;
}

.oview-vote__meter:has(.oview-vote__meter-icon) {
	grid-template-columns: auto 1fr auto;
	grid-template-areas: "icon label value" "track track track" "steps steps steps";
}

.oview-vote__button-icon,
.oview-vote__row-icon,
.oview-vote__meter-icon {
	flex: 0 0 auto;
	inline-size: 1.8rem;
	block-size: 1.8rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
}

.oview-vote__button-label {
	min-inline-size: 0;
}

/*
 * A choice's icon sits on a small tinted chip (D222), the look fragrance's
 * collection card has, so every site's choice card starts from it rather
 * than from a bare glyph beside a word. A site can colour each option its
 * own way; this is the floor.
 */
/*
 * ⚠️ CONCENTRIC, OR IT LOOKS DROPPED IN. A 6px square chip in a round pill
 * sat 6px from the top and 12px from the start, and its corners fought the
 * pill's. The pill pads its icon side by the inset on three sides, and the
 * chip's radius is the pill's minus that inset. The pill's side of it sits
 * with the button's own rules below, at one class, so a site's still wins.
 */
.oview-vote__button-icon {
	inline-size: var(--vote-chip-size);
	block-size: var(--vote-chip-size);
	border-radius: max(0px, calc(var(--vote-choice-radius) - var(--vote-chip-inset)));
	background: var(--color-accent-soft);
	color: var(--color-on-accent-soft);
	font-weight: 700;
}

/*
 * EACH OPTION ITS OWN COLOUR (D222), by position: the first declared option
 * takes `--color-choice-a`, and so on. Owning, wanting and having owned are
 * different answers, and a reader sees the colour before the word. By
 * position rather than by metric name, because the platform names no
 * dataset's metrics; a site that wants it by name still can, as site one does.
 *
 * ⚠️ ON THE ROW, `.oview-vote__buttons`, not on the card. The account page's
 * collection tabs are the same row of the same buttons outside any vote card,
 * and keyed on the card they stayed grey while the title page's turned green.
 */
.oview-vote__buttons > .oview-vote__button { --ov-choice: var(--color-choice-c); }
.oview-vote__buttons > .oview-vote__button:nth-child(1) { --ov-choice: var(--color-choice-a); }
.oview-vote__buttons > .oview-vote__button:nth-child(2) { --ov-choice: var(--color-choice-b); }

.oview-vote__buttons .oview-vote__button-icon {
	background: color-mix(in srgb, var(--ov-choice) 18%, transparent);
	/* ⚠️ Not the colour itself: a green tick on a green tint measured 1.9:1
	   in light mode. Mixed with the text colour it darkens on a light page
	   and lightens on a dark one, and passes on both. */
	color: color-mix(in oklab, var(--ov-choice) 45%, var(--color-text));
}

.oview-vote__buttons > .oview-vote__button[aria-checked="true"] {
	border-color: var(--ov-choice);
	background: var(--ov-choice);
	color: var(--color-on-choice);
}

.oview-vote__buttons > .oview-vote__button[aria-checked="true"] * {
	color: inherit;
}

.oview-vote__buttons > .oview-vote__button[aria-checked="true"] .oview-vote__button-icon {
	background: color-mix(in srgb, var(--color-on-choice) 25%, transparent);
}

/*
 * ⚠️ A BUTTON IS A ROW OF PARTS, not a block of text, now that it holds an
 * icon, a label and a count as separate elements. Structure only: what they
 * look like beside each other is the site's.
 */
.oview-vote__button {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
}

.oview-vote__buttons {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

.oview-vote__button {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	min-block-size: var(--control-h-s);
	padding-inline: var(--control-px-s);
	border-radius: var(--vote-choice-radius);
	border: 1px solid var(--color-border);
	background: var(--color-surface);
	color: var(--color-text-body);
	font-size: var(--text-xs);
	cursor: pointer;
	transition: border-color 120ms ease, background-color 120ms ease;
}

/* With an icon, the chip's inset on three sides (see the chip above). */
.oview-vote__button:where(:has(> .oview-vote__button-icon)) {
	padding-block: var(--vote-chip-inset);
	padding-inline-start: var(--vote-chip-inset);
}

/*
 * ⚠️ IT RESTATES ITS COLOUR, and it has to once the control can be a LINK.
 *
 * A vote card draws these as `<div role="radio">` and a colour rule was never
 * needed. The account page's collection tabs are the same control worn by
 * anchors, and an anchor picks up a link colour from somewhere on hover the
 * moment nothing here says otherwise - the words went blue on a white pill and
 * would have gone blue on a green one.
 *
 * Saying the resting colour again is the smallest fix that does not depend on
 * finding, and keeping out of the way of, whatever paints links on a given
 * site.
 */
.oview-vote__button:not([aria-checked="true"]):hover {
	border-color: var(--color-border-strong);
	background: var(--color-surface-sunk);
	color: var(--color-text-body);
}

/* Chosen and hovered darkens rather than reverting, like a step does. */
.oview-vote__button[aria-checked="true"]:hover {
	filter: brightness(0.94);
}

.oview-vote__button[aria-checked="true"] {
	border-color: var(--color-accent);
	background: var(--color-accent);
	color: var(--color-surface);
}

/* --------------------------------------------------------------------------
 * meters - an average per metric, each on its own scale
 * -------------------------------------------------------------------------- */

.oview-vote__meter {
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-areas: "label value" "track track" "steps steps";
	align-items: center;
	gap: var(--space-2xs) var(--space-s);
}

.oview-vote__meter-label { grid-area: label; font-size: var(--text-xs); }
.oview-vote__meter-value { grid-area: value; font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.oview-vote__meter .oview-vote__track { grid-area: track; }
.oview-vote__steps { grid-area: steps; display: flex; gap: var(--space-2xs); }

/*
 * ⚠️ A step is 24px on the nose, which is the floor and not a coincidence.
 * Three meters of five steps is fifteen targets in a column, and they are the
 * densest interactive thing on the page - the first place a size reduction
 * would break 2.5.8 without looking like it had.
 */
.oview-vote__step {
	inline-size: 2.4rem;
	block-size: 2.4rem;
	border-radius: var(--radius-full);
	border: 1px solid var(--color-border);
	background: var(--color-surface);
	cursor: pointer;
	transition: background-color 120ms ease, border-color 120ms ease;
}

/*
 * ⚠️ A STEP THAT CARRIES WORDS CANNOT BE A CIRCLE.
 *
 * `values` may name each level - "Very weak" through "Eternal" - and a labelled
 * step is then a button with text in it rather than a 24px dot. It still has to
 * clear the 2.5.8 floor, which it does by a wide margin, and the row wraps
 * rather than squeezing them because five words do not fit on a phone in one
 * line.
 *
 * ⚠️ Structure only. What a labelled step LOOKS like is the site's, and
 * `oview-site-one` restyles these. Without something here it would render as
 * overflowing text in a circle, which is not a neutral default, it is a broken
 * one.
 */
/*
 * ⚠️ THE VIEWER'S OWN ANSWER REPLACES THE AVERAGE, it does not sit beside it.
 *
 * Both are one number in one corner and showing them together is two numbers
 * that look like a comparison and are not. Before anybody votes, the average is
 * the only thing worth saying; afterwards, their own answer is.
 *
 * `data-mine` is set by `votes.js` on the row or meter, so this is a state a
 * design can react to rather than a string a design has to test.
 */
.oview-vote__mine {
	display: none;
	grid-area: value;
	font-size: var(--text-xs);
	font-variant-numeric: tabular-nums;
	text-align: end;
	color: var(--color-accent-ink);
}

.oview-vote__meter[data-mine] .oview-vote__mine,
.oview-vote__row[data-mine] .oview-vote__mine {
	display: block;
}

.oview-vote__meter[data-mine] .oview-vote__meter-value {
	display: none;
}

/*
 * A stars card has one, and it sits BESIDE the stars rather than under them.
 *
 * ⚠️ The card is a column by default, which is right for a card whose parts
 * stack and wrong the moment one of them is a word attached to the row above
 * it. "Good" on its own line under five stars reads as a separate statement
 * rather than as what the third star means.
 */
.oview-vote--stars {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-s);
}

.oview-vote--stars .oview-vote__mine {
	grid-area: auto;
	align-self: center;
}

.oview-vote--stars .oview-vote__mine:not(:empty) {
	display: block;
	/* "Rate it", then the viewer's own answer: a word beside the row, not a
	   caption under it (D222, site one's look as the default). */
	font-size: var(--text-m);
	font-weight: 600;
	color: var(--color-text-muted);
}

/*
 * THE SCORED STAR ROW, every drawn rating's default (D222): the question on
 * its own line, then the crowd's score, a divider, the stars, and "Rate it".
 * Fragrance's layout, carried by the card so no site draws it again.
 *
 * ⚠️ `order`, not markup. The readout is also where "Sign in to vote" lands,
 * and it must stay the card's last child for votes.js to find it the same way
 * on every card; only where it SHOWS changes.
 */
.oview-vote--scored .oview-vote__label {
	order: -2;
	flex-basis: 100%;
}

.oview-vote--scored .oview-vote__readout {
	order: -1;
	flex-basis: 100%;
	min-block-size: 0;
	font-size: var(--text-m);
	font-weight: 600;
	color: var(--color-text);
}

@media (min-width: 768px) {
	.oview-vote--scored .oview-vote__readout {
		flex-basis: auto;
		padding-inline-end: var(--space-s);
		border-inline-end: 1px solid var(--color-border);
	}
}

.oview-vote__step--labelled {
	inline-size: auto;
	block-size: auto;
	min-block-size: 2.4rem;
	flex: 1 1 auto;
	padding: var(--space-2xs) var(--space-xs);
	border-radius: var(--radius-s);
	/*
	 * ⚠️ `--text-s`, not `--text-xs`. This is a control a person reads and
	 * taps, so it is body text and takes the 12px floor. `--text-xs` measured
	 * 11.5px on the first design that used it, which check-mobile.js fails and
	 * is right to.
	 */
	font-size: var(--text-xs);
	line-height: 1.3;
	text-align: center;
	white-space: normal;
}

.oview-vote__meter .oview-vote__steps {
	flex-wrap: wrap;
}

/*
 * ⚠️ HOVER AND CHOSEN MUST NOT LOOK THE SAME, and they did.
 *
 * One rule gave both the filled accent, so moving the pointer along a row of
 * steps looked exactly like the selection moving with it: hovering "Long" made
 * "Moderate" appear to lose your vote, and only leaving the row put it back.
 * The state was never lost. It was covered up by a hover that had borrowed its
 * appearance.
 *
 * Hover is now an INVITATION: the border darkens and the surface lifts, and
 * nothing about it resembles a filled control. Chosen stays chosen while the
 * pointer is anywhere else on the card.
 */
.oview-vote__step:hover {
	border-color: var(--color-border-strong);
	background: var(--color-surface-sunk);
}

/*
 * ⚠️ NO `data-fill` HERE. A step is chosen or it is not; only a star fills
 * cumulatively, and this selector is what drew the generic accent on the
 * buttons below the chosen one while the chosen one drew its metric's colour.
 */
.oview-vote__step[aria-checked="true"] {
	border-color: var(--color-accent);
	background: var(--color-accent);
	color: var(--color-surface);
}

/* Chosen and hovered at once darkens rather than reverting. */
.oview-vote__step[aria-checked="true"]:hover {
	border-color: var(--color-accent-hover);
	background: var(--color-accent-hover);
}
