/* ============================================================
   Cancionero oviedo_church — hoja de estilos
   Paleta del logo: blanco hueso y negro, rojo litúrgico de acento.
   ============================================================ */

:root {
  --bg: #EFECE4;
  --surface: #F8F6F1;
  --surface-2: #E4E0D5;
  --ink: #0C0B0A;
  --ink-soft: #57534B;
  --ink-faint: #8A857A;
  --rule: #D5D0C3;
  --accent: #A82A1A;
  --accent-soft: rgba(168, 42, 26, .10);

  --fresh: #A82A1A;
  --warm: #B8862B;
  --cold: #4F7A63;
  --never: #B4AEA1;

  /* El verde de «guardar»: el mismo --cold, un punto más oscuro para que
     el texto blanco de encima llegue al contraste mínimo. */
  --ok: #456B57;
  --ok-ink: #FFFFFF;

  --f-display: "Unbounded", "Trebuchet MS", sans-serif;
  --f-body: "Source Serif 4", Georgia, serif;
  --f-mono: "JetBrains Mono", Consolas, monospace;

  --r: 4px;
  --tap: 46px;
  --head: 57px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark;
    --bg: #100F0E; --surface: #1A1917; --surface-2: #24221F;
    --ink: #EFECE4; --ink-soft: #ADA79B; --ink-faint: #7C766B;
    --rule: #302D28; --accent: #E4705A; --accent-soft: rgba(228,112,90,.13);
    --fresh: #E4705A; --warm: #D6A94E; --cold: #7FB79A; --never: #5C574F;
    --ok: #7FB79A; --ok-ink: #0C0B0A;
  }
}
:root[data-theme="dark"] { color-scheme: dark;
  --bg: #100F0E; --surface: #1A1917; --surface-2: #24221F;
  --ink: #EFECE4; --ink-soft: #ADA79B; --ink-faint: #7C766B;
  --rule: #302D28; --accent: #E4705A; --accent-soft: rgba(228,112,90,.13);
  --fresh: #E4705A; --warm: #D6A94E; --cold: #7FB79A; --never: #5C574F;
    --ok: #7FB79A; --ok-ink: #0C0B0A;
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--bg); color: var(--ink);
  font-family: var(--f-body); font-size: 17px; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------ cabecera */
.topbar {
  position: sticky; top: 0; z-index: 40;
  background: var(--bg); border-bottom: 1px solid var(--rule);
}
.topbar-in {
  max-width: 1180px; margin: 0 auto; padding: 10px 18px;
  display: flex; align-items: center; gap: 14px;
}
.brand { display: flex; align-items: center; gap: 11px; flex: none; }
.brand svg { width: 34px; height: 34px; color: var(--ink); flex: none; }
.brand b {
  font-family: var(--f-display); font-weight: 900; font-size: 17px;
  letter-spacing: -.02em; text-transform: uppercase;
}
.nav { display: flex; gap: 4px; margin-left: auto; }
.nav a {
  padding: 9px 14px; border-radius: var(--r); font-size: 15px;
  color: var(--ink-soft); white-space: nowrap;
}
.nav a:hover { background: var(--surface-2); }
.nav a.on { background: var(--ink); color: var(--bg); }
.nav a.dim { opacity: .45; cursor: default; }
.nav a.dim:hover { background: none; }

.iconbtn {
  width: 40px; height: 40px; display: grid; place-items: center; flex: none;
  border: 1px solid var(--rule); background: var(--surface);
  border-radius: var(--r); cursor: pointer; font-size: 16px;
}
.iconbtn:hover { background: var(--surface-2); }
/* Los iconos dibujados toman el color del texto del botón y se alinean solos. */
.iconbtn.ico { color: var(--ink-soft); }
.iconbtn.ico:hover { color: var(--ink); }
.iconbtn svg { display: block; }
.langpick {
  height: 40px; padding: 0 10px; border: 1px solid var(--rule);
  background: var(--surface); border-radius: var(--r); cursor: pointer;
}

.wrap { max-width: 1180px; margin: 0 auto; padding: 24px 18px 90px; }

/* --------------------------------------------------- búsqueda y filtros */
.searchrow { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.search { display: block; position: relative; flex: 1 1 320px; }
.search input {
  width: 100%; height: var(--tap); padding: 0 40px 0 44px;
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r);
}
.search .mag { position: absolute; left: 15px; top: 11px; color: var(--ink-faint); }
.search .x {
  position: absolute; right: 8px; top: 8px; width: 30px; height: 30px;
  border: 0; background: none; cursor: pointer; color: var(--ink-faint); border-radius: var(--r);
}
.search .x:hover { background: var(--surface-2); }

.seg { display: flex; border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden; }
.seg button {
  height: var(--tap); padding: 0 16px; border: 0; cursor: pointer;
  background: var(--surface); color: var(--ink-soft); font-size: 15px;
}
.seg button + button { border-left: 1px solid var(--rule); }
.seg button.on { background: var(--ink); color: var(--bg); }
/* La flecha del sentido solo la lleva el orden activo: en el otro botón
   sería una promesa de algo que aún no se está haciendo. */
.seg button .dir { font-size: 11px; margin-left: 6px; opacity: .8; }

.btn {
  height: var(--tap); padding: 0 18px; cursor: pointer;
  border: 1px solid var(--ink); background: var(--ink); color: var(--bg);
  border-radius: var(--r); font-size: 15px;
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
}
.btn:hover { opacity: .88; }
.btn.ghost { background: var(--surface); color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { background: var(--surface-2); opacity: 1; }
.btn.sm { height: 36px; padding: 0 12px; font-size: 14px; }

/* --- Un tono por función ---
   El color no está para decorar: está para que no haya que leer el botón
   antes de pulsarlo. Guardar lleva el verde de la paleta —apagado, el mismo
   que usan los servicios de oración—, borrar el rojo del logo y las acciones
   que crean cosas de golpe el ámbar. Cancelar y las herramientas se quedan
   en gris: no tienen color propio porque no comprometen a nada.
   Los que avisan van lavados, con el color solo en el texto y el borde: un
   botón rojo entero en medio de la pantalla pide que lo pulses. */
.btn.ok { background: var(--ok); border-color: var(--ok); color: var(--ok-ink); }
.btn.danger, .btn.warn {
  background: var(--surface); color: var(--ink); border-color: var(--rule);
}
.btn.danger { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--rule)); }
.btn.warn { color: var(--warm); border-color: color-mix(in srgb, var(--warm) 45%, var(--rule)); }
.btn.danger:hover { background: color-mix(in srgb, var(--accent) 10%, var(--surface)); opacity: 1; }
.btn.warn:hover { background: color-mix(in srgb, var(--warm) 12%, var(--surface)); opacity: 1; }

/* --- Los grupos, en el editor: una fila de pastillas --- */
.tags { display: flex; gap: 8px; flex-wrap: wrap; margin: 16px 0 4px; }
.tag {
  padding: 6px 13px; border: 1px solid var(--rule); border-radius: 999px;
  font-size: 14px; color: var(--ink-soft); background: var(--surface); cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px;
}
.tag:hover { background: var(--surface-2); }
.tag.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.tag .n { color: var(--ink-faint); font-size: 12px; margin-left: 5px; }
.tag.on .n { color: rgba(255,255,255,.75); }

/* ============================================================
   EL DESPLEGABLE DE GRUPOS
   Los ocho grupos ocupaban una fila entera de botones: en el móvil eran dos
   renglones antes de llegar a la primera canción. Aquí van dentro de un
   desplegable y se marcan con un tic, varios a la vez.
   ============================================================ */

/* El color de cada grupo se eligió pensando en papel claro; sobre el negro
   del modo oscuro hay que aclararlo o los ocho se parecen entre sí. --gv es
   el color ya listo para el fondo que toque, --g el que está en la base.
   Ojo: --gv tiene que declararse en el MISMO elemento que lleva --g, porque
   una variable que apunta a otra se resuelve donde se declara. */
