:root {
  --bg: #1b1611;
  --bg-glow: radial-gradient(
    ellipse 900px 480px at 50% -10%,
    rgba(217, 154, 78, 0.16),
    transparent 65%
  );
  --surface: #2a2119;
  --surface-hover: #342922;
  --surface-active: #3c2c1e;
  --border: rgba(237, 226, 208, 0.09);
  --border-strong: rgba(237, 226, 208, 0.18);
  --text: #efe4d2;
  --text-dim: #b7a892;
  --text-faint: #8a7c66;
  --amber: #d99a4e;
  --amber-soft: #e3b06e;
  --terracotta: #c1663f;
  --sage: #8ea283;
  --glow: rgba(217, 154, 78, 0.4);
  --radius: 16px;
  --radius-sm: 10px;

  /* Shippori Mincho para títulos/encabezados de sección, Zen Kaku Gothic New para
     el resto — reemplaza el stack de sistema anterior (ver body más abajo). */
  --font-heading: "Shippori Mincho", serif;
  --font-body: "Zen Kaku Gothic New", "Segoe UI", system-ui, sans-serif;

  /* Padding de #app como variables: el hero de la Home los cancela con márgenes
     negativos para ir a sangre (full-bleed) sin duplicar los valores a mano. */
  --app-pad-x: 1.5rem;
  --app-pad-top: 3.5rem;
  --content-max: 960px;

  /* Acentos fríos: la paleta base es toda cálida y no cubre agua/nieve/noche,
     necesarios para el gradiente temático de las colecciones (static/js/scenarios.js). */
  --teal: #3f7a80;
  --foam: #a9c9c2;
  --frost: #c9d8dd;
  --ice-blue: #7f9bab;
  --indigo: #3d4a6b;
  --moss: #5f7a5a;
  --sand: #b7a67f;
  --mist: #7c92a0;
  --dusk: #8a5a6b;

  /* Tratamiento fotográfico compartido (hero + cards + hero de detalle):
     grano sutil, tono cálido apagado y viñeta, definidos una sola vez.
     Deliberadamente flojo: la foto tiene que leerse, no quedar sepultada. */
  --photo-tone-filter: sepia(0.1) saturate(0.95) contrast(1.03);
  --photo-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --photo-vignette: radial-gradient(ellipse at center, transparent 55%, rgba(15, 12, 9, 0.4) 100%);
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--text);
  background: var(--bg-glow), var(--bg);
  background-attachment: fixed;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: rgba(217, 154, 78, 0.35);
  color: var(--text);
}

::-webkit-scrollbar {
  width: 10px;
}

::-webkit-scrollbar-track {
  background: var(--bg);
}

::-webkit-scrollbar-thumb {
  background: var(--surface-active);
  border-radius: 8px;
  border: 2px solid var(--bg);
}

#app {
  position: relative;
  z-index: 1; /* por encima de #collection-backdrop */
  min-height: 100vh;
  padding: var(--app-pad-top) var(--app-pad-x) 5rem;
}

/* ── Fondo a pantalla completa de la Vista 3 ──────────────────────────
   La foto de la colección ocupa el viewport y se funde con el fondo de la página
   hacia abajo, para que las sound cards caigan sobre color plano y se lean. Va
   `fixed`: al hacer scroll la foto se queda quieta y el contenido pasa por encima.
   Usa la variante de 1920px (--scenario-image-full), no la de las cards: aquí la foto
   se estira a todo el viewport y con 800px se veía pixelada. Ambas las fija
   applyAccentGradient() sobre <body> (app.js). */
#collection-backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 700ms ease;
  background-image:
    var(--photo-grain),
    linear-gradient(
      to bottom,
      rgba(27, 22, 17, 0.62) 0%,
      rgba(27, 22, 17, 0.5) 22%,
      rgba(27, 22, 17, 0.72) 52%,
      rgba(27, 22, 17, 0.93) 78%,
      var(--bg) 100%
    ),
    linear-gradient(
      160deg,
      var(--accent-from, transparent),
      var(--accent-to, transparent)
    ),
    var(--scenario-image-full, var(--scenario-image, none));
  background-repeat: repeat, no-repeat, no-repeat, no-repeat;
  background-size: 160px 160px, cover, cover, cover;
  background-position: 0 0, center, center, center;
  /* El acento va en `soft-light` sobre la foto: tiñe con el color de la colección sin
     aplanar el detalle. Los fallbacks a transparent no son decorativos — si las vars
     no estuvieran definidas, el var() inválido tumbaría el background-image entero. */
  background-blend-mode: soft-light, normal, soft-light, normal;
  filter: var(--photo-tone-filter);
}

