/* ============================================================
   comun.css — estilos compartidos por TODAS las páginas de
   ejercicios (app/ejercicios/*.html).
   Capa visual "editorial entintada" (ver app/design/README.md):
   barra superior entintada (#2f4f42), tipografía serif de aire
   editorial (Source Serif 4 + Source Sans 3), esquinas suaves y
   objetivos táctiles grandes (pizarra digital).
   Layout común: barra superior + fila con la partitura a la
   izquierda y la columna de acciones a la derecha (en pantallas
   estrechas, los botones pasan debajo).
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,600;1,8..60,400;1,8..60,600&family=Source+Sans+3:wght@400;600;700&display=swap');
/* ♭ ♮ ♯ 𝄪 𝄫 en Leland (ver ../vendor/fuentes/README.md): solo esos códigos */
@font-face{font-family:'Leland Alteraciones';src:url('../vendor/fuentes/leland-alteraciones.woff2') format('woff2');
           unicode-range:U+266D-266F,U+1D12A-1D12B}

:root{
  --bg:#f7f7f4; --card:#ffffff; --fg:#1d1d1b; --muted:#6b6b66;
  --soft:#a5a59e; --line:#dcdcd6; --line-soft:#e6e6df;
  --ink:#2f4f42; --ink-hover:#264137;
  --accent:var(--ink); --accent-soft:#e8f0ec;
  --ok:#8f4a22; --ok-bg:#f7efe8; --ok-line:#e0c9b4;
  --voz-sup:#3a5a78; --voz-inf:#b06c3a;
  --serif:'Leland Alteraciones','Source Serif 4',Georgia,serif;
  --sans:'Leland Alteraciones','Source Sans 3',system-ui,-apple-system,sans-serif;
  --main-w:1240px;
}
*{box-sizing:border-box}
body{margin:0;font-family:var(--sans);background:var(--bg);color:var(--fg);line-height:1.5}

/* ---------- barra superior entintada ---------- */
/* El HTML de la cabecera es plano (h1, .sub, a.back, .level);
   el grid lo recoloca: volver | título/subtítulo | nivel. */
header{background:var(--ink);color:#fff;
       /* el fondo ocupa todo el ancho; el contenido se centra a partir
          de --main-w gracias al padding lateral variable, alineado con
          el contenido de main (que lleva 36px de padding propio) */
       padding:16px max(36px, calc((100% - var(--main-w)) / 2 + 36px));
       display:grid;grid-template-columns:auto 1fr auto;
       grid-template-areas:"back title level" "back sub level";
       column-gap:20px;align-items:center}
header h1{grid-area:title;font-family:var(--serif);font-size:24px;font-weight:600;
       margin:0;line-height:1.2;align-self:end}
header .sub{grid-area:sub;font-size:13px;color:rgba(255,255,255,.6);align-self:start}
header a.back{grid-area:back;display:inline-flex;align-items:center;height:52px;
       padding:0 20px;border-radius:12px;background:rgba(255,255,255,.14);
       color:#fff;font-size:16px;font-weight:600;text-decoration:none;
       transition:background .15s ease}
@media(hover:hover){header a.back:hover{background:rgba(255,255,255,.22)}}
header a.back:active{background:rgba(255,255,255,.22)}
.level{grid-area:level;display:flex;align-items:center;gap:10px;
       font-size:14px;color:rgba(255,255,255,.65)}