.grow { --gv: var(--g); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .grow { --gv: color-mix(in srgb, var(--g) 46%, #F4F1E9); }
}
:root[data-theme="dark"] .grow { --gv: color-mix(in srgb, var(--g) 46%, #F4F1E9); }

.pop { position: relative; }
.gbtn {
  display: inline-flex; align-items: center; gap: 8px;
  height: var(--tap); padding: 0 14px; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r); font-size: 15px;
}
.gbtn:hover { background: var(--surface-2); }
.gbtn[aria-expanded="true"] { border-color: var(--ink-faint); }
.gbtn .caret { font-size: 11px; color: var(--ink-faint); transition: transform .18s ease; }
.gbtn[aria-expanded="true"] .caret { transform: rotate(180deg); }
/* Los iconos de los grupos puestos, en el propio botón: se sabe lo que hay
   marcado sin abrir el panel, y ocupa lo mismo que un número. */
.gbtn .picked { display: inline-flex; gap: 3px; }
.gbtn .picked i { font-style: normal; font-size: 15px; line-height: 1; }
.gbtn .badge {
  font-family: var(--f-mono); font-size: 12px; font-weight: 700;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--surface);
}

.gpanel {
  /* Cuelga del botón. Hacia qué lado se abre lo decide el propio componente
     al abrirlo, midiendo lo que queda de pantalla: el botón está en un sitio
     en la lista y en otro en el editor, y con CSS a secas se salía por el
     borde en unos anchos sí y en otros no. */
  position: absolute; z-index: 45; top: calc(100% + 6px); left: 0;
  width: max-content; min-width: 276px; max-width: min(340px, calc(100vw - 24px));
  max-height: 70vh; overflow-y: auto; padding: 6px;
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: 6px; box-shadow: 0 18px 44px rgba(0,0,0,.22);
}
.gpanel[hidden] { display: none; }
.gpanel.izq { left: auto; right: 0; }
.gpanel .foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 6px; padding: 8px 6px 4px; border-top: 1px solid var(--rule);
}
.gpanel .foot .spacer { flex: 1; }
.linkbtn {
  background: none; border: 0; cursor: pointer; padding: 4px 6px;
  font-size: 14px; color: var(--ink-faint);
}
.linkbtn:hover { color: var(--accent); }
.linkbtn.strong { color: var(--ink); font-weight: 600; }

.grow {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border: 0; border-left: 3px solid transparent;
  border-radius: var(--r); cursor: pointer; text-align: left;
  background: none; color: var(--ink); font-size: 15px;
}
.grow:hover { background: color-mix(in srgb, var(--gv) 9%, transparent); }
.grow[aria-checked="true"] {
  background: color-mix(in srgb, var(--gv) 14%, transparent);
  border-left-color: var(--gv);
}
.grow .ico {
  width: 26px; height: 26px; flex: none; border-radius: 50%;
  display: grid; place-items: center; font-size: 14px; line-height: 1;
  background: color-mix(in srgb, var(--gv) 18%, transparent);
}
.grow .nm { flex: 1; }
.grow .n {
  font-family: var(--f-mono); font-size: 12px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.grow .tick {
  width: 20px; height: 20px; flex: none; border-radius: var(--r);
  border: 1.5px solid var(--rule); background: var(--bg);
  display: grid; place-items: center; color: var(--bg); font-size: 12px;
}
.grow[aria-checked="true"] .tick { background: var(--gv); border-color: var(--gv); }
.grow[aria-checked="true"] .tick::after { content: "✓"; font-weight: 700; }


.legend {
  display: flex; gap: 18px; flex-wrap: wrap; align-items: center;
  margin: 18px 0 8px; font-size: 13px; color: var(--ink-faint);
}
.legend span { display: inline-flex; align-items: center; gap: 7px; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.d-fresh { background: var(--fresh); } .d-warm { background: var(--warm); }
.d-cold { background: var(--cold); }
.d-never { background: var(--never); box-shadow: inset 0 0 0 1px var(--rule); }

.count { font-size: 13px; color: var(--ink-faint); margin: 4px 0 8px; font-family: var(--f-mono); }

/* La cuenta y, a su lado, el filtro de las que faltan por revisar (fase 3).
   El botón solo existe cuando hay alguna: el resto del tiempo no estorba. */
.countrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 4px 0 8px; }
.countrow .count { margin: 0; }
.pendbtn {
  border: 1px solid var(--warm); background: transparent; color: var(--ink-soft);
  border-radius: 999px; padding: 3px 12px; font-size: 13px; cursor: pointer;
}
.pendbtn:hover { background: var(--surface); }
.pendbtn.on { background: var(--surface-2); color: var(--ink); font-weight: 600; }
.pendbtn[hidden] { display: none; }

/* ----------------------------------------------------- lista de canciones */
.list { border-top: 1px solid var(--rule); }
.row {
  display: grid; grid-template-columns: 54px 1fr auto auto auto;
  align-items: center; gap: 14px;
  padding: 12px 10px; border-bottom: 1px solid var(--rule); cursor: pointer;
}
.row:hover { background: var(--surface); }
.num { font-family: var(--f-mono); font-size: 14px; color: var(--ink-faint); text-align: right; }
.tt { min-width: 0; }
.tt b {
  display: block; font-family: var(--f-display); font-weight: 700; font-size: 17px;
  letter-spacing: -.015em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* En la lista el título se recorta solo, y la marca de la hoja queda fuera del
   recorte: si se cortara con el «…», en los títulos largos no se vería. */
.row .tt b { display: flex; align-items: center; gap: 7px; }
.row .tt b .tl { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.row .tt b .sheet { flex: none; display: flex; color: var(--ink-faint); cursor: default; }
.row .tt b .sheet svg { display: block; }
/* «sin revisar» y «no sale para la gente»: marcas pequeñas tras el título */
.row .tt b .flag {
  flex: none; font-style: normal; font-weight: 400; font-family: var(--f-body);
  font-size: 14px; color: var(--ink-faint); cursor: default;
}
.row .tt b .flag.pend { color: var(--warm); }
.tt small { color: var(--ink-faint); font-size: 13px; }
/* En pantalla ancha este envoltorio no pinta nada: sus hijos entran
   directamente en las columnas de la fila. En el móvil pasa a ser una
   segunda línea (ver más abajo). */
.rowmeta { display: contents; }
/* El tono va antes en el HTML (para que en el móvil suba junto al título),
   pero en pantalla ancha se dibuja donde siempre: detrás de los idiomas. */
.row .key { order: 1; }
.row .last { order: 2; }
.langs { display: flex; gap: 4px; }
.lg {
  font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em;
  padding: 3px 6px; border: 1px solid var(--rule); border-radius: 3px;
  color: var(--ink-faint); font-style: normal;
}
.lg.main { border-color: var(--ink); color: var(--ink); }
.key {
  font-family: var(--f-mono); font-weight: 700; font-size: 15px; color: var(--accent);
  min-width: 46px; text-align: center;
}
.last {
  display: inline-flex; align-items: center; gap: 8px; font-size: 13px;
  color: var(--ink-soft); min-width: 128px; justify-content: flex-end;
}
.empty { padding: 60px 10px; text-align: center; color: var(--ink-faint); }
.empty b { display: block; font-family: var(--f-display); font-size: 19px; color: var(--ink); margin-bottom: 8px; }

/* --------------------------------------------------------- ficha canción */
.songhead { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; }
.songhead h1 {
  font-family: var(--f-display); font-weight: 900; font-size: clamp(26px, 4.2vw, 42px);
  letter-spacing: -.035em; line-height: 1.05; margin: 0 0 8px;
}
.meta { color: var(--ink-faint); font-size: 14px; display: flex; gap: 14px; flex-wrap: wrap; margin: 0; }
.meta b { color: var(--ink-soft); font-weight: 600; }
.spacer { flex: 1; }

.langtabs { display: flex; margin: 20px 0 0; border-bottom: 1px solid var(--rule); flex-wrap: wrap; }
.langtabs button {
  background: none; border: 0; cursor: pointer; padding: 11px 18px;
  font-size: 16px; color: var(--ink-faint);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.langtabs button.on { color: var(--ink); border-bottom-color: var(--accent); font-weight: 600; }

.ctrl {
  position: sticky; top: var(--head); z-index: 30;
  background: var(--bg); border-bottom: 1px solid var(--rule);
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 11px 0; margin-bottom: 6px;
}
.grp {
  display: flex; align-items: center; border: 1px solid var(--rule);
  border-radius: var(--r); background: var(--surface); overflow: hidden;
}
.grp > * { border: 0; background: none; }
.grp button { width: 42px; height: 42px; cursor: pointer; font-size: 18px; }
.grp button:hover { background: var(--surface-2); }
.grp .val {
  min-width: 60px; text-align: center; font-family: var(--f-mono);
  font-weight: 700; color: var(--accent); font-size: 17px;
  border-left: 1px solid var(--rule); border-right: 1px solid var(--rule);
  height: 42px; line-height: 42px;
}
.grp .lbl { padding: 0 12px; font-size: 13px; color: var(--ink-faint); white-space: nowrap; }
.grp select { height: 42px; padding: 0 8px; cursor: pointer; }
.ctrl .more { display: none; }        /* solo hace falta en pantallas estrechas */
/* El tono es lo único que se toca mientras se canta, así que su desplegable
   se queda siempre a la vista, también en el móvil, y con su etiqueta. */
.ctrl .grp.keypick select { font-family: var(--f-mono); font-weight: 700;
                            color: var(--accent); font-size: 17px; }

/* --- La letra con los acordes.
   Cada trozo es una columna: acorde arriba, sílaba debajo. El acorde queda
   anclado a SU sílaba a cualquier tamaño de letra. --- */
.sheet { font-size: var(--lyr, 19px); max-width: 820px; }
.sec { margin: 24px 0 0; }
.sec > h4 {
  font-family: var(--f-display); font-size: 12px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint);
  margin: 0 0 10px; display: flex; align-items: center; gap: 12px;
}
.sec > h4::after { content: ""; flex: 1; height: 1px; background: var(--rule); }
.sec.chorus { padding-left: 16px; border-left: 2px solid var(--accent); }
.line { display: flex; flex-wrap: wrap; align-items: flex-end; margin-bottom: 3px; }
.line.blank { height: .7em; }
/* --- Los apuntes: «solo guitarra», «despacio», «dos veces».
   Letra fina y pequeña en el color de acento: se ven de un vistazo desde el
   atril —para eso están— pero no compiten con lo que hay que cantar. Van
   pegados al verso, dentro de la misma línea, y solo llevan la barra del
   margen cuando ocupan una línea para ellos solos. --- */
.line .cmt {
  font-style: italic; font-weight: 400; font-size: .7em; line-height: 1.4;
  color: var(--accent); opacity: .82; margin: 0 .25em;
}
.line.note { margin: 6px 0 4px; }
.line.note .cmt {
  margin: 0; padding-left: 9px; border-left: 2px solid var(--accent-soft);
}
/* Una palabra: sus trozos van pegados y la línea no puede partirla por en
   medio. El ajuste al ancho solo puede caer entre palabras, como debe ser.
   El flex-wrap es el último recurso, para cuando una palabra sola no cabe a
   lo ancho —letra muy grande en un móvil estrecho—: antes que salirse de la
   pantalla y perderse, se parte. */
.w {
  display: inline-flex; align-items: flex-end; align-content: flex-end;
  flex-wrap: wrap; max-width: 100%;
}
.ck { display: inline-flex; flex-direction: column; }
.ck > i {
  font-family: var(--f-mono); font-style: normal; font-weight: 700;
  font-size: .72em; line-height: 1.35; color: var(--accent);
  white-space: pre; letter-spacing: -.01em;
}
.ck > i em { font-style: normal; color: var(--ink-faint); font-weight: 400; font-size: .86em; }
.ck > s { text-decoration: none; white-space: pre-wrap; }
/* Un acorde sin sílaba debajo —al final de la línea, «тебе, [D] [G]», o dos
   seguidos, «[G][C]текст»— dejaba su columna con un solo piso. Como la línea
   se alinea por abajo, el acorde bajaba hasta la altura de la letra y parecía
   un apunte. Con un espacio duro invisible tiene los mismos dos pisos que los
   demás y se queda arriba, en su sitio. */
.ck > s:empty::before { content: "\00a0"; }
.sheet.bold .ck > s { font-weight: 600; }

/* Sin acordes: para quien solo canta. La letra se junta, porque el hueco que
   ocupaba el acorde ya no hace falta, y cabe casi el doble en pantalla. */
.sheet.no-chords .ck > i { display: none; }
.sheet.no-chords .line { margin-bottom: 2px; }

/* El botón, tachado cuando los acordes están escondidos */
.chordsw.off { position: relative; opacity: .65; }
.chordsw.off::after {
  content: ""; position: absolute; left: 22%; right: 22%; top: 50%;
  height: 1.5px; background: currentColor; transform: rotate(-20deg);
}

.cols { display: flex; gap: 32px; align-items: flex-start; }
.sidecar {
  border: 1px solid var(--rule); background: var(--surface);
  border-radius: var(--r); padding: 16px 18px; font-size: 14px; color: var(--ink-soft);
  width: 290px; flex: none;
}
.sidecar h5 {
  font-family: var(--f-display); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 8px;
}
.sidecar section + section { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--rule); }
.sidecar p { margin: 0 0 8px; }
.sidecar .k { font-family: var(--f-mono); color: var(--accent); font-weight: 700; }
.sidecar ul { margin: 0; padding-left: 1.1em; }
.sidecar li { margin-bottom: 4px; }

/* -------------------------------------------------------------- editor */
.edgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; align-items: start; }
.field { margin-bottom: 14px; }
.field label {
  display: block; font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); font-family: var(--f-display); margin-bottom: 6px;
}
.field input, .field select, .field textarea {
  width: 100%; padding: 10px 12px; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--r);
}
.field textarea {
  font-family: var(--f-mono); font-size: 14px; line-height: 1.7;
  min-height: 340px; resize: vertical; white-space: pre; overflow-wrap: normal; overflow-x: auto;
}
/* --- Los datos de la canción, juntos y apretados.
   Cada campo pide el ancho que necesita de verdad: el número, poco; el autor,
   lo que sobre; los tonos, lo justo para un «Bbm». En el móvil caben en dos
   renglones en vez de cinco, y el título deja de quedarse media pantalla más
   abajo. --- */
