/* 바탕: 거의 검정, 강조: 앰버. 색은 이 :root 변수로만 정한다. */
@font-face { font-family: "Gosu UI"; src: url("/ui/fonts/gmarketmedium.woff2") format("woff2"); font-weight: 400 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Gosu UI"; src: url("/ui/fonts/gmarketbold.woff2") format("woff2"); font-weight: 600 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Gosu Counter"; src: url("/ui/fonts/counter.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
/* Scrollable content keeps wheel/keyboard navigation without visible scrollbar tracks or thumbs. */
#menu-fps { color: var(--text); }
* { scrollbar-width: none !important; }
*::-webkit-scrollbar { display: none !important; }
:root { color-scheme: dark; --feel: #ffffff; --popup-dim: rgba(0, 0, 0, 0.5); --bg: #0d0d0e; --text: #ececec; --dim: #8a8a8a; --line: #2a2a2d; --field: #18181a; --textbox: #22292a; --textbox-focus: #2e3638; --textbox-border: #66e0ff;--button: #394446; --button-light: #5c6c70; --accent: #00add8; --on-accent: #0d0d0e; --accent-tint: #0a1f26; --hero: #141416; --search: #2c2c31; --scrim: rgba(13, 13, 14, 0.62); --lamp-100: #ffb000; --lamp-100-core: #fff4cf; --lamp-fc: #ffffff; --lamp-fc-glow: #09fafd; --lamp-shine: #ffffff; --lamp-clear: #7a7a7a; --lamp-gauge1: #4cd964; --lamp-gauge1-core: #82e493; --lamp-gauge2: #3d6bff; --lamp-gauge2-core: #9eb5ff; --lamp-gauge3: #b45cff; --lamp-gauge3-core: #e9ceff; --activation: #70858c; --pulse-peak: color-mix(in srgb, var(--accent) 20%, var(--accent-tint)); --pulse-rest: color-mix(in srgb, var(--accent) 10%, var(--accent-tint)); --pulse-peak-song: color-mix(in srgb, var(--accent) 20%, transparent); --pulse-rest-song: color-mix(in srgb, var(--accent) 10%, transparent);--toast: var(--button); --toast-hover: #455154; --toast-icon: #22292a; --toast-glyph: #ffffff; --toast-check: #8f9fa3; --toast-check-hover: #ffffff; --toast-close-hover: rgba(0, 0, 0, 0.15); --toast-flash: #ffffff; --cursor-body: #ffffff; --cursor-edge: #000000; --cursor-glow: #ff66aa;  --menu-band: #323232; --menu-text: #ffffff; --menu-flash: #ffffff; --menu-settings: #555555; --menu-back: #333a5e; --menu-play: #6644cc; --menu-multi: #5e3fba; --menu-edit: #eeaa00; --menu-quit: #ee3399; --chat-bg: rgba(0, 0, 0, 0.8); --chat-alt: rgba(59, 50, 52, 0.2); --chat-name-0: #588c7e; --chat-name-1: #b2a367; --chat-name-2: #c98f65; --chat-name-3: #bc5151; --chat-name-4: #5c8bd6; --chat-name-5: #7f6ab7; --chat-name-6: #a368ad; --chat-name-7: #aa6880; --chat-name-8: #6fad9b; --chat-name-9: #f2e394; --chat-name-10: #f2ae72; --chat-name-11: #f98f8a; --chat-name-12: #7daef4; --chat-name-13: #a691f2; --chat-name-14: #c894d3; --chat-name-15: #d895b0; --chat-name-16: #53c4a1; --chat-name-17: #eace5c; --chat-name-18: #ea8c47; --chat-name-19: #fc4f4f; --chat-name-20: #3d94ea; --chat-name-21: #7760ea; --chat-name-22: #af52c6; --chat-name-23: #e25696; --chat-name-24: #677c66; --chat-name-25: #9b8732; --chat-name-26: #8c5129; --chat-name-27: #8c3030; --chat-name-28: #1f5d91; --chat-name-29: #4335a5; --chat-name-30: #812a96; --chat-name-31: #992861; --note-snap-1: #ffffff; --note-snap-2: #ed1121; --note-snap-3: #8866ee; --note-snap-4: #66ccff; --note-snap-6: #eeaa00; --note-snap-8: #ffcc22; --note-snap-12: #cc6600; --note-snap-16: #6644cc; --note-snap-odd: #b3d944; --note-snap-other: #ff0000; --note-lane-a: #56b4e9; --note-lane-b: #e69f00; --note-lane-special: #f0e442; --note-mine: #f5707d; --note-lift: #6ad2f8; --note-roll: #d088f1; --story-glow: #ffffff; --story-star: #fff4cf; }
body, dialog { background: var(--bg); color: var(--text); font-family: "Gosu UI", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif; font-size: 15px; line-height: 1.5; }
input, select, textarea { font-family: inherit; font-size: inherit; }
.hints button, #downloads > header, #selected-heading, .chart-title { font-weight: 700; }
#preferences, #display-settings, #audio-settings, #offsets, .room-chat-log, #result-run { font-family: "Malgun Gothic", "Apple SD Gothic Neo", sans-serif; }
#result-accuracy, #result-combo, #result-mm-earned, #result-mm-max, .result-grade > dd:not(.result-track) { font-family: "Gosu Counter", sans-serif; font-weight: 700; font-variant-numeric: tabular-nums; }
.room-chat-panel { background: var(--chat-bg); color: var(--text); border-left: 1px solid var(--line); }
.room-chat-head { border-bottom: 1px solid var(--line); }
.room-chat-head h2 { font-size: 16px; }
.room-chat-close, .room-chat-settings { font-size: 12px; background: transparent; color: var(--dim); border: 0; }
.room-chat-tab { font-size: 13px; background: transparent; color: var(--dim); border: 0; border-bottom: 2px solid transparent; }
.room-chat-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }
.room-chat-ticker, .room-chat-popup { background: var(--chat-bg); color: var(--text); border: 1px solid var(--line); font-size: 13px; line-height: 1.6; }
.room-chat-popup { border-left: 3px solid var(--accent); }
.room-chat-resize { cursor: ew-resize; }
.room-chat-resize:focus-visible, .room-chat-resize:hover { background: var(--accent); outline: 0; }
.room-chat-compose { border-top: 1px solid var(--line); }
.room-chat-hint, .room-chat-count, .room-chat-empty { font-size: 12px; color: var(--dim); }
.room-chat-message { line-height: 1.6; }
.room-chat-compose textarea { font-family: "Malgun Gothic", "Apple SD Gothic Neo", sans-serif; font-size: 13px; line-height: 1.6; }
.room-chat-message[data-self="true"] .room-chat-name { color: var(--accent); }
/* osu!lazer ChatLine: 13 px, alternate rows tinted, names in one of 32 sender colours. */
.room-chat-message { font-size: 13px; }
.room-chat-message:nth-child(even) { background: var(--chat-alt); }
.room-chat-time { color: var(--dim); font-weight: 600; font-variant-numeric: tabular-nums; }
.room-chat-name { font-weight: 700; }
.room-chat-name[data-colour="0"] { color: var(--chat-name-0); }
.room-chat-name[data-colour="1"] { color: var(--chat-name-1); }
.room-chat-name[data-colour="2"] { color: var(--chat-name-2); }
.room-chat-name[data-colour="3"] { color: var(--chat-name-3); }
.room-chat-name[data-colour="4"] { color: var(--chat-name-4); }
.room-chat-name[data-colour="5"] { color: var(--chat-name-5); }
.room-chat-name[data-colour="6"] { color: var(--chat-name-6); }
.room-chat-name[data-colour="7"] { color: var(--chat-name-7); }
.room-chat-name[data-colour="8"] { color: var(--chat-name-8); }
.room-chat-name[data-colour="9"] { color: var(--chat-name-9); }
.room-chat-name[data-colour="10"] { color: var(--chat-name-10); }
.room-chat-name[data-colour="11"] { color: var(--chat-name-11); }
.room-chat-name[data-colour="12"] { color: var(--chat-name-12); }
.room-chat-name[data-colour="13"] { color: var(--chat-name-13); }
.room-chat-name[data-colour="14"] { color: var(--chat-name-14); }
.room-chat-name[data-colour="15"] { color: var(--chat-name-15); }
.room-chat-name[data-colour="16"] { color: var(--chat-name-16); }
.room-chat-name[data-colour="17"] { color: var(--chat-name-17); }
.room-chat-name[data-colour="18"] { color: var(--chat-name-18); }
.room-chat-name[data-colour="19"] { color: var(--chat-name-19); }
.room-chat-name[data-colour="20"] { color: var(--chat-name-20); }
.room-chat-name[data-colour="21"] { color: var(--chat-name-21); }
.room-chat-name[data-colour="22"] { color: var(--chat-name-22); }
.room-chat-name[data-colour="23"] { color: var(--chat-name-23); }
.room-chat-name[data-colour="24"] { color: var(--chat-name-24); }
.room-chat-name[data-colour="25"] { color: var(--chat-name-25); }
.room-chat-name[data-colour="26"] { color: var(--chat-name-26); }
.room-chat-name[data-colour="27"] { color: var(--chat-name-27); }
.room-chat-name[data-colour="28"] { color: var(--chat-name-28); }
.room-chat-name[data-colour="29"] { color: var(--chat-name-29); }
.room-chat-name[data-colour="30"] { color: var(--chat-name-30); }
.room-chat-name[data-colour="31"] { color: var(--chat-name-31); }
.room-chat-compose textarea { background: var(--field); color: var(--text); border: 1px solid var(--line); }
.room-chat-meta, .room-chat-status, .room-chat-context { color: var(--dim); }
.room-chat-new { color: var(--accent); }
/* osu!lazer OsuTextBox with the overlay colours: Background5 fill, Background4 + a 3px Highlight1 border on focus
   (fill fades 200ms Out), Background1 selection, italic placeholder. */
input, select { background: var(--textbox); color: var(--text); border: 3px solid var(--textbox); caret-color: var(--text); transition: background-color 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
input:focus, select:focus { outline: 0; background: var(--textbox-focus); border-color: var(--textbox-border); }
input::selection { background: var(--button-light); }
input::placeholder { color: var(--dim); font-style: italic; }
#settings .settings-row input:is([type="text"], [type="number"], [type="url"], :not([type])) { font-size: 20px; }
.settings-row .unit, #offset-total { color: var(--dim); }
#medley h3 { font-size: 17px; }
#medley-count, #medley-page, .medley-help { color: var(--dim); }
.medley-help { font-size: 12px; }
.medley-picked-name { font-size: 17px; font-weight: 700; }
.medley-picked-chart { color: var(--dim); font-size: 12px; }
#medley-songs li { border-left: 4px solid var(--accent); background: var(--pulse-rest); }
.medley-mark { color: var(--accent); font-size: 17px; }
#medley-candidates li[aria-disabled="true"] { opacity: 0.4; }
#medley-candidates li:focus-visible, #medley-songs li:focus-visible { outline: 1px solid var(--accent); }
#medley-search { background: var(--search); border: 2px solid var(--dim); font-size: 17px; }
#medley-search:focus { border-color: var(--accent); }
/* Decision 30 → osu!lazer ShearedButton: Background3 fill (hue of the accent, saturation 0.1, lightness 0.25), a 2px
   border fading from that fill to Background1 (lightness 0.4) at the bottom, TorusAlternate 17 → 17px. */
button { background: var(--button); color: var(--text); border: 1px solid var(--button); border-bottom: 1px solid var(--button-light); font-family: inherit; font-size: 17px; }
/* The search box gets its own lighter fill so it reads as a field over the chart background. */
/* osu!lazer's search box lights its border in the highlight colour while it has focus. */
#search-text { background: var(--search); border: 2px solid var(--dim); font-size: 17px; }
#search-text:focus { border-color: var(--accent); }
fieldset { border: 1px solid var(--line); }
legend, #list-status, #difficulty, dt, .hints kbd, #song-list li > span:last-child { color: var(--dim); }
#catalog-loading strong { color: var(--accent); font-size: 24px; }
#catalog-loading span { color: var(--dim); }
#edit-field, #edit-map, #edit-sv canvas { background: var(--field); border: 1px solid var(--line); }
#edit-inspector, #edit-charts { border-right: 1px solid var(--line); }
#edit-message, #edit-saved, #edit-audio-status { color: var(--dim); }
#edit-charts button[aria-current="true"], #edit-toolbar button[aria-pressed="true"], #edit-sv-effects button[aria-pressed="true"] { border-color: var(--text); }
#edit-audio-items { background: var(--field); border: 1px solid var(--line); }
#edit-audio-items label:hover { background: var(--line); }
#edit-audio-items label > span { color: transparent; }
#edit-audio-items label:has(:checked) > span { color: var(--accent); }
#edit-audio-items label:has(:disabled) { color: var(--dim); }
#edit-audio-items label:has(:focus-visible) { outline: 1px solid var(--text); }
/* lazer editor BottomBar: timestamp Torus Light 32 (spacing -2), BPM and progress 14 under it, play icon only,
   speed tabs as text that brighten and turn bold over 200 ms OutQuint. */
#edit-transport { background: var(--field); border-top: 1px solid var(--line); }
#edit-time { background: transparent; border: 0; font-size: 32px; font-weight: 400; letter-spacing: -2px; line-height: 1; font-variant-numeric: tabular-nums; }
#edit-time:hover { background: var(--line); }
#edit-progress, #edit-bpm { color: var(--dim); font-size: 14px; line-height: 1.2; font-variant-numeric: tabular-nums; }
#edit-play { background: transparent; border: 0; }
#edit-speed > span { color: var(--dim); font-size: 13px; line-height: 1.2; }
#edit-rates button, #edit-rates button[aria-pressed="true"] { background: transparent; border: 0; color: var(--dim); font-size: 14px; line-height: 16px; transition: color 200ms cubic-bezier(0.23, 1, 0.32, 1); }
#edit-rates button:hover, #edit-rates button[aria-pressed="true"] { color: var(--text); }
#edit-rates button[aria-pressed="true"] { font-weight: 700; }
.panel-heading { color: var(--accent); }
button[aria-pressed="true"], #settings-tabs button[aria-selected="true"] { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* Range windows over the level and length distributions. */
.range-bar { background: var(--line); }
.range-bar.in { background: var(--accent); }
.range-window { background: var(--accent-tint); border-left: 2px solid var(--accent); border-right: 2px solid var(--accent); }
.range-axis, .range-value { color: var(--dim); }
/* Settings sliders: osu!lazer ShearedSliderBar, shear 0.2, the nub glides 250ms OutQuint; disabled at 0.3 like lazer. */
.slider { transform: skewX(-11.3deg); }
.slider input { opacity: 0; }
#rate-presets button { transform: translateX(-50%); font-weight: 700; background: transparent; color: var(--text); border: 0; }
#rate-presets .rate-end { font-size: 12px; font-weight: 400; color: var(--dim); }
#rate-presets button.feel-press { transform: translateX(-50%) scale(0.9); }
#rate-presets .feel-label, #rate-controls .slider { transform: none; }
#rate-presets button[aria-pressed="true"] { color: var(--accent); }
#rate-presets button:hover { color: var(--accent); }
#rate-presets button:focus-visible { outline: 0; color: var(--accent); }
#rate-custom { background: transparent; border: 0; color: var(--dim); transform: none; font-size: 13px; }
#rate-custom .feel-label { transform: none; }
#rate-custom[aria-pressed="true"], #rate-custom:hover { color: var(--text); }
#rate-custom-state { font-weight: 700; font-variant-numeric: tabular-nums; }
#rate-custom[aria-pressed="true"] #rate-custom-state { color: var(--accent); }
#rate-custom:focus-visible { outline: 0; color: var(--accent); }
#time-rate { background: transparent; border: 0; color: var(--accent); font-size: 18px; font-family: ui-monospace, Consolas, monospace; font-weight: 700; }
#time-rate:focus { outline: 0; }
#rate-value, #rate-input { color: var(--accent); font-size: 18px; font-family: ui-monospace, Consolas, monospace; font-weight: 700; }
.slider-fill { background: var(--accent); }
.slider-rest { background: var(--line); }
.slider-nub { background: var(--text); border: 3px solid var(--accent); }
.slider:focus-within .slider-nub { border-color: var(--text); background: var(--accent); }
.slider:has(input:disabled) { opacity: 0.3; }
.slider-fill, .slider-rest, .slider-nub { transition: left 250ms cubic-bezier(0.23, 1, 0.32, 1), width 250ms cubic-bezier(0.23, 1, 0.32, 1); }
/* Every row reserves the bar width so selecting a row does not shift its text. */
.song-catalog li { border-left: 4px solid transparent; }
/* osu!lazer Panel: unselected rows sit further right (updateXOffset) - a chart 50 px, a closed song 100 px, and
   25 px more for every row but the selected one - and move over 400 ms OutQuint. The selection layer fades in
   over 100 ms and out over 200 ms OutQuint; it pulses with the song (songselect/pulse.js). Gradients are not
   allowed, so its flat --pulse-* colours carry the average of lazer's 0-50% accent gradient. */
.song-catalog li { margin-left: 75px; transition: margin-left 400ms cubic-bezier(0.23, 1, 0.32, 1), background 200ms cubic-bezier(0.23, 1, 0.32, 1); }
#song-list li[aria-expanded="false"] { margin-left: 125px; }
#song-list li[aria-expanded="true"], #song-list li[role="presentation"]:not(.more) { margin-left: 25px; }
/* The rail moves opposite to the row on the same curve, so it stays still while the row glides. */
#song-list li.chart-in-song::before, #song-list li.more::before { background: var(--line); transition: left 400ms cubic-bezier(0.23, 1, 0.32, 1); }
#song-list li[aria-expanded="true"] { background: var(--pulse-rest-song); transition: margin-left 400ms cubic-bezier(0.23, 1, 0.32, 1), background 100ms cubic-bezier(0.23, 1, 0.32, 1); }
.song-catalog li[aria-selected="true"] { margin-left: 0; background: var(--pulse-rest); border-left: 4px solid var(--accent); transition: margin-left 400ms cubic-bezier(0.23, 1, 0.32, 1), background 100ms cubic-bezier(0.23, 1, 0.32, 1); }
/* Adjacent, uninterrupted light bars with achievement flashes. */
.chart-level { color: var(--accent); font-family: ui-monospace, Consolas, monospace; font-size: 22px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.source-level { color: var(--dim); font-family: ui-monospace, Consolas, monospace; font-size: 17px; font-variant-numeric: tabular-nums; }
#source-level { font-size: 22px; }
.chart-points, .chart-release { font-variant-numeric: tabular-nums; }
.level-col { color: var(--dim); font-variant-numeric: tabular-nums; }
.level-col.on, .level-row.selected .level-col { color: var(--text); }
#level-head .level-col.on { color: var(--accent); }
#level-head .level-col { border: 0; background: transparent; font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; }
.chart-lamp { color: var(--dim); background: var(--line); }
.chart-lamp:not([data-state="none"]):not([data-state="unavailable"]) { background: currentColor; }
/* Clear lamp: each step up gets a brighter centre core and a wider glow; perfect shines most. Clear is a flat grey bar. */
.combo-lamp[data-state="clear"] { color: var(--lamp-clear); }
.combo-lamp[data-state="gauge1"] {
    color: var(--lamp-gauge1); background: linear-gradient(currentColor, var(--lamp-gauge1-core) 50%, currentColor);
    box-shadow: 0 0 2px currentColor, 0 0 3px currentColor;
}
.combo-lamp[data-state="gauge2"] {
    color: var(--lamp-gauge2); background: linear-gradient(currentColor, var(--lamp-gauge2-core) 50%, currentColor);
    box-shadow: 0 0 3px currentColor, 0 0 6px currentColor;
}
.combo-lamp[data-state="gauge3"] {
    color: var(--lamp-gauge3); background: linear-gradient(currentColor, var(--lamp-gauge3-core) 50%, currentColor);
    box-shadow: 0 0 4px currentColor, 0 0 8px currentColor;
}
.combo-lamp[data-state="fullcombo"] { color: var(--lamp-fc); box-shadow: 0 0 4px var(--lamp-fc-glow), 0 0 7px var(--lamp-fc-glow), 0 0 11px var(--lamp-fc-glow); }
.combo-lamp[data-state="perfect"] {
    color: var(--lamp-100); background: linear-gradient(currentColor, var(--lamp-100-core) 50%, currentColor);
    box-shadow: 0 0 5px currentColor, 0 0 10px currentColor, 0 0 16px currentColor;
}
/* Cleared only below the chosen Time Rate: the lower half lights, the upper half stays an empty lamp. */
.combo-lamp[data-half] { box-shadow: inset 0 11px 0 var(--line); }
/* Full combo and perfect: a glow flash and a white shine down the bar, timed to the song by songselect/pulse.js.
   Full combo glows cyan (beatoraja lamp.png FULL COMBO frame). */
.combo-lamp .lamp-flash, .combo-lamp .lamp-shine { opacity: 0; }
.combo-lamp[data-state="fullcombo"] .lamp-flash { box-shadow: 0 0 6px var(--lamp-fc-glow), 0 0 14px var(--lamp-fc-glow), 0 0 26px var(--lamp-fc-glow); }
.combo-lamp[data-state="perfect"] .lamp-flash { box-shadow: 0 0 6px currentColor, 0 0 14px currentColor, 0 0 26px currentColor; }
.combo-lamp .lamp-shine { background: linear-gradient(transparent, var(--lamp-shine), transparent); }
/* Key binding is a keyboard stage: outer white keys, inner light-teal keys, a mint centre key (kept off --accent so a held centre still shows). */
:root { --key-white: #e9e8e8; --key-pink: #8fd9ec; --key-special: #4cd9a8; }
.key-lane { background: transparent; border: 0; transform: none; }
.key-lane:hover, .key-lane:active { background: transparent; transform: none; }
.key-lane:focus-visible { outline: 2px solid var(--accent); }
.key-track { background: var(--key-white); border: 2px solid var(--key-white); border-bottom: 5px solid var(--dim); }
.key-lane[data-tone="pink"] .key-track { background: var(--key-pink); border-color: var(--key-pink); }
.key-lane[data-tone="special"] .key-track { background: var(--key-special); border-color: var(--key-special); }
.key-name { color: var(--on-accent); font-size: clamp(11px, 2vw, 18px); font-weight: 700; }
.key-number { color: var(--dim); font-size: 12px; }
.key-arrow { color: var(--accent); font-size: 40px; line-height: 1; opacity: 0; }
.key-lane[aria-current="true"] .key-arrow { opacity: 1; }
.key-lane:hover .key-track, .key-lane[aria-current="true"] .key-track { border-color: var(--accent); }
.key-lane[data-held] .key-track { background: var(--accent); border-color: var(--accent); }
.key-lane[aria-invalid="true"] .key-track { border-color: var(--text); border-style: dashed; }
.key-note { background: var(--on-accent); }
#key-chord { color: var(--dim); }
/* osu!lazer ButtonSystem (decision 23 redone): ButtonArea fades over 300 ms and its Gray(50) band folds flat over
   300 ms InSine or opens over 400 ms OutQuint, 150 ms after leaving the logo. The logo shrinks to 0.5 onto the facade
   over 200 ms In and returns to the middle over 800 ms OutExpo, 150 ms later. */
#title-band { background: var(--menu-band); transition: transform 400ms cubic-bezier(0.23, 1, 0.32, 1) 150ms, opacity 300ms linear 150ms; }
#title.initial #title-band { transform: scaleY(0); opacity: 0; transition: transform 300ms cubic-bezier(0.12, 0, 0.39, 0), opacity 300ms linear; }
#title-spot { transition: transform 800ms cubic-bezier(0.16, 1, 0.3, 1) 150ms; }
#title:not(.initial) #title-spot { transform: translateX(-228px) scale(0.5); transition: transform 200ms cubic-bezier(0.11, 0, 0.5, 0); }
/* MainMenuButton: expands over 500 ms OutExpo fading in over 83 ms; contracts over 500 ms OutExpo fading 500 ms;
   explodes to 2× over 200 ms OutExpo fading 150 ms. Hover keeps the size and brightens
   like ShearedButton instead (a 10% white layer over 150 ms OutQuint). The box is sheared by
   WEDGE_WIDTH / height = 0.2 with the icon and label upright. Pressing lights a white layer to 0.1 over 1000 ms
   OutQuint; a click flashes 0.9 that fades over 800 ms OutExpo. */
.menu-button { background: transparent; border: 0; color: var(--menu-text); font-size: 16px; opacity: 0; transition: width 500ms cubic-bezier(0.16, 1, 0.3, 1), opacity 500ms linear; }
.menu-button.menu-expanded { opacity: 1; transition: width 500ms cubic-bezier(0.16, 1, 0.3, 1), opacity 83ms linear; }
.menu-button.menu-exploded { opacity: 0; transition: width 200ms cubic-bezier(0.16, 1, 0.3, 1), opacity 150ms linear; }
.menu-box { transform: skewX(-11.31deg); }
.menu-flash { background: var(--menu-flash); opacity: 0; transition: opacity 800ms cubic-bezier(0.16, 1, 0.3, 1); }
.menu-hovered .menu-flash { opacity: 0.1; transition: opacity 150ms cubic-bezier(0.23, 1, 0.32, 1); }
.menu-down .menu-flash { opacity: 0.1; transition: opacity 1000ms cubic-bezier(0.23, 1, 0.32, 1); }
.menu-hit .menu-flash { opacity: 0.9; transition: none; }
#title-options .menu-box { background: var(--menu-settings); }
#title-back .menu-box { background: var(--menu-back); }
#title-play .menu-box, #title-single .menu-box { background: var(--menu-play); }
#title-multi .menu-box, #title-medley .menu-box, #title-course .menu-box, #title-story .menu-box { background: var(--menu-multi); }
#title-edit .menu-box { background: var(--menu-edit); }
#title-quit .menu-box { background: var(--menu-quit); }
/* osu!lazer OsuLogo: hover 1.1 over 500 ms OutElastic, press 0.9 over 1000 ms Out, release 500 ms
   OutElastic, click flash 0.4 fading over 1500 ms OutExpo. */
#title-logo { transition: transform 500ms linear(0, 0.272 2.5%, 0.646 5%, 1 7.5%, 1.25 10%, 1.364 12.5%, 1.354 15%, 1.257 17.5%, 1.125 20%, 1 22.5%, 0.912 25%, 0.871 27.5%, 0.875 30%, 0.909 32.5%, 0.956 35%, 1 37.5%, 1.031 40%, 1.046 42.5%, 1.044 45%, 1.032 47.5%, 1.016 50%, 1 52.5%, 0.989 55%, 0.984 57.5%, 0.984 60%, 0.989 62.5%, 0.994 65%, 1 67.5%, 1.004 70%, 1.006 72.5%, 1.006 75%, 1.004 77.5%, 1.002 80%, 1 82.5%, 0.998 87.5%, 0.998 90%, 1 97.5%, 1); }
#title-logo.hovered { transform: scale(1.1); }
#title-logo svg { transition: transform 500ms linear(0, 0.272 2.5%, 0.646 5%, 1 7.5%, 1.25 10%, 1.364 12.5%, 1.354 15%, 1.257 17.5%, 1.125 20%, 1 22.5%, 0.912 25%, 0.871 27.5%, 0.875 30%, 0.909 32.5%, 0.956 35%, 1 37.5%, 1.031 40%, 1.046 42.5%, 1.044 45%, 1.032 47.5%, 1.016 50%, 1 52.5%, 0.989 55%, 0.984 57.5%, 0.984 60%, 0.989 62.5%, 0.994 65%, 1 67.5%, 1.004 70%, 1.006 72.5%, 1.006 75%, 1.004 77.5%, 1.002 80%, 1 82.5%, 0.998 87.5%, 0.998 90%, 1 97.5%, 1); }
#title-logo.pressed svg { transform: scale(0.9); transition: transform 1000ms cubic-bezier(0.5, 1, 0.89, 1); }
#title-flash { opacity: 0; transition: opacity 1500ms cubic-bezier(0.16, 1, 0.3, 1); }
#title-flash.lit { opacity: 0.4; transition: none; }
/* osu!lazer SettingsPanel: in from the left over 600 ms OutQuint while fading over 300 ms OutQuint; out the same way. */
#settings { transition: transform 600ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#settings.away { transform: translateX(calc(-50vw - 50%)); opacity: 0; }
#title-web { background: transparent; border: 0; color: var(--text); font-size: 13px; line-height: 1.2; opacity: 0.8; }
#title-web:hover, #title-web:focus-visible { opacity: 1; }
#title-web:focus-visible { outline: 2px solid var(--accent); }
#title-web .title-brand { font-family: "Gosu Counter", "Gosu UI", sans-serif; font-size: 40px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; }
.logo-disc { color: var(--line); }
.logo-ring { color: var(--accent); }
.logo-notes { color: var(--text); }
#title-player { background: var(--chat-bg); color: var(--text); text-shadow: 0 1px 2px var(--bg); }
#title-time { color: var(--text); font-family: ui-monospace, Consolas, monospace; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Progress bar resizes over 500 ms OutQuint; music buttons take a 60% accent wash on hover (lazer's YellowDark at 0.6). */
.title-track { background: var(--button-light); transition: height 500ms cubic-bezier(0.23, 1, 0.32, 1); }
#title-progress span { background: var(--accent); }
#title-controls button { background: transparent; color: var(--text); border: 0; }
#title-controls button:hover, #title-controls button:focus-visible { background: color-mix(in srgb, var(--accent) 60%, transparent); outline: 0; }
/* Volume overlay: 100ms fade, selected meter grows to 1.04 over 500ms (OutExpo), master in the accent. */
#volume { background: var(--scrim); opacity: 0; transition: opacity 100ms linear; }
#volume[data-shown] { opacity: 1; }
.volume-meter { transform: scale(1); transition: transform 500ms cubic-bezier(0.19, 1, 0.22, 1); }
.volume-meter[data-selected] { transform: scale(1.04); }
.volume-track { color: var(--line); }
.volume-fill { color: var(--text); }
.volume-meter[data-volume="master"] .volume-fill { color: var(--accent); }
.volume-value { font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.volume-name { background: var(--field); color: var(--dim); font-size: 12px; font-weight: 700; }
.volume-meter[data-selected] .volume-name { background: var(--accent-tint); color: var(--text); }
/* Sort window: the opener and its choices are large targets. */
.hints button { font-size: 15px; font-weight: 700; line-height: 1.2; border: 0; background: var(--field); }
.hints button + button { border-left: 1px solid var(--line); }
.hints button:hover, .hints button:focus-visible { background: var(--accent-tint); }
.hints button:active { background: var(--accent); color: var(--on-accent); }
.hints button:active kbd { color: var(--on-accent); }
.hints kbd { font-family: inherit; font-size: 11px; font-weight: 400; }
#scroll-summary, #mod-summary { font-size: 13px; font-weight: 700; color: var(--accent); }
#mod-summary .mod-key { background: var(--accent); color: var(--on-accent); font-weight: 900; }
#notices > p, #popups > p { background: var(--chat-bg); color: var(--text); font-size: 14px; }
#player { font-size: 15px; line-height: 1.2; }
#player > span, #player > feel-label > span { font-size: 12px; color: var(--dim); }
#player > span b, #player > feel-label > span b { color: var(--text); }
#sort-options button { font-size: 1.1em; }
#key-pad { background: var(--field); border: 1px solid var(--line); }
#key-pad:focus { border-color: var(--accent); }
#multi-panel { background: var(--field); color: var(--text); border: 1px solid var(--line); }
/* Detail hero: the chart background fills it; level, chart name and title sit on a dark band at its foot. */
/* Pictures crossfade at full strength inside #backdrop, which alone sets the dim (osu!lazer dims the
   whole background stack), so two overlapping pictures never add up to a brighter screen. */
#bg { opacity: 0; transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1); }
#bg-old { opacity: 1; }
#bg-old.gone { opacity: 0; transition: opacity 0.25s linear; }
#bg.shown { opacity: 1; }
/* The same brightness as the game: the background dim setting (data-dim, default 75%). */
#backdrop { opacity: calc(1 - attr(data-dim type(<number>), 75) / 100); transition: opacity 500ms cubic-bezier(0.61, 1, 0.88, 1); }
#backdrop.instant { transition: none; }
/* Tab reveals the artwork at full brightness and clears menus and overlays. */
body.background-view #app > :not(#backdrop) { opacity: 0; }
body.background-view #backdrop { opacity: 1; }
#bg.instant { transition: none; }
/* osu!lazer MainMenu: with the menu buttons open the background sits at Gray(0.8), faded over 500 ms OutSine. */
#title:not([hidden]) ~ #backdrop { opacity: 0.8; }
/* Starting a chart (osu!lazer): the row flashes white 40% and clears over 1000 ms OutQuint, song select
   fades out over 300 ms OutQuint, the background brightens over 800 ms OutQuint and the chart card
   grows from 0.7 over 650 ms OutQuint while fading in over 500 ms. */
#song-list li.activated { background: var(--activation); transition: none; }
#song-list li.released { transition: background 1000ms cubic-bezier(0.23, 1, 0.32, 1), border-color 0.12s ease-out, margin-left 400ms cubic-bezier(0.23, 1, 0.32, 1); }
#songselect { transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#songselect.leaving { opacity: 0; }
/* osu!lazer SongSelect wedges (updateWedgeVisibility): arriving, the title and details wedges slide in from
   150 px left and the filter from 150 px right over 600 ms OutQuint, fading in over 200 ms Easing.In; starting a
   chart sends them back the same way. */
#detail, #list-head { transition: transform 600ms cubic-bezier(0.23, 1, 0.32, 1), opacity 200ms cubic-bezier(0.11, 0, 0.5, 0); }
#songselect.entering #detail, #songselect.leaving #detail { transform: translateX(-150px); opacity: 0; }
#songselect.entering #list-head, #songselect.leaving #list-head { transform: translateX(150px); opacity: 0; }
#songselect.entering #detail, #songselect.entering #list-head { transition: none; }
#backdrop.loading { opacity: 1; transition: opacity 800ms cubic-bezier(0.23, 1, 0.32, 1); }
#loader { background: var(--field); border: 1px solid var(--line); opacity: 0; transform: scale(0.7); }
#loader.shown { opacity: 1; transform: none; transition: transform 650ms cubic-bezier(0.23, 1, 0.32, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1); }
/* ContentOut: back to 0.7 over 600 ms and out over 300 ms, both OutQuint. */
#loader.shown.out { opacity: 0; transform: scale(0.7); transition: transform 600ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#loader-title { font-size: 20px; font-weight: 700; }
#loader-artist, #loader-chart { color: var(--dim); }
/* Results (osu!lazer ResultsScreen): the screen comes in over 250 ms while the background dims to half. */
#result { transition: opacity 250ms linear; }
#hud-preview { background: var(--field); }
#settings-preview-frame { background: var(--field); }
#settings-preview > p { color: var(--dim); font-size: 12px; }
#hud-preview iframe { border: 0; }
.hud-preview-page { background: var(--field); }
#preview-error { color: var(--text); font-size: 14px; }
#hud-layout-status { color: var(--dim); font-size: 12px; }
#result.entering { opacity: 0; transition: none; }
#backdrop.result-dim { opacity: 0.125; transition: opacity 250ms linear; }
/* Results use the same flat surfaces and cyan accent as song select. */
:root { --result-kool: #54dded; --result-cool: #a691f2; --result-good: #eace5c; --result-miss: #f98f8a; --result-fast: #75b2f2; --result-slow: #f2c15f; }
#result { background: var(--scrim); font-family: "Gosu UI", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif; }
#result-head { border-bottom: 1px solid var(--line); }
#result-heading { color: var(--dim); font-size: 12px; font-weight: 700; letter-spacing: 0.18em; }
#result-heading:focus { outline: none; }
#result-song { font-size: clamp(28px, 3vw, 40px); font-weight: 700; letter-spacing: -0.025em; line-height: 1.15; }
#result-chart-name { color: var(--text); font-size: 15px; font-weight: 700; }
#result-keys { color: var(--on-accent); background: var(--accent); font-size: 13px; letter-spacing: 0.04em; }
#result-difficulty { color: var(--accent); letter-spacing: 0.06em; }
#result-flags { color: var(--dim); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; }
#result-state { color: var(--accent); font-family: "Gosu Counter", sans-serif; font-size: clamp(32px, 4vw, 48px); font-style: italic; font-weight: 700; letter-spacing: -0.01em; line-height: 1; }
#result[data-completed="false"] #result-state { color: var(--result-miss); }
#result-run { color: var(--dim); font-size: 12px; line-height: 1.5; }
#result-run summary { cursor: pointer; }
#result-run dd { color: var(--text); }
#result-calibration { color: var(--dim); font-size: 12px; }
#result-total dt { font-size: 12px; letter-spacing: 0.06em; }
#result-mm-status, #result-performance-status { color: var(--dim); font-size: 12px; font-weight: 400; }
#result-total dt, #result-performance dt, #result h2 { color: var(--dim); }
#result-total .result-mm dd { color: var(--accent); }
#result-performance { border-top: 1px solid var(--line); }
#result-performance dt { font-size: 11px; letter-spacing: 0.04em; }
#result-performance dd { color: var(--text); font-size: 16px; font-weight: 700; }
#result-total dd { font-size: clamp(24px, 3vw, 36px); font-weight: 700; line-height: 1.4; }
#result-total #result-points { font-family: "Gosu Counter", sans-serif; font-size: clamp(44px, 5.6vw, 76px); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 0; line-height: 1.2; }
.result-points { border-bottom: 2px solid var(--accent); }
#result dd { font-variant-numeric: tabular-nums; }
#result h2 { font-size: 12px; font-weight: 400; letter-spacing: 0.06em; }
#comparison-status { color: var(--text); font-size: 16px; font-weight: 700; }
#comparison-status.improved { color: var(--accent); font-weight: 700; }
#comparison { font-size: 12px; }
#comparison #delta-points { font-size: 18px; font-weight: 700; }
#result-detail { border-left: 1px solid var(--line); }
.result-grade dt { color: inherit; font-family: "Gosu Counter", sans-serif; font-size: 14px; font-weight: 700; letter-spacing: 0.06em; }
.result-grade > dd:not(.result-track) { font-size: 22px; font-weight: 700; line-height: 1.2; }
.result-grade[data-grade="kool"] { color: var(--result-kool); }
.result-grade[data-grade="cool"] { color: var(--result-cool); }
.result-grade[data-grade="good"] { color: var(--result-good); }
.result-grade[data-grade="miss"] { color: var(--result-miss); }
#result-timing dt { font-size: 13px; font-weight: 700; letter-spacing: 0.08em; }
#result-timing dd { font-size: 17px; font-weight: 700; }
#result-timing [data-timing="fast"] { color: var(--result-fast); }
#result-timing [data-timing="slow"] { color: var(--result-slow); }
#result-timeline { background: var(--field); }
#result-timeline > span { background: var(--line); }
#result-timeline > i[data-grade="good"] { background: var(--result-good); }
#result-timeline > i[data-grade="miss"] { background: var(--result-miss); }
.result-track { background: var(--line); }
.result-track span { background: currentColor; }
#result-foot { border-top: 1px solid var(--line); }
#result-foot button { font-size: 13px; font-weight: 700; }
#result-foot #retry { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
#result-foot kbd { color: var(--dim); font-family: inherit; font-size: 11px; }
#result-saved, #result-warnings { color: var(--result-miss); font-size: 12px; }
@media (max-width: 760px) {
    #result-detail { border-left: 0; }
    #result-foot { background: var(--bg); }
}
/* Song select: every info pane sits on the same dim so text reads over the chart background. */
#top, #detail, #list-pane, #commands, #medley-top, #medley-detail, #medley-list, #medley-commands { background: var(--scrim); }
#hero-level { color: var(--accent); font-variant-numeric: tabular-nums; line-height: 1; }
#hero-level span { font-size: 11px; }
#hero-level b { font-size: 32px; font-weight: 700; }
/* A Time Rate other than 1 is a filled accent badge beside the level and on the loader. */
.rate-badge { background: var(--accent); color: var(--on-accent); font-size: 24px; font-weight: 900; font-variant-numeric: tabular-nums; line-height: 1.1; }
#selected-heading { font-size: 22px; line-height: 1.2; }
#history-status, #preview-status { color: var(--dim); }
#history li.ranked { font-variant-numeric: tabular-nums; }
#history .ranked-rank, #history .ranked-accuracy { color: var(--dim); }
#history li.ranked[aria-current="true"] { font-weight: 700; }
/* osu!lazer Leaderboard placeholder: 22px text; ScaleTo(0.8) then 1 over 900 ms OutQuint, fading in over 300 ms OutQuint. */
#history-status.placeholder { font-size: 22px; transition: transform 900ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#history-status.placeholder.entering { transform: scale(0.8); opacity: 0; transition: none; }
#preview-status { font-size: 12px; }
#hero { background: var(--hero); }
#hero-text { background: var(--scrim); }
#song-duration { color: var(--text); font-variant-numeric: tabular-nums; line-height: 1; }
#song-duration svg { color: var(--accent); }
#duration-label { color: var(--dim); font-size: 10px; }
#duration-value { font-family: "Gosu Counter", sans-serif; font-size: 22px; font-weight: 700; }
#duration-original { color: var(--dim); font-family: "Gosu Counter", sans-serif; font-size: 15px; font-weight: 700; }
#song-duration[data-adjusted="true"] #duration-value { color: var(--accent); }
#song-duration:not([data-state="ready"]) #duration-value { color: var(--dim); font-family: inherit; font-size: 12px; font-weight: 400; }
#song-notes { color: var(--dim); font-size: 12px; font-variant-numeric: tabular-nums; }
#note-count { color: var(--text); font-size: 16px; }
#hold-ratio { color: var(--accent); }
#info-density { background: var(--field); }
#info-density span { background: var(--accent); }
#chart-menu { border: 1px solid var(--line); }
#chart-menu-name { color: var(--dim); font-size: 12px; }
.score-points { font-size: 22px; font-variant-numeric: tabular-nums; line-height: 1.15; }
.score-performance [data-off="true"], #result-performance-gosu[data-off="true"] { opacity: 0.35; }
.score-mods { color: color-mix(in srgb, var(--text) 75%, transparent); font-size: 10px; line-height: 1.2; }
.score-mods > span { border: 1px solid color-mix(in srgb, currentColor 35%, transparent); }
.score-mods [data-gauge] { background: color-mix(in srgb, currentColor 7%, transparent); }
.score-mods [data-gauge="1"] { color: var(--lamp-gauge1-core); }
.score-mods [data-gauge="2"] { color: var(--lamp-gauge2-core); }
.score-mods [data-gauge="3"] { color: var(--lamp-gauge3-core); }
.score-performance { border-top: 1px solid color-mix(in srgb, var(--text) 15%, transparent); line-height: 1.2; }
.score-model, .score-value small { color: color-mix(in srgb, var(--text) 70%, transparent); font-weight: 400; }
.score-model { font-size: 10px; }
.score-performance [data-model="gosu"] .score-model { color: color-mix(in srgb, var(--accent) 60%, var(--text)); }
.score-value b { color: var(--text); font-family: "Gosu Counter", sans-serif; font-size: clamp(13px, 5.3cqi, 17px); font-variant-numeric: tabular-nums; }
.score-value small { font-size: 9px; }
/* Taller record rows keep a shallow shear so upright text stays inside the button. */
button.score-open.feel { transform: skewX(-4.6deg); }
button.score-open.feel > .feel-label { transform: skewX(4.6deg); }
button.score-open.feel.feel-press { transform: skewX(-4.6deg) scale(0.9); }
@container (max-width: 230px) {
    .score-value b { font-size: 17px; }
}
#score-tip { background: var(--field); border: 1px solid var(--line); border-left: 2px solid var(--accent); font-variant-numeric: tabular-nums; }
#score-tip .tip-main { font-size: 14px; font-weight: 700; }
#score-tip .tip-sub { color: var(--dim); font-size: 12px; }
#difficulty { color: var(--text); font-size: 15px; }
#best { color: var(--accent); font-size: 12px; font-variant-numeric: tabular-nums; }
#best-list .best-mm b { font-size: 18px; font-variant-numeric: tabular-nums; }
#best-list .best-mm small { font-size: 14px; font-variant-numeric: tabular-nums; }
#best-list .best-mm > span:last-child { color: var(--dim); font-variant-numeric: tabular-nums; }
:root { --best-box: #3a4446; --best-box-mm: #66e0ff; --best-box-unit: #94c5d1; }
#best-list .best-box { background: var(--best-box); }
#best-list .best-box b { color: var(--best-box-mm); font-size: 18px; font-variant-numeric: tabular-nums; }
#best-list .best-box small { color: var(--best-box-unit); font-size: 12px; }
/* Keep the carousel's margin transition when a row loses selection, too. */
.song-catalog li { transition: margin-left 400ms cubic-bezier(0.23, 1, 0.32, 1), background 200ms cubic-bezier(0.23, 1, 0.32, 1), border-color 120ms ease-out; }
#info-density > span { transform-origin: bottom; }
@media (prefers-reduced-motion: reduce) {
    #bg, #bg-old.gone, .song-catalog li, #song-list li.released, #songselect, #backdrop, #backdrop.loading, #loader.shown, #loader.shown.out, #result, #backdrop.result-dim, .slider-fill, .slider-rest, .slider-nub, .menu-button, .menu-flash, #title-band, #title-spot, #title-logo, #title-logo svg, #title-flash, #settings, #history-status.placeholder { transition: none; }
}
/* The in-window cursor (cursor.js) replaces the system one. */
*, *::before, *::after { cursor: none !important; }
#cursor { background: transparent; border: 0; }
.cursor-body { color: var(--cursor-body); }
.cursor-shadow, .cursor-inside { color: var(--cursor-edge); opacity: 0.5; }
.cursor-glow { color: var(--cursor-glow); }

/* Decision 28 → osu!lazer ShearedButton (motion/motion.js): sheared by 0.2 (11.31°) with the label upright and a
   2px border; hover brightens over 150 ms OutQuint (lazer's Lighten(0.2), here a 10% white layer because the
   theme has no filters); pressing shrinks to 0.9 over 2000 ms OutQuint and release springs back over 1000 ms
   OutElastic; a click flashes 90% white that clears over 800 ms OutQuint. */
button.feel { border-width: 2px; transform: skewX(-11.31deg); transition: transform 1000ms linear(0, 0.272 2.5%, 0.646 5%, 1 7.5%, 1.25 10%, 1.364 12.5%, 1.354 15%, 1.257 17.5%, 1.125 20%, 1 22.5%, 0.912 25%, 0.871 27.5%, 0.875 30%, 0.909 32.5%, 0.956 35%, 1 37.5%, 1.031 40%, 1.046 42.5%, 1.044 45%, 1.032 47.5%, 1.016 50%, 1 52.5%, 0.989 55%, 0.984 57.5%, 0.984 60%, 0.989 62.5%, 0.994 65%, 1 67.5%, 1.004 70%, 1.006 72.5%, 1.006 75%, 1.004 77.5%, 1.002 80%, 1 82.5%, 0.998 87.5%, 0.998 90%, 1 97.5%, 1); }
button.feel.feel-press { transform: skewX(-11.31deg) scale(0.9); transition: transform 2000ms cubic-bezier(0.23, 1, 0.32, 1); }
.feel-label { transform: skewX(11.31deg); }
/* The bottom command strip is flush with the bar edges, so its buttons stay unsheared (a sheared corner would stick out). */
.hints button.feel, .hints button.feel > .feel-label { transform: none; }
.hints button.feel.feel-press { transform: scale(0.9); }
.feel-hover, .feel-flash { background: var(--feel); opacity: 0; }
.feel-hover { transition: opacity 150ms cubic-bezier(0.23, 1, 0.32, 1); }
button.feel-hovered > .feel-hover { opacity: 0.1; }
.feel-flash { transition: opacity 800ms cubic-bezier(0.23, 1, 0.32, 1); }
button.feel-flash-on > .feel-flash { opacity: 0.9; transition: none; }
/* OsuTabControl: the selected tab changes over TRANSITION_LENGTH 500 ms OutQuint. */
#settings-tabs button:not(.feel-press) { transition: background 500ms cubic-bezier(0.23, 1, 0.32, 1), color 500ms cubic-bezier(0.23, 1, 0.32, 1), border-color 500ms cubic-bezier(0.23, 1, 0.32, 1), transform 1000ms linear(0, 0.272 2.5%, 0.646 5%, 1 7.5%, 1.25 10%, 1.364 12.5%, 1.354 15%, 1.257 17.5%, 1.125 20%, 1 22.5%, 0.912 25%, 0.871 27.5%, 0.875 30%, 0.909 32.5%, 0.956 35%, 1 37.5%, 1.031 40%, 1.046 42.5%, 1.044 45%, 1.032 47.5%, 1.016 50%, 1 52.5%, 0.989 55%, 0.984 57.5%, 0.984 60%, 0.989 62.5%, 0.994 65%, 1 67.5%, 1.004 70%, 1.006 72.5%, 1.006 75%, 1.004 77.5%, 1.002 80%, 1 82.5%, 0.998 87.5%, 0.998 90%, 1 97.5%, 1); }
/* Decision 29 → osu!lazer screens: a screen fades in over 300 ms OutQuint (SongSelect, MainMenu FADE_IN with
   the buttons moving back from -800 of 1366); the title leaves over 400 ms InSine, moving its buttons -800. */
#title, #editor { transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#title-menu { transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1); }
#title.entering, #songselect.entering, #editor.entering { opacity: 0; transition: none; }
#title.entering #title-menu { transform: translateX(-58.57vw); transition: none; }
#title.leaving-ghost { transition: opacity 400ms cubic-bezier(0.12, 0, 0.39, 0), transform 400ms cubic-bezier(0.12, 0, 0.39, 0); }
#title.leaving-ghost.gone { opacity: 0; transform: translateX(-58.57vw); }
/* PopupDialog: grows from 0.7 over 750 ms OutElasticHalf while fading in over 500 ms OutQuint; the screen
   behind dims to 50% over 500 ms OutQuint. */
dialog.popup { transition: transform 750ms linear(0, 0.188 2.5%, 0.388 5%, 0.58 7.5%, 0.75 10%, 0.891 12.5%, 1 15%, 1.077 17.5%, 1.125 20%, 1.149 22.5%, 1.153 25%, 1.144 27.5%, 1.125 30%, 1.102 32.5%, 1.077 35%, 1.053 37.5%, 1.031 40%, 1.014 42.5%, 1 45%, 0.99 47.5%, 0.984 50%, 0.981 52.5%, 0.981 55%, 0.982 57.5%, 0.984 60%, 0.987 62.5%, 0.99 65%, 0.993 67.5%, 0.996 70%, 0.998 72.5%, 1 75%, 1.002 80%, 1.002 90%, 1.001 97.5%, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1); }
dialog.popup.entering { transform: scale(0.7); opacity: 0; transition: none; }
dialog.popup::backdrop { background: var(--popup-dim); transition: opacity 500ms cubic-bezier(0.23, 1, 0.32, 1); }
dialog.popup.entering::backdrop { opacity: 0; transition: none; }
@media (prefers-reduced-motion: reduce) {
    button.feel, button.feel.feel-press, .feel-hover, .feel-flash, #settings-tabs button:not(.feel-press), #title, #editor, #title-menu, #title.leaving-ghost, dialog.popup, dialog.popup::backdrop, #song-list li, #song-list li::before, #detail, #list-head, #edit-rates button { transition: none; }
}

#list-position { font-variant-numeric: tabular-nums; }
.list-track { background: var(--line); }
#list-range-window { background: var(--accent); }

#playing-status { color: var(--text); }
#playing-message { background: var(--chat-bg); }
#playing-chart { color: var(--accent); }

#web-play { background: var(--bg); color: var(--text); }

#web-play iframe { border: 0; }

/* Play-mode controls share the app theme. */
.play-options { border: 0; }
.mod-section h3 { font-size: 13px; color: var(--dim); }
.mod-section output { color: var(--accent); font-size: 11px; font-weight: normal; }
.option-buttons small { font-size: 11px; }
.mod-buttons strong { font-size: 12px; line-height: 1; letter-spacing: 1px; color: var(--dim); }
.mod-buttons button { background: var(--hero); border: 1px solid var(--line); border-bottom: 3px solid var(--button); color: var(--text); font-size: 16px; transition: background-color 150ms, border-color 150ms, transform 150ms; }
.mod-buttons button:hover { background: var(--field); border-color: var(--button-light); }
.mod-buttons button[aria-pressed="true"] { background: var(--accent-tint); border-color: var(--accent); color: var(--text); }
.mod-buttons button:focus-visible { outline: 2px solid var(--text); }
.mod-buttons button:disabled, .mod-tuning button:disabled { opacity: .35; }
#mods-dialog button.feel, #mods-dialog .feel-label { transform: none; }
#mods-dialog button.feel-press { transform: scale(.97); }
.mod-buttons .feel-hover, .mod-buttons .feel-flash { display: none; }
.mod-icon { color: var(--activation); transition: color 150ms; }
.mod-buttons button:hover .mod-icon, .mod-buttons button[aria-pressed="true"] .mod-icon { color: var(--accent); }
.mod-buttons small { color: var(--dim); font-size: 10px; font-weight: normal; line-height: 1.5; }
.mod-state { color: var(--dim); font-size: 9px; font-weight: bold; letter-spacing: .5px; }
[aria-pressed="true"] > .mod-state, [aria-pressed="true"] .feel-label > .mod-state { color: var(--on-accent); background: var(--accent); }
.mod-note { color: var(--dim); font-size: 10px; line-height: 1.6; }
.mod-tuning { border-left: 1px solid var(--line); }
.mod-tuning .option-buttons { gap: 4px; }
.mod-tuning .option-buttons button { font-size: 12px; background: var(--field); border-color: var(--line); }
.mod-tuning .option-buttons button[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent); border-color: var(--accent); }
.gauge-mark { font-size: 11px; letter-spacing: -2px; }
#health-buttons [data-value="1"] .gauge-mark { color: var(--lamp-gauge1); }
#health-buttons [data-value="2"] .gauge-mark { color: var(--lamp-gauge2-core); }
#health-buttons [data-value="3"] .gauge-mark { color: var(--lamp-gauge3-core); }
#mods-head { border-bottom: 1px solid var(--line); }
#mods-dialog { border: 1px solid var(--line); border-top: 3px solid var(--accent); }
#mods-heading { font-size: 25px; }
#mods-head button { font-size: 12px; background: transparent; border-color: var(--line); }
#mods-dialog #rate-presets button.feel { transform: translateX(-50%); font-size: 13px; }
#mods-dialog #rate-presets button.feel-press { transform: translateX(-50%) scale(.97); }
@media (max-width: 800px) { .mod-tuning { border-left: 0; } }
@media (prefers-reduced-motion: reduce) { .mod-buttons button, .mod-icon { transition: none; } }
/* Toasts (notification.js): osu!lazer Notification. Background3, Background2 on hover over 200 ms OutQuint; the icon
   column on Background5; SimpleNotification text 14 px medium; check icon Foreground1, Content1 on hover. */
#toasts { background: transparent; border: 0; }
.toast { transition: translate 150ms cubic-bezier(0.25, 1, 0.5, 1), opacity 200ms linear; }
.toast[data-state="enter"] { opacity: 0; }
.toast[data-state="forward"] { translate: 400px 0; opacity: 0; transition: translate 600ms cubic-bezier(0.22, 1, 0.36, 1), opacity 600ms cubic-bezier(0.22, 1, 0.36, 1); }
.toast[data-state="fade"] { opacity: 0; transition: opacity 100ms linear; }
.toast[data-state="fling"] { transition: none; }
.toast-main { background: var(--toast); transition: transform 500ms cubic-bezier(0.22, 1, 0.36, 1), background-color 200ms cubic-bezier(0.22, 1, 0.36, 1); }
.toast[data-state="enter"] .toast-main { transform: translateX(100%); }
.toast-main:hover { background: var(--toast-hover); }
.toast-icon { background: var(--toast-icon); color: var(--toast-glyph); }
.toast-text { color: var(--text); font-size: 14px; font-weight: 500; line-height: 20px; }
.toast-text > span:last-child { color: var(--toast-check); }
.toast-close { background: transparent; color: var(--toast-check); border: 0; transition: background-color 200ms cubic-bezier(0.22, 1, 0.36, 1), color 200ms cubic-bezier(0.22, 1, 0.36, 1); }
.toast-close:hover { background: var(--toast-close-hover); color: var(--toast-check-hover); }
.toast-flash { background: var(--toast-flash); opacity: 0; transition: opacity 2000ms cubic-bezier(0.165, 0.84, 0.44, 1); }
.toast[data-state="enter"] .toast-flash { opacity: 0.8; transition: none; }
/* Long settings choices, osu!lazer OsuDropdown colours: header and menu on Background5, hovered header and
   pre-selected item Light4, the picked item Background3; a disabled dropdown drops to 30%. Menu fades and
   grows over 300 ms OutQuint; the chevron flips over 300 ms OutQuint. Items light in 100 ms OutQuint and
   clear in 600 ms; the hovered item's chevron slides in over 400 ms OutQuint and out over 200 ms In. */
.dropdown-head { background: var(--field); color: var(--text); border: 0; font-size: inherit; }
.dropdown-head:hover:not(:disabled) { background: var(--button-light); }
.dropdown-head:disabled { opacity: 0.3; }
.dropdown-chevron { border-color: var(--text); transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), margin-top 300ms cubic-bezier(0.23, 1, 0.32, 1); }
.dropdown-menu { background: var(--field); transition: grid-template-rows 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1), visibility 0s 300ms; }
.dropdown.open .dropdown-menu { transition: grid-template-rows 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1), visibility 0s; }
.dropdown-list > button { background: transparent; color: var(--text); font-size: inherit; transition: background-color 600ms cubic-bezier(0.23, 1, 0.32, 1); }
.dropdown-list > button[aria-selected="true"] { background: var(--button); transition-duration: 100ms; }
.dropdown-list > button[data-pre] { background: var(--button-light); transition-duration: 100ms; }
.dropdown-mark { border-color: var(--field); opacity: 0; transition: opacity 200ms linear, transform 200ms cubic-bezier(0.55, 0.085, 0.68, 0.53); }
.dropdown-list > button:hover .dropdown-mark { opacity: 1; transform: translate(0, -50%) rotate(-45deg); transition: opacity 400ms cubic-bezier(0.23, 1, 0.32, 1), transform 400ms cubic-bezier(0.23, 1, 0.32, 1); }
/* Story: covers of songs not yet cleared stay dim; a new clear develops in. */
.story-photo { background: var(--button); opacity: 1; transition: opacity 1200ms cubic-bezier(0.23, 1, 0.32, 1); }
.story-photo[data-state="open"] { opacity: 0.35; }
.story-photo[data-state="locked"] { opacity: 0.15; }
#story-count { color: var(--dim); }
#story-stage { background: var(--button); }
#story-cover { transition: opacity 1200ms cubic-bezier(0.23, 1, 0.32, 1), filter 1200ms cubic-bezier(0.23, 1, 0.32, 1); }
#story-cover[data-state="open"] { filter: grayscale(1); opacity: 0.6; }
.story-fx-copy, .story-fx-flash, .story-fx-dot, .story-fx-star, .story-fx-title, .story-fx-side { mix-blend-mode: plus-lighter; }
.story-fx-flash { background: var(--story-glow); }
.story-fx-dot { background: radial-gradient(circle, var(--story-glow) 0 4%, color-mix(in srgb, var(--story-glow) 52%, transparent) 4%, transparent 60%); }
.story-fx-star { background: var(--story-star); clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%); }
.story-fx-title { color: var(--story-glow); font-size: 20px; }
.story-fx-side.left { background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 60%, transparent), transparent); }
.story-fx-side.right { background: linear-gradient(270deg, color-mix(in srgb, var(--accent) 60%, transparent), transparent); }
#story-charts li[aria-selected="true"] { background: var(--pulse-rest); border-left: 4px solid var(--accent); }
