/* The player UI. The layout: the stage (canvas + HUD layer) fills the page; the full-width bottom bar carries the
   timeline on its top edge, the play controls, time and the map / player chips (hover cards expand upward without
   growing the bar) on the left and speed, volume, settings, first person and fullscreen on the right; panels and
   popovers are translucent glass over the scene. Hidden panels, popovers and cards are `display: none` and enter with a
   keyframe animation (an opacity-0 layer with a backdrop blur is still painted and rastered: Load 2 measured ~100 ms of
   GPU raster per load for two of them; a visibility-hidden one is still styled and laid out during the cold load).
   ?overlay=1 (overlay.js): a transparent page; the stage collapses into a draggable mini view above the bar. */

:root {
	--bar-row: 52px;
	--timeline-h: 18px;
	--bar-h: calc(var(--bar-row) + var(--timeline-h));
	--gutter: 16px;
	--glass: rgba(16, 16, 24, 0.58);
	--glass-strong: rgba(16, 16, 24, 0.8);
	--glass-border: rgba(255, 255, 255, 0.09);
	--glass-hi: rgba(255, 255, 255, 0.06);
	--blur: blur(18px) saturate(150%);
	--text: #f3f3f7;
	--dim: rgba(255, 255, 255, 0.64);
	--faint: rgba(255, 255, 255, 0.38);
	--accent: #e8317d;
	--accent2: #8e54e9;
	--grad: linear-gradient(90deg, #8e54e9, #e8317d);
	--radius: 16px;
	--radius-s: 10px;
	--ease: cubic-bezier(0.2, 0.8, 0.2, 1);
	--dur: 180ms;
	--shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.3);
	--safe-bottom: env(safe-area-inset-bottom, 0px);
}

html {
	background: #111;
	user-select: none;
	-webkit-tap-highlight-color: transparent;
}
html, body { margin: 0; height: 100%; overflow: hidden; }
body { background: #000; color: var(--text); font: 13px/1.4 system-ui, BlinkMacSystemFont, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif; }
button, input, select { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
.icon { width: 1em; height: 1em; vertical-align: -0.125em; flex: none; }
a { color: inherit; }

/* ---- the stage ---- */
#stage { position: fixed; inset: 0; overflow: hidden; contain: layout; }
#view { display: block; width: 100%; height: 100%; touch-action: none; }
#body:not(.showControls) #view { cursor: none; }

/* Diagnostics and load status (this player's own). */
#hud { position: fixed; right: 8px; bottom: calc(var(--bar-h) + 8px); white-space: pre; pointer-events: none; text-shadow: 0 0 3px #000; font-size: 11px; color: #aaa; display: none; }
#loading { position: fixed; right: var(--gutter); top: 12px; white-space: pre; text-align: right; pointer-events: none; text-shadow: 0 0 3px #000; color: #aaa; z-index: 5; }
#error { position: fixed; inset: 0; display: none; align-items: center; justify-content: center; text-align: center; padding: 16px; background: rgba(0, 0, 0, 0.6); z-index: 100000000; }
#drop { position: fixed; inset: 0; display: none; align-items: center; justify-content: center; font-size: 18px; background: rgba(0, 0, 0, 0.55); border: 3px dashed #888; pointer-events: none; z-index: 100000001; }

/* the in-world HUD's DOM items (hud.js): canvases placed by matrix3d in the stage */
#hudLayer { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 1; }
#hudLayer > * { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
#hudLayer > .hidden { display: none; }
#restartButton { pointer-events: auto; cursor: pointer; }

/* ---- glass ---- */
.glass, .panel, .popover > *, .card > .cardInner, #playlistContent, .glassButton {
	background: var(--glass);
	-webkit-backdrop-filter: var(--blur);
	backdrop-filter: var(--blur);
	border: 1px solid var(--glass-border);
	box-shadow: var(--shadow);
}
.glassButton { color: var(--text); border-radius: 999px; padding: 8px 16px; cursor: pointer; transition: background var(--dur) var(--ease), transform var(--dur) var(--ease); }
.glassButton:hover { background: var(--glass-strong); }
.glassButton:active { transform: scale(0.96); }

/* ---- the bottom bar ---- */
#controls {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 99999999;
	display: none;
	padding: 0 var(--gutter) var(--safe-bottom);
	background: linear-gradient(to top, rgba(8, 8, 12, 0.78), rgba(8, 8, 12, 0.5));
	-webkit-backdrop-filter: var(--blur);
	backdrop-filter: var(--blur);
	border-top: 1px solid var(--glass-border);
	transition: transform 320ms var(--ease), opacity 320ms var(--ease);
	transform: translateY(calc(100% + 4px));
	opacity: 0;
}
#controls.challengeLoaded { display: block; }
.showControls #controls { transform: none; opacity: 1; }
#controls p { margin: 0; }
#barRow { display: flex; align-items: center; justify-content: space-between; gap: 8px; height: var(--bar-row); }
#barLeft, #barRight { display: flex; align-items: center; gap: 4px; min-width: 0; }
#barLeft { flex: 1 1 auto; }
#barRight { flex: none; }

