:root {
  --bg: #f5f5f7;
  --surface: #ffffff;
  --text: #1d1d1f;
  --text-muted: #6e6e73;
  --accent: #0071e3;
  --accent-hover: #0077ed;
  --border: #e5e5ea;
  --navbar-bg: rgba(255, 255, 255, 0.8);
  --skeleton: #eceef0;
  --skeleton-shine: rgba(255, 255, 255, 0.7);
  --review-ok-fg: #1c7c3c;
  --review-ok-bg: rgba(52, 199, 89, 0.14);
  --review-pending-bg: rgba(142, 142, 147, 0.14);
  --mark-bg: rgba(255, 214, 10, 0.45);
  --chord-fg: #1d1d1f;
  --chord-bg: #e8e8ed;
  --radius-lg: 20px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --shadow: 0 2px 10px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03);
  --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.08);

  /* Tamano de la letra del cancionero. Lo ajusta el usuario con A- / A+ en el
     visor (assets/js/stage.js) y se guarda en localStorage. */
  --chord-fs: 1.05rem;

  /* Ritmo vertical del cancionero. Cada renglon de letra arrastra encima su
     fila de acordes, asi que el aire se acumula rapido: en un telefono estos
     valores deciden si se ven 8 renglones o 13. Se aprietan mas abajo en
     pantallas chicas. */
  --cl-gap: 0.6rem;
  --cl-chord-lh: 1.4;
  --cl-empty-h: 0.9em;
  --cl-section-top: 1rem;

  /* Alto real de la barra de navegacion, medido en vez de escrito a mano
     (assets/js/viewer-chrome.js): la barra del canto se apoya justo debajo y
     un valor desfasado deja colarse una franja de texto. */
  --navbar-h: 56px;

  /* Alto de la barra del canto. Es constante a proposito: es lo que permite
     reservarle el hueco una sola vez y que nada se mueva despues. */
  --song-bar-h: 56px;
}

/* Modo oscuro. La paleta clara de arriba es la unica definicion completa; aqui
   solo se redefinen los tokens que cambian. Va dos veces a proposito: una para
   el tema del sistema (salvo que el usuario haya elegido claro a mano) y otra
   para la eleccion explicita de oscuro, para que el boton gane en los dos
   sentidos. assets/js/theme.js es quien pone data-theme. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #000000;
    --surface: #1c1c1e;
    --text: #f5f5f7;
    --text-muted: #98989d;
    --accent: #0a84ff;
    --accent-hover: #409cff;
    --border: #2c2c2e;
    --navbar-bg: rgba(28, 28, 30, 0.8);
    --skeleton: #2c2c2e;
    --skeleton-shine: rgba(255, 255, 255, 0.08);
    --review-ok-fg: #4cd964;
    --review-ok-bg: rgba(52, 199, 89, 0.18);
    --review-pending-bg: rgba(142, 142, 147, 0.22);
    --mark-bg: rgba(255, 214, 10, 0.3);
    --chord-fg: #f5f5f7;
    --chord-bg: #3a3a3c;
    --shadow: 0 2px 10px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.6);
  }
}
:root[data-theme="dark"] {
  --bg: #000000;
  --surface: #1c1c1e;
  --text: #f5f5f7;
  --text-muted: #98989d;
  --accent: #0a84ff;
  --accent-hover: #409cff;
  --border: #2c2c2e;
  --navbar-bg: rgba(28, 28, 30, 0.8);
  --skeleton: #2c2c2e;
  --skeleton-shine: rgba(255, 255, 255, 0.08);
  --review-ok-fg: #4cd964;
  --review-ok-bg: rgba(52, 199, 89, 0.18);
  --review-pending-bg: rgba(142, 142, 147, 0.22);
  --mark-bg: rgba(255, 214, 10, 0.3);
  --chord-fg: #f5f5f7;
  --chord-bg: #3a3a3c;
  --shadow: 0 2px 10px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.6);
}

* { box-sizing: border-box; }

/* Bootstrap define display en .btn/.row, que le gana al [hidden] del navegador;
   con !important el atributo vuelve a ser confiable para ocultar los controles
   de edicion en el sitio publico (ver assets/js/edit-mode.js). */
