.active-whiteboard {
	box-shadow: 0 0 15px 5px var(--primary);
}
.MJXp-display {
	display: inline-block !important;
	margin: 0 !important;
}
strong {
	font-weight: 600;
}
.blue-avatar {
	width: 50px;
	height: 50px;
	border-radius: 50%;
	background-color: var(--rgba-primary-1);
	margin: auto;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 25px;
	color: var(--rgba-primary);
}
.btn.hover {
	border-color: var(--primary-hover);
	color: #fff;
	background-color: var(--primary-hover);
}
@keyframes crazy {
	0% {transform: skew(-5deg) rotate(-5deg) scale(1);}
	25% {transform: skew(5deg) rotate(5deg) scale(1.05);}
	50% {transform: skew(-8deg) rotate(-8deg) scale(1.1);}
	75% {transform: skew(8deg) rotate(8deg) scale(1.05);}
	100% {transform: skew(-5deg) rotate(-5deg) scale(1);}
}
.chest-opening-a {
	animation: crazy 0.5s infinite;
}
.chest-opening-b {
	animation: crazy 0.2s infinite;
}
.btn-gray {
	background-color: var(--bs-gray-700) !important;
	color: white !important;
}
.chest-opening-c {
	animation: crazy 0.1s infinite;
}
@keyframes fade-out {
	0% { opacity: 1; }
	100% { opacity: 0; }
}
.trail-preview-segment {
	/* Particles are quite small by default (they are sized for the in-game
	   cursor trail). Scale them up so the shop/progress previews are clearly
	   visible. `scale` composes with any `transform` the trail classes set. */
	scale: 2;
	will-change: left, top, opacity;
	transition: opacity 0.15s ease-out;
}
.trail-preview {
	position: relative;
	overflow: visible;
	transition: 0.5s ease-in-out;
}
.chest-img {
	transition: transform 0.2s ease-in-out, filter 0.3s ease-in-out;
	position: relative;
	z-index: 2;
}
/* ===== Chest sheet + reward cards ===== */
/* Centre the chest sheet, float it slightly off the bottom edge and keep
   every corner rounded so it reads as a card rather than a drawer. */
#chestModal.offcanvas-bottom {
	left: 50%;
	right: auto;
	bottom: calc(env(safe-area-inset-bottom, 0px) + 22px);
	width: min(640px, calc(100vw - 24px));
	height: auto;
	border: 0;
	border-radius: 28px;
	background: var(--tt-surface, #fff);
	box-shadow: 0 -12px 40px rgba(17, 24, 39, 0.18), 0 24px 60px rgba(17, 24, 39, 0.25);
	transform: translate(-50%, calc(100% + 40px));
	overflow: visible;
}
#chestModal.offcanvas-bottom.showing,
#chestModal.offcanvas-bottom.show:not(.hiding) {
	transform: translate(-50%, 0);
}
#chestModal .offcanvas-body {
	padding-bottom: 20px;
}
#chestModal .btn-close {
	position: relative;
	z-index: 6;
}
/* The reward row hangs above the chest. It must stack over the chest image
   (z-index 2) and its glow/rays, otherwise the chest covers the prizes. */