body[data-view="collection"] #collection-backdrop {
  opacity: 1;
}

/* ── Footer ───────────────────────────────────────────────────────── */

#app-footer {
  margin-top: 4rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--border);
  text-align: center;
}

#app-footer p {
  max-width: 38rem;
  margin: 0 auto;
  color: var(--text-faint);
  font-size: 0.78rem;
  line-height: 1.65;
  letter-spacing: 0.01em;
}

#app-footer-signature {
  margin-top: 0.6rem;
}

#app-footer-signature a {
  color: var(--text-dim);
  text-decoration: none;
}

#app-footer-signature a:hover {
  color: var(--amber-soft);
  text-decoration: underline;
}

/* ── Hero / header ─────────────────────────────────────────────────── */

#app-header {
  position: relative;
  text-align: center;
  margin-bottom: 3rem;
  animation: rise 0.6s ease both;
}

#app-header h1 {
  margin: 0 0 0.6rem;
  font-family: var(--font-heading);
  font-size: 2.4rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text);
}

/* Foto de fondo del hero — solo visible en Home (ver body[data-view] más abajo);
   #app-header en sí persiste en las 3 vistas para no perder los controles globales. */
#hero-photo {
  display: none;
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: var(--radius);
  z-index: -1;
  /* Difumina TODO el hero (foto + lavado + grano juntos) a transparente hacia el
     pie, en vez de intentar que un degradado interno acierte el color exacto del
     fondo de la página — así no depende de lo clara/oscura que salga la foto ahí. */
  mask-image: linear-gradient(to bottom, black 0%, black 42%, transparent 92%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 42%, transparent 92%);
}

#hero-photo-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 58% y no el centro: en un recorte apaisado de una foto vertical, más arriba
     solo se ve la banda de neblina plana — aquí entran el pico y las crestas. */
  object-position: var(--hero-photo-position, 50% 58%);
  filter: var(--photo-tone-filter);
  display: block;
}

/* Dos degradados: uno vertical que funde el pie del hero con el fondo de la página
   (sin costura visible) y otro lateral que oscurece la izquierda, donde va el texto. */
#hero-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    var(--photo-grain),
    linear-gradient(
      180deg,
      rgba(27, 22, 17, 0.3) 0%,
      rgba(27, 22, 17, 0.12) 32%,
      rgba(27, 22, 17, 0.72) 80%,
      var(--bg) 100%
    ),
    linear-gradient(
      90deg,
      rgba(27, 22, 17, 0.82) 0%,
      rgba(27, 22, 17, 0.28) 52%,
      transparent 82%
    );
  background-repeat: repeat, no-repeat, no-repeat;
  background-size: 160px 160px, cover, cover;
  background-blend-mode: soft-light, normal, normal;
}

/* Home: el hero va a sangre. Cancela el padding de #app con márgenes negativos
   para ocupar todo el ancho de la ventana, y el contenido se re-centra dentro
   con el mismo max-width que el resto de la página. */
body[data-view="home"] #app-header {
  min-height: min(74vh, 620px);
  margin: calc(-1 * var(--app-pad-top)) calc(-1 * var(--app-pad-x)) 3.5rem;
  padding: 0 var(--app-pad-x) 3.25rem;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  text-align: left;
}

body[data-view="home"] #hero-photo {
  display: block;
  border-radius: 0;
}

#app-header-content {
  position: relative;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
}

body[data-view="home"] #app-header h1 {
  font-size: clamp(2.5rem, 5.5vw, 4rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  max-width: 15ch;
  margin-bottom: 1.1rem;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

body[data-view="home"] #status-line {
  margin: 0 0 2.25rem;
  max-width: 54ch;
  font-size: 1rem;
  color: rgba(239, 228, 210, 0.78);
}

body[data-view="home"] #header-controls {
  justify-content: flex-start;
  margin-top: 0;
}

#status-line {
  margin: 0 auto;
  max-width: 32rem;
  color: var(--text-dim);
  font-size: 0.95rem;
  line-height: 1.6;
  font-weight: 300;
  letter-spacing: 0.01em;
}