[hidden] { display: none !important; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .fw-title {
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Navbar */
.navbar-apple {
  background: var(--navbar-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
}

.navbar-apple .navbar-brand {
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}

.navbar-apple .nav-link {
  color: var(--text-muted);
  font-weight: 500;
}

.navbar-apple .nav-link.active,
.navbar-apple .nav-link:hover {
  color: var(--text);
}

/* Buttons */
.btn-accent {
  background: var(--accent);
  border: none;
  color: #fff;
  border-radius: 980px;
  padding: 0.5rem 1.25rem;
  font-weight: 600;
  transition: background 0.15s ease;
}
.btn-accent:hover { background: var(--accent-hover); color: #fff; }

.btn-pill {
  border-radius: 980px;
  font-weight: 500;
}

/* Cards */
.card-apple {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

a.card-apple:hover {
  box-shadow: var(--shadow-hover);
  transform: translateY(-2px);
}

/* Search input */
.search-apple {
  border-radius: 980px;
  border: 1px solid var(--border);
  padding: 0.65rem 1.25rem;
  background: var(--surface);
}
.search-apple:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.15);
}

/* Tag chips */
.tag-chip {
  display: inline-block;
  border-radius: 980px;
  padding: 0.3rem 0.85rem;
  font-size: 0.8rem;
  font-weight: 600;
  border: 1.5px solid var(--tag-color, var(--border));
  background: var(--surface);
  color: var(--tag-color, var(--text-muted));
  cursor: pointer;
  user-select: none;
  transition: all 0.15s ease;
}
.tag-chip.active {
  background: var(--tag-color, var(--accent));
  border-color: var(--tag-color, var(--accent));
  color: #fff;
}
.tag-chip.tag-static {
  cursor: default;
  padding: 0.22rem 0.7rem;
  font-size: 0.72rem;
  background: var(--tag-color, var(--surface));
  border-color: transparent;
  color: #fff;
}

/* Hero header */
.hero-title {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-bottom: 0.25rem;
}
.hero-subtitle {
  color: var(--text-muted);
  font-size: 1.05rem;
}

/* Song tiles (album-style grid) */
.song-tile {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  text-decoration: none;
  color: inherit;
}
.cover-tile {
  aspect-ratio: 1 / 1;
  width: 100%;
  border-radius: var(--radius-md);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow);
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s ease;
}
.cover-tile .cover-icon {
  opacity: 0.4;
  color: #fff;
  font-size: 2.4rem;
  line-height: 1;
}
.cover-icon svg {
  width: 1em;
  height: 1em;
  fill: #fff;
}
.song-tile:hover .cover-tile,
a.song-tile:focus-visible .cover-tile {
  transform: scale(1.04) translateY(-2px);
  box-shadow: var(--shadow-hover);
}
.song-tile-title {
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.3;
  color: var(--text);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  height: 2.6em;
}
.song-tile-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  height: 1.6rem;
  overflow: hidden;
  align-items: flex-start;
}

/* Song cover thumbnail used in the viewer header */
.cover-thumb {
  width: 84px;
  height: 84px;
  min-width: 84px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cover-thumb .cover-icon {
  opacity: 0.4;
  color: #fff;
  font-size: 1.8rem;
}

/* Skeleton loaders */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--skeleton);
  border-radius: var(--radius-sm);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent);
  animation: skeleton-shimmer 1.4s infinite;
}
@keyframes skeleton-shimmer {
  100% { transform: translateX(100%); }
}
.skeleton-line { height: 0.9rem; margin-bottom: 0.5rem; border-radius: 6px; }
.skeleton-card { height: 108px; border-radius: var(--radius-lg); }

/* Chord sheet rendering */
.chordsheet {
  font-family: "Montserrat", monospace;
  font-size: var(--chord-fs);
}
.cl-line {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: var(--cl-gap);
  min-height: 1.6em;
}
.cl-line.cl-empty { min-height: var(--cl-empty-h); }
.cl-seg {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  vertical-align: top;
}
/* El acorde va en un chip, al estilo de los cancioneros de acordes.
   El truco esta en los margenes negativos: compensan exactamente el relleno,
   asi que el fondo se dibuja alrededor del acorde sin que el segmento se
   ensanche. Sin eso, un acorde mas ancho que su trozo de letra estiraria el
   segmento y separaria las silabas, que es justo lo que no puede pasar en un
   cancionero: el acorde tiene que caer sobre su silaba. */
.cl-seg .chord {
  color: var(--chord-fg);
  background: var(--chord-bg);
  border-radius: 5px;
  padding: 0.1em 0.22em;
  margin: 0 -0.22em;
  font-weight: 700;
  font-size: 0.8em;
  line-height: var(--cl-chord-lh);
  min-height: calc(var(--cl-chord-lh) * 1em);
  white-space: pre;
}
/* Un segmento sin acorde lleva un espacio dentro para reservar el alto del
   renglon. Sin esta regla ese espacio pintaria un chip gris vacio encima de
   cada trozo de letra que no lleva acorde. */
.cl-seg .chord.chord-none {
  background: none;
}
.cl-seg .lyric {
  white-space: pre;
}
/* Acorde sin letra debajo ("[A][G][D]"): el ancho del segmento lo fija el
   acorde, asi que sin esto quedan pegados. El padding solo afecta a estos
   segmentos, nunca a las lineas con letra. Escribir espacios ("[A]   [G]")
   sigue separando mas, porque la letra respeta white-space: pre. */