.chest-cards {
	display: flex;
	justify-content: center;
	align-items: stretch;
	gap: 14px;
	z-index: 5;
	pointer-events: none;
}
.chest-cards .reward-item {
	min-width: 118px;
	max-width: 150px;
	flex: 1 1 0;
	pointer-events: auto;
}
@media (max-width: 480px) {
	.chest-cards { gap: 10px; }
	.chest-cards .reward-item { min-width: 102px; }
}
.chest-cards .reward-item .card {
	width: 100%;
	height: 100%;
}
.chest-cards .card {
	--rw-c: #cbd5e1;
	--rw-c-rgb: 203, 213, 225;
	position: relative;
	margin: 0;
	border-radius: 22px;
	border: 1.5px solid rgba(var(--rw-c-rgb), 0.55);
	background:
		radial-gradient(120% 70% at 50% -10%, rgba(var(--rw-c-rgb), 0.35), transparent 60%),
		linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(244, 247, 252, 0.98));
	box-shadow:
		0 18px 40px rgba(15, 23, 42, 0.28),
		0 0 0 1px rgba(255, 255, 255, 0.5) inset,
		0 0 28px rgba(var(--rw-c-rgb), 0.35);
	transition: transform 0.6s cubic-bezier(.34,1.56,.64,1), box-shadow 0.4s ease, border-color 0.4s ease;
	will-change: transform;
	overflow: hidden;
	white-space: normal;
}
.chest-cards .card::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: linear-gradient(115deg, transparent 25%, rgba(255,255,255,0.75) 50%, transparent 75%);
	background-size: 240% 100%;
	background-position: 200% 0;
	pointer-events: none;
	opacity: 0;
	z-index: 3;
}
.chest-cards .card.shine::before {
	opacity: 1;
	animation: chest-card-shine 1.1s ease-out forwards;
}
@keyframes chest-card-shine {
	0% { background-position: 200% 0; opacity: 1; }
	100% { background-position: -140% 0; opacity: 0; }
}
.chest-cards .card-body {
	position: relative;
	z-index: 2;
	padding: 14px 10px 12px;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	gap: 4px;
	white-space: normal;
}
/* Rarity palettes */
.chest-cards .card.rarity-common    { --rw-c: #94a3b8; --rw-c-rgb: 148, 163, 184; }
.chest-cards .card.rarity-uncommon  { --rw-c: #22c55e; --rw-c-rgb: 34, 197, 94; }
.chest-cards .card.rarity-rare      { --rw-c: #3b82f6; --rw-c-rgb: 59, 130, 246; }
.chest-cards .card.rarity-epic      { --rw-c: #a855f7; --rw-c-rgb: 168, 85, 247; }
.chest-cards .card.rarity-legendary { --rw-c: #f59e0b; --rw-c-rgb: 245, 158, 11; animation: legendary-glow 2s infinite alternate; }
@keyframes legendary-glow {
	from { box-shadow: 0 18px 40px rgba(15, 23, 42, 0.28), 0 0 22px rgba(245, 158, 11, 0.45); }
	to   { box-shadow: 0 18px 40px rgba(15, 23, 42, 0.28), 0 0 48px rgba(245, 158, 11, 0.85); }
}
/* Pieces */
.rw-badge {
	width: 54px;
	height: 54px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	font-size: 26px;
	color: #fff;
	margin-bottom: 4px;
	box-shadow: 0 10px 22px rgba(15, 23, 42, 0.22), 0 0 0 4px rgba(255, 255, 255, 0.6) inset;
}
.rw-badge-coins { background: linear-gradient(160deg, #fde68a, #f59e0b 60%, #d97706); }
.rw-badge-xp    { background: linear-gradient(160deg, #93c5fd, #3b82f6 60%, #1d4ed8); }
.rw-value {
	font-size: 26px;
	line-height: 1;
	font-weight: 900;
	letter-spacing: -0.02em;
	color: #0f172a;
}
.rw-label {
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: #64748b;
}
.rw-rarity {
	align-self: center;
	font-size: 9.5px;
	font-weight: 900;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #fff;
	background: var(--rw-c);
	padding: 3px 9px;
	border-radius: 999px;
	box-shadow: 0 4px 12px rgba(var(--rw-c-rgb), 0.45);
	margin-bottom: 2px;
}
.rw-preview {
	position: relative;
	width: 100%;
	height: 56px;
	border-radius: 14px;
	background: radial-gradient(circle at 50% 50%, rgba(var(--rw-c-rgb), 0.22), rgba(var(--rw-c-rgb), 0.05) 70%);
	box-shadow: 0 0 0 1px rgba(var(--rw-c-rgb), 0.25) inset;
	overflow: visible;
	display: grid;
	place-items: center;
}
.rw-preview .trail-preview {
	position: absolute;
	inset: 0;
}
.rw-preview-frame .rw-avatar {
	width: 40px;
	height: 40px;
	position: relative;
	z-index: 1;
}
.rw-preview-frame .rw-frame {
	position: absolute;
	inset: 0;
	margin: auto;
	width: 40px;
	height: 40px;
	transform: scale(1.6);
	z-index: 2;
}
.rw-name {
	margin-top: 4px;
	font-size: 14px;
	line-height: 1.15;
	font-weight: 800;
	color: #0f172a;
	text-align: center;
}
.rw-kind {
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: #64748b;
}
.rw-select {
	margin-top: 8px;
	border: 0;
	border-radius: 999px;
	padding: 7px 14px;
	font-size: 12.5px;
	font-weight: 800;
	color: #fff;
	background: linear-gradient(160deg, var(--rw-c), color-mix(in srgb, var(--rw-c) 70%, #000));
	box-shadow: 0 8px 18px rgba(var(--rw-c-rgb), 0.45);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	white-space: nowrap;
}
.rw-select:active { transform: scale(0.96); }
.rw-select.selected-item {
	background: linear-gradient(160deg, #22c55e, #15803d);
	box-shadow: 0 8px 18px rgba(34, 197, 94, 0.45);
}

/* ===== Enhanced crate / chest opening ===== */
.chest-stage-wrap {
	position: relative;
	display: inline-block;
}
/* soft radial glow that swells behind the chest */
.chest-glow {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 300px;
	height: 300px;
	transform: translate(-50%, -50%) scale(0.4);
	background: radial-gradient(circle, rgba(255, 214, 102, 0.6) 0%, rgba(255, 193, 7, 0.28) 38%, rgba(255, 193, 7, 0) 72%);
	border-radius: 50%;
	opacity: 0;
	pointer-events: none;
	z-index: 0;
	filter: blur(4px);
	transition: opacity 0.5s ease, transform 0.5s ease;
}
.chest-glow.show {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
	animation: chest-glow-pulse 1.8s ease-in-out infinite;
}
@keyframes chest-glow-pulse {
	0%, 100% { transform: translate(-50%, -50%) scale(0.92); }
	50% { transform: translate(-50%, -50%) scale(1.12); }
}
/* rotating light rays */
.chest-rays {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 540px;
	height: 540px;
	transform: translate(-50%, -50%);
	pointer-events: none;
	z-index: 0;
	opacity: 0;
	background: repeating-conic-gradient(
		rgba(255, 223, 128, 0.45) 0deg 7deg,
		rgba(255, 223, 128, 0) 7deg 22deg
	);
	-webkit-mask-image: radial-gradient(circle, black 0%, black 26%, transparent 70%);
	mask-image: radial-gradient(circle, black 0%, black 26%, transparent 70%);
	transition: opacity 0.4s ease;
	animation: chest-rays-spin 10s linear infinite;
}
.chest-rays.show { opacity: 1; }
@keyframes chest-rays-spin {
	to { transform: translate(-50%, -50%) rotate(360deg); }
}
/* beam of light shooting up from chest */
.chest-beam {
    position: absolute;
    left: 50%;
    bottom: 50%;
    width: 60px;
    height: 0;
    background: linear-gradient(to top, rgba(255, 255, 255, 0.8), transparent);
    transform: translateX(-50%);
    filter: blur(8px);
    z-index: 1;
    pointer-events: none;
    opacity: 0;
}
.chest-beam.active {
    animation: chest-beam-shoot 1.2s ease-out forwards;
}
@keyframes chest-beam-shoot {
    0% { height: 0; opacity: 0; width: 20px; }
    20% { height: 400px; opacity: 1; width: 100px; }
    100% { height: 600px; opacity: 0; width: 200px; }
}
/* confetti particles */
.chest-confetti {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 10px;
	height: 14px;
	border-radius: 2px;
	opacity: 0;
	pointer-events: none;
	z-index: 3;
	will-change: transform, opacity;
}
@keyframes chest-confetti-burst {
	0% { opacity: 1; transform: translate(-50%, -50%) rotate(0deg) scale(1); }
	100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)) scale(0.35); }
}
/* the chest "pop" when it finishes opening */
@keyframes chest-open-pop {
	0% { transform: scale(0.82); }
	20% { transform: scale(1.3); }
	40% { transform: scale(0.9); }
	60% { transform: scale(1.15); }
	80% { transform: scale(0.98); }
	100% { transform: scale(1.05); }
}
.chest-open-pop {
	animation: chest-open-pop 0.8s cubic-bezier(.175,.885,.32,1.275) forwards;
	filter: drop-shadow(0 0 30px rgba(255, 215, 0, 0.9)) brightness(1.1);
}

/* "Opened!" title flourish */
.opening-text {
	transition: transform 0.3s ease;
}
.opening-text.opened {
	background: linear-gradient(90deg, #ffb300, #ff7043, #ffb300);
	background-size: 200% auto;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	animation: opened-pop 0.6s cubic-bezier(.175,.885,.32,1.275), opened-sheen 2.5s linear infinite 0.6s;
}
/* Failure state: the chest stays shut and explains itself */
.opening-text.failed {
	color: var(--tt-muted, #8a93a6);
}
.chest-error {
	text-align: center;
	margin: 0 auto 12px;
	max-width: 420px;
}
.chest-error-text {
	margin: 0 0 10px;
	font-size: 14px;
	color: var(--tt-ink, inherit);
}
.chest-retry {
	border-radius: 999px;
	padding: 6px 18px;
	font-weight: 700;
}
@keyframes opened-pop {
	0% { transform: scale(0.4); opacity: 0; }
	60% { transform: scale(1.16); opacity: 1; }
	100% { transform: scale(1); }
}
@keyframes opened-sheen {
	to { background-position: 200% center; }
}
.MathJax_Display {
	display: inline !important;
}
.active-whiteboard .btn-primary {
	animation: pulse 1s infinite;
}
.pulse {
	animation: pulse 1s infinite;
}
/* While the advance button still reads "Skip" it is toggled to .skip-subtle
   (see practice/events.js switchToView) so it doesn't compete with the
   question for attention; the primary styling returns for "Continue". */
.button-footer .btn.btn-primary.light.skip-subtle {
	background: transparent;
	border-color: rgba(120, 130, 150, 0.25) !important;
	color: #93a0b5;
}
.button-footer .btn.btn-primary.light.skip-subtle:hover {
	background: var(--rgba-primary-1);
	border-color: var(--rgba-primary-1) !important;
	color: var(--primary);
}
html[data-theme="dark"] .button-footer .btn.btn-primary.light.skip-subtle {
	border-color: rgba(255, 255, 255, 0.14) !important;
	color: #7f8ba0;
}
.pulse-shadow {
	animation: pulse 1s infinite;
}
/* The Continue-ready footer pulse used to run the generic "pulse" keyframes,
   which animate box-shadow on a full-width position:fixed bar - a repaint of
   the whole bar every frame for 3s, exactly while the next card is animating
   in. Same look, but the ring lives on a pseudo-element and only opacity /
   transform move, so it stays on the compositor. */
.button-footer.pulse {
	/* .footer.fixed keeps its position: fixed !important; this only anchors
	   the ring on the rare non-fixed footer */
	position: relative;
	animation: ttFooterPulse 1s infinite;
}
.button-footer.pulse::before {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: inherit;
	box-shadow: 0 0 0 10px var(--primary);
	opacity: 0;
	pointer-events: none;
	animation: ttPulseRing 1s infinite;
}
@keyframes ttFooterPulse {
	0%, 100% { transform: scale(0.95); }
	70% { transform: scale(1); }
}
@keyframes ttPulseRing {
	0% { opacity: .9; transform: scale(.985); }
	70%, 100% { opacity: 0; transform: scale(1); }
}
/* Score / streak feedback - replaces jQuery UI effect("pulsate") / ("bounce") */
.tt-pulsate {
	animation: ttPulsate 1s ease-in-out;
}
@keyframes ttPulsate {
	0%, 20%, 40%, 60%, 80%, 100% { opacity: 1; }
	10%, 30%, 50%, 70%, 90% { opacity: 0; }
}
.tt-bounce {
	animation: ttBounce .6s ease-out;
}
@keyframes ttBounce {
	0%, 50%, 100% { transform: translateY(0); }
	25% { transform: translateY(-14px); }
	75% { transform: translateY(-7px); }
}
.pulsePlusTransform {
	animation: pulsePlusTransform 1s infinite;
}
@keyframes pulse {
	0% {
		transform: scale(0.95);
		box-shadow: 0 0 0 0 var(--primary);
	}
	70% {
		transform: scale(1);
		box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
	}
	100% {
		transform: scale(0.95);
		box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
	}
}
.rotating-text p {
	display: inline-flex;
	margin: 0;
	vertical-align: top;
}
.rotating-text .word {
	position: absolute;
	display: inline-flex;
	opacity: 0;
}
.word-length {
	display: inline-block;
	transition: 1s ease;
}
.word-container {
	position: relative;
}
.rotating-text .word .letter {
	transform-origin: center center 25px;
}
.rotating-text .word .letter.out {
	transform: rotateX(90deg);
	transition: 0.32s cubic-bezier(0.6, 0, 0.7, 0.2);
}
.rotating-text .word .letter.in {
	transition: 0.38s ease;
}
.rotating-text .word .letter.behind {
	transform: rotateX(-90deg);
}
@keyframes pulsePlusTransform {
	0% {
		transform: scale(0.95) translateY(16px) translateX(-50%);
		box-shadow: 0 0 0 0 var(--primary);
	}
	70% {
		transform: scale(1) translateY(16px) translateX(-50%);
		box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
	}
	100% {
		transform: scale(0.95) translateY(16px) translateX(-50%);
		box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
	}
}
.dropdown img, .name, .dropdown-toggle {
	cursor: pointer;
}
/* Practice-page toasts: toastr targets .notification-container here
   (full-width banner look). Scoped so this sheet, which the content dashboard
   and a few student pages also load, cannot restyle the dashboard toasts. */
.notification-container #toast-container div.toast {
	border-radius: 45px;
	margin-top: 10px;
}
.notification-container #toast-container {
	position: relative !important;
	width: 100% !important;
	top: 0 !important;
	left: 0 !important;
	z-index: 1000 !important;
	padding: 0 !important;
}
.notification-container #toast-container>.toast {
	width: 100% !important;
	max-width: 100% !important;
	margin: 0 0 10px 0 !important;
	border-radius: 0 !important;
	background-image: none!important;
	z-index: 55;
	pointer-events: all;
	box-shadow: none !important;
}
.notification-container {
	pointer-events: none;
	position: relative;
	width: 100%;
	z-index: 1000;
	display: block !important;
	overflow: visible !important;
}
.notification-container .toast-message {
	font-size: 1.2rem;
	font-weight: 600;
	padding-left: 45px;
}
.notification-container .toast.toast-error {
	background-color: #f75a5b;
	display: flex;
	align-items: center;
}
.notification-container .toast.toast-success {
	display: flex;
	align-items: center;
	background-color: #6fcf78;
}
.notification-container #toast-container > .toast-error::before {
	content: "00d";
	font-family: 'FontAwesome';
	display: inline-block;
	margin-right: 5px;
	position: absolute;
	margin-left: -35px;
	font-size: 32px;
	margin-top: 0px;
}
.notification-container #toast-container > .toast-success::before {
	content: "00c";
	font-family: 'FontAwesome';
	display: inline-block;
	margin-right: 5px;
	position: absolute;
	margin-left: -35px;
	font-size: 32px;
	margin-top: 0px;
}
.notification-container {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
}
.progress-level {
	font-size: 18px;
}
.chat-box-area {
	overflow: hidden !important;
}
.reward-item {
	display: flex !important;
	justify-content: center !important;
	min-height: 120px;
}
.shownAssignmentsDisplay .quest-item {
	touch-action: none;
}
.shownAssignmentsDisplay {
	position: fixed;
	/* Clear the iOS status bar / notch inside the app (app_safe_area.js sets
	   --app-safe-top on edge-to-edge shells; it is 0 everywhere else). */
	top: calc(var(--app-safe-top, 0px) + 8px);
	z-index: 100000;
	pointer-events: none;
}
.progress-bar {
	transition: width 1s ease-in-out;
}
.shownAssignmentsDisplay .quest-item {
	box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px;
	pointer-events: all;
}
.shownAssignmentsDisplay .quest-item.pulse {
	animation: pulse-shadow 1s infinite !important;
}
@keyframes pulse-shadow {
	0% {
		transform: scale(0.95);
		box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px, 0 0 0 0 var(--primary);
	}
	70% {
		transform: scale(1);
		box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px, 0 0 0 10px rgba(0, 0, 0, 0);
	}
	100% {
		transform: scale(0.95);
		box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px, 0 0 0 0 rgba(0, 0, 0, 0);
	}
}
#preloader .spinner {
	border-top-color: #008CFF !important;
}
.tag {
	font-weight: 900;
	padding: 3px 10px 3px 10px;
	border-radius: 13px;
}
.tag.tag-gold {
	color: #ff4d00;
	background-color: #ff4d0036;
}
.tag.tag-green {
	color: #00ff4d;
	background-color: #00ff4d36;
}
.tag.tag-blue {
	color: #008CFF;
	background-color: #008CFF36;
}
.modal.show ~ header {
	transform: translateY(-150px) !important;
}
header {
	transition: all 0.3s ease-in-out;
}
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
	background: #ddd;
}
.select2-container--default .select2-results>.select2-results__options {
	max-height: 300px !important;
}
.input-group > :not(:first-child) {
	padding: 0 !important;
}
.continue-btn {
	opacity: 0.5;
}
.serach-area {
	margin-top: 15px;
}
.filter-area {
	margin-top: 5px !important;
}
.filter-area #qrcode img {
	margin: auto;
}
@media (max-width: 767px) {
	.filter-area #qrcode img {
		height: 250px;
		margin-bottom: 20px;
	}
}
@media (min-width: 768px) {
	.filter-area #qrcode img {
		transform: scale(1.2);
	}
}
.continue-btn:hover {
	opacity: 1;
}
/* .device-avatar sizing comes from main.css - the old 35px + scale(1.5)
   rules here fought the new XP-capsule header and blew the avatar up over
   the level badge. */
.filter-item {
	height: 50px; max-width: 50px; object-fit: contain;
}
.item-image {
	height: 120px; width: 120px; max-width: 120px;
}
.select2-container--default .select2-selection--multiple {
	min-height: 48px;
	padding: 0.375rem 2.25rem 0.375rem 0.75rem;
	-moz-padding-start: calc(0.75rem - 3px);
	font-size: 0.875rem;
	font-weight: 500;
	line-height: 1.6;
	color: #7e7e7e;
	background-color: #f6f6f6;
	background-repeat: no-repeat;
	background-position: right 0.75rem center;
	background-size: 16px 12px;
	border: 1px solid #ced4da;
	border-radius: 0.25rem;
	transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
	appearance: none;
}
.jsgif {
	transform: translateY(4px);
}
.delete-course {
	z-index: 70;
}
.dot {
	height: 10px;
	width: 10px;
	min-width: 10px;
	min-height: 10px;
	background-color: #2196f3;
	border-radius: 50%;
	display: inline-block;
	position: absolute;
	margin-left: 60px;
}
.needs-blue-outline:after {
	content: '';
	position: absolute;
	top: -3px;
	right: -3px;
	bottom: -3px;
	left: -3px;
	border: 3px solid var(--rgba-primary-3);
	border-radius: 11px;
}
/* Anchor the outline ring to the level badge itself - without this the
   absolutely-positioned :after stretches over the whole progression
   wrapper (blue rectangle around the XP pill and avatar). */
.progression-wrapper .dz-icon.needs-blue-outline {
	position: relative;
}
.progression-wrapper .dz-icon.needs-blue-outline:after {
	border-radius: 50%;
}
.skip-item {
	/* Revert dimmed appearance – keep skip items fully visible */
	opacity: 1;
}
.skip-item:hover {
	/* Maintain consistent look on hover */
	opacity: 1;
}
.needs-gray-outline:after {
	content: '';
	position: absolute;
	top: -3px;
	right: -3px;
	bottom: -3px;
	left: -3px;
	border: 3px solid rgba(73, 80, 87, 0.5);
	border-radius: 11px;
}
.pulse a {
	animation: pulse_3_times 1s infinite;
}
@keyframes pulse_3_times {
	0% { transform: scale(1); }
	50% { transform: scale(1.1); }
	100% { transform: scale(1); }
}
.recent-jobs-list ul li .item-content .item-inner {
	margin: auto;
}
.head-details {
	background: var(--gradient);
}
/* Only while practice content is actually on the page: this stylesheet stays
   loaded after practice is htmx-swapped out of #page-root, and an unscoped
   html/body height cap leaves the swapped-in learn/course page unscrollable. */
html:has(.practice-canvas), body:has(.practice-canvas) {
	width: 100vw;
	height: 100vh;
	overscroll-behavior: none;
}
.recent-jobs-list ul li .item-content {
	padding-left: 15px !important;
	padding-right: 15px !important;
}
.item-list
.skill-bar .dz-icon {
	transform: scale(2);
	transform-origin: right;
}
.bg-white .skill-bar {
	background-color: white;
}
.btn-outline-primary:hover {
	color: #fff;
}
.btn-outline-primary:active {
	color: #fff;
}
.btn-outline-primary {
	background-color: white;
}
.dz-list > ul > li .item-link:after {
	transform: translateY(-50%) scale(2);
	transform-origin: left;
}
.tapAway {
	cursor: pointer;
}
/* Practice only: on any other page that loads this sheet (/shop, /progress)
   a .page-content with overflow set becomes a scroll container, and contain
   then stops touch scrolls chaining to the page. */
body:has(.practice-canvas) .page-content {
	overscroll-behavior: contain;
}

/* Keep the bottom action bar visible at all times with a card background */
.button-footer.footer.fixed {
	position: fixed !important;
	width: 100%;
	left: 0;
	bottom: 0;
	z-index: 999;
	background-color: var(--bg-white);
	border-top: 1px solid var(--border-color);
	box-shadow: 0 -8px 12px 0 rgba(0, 0, 0, 0.03);
}
/* Reserve space so the fixed bar doesn't cover the page content */
body:has(.button-footer.footer.fixed) .page-content {
	padding-bottom: 120px;
}
#whiteboard ol li {
	list-style: auto;
	display: list-item;
	overflow: visible;
	margin-left: 1em;
	font-size: 1.2rem !important;
	opacity: 1;
	padding-top: 10px;
	padding-bottom: 10px;
	padding-left: 20px;
	padding-right: 20px;
}
.dz-lightgallery img {
	height: 196px;
	object-fit: contain;
	object-position: center;
	width: 100%;
}
.recent-jobs-list ul li .item-content .item-inner .item-title-row{
	margin-bottom: 0px;
}
#whiteboard ul li {
	list-style: auto;
	display: list-item;
	overflow: visible;
	margin-left: 1em;
	font-size: 1.2rem !important;
	opacity: 1;
	padding-top: 10px;
	padding-bottom: 10px;
	padding-left: 20px;
	padding-right: 20px;
}
.freq-card .select2-selection {
	padding-left: 0 !important;
	padding-right: 0 !important;
	display: flex;
}
.freq-card .select2 {
	text-align: center;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
	margin: 2px !important;
}
.content-toolkit {
	position: absolute;
	top: 0;
	left: 0;
}
body {
	overflow-x: hidden !important;
}
.flagged-for-review {
	transform: scale(1);
}
li:has(>.dd-option-selected) {
	display: none;
}
.flagging {
	padding-top: 20px;
}
.flagging li {
	transition: transform 0.2s ease-in-out;
}
.flagged-for-learning {
	transform: scale(1) !important;
}
.flagging li:not(.flagged-for-review,.flagged-for-learning) {
	transform: scale(0.8) !important;
}
.xp-text {
	position: absolute;
	white-space: nowrap;
	color: white;
	font-size: 1.2rem;
	font-weight: 600;
	text-shadow: 0px 0px 10px rgba(0,0,0,0.5);
}
.swiper-pagination-bullet {
	width: 15px !important;
	height: 15px !important;
	border-radius: 90rem !important;
}
.course-icon {
	cursor: pointer;
}
.character-win {
	height: 100px; object-fit: cover; width: 100px; max-width: 100px; min-width: 100px; min-height: 100px; transform: scale(1.2);
}
.dz-list > ul > li .item-link:after {
	display: none !important;
}
.robot {
	margin-top: -94px; z-index: -1; height: 200px; position: absolute;
}
.alert-top {
	height: 150px; width: auto;
}
.paywall {
	filter: blur(5px);
	pointer-events: none;
}
.buy-img {
	height: 150px; width: auto;
}
.course-icon-first {
	position: absolute; height: 120px; width: auto; z-index: 99;
}
.course-icon-second {
	height: 120px; width: auto; z-index: 99;
}
.item-img {
	height: 110px;
}
.page-wraper {
	max-width: 100%;
	overflow-x: hidden;
}
.rating-star {
	font-size: 1.7rem;
	color: #FFD700;
	transition: transform 0.2s ease-in-out;
	cursor: pointer;
}
.rating-star-over {
	font-size: 1.7rem;
	color: #FFD700;
	transition: transform 0.2s ease-in-out;
	cursor: pointer;
	opacity: 0.3;
}
.rating-star.hovered {
	transform: scale(1.1);
	color: #FFD700;
}
#whiteboard>li[data-uuid] {
	transform: scale(0);
	transition: height 0.25s, opacity 0.25s, transform 0.25s;
}
#whiteboard .typing {
	white-space: pre-wrap;
}

