/* =========================================================================
   ENHANCEMENTS.CSS — Yamiko Dashboard visual/animation polish layer.

   Purely additive: nothing here overrides the structural rules in
   styles.css, it only layers motion, depth, and finishing touches on top
   of the classes that already exist. Safe to delete this one file (and
   its <link>) to fully revert to the previous look.
   ========================================================================= */

/* ---------- Motion accessibility ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

html { scroll-behavior: smooth; }

/* ---------- Custom scrollbars everywhere ---------- */
* {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--accent) 55%, transparent) transparent;
}
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--accent) 75%, transparent);
  background-clip: padding-box;
}

/* ---------- Focus states (a11y + polish) ---------- */
a, button, input, select, .nav-item, .qa-btn, .ctrl-btn, .icon-btn {
  outline: none;
}
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, .nav-item:focus-visible, .qa-btn:focus-visible,
.ctrl-btn:focus-visible, .icon-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px color-mix(in srgb, var(--accent) 70%, transparent);
  border-radius: 6px;
}

/* =========================================================================
   AMBIENT BACKGROUND — soft drifting glow blobs behind the whole app,
   purely decorative, sits behind every panel via z-index/pointer-events.

   Previously used filter:blur(110px) on a position:fixed element with a
   continuous, infinite transform animation — running on EVERY page, all
   the time. Blur at that radius forces the browser to rasterize an area
   much larger than the element itself on every single animation frame,
   which was a major, constant source of the "laggy" feel. The extra
   radial-gradient stops below give effectively the same soft-edged glow
   without ever invoking filter, and will-change lets the transform-only
   animation run on the compositor instead of repainting.
   ========================================================================= */
.app { position: relative; isolation: isolate; }
.app::before,
.app::after {
  content: '';
  position: fixed;
  z-index: -1;
  width: 640px;
  height: 640px;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0.16;
  background: radial-gradient(
    circle,
    var(--accent) 0%,
    color-mix(in srgb, var(--accent) 55%, transparent) 22%,
    color-mix(in srgb, var(--accent) 18%, transparent) 45%,
    transparent 70%
  );
  animation: ambientDrift 22s ease-in-out infinite alternate;
  will-change: transform;
}
.app::before { top: -200px; left: -140px; animation-delay: 0s; }
.app::after {
  bottom: -220px; right: -160px; animation-delay: -11s; opacity: 0.08;
  background: radial-gradient(
    circle,
    #ff7a7a 0%,
    color-mix(in srgb, #ff7a7a 55%, transparent) 22%,
    color-mix(in srgb, #ff7a7a 18%, transparent) 45%,
    transparent 70%
  );
}

@keyframes ambientDrift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(60px, 40px) scale(1.15); }
  100% { transform: translate(-30px, 70px) scale(0.95); }
}

/* ---------- Body / page base transitions ---------- */
body { animation: bodyFadeIn 0.5s ease both; }
@keyframes bodyFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* =========================================================================
   PAGE TRANSITIONS — .page.active gets a fade+rise on entry. Re-triggered
   by enhancements.js toggling .anim-in off/on whenever app.js switches
   the active page, so this works with the existing nav logic untouched.
   ========================================================================= */