.cl-seg.cl-chord-only .chord {
  /* 0.22em de relleno + 0.48em de margen = los mismos 0.7em de aire que
     separaban los acordes seguidos antes del chip. */
  margin-right: 0.48em;
}
/* Linea de puros acordes ("[Bm][Em][A7]"): no hay letra que mostrar, asi que el
   renglon de letra se colapsa a altura cero en vez de dejar un hueco debajo.
   Conserva el ancho (white-space: pre), para que los espacios sigan separando. */
.cl-line-chords {
  min-height: 0;
}
.cl-line-chords .lyric {
  line-height: 0;
}
.cl-section {
  font-weight: 600;
  color: var(--text-muted);
  margin: var(--cl-section-top) 0 0.25rem;
  text-transform: uppercase;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
}

/* Song viewer key control */
.key-control {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 980px;
  padding: 0.35rem 0.5rem;
}
.key-control button {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  font-weight: 700;
  font-size: 1.1rem;
  line-height: 1;
}
.key-control button:hover { background: var(--border); }
.key-control .key-select {
  border: none;
  background: transparent;
  font-family: "Montserrat", sans-serif;
  font-size: 1rem;
  text-align: center;
  text-align-last: center;
  min-width: 4rem;
  padding: 0.25rem 0.25rem;
  color: var(--text);
  cursor: pointer;
}
.key-control .key-select:focus {
  outline: none;
}