#header-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 2rem;
}

/* Sin píldora: fondo, borde y sombra fuera. Es un control secundario y ese chrome
   lo hacía competir con el hero. Queda etiqueta + slider al aire; la sombra de texto
   es lo que lo sostiene sobre la foto de la Vista 3, donde ya no hay fondo propio. */
#master-volume-control {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  min-width: 16rem;
  padding: 0.2rem 0;
}

#master-volume-control label {
  font-size: 0.72rem;
  color: var(--text-faint);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 1px 6px rgba(8, 6, 4, 0.6);
}

#master-volume {
  flex: 1;
  width: auto;
}

/* ── Interruptor de sonido (fijo, arriba a la derecha) ───────────────
   Fuera del flujo del header para acompañar en las 3 vistas y sobre la foto
   a pantalla completa de la Vista 3, de ahí el fondo translúcido. */
/* El botón es solo área de pulsación (44px de alto, el mínimo cómodo en táctil):
   sin fondo ni borde propios, lo que se ve es la pista. Antes llevaba una píldora
   translúcida alrededor y eso era la mitad del volumen visual. */
#mute-toggle {
  position: fixed;
  top: 0.9rem;
  right: 1.4rem;
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem;
  border: 0;
  background: none;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.2s ease;
}

/* El icono dice para qué es el botón; el conmutador, en qué estado está. */
.switch-icon {
  display: inline-flex;
  color: var(--text-dim);
  transition: color 0.25s ease;
}

.switch-icon svg {
  display: block;
  width: 1.05rem;
  height: 1.05rem;
}

#mute-toggle[aria-checked="true"] .switch-icon {
  color: var(--text);
}

/* Qué icono se ve lo decide el estado, sin tocar el DOM desde JS. */
#mute-toggle .icon-off,
#mute-toggle[aria-checked="false"] .icon-on {
  display: none;
}

#mute-toggle[aria-checked="false"] .icon-off {
  display: block;
}

#mute-toggle:hover .switch-track {
  border-color: rgba(237, 226, 208, 0.28);
}

/* El anillo va en la pista, no en el botón: el botón es solo área de pulsación
   invisible y el foco quedaría flotando lejos del control que se ve. */
#mute-toggle:focus-visible {
  outline: none;
}

#mute-toggle:focus-visible .switch-track {
  outline: 2px solid var(--amber-soft);
  outline-offset: 3px;
}

/* Mantiene la proporción de iOS (bolita casi tangente a la pista, que es lo que lo
   hace parecer un interruptor y no una barra con un punto), pero a menor escala.
   Opaca a propósito: translúcida absorbía el tinte de la foto de detrás y en las
   colecciones de acento frío o verde el interruptor cambiaba de color. */
.switch-track {
  position: relative;
  display: block;
  width: 2.3rem;
  height: 1.32rem;
  flex: 0 0 auto;
  border-radius: 999px;
  border: 1px solid rgba(237, 226, 208, 0.14);
  background: #241d16;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: background 0.3s cubic-bezier(0.32, 0.72, 0, 1),
    border-color 0.2s ease;
}

.switch-knob {
  position: absolute;
  top: 0.13rem;
  left: 0.13rem;
  width: 0.94rem;
  height: 0.94rem;
  border-radius: 50%;
  background: #fdfbf7;
  /* Sombra en dos capas como la de iOS: una difusa que despega la bolita de la
     pista y otra de 1px que le da el canto. Con una sola se ve plana. */
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3), 0 1px 1px rgba(0, 0, 0, 0.2);
  transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1),
    width 0.22s cubic-bezier(0.32, 0.72, 0, 1);
}

/* Marcado = suena. El acento cálido solo aparece con el sonido activo, así el
   estado se lee por color además de por posición (de un vistazo el color se capta
   antes que el desplazamiento de la bolita). */
#mute-toggle[aria-checked="true"] .switch-track {
  background: var(--terracotta);
  border-color: var(--terracotta);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15);
}

#mute-toggle[aria-checked="true"] .switch-knob {
  transform: translateX(0.98rem);
}

/* iOS estira la bolita mientras la mantienes pulsada; es el detalle que más
   sensación de tacto da. Al soltar vuelve sola por la transición de `width`. */
#mute-toggle:active .switch-knob {
  width: 1.12rem;
}