.page.active.anim-in {
  animation: pageEnter 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Stagger the direct panel children of an entering page */
.page.active.anim-in .panel,
.page.active.anim-in .content-main > *,
.page.active.anim-in .right-rail > * {
  animation: panelEnter 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.page.active.anim-in .content-main > *:nth-child(1),
.page.active.anim-in .right-rail > *:nth-child(1) { animation-delay: 0.02s; }
.page.active.anim-in .content-main > *:nth-child(2),
.page.active.anim-in .right-rail > *:nth-child(2) { animation-delay: 0.08s; }
.page.active.anim-in .content-main > *:nth-child(3),
.page.active.anim-in .right-rail > *:nth-child(3) { animation-delay: 0.14s; }
.page.active.anim-in .content-main > *:nth-child(4),
.page.active.anim-in .right-rail > *:nth-child(4) { animation-delay: 0.2s; }
.page.active.anim-in .content-main > *:nth-child(n+5),
.page.active.anim-in .right-rail > *:nth-child(n+5) { animation-delay: 0.26s; }

@keyframes panelEnter {
  from { opacity: 0; transform: translateY(10px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* =========================================================================
   SIDEBAR
   ========================================================================= */
.sidebar { position: relative; }

.brand-avatar {
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent);
}
.brand:hover .brand-avatar {
  transform: scale(1.06) rotate(-3deg);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent), 0 0 22px color-mix(in srgb, var(--accent) 35%, transparent);
}
.brand-icon { display: inline-block; transition: transform 0.4s ease; }
.brand:hover .brand-icon { transform: rotate(-12deg) scale(1.12); }

.server-picker {
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.15s ease;
}
.server-picker:hover {
  border-color: var(--accent-dim);
  transform: translateY(-1px);
}
.server-picker:active { transform: translateY(0) scale(0.99); }
.server-picker svg.chev { transition: transform 0.2s ease; }
.server-picker[aria-expanded="true"] svg.chev,
.server-dropdown:not(.hidden) ~ .server-picker svg.chev { transform: rotate(180deg); }

.server-dropdown:not(.hidden) {
  animation: dropdownOpen 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes dropdownOpen {
  from { opacity: 0; transform: translateY(-6px) scaleY(0.96); transform-origin: top; }
  to   { opacity: 1; transform: translateY(0) scaleY(1); }
}
.server-dropdown-item { transition: background 0.15s ease, transform 0.15s ease, padding-left 0.15s ease; }
.server-dropdown-item:hover { transform: translateX(2px); }

/* Nav items: smooth sliding accent bar instead of an instant snap */
.nav-item {
  position: relative;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, padding-left 0.2s ease, transform 0.15s ease;
  overflow: hidden;
}
.nav-item::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 3px; height: 0;
  background: var(--accent);
  border-radius: 0 3px 3px 0;
  transform: translateY(-50%);
  transition: height 0.22s cubic-bezier(0.22, 1, 0.36, 1);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 70%, transparent);
}
.nav-item.active::before { height: 62%; }
.nav-item:hover { padding-left: 13px; }
.nav-item:active { transform: scale(0.98); }
.nav-item svg.icon { transition: transform 0.2s ease; }
.nav-item:hover svg.icon { transform: scale(1.1); }

.nav-chevron { transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1); }
.nav-subgroup {
  transition: max-height 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.nav-subitem {
  transition: background 0.2s ease, color 0.2s ease, transform 0.15s ease;
}
.nav-subitem:hover { transform: translateX(3px); }

.sidebar-user { transition: border-color 0.2s ease, transform 0.2s ease; }
.sidebar-user:hover { border-color: var(--accent-dim); transform: translateY(-1px); }

.status-dot {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 65%, transparent);
  animation: statusPulse 2.2s ease-out infinite;
}
@keyframes statusPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--good) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 0%, transparent); }
}

.user-avatar, .brand-avatar { transition: filter 0.2s ease; }
.sidebar-user:hover .user-avatar { filter: brightness(1.08); }

/* =========================================================================
   TOPBAR
   ========================================================================= */
.icon-btn {
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
.icon-btn:hover {
  transform: translateY(-2px) scale(1.06);
  border-color: var(--accent-dim);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 22%, transparent);
}
.icon-btn:active { transform: translateY(0) scale(0.95); }

.topbar-user { transition: border-color 0.2s ease, transform 0.2s ease; }
.topbar-user:hover { border-color: var(--accent-dim); transform: translateY(-1px); }

.logout-btn {
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}
.logout-btn:hover:not(:disabled) { transform: translateY(-1px); }
.logout-btn:active:not(:disabled) { transform: translateY(0) scale(0.97); }