/* Estado de revision: distintivo en el visor y palomita en la biblioteca. */
.review-badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  line-height: 1.5;
}
.review-badge-ok {
  color: var(--review-ok-fg);
  background: var(--review-ok-bg);
}
.review-badge-pending {
  color: var(--text-muted);
  background: var(--review-pending-bg);
}
.tile-review {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 50%;
  background: #34c759;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Controles de lectura del visor (tamano de letra y pantalla activa) */
.stage-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.font-control {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 980px;
  padding: 0.2rem 0.3rem;
}
.font-control button {
  min-width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  color: var(--text);
  font-weight: 700;
  line-height: 1;
}
.font-control button:hover:not(:disabled) { background: var(--border); }
.font-control button:disabled { opacity: 0.35; }
.font-control .font-small { font-size: 0.72rem; }
.font-control .font-large { font-size: 1rem; }

/* Interruptor tipo pastilla: se ve encendido o apagado de un vistazo. */
.toggle-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border-radius: 980px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.32rem 0.8rem;
  cursor: pointer;
  transition: all 0.15s ease;
}
.toggle-pill:hover { color: var(--text); }
.toggle-pill[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* Fragmento de letra que coincide con la busqueda, bajo cada tile.
   Ocupa siempre el mismo alto mientras hay busqueda activa (incluso vacio),
   para que los tiles de la fila no se desalineen. */
.song-tile-snippet {
  font-size: 0.75rem;
  line-height: 1.35;
  color: var(--text-muted);
  height: 2.7em;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.song-tile-snippet mark {
  background: var(--mark-bg);
  color: inherit;
  padding: 0 0.1em;
  border-radius: 3px;
}

/* Aviso de "estas viendo una copia guardada" cuando no hay conexion */
.offline-note {
  font-size: 0.78rem;
  color: var(--text-muted);
  background: var(--review-pending-bg);
  border-radius: 980px;
  padding: 0.25rem 0.8rem;
  display: inline-block;
}

/* ---------------------------------------------------------------------------
   Visor: barra del canto

   El encabezado es contenido normal y se va con el scroll. Lo que se queda es
   esta barra, fija bajo la de navegacion y de altura constante.

   Fija y de altura constante son las dos condiciones que importan: al estar
   fuera del flujo no puede alterar el alto del documento, y al no cambiar de
   tamano no hay nada que compensar. El planteamiento anterior -- encabezado
   pegajoso que encogia al bajar -- si alteraba ese alto, y de ahi salieron el
   rebote al final del canto, el parpadeo al encogerse y el salto de 57px.
   Aqui lo unico que cambia al scrollear es la opacidad del titulo.
   --------------------------------------------------------------------------- */

.song-bar {
  position: fixed;
  top: var(--navbar-h);
  left: 0;
  right: 0;
  z-index: 90;
  height: var(--song-bar-h);
  background: var(--navbar-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
}
.song-bar-inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.song-bar-title {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Invisible mientras el encabezado esta a la vista, para no repetir el
     titulo dos veces. Se anima la opacidad, que no afecta a la maquetacion. */
  opacity: 0;
  transition: opacity 0.2s ease;
}
body.bar-title .song-bar-title { opacity: 1; }
.song-bar .key-control { flex: none; }

/* El hueco de la barra se reserva de una vez, no depende de nada que pase
   luego. Sustituye al py-5 de Bootstrap para poder sumarle esa altura. */
.song-main {
  padding-top: calc(var(--song-bar-h) + 1.5rem);
  padding-bottom: 3rem;
}

.song-header { margin-bottom: 1.25rem; }
.song-header-main {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.song-header-text { min-width: 0; }
#song-title { font-size: clamp(1.4rem, 4vw, 2.2rem); }

/* Pie del canto: cierra la pagina y da salida a la biblioteca sin volver
   arriba, que en un canto largo son varias pasadas de dedo. La linea de
   arriba separa la letra del canto de los botones; se perdio al reescribir
   el bloque del encabezado pegajoso y se restituye aqui. */
.song-footer {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}
.song-footer .footer-note {
  color: var(--text-muted);
  font-size: 0.78rem;
}

.viewer-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.toolbar-review { margin-left: auto; }

@media (max-width: 575.98px) {
  /* Cada renglon arrastra su fila de acordes, asi que apretar estos cuatro
     valores es lo que hace que quepan ~13 renglones en vez de 8. */
  :root {
    --cl-gap: 0.28rem;
    --cl-chord-lh: 1.2;
    --cl-empty-h: 0.5em;
    --cl-section-top: 0.7rem;
  }

  .toolbar-review {
    margin-left: 0;
    width: 100%;
  }

}

/* ---------------------------------------------------------------------------
   Panel lateral de ajustes (assets/js/drawer.js)

   Va en position: fixed a proposito. El panel desplegable al que sustituye
   crecia dentro del flujo y cambiaba el alto de la pagina al abrirse, que es
   la misma causa del rebote que tenia el visor al final de un canto. Flotando
   por encima, no puede desplazar nada.
   --------------------------------------------------------------------------- */

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
body.drawer-open .drawer-backdrop {
  opacity: 1;
  pointer-events: auto;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  width: min(320px, 85vw);
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -12px 0 32px -16px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  /* Respeta la muesca y la barra inferior del telefono. */
  padding: env(safe-area-inset-top, 0px) 0 env(safe-area-inset-bottom, 0px);
  transform: translateX(100%);
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
  overflow-y: auto;
}
body.drawer-open .drawer {
  transform: translateX(0);
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.15rem;
  border-bottom: 1px solid var(--border);
}
.drawer-title {
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: 1.05rem;
  margin: 0;
}

.drawer-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 1.15rem;
  border-bottom: 1px solid var(--border);
}
.drawer-label {
  font-size: 0.88rem;
  font-weight: 500;
}
.drawer-hint {
  display: block;
  font-size: 0.72rem;
  color: var(--text-muted);
  font-weight: 400;
  margin-top: 0.1rem;
}

/* Formulario de acceso, dentro del panel. Va en su propio bloque y no en una
   fila, porque tres campos apilados no caben en el patron etiqueta/control. */
.drawer-login {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 1.15rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.drawer-login .login-error {
  margin: 0;
  font-size: 0.78rem;
  color: #ff453a;
}

/* El boton hamburguesa: las tres rayas se dibujan con el trazo del SVG, asi
   que heredan el color del texto y funcionan en los dos temas. */
.drawer-open-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.3rem 0.6rem;
}
.drawer-open-btn svg {
  width: 18px;
  height: 18px;
  display: block;
}

@media (prefers-reduced-motion: reduce) {
  .drawer,
  .drawer-backdrop {
    transition: none;
  }
}

/* Interruptor: para algo que sólo está encendido o apagado, una pastilla con
   texto obliga a leer para saber en qué estado está; un interruptor se ve. */
.switch {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 46px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--border);
  position: relative;
  cursor: pointer;
  transition: background 0.2s ease;
}
.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.switch[aria-checked="true"] { background: #34c759; }
.switch[aria-checked="true"]::after { transform: translateX(18px); }
.switch:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .switch,
  .switch::after { transition: none; }
}

@media print {
  /* El papel siempre va en claro, aunque la pantalla este en modo oscuro. */
  :root {
    --bg: #ffffff;
    --surface: #ffffff;
    --text: #000000;
    --text-muted: #444444;
    --accent: #0057b8;
    --border: #cccccc;
  }
  .navbar-apple, .no-print, .review-badge, .song-tile-snippet { display: none !important; }
  .drawer, .drawer-backdrop, .song-bar { display: none !important; }
  .song-main { padding-top: 0; }
  /* Que el encabezado no se quede pegado ni encogido en el papel. */
  #song-title { font-size: 1.6rem; }
  body { background: #fff; color: #000; }
  .card-apple { box-shadow: none; border: none; }
}