/* ============ Card change transition ============
   Flick and spring. Same direction of travel as the swipe gesture
   (practice/swipe.js): going forward the finished card is flicked off to the
   left and falls back while the next one swings in from the right and springs
   into the slot, its rows settling in a short cascade. The `-back` variants
   mirror it for undo. hideItem() lifts the outgoing card out of the flow and
   pins the board's height (holdBoardHeight), so the slot never collapses under
   it while the next card is still on its way. Transform / opacity only, no
   perspective: it all stays on the compositor while MathJax and the typing
   loop work the main thread. */
/* The card's containers clip (.chat-box-area hidden, .bottom-content auto),
   which cut the moving cards off at the column edge. The page scrolls on
   <body>, so these can safely open up for the run (same as the swipe). */
.chat-box-area:has(#whiteboard > li:is(.tt-card-exit, .tt-card-exit-back, .tt-card-enter, .tt-card-enter-back)),
.chat-box-area:has(#whiteboard > li:is(.tt-card-exit, .tt-card-exit-back, .tt-card-enter, .tt-card-enter-back)) .bottom-content {
	overflow: visible !important;
}
#whiteboard > li.tt-card-exit,
#whiteboard > li.tt-card-exit-back {
	--tt-card-dir: -1;
	pointer-events: none;
	z-index: 1;
	will-change: transform, opacity;
	transform-origin: 50% 100%;
	animation: ttCardOut .3s cubic-bezier(.45, 0, .85, .4) both;
}
#whiteboard > li.tt-card-exit-back {
	--tt-card-dir: 1;
}
@keyframes ttCardOut {
	0%   { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
	85%  { opacity: 0; }
	100% { opacity: 0; transform: translate3d(calc(var(--tt-card-dir) * max(56px, 6%)), 10px, 0) rotate(calc(var(--tt-card-dir) * 1.5deg)) scale(.93); }
}
#whiteboard > li.tt-card-enter,
#whiteboard > li.tt-card-enter-back {
	--tt-card-dir: 1;
	position: relative;
	z-index: 2;
	will-change: transform, opacity;
	transform-origin: 50% 100%;
	animation:
		ttCardInFade .22s ease-out .04s both,
		ttCardIn .7s cubic-bezier(.2, .9, .3, 1) both;
}
#whiteboard > li.tt-card-enter-back {
	--tt-card-dir: -1;
}
/* Damped spring (about 4% overshoot) where linear() is available. */
@supports (animation-timing-function: linear(0, 1)) {
	#whiteboard > li.tt-card-enter,
	#whiteboard > li.tt-card-enter-back {
		animation-timing-function: ease-out, linear(0, .098 5%, .306 10%, .531 15%, .726 20%, .871 25%, .965 30%, 1.018 35%, 1.042 40%, 1.046 45%, 1.04 50%, 1.02 60%, 1.005 70%, .999 80%, 1);
	}
}
@keyframes ttCardInFade {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@keyframes ttCardIn {
	from { transform: translate3d(calc(var(--tt-card-dir) * max(72px, 8%)), 14px, 0) rotate(calc(var(--tt-card-dir) * 1.5deg)) scale(.94); }
	to   { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
}
/* Inner rows settle a beat after the card lands (42ms stagger, --tt-i set by
   playCardEnter). Not applied to pairs / drag, which measure geometry as
   soon as they are set up. */
#whiteboard > li.tt-card-enter .tt-card-rise,
#whiteboard > li.tt-card-enter-back .tt-card-rise {
	animation: ttCardSettle .5s cubic-bezier(.22, 1, .36, 1) both;
	animation-delay: calc(150ms + var(--tt-i, 0) * 42ms);
}
@keyframes ttCardSettle {
	from { opacity: 0; transform: translate3d(0, 14px, 0); }
	to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
	#whiteboard > li.tt-card-exit,
	#whiteboard > li.tt-card-exit-back {
		animation: ttCardFadeOut .2s ease both;
	}
	#whiteboard > li.tt-card-enter,
	#whiteboard > li.tt-card-enter-back {
		animation: ttCardInFade .2s ease both;
	}
	#whiteboard > li.tt-card-enter .tt-card-rise,
	#whiteboard > li.tt-card-enter-back .tt-card-rise {
		animation: none;
	}
}
@keyframes ttCardFadeOut {
	from { opacity: 1; }
	to   { opacity: 0; }
}
.height-0 {
	height: 0 !important;
	opacity: 0;
	margin-bottom: 0 !important;
}
.rating-star:hover {
	transform: scale(1.2);
}
.or-hr {
	margin-top: -27px;
	position: absolute;
	width: 100%;
	text-align: center;
	right: 0;
	left: 0;
	text-shadow: 8px 0 #fff, -8px 0 #fff, 0 8px #fff, 0 -8px #fff, 4px 4px #fff, -4px -4px #fff, 4px -4px #fff, -4px 4px #fff;
	color: gray;
	font-weight: 500;
}
.rating-stars-over {
	overflow: hidden; white-space: nowrap;
}
.trail-1 {
	position: absolute;
	height: 6px; width: 6px;
	border-radius: 3px;
	background: #01bb1a;
	pointer-events: none;
	transition: opacity 0.5s;
}
.trail-2 {
	position: absolute;
	height: 6px; width: 6px;
	border-radius: 3px;
	background: #bb0101;
	pointer-events: none;
	transition: opacity 0.5s;
}
.trail-3 {
	position: absolute;
	height: 6px; width: 6px;
	border-radius: 3px;
	background: #0101bb;
	pointer-events: none;
	transition: opacity 0.5s;
}
.trail-4 {
	position: absolute;
	height: 0; width: 0;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-bottom: 10px solid #49a3ff;
	pointer-events: none;
}
.trail-11 {
	position: absolute;
	height: 10px; width: 10px;
	border-radius: 50%;
	background: #49a3ff;
	pointer-events: none;
}
.trail-12 {
	position: absolute;
	height: 10px; width: 10px;
	border-radius: 0;
	background: #49a3ff;
	pointer-events: none;
}
.trail-5 {
	position: absolute;
	height: 5px; width: 5px;
	border-radius: 45rem;
	background: linear-gradient(
		90deg,
		rgba(255, 0, 0, 1) 0%,
		rgba(255, 154, 0, 1) 10%,
		rgba(208, 222, 33, 1) 20%,
		rgba(79, 220, 74, 1) 30%,
		rgba(63, 218, 216, 1) 40%,
		rgba(47, 201, 226, 1) 50%,
		rgba(28, 127, 238, 1) 60%,
		rgba(95, 21, 242, 1) 70%,
		rgba(186, 12, 248, 1) 80%,
		rgba(251, 7, 217, 1) 90%,
		rgba(255, 0, 0, 1) 100%
	);
	pointer-events: none;
	margin: 20px auto;
	transition: opacity 0.5s;
	animation: rotate 5s linear infinite;
	transform: scale(1.5) rotate(90deg) translateX(-10px);
}
.fire {
	animation: burn 1.5s linear infinite alternate;
}
@keyframes burn {
	from {
		transform: scale(1.6) skew(12deg) rotate(12deg);
		text-shadow: 0 1px 1px #FEFCC9,
		0 2px 2px #FEEC85,
		0 3px 3px #FFAE34,
		0 4px 4px #EC760C,
		0 5px 5px #CD4606,
		0 6px 6px #973716,
		0 7px 7px #451B0E;
	}
	to {
		transform: scale(1.4) skew(-8deg) rotate(-8deg);
		text-shadow: 0 1px 4px #FEFCC9,
		0 2px 6px #FEEC85,
		0 3px 9px #FFAE34,
		0 4px 11px #EC760C,
		0 5px 14px #CD4606,
		0 6px 17px #973716,
		0 7px 20px #451B0E;
	}
}
.trail-6 {
	position: absolute;
	height: 0;
	width: 0;
	border-left: 6px solid transparent;
	border-right: 6px solid transparent;
	pointer-events: none;
	transform: scale(1.6) translateY(-10px);
	content: 'O';
	transition: opacity 0.5s;
}
.trail-6::after {
	content: '^';
	position: absolute;
	color: white;
	filter: blur(1px);
	top: 0;
	left: 0;
	font-size: 5.5px;
	transform: scale(0.3);
	animation: burn 1.5s linear infinite alternate;
}
.trail-7 {
	position: absolute;
	height: 6px; width: 6px;
	border-radius: 3px;
	background: #FFD700;
	box-shadow: 0 0 10px #FFD700;
	pointer-events: none;
	transition: opacity 0.5s;
	animation: shine 1s infinite ease-in-out;
}
@keyframes shine {
	0% {background: #FFD700; box-shadow: 0 0 10px #FFD700;}
	50% {background: #FFAA00; box-shadow: 0 0 20px #FFAA00, 0 0 30px #FFAA00, 0 0 40px #FFAA00;}
	100% {background: #FFD700; box-shadow: 0 0 10px #FFD700;}
}
.trail-8 {
	position: absolute;
	height: 8px; width: 8px;
	border-radius: 4px;
	background: #DC143C;
	box-shadow: 0 0 15px #DC143C;
	pointer-events: none;
	transition: opacity 1s;
	animation: burn 2s infinite ease-in-out;
}
@keyframes burn {
	0% {background: #DC143C; box-shadow: 0 0 15px #DC143C;}
	50% {background: #FF0000; box-shadow: 0 0 30px #FF0000, 0 0 45px #FF0000, 0 0 60px #FF0000;}
	100% {background: #DC143C; box-shadow: 0 0 15px #DC143C;}
}
.trail-9 {
	position: absolute;
	height: 10px; width: 10px;
	border-radius: 50%;
	background: #00FFFF;
	box-shadow: 0 0 10px #00FFFF;
	pointer-events: none;
	opacity: 0.8;
	animation: expandripple 1s infinite ease-out forwards;
}
@keyframes expandripple {
	0% { transform: scale(0); opacity: 0.8; }
	100% { transform: scale(2); opacity: 0; }
}
.trail-10 {
	position: absolute;
	height: 7px; width: 7px;
	border-radius: 3.5px;
	background: #800080;
	box-shadow: 0 0 15px #800080, 0 0 20px #800080;
	pointer-events: none;
	opacity: 0.7;
	animation: shimmeringstar 1s alternate infinite;
}
@keyframes shimmeringstar {
	0% { opacity: 0.7; transform: rotate(0deg); }
	50% { opacity: 0.9; background: #D02090; transform: rotate(180deg); }
	100% { opacity: 0.7; transform: rotate(360deg); }
}
.trail-10::after {
	content: '★';
	position: absolute;
	color: #800080;
	top: 0;
	left: 0;
	font-size: 5.5px;
	transform: scale(5);
}
.trail-13 {
	position: absolute;
	height: 7px; width: 7px;
	border-radius: 3.5px;
	background: #FF69B4;
	box-shadow: 0 0 15px #FF69B4, 0 0 20px #FF69B4;
	pointer-events: none;
	opacity: 0.7;
	animation: rollingheart 1s infinite;
}
@keyframes rollingheart {
	0% { opacity: 0.7; transform: rotate(0deg); }
	50% { opacity: 0.9; transform: rotate(180deg); }
	100% { opacity: 0.7; transform: rotate(360deg); }
}
.trail-13::after {
	content: '❤️';
	position: absolute;
	color: #FF69B4;
	top: 0;
	left: 0;
	font-size: 5.5px;
	transform: scale(3);
}
.trail-14 {
	position: absolute;
	height: 7px; width: 7px;
	border-radius: 3.5px;
	background: #32CD32;
	box-shadow: 0 0 15px #32CD32, 0 0 20px #32CD32;
	pointer-events: none;
	opacity: 0.7;
	animation: spinningclover 1s infinite;
}
@keyframes spinningclover {
	0% { opacity: 0.7; transform: rotate(0deg); }
	50% { opacity: 0.9; transform: rotate(180deg); }
	100% { opacity: 0.7; transform: rotate(360deg); }
}
.trail-14::after {
	content: '🍀';
	position: absolute;
	color: #32CD32;
	top: 0;
	left: 0;
	font-size: 5.5px;
	transform: scale(3);
}
.trail-15 {
	position: absolute;
	height: 10px; width: 10px;
	border-radius: 50%;
	background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet);
	box-shadow: 0 0 10px white, 0 0 20px white;
	pointer-events: none;
	opacity: 0.8;
	animation: sparklerainbow 1s infinite ease-out forwards;
}
@keyframes sparklerainbow {
	0% { transform: scale(0); opacity: 0.8; }
	25% { box-shadow: 0 0 10px white, 0 0 20px white; }
	50% { box-shadow: 0 0 15px white, 0 0 25px white; }
	75% { box-shadow: 0 0 10px white, 0 0 20px white; }
	100% { transform: scale(2); opacity: 0; }
}
.trail-15::after {
	content: '✨';
	position: absolute;
	color: white;
	top: 0;
	left: 0;
	font-size: 5.5px;
	transform: scale(3);
}
.assignment-popup-helper {
	transition: transform 0.5s, opacity 0.5s, height 0.5s;
}
.lives-deduction-animation {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	font-size: 2rem;
	color: red;
	z-index: 100000;
	pointer-events: none;
	opacity: 1;
	transition: opacity 1s;
}
.incorrect {
	background-color: #f87374;
}
.correct {
	background-color: #56c760;
}
.heart-half-1 {
	position: absolute;
	transform: rotate(0deg);
	opacity: 1;
	transition: all 1s;
}
.lesson-progress .progress-item {
	height: 5px;
	transition: width 1s ease-out, opacity 1s ease-out;
}

/* Rio is absolutely positioned and hangs below the header bar, so he has to
   sit in front of the content cards - without a stacking context on .header
   its z-index: 2 is inert (it's statically positioned) and the first card
   paints over his feet. */
.header {
	position: relative;
	z-index: 20;
}
#parrot {
	z-index: 21;
}

/* Practice header layout: keep the counters on one row on desktop and give
   the lesson progress bar clearance from the absolutely-positioned parrot. */
.header .header-content .right-content-container {
	flex: 0 0 auto;
	flex-wrap: nowrap;
}
.header .header-content .mid-content {
	min-width: 0;
	padding-left: 85px;
	padding-right: 20px;
}
/* Keep each counter icon centred over its badge and stop the streak/heart
   icons crowding into each other. */
.header .header-content .right-content-container .right-content {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 36px;
}
/* The cosmetic avatar frame is scaled 1.6x globally, which swallows the XP
   widget in the compact practice header - tone it down here. */
.header .header-content .device-frame {
	transform: scale(1.25);
}

/* Clear subtopic progress bar shown in the practice header.
   Designed as a compact one-row "game HUD" pill: counter, glowing animated
   gradient track (with the current content type riding it as a runner badge
   and upcoming types waiting as ghost dots), and a short remaining label. */
.lesson-progress-inner {
	width: 100%;
	max-width: 380px;
	margin: 0 auto;
	padding: 9px 14px;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	gap: 12px;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(244, 247, 252, 0.9));
	border: 1px solid rgba(47, 107, 255, 0.12);
	border-radius: 999px;
	box-shadow: 0 4px 14px rgba(28, 28, 40, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8);
	backdrop-filter: blur(6px);
}
.lesson-progress-count {
	display: inline-flex;
	align-items: baseline;
	gap: 1px;
	padding: 2px 9px;
	border-radius: 999px;
	background: linear-gradient(135deg, var(--primary, #2f6bff), #6b9bff);
	color: #fff;
	font-weight: 800;
	font-size: 0.72rem;
	line-height: 1.5;
	font-variant-numeric: tabular-nums;
	box-shadow: 0 2px 6px rgba(47, 107, 255, 0.35);
	white-space: nowrap;
	flex: 0 0 auto;
}
.lesson-progress-left {
	font-weight: 800;
	font-size: 0.68rem;
	color: #5b6575;
	letter-spacing: 0.2px;
	text-align: right;
	flex: 0 0 auto;
	white-space: nowrap;
}
.lesson-progress-track {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
	height: 10px;
	background: #e6ebf3;
	border-radius: 999px;
	overflow: hidden;
	box-shadow: inset 0 1px 2px rgba(28, 28, 40, 0.1);
}
.lesson-progress-fill {
	position: relative;
	height: 100%;
	width: 0%;
	min-width: 10px;
	border-radius: 999px;
	background: linear-gradient(90deg, var(--primary, #2f6bff), #6b9bff);
	box-shadow: 0 0 8px rgba(47, 107, 255, 0.45);
	transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1), background 0.4s ease;
}
/* Moving shine sweep across the filled portion. */
.lesson-progress-fill::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 999px;
	background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.55) 48%, transparent 62%);
	background-size: 220% 100%;
	animation: lesson-progress-shine 2.6s ease-in-out infinite;
}
@keyframes lesson-progress-shine {
	0% { background-position: 130% 0; }
	60%, 100% { background-position: -90% 0; }
}
.lesson-progress-fill.complete {
	background: linear-gradient(90deg, #56c760, #2fae4f);
	box-shadow: 0 0 10px rgba(86, 199, 96, 0.5);
}
.lesson-progress-fill.struggling {
	background: linear-gradient(90deg, #ffb03a, #ff6a2f);
	box-shadow: 0 0 10px rgba(255, 122, 47, 0.5);
	animation: lesson-progress-ember 1.4s ease-in-out infinite;
}
@keyframes lesson-progress-ember {
	0%, 100% { filter: brightness(1); }
	50% { filter: brightness(1.18); }
}
.lesson-progress-left.struggling {
	color: #f25c1f;
}
.lesson-progress-left .fa-fire {
	margin-right: 3px;
	animation: lesson-progress-flicker 1s ease-in-out infinite;
}
@keyframes lesson-progress-flicker {
	0%, 100% { transform: scale(1); opacity: 1; }
	50% { transform: scale(1.15); opacity: 0.85; }
}
/* Segment tick marks on the track: each remaining activity is a visible step. */
.lesson-progress-ticks {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 1;
}
.lesson-progress-tick {
	position: absolute;
	top: 2px;
	bottom: 2px;
	width: 2px;
	margin-left: -1px;
	border-radius: 2px;
	background: rgba(28, 28, 40, 0.12);
}
.lesson-progress-fill {
	z-index: 2;
	overflow: hidden;
}
/* Let the milestone star overhang the ends of the bar; the fill and its shine
   clip themselves via their own rounded overflow. */
.lesson-progress-track {
	overflow: visible;
}
/* Milestone star pinned to the end of the track: the prize you're chasing. */
.lesson-progress-goal {
	position: absolute;
	top: 50%;
	right: -2px;
	transform: translateY(-50%);
	z-index: 3;
	width: 18px;
	height: 18px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: #fff;
	border: 1px solid #e3e9f2;
	color: #c3ccd9;
	font-size: 0.55rem;
	box-shadow: 0 1px 4px rgba(28, 28, 40, 0.15);
	transition: color 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
	pointer-events: none;
}
.lesson-progress-goal.near {
	color: #f5a623;
	box-shadow: 0 0 8px rgba(245, 166, 35, 0.55);
	animation: lesson-progress-goal-wiggle 0.9s ease-in-out infinite;
}
.lesson-progress-goal.reached {
	color: #fff;
	background: linear-gradient(135deg, #ffd34d, #f5a623);
	border-color: transparent;
	box-shadow: 0 0 10px rgba(245, 166, 35, 0.7);
	animation: lesson-progress-goal-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes lesson-progress-goal-wiggle {
	0%, 100% { transform: translateY(-50%) rotate(0deg); }
	25% { transform: translateY(-50%) rotate(-12deg); }
	75% { transform: translateY(-50%) rotate(12deg); }
}
@keyframes lesson-progress-goal-pop {
	0% { transform: translateY(-50%) scale(0.4); }
	60% { transform: translateY(-50%) scale(1.35); }
	100% { transform: translateY(-50%) scale(1); }
}
/* Gold "final stretch" state when the milestone is nearly reached. */
.lesson-progress-fill.near-goal {
	background: linear-gradient(90deg, #ffb93a, #ffd34d);
	box-shadow: 0 0 10px rgba(245, 166, 35, 0.6);
}
.lesson-progress-left.near-goal {
	color: #e8930c;
}
.lesson-progress-left .fa-bolt {
	margin-right: 3px;
	color: #f5a623;
	animation: lesson-progress-flicker 1s ease-in-out infinite;
}
/* Satisfying bump each time the person makes progress. */
.lesson-progress-count.bump {
	animation: lesson-progress-count-bump 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes lesson-progress-count-bump {
	0% { transform: scale(1); }
	40% { transform: scale(1.25); }
	100% { transform: scale(1); }
}
.lesson-progress-fill.bump {
	animation: lesson-progress-fill-bump 0.45s ease;
}
@keyframes lesson-progress-fill-bump {
	0%, 100% { filter: brightness(1); }
	40% { filter: brightness(1.35); }
}
/* Runner badge: the current content type riding the fill's leading edge. */
.lesson-progress-runner {
	position: absolute;
	top: 50%;
	left: 0;
	transform: translate(-50%, -50%);
	z-index: 4;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(135deg, var(--primary, #2f6bff), #6b9bff);
	border: 2px solid #fff;
	color: #fff;
	font-size: 0.55rem;
	box-shadow: 0 2px 7px rgba(47, 107, 255, 0.45);
	transition: left 0.6s cubic-bezier(0.22, 1, 0.36, 1), background 0.4s ease;
	cursor: help;
}
.lesson-progress-runner.struggling {
	background: linear-gradient(135deg, #ffb03a, #ff6a2f);
	box-shadow: 0 2px 7px rgba(255, 122, 47, 0.5);
}
.lesson-progress-runner.pop {
	animation: lesson-progress-runner-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes lesson-progress-runner-pop {
	0% { transform: translate(-50%, -50%) scale(0.5); }
	60% { transform: translate(-50%, -50%) scale(1.25); }
	100% { transform: translate(-50%, -50%) scale(1); }
}
/* Ghost dots: upcoming content types waiting on their future segments. */
.lesson-progress-upcoming {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
}
.lesson-progress-upcoming-dot {
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
	width: 16px;
	height: 16px;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: #fff;
	border: 1px solid #e3e9f2;
	color: #a9b3c2;
	font-size: 0.45rem;
	box-shadow: 0 1px 3px rgba(28, 28, 40, 0.1);
	pointer-events: auto;
	cursor: help;
}

/* "What's next" hover card under the HUD pill. */
.lesson-progress-peek {
	position: absolute;
	top: calc(100% + 8px);
	left: 50%;
	transform: translate(-50%, -4px);
	z-index: 50;
	min-width: 200px;
	max-width: 260px;
	padding: 10px 12px;
	border-radius: 14px;
	background: #fff;
	border: 1px solid rgba(47, 107, 255, 0.14);
	box-shadow: 0 12px 30px rgba(28, 28, 40, 0.16);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.16s ease, transform 0.16s ease, visibility 0s linear 0.16s;
	text-align: left;
}
.lesson-progress-peek.open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translate(-50%, 0);
	transition: opacity 0.16s ease, transform 0.16s ease, visibility 0s;
}
.lesson-progress-peek::before {
	content: "";
	position: absolute;
	top: -6px;
	left: 50%;
	width: 10px;
	height: 10px;
	transform: translateX(-50%) rotate(45deg);
	background: inherit;
	border-left: 1px solid rgba(47, 107, 255, 0.14);
	border-top: 1px solid rgba(47, 107, 255, 0.14);
}
.lesson-progress-peek-title {
	font-size: 0.62rem;
	font-weight: 800;
	letter-spacing: 0.6px;
	text-transform: uppercase;
	color: #8a94a6;
	margin-bottom: 6px;
}
.lesson-progress-peek-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.lesson-progress-peek-list li {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 4px 6px;
	border-radius: 8px;
	font-size: 0.78rem;
	font-weight: 700;
	color: #1c1c28;
}
.lesson-progress-peek-list li.now {
	background: rgba(47, 107, 255, 0.08);
}
.lesson-progress-peek-list li.more {
	color: #8a94a6;
	font-weight: 600;
}
.lesson-progress-peek-icon {
	width: 22px;
	height: 22px;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	background: #eef2f9;
	color: #5b6575;
	font-size: 0.6rem;
}
.lesson-progress-peek-list li.now .lesson-progress-peek-icon {
	background: linear-gradient(135deg, var(--primary, #2f6bff), #6b9bff);
	color: #fff;
}
.lesson-progress-peek-label {
	flex: 1 1 auto;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.lesson-progress-peek-tag {
	flex: 0 0 auto;
	font-size: 0.6rem;
	font-weight: 800;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: #8a94a6;
}
.lesson-progress-peek-list li.now .lesson-progress-peek-tag {
	color: var(--primary, #2f6bff);
}
.lesson-progress-peek-footer {
	display: flex;
	align-items: center;
	gap: 6px;
	margin-top: 8px;
	padding-top: 8px;
	border-top: 1px solid rgba(28, 28, 40, 0.08);
	font-size: 0.72rem;
	font-weight: 700;
	color: #5b6575;
}
.lesson-progress-peek-footer i {
	color: #f5a623;
}

/* Medium windows: the row can't fit the left icons + parrot, the lesson
   progress pill and the counters side by side, so the pill overflows into
   the streak/heart/XP icons. Drop it onto its own full-width row instead,
   same treatment as mobile below. */
@media only screen and (max-width: 991px) {
	.header .header-content {
		flex-wrap: wrap;
		padding-top: 6px;
		padding-bottom: 6px;
	}
	.header .header-content .right-content-container {
		order: 1;
		flex: 1 1 auto;
		min-width: 0;
		flex-wrap: nowrap;
		justify-content: flex-end;
		align-items: center;
	}
	.header .header-content .mid-content {
		order: 2;
		width: 100%;
		flex: none;
		padding-left: 0;
		padding-right: 0;
		/* Clearance below the icon row: the counters and avatar frame
		   visually overflow their layout box. */
		margin-top: 14px;
	}
}

/* Mobile practice header: keep the icons on one compact row and drop the
   lesson progress bar onto its own full-width row underneath. Overrides the
   generic header stacking rules in main.css (this file loads after it). */
@media only screen and (max-width: 576px) {
	.header .header-content {
		padding-top: 6px;
		padding-bottom: 6px;
	}
	#parrot {
		display: none !important;
	}
	.header .header-content .right-content-container {
		order: 1;
		width: auto;
		flex: 1;
		flex-wrap: nowrap;
		justify-content: flex-end;
		align-items: center;
		margin-top: 0;
		padding-left: 0;
		/* Room on the right for the avatar frame (scaled) so it doesn't
		   get clipped by the screen edge. */
		padding-right: 10px;
		gap: 12px;
	}
	/* The stat chips keep the compact pill sizing from main.css's mobile
	   rules - just stop them being squashed into each other. */
	.header .header-content .right-content-container .right-content {
		flex: 0 0 auto;
	}
	/* When the row still doesn't fit, shrink the XP capsule instead of
	   letting it bleed over the lives pill (the base .progress-item rule
	   centres it inside a 36px min-width slot). */
	.header .header-content .right-content-container .progress-item {
		flex-shrink: 1;
		min-width: 0;
		justify-content: flex-end;
	}
	/* Give the calendar/notes icon breathing room before the counters. */
	.header .header-content .left-content.mx-2 {
		margin-right: 10px !important;
	}
	/* Keep the scaled avatar frame clear of the XP capsule. */
	.header .header-content .device-frame {
		transform: scale(1.1);
	}
	.header .header-content .device-avatar-wrapper {
		margin-left: 8px;
	}
	.header .header-content .right-content-container .progress-component-wrapper {
		width: auto;
		order: 0;
		margin-top: 0;
		display: flex;
		justify-content: flex-end;
	}
	.header .header-content .mid-content {
		/* main.css hides .mid-content entirely at this width - restore it,
		   the lesson progress bar lives here. */
		display: block;
		order: 2;
		width: 100%;
		flex: none;
		padding-left: 0;
		/* Clearance below the icon row: the avatar frame (scaled 1.6x) and
		   lives/streaks counters visually overflow their layout box. */
		margin-top: 14px;
	}
	/* Compact the XP progress widget so the whole icon row fits on one line.
	   Sizing (42px bar, shrinkable) comes from main.css's mobile block - a
	   fixed 36px-tall override here used to blow the bar out of the capsule. */
	.header .header-content .progression-wrapper {
		gap: 6px;
	}
	.lesson-progress-inner {
		max-width: 360px;
		margin: 0 auto;
		padding: 8px 12px;
		gap: 10px;
	}
}

/* Very narrow phones: even fully shrunk, the pills + XP capsule don't fit on
   one row - drop the XP bar (level badge + avatar stay) and tighten gaps so
   nothing gets pushed off-screen. */
@media only screen and (max-width: 374px) {
	.header .header-content .right-content-container {
		gap: 8px;
	}
	.header .header-content .progress-bar-outer {
		display: none;
	}
	.header .header-content .lives-link,
	.header .header-content .streaks-link {
		padding: 0 9px;
	}
}
.heart-half-2 {
	transform: rotate(0deg);
	transition: all 1s;
	opacity: 1;
}
.half-heart-2-after {
	transform: rotate(90deg) translateY(-100%) translateX(50%);
	opacity: 0;
}
.half-heart-1-after {
	transform: rotate(-90deg) translateY(-100%) translateX(-50%);
	opacity: 0;
}
.item-inner p, code {
	margin: 0;
	font-size: 1.2rem !important;
}
.item-inner button {
	margin: 0;
	font-size: 1rem !important;
}
.item-inner button p {
	margin: 0;
	font-size: 1rem !important;
}
.item-inner strong {
	font-weight: 600;
}

/* Gamification Enhancements */
.combo-badge {
    position: fixed;
    top: 90px;
    right: 20px;
    z-index: 1000;
    background: linear-gradient(135deg, #ff8a00, #e52e71);
    color: white;
    padding: 8px 20px;
    border-radius: 50px;
    font-weight: 900;
    font-size: 1.25rem;
    box-shadow: 0 4px 15px rgba(229, 46, 113, 0.4), inset 0 0 10px rgba(255, 255, 255, 0.2);
    transform: translateX(120%) scale(0.5);
    transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    pointer-events: none;
    text-transform: uppercase;
    letter-spacing: 1px;
    display: flex;
    align-items: center;
    gap: 8px;
    border: 2px solid rgba(255, 255, 255, 0.3);
}

.combo-badge::before {
    content: '🔥';
    font-size: 1.4rem;
    filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.5));
}

.combo-badge.show {
    transform: translateX(0) scale(1);
    animation: combo-float 3s ease-in-out infinite;
}

.combo-badge.pop {
    animation: combo-pop 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.combo-badge.tier-2 {
    background: linear-gradient(135deg, #e52e71, #923eff);
    box-shadow: 0 4px 20px rgba(146, 62, 255, 0.5);
    font-size: 1.4rem;
}

.combo-badge.tier-3 {
    background: linear-gradient(135deg, #923eff, #00d2ff);
    box-shadow: 0 4px 25px rgba(0, 210, 255, 0.6);
    font-size: 1.6rem;
    animation: combo-float 2s ease-in-out infinite, combo-glow 1.5s infinite alternate;
}

@keyframes combo-glow {
    from { filter: brightness(1) drop-shadow(0 0 5px rgba(255,255,255,0.3)); }
    to { filter: brightness(1.3) drop-shadow(0 0 15px rgba(255,255,255,0.6)); }
}

@keyframes combo-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-5px); }
}

@keyframes combo-pop {
    0% { transform: scale(1); }
    50% { transform: scale(1.3); filter: brightness(1.2); }
    100% { transform: scale(1); }
}

@keyframes combo-pulse {
    from { box-shadow: 0 4px 15px rgba(255, 138, 0, 0.4); }
    to { box-shadow: 0 8px 25px rgba(229, 46, 113, 0.6); }
}

.floating-score {
    position: fixed;
    z-index: 10001;
    color: #FFD700;
    font-weight: 900;
    font-size: 2rem;
    pointer-events: none;
    text-shadow: 0 0 10px rgba(0,0,0,0.5), 0 0 20px rgba(255, 215, 0, 0.5);
    animation: float-up-fade 1.2s forwards cubic-bezier(0.22, 1, 0.36, 1);
}

.floating-score.perfect {
    color: #00ffcc;
    text-shadow: 0 0 15px rgba(0, 255, 204, 0.8);
    font-size: 2.5rem;
}

.floating-score.level-up {
    color: #ff00ff;
    text-shadow: 0 0 15px rgba(255, 0, 255, 0.8), 0 0 25px rgba(255, 255, 255, 0.5);
    font-size: 3rem;
}

@keyframes float-up-fade {
    0% { transform: translateY(0) scale(0.5); opacity: 0; }
    20% { transform: translateY(-20px) scale(1.2); opacity: 1; }
    100% { transform: translateY(-100px) scale(1); opacity: 0; }
}

.xp-text {
    position: absolute;
    color: var(--primary);
    font-weight: 900;
    font-size: 1.5rem;
    pointer-events: none;
    z-index: 100;
    white-space: nowrap;
    text-shadow: 0 0 5px white;
}

.level-up-modal-content {
    text-align: center;
    padding: 2rem;
}

.level-up-badge {
    width: 120px;
    height: 120px;
    background: var(--primary);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
    font-weight: 900;
    margin: 0 auto 1.5rem;
    box-shadow: 0 0 30px var(--rgba-primary-4);
    animation: level-up-pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes level-up-pop {
    0% { transform: scale(0); rotate: -180deg; }
    100% { transform: scale(1); rotate: 0deg; }
}

.shake-heavy {
    animation: shake-heavy 0.3s linear;
}

@keyframes shake-heavy {
    0% { transform: translate(0,0); }
    10% { transform: translate(-10px, -10px); }
    20% { transform: translate(10px, 10px); }
    30% { transform: translate(-10px, 10px); }
    40% { transform: translate(10px, -10px); }
    50% { transform: translate(-10px, -10px); }
    60% { transform: translate(10px, 10px); }
    70% { transform: translate(-10px, 10px); }
    80% { transform: translate(10px, -10px); }
    90% { transform: translate(-10px, -10px); }
    100% { transform: translate(0,0); }
}

/* =============================================================================
   Ask Rio - learning mode chat panel (practice/learning.js)
   ============================================================================= */
.ask-ai-backdrop {
	position: fixed;
	inset: 0;
	z-index: 9990;
	background: rgba(15, 23, 42, 0.55);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	opacity: 0;
	transition: opacity 0.25s ease;
}
.ask-ai-backdrop.is-in {
	opacity: 1;
}
.ask-ai-panel {
	position: fixed;
	z-index: 9991;
	left: 50%;
	bottom: 24px;
	transform: translateX(-50%) translateY(24px) scale(0.97);
	width: min(600px, calc(100vw - 24px));
	max-height: min(82vh, 760px);
	display: flex;
	flex-direction: column;
	background: #fff;
	border-radius: 26px;
	box-shadow: 0 30px 80px -20px rgba(15, 23, 42, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.08);
	overflow: hidden;
	opacity: 0;
	transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.ask-ai-panel.is-in {
	opacity: 1;
	transform: translateX(-50%) translateY(0) scale(1);
}
@media (max-width: 576px) {
	.ask-ai-panel {
		bottom: 0;
		width: 100vw;
		max-height: 88vh;
		border-bottom-left-radius: 0;
		border-bottom-right-radius: 0;
	}
}
/* --- header --- */
.ask-ai-header {
	position: relative;
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 16px 18px;
	background: linear-gradient(120deg, var(--primary, #4c6fff) 0%, #6d5df6 55%, #38bdf8 120%);
	color: #fff;
	overflow: hidden;
	flex: 0 0 auto;
}
.ask-ai-orb {
	position: absolute;
	border-radius: 50%;
	filter: blur(30px);
	opacity: 0.35;
	pointer-events: none;
}
.ask-ai-orb-1 {
	width: 160px;
	height: 160px;
	background: #fff;
	top: -90px;
	left: -40px;
}
.ask-ai-orb-2 {
	width: 140px;
	height: 140px;
	background: #38bdf8;
	bottom: -80px;
	right: -30px;
}
.ask-ai-avatar {
	position: relative;
	width: 58px;
	height: 58px;
	flex: 0 0 auto;
	border-radius: 18px;
	background: rgba(255, 255, 255, 0.18);
	border: 1px solid rgba(255, 255, 255, 0.35);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.ask-ai-avatar-fallback {
	position: absolute;
	font-size: 1.5rem;
	color: #fff;
	opacity: 0.9;
}
.ask-ai-headings {
	position: relative;
	flex: 1;
	min-width: 0;
}
.ask-ai-title {
	font-weight: 800;
	font-size: 1.25rem;
	letter-spacing: -0.01em;
	line-height: 1.2;
	color: #fff;
}
.ask-ai-subtitle {
	font-size: 0.8rem;
	font-weight: 600;
	color: rgba(255, 255, 255, 0.75);
}
.ask-ai-header-right {
	position: relative;
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
}
.ask-ai-remaining {
	display: inline-flex;
	align-items: baseline;
	gap: 4px;
	background: rgba(255, 255, 255, 0.16);
	border: 1px solid rgba(255, 255, 255, 0.3);
	color: #fff;
	border-radius: 999px;
	padding: 5px 12px;
	font-size: 0.8rem;
	font-weight: 700;
	white-space: nowrap;
}
.ask-ai-remaining small {
	font-weight: 600;
	opacity: 0.7;
}
.ask-ai-remaining.is-low {
	background: rgba(244, 63, 94, 0.35);
	border-color: rgba(255, 255, 255, 0.4);
}
.ask-ai-remaining.is-bar {
	position: relative;
	align-items: center;
	gap: 8px;
	cursor: default;
	outline: none;
}
.ask-ai-power {
	display: block;
	width: 72px;
	height: 8px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.22);
	overflow: hidden;
}
.ask-ai-power-fill {
	display: block;
	height: 100%;
	min-width: 4px;
	border-radius: inherit;
	background: linear-gradient(90deg, #fde047, #fff);
	box-shadow: 0 0 8px rgba(253, 224, 71, 0.7);
	transition: width 0.4s ease;
}
.ask-ai-remaining.is-low .ask-ai-power-fill {
	background: #fff;
	box-shadow: none;
}
.ask-ai-remaining.is-bar::after {
	content: attr(data-tip);
	position: absolute;
	top: calc(100% + 8px);
	right: 0;
	background: rgba(15, 23, 42, 0.92);
	color: #fff;
	font-size: 0.75rem;
	font-weight: 600;
	padding: 5px 10px;
	border-radius: 8px;
	white-space: nowrap;
	opacity: 0;
	transform: translateY(-4px);
	pointer-events: none;
	transition: opacity 0.15s ease, transform 0.15s ease;
	z-index: 5;
}
.ask-ai-remaining.is-bar:hover::after,
.ask-ai-remaining.is-bar:focus::after {
	opacity: 1;
	transform: translateY(0);
}
.ask-ai-close {
	width: 36px;
	height: 36px;
	border: none;
	border-radius: 12px;
	background: rgba(255, 255, 255, 0.16);
	color: #fff;
	font-size: 1rem;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 0.15s ease, transform 0.15s ease;
}
.ask-ai-close:hover {
	background: rgba(255, 255, 255, 0.3);
	transform: scale(1.06);
}
/* --- spotlight ---
   The card being asked about is the real on-page element, raised above the
   backdrop (which sits at z-index 9990) so it stays crisp and readable while
   everything else dims and blurs. View-only while the panel is open. */
#whiteboard > li.ask-ai-target {
	position: relative;
	z-index: 9991;
	pointer-events: none;
	outline: 3px solid var(--primary, #4c6fff);
	outline-offset: 4px;
	border-radius: 12px;
	box-shadow: 0 18px 50px rgba(15, 23, 42, 0.35);
	animation: askAISpotlight 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes askAISpotlight {
	from {
		outline-color: rgba(76, 111, 255, 0);
		box-shadow: 0 0 0 rgba(15, 23, 42, 0);
	}
}
/* --- thread --- */
.ask-ai-thread {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 18px;
	display: flex;
	flex-direction: column;
	gap: 12px;
	min-height: 180px;
	background:
		radial-gradient(circle at 85% 10%, rgba(109, 93, 246, 0.05), transparent 40%),
		radial-gradient(circle at 10% 90%, rgba(56, 189, 248, 0.06), transparent 40%),
		#fff;
	overscroll-behavior: contain;
}
.ask-ai-empty {
	margin: auto 0;
	text-align: center;
	padding: 8px 6px 4px;
}
.ask-ai-empty p {
	color: #64748b;
	font-size: 0.95rem;
	font-weight: 500;
	max-width: 380px;
	margin: 0 auto 16px;
	line-height: 1.55;
}
.ask-ai-chips {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
}
.ask-ai-chip {
	border: 1px solid #e2e8f0;
	background: #fff;
	color: #334155;
	border-radius: 999px;
	padding: 8px 16px;
	font-size: 0.85rem;
	font-weight: 600;
	cursor: pointer;
	box-shadow: 0 2px 6px rgba(15, 23, 42, 0.05);
	transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ask-ai-chip i {
	color: var(--primary, #4c6fff);
	margin-right: 4px;
}
.ask-ai-chip:hover {
	transform: translateY(-2px);
	border-color: var(--primary, #4c6fff);
	color: var(--primary, #4c6fff);
	box-shadow: 0 6px 16px rgba(76, 111, 255, 0.18);
}
.ask-ai-msg {
	display: flex;
	gap: 10px;
	animation: askAIMsgIn 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes askAIMsgIn {
	from { opacity: 0; transform: translateY(8px); }
	to { opacity: 1; transform: none; }
}
.ask-ai-msg-user {
	justify-content: flex-end;
}
.ask-ai-msg-avatar {
	width: 30px;
	height: 30px;
	flex: 0 0 auto;
	border-radius: 50%;
	background: linear-gradient(135deg, var(--primary, #4c6fff), #6d5df6);
	color: #fff;
	font-size: 0.75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 4px 10px rgba(76, 111, 255, 0.35);
	margin-top: 2px;
}
.ask-ai-bubble {
	max-width: 82%;
	padding: 12px 16px;
	border-radius: 18px;
	font-size: 0.95rem;
	line-height: 1.6;
	word-break: break-word;
}
.ask-ai-msg-user .ask-ai-bubble {
	background: linear-gradient(120deg, var(--primary, #4c6fff), #6d5df6);
	color: #fff;
	border-bottom-right-radius: 6px;
	box-shadow: 0 8px 20px -6px rgba(76, 111, 255, 0.5);
	font-weight: 500;
}
.ask-ai-msg-ai .ask-ai-bubble {
	background: #f4f6fb;
	color: #1e293b;
	border: 1px solid #e8edf7;
	border-bottom-left-radius: 6px;
}
.ask-ai-msg-ai .ask-ai-bubble.is-error {
	background: #fff5f5;
	border-color: #fecaca;
	color: #b91c1c;
}
.ask-ai-msg-ai .ask-ai-bubble code {
	background: #e8edf7;
	border-radius: 6px;
	padding: 1px 6px;
	font-size: 0.85em;
	color: #4338ca;
}
.ask-ai-typing {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 4px 2px;
}
.ask-ai-typing span {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: #94a3b8;
	animation: askAITyping 1.2s ease-in-out infinite;
}
.ask-ai-typing span:nth-child(2) { animation-delay: 0.15s; }
.ask-ai-typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes askAITyping {
	0%, 100% { transform: translateY(0); opacity: 0.4; }
	50% { transform: translateY(-5px); opacity: 1; }
}
.ask-ai-caret {
	display: inline-block;
	width: 2px;
	height: 1em;
	margin-left: 2px;
	vertical-align: text-bottom;
	background: var(--primary, #4c6fff);
	animation: askAICaret 0.9s steps(2) infinite;
}
@keyframes askAICaret {
	to { opacity: 0; }
}
/* --- input bar --- */
.ask-ai-inputbar {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px 16px;
	border-top: 1px solid #eef2f9;
	background: #fff;
	flex: 0 0 auto;
}
.ask-ai-input {
	flex: 1;
	border: 2px solid #eef2f9;
	background: #f8fafc;
	border-radius: 999px;
	padding: 12px 18px;
	font-size: 0.95rem;
	font-weight: 500;
	color: #1e293b;
	outline: none;
	transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
	min-width: 0;
}
.ask-ai-input:focus {
	border-color: var(--primary, #4c6fff);
	background: #fff;
	box-shadow: 0 4px 16px rgba(76, 111, 255, 0.12);
}
.ask-ai-input:disabled {
	opacity: 0.6;
}
.ask-ai-count {
	font-size: 0.7rem;
	font-weight: 700;
	color: #94a3b8;
	opacity: 0;
	transition: opacity 0.2s ease;
	white-space: nowrap;
}
.ask-ai-count.is-visible {
	opacity: 1;
}
.ask-ai-send {
	width: 46px;
	height: 46px;
	flex: 0 0 auto;
	border: none;
	border-radius: 50%;
	background: linear-gradient(135deg, var(--primary, #4c6fff), #6d5df6);
	color: #fff;
	font-size: 1.05rem;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 8px 20px -6px rgba(76, 111, 255, 0.6);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ask-ai-send:hover:not(:disabled) {
	transform: translateY(-2px) scale(1.05);
	box-shadow: 0 12px 26px -6px rgba(76, 111, 255, 0.7);
}
.ask-ai-send:active:not(:disabled) {
	transform: scale(0.96);
}
.ask-ai-send:disabled {
	cursor: default;
	opacity: 0.75;
}
/* --- pick mode --- */
.ask-ai-pickbar {
	position: fixed;
	top: 18px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 9992;
	display: flex;
	align-items: center;
	gap: 10px;
	background: #0f172a;
	color: #fff;
	border-radius: 999px;
	padding: 10px 18px;
	font-size: 0.9rem;
	font-weight: 600;
	box-shadow: 0 12px 30px rgba(15, 23, 42, 0.4);
	animation: askAIMsgIn 0.3s cubic-bezier(0.22, 1, 0.36, 1);
	max-width: calc(100vw - 24px);
}
.ask-ai-pickbar i {
	color: #38bdf8;
}
.ask-ai-pickbar button {
	border: none;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	border-radius: 999px;
	padding: 5px 14px;
	font-size: 0.8rem;
	font-weight: 700;
	cursor: pointer;
	transition: background 0.15s ease;
}
.ask-ai-pickbar button:hover {
	background: rgba(255, 255, 255, 0.28);
}
body.ask-ai-picking #whiteboard > li[data-uuid] {
	cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}
body.ask-ai-picking #whiteboard > li[data-uuid]:hover {
	transform: translateY(-3px) scale(1.01);
	box-shadow: 0 16px 40px rgba(76, 111, 255, 0.25) !important;
	outline: 3px solid var(--primary, #4c6fff);
	outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
	.ask-ai-backdrop,
	.ask-ai-panel,
	.ask-ai-msg,
	.ask-ai-typing span,
	.ask-ai-caret,
	#whiteboard > li.ask-ai-target {
		animation: none !important;
		transition: none !important;
	}
}

/* ============ Dark theme ============ */
/* theme.css stamps html[data-theme="dark"] and supplies the --tt-* scale
   (#0b1120 canvas / #111a2e surfaces / #263450 lines). Only colour-bearing
   declarations are restated here; layout stays with the light rules above.
   Vivid gamification artwork (chest glow/rays/confetti, combo badges,
   floating scores, cursor trails, fire/opened text gradients) already reads
   well on a dark canvas and is left untouched. */

/* Chest sheet + reward cards */
html[data-theme="dark"] #chestModal.offcanvas-bottom {
	background: var(--tt-surface, #111a2e);
	box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.45), 0 24px 60px rgba(0, 0, 0, 0.55);
}
html[data-theme="dark"] .chest-cards .card {
	background:
		radial-gradient(120% 70% at 50% -10%, rgba(var(--rw-c-rgb), 0.38), transparent 60%),
		linear-gradient(180deg, #1b2740, #121b30);
	border-color: rgba(var(--rw-c-rgb), 0.6);
	box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.06) inset, 0 0 28px rgba(var(--rw-c-rgb), 0.3);
}
html[data-theme="dark"] .rw-value,
html[data-theme="dark"] .rw-name { color: #f1f5f9; }
html[data-theme="dark"] .rw-label,
html[data-theme="dark"] .rw-kind { color: #94a3b8; }
html[data-theme="dark"] .rw-badge { box-shadow: 0 10px 22px rgba(0, 0, 0, 0.45), 0 0 0 4px rgba(255, 255, 255, 0.12) inset; }

/* Select2 (course/filter pickers) */
html[data-theme="dark"] .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
	background: var(--tt-surface-3, #1e2c48);
	color: var(--tt-ink, #e6ebf5);
}
html[data-theme="dark"] .select2-container--default .select2-selection--multiple {
	color: var(--tt-muted, #94a3b8);
	background-color: var(--tt-surface-2, #17233b);
	border-color: var(--tt-line-strong, #33436a);
}

/* Quest cards */
html[data-theme="dark"] .quest-item:hover {
	box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45) !important;
}
html[data-theme="dark"] .quest-icon-wrap {
	background: linear-gradient(145deg, rgba(96, 165, 250, 0.18) 0%, rgba(96, 165, 250, 0.1) 100%);
	box-shadow: inset 0 0 0 1px rgba(96, 165, 250, 0.3);
}
html[data-theme="dark"] .quest-title {
	color: var(--tt-ink, #e6ebf5);
}
html[data-theme="dark"] .quest-progress {
	background: var(--tt-surface-3, #1e2c48) !important;
	box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.35);
}

/* Buttons / misc chrome */
html[data-theme="dark"] .btn-outline-primary {
	background-color: var(--tt-surface, #111a2e);
}
html[data-theme="dark"] .bg-white .skill-bar {
	background-color: var(--tt-surface, #111a2e);
}
html[data-theme="dark"] .button-footer.footer.fixed {
	background-color: var(--tt-surface, #111a2e);
	border-top-color: var(--tt-line, #263450);
	box-shadow: 0 -8px 12px 0 rgba(0, 0, 0, 0.3);
}
html[data-theme="dark"] .needs-gray-outline:after {
	border-color: rgba(148, 163, 184, 0.5);
}
/* "or" divider: the white halo that lifts it off the light page becomes a
   canvas-coloured halo so the text doesn't wear a bright box. */
html[data-theme="dark"] .or-hr {
	color: var(--tt-muted, #94a3b8);
	text-shadow: 8px 0 var(--tt-bg, #0b1120), -8px 0 var(--tt-bg, #0b1120), 0 8px var(--tt-bg, #0b1120), 0 -8px var(--tt-bg, #0b1120), 4px 4px var(--tt-bg, #0b1120), -4px -4px var(--tt-bg, #0b1120), 4px -4px var(--tt-bg, #0b1120), -4px 4px var(--tt-bg, #0b1120);
}
/* The later .xp-text rule (primary text on a white glow) needs a dark glow. */
html[data-theme="dark"] .xp-text {
	text-shadow: 0 0 5px rgba(0, 0, 0, 0.65);
}

/* Lesson progress HUD pill */
html[data-theme="dark"] .lesson-progress-inner {
	background: linear-gradient(180deg, rgba(23, 35, 59, 0.92), rgba(17, 26, 46, 0.92));
	border-color: rgba(96, 165, 250, 0.22);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(230, 235, 245, 0.06);
}
html[data-theme="dark"] .lesson-progress-left {
	color: var(--tt-muted, #94a3b8);
}
html[data-theme="dark"] .lesson-progress-track {
	background: var(--tt-surface-3, #1e2c48);
	box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
}
html[data-theme="dark"] .lesson-progress-tick {
	background: rgba(230, 235, 245, 0.14);
}
html[data-theme="dark"] .lesson-progress-goal {
	background: var(--tt-surface-2, #17233b);
	border-color: var(--tt-line, #263450);
	color: var(--tt-muted, #94a3b8);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .lesson-progress-goal.reached {
	background: linear-gradient(135deg, #ffd34d, #f5a623);
	border-color: transparent;
	color: #fff;
	box-shadow: 0 0 10px rgba(245, 166, 35, 0.7);
}
html[data-theme="dark"] .lesson-progress-runner {
	border-color: var(--tt-surface, #111a2e);
}
html[data-theme="dark"] .lesson-progress-upcoming-dot {
	background: var(--tt-surface-2, #17233b);
	border-color: var(--tt-line, #263450);
	color: var(--tt-muted, #94a3b8);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

html[data-theme="dark"] .lesson-progress-peek {
	background: var(--tt-surface-2, #17233b);
	border-color: var(--tt-line, #263450);
	box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .lesson-progress-peek::before {
	border-color: var(--tt-line, #263450);
}
html[data-theme="dark"] .lesson-progress-peek-title,
html[data-theme="dark"] .lesson-progress-peek-tag,
html[data-theme="dark"] .lesson-progress-peek-list li.more,
html[data-theme="dark"] .lesson-progress-peek-footer {
	color: var(--tt-muted, #94a3b8);
}
html[data-theme="dark"] .lesson-progress-peek-list li {
	color: var(--tt-text, #e6ebf5);
}
html[data-theme="dark"] .lesson-progress-peek-list li.now {
	background: rgba(96, 165, 250, 0.14);
}
html[data-theme="dark"] .lesson-progress-peek-icon {
	background: var(--tt-surface-3, #1e2c48);
	color: var(--tt-muted, #94a3b8);
}
html[data-theme="dark"] .lesson-progress-peek-footer {
	border-top-color: var(--tt-line, #263450);
}
html[data-theme="dark"] .lesson-progress-peek-list li.now .lesson-progress-peek-tag {
	color: #6b9bff;
}

/* Ask Rio chat panel */
html[data-theme="dark"] .ask-ai-panel {
	background: var(--tt-surface, #111a2e);
	box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--tt-line, #263450);
}
html[data-theme="dark"] .ask-ai-thread {
	background:
		radial-gradient(circle at 85% 10%, rgba(109, 93, 246, 0.08), transparent 40%),
		radial-gradient(circle at 10% 90%, rgba(56, 189, 248, 0.08), transparent 40%),
		var(--tt-surface, #111a2e);
}
html[data-theme="dark"] .ask-ai-empty p {
	color: var(--tt-muted, #94a3b8);
}
html[data-theme="dark"] .ask-ai-chip {
	border-color: var(--tt-line, #263450);
	background: var(--tt-surface-2, #17233b);
	color: #c3cddd;
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}
html[data-theme="dark"] .ask-ai-chip:hover {
	border-color: #60a5fa;
	color: #60a5fa;
	box-shadow: 0 6px 16px rgba(96, 165, 250, 0.2);
}
html[data-theme="dark"] .ask-ai-msg-ai .ask-ai-bubble {
	background: var(--tt-surface-2, #17233b);
	color: var(--tt-ink, #e6ebf5);
	border-color: var(--tt-line, #263450);
}
html[data-theme="dark"] .ask-ai-msg-ai .ask-ai-bubble.is-error {
	background: rgba(248, 113, 113, 0.15);
	border-color: rgba(248, 113, 113, 0.4);
	color: #f87171;
}
html[data-theme="dark"] .ask-ai-msg-ai .ask-ai-bubble code {
	background: var(--tt-surface-3, #1e2c48);
	color: #a5b4fc;
}
html[data-theme="dark"] .ask-ai-inputbar {
	border-top-color: var(--tt-line, #263450);
	background: var(--tt-surface, #111a2e);
}
html[data-theme="dark"] .ask-ai-input {
	border-color: var(--tt-line, #263450);
	background: var(--tt-surface-2, #17233b);
	color: var(--tt-ink, #e6ebf5);
}
html[data-theme="dark"] .ask-ai-input::placeholder {
	color: var(--tt-muted, #94a3b8);
}
html[data-theme="dark"] .ask-ai-input:focus {
	border-color: #60a5fa;
	background: var(--tt-surface-3, #1e2c48);
	box-shadow: 0 4px 16px rgba(96, 165, 250, 0.15);
}
/* Pick-mode toolbar is already slate (#0f172a); just seat it on the canvas. */
html[data-theme="dark"] .ask-ai-pickbar {
	background: var(--tt-surface-3, #1e2c48);
	box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55), 0 0 0 1px var(--tt-line-strong, #33436a);
}


/* Practice page canvas - was an inline background: #e5f3ff in practice_body.templ */
.page-content.practice-canvas { background: #e5f3ff; }
html[data-theme="dark"] .page-content.practice-canvas { background: var(--tt-bg, #0b1120); }

/* ---------------------------------------------------------------------------
   Card swipe navigation (practice/swipe.js), mobile only
   --------------------------------------------------------------------------- */
@media (pointer: coarse) {
	#whiteboard > li[data-uuid] {
		touch-action: pan-y;
	}
}
body.tt-swiping,
body:has(#whiteboard > li.tt-swipe-exit) {
	overflow-x: clip;
}
body.tt-swiping {
	user-select: none;
	-webkit-user-select: none;
}
/* The card's containers clip it at the column edge mid-drag / mid fly-off.
   The page scrolls on <body> (clipped above), so these can safely open up. */
.chat-box-area:has(#whiteboard > li:is(.tt-swiping, .tt-swipe-exit)),
.chat-box-area:has(#whiteboard > li:is(.tt-swiping, .tt-swipe-exit)) .bottom-content {
	overflow: visible !important;
}
#whiteboard > li.tt-swiping {
	position: relative;
	will-change: transform;
	z-index: 5;
	box-shadow:
		0 24px 60px rgba(0, 0, 0, calc(0.25 + var(--tt-swipe-p, 0) * 0.2)),
		0 0 0 calc(var(--tt-swipe-p, 0) * 3px) rgba(73, 163, 255, calc(var(--tt-swipe-p, 0) * 0.55));
}
#whiteboard > li.tt-swiping.tt-swipe-armed {
	box-shadow:
		0 28px 70px rgba(0, 0, 0, 0.45),
		0 0 0 3px rgba(73, 163, 255, 0.9),
		0 0 40px rgba(73, 163, 255, 0.55);
}
@media (hover: hover) and (pointer: fine) {
	#whiteboard > li.tt-swipeable {
		cursor: grab;
	}
	#whiteboard > li.tt-swipeable.tt-swiping {
		cursor: grabbing;
	}
}
#whiteboard > li.tt-swipe-exit {
	pointer-events: none;
}
#whiteboard > li.tt-swipe-denied {
	animation: ttSwipeDenied .4s ease;
}
@keyframes ttSwipeDenied {
	0%, 100% { translate: 0; }
	25% { translate: -6px; }
	50% { translate: 6px; }
	75% { translate: -3px; }
}
#whiteboard > li.tt-swipe-nudge {
	animation: ttSwipeNudge 1.3s cubic-bezier(.45, 0, .2, 1);
}
@keyframes ttSwipeNudge {
	0%, 100% { translate: 0; rotate: 0deg; }
	30% { translate: -28px; rotate: -1.5deg; }
	55% { translate: 6px; rotate: .4deg; }
}
.tt-swipe-hint {
	position: fixed;
	left: 50%;
	bottom: calc(110px + env(safe-area-inset-bottom));
	transform: translateX(-50%);
	z-index: 1030; /* below offcanvas/modal (1040+) so sheets always cover it */
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 18px;
	border-radius: 999px;
	background: rgba(15, 23, 42, .85);
	color: #fff;
	font-weight: 700;
	font-size: .95rem;
	white-space: nowrap;
	box-shadow: 0 10px 30px rgba(0, 0, 0, .4), 0 0 0 1px rgba(255, 255, 255, .08);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	animation: ttSwipeHintIn .45s cubic-bezier(.34, 1.56, .64, 1);
	transition: opacity .35s ease, transform .35s ease;
}
.tt-swipe-hint i {
	color: #49a3ff;
	animation: ttSwipeHintHand 1.3s ease-in-out infinite;
}
.tt-swipe-hint-out {
	opacity: 0;
	transform: translate(-50%, 10px);
}
@keyframes ttSwipeHintIn {
	from { opacity: 0; transform: translate(-50%, 16px) scale(.8); }
	to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
@keyframes ttSwipeHintHand {
	0%, 100% { transform: translateX(6px) rotate(8deg); }
	50% { transform: translateX(-8px) rotate(-6deg); }
}

/* ------------------------------------------------------------------ */
/* Fill-in-the-blank: make the blank read as an input you type into,  */
/* not a decorative underline. Overrides the inline fallback styling   */
/* that content.blankInput ships for contexts without this sheet.      */
/* ------------------------------------------------------------------ */
.fib input.blank {
	box-sizing: content-box;
	min-width: 90px;
	margin: 0 0.15em;
	padding: 0.1em 0.6em !important;
	border: 2px dashed var(--primary, #008CFF) !important;
	border-radius: 10px;
	background: color-mix(in srgb, var(--primary, #008CFF) 10%, transparent) !important;
	color: inherit;
	font-weight: 700;
	text-align: center;
	line-height: 1.5;
	outline: none;
	cursor: text;
	caret-color: var(--primary, #008CFF);
	transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
	animation: tt-blank-beckon 1.6s ease-in-out infinite;
}
.fib input.blank::placeholder {
	color: var(--primary, #008CFF);
	opacity: 0.6;
	font-weight: 600;
	font-style: italic;
}
.fib input.blank:focus {
	border-style: solid !important;
	background: color-mix(in srgb, var(--primary, #008CFF) 16%, transparent) !important;
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary, #008CFF) 25%, transparent);
	animation: none;
}
.fib input.blank:focus::placeholder { opacity: 0.35; }
.fib input.blank[data-filled],
.fib input.blank:disabled {
	animation: none;
	border-style: solid !important;
	box-shadow: none;
	cursor: default;
}
@keyframes tt-blank-beckon {
	0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary, #008CFF) 45%, transparent); }
	50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary, #008CFF) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
	.fib input.blank { animation: none; }
}

.fill-hint {
	margin: 12px 4px 0;
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--tt-muted, #6b7280);
	display: flex;
	align-items: center;
	gap: 0.45em;
}
.fill-hint i { color: var(--primary, #008CFF); }
.fill-hint kbd {
	font: inherit;
	font-size: 0.8em;
	padding: 0.05em 0.45em;
	border-radius: 6px;
	border: 1px solid var(--tt-line, rgba(127,127,127,0.35));
	background: var(--tt-surface-2, rgba(127,127,127,0.12));
	color: inherit;
}
/* Once the blank is answered the instructions are noise. */
li[data-type="fill"].tapAway .fill-hint,
li[data-type="fill"]:has(input.blank[data-filled]) .fill-hint { display: none; }
@media (pointer: coarse) {
	.fill-hint kbd { display: none; }
}

/* ============ Standalone image card ============
   A picture piece on its own (no caption: Images.Description is the
   generation prompt, not learner copy) used to leave most of the board
   blank under a small card. The card now fills the gap between the header
   and the fixed footer and the picture scales into it, centred. The deck
   shows one card at a time (processContent benches the next piece), so the
   following piece is not shown underneath - it is usually a question whose
   answers must stay off the DOM until it is live. Heights are viewport
   based so a phone gets a tall picture and a laptop, where the column is
   wide but short, gets one that fits without scrolling. */
:root {
	/* header (top row + progress) and footer chrome around the board */
	--tt-image-card-chrome: 320px;
}
#whiteboard > li.tt-image-card {
	display: flex;
	flex-direction: column;
	/* !important: the li carries an inline min-height: 60px */
	min-height: max(320px, calc(100dvh - var(--tt-image-card-chrome))) !important;
}
#whiteboard > li.tt-image-card > .item-content {
	flex: 1 1 auto;
	display: flex;
}
#whiteboard > li.tt-image-card > .item-content > .item-inner {
	flex: 1 1 auto;
	align-items: center;
	align-content: center;
}
#whiteboard > li.tt-image-card .zoom-image {
	display: flex;
	align-items: center;
	justify-content: center;
	max-height: calc(100dvh - var(--tt-image-card-chrome) - 40px);
}
#whiteboard > li.tt-image-card .tt-image-card-img {
	/* the inline 500px cap kept the picture small on tall phones */
	max-height: calc(100dvh - var(--tt-image-card-chrome) - 40px) !important;
	width: auto !important;
	max-width: 100%;
	margin: 0 auto;
}
/* Two or three pictures side by side: let them share the row. */
#whiteboard > li.tt-image-card .zoom-image:not(:only-child) .tt-image-card-img {
	max-height: calc((100dvh - var(--tt-image-card-chrome)) / 2) !important;
}
@media (max-width: 767px) {
	:root { --tt-image-card-chrome: 290px; }
}
/* Laptops: short viewports, so keep a little air around the card. */
@media (min-width: 768px) and (max-height: 820px) {
	:root { --tt-image-card-chrome: 300px; }
}