.level b{display:inline-flex;align-items:center;justify-content:center;
       min-width:40px;height:40px;padding:0 8px;border-radius:10px;
       background:#fff;color:var(--ink);font-size:16px;font-weight:700}

main{max-width:var(--main-w);margin:0 auto;padding:34px 36px 46px}
/* ---------- ayuda plegada bajo el ejercicio ----------
   El enunciado largo (.prompt) va dentro de <details class="ayuda">, debajo
   de la fila partitura + acciones; el <summary> hace de botón (i). */
.ayuda{margin-top:22px}
.ayuda summary{display:inline-flex;align-items:center;gap:8px;list-style:none;cursor:pointer;
     min-height:56px;padding:0 20px 0 16px;border:1.5px solid var(--line);border-radius:12px;
     background:var(--card);color:var(--muted);font-size:17px;font-weight:600;user-select:none;
     transition:border-color .15s ease,color .15s ease}
.ayuda summary::-webkit-details-marker{display:none}
@media(hover:hover){.ayuda summary:hover{border-color:var(--ink);color:var(--ink)}}
.ayuda[open] summary{border-color:var(--ink);color:var(--ink)}
/* Fila del enlace a los apuntes y la ayuda (la arma comun.js cuando hay
   apunte publicado): el enlace delante; la ayuda, al abrirse, baja a su
   propia línea a todo el ancho. Mismo aspecto que el botón de ayuda. */
.pie-ej{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start;margin-top:22px}
.pie-ej .ayuda{margin-top:0}
.pie-ej .ayuda[open]{flex-basis:100%}
a.apuntes-enlace{display:inline-flex;align-items:center;gap:8px;min-height:56px;
     padding:0 20px 0 16px;border:1.5px solid var(--line);border-radius:12px;
     background:var(--card);color:var(--muted);font-size:17px;font-weight:600;
     text-decoration:none;transition:border-color .15s ease,color .15s ease}
@media(hover:hover){a.apuntes-enlace:hover{border-color:var(--ink);color:var(--ink)}}
a.apuntes-enlace:active{border-color:var(--ink);color:var(--ink)}
.prompt{font-size:18px;color:var(--muted);margin:14px 0 0;max-width:860px}
.prompt b{color:var(--fg)}

/* ---------- fila partitura + acciones ---------- */
.ej-row{display:flex;gap:30px;align-items:flex-start}
.ej-main{flex:1;min-width:0}
.score-card{background:var(--card);border:1px solid var(--line);border-radius:14px;
     min-height:260px;display:flex;align-items:center;justify-content:center;
     padding:34px;overflow:auto}
.score-wrap{position:relative;max-width:100%}
#notation svg{max-width:100%;height:auto;display:block}
#notation .ph{color:var(--soft);font-size:15px;text-align:center}
/* Dato de partida dentro de la partitura (<reh type="dato">, ver toMEI en
   cadencias-core.js): lo que el ejercicio DA —tonalidad, tipo de
   cadencia…—, anclado al primer tiempo y por tanto alineado con el comienzo
   de la música. Entintado y en serif para que no se confunda ni con el
   cifrado (negro, dentro de la partitura) ni con la respuesta (terroso). */
#notation .reh.dato text{fill:var(--ink);font-family:var(--serif);font-weight:600}

/* Cifrados alternativos (segunda fila de <harm>, marcada type="alt" en el MEI:
   Verovio lo vuelca a la clase del SVG). Gris, como las alternativas del texto. */
#notation g.harm.alt, #notation g.harm.alt text{fill:var(--soft)}
/* Etiqueta de cada tramo (Prolongación: «Prol. I», «SC», «CA»; <reh
   type="tramo">, ver toMEI en prolongacion-core.js) y su corchete hasta
   el final del tramo (ArmoniaEj.corchetesTramo). Es respuesta: color de
   acierto y serif, como el titular de la respuesta. */
#notation .reh.tramo text{fill:var(--ok);font-family:var(--serif);font-weight:600}
#notation .reh.tramo path.corchete{fill:none;stroke:var(--ok)}
/* lo que dibuja ArmoniaEj.rotulosEncima (Secuencia): tramos y corchetes de
   módulo, como las etiquetas de tramo; la tonalidad, como el dato */
#notation .rotulo-encima text{fill:var(--ok);font-family:var(--serif);font-weight:600}
#notation .rotulo-encima path.corchete{fill:none;stroke:var(--ok)}
#notation .rotulo-encima.dato text{fill:var(--ink)}
/* Cifrado americano en segundo plano (<harm type="americano">, más pequeño
   desde el MEI): en Cadencias y Prolongación es información añadida, no lo
   que se pregunta. Donde el americano ES la respuesta (3.º UD 0), no se marca. */
#notation g.harm.americano, #notation g.harm.americano text{fill:var(--muted)}
/* Grado del bajo (<harm type="gradobajo">): el círculo y la alteración los
   dibuja ArmoniaEj.circularGrados tras el render. */
#notation g.harm.gradobajo circle.circulo{fill:none;stroke:currentColor}
#notation g.harm.gradobajo text.alteracion{font-family:var(--serif)}
/* Rótulos bajo cada compás (ArmoniaEj.rotulosBajo): serif en cursiva, como las
   indicaciones de una partitura; el color dice qué es. Falta: el de la
   respuesta; aviso (algo a evitar sin ser falta): gris; bien (✓): tinta. */
#notation text.rotulo{font-family:var(--serif);font-style:italic;font-weight:600;fill:var(--fg)}
#notation text.rotulo.dis{fill:var(--ok)}
#notation text.rotulo.aviso{fill:var(--muted)}
#notation text.rotulo.bien{fill:var(--ink)}
/* Corchete de los rótulos entre notas (ArmoniaEj.rotulosEntre), del color del
   rótulo; rayas de movimiento (ArmoniaEj.lineasMovimiento), una por voz */
#notation path.corchete-rot{fill:none;stroke:var(--fg)}
#notation path.corchete-rot.dis{stroke:var(--ok)}
#notation path.corchete-rot.aviso{stroke:var(--muted)}
#notation line.raya{stroke-linecap:round;opacity:.85}
#notation line.raya.voz-sup{stroke:var(--voz-sup)}
#notation line.raya.voz-inf{stroke:var(--voz-inf)}
/* voces que no se preguntan (la pareja resaltada entre cuatro), en gris */
#notation g.note.gris, #notation g.ledgerLines path.gris{opacity:.32}
/* 7.ª diatónica: al revelar, en gris las notas superiores que no son de la
   línea de la 7.ª (preparación, 7.ª, resolución), y en el color de la
   respuesta la línea (y su ligadura) cuando se destaca sobre la realización */
.mascara.revelado #notation g.note.atenua, .mascara.revelado #notation g.ledgerLines path.atenua{opacity:.32}
.mascara.revelado #notation g.note.destaca{fill:var(--ok)}
/* nota dada dentro de una voz oculta (el primer acorde de Secuencias ·
   Círculo de 5.as): a la vista aunque su capa sea `resp` */
.mascara:not(.oir) #notation g.note.dada, .mascara.revelado #notation g.note.dada{visibility:visible}
.mascara.revelado #notation g.tie.destaca path{fill:var(--ok);stroke:var(--ok)}
/* enunciado textual en la tarjeta de partitura (Unidad 0: nombre de la
   tonalidad o cifrado americano, cuando la partitura es la respuesta) */
#notation .big-name,.big-name{font-family:var(--serif);font-size:clamp(28px,5vw,44px);
     font-weight:600;color:var(--ink);text-align:center}
