/**
 * Quizpio Pro — host leaderboard ranking-transition animation.
 *
 * One colour language across both motion modes: gained rank = green,
 * dropped = grey. The wash is always a one-shot class tied to the moment of
 * change — never a persistent element — so rows stay exactly the core
 * markup. Full motion: the wash rides the row's slide (core's own
 * `transition: transform 0.3s ease` drives the movement) and decays as the
 * row lands. Reduced motion: no movement; the same wash, held longer.
 *
 * Keyframes end unset so every row decays to its own resting background
 * (including the gold/silver/bronze rank tints) automatically.
 */

.quizpio-mount .qp-sidebar-row.qp-pro-moving {
	position: relative;
	z-index: 2;
}

/* Full motion — wash rides the slide. */
.quizpio-mount .qp-sidebar-row.qp-wash-up {
	animation: qp-pro-wash-up 0.65s ease;
}

.quizpio-mount .qp-sidebar-row.qp-wash-down {
	animation: qp-pro-wash-down 0.65s ease;
}

/* Reduced motion — same wash on an instant reorder, held longer. */
.quizpio-mount .qp-sidebar-row.qp-flash-up {
	animation: qp-pro-wash-up 1.15s ease;
}

.quizpio-mount .qp-sidebar-row.qp-flash-down {
	animation: qp-pro-wash-down 1.15s ease;
}

@keyframes qp-pro-wash-up {
	0% {
		background: #dcfce7;
		border-color: #86efac;
	}

	100% {}
}

@keyframes qp-pro-wash-down {
	0% {
		background: #f3f4f6;
		border-color: #e5e7eb;
	}

	100% {}
}

/*
 * The OS setting always wins: the Pro script never applies transforms under
 * reduced motion, and this block additionally disables core's row transition
 * so no positional animation can occur from any source.
 */
@media ( prefers-reduced-motion: reduce ) {
	.quizpio-mount .qp-sidebar-row {
		transition: none !important;
	}
}

/* ==== P10 — the streak badge (host sidebar) ==== */

/* The row grid gains a fifth column only when a badge is present — the
   class is set by Pro's decorator, so no :has() dependency. The badge is
   the row's LAST child in the DOM; `order` places it before the score. */
.quizpio-mount .qp-sidebar-row.qp-pro-has-streak {
	grid-template-columns: 24px 1.75rem 1fr auto auto;
}

.quizpio-mount .qp-sidebar-row.qp-pro-has-streak .qp-sidebar-score {
	order: 2;
}

/* ★ P29 — the player's certificate button sits ABOVE core's "Play another quiz".
   Core's .qp-final-actions is a flex column (frontend.css:542#display @A56), so
   `order` places Pro's appended button first without Pro touching core's DOM.
   Core's own buttons carry no explicit order (default 0), so a negative value
   lifts Pro's above them and nothing else moves.
   ★ THIS IS A DECLARED CROSS-LAYER CSS COUPLING — §3 C24, row 2. Pro now depends
   on that container being flex and on core's buttons having no order set. It is
   in b3-manual-reverify.md and re-walked at every core re-pin. It was added ON
   PURPOSE, after the fourteen existing couplings were finally written down —
   not by accident, which is how the first fourteen happened. */
.quizpio-mount .qp-final-actions .qp-pro-cert-mine {
	order: -1;
}

.quizpio-mount .qp-pro-streak {
	order: 1;
	display: inline-flex;
	align-items: center;
	gap: 3px;
	background: #fcd34d;
	color: #78350f;
	font-size: 11px;
	font-weight: 800;
	padding: 2px 7px 2px 5px;
	border-radius: 9px;
	line-height: 1.4;
	animation: qp-pro-badge-in 0.4s ease;
}

.quizpio-mount .qp-pro-streak svg {
	display: block;
}

@keyframes qp-pro-badge-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.quizpio-mount .qp-pro-streak {
		animation: none;
	}
}

/* ---------- Question images (P11) ----------
   One image above the question text, everywhere the core slot fires.
   Contain (never crop — the answer might live in the cropped part),
   height-capped so the options stay reachable, centered, letterboxed
   on a soft background when the ratio differs from the frame. */
.quizpio-mount .qp-pro-qmedia {
	display: block;
	max-width: 100%;
	max-height: 225px;
	margin: 0 auto 16px;
	object-fit: contain;
	border: 1px solid #e5e7eb;
	border-radius: 10px;
	background: #f9fafb;
}

@media ( max-width: 600px ) {
	.quizpio-mount .qp-pro-qmedia {
		max-height: 145px;
	}
}

/* ---------- Option images (P13) ----------
   One element, context-styled.

   BASE = the 26px thumbnail: what reveal-bar labels always show, and what
   answer buttons show in browsers without :has() support (the progressive
   fallback — same picture, humbler frame, zero breakage).

   CARD = inside an answer button, modern browsers reflow the whole button
   via :has(): image on top, letter + text in the row beneath. Grid areas,
   not column-flex, because core's DOM order is letter / image / text.

   Contain everywhere — at any size, the answer may live in the part a
   crop would remove. */
.quizpio-mount .qp-pro-omedia {
	width: 26px;
	height: 26px;
	border-radius: 5px;
	border: 1px solid #e5e7eb;
	background: #f9fafb;
	object-fit: contain;
	flex: 0 0 auto;
}