#mute-toggle[aria-checked="true"]:active .switch-knob {
  transform: translateX(0.8rem);
}

@media (prefers-reduced-motion: reduce) {
  .switch-track,
  .switch-knob {
    transition: none;
  }
}

/* ── Inputs & controls (shared look) ─────────────────────────────── */

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: rgba(237, 226, 208, 0.14);
  cursor: pointer;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--amber-soft);
  box-shadow: 0 0 0 3px rgba(217, 154, 78, 0.18);
  cursor: pointer;
  transition: box-shadow 0.2s ease, background 0.2s ease;
}

input[type="range"]::-webkit-slider-thumb:hover {
  background: var(--amber);
  box-shadow: 0 0 0 5px rgba(217, 154, 78, 0.25);
}

input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: none;
  border-radius: 50%;
  background: var(--amber-soft);
  cursor: pointer;
}

input[type="checkbox"] {
  accent-color: var(--amber);
  width: 15px;
  height: 15px;
  cursor: pointer;
}

/* ── Vistas ───────────────────────────────────────────────────────── */

.view {
  animation: rise 0.4s ease both;
}

#view-home {
  max-width: 960px;
  margin: 0 auto;
}

#view-collections,
#view-collection {
  max-width: 960px;
  margin: 0 auto;
}

/* ── Breadcrumb (Vista 2 y 3) ─────────────────────────────────────── */

.breadcrumb {
  font-size: 0.8rem;
  color: var(--text-faint);
  margin-bottom: 0.9rem;
}

.breadcrumb a {
  color: var(--text-dim);
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--amber-soft);
  text-decoration: underline;
}

#view-collections h2 {
  margin: 0 0 1.25rem;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text);
}

/* ── Colecciones: fila destacada (Home) y galería completa (Vista 2) ─ */

.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.section-heading h2 {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.section-heading h2 a {
  color: inherit;
  text-decoration: none;
}

#view-all-link {
  font-size: 0.82rem;
  color: var(--amber-soft);
  text-decoration: none;
  white-space: nowrap;
}

#view-all-link:hover {
  color: var(--amber);
  text-decoration: underline;
}

#featured-section {
  margin-bottom: 2.5rem;
}

/* Fila fija de destacadas (siempre las 5 que SCENARIOS marca featured:true) — sin
   scroll horizontal; auto-fit para que en pantallas estrechas envuelvan en vez de
   apretarse, en vez de forzar 5 columnas literales. */
#featured-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.9rem;
  padding: 0.25rem 0 0.9rem;
}

#all-collections-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

.collection-card {
  position: relative;
  width: 100%;
  height: 190px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  padding: 0.95rem 1rem;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  /* La card es un <a>, no un <button>: sin esto hereda el subrayado y el azul/morado
     de :visited del enlace por defecto. */
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(155deg, var(--accent-from), var(--accent-to));
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  transition: transform 0.2s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

/* Foto + grano + un degradado que SOLO oscurece el tercio inferior, lo justo para
   que el caption se lea; los dos tercios de arriba quedan limpios para que se vea
   la escena. var(--scenario-image) la fija applyAccentGradient() (scenarios.js);
   si falta o no ha cargado, cae limpio al degradado de acento de fondo. */
.collection-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    var(--photo-grain),
    linear-gradient(
      0deg,
      rgba(12, 10, 8, 0.92) 0%,
      rgba(12, 10, 8, 0.55) 26%,
      rgba(12, 10, 8, 0.08) 55%,
      transparent 75%
    ),
    var(--scenario-image, none);
  background-repeat: repeat, no-repeat, no-repeat;
  background-size: 160px 160px, cover, cover;
  background-position: 0 0, center, var(--card-image-position, center);
  background-blend-mode: soft-light, normal, normal;
  filter: var(--photo-tone-filter);
  transition: transform 0.4s ease;
}

.collection-card:hover::before {
  transform: scale(1.04);
}

.collection-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32);
}

.collection-card:focus-visible {
  outline: none;
  border-color: var(--amber-soft);
  box-shadow: 0 0 0 3px rgba(217, 154, 78, 0.25);
}

.collection-caption {
  position: relative;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0;
  color: #fff;
  line-height: 1.3;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* La lámpara/foco cálido de la foto queda en el tercio inferior del encuadre original;
   el resto de cards usa el center por defecto (ver --card-image-position en ::before). */
.collection-card[data-scenario-id="late_night_study"] {
  --card-image-position: 50% 68%;
}

/* ── Pestañas de categoría (Home) ─────────────────────────────────── */

#category-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
}