.fieldrow { display: flex; gap: 10px 12px; flex-wrap: wrap; align-items: end; }
/* min-width: 0 es lo que hace que quepan: sin él, un campo no puede
   estrecharse por debajo de su palabra más larga —«ТОНАЛЬНІСТЬ»— y empuja a
   los demás al renglón siguiente. La etiqueta se parte en dos líneas y ya. */
.fieldrow .field { flex: 1 1 130px; min-width: 0; margin-bottom: 0; }
.fieldrow .f-groups { flex: 0 0 auto; }

/* --- Título, número y autor: los tres en un renglón ---
   El título va el primero y se lleva casi todo lo que sobra: es lo que se
   escribe nada más entrar y lo que más falta hace ver entero. Sin etiqueta
   encima —las pestañas de idioma ocupan ese renglón— para que los tres
   recuadros queden a la misma altura. De partida 180 + 70 + 90 y los huecos
   son 364, y en una pantalla de 430 quedan 402 libres. */
.fieldrow.datos .f-title { flex: 8 1 180px; }
.fieldrow.datos .f-num { flex: 0 1 70px; }
.fieldrow.datos .f-author { flex: 3 1 90px; }
/* Las pestañas de idioma ocupan el renglón de la etiqueta y con su misma
   altura: el título es lo que cambia al cambiar de idioma, así que van
   pegadas a él, y ahí no gastan una fila entera. Con las siglas —UK, RU,
   ES— y no con el nombre completo, que se llevaba media pantalla. */
.fieldrow .f-title .langtabs {
  margin: 0; border-bottom: 0; min-height: 2.1em; align-items: flex-end;
}
.fieldrow .f-title .langtabs button { padding: 4px 9px; font-size: 14px; }
/* width: auto porque dentro de un .field los select valen el 100%, y el de
   «añadir idioma» se estiraba a lo ancho del título. El relleno también hay
   que rebajarlo: con el de los campos grandes el texto no cabía a lo alto. */
.fieldrow .f-title .langtabs select {
  width: auto; padding: 5px 6px; margin-left: 4px; align-self: center;
}
/* El «＋» no lleva flecha ni se estira: un select mide lo que su opción más
   larga —«Українська»— aunque enseñe un signo de sumar, así que hay que
   ponerle el ancho a mano. La lista, al abrirla, sigue saliendo entera. */
.fieldrow .f-title .langtabs select.mas {
  appearance: none; -webkit-appearance: none; text-align: center;
  width: 34px; padding: 5px 0; cursor: pointer;
}
/* La segunda fila es la de lo que se elige de una lista y casi no se toca: un
   poco de aire por arriba para que se lea como un bloque aparte. Los tres
   caben en un renglón hasta en el móvil si el botón de grupos puede encoger y
   la pareja de tonos se conforma con menos: las etiquetas se parten en dos
   líneas, que es mejor que llevarse dos renglones enteros de pantalla. */