.search-box { transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.search-box:focus-within {
  border-color: var(--accent-dim);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}

/* =========================================================================
   PANELS — lift + glow on hover, glossy top edge, animated border sheen.
   ========================================================================= */
.panel {
  position: relative;
  transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), border-color 0.25s ease, box-shadow 0.25s ease;
  will-change: transform;
}
.panel:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--panel-border));
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35), 0 0 0 1px color-mix(in srgb, var(--accent) 8%, transparent);
}
/* Skip the lift on panels the user is actively interacting with */
.dj-panel.panel:hover, .now-playing.panel:hover { transform: none; }
.panel:not(.dj-panel):not(.now-playing):hover { transform: translateY(-3px); }

.panel-title { position: relative; }
.live-dot {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 60%, transparent);
  animation: liveDotPulse 1.6s ease-out infinite;
}
@keyframes liveDotPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 55%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--good) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 0%, transparent); }
}

/* =========================================================================
   NOW PLAYING
   ========================================================================= */
.artwork {
  position: relative;
  overflow: hidden;
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.artwork::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 30%, color-mix(in srgb, var(--accent) 18%, transparent) 45%, transparent 60%);
  background-size: 220% 220%;
  background-position: 130% 130%;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.now-playing:hover .artwork::after {
  opacity: 1;
  animation: artworkSheen 1.6s ease forwards;
}
@keyframes artworkSheen {
  from { background-position: 130% 130%; }
  to   { background-position: -30% -30%; }
}
.now-playing:hover .artwork {
  box-shadow: 0 8px 26px color-mix(in srgb, var(--accent) 25%, transparent);
  transform: translateY(-2px);
}
/* Gentle spin while a track is actually playing (toggled by enhancements.js
   reading the existing #playing-badge text -- no app.js changes needed) */
.artwork.is-playing {
  animation: artworkSpin 14s linear infinite;
}
@keyframes artworkSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.now-playing:hover .artwork.is-playing { animation-play-state: paused; }

.badge-playing {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.25s ease, color 0.25s ease;
}
.badge-playing::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: badgeBlip 1.4s ease-in-out infinite;
}
@keyframes badgeBlip {
  0%, 100% { opacity: 0.4; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1.15); }
}

.track-title { transition: color 0.2s ease; }

.viz-bar {
  transition: height 0.15s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 40%, transparent));
  border-radius: 2px 2px 0 0;
}

.progress-track, .volume-track { transition: height 0.15s ease; }
.progress-track:hover, .volume-track:hover { height: 6px; }
.progress-fill, .volume-fill {
  transition: box-shadow 0.2s ease;
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 50%, transparent);
}
.progress-handle, .volume-handle {
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.18s ease;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent);
}
.progress-track:hover .progress-handle,
.volume-track:hover .volume-handle {
  transform: translate(-50%, -50%) scale(1.35);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 18%, transparent);
}

.ctrl-btn-main {
  position: relative;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
}
.ctrl-btn-main.is-playing {
  animation: mainBtnPulse 2s ease-out infinite;
}
@keyframes mainBtnPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  70%  { box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
}

/* =========================================================================
   BUTTONS — ripple support (spawned by enhancements.js), consistent lift.
   ========================================================================= */
.qa-btn, .ctrl-btn, .btn-outline, .btn-text, .play-row-btn, .log-tab,
.settings-tab, .logout-btn, .login-btn, .lvl-banner-dropzone {
  position: relative;
  overflow: hidden;
}
.ripple {
  position: absolute;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 45%, white 10%);
  opacity: 0.45;
  transform: scale(0);
  pointer-events: none;
  animation: rippleOut 0.6s ease-out forwards;
}
@keyframes rippleOut {
  to { transform: scale(2.6); opacity: 0; }
}

.qa-btn svg.icon { transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); }
.qa-btn:hover svg.icon { transform: scale(1.15) rotate(-4deg); }