.category-tab {
  font-family: inherit;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  padding: 0.45rem 1rem;
  border-radius: 999px;
  font-size: 0.82rem;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.category-tab:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--text);
}

.category-tab[aria-pressed="true"] {
  background: linear-gradient(135deg, var(--amber-soft), var(--terracotta));
  border-color: transparent;
  color: #241a10;
  font-weight: 700;
}

/* ── Detalle de colección (Vista 3) ───────────────────────────────── */

/* La foto ya no vive dentro del hero: ocupa el viewport entero (#collection-backdrop),
   así que aquí solo queda el texto encima, sin chrome de tarjeta. */
#collection-hero {
  position: relative;
  padding: 2.5rem 0 3rem;
  margin-bottom: 0.5rem;
}

#collection-hero > * {
  position: relative;
  text-shadow: 0 2px 12px rgba(8, 6, 4, 0.75);
}

#collection-hero .breadcrumb,
#collection-hero .breadcrumb a {
  color: rgba(255, 255, 255, 0.75);
}

#collection-hero .breadcrumb a:hover {
  color: #fff;
}

#collection-hero .breadcrumb span {
  color: #fff;
}

/* Cards translúcidas con desenfoque: aquí flotan sobre la foto y taparla entera
   desperdicia el fondo a pantalla completa. Deliberadamente acotado a esta vista —
   en la Home el fondo es plano (no habría nada que dejar ver) y son 29 cards, así
   que el backdrop-filter costaría rendimiento justo donde el filtro de categorías
   las anima moviéndolas. Aquí son 3-5 y están quietas. */
body[data-view="collection"] .sound-card {
  background-color: rgba(26, 20, 15, 0.18);
  /* Desenfoque bajo a propósito: subirlo emborrona la foto justo donde se quería
     ver, así que por mucho que se baje el alfa solo se vería una mancha. Los 4px
     quitan el ruido fino sin borrar el motivo. */
  backdrop-filter: blur(4px) saturate(1.2);
  -webkit-backdrop-filter: blur(4px) saturate(1.2);
  background-image: none; /* el radial de la base restaba transparencia */
  border-color: rgba(237, 226, 208, 0.22);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.32);
}

/* Con la card tan transparente el texto ya no cae sobre color plano: la sombra es
   lo que lo mantiene legible sobre las zonas claras de la foto. */
body[data-view="collection"] .sound-card .name {
  text-shadow: 0 1px 8px rgba(8, 6, 4, 0.85);
}

body[data-view="collection"] .sound-card:hover {
  background-color: rgba(38, 30, 22, 0.3);
}

body[data-view="collection"] .sound-card.active {
  background-color: rgba(46, 34, 23, 0.26);
}

#collection-title {
  margin: 0.3rem 0 0.5rem;
  font-family: var(--font-heading);
  font-size: 1.85rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}

#collection-description {
  margin: 0;
  max-width: 40rem;
  color: rgba(255, 255, 255, 0.88);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* ── Sounds grid ──────────────────────────────────────────────────── */

#sounds-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
  max-width: 960px;
  margin: 0 auto;
}

.sound-card {
  background: var(--surface);
  background-image: radial-gradient(
    circle at 30% 20%,
    rgba(237, 226, 208, 0.035),
    transparent 60%
  );
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.15rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  transition: background 0.25s ease, border-color 0.25s ease,
    box-shadow 0.25s ease, transform 0.2s ease, opacity 0.4s ease;
}

.sound-card:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  transform: translateY(-2px);
}

/* .sound-card fija su propio "display", que si no se pisa explícitamente gana
   sobre el display:none nativo de [hidden] (misma especificidad, pero la regla
   de autor prevalece sobre la del user-agent) y la card se seguiría viendo. */
.sound-card[hidden] {
  display: none;
}

/* Filtro de categoría (Home): en vez de ocultar lo que no coincide, se manda
   al fondo visual — sigue sonando/clicable si ya estaba activo. El reordenado
   en sí (grid `order`) lo anima mixer.js vía FLIP con la Web Animations API. */
.sound-card.dimmed {
  opacity: 0.38;
}