.fieldrow.ajustes { margin-top: 12px; }
/* Con dos o tres grupos marcados el botón se llena de nombres y, suelto, se
   comía el renglón entero. Con tope se queda en su sitio y recorta. */
.fieldrow.ajustes .f-groups { flex: 0 1 auto; min-width: 0; max-width: 260px; }
/* El botón de grupos tiene que poder encoger, y para eso lo que encoge de
   verdad es el texto de dentro: sin min-width:0 su palabra más larga marca el
   ancho mínimo de la fila y la pareja de tonos se cae al renglón siguiente. */
.fieldrow.ajustes .f-groups .gbtn { max-width: 100%; min-width: 0; }
.fieldrow.ajustes .f-groups .gbtn > span:not(.caret) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fieldrow.ajustes .keypair { flex: 3 1 210px; }
/* La pareja de tonos se mueve como una sola pieza y por dentro se reparte a
   medias. Sueltos, uno se quedaba solo ocupando un renglón entero. Llevan una
   etiqueta común arriba —«Tonalidad»— y debajo solo la palabra que los
   distingue: el nombre completo encima de cada uno no cabía en el móvil. */
.fieldrow .keypair { min-width: 0; }
.fieldrow .keypair .pair { display: flex; gap: 12px; min-width: 0; }
.fieldrow .keypair .sub { flex: 1 1 0; min-width: 0; display: block; cursor: pointer; }
/* En minúscula y sin espaciar: así se leen como lo que son, la coletilla de
   «Tonalidad», y no como dos etiquetas más al mismo nivel. */