.quizpio-mount .qp-options .qp-option:has( .qp-pro-omedia ) {
	display: grid;
	grid-template-columns: auto 1fr;
	grid-template-areas:
		'img  img'
		'shape text';
	align-items: center;
	padding: 0;
	overflow: hidden;
	gap: 0;
}

.quizpio-mount .qp-options .qp-option:has( .qp-pro-omedia ) .qp-pro-omedia {
	grid-area: img;
	width: 100%;
	height: 120px;
	border: 0;
	border-radius: 0;
	border-bottom: 1px solid #e5e7eb;
}

.quizpio-mount .qp-options .qp-option:has( .qp-pro-omedia ) .qp-shape {
	grid-area: shape;
	margin: 11px 10px 11px 14px;
}

.quizpio-mount .qp-options .qp-option:has( .qp-pro-omedia ) .qp-opt-text {
	grid-area: text;
	padding: 11px 14px 11px 0;
}

@media ( max-width: 600px ) {
	.quizpio-mount .qp-options .qp-option:has( .qp-pro-omedia ) .qp-pro-omedia {
		height: 96px;
	}
}

/* ============================================================
   P23 — the seam consumers.
   ============================================================ */

/* The 2× Points tag (quizpio.question.tags). Core's poll-tag GEOMETRY, so
   the heading's rhythm is unbroken — but Pro's amber, so it reads as Pro's
   own and can never be mistaken for core's indigo chrome. It speaks the same
   visual language as the streak pill, which is the point: both are Pro
   telling you about points. */
.quizpio-mount .qp-pro-double-tag {
	display: inline-block;
	vertical-align: 4px;
	margin-left: 10px;
	font-size: 12px;
	font-weight: 800;
	background: #fef3c7;
	color: #92400e;
	border: 1px solid #fcd34d;
	padding: 2px 10px;
	border-radius: 999px;
	letter-spacing: 0.2px;
	white-space: nowrap;
}

/* The host's projected screens carry the question at 28px; the tag scales
   with it or it disappears from the back of a classroom. */
.quizpio-mount .qp-host-question .qp-pro-double-tag,
.quizpio-mount .qp-host-reveal .qp-pro-double-tag {
	font-size: 15px;
	padding: 3px 13px;
	vertical-align: 6px;
}

/* The player's own streak line (core A55 renders it; the class is core's and
   core has promised not to reach into it). Amber, so the note and the flame
   are visibly the same feature speaking. It is a SUB-LINE of the feedback
   banner it explains — no border, no background, nothing that would make it
   read as a second banner (composition rule, Collision 4).

   The measure is deliberate: side padding keeps it off the edges of a 330px
   phone at any bonus number, and the max-width stops it stretching toward a
   900px line on a desktop, where core gives the player 912px of content. */
.quizpio-mount .qp-reveal-note {
	max-width: 42rem;
	margin: -8px auto 16px;
	padding: 0 14px;
	box-sizing: border-box;
	color: #b45309;
	font-size: 13.5px;
	font-weight: 700;
	line-height: 1.45;
	text-align: center;
}

/* Streak flames on the SHARED standings (quizpio.leaderboard.rows).
   The same mechanism the host sidebar has shipped since P10: the filter hands
   us a rendered row, so the badge can only be APPENDED (last child in the
   DOM), and `order` is the only way to place it — before the score. The row
   class is set by Pro's decorator, so no :has() dependency. */
.quizpio-mount .qp-lb-row.qp-pro-has-streak {
	grid-template-columns: 28px 1fr auto auto;
}

.quizpio-mount .qp-lb-row.qp-pro-has-streak .qp-lb-score {
	order: 2;
}

/* OI-13 — the join-screen certificate hint.
   Sizing follows CORE'S OWN subdued-helper pattern, .qp-lobby-help
   (frontend.css:449 @A84 — 13px, muted), rather than a new invention.
   Colour is core's --qp-muted TOKEN (frontend.css:1119 @A84), never a retyped
   hex: if core restyles, Pro follows. Same reasoning as qp-btn-primary at P30.

   margin -4px: core's .qp-join input carries margin-bottom 12px and Pro must
   not touch it, so the negative pull is the honest way to reach 8px above /
   16px below. The asymmetry ties the hint to the field it describes instead of
   letting it float midway to the button.

   display:flex is NOT decoration. With an inline icon a wrapped translation
   runs its second line back underneath the icon and the block loses its left
   edge. English never wraps, so this would have shipped invisible and surfaced
   only in a translated locale; the German panel in the approved mockup is what
   caught it.

   The icon is drawn in CSS rather than as an inline SVG because it is geometry
   plus a font glyph — a circle and a letter — not a shape CSS cannot draw.
   Pro's streak flame IS an SVG (pro-frontend.js) because a flame silhouette
   has no CSS expression. That is the dividing line, and it is the rule.
   Trade accepted knowingly: generated content is announced by some screen
   readers. The sentence carries the whole meaning, so an announced "i" is
   noise, not a barrier. */
.quizpio-mount .qp-pro-join-hint {
	display: flex;
	align-items: flex-start;
	margin: -4px 0 16px;
	font-size: 13px;
	line-height: 1.45;
	color: var( --qp-muted );
}

.quizpio-mount .qp-pro-join-hint::before {
	content: 'i';
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 14px;
	height: 14px;
	margin-inline-end: 7px;
	margin-top: 1px;
	border: 1px solid currentColor;
	border-radius: 50%;
	font-size: 9px;
	font-weight: 700;
	font-style: italic;
	line-height: 1;
}