.sound-card.active {
  border-color: rgba(217, 154, 78, 0.55);
  background: var(--surface-active);
  box-shadow: 0 0 0 1px rgba(217, 154, 78, 0.25),
    0 0 26px var(--glow), 0 6px 18px rgba(0, 0, 0, 0.25);
}

.sound-card .name {
  font-size: 0.92rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-align: center;
  color: var(--text);
}

/* Botón de play/pausa dedicado — antes toda la card actuaba como control
   implícito (role=button en el article); ahora el control real es este botón
   nativo, que ya trae foco/teclado gratis y evita anidar interactivos. */
.sound-card .play-btn {
  width: 2.75rem;
  height: 2.75rem;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface-hover);
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.sound-card .play-btn:hover {
  background: var(--surface-active);
  border-color: var(--border-strong);
  transform: scale(1.05);
}

.sound-card .play-btn:focus-visible {
  outline: none;
  border-color: var(--amber-soft);
  box-shadow: 0 0 0 3px rgba(217, 154, 78, 0.2);
}

.sound-card.active .play-btn {
  border-color: rgba(217, 154, 78, 0.55);
  background: var(--surface-active);
  color: var(--amber-soft);
}

.sound-card .waveform {
  width: 100%;
  height: 36px;
  opacity: 0.85;
  /* el canvas pinta en azul vía JS; lo re-tintamos hacia la paleta cálida sin tocar el script */
  filter: sepia(0.85) saturate(2.4) hue-rotate(-18deg) brightness(1.05);
}

.sound-card .volume-slider {
  width: 100%;
  cursor: pointer;
}

/* ── Timer & presets panels ──────────────────────────────────────── */

#timer-section,
#presets-section {
  max-width: 480px;
  margin: 2.5rem auto 0;
  padding: 1.5rem 1.5rem 1.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  text-align: center;
}

#presets-section {
  margin-top: 1.5rem;
}

#timer-section h2,
#presets-section h2 {
  margin: 0 0 1.1rem;
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--amber-soft);
  text-transform: uppercase;
}

#timer-form,
#presets-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.55rem 0.8rem;
}

#timer-form label {
  font-size: 0.78rem;
  color: var(--text-faint);
}

#timer-form input[type="number"] {
  width: 4.5rem;
  background: rgba(237, 226, 208, 0.05);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
}

#timer-form select {
  background: rgba(237, 226, 208, 0.05);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
  cursor: pointer;
}

#timer-form input[type="number"]:focus,
#timer-form select:focus,
#preset-name:focus {
  outline: none;
  border-color: var(--amber-soft);
  box-shadow: 0 0 0 3px rgba(217, 154, 78, 0.16);
}

#timer-form button,
#preset-save {
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.15rem;
  cursor: pointer;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  transition: filter 0.2s ease, transform 0.2s ease;
}

#timer-form button[type="submit"],
#preset-save {
  background: linear-gradient(135deg, var(--amber-soft), var(--terracotta));
  color: #241a10;
}

#timer-form button[type="submit"]:hover,
#preset-save:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

#timer-form button[type="button"] {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
}

#timer-form button[type="button"]:hover {
  background: var(--surface-hover);
  color: var(--text);
}

#timer-status {
  margin: 1rem 0 0;
  color: var(--text-dim);
  font-size: 0.85rem;
}

#preset-name {
  background: rgba(237, 226, 208, 0.05);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 0.45rem 0.7rem;
  min-width: 190px;
  font-size: 0.85rem;
}

#preset-name::placeholder {
  color: var(--text-faint);
}

#preset-public-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: var(--text-dim);
}

#preset-result {
  margin: 1rem 0 0;
  font-size: 0.82rem;
  color: var(--sage);
  word-break: break-all;
}

#preset-result a {
  color: var(--amber-soft);
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (max-width: 480px) {
  /* Se redefinen las variables, no el padding a pelo: el hero full-bleed calcula
     su margen negativo desde ellas y si no cuadran se sale del ancho. */
  :root {
    --app-pad-x: 1rem;
    --app-pad-top: 2.5rem;
  }

  #app {
    padding-bottom: 3.5rem;
  }

  #app-header h1 {
    font-size: 1.9rem;
  }

  body[data-view="home"] #app-header {
    min-height: min(62vh, 420px);
    padding-bottom: 2.25rem;
  }

  body[data-view="home"] #app-header h1 {
    font-size: clamp(2rem, 8.5vw, 2.6rem);
  }
}