.barButton {
	position: relative;
	flex: none;
	width: 40px;
	height: 40px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: var(--radius-s);
	background: transparent;
	color: var(--text);
	font-size: 20px;
	cursor: pointer;
	transition: background var(--dur) var(--ease), transform 120ms var(--ease), color var(--dur) var(--ease);
}
.barButton:hover { background: rgba(255, 255, 255, 0.1); }
.barButton:active { transform: scale(0.92); }
.barButton:focus-visible, .chip:focus-visible, .tab-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.barButton:disabled { opacity: 0.35; cursor: default; }
.barButton.active, .popoverHost.open > .barButton { color: #fff; background: rgba(232, 49, 125, 0.35); }
.barButton.pill { width: auto; min-width: 48px; padding: 0 10px; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; gap: 4px; }
.songEffectiveSpeed { color: #ffcf66; font-size: 11px; display: none; }
.songEffectiveSpeed.on { display: inline; }
.playlistOnly, .overlayOnly { display: none !important; }
.playlistOpen .playlistOnly { display: inline-flex !important; }
html.overlay .overlayOnly { display: inline-flex !important; }
.controlsFullscreen .exitFullscreen, .controlsFullscreen.inFullscreen .enterFullscreen { display: none; }
.controlsFullscreen.inFullscreen .exitFullscreen { display: inline; }

/* play / pause: three round-capped bars (3 x 20 px capsules: cap centres 17 px apart) morph between two bars and an
   outlined equilateral triangle of side 17 px with round joins (the union of three capsules whose cap centres meet at
   the corners); its vertical edge is the left pause bar, which stays (on whole pixels: crisp at 1x), so its centroid
   is 0.41 px right of the button's centre. Each bar is placed from the button's centre by translate + rotate only (no
   scale: it would squash the caps), so the glyph is the same at every (even) button size. The bar's box sits on whole
   pixels (Chrome snaps a transformed box's fractional offset to a whole pixel): its centre is 0.5 px left of the
   button's centre, which every translate adds back. */
.playButton { width: 44px; height: 44px; border-radius: 50%; background: rgba(255, 255, 255, 0.1); }
.playButton:hover { background: rgba(255, 255, 255, 0.18); }
.playButton .bar { position: absolute; left: 50%; top: 50%; width: 3px; height: 20px; margin: -10px 0 0 -2px; border-radius: 1.5px; background-color: #fff; transition: transform 320ms var(--ease); }
/* pause: bars centred 4.5 px either side (on whole pixels: 16..19 and 25..28 of a 44 px button) */
.playButton.pause .bar-1, .playButton.pause .bar-3 { transform: translate(-4px, 0) rotate(0deg); }
.playButton.pause .bar-2 { transform: translate(5px, 0) rotate(0deg); }
/* play: corners from the button's centre top (-4.5, -8.5), bottom (-4.5, 8.5), tip (10.222, 0) (17 * sqrt(3) / 2 =
   14.722 right of the edge); each slanted bar at its edge's midpoint (2.861, -/+4.25) */
.playButton.play .bar-1 { transform: translate(3.361px, -4.25px) rotate(-60deg); }
.playButton.play .bar-2 { transform: translate(3.361px, 4.25px) rotate(60deg); }
.playButton.play .bar-3 { transform: translate(-4px, 0) rotate(0deg); }

#songTime { flex: none; margin: 0 6px 0 4px !important; color: var(--dim); font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; }
#songProgress { color: var(--text); }

/* the map / player chips and their cards (hover / focus / .open on touch); the card is absolute: the bar does not grow */
#infoChips { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1 1 auto; }
.chip {
	position: relative;
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
	max-width: 280px;
	height: 40px;
	padding: 4px 10px 4px 4px;
	border-radius: 12px;
	background: rgba(255, 255, 255, 0.05);
	cursor: default;
	outline: none;
	transition: background var(--dur) var(--ease);
}
.chip:hover, .chip.open, .chip:focus-within { background: rgba(255, 255, 255, 0.12); }
.chip.empty { display: none; }
.chipImage { width: 32px; height: 32px; border-radius: 8px; object-fit: cover; flex: none; background: rgba(255, 255, 255, 0.06); }
.chipImage.round { border-radius: 50%; }
.chipText { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.chipTitle { font-weight: 650; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chipSub { display: flex; align-items: center; gap: 5px; color: var(--dim); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chipSub > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.flag { width: 16px; height: 11px; border-radius: 2px; flex: none; }
.flag[src=""], .flag:not([src]) { display: none; }
.diffBadge { flex: none; padding: 0 5px; border-radius: 4px; color: #fff; font-size: 10px; font-weight: 600; line-height: 15px; }
.diffBadge:empty { display: none; }

/* hidden = display none (not styled or laid out during the load); shown with a keyframe entrance */
.card { position: absolute; left: 0; bottom: calc(100% + 14px); width: 340px; max-width: calc(100vw - 2 * var(--gutter)); display: none; z-index: 3; }
.card::before { content: ''; position: absolute; left: 0; right: 0; bottom: -16px; height: 18px; }
.card > .cardInner { background: var(--glass-strong); border-radius: var(--radius); padding: 14px; transform-origin: 20% 100%; max-height: calc(100vh - var(--bar-h) - 40px); overflow: auto; animation: cardIn 220ms var(--ease); }
@keyframes cardIn { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }
.chip:hover > .card, .chip.open > .card, .chip:focus-within > .card { display: block; }
.chip.empty > .card { display: none !important; }
.cardHead { display: flex; gap: 12px; align-items: center; }
.cardHead > img { width: 72px; height: 72px; border-radius: 12px; object-fit: cover; flex: none; background: rgba(255, 255, 255, 0.06); }
.cardHead > img.round { border-radius: 50%; }
.cardSub .flag { vertical-align: -1px; }
.cardTitle { font-size: 16px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.cardTitle a { text-decoration: none; }
.cardTitle a:hover { text-decoration: underline; }
.cardSub { color: var(--dim); font-size: 12px; margin-top: 2px; overflow-wrap: anywhere; }
.cardBadges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.badge { padding: 1px 7px; border-radius: 999px; background: rgba(255, 255, 255, 0.1); font-size: 11px; font-weight: 600; white-space: nowrap; }
.badge.warn { background: rgba(255, 80, 80, 0.3); color: #ffd0d0; }
.badge.ranked { background: rgba(255, 196, 0, 0.25); color: #ffe08a; }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 12px; }
.stat { padding: 7px 8px; border-radius: 10px; background: rgba(255, 255, 255, 0.05); min-width: 0; }
.stat b { display: block; font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat span { display: block; color: var(--faint); font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; }
.stat.pp b { color: #a8b1ff; }
.stat.good b { color: #8ff0a4; }
.stat.bad b { color: #ff9c9c; }
.cardLines { margin-top: 10px; display: flex; flex-direction: column; gap: 3px; color: var(--dim); font-size: 12px; }
.cardLines b { color: var(--text); font-weight: 600; }
.cardLinks { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.cardLinks a { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 999px; background: rgba(255, 255, 255, 0.08); text-decoration: none; font-size: 12px; transition: background var(--dur) var(--ease); }
.cardLinks a:hover { background: rgba(255, 255, 255, 0.16); }

/* ---- the timeline: the track on the bar's top edge, the accuracy graph above it while hovered ---- */
#timeline { position: relative; height: var(--timeline-h); margin: 0 2px; cursor: pointer; touch-action: none; }
#timelineTrack { position: absolute; left: 0; right: 0; top: 7px; height: 4px; border-radius: 4px; background: rgba(255, 255, 255, 0.16); transition: height 140ms var(--ease), top 140ms var(--ease); overflow: hidden; }
#timeline:hover #timelineTrack, #timeline.active #timelineTrack { top: 5.5px; height: 7px; }
#timelineBuffered { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: rgba(255, 255, 255, 0.28); transition: width 300ms linear; }
#timelineBuffered.done { display: none; }
#playhead { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--grad); background-size: var(--track-w, 100vw) 100%; }
#timelineKnob { position: absolute; top: 9px; left: 0; width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 3px rgba(232, 49, 125, 0.5); transform: scale(0); transition: transform 140ms var(--ease); pointer-events: none; z-index: 3; }
#timeline:hover #timelineKnob, #timeline.active #timelineKnob { transform: scale(1); }
/* The hover zone: the timeline's box at rest; while raised, the graph and its backdrop join it (they take the pointer:
   the timeline stays hovered over them). It only grows on hover, so no pointer position can toggle it (an element
   that leaves hit testing on hover, as the markers canvas did, flips the hover every frame). */
#timelineGraph { position: absolute; left: 0; right: 0; bottom: calc(100% - 4px); height: 84px; pointer-events: none; opacity: 0; transform: translateY(6px); transition: opacity 180ms var(--ease), transform 220ms var(--ease); visibility: hidden; }
#timeline:hover #timelineGraph, #timeline.active #timelineGraph { opacity: 1; transform: none; visibility: visible; pointer-events: auto; }
#timelineGraph::before { content: ''; position: absolute; left: calc(-1 * var(--gutter) - 2px); right: calc(-1 * var(--gutter) - 2px); top: -14px; bottom: -8px; background: linear-gradient(to top, rgba(8, 8, 12, 0.82), rgba(8, 8, 12, 0.55) 70%, rgba(8, 8, 12, 0)); }
#timelineGraph canvas { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
#timelinePlayedClip { position: absolute; left: 0; top: 0; bottom: 0; width: 0; overflow: hidden; }
#timelinePlayedClip canvas { width: var(--track-w, 100vw); }
#timelineMarkers { position: absolute; left: 0; top: -6px; width: 100%; height: 14px; z-index: 2; pointer-events: none; }
#timeline:hover #timelineMarkers, #timeline.active #timelineMarkers { visibility: hidden; }
#timelineHover { position: absolute; bottom: calc(100% + 86px); left: 0; display: none; padding: 5px 9px; border-radius: 9px; background: var(--glass-strong); border: 1px solid var(--glass-border); color: #fff; font-size: 12px; white-space: pre; pointer-events: none; font-variant-numeric: tabular-nums; transform: translateX(-50%); z-index: 4; }
#timelineHover.timelineHoverActive { display: block; }
#timelineHover .dim { color: var(--dim); }

/* ---- popovers over the bar (speed, volume) ---- */
.popoverHost { position: relative; }
.popover { position: absolute; right: -6px; bottom: calc(100% + 14px); display: none; z-index: 3; }
.popover > * { box-shadow: none; border: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.popover { width: 260px; padding: 12px; border-radius: var(--radius); background: var(--glass-strong); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); border: 1px solid var(--glass-border); box-shadow: var(--shadow); }
.popover.open, .popoverHost.open > .popover { display: block; animation: popoverIn 200ms var(--ease); }
@keyframes popoverIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.popoverTitle { display: flex; align-items: center; justify-content: space-between; margin: 0 4px 8px; font-weight: 650; }
.popoverTitle output { color: var(--dim); font-variant-numeric: tabular-nums; }
.presetRow { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.presetRow button, .chipButton { border: 0; border-radius: 999px; padding: 3px 9px; background: rgba(255, 255, 255, 0.08); font-size: 12px; cursor: pointer; transition: background var(--dur) var(--ease); }
.presetRow button:hover, .chipButton:hover { background: rgba(255, 255, 255, 0.16); }
.presetRow button.active, .chipButton.selected { background: var(--grad); color: #fff; }
.presetRow button.modifier { font-weight: 700; }
#speedSlider { width: 100%; }
.volumeHide { display: none !important; }
#volumeSliderContainer { width: 300px; max-width: calc(100vw - 2 * var(--gutter)); }
#volumeSliderContainer .row { padding: 4px; }
#volumeSliderContainer .rowLabel { white-space: nowrap; }
#volumeSliderContainer .row .settingRange { width: 130px; }

/* ---- panels ---- */
.panel { border-radius: 18px; }
#settingsContainer {
	position: fixed;
	right: var(--gutter);
	bottom: calc(var(--bar-h) + 12px + var(--safe-bottom));
	width: min(620px, calc(100vw - 2 * var(--gutter)));
	height: min(580px, calc(100vh - var(--bar-h) - 40px));
	display: none;
	flex-direction: column;
	z-index: 100000000;
	background: var(--glass-strong);
	transform-origin: 90% 100%;
	overflow: hidden;
}
#settingsContainer.settingsActive { display: flex; animation: panelIn 240ms var(--ease); }
@keyframes panelIn { from { opacity: 0; transform: translateY(12px) scale(0.985); } to { opacity: 1; transform: none; } }
.panelHeader { display: flex; align-items: center; justify-content: space-between; padding: 10px 10px 6px 18px; flex: none; }
.panelTitle { font-size: 15px; font-weight: 700; }
.iconButton { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 9px; background: transparent; font-size: 16px; cursor: pointer; transition: background var(--dur) var(--ease); }
.iconButton:hover { background: rgba(255, 255, 255, 0.1); }
.tab-container { display: flex; flex: 1; min-height: 0; }
.tab-buttons { flex: none; width: 150px; display: flex; flex-direction: column; gap: 2px; padding: 4px 8px 12px; overflow-y: auto; }
.tab-button { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 0; border-radius: 10px; background: transparent; color: var(--dim); cursor: pointer; text-align: left; font-size: 13px; font-weight: 550; transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.tab-button .icon { font-size: 16px; }
.tab-button:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.tab-button.active { background: rgba(255, 255, 255, 0.1); color: #fff; box-shadow: inset 3px 0 0 var(--accent); }
.tab-content { flex: 1; min-width: 0; overflow-y: auto; padding: 0 12px 16px 4px; scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.2) transparent; }
.tab-pane { display: none; }
.tab-pane.active { display: block; animation: paneIn 220ms var(--ease); }
@keyframes paneIn { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: none; } }
.tab-pane h3 { margin: 14px 10px 4px; color: var(--faint); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; }
.tab-pane h3:first-child { margin-top: 4px; }

/* setting rows */
.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 36px; padding: 4px 10px; border-radius: 10px; transition: background var(--dur) var(--ease); }
.row:hover { background: rgba(255, 255, 255, 0.04); }
.rowLabel { flex: 1 1 auto; min-width: 0; color: var(--text); display: flex; align-items: center; gap: 8px; }
.rowValue { flex: none; min-width: 42px; text-align: right; color: var(--dim); font-variant-numeric: tabular-nums; font-size: 12px; }
.row.range .settingRange { flex: 0 1 190px; min-width: 90px; }
.rowControls { display: flex; gap: 6px; }
.markerIcon { width: 14px; height: 14px; }
.hint { margin: 2px 10px 6px; color: var(--faint); font-size: 11px; line-height: 1.35; overflow-wrap: anywhere; }
.hint.error { color: #ff8a8a; }
.hint:empty { display: none; }
.jumpOption { display: none; }
.jumpOption.on { display: flex; }
.phoneOnly { display: none !important; }
.buttonRow { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 10px; }
.buttonColumn { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 4px 10px; }
.segmented { display: inline-flex; margin: 4px 10px 6px; padding: 3px; border-radius: 11px; background: rgba(255, 255, 255, 0.07); }
.segmented button { border: 0; border-radius: 8px; padding: 6px 12px; background: transparent; color: var(--dim); cursor: pointer; font-weight: 600; transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.segmented button.active { background: rgba(255, 255, 255, 0.14); color: #fff; }

.settingButton { border: 0; border-radius: 9px; padding: 6px 12px; background: rgba(255, 255, 255, 0.09); color: var(--text); cursor: pointer; font-size: 12.5px; display: inline-flex; align-items: center; gap: 6px; transition: background var(--dur) var(--ease), transform 120ms var(--ease); }
.settingButton:hover:enabled { background: rgba(255, 255, 255, 0.16); }
.settingButton:active:enabled { transform: scale(0.97); }
.settingButton:disabled { opacity: 0.4; cursor: default; }
.linkButton { background: transparent; color: var(--dim); }
.settingSelect { flex: none; max-width: 190px; border: 1px solid var(--glass-border); border-radius: 9px; padding: 5px 8px; background: rgba(0, 0, 0, 0.35); color: var(--text); cursor: pointer; font-size: 12.5px; }
.settingSelect option { background: #1b1b22; color: #fff; }
input[type=color] { flex: none; width: 34px; height: 24px; padding: 0; border: 0; border-radius: 7px; background: none; cursor: pointer; }
input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
input[type=color]::-webkit-color-swatch { border: 1px solid rgba(255, 255, 255, 0.25); border-radius: 7px; }
.schemeGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; padding: 6px 10px; }
.schemeColor { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 4px; border-radius: 12px; background: rgba(255, 255, 255, 0.05); cursor: pointer; font-size: 11px; color: var(--dim); }
.schemeColor input[type=color] { width: 44px; height: 30px; }
.notesOnly .lightsColor { opacity: 0.35; }
#colorOverrideDetails { transition: opacity var(--dur) var(--ease); }
#colorOverrideDetails.off { opacity: 0.4; pointer-events: none; }
#resetColors { margin: 10px; }
/* the replay player's profile scheme: an unset key shows its default dimmed; the clear button only on set keys */
.profileColor { position: relative; }
.profileColor.unset input[type=color] { opacity: 0.35; }
.profileColor.unset span::after { content: ' (not set)'; color: var(--faint); }
.clearColor { position: absolute; top: 2px; right: 4px; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.12); color: var(--dim); font-size: 12px; line-height: 18px; cursor: pointer; }
.clearColor:hover { background: rgba(255, 255, 255, 0.24); color: #fff; }
.profileColor.unset .clearColor { display: none; }
#profileColors.notApplied .profileGrid { opacity: 0.55; }

/* Hit scores tab (hit-scores-ui.js) */
.hsvList { display: flex; flex-direction: column; gap: 3px; padding: 4px 10px; }
.hsvItem { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 32px; padding: 4px 10px; border: 1px solid transparent; border-radius: 10px; background: rgba(255, 255, 255, 0.04); color: var(--text); text-align: left; cursor: pointer; transition: background var(--dur) var(--ease); }
.hsvItem:hover { background: rgba(255, 255, 255, 0.09); }
.hsvItem.selected { border-color: var(--accent); background: rgba(232, 49, 125, 0.12); }
.hsvName { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hsvTag { flex: none; font-size: 10.5px; color: var(--faint); }
.hsvShared { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 10px; color: var(--dim); font-size: 12px; }
.hsvImport { display: flex; flex-direction: column; gap: 6px; padding: 4px 10px; }
.hsvImport[hidden], .hsvImport [hidden] { display: none; }
.hsvImport textarea, .hsvImport input, .hsvRaw { width: 100%; box-sizing: border-box; border: 1px solid var(--glass-border); border-radius: 9px; padding: 6px 8px; background: rgba(0, 0, 0, 0.35); color: var(--text); font: 12px/1.35 ui-monospace, Consolas, monospace; user-select: text; }
.hsvMessage.error { color: #ff8a8a; }
.hsvServerRow { display: flex; align-items: center; gap: 4px; padding: 2px 10px; }
.hsvServerRow .iconButton { width: 28px; height: 28px; font-size: 14px; color: var(--dim); }
.hsvServerRow .iconButton[aria-pressed=true] { color: #ffd34d; }
.hsvServer > .settingButton { margin: 6px 10px; }
.hsvEditor { padding-bottom: 12px; }
.hsvEditor > .settingButton { margin: 6px 10px; }
.hsvEditor h4 { margin: 10px 10px 4px; font-size: 12px; color: var(--dim); }
.hsvStatus { margin: 4px 10px; padding: 6px 10px; border-radius: 9px; background: rgba(80, 200, 120, 0.12); color: var(--dim); font-size: 12px; }
.hsvStatus.error { background: rgba(255, 90, 90, 0.14); color: #ffb0b0; }
.hsvStatus .error { color: #ff8a8a; }
.hsvNum { width: 64px; flex: none; border: 1px solid var(--glass-border); border-radius: 7px; padding: 3px 5px; background: rgba(0, 0, 0, 0.35); color: var(--text); font-size: 12px; }
.hsvText { width: 100%; min-width: 0; box-sizing: border-box; border: 1px solid var(--glass-border); border-radius: 7px; padding: 4px 6px; background: rgba(0, 0, 0, 0.35); color: var(--text); font: 12px ui-monospace, Consolas, monospace; user-select: text; }
.row > .hsvText { max-width: 220px; }
.hsvVersion, .hsvVector, .hsvColor { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.hsvListEdit { margin: 6px 10px; padding: 6px; border-radius: 10px; background: rgba(255, 255, 255, 0.03); }
.hsvListHead { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 4px 4px; }
.hsvListLabel { color: var(--text); font-size: 12.5px; }
.hsvEnable, .hsvFade { display: inline-flex; align-items: center; gap: 3px; color: var(--dim); font-size: 11.5px; white-space: nowrap; }
.hsvRow { display: flex; align-items: center; gap: 5px; padding: 2px 0; flex-wrap: wrap; }
.hsvRow .iconButton { width: 26px; height: 26px; font-size: 13px; }
.hsvCell { display: inline-flex; align-items: center; gap: 4px; color: var(--faint); font-size: 11px; }
.hsvWide { flex: 1 1 140px; min-width: 120px; }
.hsvAdd { margin-top: 4px; }
.hsvPreview { display: flex; flex-direction: column; gap: 2px; padding: 0 10px; }
.hsvSample { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--dim); }
.hsvSample code { color: var(--text); overflow-wrap: anywhere; user-select: text; }
.hsvSampleLabel { flex: none; width: 92px; color: var(--faint); }
.hsvSwatch { flex: none; width: 12px; height: 12px; border-radius: 3px; border: 1px solid rgba(255, 255, 255, 0.3); }
.hsvRawBox { margin: 6px 10px; }
.hsvRawBox summary { cursor: pointer; color: var(--dim); font-size: 12px; }
/* the visual config editor (hsv-editor.js) */
.hsvFaint { color: var(--faint); font-size: 11px; }
.hsvProblems { display: flex; flex-direction: column; gap: 4px; margin: 6px 10px; padding: 6px 10px; border-radius: 9px; background: rgba(255, 90, 90, 0.14); color: #ffd0d0; font-size: 12px; }
.hsvProblems.ok { background: rgba(80, 200, 120, 0.12); color: var(--dim); }
.hsvProblem { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.hsvProblem .settingButton { flex: none; margin: 0; padding: 3px 9px; font-size: 11.5px; }
.hsvRules { color: var(--faint); font-size: 11px; }
.hsvRules summary { cursor: pointer; }
.hsvStripHead { margin: 8px 10px 4px; color: var(--dim); font-size: 12px; }
.hsvStrip { display: grid; grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); gap: 4px; padding: 0 10px; }
.hsvStripCell { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 0; color: var(--faint); font-size: 10.5px; }
.hsvStripCanvas, .hsvModeCanvas, .hsvTextPreview { display: block; width: 100%; height: auto; border-radius: 7px; background: #0b0b12; }
.hsvTabs { display: flex; flex-wrap: wrap; margin: 10px 10px 4px; }
.hsvTabs button { padding: 5px 9px; font-size: 12px; }
.hsvSection { margin: 6px 10px 10px; padding: 8px; border-radius: 10px; background: rgba(255, 255, 255, 0.03); }
.hsvEditor .hsvSection h4, .hsvEditor .hsvStart h4 { margin: 0 0 4px; color: var(--text); font-size: 12.5px; }
.hsvSectionHead { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; }
.hsvSectionHead .hsvZoom { margin-left: auto; }
.hsvSection > .row { padding: 4px 0; }
.hsvSection > .settingButton { margin: 6px 6px 0 0; }
.hsvModes { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 5px; }
.hsvMode { display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 6px; border: 1px solid var(--glass-border); border-radius: 9px; background: rgba(255, 255, 255, 0.04); color: var(--text); text-align: left; cursor: pointer; transition: background var(--dur) var(--ease); }
.hsvMode:hover:not(:disabled) { background: rgba(255, 255, 255, 0.09); }
.hsvMode.selected { border-color: var(--accent); background: rgba(232, 49, 125, 0.12); }
.hsvMode:disabled { cursor: default; }
.hsvModeName { font-size: 12px; font-weight: 600; }
.hsvModeDesc { color: var(--faint); font-size: 10.5px; line-height: 1.3; }
.hsvBarWrap { position: relative; margin: 6px 0 2px; }
.hsvHist { display: block; width: 100%; height: 30px; }
.hsvBar { position: relative; height: 26px; overflow: hidden; border-radius: 6px; background: rgba(255, 255, 255, 0.05); touch-action: none; }
.hsvRegion { position: absolute; top: 0; bottom: 0; box-sizing: border-box; overflow: hidden; border-right: 1px solid rgba(0, 0, 0, 0.55); cursor: pointer; }
.hsvRegion.uncovered { background: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.07) 0 4px, transparent 4px 8px); cursor: default; }
.hsvRegion.selected { box-shadow: inset 0 0 0 2px #fff, inset 0 0 0 3px rgba(0, 0, 0, 0.7); }
.hsvRegionLabel { position: absolute; left: 4px; top: 50%; transform: translateY(-50%); color: #fff; font-size: 10.5px; font-weight: 650; white-space: nowrap; text-shadow: 0 0 3px #000, 0 0 2px #000; pointer-events: none; }
.hsvHandle { position: absolute; top: 0; bottom: 0; z-index: 2; width: 14px; margin-left: -7px; cursor: ew-resize; touch-action: none; }
.hsvHandle::after { content: ''; position: absolute; top: 0; bottom: 0; left: 6px; width: 2px; background: #fff; box-shadow: 0 0 2px #000; }
.hsvHandle:focus-visible { outline: none; }
.hsvHandle:focus-visible::after { left: 4px; width: 6px; background: var(--accent); }
.hsvTip { position: absolute; top: 0; z-index: 3; transform: translateX(-50%); padding: 1px 6px; border-radius: 6px; background: rgba(0, 0, 0, 0.85); color: #fff; font-size: 11px; white-space: nowrap; pointer-events: none; }
.hsvTip[hidden] { display: none; }
.hsvScale { position: relative; height: 14px; color: var(--faint); font-size: 10px; }
.hsvScale span { position: absolute; top: 1px; transform: translateX(-50%); white-space: nowrap; }
.hsvScale span.first { transform: none; }
.hsvScale span.last { transform: translateX(-100%); }
.hsvBarWrap .hint, .hsvSection > .hint { margin: 3px 0; }
.hsvRegionEdit, .hsvDisplay { margin-top: 6px; padding: 6px; border-radius: 8px; background: rgba(255, 255, 255, 0.04); }
.hsvRegionEdit .settingButton, .hsvDisplay .settingButton { margin: 0; padding: 3px 9px; font-size: 11.5px; }
.hsvOpacity { display: inline-flex; align-items: center; gap: 4px; color: var(--dim); font-size: 11.5px; }
.hsvOpacity input { width: 80px; }
.hsvOpacity .rowValue { min-width: 32px; }
.hsvBuilder { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.hsvChips { display: flex; flex-wrap: wrap; gap: 3px; min-height: 30px; padding: 4px; box-sizing: border-box; border: 1px solid var(--glass-border); border-radius: 8px; background: rgba(0, 0, 0, 0.3); }
.hsvChip { padding: 2px 7px; border: 1px solid transparent; border-radius: 6px; background: rgba(255, 255, 255, 0.12); color: var(--text); font-size: 11.5px; white-space: pre; cursor: pointer; }
.hsvChip.tok { background: rgba(60, 140, 255, 0.3); }
.hsvChip.tag { background: rgba(255, 200, 60, 0.16); color: #ffe3a0; font-size: 10.5px; }
.hsvChip.tag.close { opacity: 0.7; }
.hsvChip.unknown { background: rgba(255, 255, 255, 0.05); color: var(--faint); }
.hsvChip.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.hsvTools { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; }
.hsvAddChip, .hsvStyle { padding: 2px 7px; border: 1px solid var(--glass-border); border-radius: 6px; background: rgba(255, 255, 255, 0.05); color: var(--text); font-size: 11px; cursor: pointer; }
.hsvAddChip:hover, .hsvStyle:hover { background: rgba(255, 255, 255, 0.12); }
.hsvAddChip.tok { border-color: rgba(60, 140, 255, 0.55); }
.hsvStyle { min-width: 24px; font-weight: 700; }
.hsvStyle-i { font-style: italic; }
.hsvStyle-u { text-decoration: underline; }
.hsvStyle-s { text-decoration: line-through; }
.hsvTools .settingSelect { padding: 2px 6px; font-size: 11px; }
.hsvDiagram svg { display: block; }
.hsvStart { display: flex; flex-direction: column; gap: 6px; margin: 6px 10px; padding: 8px; border: 1px solid var(--accent); border-radius: 10px; background: rgba(232, 49, 125, 0.06); }
.hsvStart .settingButton { margin: 0 6px 0 0; }

/* switches */
.switch { position: relative; display: inline-block; flex: none; width: 38px; height: 22px; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; z-index: 1; }
.slider { position: absolute; inset: 0; border-radius: 999px; background: rgba(255, 255, 255, 0.16); transition: background var(--dur) var(--ease); pointer-events: none; }
.slider::before { content: ''; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); transition: transform var(--dur) var(--ease); }
input:checked + .slider { background: var(--grad); }
input:checked + .slider::before { transform: translateX(16px); }
input:focus-visible + .slider { outline: 2px solid var(--accent); outline-offset: 2px; }
.toggleButtonLabel { color: var(--text); font-size: 12px; }

/* sliders */
input[type=range].settingRange { -webkit-appearance: none; appearance: none; height: 24px; margin: 0; padding: 0; background: transparent; cursor: pointer; touch-action: none; accent-color: var(--accent); }
input[type=range].settingRange::-webkit-slider-runnable-track { height: 4px; border-radius: 4px; background: linear-gradient(90deg, var(--accent2), var(--accent)) 0 / var(--fill, 0%) 100% no-repeat, rgba(255, 255, 255, 0.16); }
input[type=range].settingRange::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; margin-top: -6px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); transition: transform 120ms var(--ease); }
input[type=range].settingRange:hover::-webkit-slider-thumb { transform: scale(1.12); }
input[type=range].settingRange::-moz-range-track { height: 4px; border-radius: 4px; background: rgba(255, 255, 255, 0.16); }
input[type=range].settingRange::-moz-range-progress { height: 4px; border-radius: 4px; background: var(--grad); }
input[type=range].settingRange::-moz-range-thumb { width: 16px; height: 16px; border: 0; border-radius: 50%; background: #fff; }
@media (pointer: coarse) {
	input[type=range].settingRange { height: 36px; }
	input[type=range].settingRange::-webkit-slider-thumb { width: 22px; height: 22px; margin-top: -9px; }
	.row { min-height: 44px; }
}

/* the JD slider's marks: the map's default (click: use it) and the effective VNJS jump distance */
.jdSlider { position: relative; flex: 0 1 190px; min-width: 90px; display: flex; flex-direction: column; }
.row.range .jdSlider .settingRange { flex: none; width: 100%; min-width: 0; }
.jdMarks { position: relative; height: 14px; margin: -4px 8px 0; }
.jdTick { position: absolute; top: 0; width: 1px; height: 5px; background: var(--faint); }
.jdTick.vnjs { background: #ff6b6b; }
.jdPoint { position: absolute; top: 4px; transform: translateX(-50%); font-size: 10px; color: var(--dim); cursor: pointer; white-space: nowrap; }
.jdTick.vnjs .jdPoint { color: #ff6b6b; cursor: default; top: -16px; }
.jdPoint:hover { color: var(--accent); }

/* settings with no feature behind them yet (settings.js UNSUPPORTED: the tooltip says what they need) */
.unsupported { opacity: 0.42; }
.unsupported .slider, .unsupported input, .unsupported select { cursor: not-allowed; }

/* ---- the context menu ---- */
#ctxMenu { display: none; position: fixed; overflow: hidden; border-radius: 12px; background: var(--glass-strong); z-index: 100000002; font-size: 13px; padding: 4px; min-width: 240px; animation: popIn 140ms var(--ease); }
@keyframes popIn { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: none; } }
.panel-menu { display: flex; flex-direction: column; color: #eee; }
.menuitem { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 8px; cursor: default; outline: none; }
.menuitem:hover, .menuitem:focus-visible { background: rgba(255, 255, 255, 0.1); }
.menuitem.unsupported:hover { background: none; }
.menuitem-icon { width: 18px; display: inline-flex; justify-content: center; color: var(--dim); }

/* ---- skip intro, random replay ---- */
#skipIntro { position: fixed; left: var(--gutter); bottom: calc(var(--bar-h) + 16px + var(--safe-bottom)); z-index: 99999998; font-size: 13px; font-weight: 600; }
#randomReplay { position: fixed; display: flex; gap: 12px; right: var(--gutter); bottom: calc(var(--bar-h) + 16px + var(--safe-bottom)); padding: 12px; border-radius: var(--radius); max-width: min(320px, calc(100vw - 2 * var(--gutter))); z-index: 10000; animation: popIn 200ms var(--ease); }
#randomReplayInfo { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
#randomReplayInfo > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#randomReplayNext { font-weight: 700; text-decoration: none; }
#randomReplayImage { width: 60px; height: 60px; border-radius: 10px; object-fit: cover; }
#randomReplayButtons { display: flex; gap: 2px; margin-top: 4px; }
.playlistOpen #randomReplay { display: none !important; }

/* ---- hotkey notification ---- */
.hotkey-notification { position: fixed; bottom: calc(var(--bar-h) + 60px); left: 50%; transform: translateX(-50%); background: var(--glass); border: 1px solid var(--glass-border); border-radius: 18px; padding: 18px 28px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; z-index: 999999999; min-width: 200px; -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); transition: opacity 0.2s ease, transform 0.2s ease; pointer-events: none; }
/* hidden: also visibility hidden once faded out (an opacity-0 layer is still painted and rastered: its blur and text cost
   the GPU process ~100 ms of raster while the page loads) */
.hotkey-notification.hidden { opacity: 0; transform: translateX(-50%) translateY(20px); visibility: hidden; transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s; }
.hotkey-notification.visible { opacity: 1; transform: translateX(-50%) translateY(0); visibility: visible; }
.hotkey-notification .hotkey-icon { font-size: 34px; color: var(--accent); display: flex; }
.hotkey-notification .hotkey-text { font-size: 17px; font-weight: 600; color: #fafafa; text-align: center; white-space: nowrap; }
.hotkey-notification .hotkey-note { font-size: 11px; color: rgba(255, 255, 255, 0.4); text-align: center; margin-top: 2px; }
.hotkey-notification .hotkey-note kbd { display: inline-block; padding: 2px 5px; font-family: inherit; font-size: 10px; font-weight: 600; color: rgba(255, 255, 255, 0.6); background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.15); border-radius: 3px; margin: 0 2px; }

/* ---- hotkey help ---- */
.hotkey-help-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); z-index: 2147483000; display: flex; align-items: center; justify-content: center; transition: opacity 0.3s ease; }
.hotkey-help-overlay.hidden { opacity: 0; pointer-events: none; visibility: hidden; transition: opacity 0.3s ease, visibility 0s 0.3s; }
.hotkey-help-overlay.visible { opacity: 1; pointer-events: all; visibility: visible; }
.hotkey-help-content { width: 80%; height: 80%; max-width: 1100px; max-height: 860px; background: var(--glass-strong); border-radius: 22px; border: 1px solid var(--glass-border); box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden; animation: slideIn 0.3s ease; }
@keyframes slideIn { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.hotkey-help-header { padding: 24px 32px; border-bottom: 1px solid var(--glass-border); display: flex; justify-content: space-between; align-items: center; }
.hotkey-help-header h1 { font-size: 26px; font-weight: 700; color: #fafafa; margin: 0; display: flex; align-items: center; gap: 14px; }
.hotkey-help-header h1 .icon { color: var(--accent); }
.hotkey-help-close { background: none; border: none; color: #fafafa; font-size: 24px; cursor: pointer; padding: 5px 10px; border-radius: 8px; transition: background 0.2s ease, color 0.2s ease; display: flex; }
.hotkey-help-close:hover { background: rgba(232, 49, 125, 0.2); color: var(--accent); }
.hotkey-help-sections { flex: 1; overflow-y: auto; padding: 28px 32px; display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 26px; align-content: start; }
.hotkey-help-section h2 { font-size: 17px; font-weight: 650; color: var(--accent); margin: 0 0 12px 0; display: flex; align-items: center; gap: 10px; }
.hotkey-help-table { width: 100%; border-collapse: separate; border-spacing: 0 6px; }
.hotkey-help-table tr { background: rgba(255, 255, 255, 0.04); transition: background 0.2s ease; }
.hotkey-help-table tr:hover { background: rgba(232, 49, 125, 0.1); }
.hotkey-help-table td { padding: 10px 14px; }
.hotkey-help-table td:first-child { border-radius: 10px 0 0 10px; }
.hotkey-help-table td:last-child { border-radius: 0 10px 10px 0; }
.hotkey-keys { white-space: nowrap; width: 40%; color: #fafafa; }
.hotkey-keys kbd { display: inline-block; padding: 5px 10px; font-family: inherit; font-size: 12px; font-weight: 600; color: #fafafa; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 7px; margin: 0 3px; min-width: 26px; text-align: center; }
.hotkey-action { color: #ccc; font-size: 13.5px; }
.hotkey-help-footer { padding: 16px 32px; border-top: 1px solid var(--glass-border); text-align: center; }
.hotkey-help-footer p { margin: 0; font-size: 13px; color: #ccc; display: flex; align-items: center; justify-content: center; gap: 8px; }
.hotkey-help-footer p .icon { color: var(--accent); }
.hotkey-help-footer kbd { display: inline-block; padding: 3px 7px; font-family: inherit; font-size: 12px; font-weight: 600; color: #fafafa; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; margin: 0 2px; }
@media screen and (max-width: 900px) {
	.hotkey-help-content { width: calc(100% - 2 * var(--gutter)); height: 92%; }
	.hotkey-help-sections { grid-template-columns: 1fr; padding: 18px; gap: 18px; }
	.hotkey-help-header { padding: 16px 18px; }
	.hotkey-help-header h1 { font-size: 20px; }
	.hotkey-help-table td { padding: 8px 10px; font-size: 12px; }
	.hotkey-keys kbd { padding: 4px 8px; font-size: 11px; }
}

/* ---- the playlist panel (templates/playlist.html) ---- */
#playlistPanel { display: none; position: fixed; top: 12px; right: var(--gutter); max-height: calc(100% - var(--bar-h) - 36px); width: 340px; max-width: calc(100vw - 2 * var(--gutter) - 32px); z-index: 9999999; color: var(--text); transition: transform 0.45s var(--ease); }
.playlistOpen #playlistPanel { display: flex; }
#playlistPanel.collapsed { transform: translateX(calc(100% + var(--gutter) + 2px)); }
.playlistOpen #loading { right: 372px; }
.playlistField { width: 100%; box-sizing: border-box; padding: 5px 8px; border: 1px solid var(--glass-border); border-radius: 9px; background: rgba(0, 0, 0, 0.35); color: var(--text); font: inherit; font-size: 12.5px; user-select: text; }
#body:not(.showControls) #playlistPanel:not(:focus-within) { transform: translateX(calc(100% + 60px)); }
#playlistToggle { position: absolute; left: -30px; top: 50%; width: 26px; height: 52px; margin-top: -26px; border: 1px solid var(--glass-border); border-right: 0; border-radius: 10px 0 0 10px; background: var(--glass-strong); color: var(--text); cursor: pointer; padding: 0; -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); }
#playlistToggle .icon { transition: transform 0.45s var(--ease); }
.collapsed #playlistToggle .icon { transform: rotate(180deg); }
#playlistContent { display: flex; flex-direction: column; flex: 1; min-width: 0; border-radius: var(--radius); overflow: hidden; background: var(--glass-strong); }
#playlistPanel:not(.loaded) #playlistContent > :not(#playlistStatus) { display: none; }
#playlistHeader { display: flex; gap: 10px; padding: 12px; }
#playlistCoverContainer { position: relative; flex: none; width: 64px; height: 64px; }
#playlistCoverContainer img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; }
#playlistInfo { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
#playlistTitle { color: #fff; font-size: 15px; font-weight: 650; text-decoration: none; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
#playlistTitle[href]:hover { text-decoration: underline; }
#playlistOwner { display: flex; align-items: center; gap: 5px; color: var(--dim); font-size: 12px; text-decoration: none; }
#playlistOwner img { width: 18px; height: 18px; border-radius: 50%; }
#playlistOwner[href]:hover { color: #fff; }
#playlistBadges { display: flex; gap: 4px; }
.playlistBadge { padding: 1px 7px; border: none; border-radius: 999px; background: rgba(255, 255, 255, 0.1); color: #fff; font-size: 10px; white-space: nowrap; }
.playlistBadge:disabled { color: #fff; }
.playlistBadge.public { background: rgba(46, 125, 50, 0.7); }
#playlistHeaderButtons { display: flex; flex-direction: column; gap: 2px; flex: none; }
#playlistDescription { margin: 0 12px 8px; max-height: 6em; overflow-y: auto; color: var(--dim); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
#playlistDescription:empty { display: none; }
.playlistIconButton { flex: none; width: 26px; height: 26px; padding: 0; border: none; border-radius: 7px; background: none; color: var(--dim); font-size: 13px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.playlistIconButton:hover:enabled { background: rgba(255, 255, 255, 0.1); color: #fff; }
.playlistIconButton:disabled { opacity: 0.3; cursor: default; }
#playlistNav { display: flex; align-items: center; gap: 4px; padding: 5px 12px; border-top: 1px solid var(--glass-border); border-bottom: 1px solid var(--glass-border); font-size: 12px; }
#playlistPosition { min-width: 50px; text-align: center; font-variant-numeric: tabular-nums; }
.countingDown #playlistPosition { display: none; }
#playlistCountdown { display: none; align-items: center; color: #ffd24d; }
.countingDown #playlistCountdown { display: flex; }
.playlistToggleLabel { display: flex; align-items: center; gap: 6px; margin-left: auto; cursor: pointer; }
.playlistToggleLabel .switch { transform: scale(0.85); }
#playlistMapOptions { display: none; align-items: center; gap: 6px; padding: 5px 12px; border-bottom: 1px solid var(--glass-border); }
.mapPlaylist #playlistMapOptions { display: flex; }
#playlistStatus { margin: 0; padding: 8px 12px; color: var(--dim); font-size: 12px; }
#playlistStatus:empty { display: none; }
#playlistStatus.error { color: #ff8a8a; }
#playlistVote { display: flex; flex-direction: column; gap: 4px; margin: 6px 8px 0; padding: 8px 10px; border: 1px solid rgba(155, 109, 255, 0.4); border-radius: 10px; background: rgba(155, 109, 255, 0.08); font-size: 12px; }
#playlistVote:empty { display: none; }
.playlistVoteHead { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.playlistVoteHead .icon { color: #9b6dff; }
.playlistVoteMeta, .playlistVoteActions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.playlistVoteMeta, .playlistVoteNote { color: var(--dim); font-size: 11px; }
.playlistVoteTally { display: flex; align-items: center; gap: 6px; color: var(--dim); }
.playlistVoteTally b { color: #fff; }
.playlistVoteBar { flex: 1; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.1); overflow: hidden; }
.playlistVoteBar span { display: block; height: 100%; background: #9b6dff; }
.playlistMore { width: 100%; margin: 4px 0; padding: 6px; border: none; border-radius: 8px; background: rgba(255, 255, 255, 0.08); color: #fff; cursor: pointer; }
#playlistItems { position: relative; flex: 1; min-height: 0; overflow-y: auto; padding: 4px; scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.2) transparent; }
.playlistItem { position: relative; display: flex; align-items: flex-start; gap: 8px; padding: 6px; border-radius: 10px; cursor: pointer; transition: background var(--dur) var(--ease); }
.playlistItem:hover { background: rgba(255, 255, 255, 0.06); }
.playlistItem.current { background: rgba(142, 84, 233, 0.32); }
.playlistItem.unavailable { opacity: 0.65; cursor: default; }
.playlistItem.failed .playlistItemSong { color: #ff8a8a; }
.playlistItemPosition { flex: none; min-width: 20px; padding-top: 2px; color: var(--faint); font-size: 11px; text-align: right; font-variant-numeric: tabular-nums; }
.playlistItemCover { flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 8px; background: rgba(255, 255, 255, 0.05); object-fit: cover; color: var(--faint); }
.playlistItemInfo { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; font-size: 11px; }
.playlistItemSong { color: #fff; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.playlistItemMap, .playlistItemPlayer { display: flex; align-items: center; gap: 4px; min-width: 0; white-space: nowrap; }
.playlistItemDifficulty { flex: none; padding: 0 5px; border-radius: 4px; background: rgba(255, 255, 255, 0.12); color: #fff; font-size: 10px; }
.playlistItemDifficulty[data-entry] { cursor: pointer; }
.playlistItemDifficulty.empty { opacity: 0.4; cursor: default; }
.playlistItemDifficulty.current { box-shadow: 0 0 0 1px #fff; }
.playlistItemStars { flex: none; color: var(--dim); }
.playlistItemMapper, .playlistItemPlayerName { overflow: hidden; text-overflow: ellipsis; color: var(--dim); }
.playlistItemAvatar { flex: none; width: 14px; height: 14px; border-radius: 50%; }
.playlistItemEndType { flex: none; padding: 0 5px; border-radius: 4px; background: #6b4e16; font-size: 10px; }
.playlistItemStats { display: flex; gap: 6px; margin-left: auto; padding-left: 4px; }
.playlistItemPp { color: #a8b1ff; }
.playlistItemNote { color: var(--dim); font-style: italic; white-space: pre-wrap; overflow-wrap: anywhere; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.current .playlistItemNote { display: block; }
#addToPlaylist .menuitem-icon .icon { color: #fff; }
/* editing (the owner's / an editor's: .editable), votes, the "Add to playlist" dialog (master index.styl) */
#playlistCoverContainer input { display: none; }
#playlistCoverEdit { display: none; position: absolute; inset: 0; align-items: center; justify-content: center; border-radius: 10px; background: rgba(0, 0, 0, 0.6); cursor: pointer; }
.editable #playlistCoverContainer:hover #playlistCoverEdit { display: flex; }
.playlistBadge:enabled { cursor: pointer; }
#playlistRole { background: #1f6fb2; }
#playlistEditInfo { display: none; }
.editable #playlistEditInfo { display: inline-flex; }
#playlistInfoForm { display: none; flex-direction: column; gap: 4px; padding: 0 12px 8px; }
.editingInfo #playlistInfoForm { display: flex; }
.editingInfo #playlistHeader .playlistBadge, .editingInfo #playlistHeaderButtons, .editingInfo #playlistDescription { display: none; }
.playlistFormButtons { display: flex; justify-content: flex-end; gap: 2px; }
#playlistStatus a { color: #fff; }
.playlistButton { padding: 3px 10px; border: none; border-radius: 7px; background: #9b6dff; color: #fff; cursor: pointer; }
.playlistButton:disabled { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.5); cursor: default; }
.playlistVoteLink { padding: 0; border: none; background: none; color: var(--dim); font-size: 11px; text-decoration: underline; cursor: pointer; }
.playlistVoteLink.danger { color: #ff8a8a; }
.playlistVotePick { flex: none; display: flex; align-items: center; justify-content: center; width: 16px; height: 16px; margin-top: 2px; padding: 0; border: 2px solid rgba(255, 255, 255, 0.5); border-radius: 4px; background: transparent; color: #fff; font-size: 9px; cursor: pointer; }
.playlistVotePick.single { border-radius: 50%; }
.playlistVotePick.on { border-color: #9b6dff; background: #9b6dff; }
.playlistVotePick.ghost { opacity: 0.3; }
.playlistVotePick:disabled { cursor: default; }
.playlistVotePick .icon { width: 10px; height: 10px; }
.playlistItem.dragging { opacity: 0.4; }
.playlistItem.dropBefore { box-shadow: inset 0 2px #eb008c; }
.playlistItem.dropAfter { box-shadow: inset 0 -2px #eb008c; }
.playlistItemPosition .icon { display: none; cursor: grab; }
.playlistItem:hover .playlistItemPosition.draggable .playlistItemNumber { display: none; }
.playlistItem:hover .playlistItemPosition.draggable .icon { display: inline; }
.playlistNoteForm { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.playlistItemActions { position: absolute; top: 4px; right: 4px; display: flex; border-radius: 7px; background: rgba(0, 0, 0, 0.8); opacity: 0; }
.playlistItem:hover .playlistItemActions { opacity: 1; }
@media (hover: none) { .playlistItemActions { opacity: 1; } }
#playlistPicker { display: none; position: fixed; inset: 0; z-index: 999999990; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.4); color: var(--text); }
#playlistPicker.open { display: flex; }
#playlistPickerDialog { display: flex; flex-direction: column; gap: 8px; width: 360px; max-width: calc(100vw - 32px); max-height: calc(100vh - 32px); box-sizing: border-box; padding: 12px; border-radius: var(--radius); background: rgba(0, 0, 0, 0.9); font-size: 12px; }
#playlistPickerHead { display: flex; align-items: center; justify-content: space-between; font-size: 15px; }
#playlistPickerNoteHint, .playlistPickerEmpty { color: var(--faint); font-size: 11px; }
#playlistPickerNoteHint:empty, #playlistPickerStatus:empty { display: none; }
#playlistPickerStatus { margin: 0; color: #ff8a8a; }
#playlistPickerList { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow-y: auto; }
.playlistPickerEmpty { margin: 4px 0; }
.playlistPickerRow { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px; border: none; border-radius: 8px; background: none; color: #fff; text-align: left; cursor: pointer; }
.playlistPickerRow:hover:enabled { background: rgba(255, 255, 255, 0.06); }
.playlistPickerRow:disabled { opacity: 0.5; cursor: default; }
.playlistPickerRow img { flex: none; width: 36px; height: 36px; border-radius: 6px; object-fit: cover; }
.playlistPickerRow .icon { flex: none; width: 16px; height: 16px; color: rgba(255, 255, 255, 0.5); }
.playlistPickerRow.in .icon { color: rgb(142, 84, 233); }
.playlistPickerText { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.playlistPickerText b, .playlistPickerText small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.playlistPickerText small { color: var(--dim); }
#playlistPickerCreate { display: none; gap: 6px; }
#playlistPickerCreate.open { display: flex; }

/* ---- narrow screens ---- */
@media (max-width: 760px) {
	.chip { max-width: 200px; }
	#playerChip .chipSub { display: none; }
}
@media (max-width: 640px) {
	#speedControl, #volumeControl { display: none; }
	.phoneOnly { display: flex !important; }
	.tab-container { flex-direction: column; }
	.tab-buttons { width: auto; flex-direction: row; overflow-x: auto; overflow-y: hidden; padding: 2px 10px 8px; gap: 4px; scrollbar-width: none; }
	.tab-buttons::-webkit-scrollbar { display: none; }
	.tab-button { flex: none; padding: 7px 10px; }
	.tab-button.active { box-shadow: inset 0 -2px 0 var(--accent); }
	.tab-content { padding: 0 8px 16px; }
	#settingsContainer { left: var(--gutter); right: var(--gutter); width: auto; height: min(560px, calc(100vh - var(--bar-h) - 32px)); }
	#playlistPanel { width: calc(100vw - 2 * var(--gutter) - 32px); }
	.playlistOpen #loading { right: var(--gutter); top: 72px; }
}
@media (max-width: 520px) {
	:root { --bar-row: 50px; }
	.barButton { width: 34px; height: 34px; font-size: 18px; }
	.playButton { width: 38px; height: 38px; }
	#barRight .povswitch { display: none; }
	#songTime { font-size: 12px; margin: 0 2px !important; }
	#playerChip .chipText { display: none; }
	#playerChip { padding-right: 4px; }
	.chip { max-width: 130px; padding-right: 6px; }
	#songChip .chipSub { display: none; }
	/* the overlay's collapse and close buttons take the fullscreen button's place */
	html.overlay #barRight .controlsFullscreen { display: none; }
	.card { position: fixed; left: var(--gutter); right: var(--gutter); width: auto; bottom: calc(var(--bar-h) + 10px + var(--safe-bottom)); }
	.stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 400px) {
	#songTime .timeSep, #songDuration { display: none; }
	.chip { max-width: 100px; }
}

/* ---- the overlay mode (?overlay=1, overlay.js): transparent page; collapsed = the mini view + the bar ---- */
html.overlay, html.overlay body { background: transparent !important; }
html.overlay #stage { background: #000; }
html.overlay.closedOverlay body { visibility: hidden; }
html.overlay #controls.challengeLoaded, html.overlay.collapsed #controls { display: block; }
html.overlay.collapsed #controls { transform: none !important; opacity: 1 !important; }
html.overlay.collapsed #stage {
	inset: auto;
	left: 0;
	top: 0;
	width: var(--mini-w, 400px);
	height: var(--mini-h, 225px);
	transform: translate(var(--mini-x, 0px), var(--mini-y, 0px));
	border-radius: 14px;
	box-shadow: var(--shadow);
	border: 1px solid var(--glass-border);
	background: #000;
}
html.overlay.collapsed.dragging #stage { transition: none; cursor: grabbing; }
html.overlay #stage { transition: border-radius 240ms var(--ease); }
#miniChrome { display: none; }
html.overlay.collapsed #miniChrome { display: flex; position: absolute; left: 0; right: 0; top: 0; height: 36px; align-items: center; justify-content: space-between; padding: 0 4px 0 0; background: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), transparent); opacity: 0; transition: opacity var(--dur) var(--ease); z-index: 2; }
html.overlay.collapsed #stage:hover #miniChrome, html.overlay.collapsed.dragging #miniChrome, html.overlay.collapsed #stage.touched #miniChrome { opacity: 1; }
#miniDrag { flex: 1; height: 100%; cursor: grab; touch-action: none; display: flex; align-items: center; justify-content: center; }
#miniDrag .grip { width: 36px; height: 4px; border-radius: 4px; background: rgba(255, 255, 255, 0.6); }
.miniButton { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 8px; background: rgba(0, 0, 0, 0.35); color: #fff; font-size: 15px; cursor: pointer; }
.miniButton:hover { background: rgba(0, 0, 0, 0.6); }
html.overlay.collapsed #playlistPanel, html.overlay.collapsed #loading, html.overlay.collapsed #randomReplay { display: none !important; }
html.overlay.collapsed #hudLayer { display: none; }
/* the bar over a page it cannot blur (an iframe's backdrop filter sees only its own content): more opaque, unless the
   host draws the blur under the glass regions (html.hostGlass, overlay.js: then as translucent as on the normal page) */
html.overlay.collapsed:not(.hostGlass) #controls { background: linear-gradient(to top, rgba(12, 12, 18, 0.96), rgba(12, 12, 18, 0.9)); }
html.overlay.collapsed:not(.hostGlass) .popover, html.overlay.collapsed:not(.hostGlass) .card > .cardInner, html.overlay.collapsed:not(.hostGlass) #settingsContainer { background: rgba(18, 18, 26, 0.96); }
html.overlay.collapsed:not(.hostGlass) #timelineGraph::before { background: linear-gradient(to top, rgba(12, 12, 18, 0.96), rgba(12, 12, 18, 0.9)); }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; animation-iteration-count: 1 !important; }
}