#notation .ph .icon{font-size:30px;display:block;margin-bottom:8px}
#overlay{position:absolute;inset:0;pointer-events:none;overflow:visible}

/* ---------- acciones (columna a la derecha) ---------- */
.controls{display:flex;flex-direction:column;gap:12px;width:340px;flex-shrink:0}
button{font-family:var(--sans);font-size:17px;font-weight:600;
     border:1.5px solid var(--line);background:var(--card);color:var(--fg);
     padding:0 20px;min-height:64px;border-radius:14px;cursor:pointer;
     transition:background .15s ease,border-color .15s ease,color .15s ease;
     display:inline-flex;align-items:center;gap:12px;touch-action:manipulation}
.controls button{width:100%;justify-content:flex-start;text-align:left}
button .ic{width:20px;text-align:center;flex-shrink:0}
/* hover solo donde hay puntero que flote (en táctil se quedaría pegado
   tras el toque); el feedback táctil es :active */
@media(hover:hover){
  button:hover{border-color:var(--ink);color:var(--ink)}
  button.primary:hover{background:var(--ink-hover);border-color:var(--ink-hover);color:#fff}
  button:disabled:hover{border-color:var(--line);color:var(--fg)}
  button.primary:disabled:hover{background:var(--ink);border-color:var(--ink);color:#fff}
}
button:active:not(:disabled){border-color:var(--ink);color:var(--ink)}
button.primary{background:var(--ink);color:#fff;border-color:var(--ink);font-weight:700}
button.primary:active:not(:disabled){background:var(--ink-hover);border-color:var(--ink-hover);color:#fff}
button:disabled{opacity:.45;cursor:default}
button.toggle{min-height:56px}
button.toggle.on{background:var(--accent-soft);border-color:var(--ink);
     color:var(--ink);font-weight:700}
.sep{height:1px;width:100%;background:var(--line);margin:4px 0}

/* ---------- tira deslizante (series encadenadas) ----------
   Visor de tira-partitura.js: la partitura entera (un sistema) se
   desplaza dentro de .tira; los velos difuminan lo anterior y lo
   posterior al compás centrado; .tira-resp son las capas de
   respuesta superpuestas (encima/debajo del pentagrama). */
.score-card.tira-card{padding:16px 0;display:block}
/* contain:inline-size: el visor no propaga a sus ancestros el ancho
   intrínseco de la tira (5000 px), que overflow:hidden no corta y que en
   un contenedor flex/grid ensancharía toda la página */
.tira{position:relative;overflow:hidden;width:100%;padding:52px 0;contain:inline-size}
.tira-inner{width:max-content;min-width:100%;text-align:center;
     transition:transform .6s ease;will-change:transform}
#notation.tira-inner svg,.tira-inner svg{max-width:none;display:block}
.tira-velo{position:absolute;top:0;bottom:0;z-index:2;pointer-events:none;
     width:max(0px,calc(50% - 210px))}
.tira-velo.izq{left:0;background:linear-gradient(to right,
     var(--card) 0,var(--card) calc(100% - 70px),rgba(255,255,255,0) 100%)}
.tira-velo.der{right:0;background:linear-gradient(to left,
     var(--card) 0,var(--card) calc(100% - 70px),rgba(255,255,255,0) 100%)}
.tira-resp{position:absolute;left:0;right:0;z-index:3;text-align:center;
     font-family:var(--serif);font-size:28px;font-weight:600;line-height:1.1;
     color:var(--ok);opacity:0;transition:opacity .25s ease;pointer-events:none}
.tira-resp.sup{top:8px}
.tira-resp.inf{bottom:8px}
.tira-resp.show{opacity:1}
/* variante "pregunta": el dato mostrado (no la respuesta) va en tinta */
.tira-resp.pregunta{color:var(--ink)}
/* respuesta centrada sobre el pentagrama (p. ej. «sin alteraciones»
   cuando la armadura revelada no dibuja nada) */
.tira-resp.centro{top:50%;left:50%;right:auto;transform:translate(-50%,-50%);
     font-size:19px;background:var(--card);padding:2px 14px;border-radius:8px}

/* ---------- bajo la partitura ---------- */
.under{display:flex;align-items:center;gap:14px;margin-top:12px;min-height:32px;flex-wrap:wrap}
.motion{font-size:24px;font-weight:600;font-family:var(--serif);color:var(--ink)}
.motion.dim{color:var(--muted);font-weight:400;font-family:var(--sans);font-size:15px}
.step{font-size:14px;color:var(--muted);margin-left:auto}
.legend{display:none;gap:12px;font-size:13px;color:var(--muted)}
.legend.show{display:flex}
.legend i{display:inline-block;width:16px;height:3px;border-radius:2px;
     vertical-align:middle;margin-right:5px}
/* Lo que se pregunta: debajo de la partitura y con menos peso que el dato y
   que la respuesta. El enunciado largo sigue en <details class="ayuda">. */
.pregunta{font-size:16px;color:var(--muted);margin:0;max-width:860px}
.pregunta b{color:var(--fg);font-weight:600}

.motions-line{font-size:14px;color:var(--muted);display:none}
.motions-line.show{display:block}
.motions-line b{color:var(--ink);font-weight:600}

/* ---------- panel de respuesta ---------- */
.answer{margin-top:16px;padding:20px 24px;border:1px solid var(--ok-line);
     border-radius:14px;background:var(--ok-bg);display:none}
.answer.show{display:block}
.answer .q{font-family:var(--serif);font-size:30px;font-weight:600;color:var(--ok);
     line-height:1.25}
.answer .det{color:var(--muted);font-size:15px;font-weight:600;margin-top:4px}
.answer .det b{color:var(--ink);font-weight:600}
.answer .compound{font-size:15px;font-weight:400;color:var(--muted);margin-left:6px}

/* ---------- página común (ArmoniaEj.ejercicio, Modelo-ejercicios.md §2) ----------
   El <body> lleva `mascara` en las páginas migradas. La partitura se dibuja
   completa una vez; lo que es respuesta lleva la clase `resp` (desde el @type
   del MEI) y lo que solo es pregunta, `preg`. Revelar = `revelado` en <body>:
   nada se vuelve a dibujar ni se mueve. El panel de respuesta ocupa su sitio
   desde el principio, invisible. visibility (no display): las medidas tras el
   render (cifras apiladas, círculos, corchetes) siguen funcionando. */
.mascara:not(.revelado) #notation .resp,
.mascara.revelado #notation .preg,
/* barra de un compás que solo existe al revelar (la doble entre el intervalo
   y su inversión): Verovio la dibuja dentro del compás, marcado barra-resp */
.mascara:not(.revelado) #notation g.measure.barra-resp > g.barLine{visibility:hidden}
.mascara .answer{display:block}
/* modo por pasos (ejercicio con `pasos`): lo de los pasos ya mostrados */
.mascara:not(.revelado) #notation .resp.visto{visibility:visible}
/* «Oír» (body.oir): la partitura se oculta hasta revelar y en su lugar sale el
   aviso; la tarjeta conserva su tamaño (visibility, no display) */
.mascara.oir:not(.revelado) #notation{visibility:hidden}
.score-card{position:relative}
.oir-aviso{position:absolute;inset:0;display:none;flex-direction:column;align-items:center;
     justify-content:center;gap:10px;color:var(--soft);font-size:17px;font-weight:600}
.oir-aviso svg{width:44px;height:44px}
.mascara.oir:not(.revelado) .oir-aviso{display:flex}
.oir-aviso .oir-dato{font-family:var(--serif);font-weight:600;color:var(--ink);font-size:20px}
/* botones que solo tienen sentido con «Oír» (p. ej. «Solo el bajo») */
body:not(.oir) .controls .solo-oir{display:none}
.mascara:not(.revelado) .answer{visibility:hidden}

/* La pregunta, ENCIMA de la partitura y siempre visible: primer hijo de
   .ej-main (también en las series de armaduras, que no usan la máscara). En
   las páginas antiguas sigue debajo, dentro de .under, con su estilo de arriba. */
.ej-main > .pregunta:first-child{font-size:19px;color:var(--fg);margin:0 0 12px;line-height:1.35}
.ej-main > .pregunta:first-child b{color:var(--ink);font-weight:700}
/* Lo que incluye el nivel actual, bajo la partitura */
.nivel-desc{font-size:15px;color:var(--muted);margin:0;max-width:860px}
.nivel-desc b{color:var(--fg);font-weight:600}

/* Selector de nivel en la cabecera entintada (sustituye a «Nivel N» fijo) */
.level button.niv{min-width:48px;min-height:48px;padding:0;border-radius:10px;
     justify-content:center;font-size:17px;font-weight:700;
     background:rgba(255,255,255,.14);border:1.5px solid transparent;color:#fff}
.level button.niv[aria-pressed="true"]{background:#fff;color:var(--ink)}
@media(hover:hover){
  .level button.niv:hover{border-color:rgba(255,255,255,.6);color:#fff}
  .level button.niv[aria-pressed="true"]:hover{color:var(--ink)}
}
.level button.niv:active:not(:disabled){border-color:#fff;color:#fff}
.level .niv-rotulo{margin-right:2px}

@media(max-width:860px){
  header{padding:12px 16px;column-gap:12px}
  header h1{font-size:19px}
  main{padding:20px 16px 32px}
  /* en columna, flex-start haría que cada hijo tomase el ancho de su
     contenido (la partitura), desbordando la pantalla: estirar */
  .ej-row{flex-direction:column;align-items:stretch}
  .ej-main{width:100%}
  .controls{flex-direction:row;flex-wrap:wrap;width:auto}
  .controls button{width:auto;min-height:56px}
  .sep{width:1px;height:32px;margin:0}
}

/* ---------- modo compacto: móvil vertical (< 720 px) ----------
   Ver design/RESPONSIVE.md. Solo reorganiza; por encima de 720 px nada
   de esto se aplica. Cabecera en dos filas (volver + nivel / título),
   partitura a ancho completo y las acciones en una barra pegada al
   borde inferior de la pantalla, en filas de dos (los .sep hacen de
   salto de fila). */
@media(max-width:719.98px){
  body{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
  header{padding:10px 16px 12px;row-gap:6px;column-gap:12px;
         grid-template-columns:auto 1fr auto;
         grid-template-areas:"back . level" "title title title" "sub sub sub"}
  header h1{font-size:19px;align-self:auto}
  header .sub{font-size:12px;align-self:auto}
  header a.back{height:44px;padding:0 14px;font-size:15px}
  .level{font-size:13px;gap:8px}
  .level b{min-width:36px;height:36px;font-size:15px}
  .level button.niv{min-width:42px;min-height:42px;font-size:16px}
  .ej-main > .pregunta:first-child{font-size:16px;margin-bottom:10px}
  .nivel-desc{font-size:13px}

  /* main pasa a columna flex y .ej-row se disuelve (display:contents):
     partitura, ayuda y barra de acciones son hijos directos de main, en
     ese orden; la partitura empuja el resto al fondo y la barra es lo
     último, pegada al borde inferior */
  main{flex:1;width:100%;margin:0;display:flex;flex-direction:column;gap:14px;padding:16px 16px 0}
  .ej-row{display:contents}
  .ej-main{flex:1}
  .score-card{padding:18px 14px;min-height:200px}
  .score-card.tira-card{padding:12px 0}
  .answer{padding:16px 18px}
  .answer .q{font-size:26px}

  .controls{position:sticky;bottom:0;z-index:5;order:1;   /* detrás de la ayuda */
            margin:0 -16px;padding:12px 16px calc(2px + env(safe-area-inset-bottom));
            background:var(--bg);border-top:1px solid var(--line);
            flex-direction:row;flex-wrap:wrap;gap:0 10px;align-items:stretch}
  .controls button{flex:1 1 40%;width:auto;min-height:52px;margin-bottom:10px;
            justify-content:center;text-align:center;font-size:16px;padding:0 14px}
  .controls button.primary{flex:2 1 55%}
  .controls button.toggle{min-height:52px}
  .controls .sep{flex-basis:100%;width:100%;height:0;margin:0;background:none}
  .under{margin-top:10px;font-size:13px}
  .pregunta{font-size:15px}
  .ayuda{margin:0 0 6px}
  .ayuda summary{min-height:48px;font-size:15px}
  .pie-ej{margin:0 0 6px;gap:10px}
  .pie-ej .ayuda{margin:0}
  a.apuntes-enlace{min-height:48px;font-size:15px}
  a.apuntes-enlace .ap-resto{display:none}
  .prompt{font-size:16px}
}