.play-row-btn { transition: background 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease; }
.play-row-btn:hover { box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 40%, transparent); }

.log-tab, .settings-tab { transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease; }
.log-tab:hover, .settings-tab:hover { transform: translateY(-1px); }

/* =========================================================================
   TOGGLES
   ========================================================================= */
.slider { transition: background 0.25s ease, box-shadow 0.25s ease; }
.slider::before {
  transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.25s ease;
}
input:checked + .slider {
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* =========================================================================
   TABLE ROWS — subtle fade-in + hover slide
   ========================================================================= */
.queue-table tbody tr {
  transition: background 0.15s ease;
  animation: rowFadeIn 0.35s ease both;
}
@keyframes rowFadeIn {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: translateX(0); }
}
.queue-table tr:hover td { transform: translateX(2px); }
.queue-table td { transition: background 0.15s ease, transform 0.15s ease; }

.log-entry {
  animation: logSlideIn 0.3s ease both;
}
@keyframes logSlideIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* =========================================================================
   MODALS / OVERLAYS
   ========================================================================= */
.dj-overlay:not(.hidden) {
  animation: overlayFade 0.2s ease both;
  backdrop-filter: blur(4px);
}
@keyframes overlayFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.dj-overlay:not(.hidden) .dj-panel {
  animation: modalPop 0.28s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes modalPop {
  from { opacity: 0; transform: translateY(14px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* =========================================================================
   LOGIN PAGE — floating ambient orbs, glass card entrance, shine button.
   ========================================================================= */
.login-body { overflow: hidden; }
.login-hero {
  position: relative;
  animation: loginBgZoom 18s ease-in-out infinite alternate;
}
@keyframes loginBgZoom {
  from { background-size: cover; background-position: center 30%; }
  to   { background-size: 112% auto; background-position: center 22%; }
}

.login-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.35;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(circle, var(--accent), transparent 70%);
  animation: orbFloat 12s ease-in-out infinite alternate;
}
.login-orb.orb-1 { width: 320px; height: 320px; top: 8%; left: 6%; animation-duration: 14s; }
.login-orb.orb-2 { width: 260px; height: 260px; bottom: 10%; right: 8%; animation-duration: 17s; animation-delay: -4s; background: radial-gradient(circle, #ff9d4d, transparent 70%); }
.login-orb.orb-3 { width: 180px; height: 180px; top: 50%; right: 20%; animation-duration: 11s; animation-delay: -7s; opacity: 0.22; }

@keyframes orbFloat {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(40px, -30px) scale(1.12); }
}

.login-card {
  position: relative;
  z-index: 1;
  animation: cardRise 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
@keyframes cardRise {
  from { opacity: 0; transform: translateY(28px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.login-card .brand-icon {
  display: inline-block;
  animation: iconFloat 3.2s ease-in-out infinite;
}
@keyframes iconFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-4px) rotate(-6deg); }
}
.login-eyebrow { animation: fadeSlideIn 0.6s ease 0.15s both; }
.login-title { animation: fadeSlideIn 0.6s ease 0.25s both; }
.login-copy { animation: fadeSlideIn 0.6s ease 0.35s both; }
.login-btn { animation: fadeSlideIn 0.6s ease 0.45s both; }
@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.login-btn {
  position: relative;
  overflow: hidden;
  transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.login-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px color-mix(in srgb, var(--accent) 45%, transparent);
}
.login-btn:active { transform: translateY(0) scale(0.98); }
.login-btn::before {
  content: '';
  position: absolute;
  top: 0; left: -60%;
  width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.55), transparent);
  transform: skewX(-20deg);
  transition: left 0.6s ease;
}
.login-btn:hover::before { left: 130%; }

/* =========================================================================
   REVEAL ON SCROLL — used by enhancements.js for long settings pages
   ========================================================================= */
.reveal-on-scroll {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.reveal-on-scroll.revealed {
  opacity: 1;
  transform: translateY(0);
}