.fieldrow .keypair .sub > span {
  display: block; font-size: 13px; color: var(--ink-faint);
  text-transform: none; letter-spacing: 0; font-family: var(--f-body);
  margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* La etiqueta puede partirse en dos líneas sin descuadrar nada: los campos se
   alinean por abajo, que es donde está lo que se rellena. */
.fieldrow .field label { min-height: 2.1em; }

/* «Para la gente» (fase 3): una casilla a la altura de los desplegables, sin
   el aspecto de etiqueta en mayúsculas que tienen las demás. */
.fieldrow.ajustes .f-public { flex: 0 0 auto; }
.field label.pubchk {
  display: flex; align-items: center; gap: 8px; min-height: 42px; margin: 0;
  font-family: var(--f-body); font-size: 15px; letter-spacing: 0; text-transform: none;
  color: var(--ink); cursor: pointer;
}
.field .pubchk input { width: 20px; height: 20px; padding: 0; margin: 0; accent-color: var(--accent); }

/* --- Leer una canción de una foto ---
   La foto se queda a la vista mientras se revisa: comparar de memoria no vale
   para esto, porque un verso inventado suena igual de bien que el de verdad. */
.shots { display: flex; flex-wrap: wrap; gap: 8px; }
.shots img {
  max-height: 260px; max-width: 100%; border-radius: var(--r);
  border: 1px solid var(--rule); display: block;
}
.livebar.check { background: var(--accent-soft); border-color: var(--accent); }
.oddwarn { color: var(--accent); margin: 0 0 8px; }
/* El acorde que chirría: el que hay que mirar primero con la foto delante. */
.ck > i.odd {
  background: var(--accent); color: var(--surface);
  border-radius: 3px; padding: 0 3px; margin: 0 -3px;
}

/* La foto de la hoja, a pantalla completa. Se abre para comparar un verso con
   el papel, y para eso hay que verla grande. */
.lightbox {
  position: fixed; inset: 0; z-index: 95; display: grid; place-items: center;
  padding: 14px; background: rgba(8, 8, 7, .97);
  /* La fila TIENE que medir lo que mide la caja. Con la fila implícita («auto»)
     la hoja se salía por abajo: el `max-height: 100%` de la foto no tenía
     contra qué resolverse, se quedaba en nada y mandaba solo el ancho. Es el
     mismo `minmax(0, …)` del calendario, por el mismo motivo. */
  grid-template-rows: minmax(0, 1fr);
}
.lightbox img {
  max-width: 100%; max-height: 100%; object-fit: contain;
  border-radius: var(--r); background: #fff;
}
.lbbar {
  position: absolute; top: 10px; right: 10px; z-index: 1;
  display: flex; gap: 6px; align-items: center;
}
.lbbar .count {
  font-family: var(--f-mono); font-size: 13px; color: #EFECE4;
  padding: 0 8px; font-variant-numeric: tabular-nums;
}
.lbbar .iconbtn { background: #1A1917; border-color: #322E29; color: #EFECE4; }
.lbbar .iconbtn:hover { background: #2A2724; }

/* Quitar el idioma que se está editando. En pantalla estrecha se queda en la
   ✕ sola: con el texto entero se llevaba un renglón para él. */
.droplang { margin-left: auto; color: var(--accent); background: none; border: 0;
            cursor: pointer; font-size: inherit; font-family: inherit; }
.droplang .x { display: none; }

/* Crear un grupo desde dentro del propio desplegable. */
.newgroup {
  width: 100%; margin-top: 4px; padding: 9px;
  border: 1px dashed var(--rule); border-radius: var(--r);
  background: none; color: var(--ink-faint); cursor: pointer;
  font-size: 14px; font-family: inherit;
}
.newgroup:hover { color: var(--accent); border-color: var(--accent); }

/* --- El cuadro de diálogo --- */
.dlg-back {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  padding: 20px; background: rgba(12, 11, 10, .55);
}
.dlg {
  width: min(420px, 100%); max-height: 88vh; overflow-y: auto; padding: 22px;
  background: var(--bg); border: 1px solid var(--rule); border-radius: 8px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .3);
}
.dlg h3 {
  font-family: var(--f-display); font-size: 17px; font-weight: 700;
  letter-spacing: -.01em; margin: 0 0 16px;
}
.dlg-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.pickrow { display: flex; flex-wrap: wrap; gap: 6px; }
.pick {
  width: 36px; height: 36px; display: grid; place-items: center; cursor: pointer;
  font-size: 17px; line-height: 1; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--r);
}
.pick:hover { background: var(--surface-2); }
.pick.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.pick.swatch { background: var(--g); border-color: rgba(0, 0, 0, .18); }
.pick.swatch.on { box-shadow: inset 0 0 0 2px var(--bg), 0 0 0 2px var(--ink); }
.icorow { display: flex; gap: 8px; align-items: flex-start; }
.icoinput { width: 58px !important; text-align: center; font-size: 17px; flex: none; }
.gpreview {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px 7px 8px; border-radius: 999px; font-size: 14px;
  background: color-mix(in srgb, var(--g) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--g) 45%, transparent);
}
.gpreview .ico {
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  font-size: 13px; background: color-mix(in srgb, var(--g) 22%, transparent);
}
.hint { font-size: 13px; color: var(--ink-faint); margin: 6px 0 0; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.previewbox {
  border: 1px solid var(--rule); border-radius: var(--r);
  background: var(--surface); padding: 18px; min-height: 340px;
}
.previewbox .sheet { font-size: 17px; }

/* ---------------------------------------------------------- quién soy */
.who {
  display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--ink-soft);
  padding-left: 12px; border-left: 1px solid var(--rule); flex: none;
}
.avatar {
  width: 30px; height: 30px; border-radius: 50%; background: var(--ink); color: var(--bg);
  display: grid; place-items: center; font-family: var(--f-display);
  font-size: 11px; font-weight: 700; flex: none;
}
.link {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--never); box-shadow: inset 0 0 0 1px var(--rule);
}
.link.on { background: var(--cold); box-shadow: none; }
.pending {
  min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px;
  background: var(--warm); color: #fff; font-family: var(--f-mono);
  font-size: 12px; display: grid; place-items: center; cursor: pointer;
}
.whoname { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ------------------------------------------------------------ calendario
   Tres alturas de vuelo: el año para localizar, el mes —una tira continua de
   semanas— para moverse, y el día para trabajar. En pantalla ancha el día va
   al lado del calendario; en estrecho, pegado al borde de abajo. Debajo del
   calendario no puede ir: encima de él la rueda mueve los meses, así que para
   bajar a verlo habría que sacar el ratón fuera. */
.callupa {
  display: grid; grid-template-columns: minmax(0, 1fr) 330px;
  gap: 0 20px; align-items: start;
}
/* En la vista de año no hay día abierto: el calendario ocupa todo el ancho. */
.callupa.solo { grid-template-columns: minmax(0, 1fr); }

.calbarra {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 0;
}
.calzoom {
  appearance: none; border: 0; background: none; cursor: pointer; padding: 0;
  font: inherit; font-family: var(--f-display); font-size: 21px;
  letter-spacing: -.02em; color: var(--ink); text-transform: capitalize;
}
.calzoom:hover { color: var(--accent); }
.calzoom .chev { color: var(--accent); margin-right: 4px; }

.calscroll {
  /* `relative` no es decorativo: los saltos («ponme en octubre») se calculan
     con offsetTop, y sin esto se medirían contra toda la página. */
  position: relative;
  height: 58vh; min-height: 340px; overflow-y: auto;
  /* Al llegar al final de los meses, que no siga tirando de la página entera. */
  overscroll-behavior: contain;
  border: 1px solid var(--rule); border-radius: var(--r); background: var(--bg);
}

/* --- altura 1: el año entero --- */
.calanyo { padding: 4px 14px 22px; }
.calanyo > h5 {
  position: sticky; top: 0; z-index: 2; margin: 0; padding: 14px 0 8px;
  background: var(--bg); font-family: var(--f-display); font-size: 27px;
  letter-spacing: -.03em;
}
.calmeses { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px 18px; }
.calmesito {
  appearance: none; border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; text-align: left;
}
.calmesito > b {
  display: block; font-family: var(--f-display); font-size: 14px;
  margin-bottom: 4px; text-transform: capitalize;
}
.calmesito:hover > b { color: var(--accent); }
.calmini { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.calmini span {
  font-family: var(--f-mono); font-size: 10px; line-height: 16px; height: 16px;
  text-align: center; color: var(--ink-faint); border-radius: 50%;
}
.calmini span.lleno { color: var(--accent); font-weight: 700; }
.calmini span.vacio { color: var(--warm); font-weight: 700; }
.calmini span.hoy { background: var(--accent); color: #fff; }

/* --- altura 2: la tira continua de semanas --- */
/* La etiqueta del mes NO va pegada arriba: con `sticky` las veintitantas se
   apilaban unas sobre otras en el borde y, de paso, offsetTop dejaba de valer
   para saltar de mes. Va como separador, y el mes en el que estás lo canta el
   título de la barra, que se actualiza al desplazarte. */
.caletiqueta {
  padding: 16px 14px 6px; margin-top: 8px; border-top: 1px solid var(--rule);
  background: var(--bg); font-family: var(--f-display); font-size: 17px;
  letter-spacing: -.02em; text-transform: capitalize;
}
.caletiqueta:first-of-type { margin-top: 0; border-top: 0; }
.calsemana { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.calcabecera {
  position: sticky; top: 0; z-index: 3; background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.calcabecera span {
  text-align: center; padding: 6px 0; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}
.calcelda {
  appearance: none; background: none; border: 0; font: inherit; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 9px 0 8px; min-width: 0;
}
.calcelda .num {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  font-family: var(--f-mono); font-size: 15px; line-height: 1;
}
.calcelda.hoy .num { color: var(--accent); font-weight: 700; }
.calcelda.elegido .num { background: var(--ink); color: var(--bg); }
.calcelda.hoy.elegido .num { background: var(--accent); color: #fff; }
.calcelda .puntos { display: flex; gap: 3px; height: 6px; }
.calcelda .puntos i {
  width: 6px; height: 6px; border-radius: 50%; display: block;
  border: 1.5px solid var(--ink-faint);
}
.calcelda .puntos i.lleno { background: var(--ink-faint); }
.calcelda .puntos i.k-sunday { border-color: var(--accent); }
.calcelda .puntos i.k-sunday.lleno { background: var(--accent); }
.calcelda .puntos i.k-youth { border-color: var(--warm); }
.calcelda .puntos i.k-youth.lleno { background: var(--warm); }
.calcelda .puntos i.k-prayer { border-color: var(--cold); }
.calcelda .puntos i.k-prayer.lleno { background: var(--cold); }

/* --- el día abierto --- */
.caldia {
  height: 58vh; min-height: 340px; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 2px;
}
.caldia > h4 {
  position: sticky; top: 0; z-index: 1; background: var(--bg);
  margin: 0; padding: 10px 0 8px; border-bottom: 1px solid var(--rule);
  font-family: var(--f-display); font-size: 12px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-faint);
}
.calev {
  display: grid; grid-template-columns: 58px 1fr; gap: 14px;
  padding: 12px 8px; border-bottom: 1px solid var(--rule);
  border-left: 3px solid transparent; text-decoration: none; color: inherit;
}
.calev:hover { background: var(--surface); }
.calev.k-sunday { border-left-color: var(--accent); }
.calev.k-youth  { border-left-color: var(--warm); }
.calev.k-prayer { border-left-color: var(--cold); }
.calev .hora { font-family: var(--f-mono); font-size: 13px; color: var(--ink-faint); }
.calev .cual { min-width: 0; }
.calev b { display: block; font-weight: 600; }
.calev ol { margin: 6px 0 0; padding-left: 20px; }
.calev ol li { font-size: 14px; padding: 2px 0; }
.calev ol li.cargando { list-style: none; margin-left: -20px; color: var(--ink-faint); }
.calev .falta { display: block; margin-top: 4px; font-size: 14px; color: var(--warm); }
.calnada {
  padding: 16px 8px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  color: var(--ink-faint); font-size: 14px;
}

/* En estrecho el día se convierte en una hoja pegada al borde de abajo: así
   sigue a la vista sin tener que desplazar la página. `dvh` y no `vh` porque
   en el móvil la barra del navegador aparece y desaparece, y con `vh` la hoja
   se quedaba justo por debajo del borde. */
@media (max-width: 900px) {
  .callupa { grid-template-columns: minmax(0, 1fr); padding-bottom: 8px; }
  .calscroll { height: 48dvh; min-height: 230px; }
  .calmeses { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .caldia {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    height: auto; min-height: 0; max-height: 46dvh;
    padding: 0 16px 16px; background: var(--bg);
    border-top: 1px solid var(--rule); border-radius: 14px 14px 0 0;
    box-shadow: 0 -10px 30px rgba(20, 16, 12, .16);
  }
  .caldia > h4 { padding: 14px 0 8px; }
}
@media (max-width: 620px) {
  .calmeses { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .calcelda .num { width: 30px; height: 30px; font-size: 14px; }
  .calev { grid-template-columns: 50px 1fr; gap: 10px; }
}

/* ------------------------------------------------------ filas de usuario */
.userrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 12px 10px; border-bottom: 1px solid var(--rule);
}
.userrow:hover { background: var(--surface); }
.userrow .tt { flex: 1 1 190px; min-width: 0; }
.userrow .tt b { font-family: var(--f-display); font-size: 16px; }
.userrow .tt small { display: block; color: var(--ink-faint); font-size: 13px; }

/* --------------------------------------------------------------- set list */
.setlist { border-top: 1px solid var(--rule); }
.setrow {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 10px; border-bottom: 1px solid var(--rule); background: var(--bg);
}
.setrow:hover { background: var(--surface); }
.setrow.dragging { opacity: .4; }
.setrow.over { box-shadow: inset 0 2px 0 var(--accent); }
.setrow[draggable="true"] { cursor: grab; }
.setrow .pos {
  width: 28px; height: 28px; flex: none; display: grid; place-items: center;
  background: var(--ink); color: var(--bg); border-radius: 50%;
  font-family: var(--f-mono); font-size: 13px; font-weight: 700;
}
.setrow .tt { flex: 1 1 220px; min-width: 0; }
.setrow .tt b { font-family: var(--f-display); font-size: 16px; letter-spacing: -.01em; }
.setrow .iconbtn { width: 34px; height: 34px; font-size: 14px; }

.picker { display: flex; flex-direction: column; margin-top: 8px; }
.pickitem {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  padding: 10px 12px; border: 1px solid var(--rule); border-top: 0;
  background: var(--surface); cursor: pointer; text-align: left;
}
.pickitem:first-child { border-top: 1px solid var(--rule); }
.pickitem:hover { background: var(--accent-soft); }
.pickitem b { font-family: var(--f-display); font-size: 15px; font-weight: 700; }
.pickitem span { color: var(--ink-faint); font-family: var(--f-mono); font-size: 12px; }

.livebar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 14px; margin: 0 0 14px;
  background: var(--accent-soft); border-left: 3px solid var(--accent);
  border-radius: var(--r); font-size: 15px;
}
.livebar span { flex: 1; }

/* Dudas pendientes de la hoja de papel: a la vista del músico pero sin
   gritar, con el mismo filo que los avisos en vivo pero en tono apagado. */
.review {
  margin: 0 0 14px; padding: 10px 14px; border-left: 3px solid var(--ink-faint);
  background: var(--surface); border-radius: var(--r); font-size: 14.5px;
}
.review h5 {
  margin: 0 0 6px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft);
}
.review .rv { display: flex; align-items: flex-start; gap: 12px; padding: 6px 0; }
.review .rv + .rv { border-top: 1px solid var(--rule); }
.review .rv p { flex: 1; margin: 0; min-width: 0; line-height: 1.45; }
.review .rv .btn { flex: none; }
/* La canción entera sin revisar: el mismo cajón, con el filo en ámbar. */
.review.pendbox { border-left-color: var(--warm); }
@media (max-width: 700px) {
  .review .rv { flex-direction: column; gap: 6px; }
}

.dropzone {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 22px; border: 2px dashed var(--rule); border-radius: var(--r);
  background: var(--surface); max-width: 620px;
}
.dropzone.over { border-color: var(--accent); background: var(--accent-soft); }
.dropzone.busy { opacity: .5; pointer-events: none; }
.dropzone b { font-family: var(--f-display); font-size: 16px; }
.dropzone .hint { margin: 0; }

.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  background: var(--ink); color: var(--bg); padding: 12px 22px; border-radius: var(--r);
  font-size: 15px; z-index: 90; box-shadow: 0 6px 30px rgba(0,0,0,.25);
}
.toast.err { background: var(--accent); color: #fff; }

/* ------------------------------------------------------- modo escenario */
body.stage-on { overflow: hidden; }
body.stage-on .topbar { display: none; }
body.stage-on .wrap { max-width: none; padding: 0; }

/* El aspecto del escenario: fondo y letra los elige cada persona en el
   Perfil. Van en variables y no escritos en cada regla porque la muestra del
   Perfil usa las mismas: lo que se ve allí es exactamente lo que sale aquí.
   Lo de serie es lo de siempre, negro y letra hueso, que se lee con la luz
   que haya. No depende del tema claro/oscuro del resto de la aplicación.
   Cada fondo tiene sus acordes y apuntes a medida, todos con un contraste de
   4,5:1 o más (la letra, de 12:1 para arriba). */
.stage-look {
  --st-bg: #080807; --st-ink: #F4F1E9; --st-chord: #FF8A6B; --st-shape: #7C766B;
  --st-sec: #8A857A; --st-rule: #2A2724; --st-chorus: #E4705A;
  --st-note: #FFAF9B; --st-note-line: rgba(255, 138, 107, .3);
  --st-bar: rgba(12, 11, 10, .96); --st-bar-line: #322E29; --st-hover: #2A2724;
  --st-muted: #8A857A; --st-hint: #6B665C; --st-shadow: rgba(0, 0, 0, .45);
  --st-pop: rgba(26, 25, 23, .92);
  --st-font: var(--f-body);
  --st-weight: 400; --st-note-weight: 400;
}
/* Papel: el crema de la carpeta de hojas impresas. */
.stage-look[data-look="paper"] {
  --st-bg: #F6EEDD; --st-ink: #221D18; --st-chord: #A3361A; --st-shape: #6F6455;
  --st-sec: #6F6455; --st-rule: #DCCFB6; --st-chorus: #B8502C;
  --st-note: #8C3D20; --st-note-line: rgba(163, 54, 26, .3);
  --st-bar: rgba(239, 229, 208, .97); --st-bar-line: #D6C8AC; --st-hover: #E4D8BF;
  --st-muted: #6F6455; --st-hint: #8F8371; --st-shadow: rgba(80, 60, 30, .18);
  --st-pop: rgba(255, 250, 240, .95);
}
.stage-look[data-look="white"] {
  --st-bg: #FFFFFF; --st-ink: #1A1A1A; --st-chord: #B0351A; --st-shape: #666666;
  --st-sec: #666666; --st-rule: #E2E2E2; --st-chorus: #C2492A;
  --st-note: #97391D; --st-note-line: rgba(176, 53, 26, .3);
  --st-bar: rgba(246, 246, 246, .97); --st-bar-line: #DDDDDD; --st-hover: #EAEAEA;
  --st-muted: #666666; --st-hint: #8A8A8A; --st-shadow: rgba(0, 0, 0, .12);
  --st-pop: rgba(255, 255, 255, .95);
}
.stage-look[data-look="gray"] {
  --st-bg: #E8E8E5; --st-ink: #1C1C1B; --st-chord: #9E3216; --st-shape: #5B5B58;
  --st-sec: #5B5B58; --st-rule: #CFCFCB; --st-chorus: #B5462A;
  --st-note: #86361B; --st-note-line: rgba(158, 50, 22, .3);
  --st-bar: rgba(222, 222, 219, .97); --st-bar-line: #C8C8C4; --st-hover: #D6D6D2;
  --st-muted: #5B5B58; --st-hint: #7E7E7A; --st-shadow: rgba(0, 0, 0, .12);
  --st-pop: rgba(240, 240, 238, .95);
}
.stage-look[data-look="graphite"] {
  --st-bg: #2A2C2E; --st-ink: #EEEEEC; --st-chord: #FFA486; --st-shape: #A4A6A8;
  --st-sec: #A9ABAD; --st-rule: #3E4144; --st-chorus: #F08A6C;
  --st-note: #FFC6AE; --st-note-line: rgba(255, 164, 134, .35);
  --st-bar: rgba(35, 37, 39, .97); --st-bar-line: #3E4144; --st-hover: #3A3D40;
  --st-muted: #A9ABAD; --st-hint: #85888B; --st-shadow: rgba(0, 0, 0, .35);
  --st-pop: rgba(20, 21, 22, .92);
}
.stage-look[data-look="navy"] {
  --st-bg: #15203A; --st-ink: #EEF2F8; --st-chord: #FFB870; --st-shape: #9AA7C0;
  --st-sec: #9EABC4; --st-rule: #2A3858; --st-chorus: #F2A65A;
  --st-note: #FFD3A1; --st-note-line: rgba(255, 184, 112, .35);
  --st-bar: rgba(17, 26, 48, .97); --st-bar-line: #2A3858; --st-hover: #22304F;
  --st-muted: #9EABC4; --st-hint: #7886A3; --st-shadow: rgba(0, 0, 0, .4);
  --st-pop: rgba(12, 19, 36, .92);
}
/* Las letras. Todas tienen el cirílico completo (también ґ, є, ї, ё) y lo
   que hace falta en español (ñ, tildes).
   · «Як у папці» y «Простий» son del propio dispositivo.
   · Rubik, Montserrat y Roboto Slab vienen de Google Fonts y el service
     worker las guarda la primera vez, así que también van sin wifi. Se
     eligieron para leer de lejos: trazo firme y letra abierta. Las tres
     tienen todos los grosores, de fino a muy grueso.
   Si una letra no estuviera, sale la siguiente de la lista: nunca un hueco. */
.stage-look[data-font="book"] {
  --st-font: "Times New Roman", Times, "Liberation Serif", "Noto Serif", serif;
}
.stage-look[data-font="sans"] {
  --st-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.stage-look[data-font="rubik"] { --st-font: "Rubik", system-ui, sans-serif; }
.stage-look[data-font="wide"] { --st-font: "Montserrat", Verdana, system-ui, sans-serif; }
.stage-look[data-font="slab"] { --st-font: "Roboto Slab", Rockwell, Georgia, serif; }
/* El grosor: un trazo fino, a un metro del atril, se pierde. Los apuntes
   suben un poco menos: siguen siendo apuntes, no letra que cantar. */
.stage-look[data-weight="semi"] { --st-weight: 600; --st-note-weight: 500; }
.stage-look[data-weight="bold"] { --st-weight: 800; --st-note-weight: 600; }

.stage {
  position: fixed; inset: 0; z-index: 60;
  background: var(--st-bg); color: var(--st-ink);
  display: flex; flex-direction: column;
}
.stage-page {
  flex: 1; overflow-y: auto; padding: 30px 34px 120px;
  scrollbar-width: none;
  /* Un dedo desplaza la letra como siempre; los dos dedos los recoge el
     programa para cambiar el tamaño en vez de ampliar la pantalla. */
  touch-action: pan-y;
}
.stage-page::-webkit-scrollbar { display: none; }
.stage-title {
  font-family: var(--f-display); font-weight: 900; letter-spacing: -.03em;
  font-size: clamp(22px, 3vw, 34px); margin-bottom: 22px; color: var(--st-ink);
}
.stage-sheet { max-width: none; column-gap: 46px; font-family: var(--st-font); }
.stage-sheet .sec > h4 { color: var(--st-sec); }
.stage-sheet .sec > h4::after { background: var(--st-rule); }
.stage-sheet .sec.chorus { border-left-color: var(--st-chorus); }
.stage-sheet .ck > i { color: var(--st-chord); }   /* acordes bien separados de la letra */
.stage-sheet .ck > i em { color: var(--st-shape); }
/* Los apuntes, en el atril: se leen a un metro y con media luz o no sirven. */
.stage-sheet .line .cmt { color: var(--st-note); opacity: .9; }
.stage-sheet .line.note .cmt { border-left-color: var(--st-note-line); }
.stage-sheet .ck > s { font-weight: var(--st-weight); }
.stage-sheet .line .cmt { font-weight: var(--st-note-weight); }
.stage-sheet .sec { break-inside: avoid-column; }

/* Barra al pie, de lado a lado. Antes era un recuadro flotando en el centro
   y tapaba justo la letra que se estaba cantando. Abajo, además, cae donde
   está el pulgar. Si no caben todos los mandos, la barra se desplaza a lo
   ancho en vez de partirse en varias filas.
   Centrada con márgenes automáticos y NO con justify-content: center. Con
   center, cuando la barra no cabe (cualquier móvil en vertical) se sale por
   los dos lados, y lo de la izquierda —salir, anterior y el contador— queda
   fuera de la pantalla sin forma de llegar: solo se puede desplazar hacia la
   derecha. Los márgenes automáticos centran si sobra sitio y se quedan en
   cero si falta, así que entonces la barra empieza por la izquierda. */
.stage-bar {
  position: absolute; left: 0; right: 0; bottom: 0; transform: none;
  display: flex; align-items: center; gap: 4px; flex-wrap: nowrap;
  justify-content: flex-start; overflow-x: auto; scrollbar-width: none;
  background: var(--st-bar); border-top: 1px solid var(--st-bar-line);
  border-radius: 0; max-width: none;
  padding: 6px 10px calc(6px + env(safe-area-inset-bottom, 0px));
  transition: opacity .35s; box-shadow: 0 -10px 30px var(--st-shadow);
}
.stage-bar::-webkit-scrollbar { display: none; }
.stage-bar > * { flex: none; }
.stage-bar > :first-child { margin-left: auto; }
.stage-bar > :last-child { margin-right: auto; }
.stage-bar.away { opacity: 0; pointer-events: none; }
.stage-bar button {
  min-width: 44px; height: 44px; padding: 0 10px; cursor: pointer;
  background: none; border: 0; color: var(--st-ink); font-size: 17px; border-radius: 5px;
}
.stage-bar button:hover { background: var(--st-hover); }
.stage-bar .chordsw.off { color: var(--st-muted); }
.stage-bar b {
  font-family: var(--f-mono); color: var(--st-chord); font-size: 17px;
  min-width: 46px; text-align: center;
}
.stage-bar .sep { width: 1px; height: 26px; background: var(--st-bar-line); margin: 0 6px; }
.stage-count { font-family: var(--f-mono); font-size: 13px; color: var(--st-muted); min-width: 54px;
               text-align: center; }
/* El tamaño mientras se pellizca: aparece, se lee y se va solo. */
.stage-size {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 70; padding: 10px 18px; border-radius: 8px;
  background: var(--st-pop); color: var(--st-ink);
  font-family: var(--f-mono); font-size: 26px; font-weight: 700;
  font-variant-numeric: tabular-nums; pointer-events: none;
  opacity: 0; transition: opacity .18s ease;
}
.stage-size.on { opacity: 1; }

.stage-hint {
  position: absolute; left: 0; right: 0; top: 12px; text-align: center;
  font-size: 12px; color: var(--st-hint); transition: opacity .35s; pointer-events: none;
}
.stage-hint.away { opacity: 0; }

/* --- Perfil: el aspecto del escenario, con su muestra. La muestra lleva las
   mismas clases y variables que el escenario de verdad. --- */
.stage-preview {
  background: var(--st-bg); color: var(--st-ink);
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: 14px 18px 18px; margin: 4px 0 16px; overflow: hidden;
  transition: background-color .2s, color .2s;
}
.stage-preview .stage-title { font-size: 20px; margin-bottom: 0; }
.stage-preview .sheet { --lyr: 23px; }
.stage-preview .sec { margin-top: 12px; }
.lookpick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.lookpick button {
  position: relative; min-height: 66px; padding: 6px 4px; cursor: pointer;
  background: var(--st-bg); color: var(--st-ink);
  border: 1px solid var(--rule); border-radius: var(--r);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
}
.lookpick button b {
  font-family: var(--st-font); font-size: 21px; line-height: 1; font-weight: var(--st-weight);
}
.lookpick button i {
  font-family: var(--f-mono); font-style: normal; font-weight: 700; font-size: 12px;
  color: var(--st-chord);
}
.lookpick button small { font-size: 12px; line-height: 1.2; color: var(--st-muted); }
.lookpick button[aria-checked="true"] { outline: 3px solid var(--accent); outline-offset: 2px; }
.lookpick button[aria-checked="true"]::after {
  content: "✓"; position: absolute; top: 3px; right: 7px;
  font-size: 14px; font-weight: 700; color: var(--st-chord);
}
/* Cada letra, escrita en ella misma, pero siempre con trazo normal: en
   negrita y a lo ancho de un móvil, «Звичайний» se partía por la mitad. Las
   palabras solo se cortan entre palabra y palabra. */
.fontpick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.fontpick button {
  min-height: var(--tap); padding: 6px 6px; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r);
  font-family: var(--st-font); font-weight: 400; font-size: 15px; line-height: 1.2;
  overflow-wrap: normal;
}
/* El grosor: un «Аа» grande con ese trazo, en la letra elegida, y el nombre
   debajo en pequeño y normal, que así cabe siempre. */
.fontpick.weights button {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
}
.fontpick.weights button b { font-size: 22px; line-height: 1.1; font-weight: var(--st-weight); }
.fontpick.weights button small { font-family: var(--f-body); font-size: 12px; color: var(--ink-faint); }
.fontpick button[aria-checked="true"] {
  border-color: var(--accent); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
}

@media (max-width: 700px) {
  .stage-page { padding: 18px 16px 110px; }
  .stage-bar { gap: 2px; padding: 6px 8px calc(6px + env(safe-area-inset-bottom, 0px)); }
  .stage-bar button { min-width: 40px; height: 42px; padding: 0 6px; font-size: 15px; }
  .stage-bar .sep { margin: 0 3px; }
  .stage-hint { display: none; }
}

/* -------------------------------------------------------------- móvil */
/* ------------------------------- tablet en vertical y móvil (hasta 900 px)
   La tablet en vertical mide 800 px: cabe una lista completa, pero NO la
   cabecera con todo (logo, nombre, cuatro secciones y los ajustes). Por eso
   la navegación, la cabecera y la barra de controles se compactan ya aquí,
   y no solo en el móvil. */
@media (max-width: 900px) {
  .cols { flex-direction: column; }
  .sidecar { width: 100%; }
  .edgrid { grid-template-columns: 1fr; }
  .droplang .txt { display: none; }
  .droplang .x { display: inline; font-size: 17px; }

  /* En el móvil no caben cabecera y navegación completas. Se quedan los
     enlaces que funcionan; los de las fases siguientes se esconden hasta
     que existan (entonces pasarán a una barra inferior). */
  .nav a.dim { display: none; }
  .nav a { padding: 9px 10px; font-size: 14px; }
  .brand b { display: none; }
  .topbar-in { gap: 10px; padding: 10px 14px; }

  /* --- la barra de la canción, compacta ---
     En el móvil ocupaba media pantalla antes de llegar a la letra. Se queda a
     la vista lo que se toca cantando (el tono) y lo demás se despliega con
     el botón «⋯»: la cejilla, la notación y el tamaño se eligen una vez, no
     en mitad de un culto. */
  .ctrl { gap: 6px; padding: 8px 0; }
  .ctrl .grp .lbl { display: none; }
  .ctrl .grp button { width: 40px; height: 40px; font-size: 16px; }
  .ctrl .grp .val { min-width: 44px; height: 40px; line-height: 40px; font-size: 15px; }
  .ctrl .grp select { height: 40px; padding: 0 4px; font-size: 14px; }
  .ctrl .btn { height: 40px; padding: 0 12px; font-size: 15px; }
  .ctrl .btn .txt { display: none; }          /* solo el icono */
  .ctrl .spacer { display: none; }
  .ctrl .more { display: grid; width: 40px; height: 40px; }
  .ctrl .grp.extra { display: none; }
  .ctrl.open .grp.extra { display: flex; }
  .ctrl.open .btn .txt { display: inline; }   /* desplegada, con sus nombres */

  /* En el móvil la cabecera no da para todo. Arriba se queda la identidad y
     los ajustes; la navegación baja al pie, al alcance del pulgar, que es
     como se usa de pie y con una mano. */
  .whoname { display: none; }
  .who { padding-left: 8px; border-left: 0; }

  .nav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; margin: 0;
    background: var(--bg); border-top: 1px solid var(--rule);
    display: flex; gap: 0;
    padding: 0 4px env(safe-area-inset-bottom, 0px);
  }
  .nav a {
    flex: 1; text-align: center; padding: 13px 4px; font-size: 12px;
    border-radius: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .nav a.on {
    background: none; color: var(--accent); font-weight: 600;
    box-shadow: inset 0 -3px 0 var(--accent);
  }
  .wrap { padding-bottom: 96px; }
}
@media (max-width: 700px) {
  /* --- la fila, en dos líneas ---
     Antes se escondían los idiomas y la última vez que se cantó, que es
     justo lo que hace útil la lista: saber en qué idioma existe y si se
     cantó el domingo pasado. Ahora bajan a una segunda línea. */
  .row {
    grid-template-columns: 34px 1fr auto;
    grid-template-areas: "num title key" ". meta meta";
    gap: 2px 10px; padding: 10px;
  }
  .row .num { grid-area: num; }
  .row .tt { grid-area: title; }
  .row .key { grid-area: key; min-width: 0; text-align: right; }
  .row .rowmeta {
    grid-area: meta; display: flex; align-items: center; gap: 10px;
    flex-wrap: wrap; min-width: 0;
  }
  .row .key, .row .last { order: 0; }        /* aquí manda la rejilla */
  .row .last { min-width: 0; justify-content: flex-start; font-size: 12px; }
  .row .lg { padding: 2px 5px; font-size: 10px; }
  .tt small {
    display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* la leyenda de colores, en una línea */
  .legend { gap: 10px; font-size: 11.5px; margin: 12px 0 6px; }
  .legend .dot { width: 8px; height: 8px; }
  .wrap { padding: 18px 14px 80px; }

  /* --- cabecera de la canción: cuanto más baja, más letra se ve ---
     Se queda el título y el número. El autor, las etiquetas y el tono de la
     iglesia se consultan en la ficha con calma, no de pie y cantando; el tono
     que importa está en grande en la barra, justo debajo. */
  .songhead { gap: 8px; }
  .songhead h1 { font-size: 22px; line-height: 1.15; margin: 0 0 4px; }
  .meta { font-size: 13px; gap: 10px; }
  .meta .m-author, .meta .m-key, .meta .m-tags { display: none; }
  .langtabs { margin-top: 12px; }
  .langtabs button { padding: 8px 14px; font-size: 15px; }

  /* el mes entero no cabe: se ven los días con contenido, sin cuadrícula */
  .calmonth { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  .calday { min-height: 62px; padding: 4px 4px 4px; font-size: 12px; }
  .calday .addday { display: none; }
  .ev b { font-size: 11px; }
  .ev small { display: none; }
  .weekrow { grid-template-columns: 84px 1fr; gap: 10px; }
  .weekrow .wev .ev { min-width: 0; }
}

/* ------------------------------------------------------- vista de impresión */
.printbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 0 0 16px; border-bottom: 1px solid var(--rule); margin-bottom: 22px;
}
.printbar .lbl { font-size: 13px; color: var(--ink-faint); }
.printbar .hint { font-size: 13px; color: var(--ink-faint); max-width: 320px; }

.printdoc { max-width: 900px; }
.printhead {
  font-family: var(--f-display); font-weight: 900; font-size: 24px;
  letter-spacing: -.03em; margin: 0 0 24px;
}
.printsong { margin-bottom: 34px; }
.printtitle {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  border-bottom: 1px solid var(--rule); padding-bottom: 6px; margin-bottom: 12px;
}
.printtitle b { font-family: var(--f-display); font-weight: 700; font-size: 19px; }
.printtitle span { color: var(--ink-faint); font-size: 13px; }
.printlangs { display: grid; gap: 26px; align-items: start; }
.printlang {
  font-family: var(--f-display); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px;
}
.printsheet { font-size: var(--print-size, 12pt); max-width: none; }
.printdoc.no-chords .ck > i { display: none; }
.printdoc.no-chords .line { margin-bottom: 1px; }

/* ------------------------------------------------------------ impresión */
@media print {
  .topbar, .ctrl, .langtabs, .sidecar, .legend, .searchrow, .tags, .gpanel,
  .toast, .printbar, .livebar, .nav, .stage-bar, .stage-hint { display: none !important; }

  body { background: #fff; color: #000; font-size: 12pt; }
  .wrap { max-width: none; padding: 0; }
  .sheet { font-size: 12pt; max-width: none; }
  .ck > i { color: #000; font-weight: 700; }
  .ck > i em { color: #555; }
  /* En papel no hay color de acento que valga: los apuntes se distinguen por
     la cursiva y, si van en su línea, por la barra del margen. */
  .line .cmt { color: #000; opacity: 1; }
  .line.note .cmt { border-left-color: #999; }
  .sec { break-inside: avoid; }          /* una estrofa no se parte entre páginas */
  .songhead h1 { font-size: 20pt; }
  .printsheet { font-size: var(--print-size, 12pt); }
  .printsong { margin-bottom: 0; }
  .printsong.breakafter { break-after: page; }
  .printtitle { border-bottom: 1px solid #000; }
  .sec.chorus { border-left: 2px solid #000; }
  a { text-decoration: none; color: #000; }

  @page { margin: 14mm 12mm; }
}

/* ---------------------------------------------- elegir acorde de una lista
   Escribir «F#m7» a mano en el móvil es lento y se cuela una errata que luego
   no suena a nada. Arriba, de un toque, los siete de la tonalidad y los que
   la canción ya usa —que es lo que hace falta casi siempre—; debajo, la
   rejilla completa para lo que se salga de ahí. */
.chorddlg { width: min(460px, 100%); }
.chordhead {
  font-family: var(--f-display); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint); margin: 16px 0 7px;
}
.chordhead:first-of-type { margin-top: 0; }
.chordrow { display: flex; flex-wrap: wrap; gap: 6px; }
.chordrow + .chordrow { margin-top: 6px; }
.chordchip {
  min-width: 46px; height: 40px; padding: 0 10px; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r);
  font-family: var(--f-mono); font-size: 15px;
}
.chordchip:hover { background: var(--surface-2); }
/* El elegido de la rejilla va marcado; los de arriba no se marcan porque se
   ponen en el mismo toque, no hay estado que enseñar. */
.chordchip.on { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.chordchip.qual { font-size: 14px; min-width: 40px; }
.chordbass {
  display: flex; align-items: center; gap: 8px; margin-top: 12px;
  font-size: 14px; color: var(--ink-faint);
}
.chordbass select {
  height: 36px; padding: 0 8px; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--r);
}
/* El botón de poner enseña el acorde que va a meter: es la única confirmación
   de que lo elegido es lo que se quería. */
.chordnow { font-family: var(--f-mono); font-weight: 700; }

/* Tu propia cuenta, en la lista de usuarios: «activo» como texto y no como
   botón, porque desactivarse uno mismo te deja fuera sin poder volver. */
.selfactive {
  display: inline-flex; align-items: center; height: 36px; padding: 0 12px;
  font-size: 14px; color: var(--ink-faint); cursor: help;
}
.userrow select:disabled { opacity: .6; cursor: not-allowed; }
