/* La aplicación, a partir del "sí": blanca y en calma.
   Misma paleta que la declaración (base.css), pero de día desde el principio.

   Los tamaños siguen la misma idea que la escena: mínimo pensado para el móvil
   —donde ya estaba bien— y un techo generoso, con vw y vh mezclados para que la
   letra crezca con la pantalla y no con uno solo de sus dos lados. */

body.dia {
  --fondo: var(--marfil);
  --texto: var(--tinta-oscura);
  --texto-tenue: var(--tinta-oscura-tenue);
  --linea: #e6dfd2;
  --linea-fuerte: #cfc5b2;
  --papel: #ffffff;
  --sombra: 0 1px 2px rgba(58, 56, 51, 0.04), 0 8px 28px rgba(58, 56, 51, 0.06);

  min-height: 100%;
  background: var(--marfil);
  color: var(--tinta-oscura);
  font-size: clamp(1rem, 0.42vw + 0.72vh, 1.25rem);
  line-height: 1.6;
}

.hoja {
  width: min(40rem, 92vw);
  margin: 0 auto;
  padding: max(2rem, env(safe-area-inset-top)) 0 max(3.5rem, env(safe-area-inset-bottom));
}

.hoja--ancha {
  width: min(52rem, 94vw);
}

/* ── Cabecera ─────────────────────────────────────────────────────────────── */

.encabezado {
  margin: 0 0 1.6em;
  text-align: center;
}

.encabezado__ojo {
  margin: 0 0 0.5em;
  font-family: var(--letra-serif);
  font-size: 0.82em;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.encabezado h1 {
  margin: 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 1.5vw + 1.9vh, 3rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
}

.encabezado p {
  margin: 0.7em auto 0;
  max-width: 32em;
  color: var(--texto-tenue);
}

/* ── Tarjetas ─────────────────────────────────────────────────────────────── */

.tarjeta {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: 18px;
  padding: 1.5em 1.4em;
  box-shadow: var(--sombra);
}

.tarjeta + .tarjeta {
  margin-top: 1em;
}

.tarjeta h2 {
  margin: 0 0 0.35em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.3em;
}

.tarjeta p {
  margin: 0 0 0.8em;
  color: var(--texto-tenue);
}

.tarjeta p:last-child {
  margin-bottom: 0;
}

/* Una tarjeta que es un enlace entero. */
a.tarjeta {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 220ms ease, transform 220ms ease;
}

a.tarjeta:hover,
a.tarjeta:focus-visible {
  border-color: var(--linea-fuerte);
  transform: translateY(-1px);
}

/* ── Formularios ──────────────────────────────────────────────────────────── */

.campo {
  display: block;
  margin: 0 0 1.15em;
}

.campo__nombre {
  display: block;
  margin: 0 0 0.35em;
  font-size: 0.92em;
  letter-spacing: 0.02em;
  color: var(--texto);
}

.campo__ayuda {
  display: block;
  margin: 0.4em 0 0;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

input[type="text"],
input[type="email"],
input[type="date"],
input[type="time"],
input[type="tel"],
input[type="password"],
select,
textarea {
  display: block;
  width: 100%;
  padding: 0.72em 0.85em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 12px;
  background: var(--papel);
  color: var(--texto);
  font-family: var(--letra-sans);
  font-weight: 300;
  /* 16px como mínimo: por debajo de eso, Safari en el iPhone hace zoom solo al
     tocar el campo y descoloca la página entera. */
  font-size: max(16px, 1em);
  line-height: 1.4;
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--linea-fuerte);
  outline-offset: 1px;
}

input[readonly] {
  background: #f7f4ee;
  color: var(--texto-tenue);
}

/* El código de 6 dígitos: grande y espaciado, que se vea lo que se escribe. */
.codigo input {
  text-align: center;
  font-size: max(24px, 1.6em);
  letter-spacing: 0.42em;
  text-indent: 0.42em; /* compensa el hueco que el letter-spacing deja al final */
  font-weight: 400;
}

/* ── Botones ──────────────────────────────────────────────────────────────── */

.boton-app {
  display: inline-block;
  width: 100%;
  padding: 0.9em 1.6em;
  border: 1px solid var(--tinta-oscura);
  border-radius: 999px;
  background: var(--tinta-oscura);
  color: var(--marfil);
  font-family: var(--letra-sans);
  font-weight: 300;
  font-size: max(16px, 1em);
  letter-spacing: 0.08em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: opacity 220ms ease;
}

.boton-app:hover,
.boton-app:focus-visible {
  opacity: 0.86;
}

.boton-app--suave {
  background: transparent;
  color: var(--texto);
  border-color: var(--linea-fuerte);
}

.boton-app--pequeno {
  width: auto;
  padding: 0.6em 1.3em;
  font-size: 0.9em;
}

.botones {
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  margin-top: 1.4em;
}

@media (min-width: 34rem) {
  .botones--fila {
    flex-direction: row-reverse; /* la acción principal, a la derecha */
  }
  .botones--fila .boton-app {
    flex: 1;
  }
}

.enlace-suave {
  display: inline-block;
  margin-top: 1.6em;
  color: var(--texto-tenue);
  font-size: 0.9em;
  letter-spacing: 0.04em;
}

.pie-app {
  margin-top: 2.4em;
  text-align: center;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

.pie-app a {
  color: inherit;
}

/* ── Avisos ───────────────────────────────────────────────────────────────── */

.aviso {
  margin: 0 0 1.2em;
  padding: 0.9em 1.05em;
  border: 1px solid var(--linea-fuerte);
  border-left-width: 3px;
  border-radius: 12px;
  background: #fdfbf7;
  font-size: 0.95em;
}

.aviso--mal {
  border-color: #c9a99a;
  border-left-color: #b07a63;
  background: #fdf6f3;
}

.aviso--bien {
  border-color: #b9c3ac;
  border-left-color: #7d9166;
  background: #f7faf3;
}

/* ── La confirmación del correo (el salvavidas) ───────────────────────────── */

.correo-grande {
  margin: 1.1em 0;
  padding: 1.1em 0.8em;
  border: 1px dashed var(--linea-fuerte);
  border-radius: 14px;
  background: #fdfbf7;
  text-align: center;
  font-size: clamp(1.15rem, 0.9vw + 1.2vh, 1.8rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  word-break: break-all;
  line-height: 1.35;
}

/* ── El acta ──────────────────────────────────────────────────────────────── */

.acta {
  position: relative;
  background: var(--papel);
  border: 1px solid var(--linea-fuerte);
  border-radius: 6px;
  padding: 2.2em 1.5em 2em;
  box-shadow: var(--sombra);
}

/* El filete doble de los documentos serios. */
.acta::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid var(--linea);
  border-radius: 3px;
  pointer-events: none;
}

.acta__titulo {
  margin: 0;
  text-align: center;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 1.2vw + 1.7vh, 2.4rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.acta__subtitulo {
  margin: 0.5em 0 1.6em;
  text-align: center;
  font-family: var(--letra-serif);
  font-size: 0.9em;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.acta__regla {
  height: 1px;
  margin: 1.5em 0;
  border: 0;
  background: linear-gradient(90deg, transparent, var(--linea-fuerte), transparent);
}

.acta__parrafo {
  margin: 0 0 1em;
  text-align: justify;
  hyphens: auto;
}

.acta__clausula {
  margin: 0 0 0.85em;
  padding-left: 1.9em;
  text-indent: -1.9em;
}

.acta__clausula-num {
  font-family: var(--letra-serif);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* La casilla ya marcada. No es un control: es parte del texto del acta, y por
   eso no se puede desmarcar — ni con el dedo, ni con el teclado, ni quitándole
   el JavaScript. El valor viaja en un campo oculto. */
.casilla-fija {
  display: inline-block;
  width: 1.05em;
  height: 1.05em;
  margin-right: 0.5em;
  vertical-align: -0.15em;
  pointer-events: none;
}

.acta__firmas {
  display: grid;
  gap: 1.6em;
  margin-top: 1.8em;
}

@media (min-width: 34rem) {
  .acta__firmas {
    grid-template-columns: 1fr 1fr;
  }
}

.firma {
  text-align: center;
}

.firma__imagen {
  display: block;
  width: 100%;
  max-width: 15rem;
  height: 5.2rem;
  margin: 0 auto 0.4em;
  object-fit: contain;
}

.firma__vacia {
  display: block;
  height: 5.2rem;
  margin-bottom: 0.4em;
}

.firma__linea {
  margin: 0 auto;
  max-width: 15rem;
  border-top: 1px solid var(--linea-fuerte);
  padding-top: 0.5em;
  font-family: var(--letra-serif);
  font-size: 0.9em;
  letter-spacing: 0.06em;
}

.firma__pie {
  margin: 0.2em 0 0;
  font-size: 0.8em;
  color: var(--texto-tenue);
}

.sello {
  display: block;
  margin: 1.8em auto 0;
  width: 8.5rem;
  height: 8.5rem;
  opacity: 0.72;
}

/* ── El lienzo de la firma ────────────────────────────────────────────────── */

.firmario {
  margin: 0.4em 0 0;
  border: 1px solid var(--linea-fuerte);
  border-radius: 12px;
  background: var(--papel);
  overflow: hidden;
}

#firma {
  display: block;
  width: 100%;
  /* Proporción fija en vez de altura fija: así lo que se dibuja en pantalla y
     lo que se guarda como imagen tienen la misma forma y la firma no sale
     estirada de ancho. */
  aspect-ratio: 15 / 7;
  height: auto;
  /* El dedo firma; no arrastra la página. */
  touch-action: none;
  cursor: crosshair;
}

.firmario__pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8em;
  padding: 0.55em 0.7em;
  border-top: 1px solid var(--linea);
  background: #fdfbf7;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

.firmario__borrar {
  padding: 0.35em 0.9em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 999px;
  background: transparent;
  color: var(--texto);
  font-family: var(--letra-sans);
  font-size: 0.95em;
  cursor: pointer;
}

/* ── Sin JavaScript ───────────────────────────────────────────────────────── */

.sin-js-app {
  margin: 0 0 1.2em;
  padding: 0.9em 1.05em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 12px;
  background: #fdf6f3;
  font-size: 0.95em;
}

/* ── El espacio del servidor (solo en administración) ─────────────────────── */

.espacio {
  width: 100%;
  margin: 0.4em 0 1em;
  border-collapse: collapse;
  font-size: 0.95em;
}

.espacio th,
.espacio td {
  padding: 0.42em 0;
  text-align: left;
  font-weight: 300;
  border-bottom: 1px solid var(--linea);
}

.espacio th {
  color: var(--texto-tenue);
}

.espacio td:nth-child(2) {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.espacio td:nth-child(3) {
  width: 40%;
  padding-left: 1em;
  color: var(--texto-tenue);
  font-size: 0.9em;
  text-align: right;
}

.espacio__total th,
.espacio__total td {
  border-bottom: 0;
  color: var(--texto);
}

.barra {
  height: 8px;
  margin: 0.5em 0;
  border-radius: 999px;
  background: #ece6da;
  overflow: hidden;
}

.barra span {
  display: block;
  height: 100%;
  background: #8a8578;
  border-radius: 999px;
}

.barra--alerta span {
  background: #b07a63;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA CASA — la aplicación por dentro.

   Criterio, no negociable: esto es una casa, no una herramienta. Mucho aire,
   serif en los títulos, sin sombras duras, sin bordes marcados, sin colores de
   alerta. Si una pantalla parece un panel de administración, está mal hecha.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Navegación ──────────────────────────────────────────────────────────────
   Cuatro palabras y ni una más. Sin iconos: un icono pequeño repetido cuatro
   veces convierte una casa en un tablero de mandos, y además obliga a dibujar
   metáforas ("¿qué icono es «Rincón»?") que nunca se leen bien. */

.navegacion {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  justify-content: space-around;
  align-items: stretch;
  padding-bottom: env(safe-area-inset-bottom);
  background: color-mix(in srgb, var(--marfil) 88%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--linea);
  /* Para que vuelva sin dar un salto cuando se cierra el visor de una foto,
     que es lo único que la esconde. */
  opacity: 1;
  visibility: visible;
  transition: opacity 260ms ease, visibility 0s;
}

.navegacion__ir {
  flex: 1;
  padding: 1em 0.4em;
  text-align: center;
  text-decoration: none;
  color: var(--texto-tenue);
  font-family: var(--letra-sans);
  font-weight: 300;
  font-size: 0.86rem;
  letter-spacing: 0.14em;
  text-transform: lowercase;
  transition: color 300ms ease;
}

.navegacion__ir.es-actual {
  color: var(--texto);
}

/* El punto del sitio en el que estás. Un subrayado sería un borde marcado. */
.navegacion__ir.es-actual::after {
  content: "";
  display: block;
  width: 3px;
  height: 3px;
  margin: 0.5em auto 0;
  border-radius: 50%;
  background: currentColor;
}

.contenido {
  /* Sitio para la barra de abajo, que va fija. */
  padding-bottom: 5.5rem;
}

@media (min-width: 46rem) {
  .navegacion {
    position: static;
    justify-content: center;
    gap: 2.4rem;
    margin-bottom: 2.6rem;
    padding-bottom: 0;
    border-top: 0;
    border-bottom: 1px solid var(--linea);
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .navegacion__ir {
    flex: 0 0 auto;
    padding: 0 0 0.9em;
  }

  .contenido {
    padding-bottom: 2rem;
  }
}

/* ── El saludo ───────────────────────────────────────────────────────────────
   Sin caja y sin marco: es lo primero que se lee, no un widget. */

.saludo {
  margin: 0 0 2.4rem;
  text-align: center;
}

.saludo__hola {
  margin: 0;
  font-family: var(--letra-serif);
  font-weight: 300;
  font-size: clamp(1.6rem, 1.4vw + 1.9vh, 2.9rem);
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: var(--texto);
}

.saludo__dias {
  margin: 0.75em 0 0;
  font-size: 0.82em;
  letter-spacing: 0.16em;
  text-transform: lowercase;
  color: var(--texto-tenue);
}

/* ── Las tarjetas de la portada ─────────────────────────────────────────────
   Pocas y grandes, en una columna. En escritorio, dos columnas para aprovechar
   el ancho sin estirar los renglones de texto. */

.tarjetas {
  display: grid;
  gap: 1.1rem;
}

@media (min-width: 46rem) {
  .tarjetas {
    grid-template-columns: 1fr 1fr;
    gap: 1.3rem;
  }
  /* Los recuerdos, abajo del todo y a lo ancho: no son de uso diario. */
  .tarjetas > .tarjeta-grande--recuerdos {
    grid-column: 1 / -1;
  }
}

.tarjeta-grande {
  display: block;
  padding: 1.7em 1.5em;
  border: 1px solid var(--linea);
  border-radius: 20px;
  background: var(--papel);
  color: inherit;
  text-decoration: none;
  box-shadow: var(--sombra);
  transition: border-color 260ms ease, transform 260ms ease;
}

a.tarjeta-grande:hover,
a.tarjeta-grande:focus-visible {
  border-color: var(--linea-fuerte);
  transform: translateY(-1px);
}

.tarjeta-grande__ojo {
  margin: 0 0 0.55em;
  font-family: var(--letra-serif);
  font-size: 0.76em;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.tarjeta-grande__titulo {
  margin: 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.25rem, 0.7vw + 1.25vh, 1.7rem);
  line-height: 1.25;
}

.tarjeta-grande__texto {
  margin: 0.7em 0 0;
  color: var(--texto-tenue);
}

.tarjeta-grande__pie {
  display: block;
  margin: 1.1em 0 0;
  font-size: 0.86em;
  letter-spacing: 0.1em;
  color: var(--texto-tenue);
}

/* Lo que todavía no existe: se dice, sin disculpas y sin ruido. */
.tarjeta-grande--pendiente {
  border-style: dashed;
  background: none;
  box-shadow: none;
}

.tarjeta-grande--recuerdos {
  background: none;
  box-shadow: none;
  border-color: transparent;
  border-top: 1px solid var(--linea);
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
  margin-top: 1.4rem;
}

.recuerdos__enlaces {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem;
  margin-top: 1em;
}

.recuerdos__enlaces a {
  color: var(--texto);
  text-decoration: none;
  border-bottom: 1px solid var(--linea-fuerte);
  padding-bottom: 0.15em;
  font-size: 0.95em;
}

/* ── Las fotos que se asoman ─────────────────────────────────────────────── */

.asomo {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  margin: 1.1em 0 0;
}

.asomo img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 12px;
}

/* ── La línea de tiempo ──────────────────────────────────────────────────── */

.entrada {
  padding: 1.6em 0 1.9em;
  border-bottom: 1px solid var(--linea);
}

.entrada:last-child {
  border-bottom: 0;
}

.entrada__quien {
  margin: 0 0 0.9em;
  font-size: 0.84em;
  letter-spacing: 0.06em;
  color: var(--texto-tenue);
}

.entrada__fotos {
  display: grid;
  gap: 0.45rem;
  margin: 0 0 1em;
}

.entrada__fotos--1 { grid-template-columns: 1fr; }
.entrada__fotos--2 { grid-template-columns: 1fr 1fr; }
.entrada__fotos--muchas { grid-template-columns: repeat(3, 1fr); }

.entrada__fotos a {
  display: block;
}

.entrada__fotos img {
  display: block;
  width: 100%;
  border-radius: 14px;
  object-fit: cover;
}

.entrada__fotos--1 img { aspect-ratio: 4 / 3; }
.entrada__fotos--2 img,
.entrada__fotos--muchas img { aspect-ratio: 1; }

.entrada__texto {
  margin: 0 0 0.9em;
  white-space: pre-wrap;
}

.entrada__titulo {
  margin: 0 0 0.35em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.25em;
}

.entrada__acciones {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin-top: 0.6em;
}

/* El lirio: una sola reacción. Una sopa de emojis convierte un recuerdo en una
   publicación, y esto no es una red social. */
.lirio {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.35em 0.9em 0.35em 0.6em;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: none;
  color: var(--texto-tenue);
  font-family: var(--letra-sans);
  font-size: 0.9em;
  cursor: pointer;
  transition: border-color 260ms ease, color 260ms ease;
}

.lirio svg {
  width: 1.15em;
  height: 1.15em;
}

.lirio path,
.lirio circle {
  transition: fill 400ms ease, stroke 400ms ease;
}

.lirio.encendido {
  border-color: var(--linea-fuerte);
  color: var(--texto);
}

.lirio__cuenta {
  font-variant-numeric: tabular-nums;
}

.comentarios {
  margin-top: 1.2em;
}

.comentario {
  margin: 0 0 0.9em;
  padding-left: 0.9em;
  border-left: 1px solid var(--linea);
}

.comentario__quien {
  display: block;
  font-size: 0.8em;
  letter-spacing: 0.05em;
  color: var(--texto-tenue);
  margin-bottom: 0.2em;
}

.comentario__cuerpo {
  margin: 0;
  white-space: pre-wrap;
}

.comentario-nuevo {
  display: flex;
  gap: 0.6em;
  align-items: flex-start;
  margin-top: 1em;
}

.comentario-nuevo textarea {
  flex: 1;
  min-height: 2.6em;
  resize: vertical;
}

/* ── Subir algo ──────────────────────────────────────────────────────────── */

.elegir {
  display: block;
  padding: 1.6em 1.2em;
  border: 1px dashed var(--linea-fuerte);
  border-radius: 16px;
  text-align: center;
  color: var(--texto-tenue);
  cursor: pointer;
}

.elegir input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.elegidas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: 0.5rem;
  margin: 1em 0 0;
}

.elegidas figure {
  position: relative;
  margin: 0;
}

.elegidas img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 10px;
  opacity: 0.45;
  transition: opacity 500ms ease;
}

.elegidas figure.lista img {
  opacity: 1;
}

/* La barra de progreso: serena, sin porcentajes saltando ni colores de alerta. */
.progreso {
  height: 2px;
  margin: 1.4em 0 0.6em;
  border-radius: 999px;
  background: var(--linea);
  overflow: hidden;
}

.progreso span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--texto-tenue);
  transition: width 400ms ease;
}

.progreso__texto {
  margin: 0;
  text-align: center;
  font-size: 0.85em;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
}

/* ── Perfil ──────────────────────────────────────────────────────────────── */

.retrato {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-bottom: 1.4em;
}

.retrato img,
.retrato .retrato__hueco {
  width: 5.2rem;
  height: 5.2rem;
  border-radius: 50%;
  object-fit: cover;
  background: #f2ede3;
  flex: 0 0 auto;
}

.retrato__nombre {
  margin: 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.5em;
}

.retrato__quien {
  margin: 0.2em 0 0;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

.vacio {
  margin: 3rem 0;
  text-align: center;
  color: var(--texto-tenue);
}

.vacio__titulo {
  font-family: var(--letra-serif);
  font-size: 1.3em;
  color: var(--texto);
  margin: 0 0 0.4em;
}

/* ── La línea de tiempo por meses ────────────────────────────────────────────
   Encabezados grandes y serios, como la galería del teléfono: de un vistazo se
   sabe por dónde va uno sin leer ninguna fecha pequeña. */

.mes {
  margin: 2.6rem 0 0.2rem;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 1.1vw + 1.6vh, 2.3rem);
  letter-spacing: 0.01em;
  color: var(--texto);
}

.mes:first-of-type {
  margin-top: 1.4rem;
}

.anios {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin: 1.4rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--linea);
}

.anios a {
  color: var(--texto-tenue);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  font-size: 0.92em;
  letter-spacing: 0.06em;
}

.anios a:hover,
.anios a:focus-visible {
  color: var(--texto);
}

.atajos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 1.4rem 0 0;
}

.atajos .boton-app {
  width: auto;
  flex: 1 1 auto;
  padding: 0.7em 1.2em;
  font-size: 0.92em;
}

/* De dónde era esa hora. Solo sale cuando no fue en casa. */
.cuando__lugar {
  color: var(--texto-tenue);
  font-size: 0.94em;
}

/* ── Fotos que aparecen sin sobresaltos ─────────────────────────────────── */

.perezosa {
  opacity: 0;
  transition: opacity 500ms ease;
  background: #f2ede3;
}

.perezosa.cargada {
  opacity: 1;
}

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

/* ── La rejilla de la galería ────────────────────────────────────────────── */

.rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: 0.4rem;
  margin: 0.7rem 0 0;
}

@media (min-width: 46rem) {
  .rejilla {
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    gap: 0.5rem;
  }
}

.celda {
  position: relative;
  display: block;
  cursor: pointer;
}

.celda img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 10px;
  transition: opacity 500ms ease, transform 260ms ease;
}

/* La casilla no se ve; lo que se ve es la marca. Una casilla de sistema encima
   de cada foto convierte la galería en un formulario. */
.celda input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.celda__marca {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  width: 1.15rem;
  height: 1.15rem;
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: rgba(58, 56, 51, 0.18);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 240ms ease, background-color 240ms ease;
}

.celda:hover .celda__marca,
.celda input:focus-visible ~ .celda__marca {
  opacity: 0.75;
}

.celda input:checked ~ .celda__marca {
  opacity: 1;
  background: var(--tinta-oscura);
  border-color: var(--marfil);
}

.celda input:checked ~ .celda__marca::after {
  content: "";
  position: absolute;
  inset: 0;
  background: no-repeat center / 0.7rem
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4.5 10.4l3.4 3.4 7.6-8' fill='none' stroke='%23fbf9f6' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.celda input:checked ~ img {
  transform: scale(0.93);
}

.celda.es-portada img {
  outline: 2px solid var(--linea-fuerte);
  outline-offset: 2px;
}

/* ── La barra de selección ───────────────────────────────────────────────── */

.barra-seleccion {
  position: sticky;
  bottom: 5.2rem;
  z-index: 15;
  margin: 1.6rem 0 0;
  padding: 1em 1.1em;
  border: 1px solid var(--linea);
  border-radius: 18px;
  background: color-mix(in srgb, var(--papel) 94%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--sombra);
  opacity: 0;
  transform: translateY(0.5rem);
  pointer-events: none;
  transition: opacity 300ms ease, transform 300ms ease;
}

.barra-seleccion.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Sin JavaScript la barra tiene que verse siempre: si no, no habría forma de
   usarla. `:has` lo resuelve sin una línea de código. */
.barra-seleccion:has(:focus),
#galeria:has(input[name="media"]:checked) .barra-seleccion {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

@media (min-width: 46rem) {
  .barra-seleccion {
    bottom: 1.5rem;
  }
}

.barra-seleccion__cuenta {
  margin: 0 0 0.7em;
  font-family: var(--letra-serif);
  font-size: 1.05em;
}

.barra-seleccion__acciones {
  display: grid;
  gap: 0.7rem;
}

.barra-seleccion__acciones .campo {
  margin: 0;
}

@media (min-width: 40rem) {
  .barra-seleccion__acciones {
    grid-template-columns: 1fr 1fr auto;
    align-items: end;
  }
  .barra-seleccion__acciones .boton-app {
    width: auto;
  }
}

.dos-campos {
  display: grid;
  gap: 0.8rem;
}

@media (min-width: 34rem) {
  .dos-campos {
    grid-template-columns: 1fr 1fr;
  }
}

/* ── Álbumes ─────────────────────────────────────────────────────────────── */

.albumes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.album {
  display: block;
  color: inherit;
  text-decoration: none;
}

.album__portada {
  border-radius: 14px;
  overflow: hidden;
  background: #f2ede3;
}

.album__portada img,
.album__hueco {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.album__titulo {
  margin: 0.55em 0 0;
  font-family: var(--letra-serif);
  font-size: 1.05em;
}

.album__cuenta {
  margin: 0.15em 0 0;
  font-size: 0.84em;
  color: var(--texto-tenue);
}

/* ── Lo que se abre solo si hace falta ───────────────────────────────────── */

.corregir {
  margin: 1.6em 0 0;
  padding-top: 1.1em;
  border-top: 1px solid var(--linea);
}

.corregir summary {
  cursor: pointer;
  color: var(--texto-tenue);
  font-size: 0.9em;
  letter-spacing: 0.06em;
  list-style: none;
}

.corregir summary::-webkit-details-marker {
  display: none;
}

.corregir summary::before {
  content: "+ ";
}

.corregir[open] summary::before {
  content: "– ";
}

.corregir > form,
.corregir > p {
  margin-top: 1em;
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL REFUGIO

   Lo va a abrir de noche, con ansiedad y sin ganas de pensar. Todo lo de aquí
   sale de ahí: mucho aire, una sola cosa por pantalla, nada que se mueva
   deprisa y ni un color de alerta en toda la sección.

   Se anima SOLO transform y opacity —nunca width, height ni top— porque son
   las dos únicas propiedades que el navegador puede mover sin rehacer la
   página, y es lo que separa una animación fluida de una que se entrecorta
   justo cuando ella la necesita en calma.
   ═══════════════════════════════════════════════════════════════════════════ */

.refugio {
  margin: 0 auto;
  max-width: 34rem;
}

/* ── El frasco ───────────────────────────────────────────────────────────────
   Dibujado, como el sello del acta y el lirio. Un emoji de frasco cambia de
   forma y de color en cada teléfono, y aquí es lo primero que se ve. */

.frasco {
  display: block;
  width: 100%;
  height: auto;
}

.frasco path,
.frasco rect {
  fill: none;
  stroke: var(--linea-fuerte);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Los papelitos del fondo sí van rellenos: si no, se pierden entre las líneas
   del cristal y el frasco parece vacío. */
.frasco__papeles rect {
  fill: #f6f1e6;
  stroke-width: 1.2;
}

.frasco__tapa {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.frasco-cerrado,
.frasco-abierto {
  width: min(38vw, 7.5rem);
  margin: 0 auto 1.8rem;
  opacity: 0.9;
}

.frasco-abierto {
  width: min(30vw, 5.6rem);
  margin-bottom: 1.4rem;
}

/* Abierto: la tapa se queda a un lado. Es el estado, no la animación — al
   recargar la página el frasco sigue abierto, que es la verdad. */
.frasco-abierto .frasco__tapa {
  transform: translateY(-9px) rotate(-12deg);
}

/* ── La pregunta ─────────────────────────────────────────────────────────────
   Diez palabras y nada más. Sin caritas, sin iconos, sin numerar y sin
   «elige una opción»: eso es un cuestionario, y un cuestionario es justo lo
   que no se puede contestar a las tres de la mañana. */

.sentires {
  display: grid;
  gap: 0.15rem;
  margin-top: 0.6rem;
}

@media (min-width: 34rem) {
  .sentires {
    grid-template-columns: 1fr 1fr;
    gap: 0.3rem 1rem;
  }
}

.sentir {
  display: block;
  width: 100%;
  padding: 0.8em 0.7em;
  border: 0;
  border-radius: 14px;
  background: none;
  color: var(--texto);
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.3rem, 0.6vw + 1.2vh, 1.6rem);
  line-height: 1.3;
  text-align: center;
  cursor: pointer;
  transition: background-color 260ms ease, transform 260ms ease;
}

.sentir:hover,
.sentir:focus-visible {
  background: #f5f0e6;
}

.sentir:active {
  transform: scale(0.985);
}

/* ── El papelito ─────────────────────────────────────────────────────────── */

.papel {
  position: relative;
  margin: 0;
  padding: 2em 1.6em 1.7em;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel);
  box-shadow: var(--sombra);
  text-align: center;
}

/* El pliegue por donde venía doblado. Sin esto es una tarjeta; con esto es un
   papel que estaba guardado. */
.papel::before {
  content: "";
  position: absolute;
  left: 1.2em;
  right: 1.2em;
  top: 50%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--linea), transparent);
  opacity: 0.7;
  pointer-events: none;
}

.papel__texto {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: clamp(1.28rem, 0.85vw + 1.3vh, 1.85rem);
  line-height: 1.5;
  letter-spacing: 0.005em;
}

.papel__cita {
  margin: 1.2em 0 0;
  font-size: 0.8em;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

/* ── Su nota ─────────────────────────────────────────────────────────────── */

.nota {
  margin: 1.9rem 0 0;
  padding: 0 0.6rem;
  text-align: center;
}

.nota__texto {
  margin: 0;
  font-size: 1.02em;
  line-height: 1.75;
}

.nota__firma {
  margin: 0.6em 0 0;
  font-family: var(--letra-mano);
  font-size: 1.6em;
  line-height: 1;
  color: var(--texto-tenue);
}

/* ── El cierre: orar ─────────────────────────────────────────────────────────
   Va SIEMPRE y va el último. No es una sección más de la pantalla: es el final
   de la visita. */

.orar {
  margin: 2.2rem 0 0;
  padding-top: 1.7rem;
  border-top: 1px solid var(--linea);
  text-align: center;
}

.orar__invitacion {
  margin: 0 auto 1.1em;
  max-width: 26em;
  font-size: 0.92em;
  color: var(--texto-tenue);
}

.orar__oracion {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: clamp(1.12rem, 0.5vw + 1.1vh, 1.4rem);
  line-height: 1.95;
}

/* ── Guardar, pedir otro, y los enlaces de abajo ─────────────────────────── */

.refugio__acciones {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  margin: 2.2rem auto 0;
  max-width: 20rem;
}

.refugio__acciones form {
  width: 100%;
  text-align: center;
}

/* Un botón que no parece un botón. «Dame otro» y «olvidar este día» tienen que
   estar y no pesar: si pesan, pedir otro se siente como rechazar algo. */
.enlace-boton {
  padding: 0.3em 0.2em;
  border: 0;
  border-bottom: 1px solid transparent;
  background: none;
  color: var(--texto-tenue);
  font-family: var(--letra-sans);
  font-weight: 300;
  font-size: 0.9em;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: color 240ms ease, border-color 240ms ease;
}

.enlace-boton:hover,
.enlace-boton:focus-visible {
  color: var(--texto);
  border-bottom-color: var(--linea-fuerte);
}

.refugio__nota-pie {
  margin: 0.9rem 0 0;
  text-align: center;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

.refugio__aparte {
  margin: 2.6rem 0 0;
  text-align: center;
  font-size: 0.88em;
  color: var(--texto-tenue);
}

.refugio__aparte a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--linea);
  padding-bottom: 0.15em;
}

.refugio__aparte a:hover,
.refugio__aparte a:focus-visible {
  border-bottom-color: var(--linea-fuerte);
  color: var(--texto);
}

.refugio__punto {
  margin: 0 0.75em;
  opacity: 0.45;
}

.encabezado__ojo--solo {
  margin: 0 0 1.6em;
  text-align: center;
}

/* ── Los guardados ───────────────────────────────────────────────────────── */

.guardado {
  margin: 0 auto 1.6rem;
  max-width: 34rem;
  text-align: center;
}

.papel--guardado {
  padding: 1.5em 1.3em 1.3em;
}

.papel--guardado .papel__texto {
  font-size: clamp(1.1rem, 0.5vw + 1.05vh, 1.35rem);
}

.guardado form {
  margin-top: 0.5rem;
}

/* ── El historial ────────────────────────────────────────────────────────────
   Cerrado, sin números, sin gráficas y sin días seguidos. Que exista para
   cuando quiera mirarlo, y que no le salte a la cara cuando no. */

.discreto {
  margin: 2.8rem auto 0;
  max-width: 34rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--linea);
}

.discreto summary {
  list-style: none;
  cursor: pointer;
  text-align: center;
  color: var(--texto-tenue);
  font-size: 0.86em;
  letter-spacing: 0.12em;
}

.discreto summary::-webkit-details-marker {
  display: none;
}

.discreto__vacio {
  margin: 1.2rem 0 0;
  text-align: center;
  font-size: 0.9em;
  color: var(--texto-tenue);
}

.historial {
  margin: 1.4rem 0 0;
  padding: 0;
  list-style: none;
}

.historial__dia {
  padding: 0.75em 0;
  border-bottom: 1px solid var(--linea);
}

.historial__dia:last-child {
  border-bottom: 0;
}

.historial__cuando {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: 1.05em;
}

.historial__que {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0.1em 0 0;
  font-size: 0.88em;
  color: var(--texto-tenue);
}

.historial__que form {
  flex: 0 0 auto;
}

/* ── El frasco abriéndose ────────────────────────────────────────────────────
   Solo se reproduce entera cuando acaba de elegir (la dirección trae ?abre=1).
   Al recargar para releerlo, el papel ya está desplegado: repetir la ceremonia
   cada vez que vuelve la convertiría en una espera. */

@keyframes destapar {
  from {
    transform: none;
  }
  to {
    transform: translateY(-9px) rotate(-12deg);
  }
}

@keyframes desplegar {
  from {
    opacity: 0;
    transform: translateY(-8px) scaleY(0.04);
  }
  55% {
    opacity: 1;
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes asomar {
  from {
    opacity: 0;
    transform: translateY(9px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.abriendo .frasco__tapa {
  animation: destapar 850ms cubic-bezier(0.2, 0.75, 0.25, 1) both;
}

.abriendo .papel {
  transform-origin: top center;
  animation: desplegar 900ms 520ms cubic-bezier(0.2, 0.75, 0.25, 1) both;
}

.abriendo .nota {
  animation: asomar 700ms 1280ms ease both;
}

.abriendo .orar {
  animation: asomar 700ms 1560ms ease both;
}

/* Al volver a entrar, sin ceremonia: solo aparece. */
.refugio--abierto:not(.abriendo) .papel {
  animation: asomar 420ms ease both;
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESPIRAR — 4 · 7 · 8

   Diecinueve segundos de animación de CSS que se repite sola. Sin JavaScript a
   propósito: no hay temporizador que se desincronice si el teléfono se
   bloquea, no hay nada que pulsar para empezar, y se sale saliendo.

   Los porcentajes son los cuatro, siete y ocho segundos sobre 19:
   4/19 = 21,05 %   y   11/19 = 57,89 %.
   ═══════════════════════════════════════════════════════════════════════════ */

.respirar {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.8rem;
  min-height: 58vh;
  text-align: center;
}

.respirar__entrada {
  margin: 0;
  max-width: 22em;
  color: var(--texto-tenue);
  font-size: 0.95em;
}

.respirar__ruedo {
  position: relative;
  display: grid;
  place-items: center;
  width: min(64vw, 17rem);
  aspect-ratio: 1;
}

.respirar__halo,
.respirar__circulo {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* will-change no: son dos elementos y el navegador ya los sube a su propia
     capa al animarles el transform. Pedirlo a mano solo gasta memoria. */
}

.respirar__halo {
  background: #f1ead9;
  opacity: 0.3;
}

.respirar__circulo {
  border: 1px solid var(--linea-fuerte);
  background: radial-gradient(circle at 50% 42%, #ffffff, #f6f1e6);
}

.respirar__palabras {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  margin: 0;
  z-index: 1;
}

.respirar__paso {
  grid-area: 1 / 1;
  opacity: 0;
  font-family: var(--letra-serif);
  font-size: clamp(1.2rem, 0.7vw + 1.2vh, 1.7rem);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

@keyframes respiracion {
  0% {
    transform: scale(0.44);
  }
  21.05% {
    transform: scale(1);
  }
  57.89% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.44);
  }
}

@keyframes halo {
  0% {
    opacity: 0.16;
    transform: scale(0.5);
  }
  21.05% {
    opacity: 0.42;
    transform: scale(1.1);
  }
  57.89% {
    opacity: 0.42;
    transform: scale(1.1);
  }
  100% {
    opacity: 0.16;
    transform: scale(0.5);
  }
}

@keyframes decirTomar {
  0%, 21.05%, 100% {
    opacity: 0;
  }
  3.5%, 18% {
    opacity: 1;
  }
}

@keyframes decirSostener {
  0%, 21.05%, 57.89%, 100% {
    opacity: 0;
  }
  25%, 54% {
    opacity: 1;
  }
}

@keyframes decirSoltar {
  0%, 57.89%, 100% {
    opacity: 0;
  }
  61.5%, 96% {
    opacity: 1;
  }
}

/* El retraso del principio es para que el círculo no la pille a media
   respiración nada más entrar. */
.respirar__circulo {
  animation: respiracion 19s 2.5s cubic-bezier(0.45, 0, 0.55, 1) infinite both;
}

.respirar__halo {
  animation: halo 19s 2.5s cubic-bezier(0.45, 0, 0.55, 1) infinite both;
}

.respirar__paso--tomar {
  animation: decirTomar 19s 2.5s linear infinite both;
}

.respirar__paso--sostener {
  animation: decirSostener 19s 2.5s linear infinite both;
}

.respirar__paso--soltar {
  animation: decirSoltar 19s 2.5s linear infinite both;
}

.respirar__quieto {
  display: none;
  margin: 0;
  max-width: 24em;
  line-height: 1.8;
}

.respirar__pie {
  margin: 0;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

/* Con «reducir movimiento» puesto no se mueve nada: se lee. Quien activa esa
   opción muchas veces lo hace porque el movimiento le marea, y marear a
   alguien que ha entrado aquí con ansiedad sería el peor final posible. */
@media (prefers-reduced-motion: reduce) {
  .respirar__circulo,
  .respirar__halo,
  .respirar__paso {
    animation: none;
  }

  .respirar__circulo {
    transform: scale(0.82);
  }

  .respirar__halo {
    opacity: 0.28;
    transform: scale(0.95);
  }

  .respirar__paso {
    display: none;
  }

  .respirar__quieto {
    display: block;
  }

  .abriendo .frasco__tapa,
  .abriendo .papel,
  .abriendo .nota,
  .abriendo .orar,
  .refugio--abierto:not(.abriendo) .papel {
    animation: none;
  }

  .sentir {
    transition: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LO QUE SE DEJA GUARDADO DE ANTEMANO

   Cartas selladas, notas de voz y el botón de «estoy contigo». Todo esto se
   abre igual que el refugio: de noche, deprisa y sin ganas de pensar. Así que
   valen las mismas reglas — mucho aire, una cosa por pantalla, ni un color de
   alerta, y solo se animan transform y opacity.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── El botón grande ─────────────────────────────────────────────────────────
   Es lo primero que se ve en su rincón y tiene que poder tocarse a oscuras y
   con una mano. Grande, redondo, sin icono y sin borde duro: lo que hay debajo
   del dedo cuando no se quiere pensar en nada. */

.contigo {
  margin: 0 auto 2.6rem;
  max-width: 24rem;
  text-align: center;
}

.contigo__boton {
  display: block;
  width: 100%;
  padding: 1.5em 1.2em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 999px;
  background: linear-gradient(180deg, #ffffff, #f8f3e9);
  box-shadow: var(--sombra);
  color: var(--texto);
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 0.9vw + 1.5vh, 2.1rem);
  line-height: 1.2;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: transform 240ms ease, box-shadow 240ms ease;
}

.contigo__boton:hover,
.contigo__boton:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(58, 56, 51, 0.05), 0 14px 34px rgba(58, 56, 51, 0.09);
}

.contigo__boton:active {
  transform: scale(0.99);
}

.contigo__pie {
  margin: 0.9em 0 0;
  font-size: 0.88em;
  color: var(--texto-tenue);
}

/* ── Los sobres ──────────────────────────────────────────────────────────────
   Cerrados, con su lacre y su etiqueta. Lo único que se lee antes de abrir es
   «ábrela cuando…»: elegir cuál necesita hoy es la mitad del regalo. */

.sobres {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 1rem;
  margin: 0 0 2.4rem;
}

.sobres--uno {
  grid-template-columns: minmax(0, 15rem);
  justify-content: center;
}

.sobre {
  margin: 0;
}

.sobre__boton {
  display: block;
  width: 100%;
  padding: 1.1em 0.9em 1em;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel);
  box-shadow: var(--sombra);
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: transform 240ms ease, border-color 240ms ease;
}

.sobre__boton:hover,
.sobre__boton:focus-visible {
  border-color: var(--linea-fuerte);
  transform: translateY(-2px);
}

.sobre__dibujo {
  display: block;
  width: 78%;
  margin: 0 auto 0.7em;
  height: auto;
}

.sobre__papel,
.sobre__solapa,
.sobre__pliegue {
  fill: none;
  stroke: var(--linea-fuerte);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sobre__papel {
  fill: #fdfbf7;
}

.sobre__pliegue {
  opacity: 0.45;
}

/* El lacre: lo único con algo de cuerpo en todo el dibujo. Es lo que hace que
   se lea «cerrado» de un vistazo, sin escribir la palabra. */
.sobre__lacre circle {
  fill: #efe3cd;
  stroke: #cbbb9c;
  stroke-width: 1.4;
}

.sobre__lacre path {
  fill: none;
  stroke: #a89e8c;
  stroke-width: 1.4;
  stroke-linecap: round;
}

.sobre__etiqueta {
  display: block;
  font-family: var(--letra-serif);
  font-size: 1.12em;
  line-height: 1.3;
}

.sobre__abrir {
  display: block;
  margin-top: 0.5em;
  font-size: 0.78em;
  letter-spacing: 0.14em;
  text-transform: lowercase;
  color: var(--texto-tenue);
}

/* Las que ya abrió. Sin sobre y sin ceremonia: ya son un texto que releer. */
.abiertas {
  margin: 2.6rem 0 0;
  padding-top: 1.4rem;
  border-top: 1px solid var(--linea);
}

.abiertas__titulo {
  margin: 0 0 1em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.15em;
  color: var(--texto-tenue);
  text-align: center;
}

.abierta {
  display: block;
  padding: 0.85em 0;
  border-bottom: 1px solid var(--linea);
  color: inherit;
  text-decoration: none;
}

.abierta:last-of-type {
  border-bottom: 0;
}

.abierta__etiqueta {
  display: block;
  font-family: var(--letra-serif);
  font-size: 1.08em;
}

.abierta__titulo {
  display: block;
  font-size: 0.92em;
  color: var(--texto-tenue);
}

.abierta__releer {
  display: block;
  margin-top: 0.2em;
  font-size: 0.82em;
  letter-spacing: 0.08em;
  color: var(--texto-tenue);
}

/* ── La carta desplegada ─────────────────────────────────────────────────── */

.carta {
  position: relative;
  margin: 0 auto;
  max-width: 34rem;
  padding: 2.4em 1.8em 2em;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel);
  box-shadow: var(--sombra);
}

.floron {
  display: block;
  width: 3.4rem;
  margin: 0 auto 1.4em;
  height: auto;
  opacity: 0.6;
}

.floron path,
.floron circle {
  fill: none;
  stroke: var(--linea-fuerte);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.carta__titulo {
  margin: 0 0 0.15em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 0.8vw + 1.4vh, 2rem);
  line-height: 1.25;
  text-align: center;
}

.carta__etiqueta {
  margin: 0 0 1.6em;
  text-align: center;
  font-size: 0.78em;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.carta__cuerpo p {
  margin: 0 0 1.1em;
  font-size: clamp(1.05rem, 0.4vw + 1.05vh, 1.22rem);
  line-height: 1.85;
}

.carta__cuerpo p:last-child {
  margin-bottom: 0;
}

/* ── Una frase suelta ────────────────────────────────────────────────────── */

.frase {
  margin: 2rem auto;
  max-width: 30rem;
  text-align: center;
}

.frase__texto {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: clamp(1.35rem, 0.9vw + 1.35vh, 1.95rem);
  line-height: 1.55;
}

/* ── Un recuerdo entregado ───────────────────────────────────────────────── */

.recuerdo {
  margin: 0 auto;
  max-width: 34rem;
}

.recuerdo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 16px;
}

.recuerdo__pie {
  margin: 0.9em 0 0;
  text-align: center;
  font-size: 0.95em;
  color: var(--texto-tenue);
}

/* ── Las notas de voz ────────────────────────────────────────────────────── */

.nota-voz {
  margin: 0 auto 1.6rem;
  max-width: 34rem;
  padding: 1.3em 1.3em 1.1em;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel);
}

.nota-voz--sola {
  padding: 2em 1.5em 1.6em;
}

.nota-voz__etiqueta {
  margin: 0;
  font-size: 0.78em;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.nota-voz__titulo {
  margin: 0.35em 0 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.3em;
  line-height: 1.3;
}

/* El reproductor: un botón, una barra y el tiempo. Nada más. El <audio> de
   verdad sigue ahí debajo, escondido, y vuelve a aparecer si el guion no carga. */
.voz {
  margin-top: 1em;
}

.voz__fuente {
  display: block;
  width: 100%;
}

.voz__fuente--oculta {
  display: none;
}

.voz__mando {
  display: flex;
  align-items: center;
  gap: 0.9em;
}

.voz__boton {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1px solid var(--linea-fuerte);
  border-radius: 50%;
  background: var(--papel);
  color: var(--texto);
  cursor: pointer;
  transition: background-color 220ms ease;
}

.voz__boton:hover,
.voz__boton:focus-visible {
  background: #f5f0e6;
}

.voz__boton svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

.voz__barra {
  position: relative;
  flex: 1;
  height: 1.4rem; /* alto de toque cómodo; la raya se dibuja dentro */
  cursor: pointer;
  touch-action: none;
}

.voz__barra::before {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  height: 3px;
  border-radius: 3px;
  background: var(--linea);
  transform: translateY(-50%);
}

.voz__llena {
  position: absolute;
  inset: 50% 0 auto;
  height: 3px;
  border-radius: 3px;
  background: var(--linea-fuerte);
  transform: translateY(-50%) scaleX(0);
  transform-origin: left center;
}

.voz__tiempo {
  flex: 0 0 auto;
  min-width: 2.6em;
  text-align: right;
  font-size: 0.85em;
  font-variant-numeric: tabular-nums;
  color: var(--texto-tenue);
}

.voz__aviso {
  margin: 0.8em 0 0;
  font-size: 0.88em;
  color: var(--texto-tenue);
}

/* ── La grabadora ────────────────────────────────────────────────────────── */

.grabadora {
  margin: 0 0 1.4em;
  padding: 1.6em 1.2em;
  border: 1px solid var(--linea);
  border-radius: 16px;
  text-align: center;
}

.grabadora__boton {
  display: inline-block;
  padding: 1.05em 2.4em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 999px;
  background: var(--papel);
  color: var(--texto);
  font-family: var(--letra-serif);
  font-size: 1.4em;
  cursor: pointer;
  transition: background-color 240ms ease;
}

/* Grabando: un punto que late. Sin rojo de alerta — es champán, como todo. */
.grabadora__boton--grabando {
  background: #f3ead8;
}

.grabadora__boton--grabando::before {
  content: "";
  display: inline-block;
  width: 0.55em;
  height: 0.55em;
  margin-right: 0.55em;
  border-radius: 50%;
  background: #b9a377;
  vertical-align: middle;
  animation: latir 1.6s ease-in-out infinite;
}

@keyframes latir {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

.grabadora__reloj {
  margin: 0.7em 0 0;
  font-family: var(--letra-serif);
  font-size: 1.6em;
  font-variant-numeric: tabular-nums;
  color: var(--texto-tenue);
}

.grabadora__estado {
  margin: 0.3em 0 0;
  font-size: 0.88em;
  color: var(--texto-tenue);
}

.grabadora__escucha {
  display: block;
  width: 100%;
  margin: 1em 0 0.6em;
}

.elegir--otra-via {
  margin-bottom: 1.15em;
  font-size: 0.92em;
}

/* ── El taller: lo que tiene escrito ─────────────────────────────────────── */

.piezas {
  margin: 2.4rem 0 0;
}

.piezas__titulo {
  margin: 0 0 1em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.15em;
  color: var(--texto-tenue);
}

.pieza {
  padding: 1.1em 0;
  border-bottom: 1px solid var(--linea);
}

.pieza:last-child {
  border-bottom: 0;
}

.pieza__que {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6em;
  align-items: baseline;
  font-size: 0.8em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.pieza__tipo {
  color: var(--texto);
}

.pieza__titulo {
  margin: 0.3em 0 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.2em;
}

.pieza__asomo {
  margin: 0.25em 0 0;
  font-size: 0.95em;
  color: var(--texto-tenue);
}

.pieza__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2em;
  align-items: baseline;
  margin-top: 0.5em;
}

.pieza__acciones form {
  margin: 0;
}

.pieza__estado {
  font-size: 0.85em;
  letter-spacing: 0.06em;
  color: var(--texto-tenue);
}

a.enlace-boton {
  text-decoration: none;
}

.borrar {
  margin: 1.6rem 0 0;
  text-align: center;
}

/* ── El sello rompiéndose ────────────────────────────────────────────────────
   Solo la primera vez, cuando la dirección trae ?abre=1. Al volver a leerla la
   carta ya está desplegada: repetir la ceremonia cada vez la convertiría en una
   espera, que es justo lo contrario de lo que es. */

@keyframes desplegarCarta {
  from {
    opacity: 0;
    transform: translateY(-10px) scaleY(0.06);
  }
  55% {
    opacity: 1;
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes romperse {
  0% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: scale(1.7) rotate(14deg);
  }
}

.carta.abriendo {
  transform-origin: top center;
  animation: desplegarCarta 900ms 380ms cubic-bezier(0.2, 0.75, 0.25, 1) both;
}

.carta.abriendo .floron {
  animation: romperse 420ms ease-in both;
}

/* ── El acta: firmar antes y llevársela ──────────────────────────────────── */

.tarjeta--enlace .tarjeta__pie {
  margin: 0.8em 0 0;
  font-size: 0.85em;
  letter-spacing: 0.1em;
  color: var(--texto-tenue);
}

.tarjeta--firmada {
  text-align: center;
}

.firma--suelta {
  margin-top: 1.4em;
}

.descarga {
  margin: 0 auto;
  max-width: 34rem;
}

.descarga__marco {
  position: relative;
  min-height: 12rem;
  padding: 0.9em;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel);
}

.descarga__marco img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}

.descarga__esperando {
  position: absolute;
  inset: 50% 0 auto;
  margin: 0;
  transform: translateY(-50%);
  text-align: center;
  color: var(--texto-tenue);
}

.descarga__pie {
  margin: 1em 0 0;
  text-align: center;
  font-size: 0.85em;
  color: var(--texto-tenue);
}

/* ── Imprimir ────────────────────────────────────────────────────────────────
   Para quien mande el acta a la impresora desde su propia página en vez de
   bajarse la imagen. Se va todo lo que no es el documento. */

/* ── LO QUE VIENE ─────────────────────────────────────────────────────────────
   Una lista en columna, sin cuadrícula y sin iconos: es lo mismo que hacen la
   portada y el taller. Cada cosa dice PRIMERO los días que faltan, porque es lo
   único que se mira de un vistazo, y después qué es y cuándo. */

.vienen {
  margin: 2.2rem 0 0;
}

.viene {
  display: block;
  padding: 1.1em 0;
  border-bottom: 1px solid var(--linea);
  color: inherit;
  text-decoration: none;
  transition: transform 260ms ease;
}

.viene:last-child {
  border-bottom: 0;
}

a.viene:hover,
a.viene:focus-visible {
  transform: translateX(2px);
}

.viene__falta {
  margin: 0;
  font-size: 0.78em;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.viene__titulo {
  margin: 0.25em 0 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.3em;
  line-height: 1.25;
}

.viene__cuando {
  margin: 0.15em 0 0;
  font-size: 0.92em;
  color: var(--texto-tenue);
}

/* ── UN PLAN ──────────────────────────────────────────────────────────────── */

.plan {
  margin: 1.5rem 0 0;
  padding: 2em 0 0;
}

.plan__ojo {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: 0.8em;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--texto-tenue);
}

.plan__titulo {
  margin: 0.35em 0 0;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 1vw + 1.7vh, 2.4rem);
  line-height: 1.2;
}

.plan__cuando {
  margin: 0.8em 0 0;
  font-family: var(--letra-serif);
  font-size: 1.2em;
  line-height: 1.5;
}

.plan__zona {
  font-family: var(--letra-sans);
  font-size: 0.72em;
  letter-spacing: 0.12em;
  color: var(--texto-tenue);
}

.plan__lugar {
  margin: 0.5em 0 0;
  font-size: 1.02em;
}

.plan__nota {
  margin: 1.1em 0 0;
  white-space: pre-wrap;
  color: var(--texto-tenue);
}

.plan__quien {
  margin: 1.4em 0 0;
  font-size: 0.9em;
  color: var(--texto-tenue);
}

.plan__aviso {
  margin: 1.4em 0 0;
  padding-top: 1.2em;
  border-top: 1px solid var(--linea);
  font-size: 0.94em;
  color: var(--texto-tenue);
}

/* Cancelado se dice con calma, no con rojo: aquí no hay colores de alerta. */
.plan--cancelado .plan__titulo,
.plan--cancelado .plan__cuando {
  color: var(--texto-tenue);
}

.plan__acciones,
.plan__editar,
.pregunta__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4em;
  align-items: baseline;
  margin-top: 1.6em;
}

.plan__acciones form,
.plan__editar form,
.pregunta__acciones form {
  margin: 0;
}

/* Los de cambiar y cancelar van abajo del todo y en pequeño: se usan una vez
   de cada veinte, y arriba solo estorbarían. */
.plan__editar {
  margin-top: 2.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--linea);
  justify-content: center;
}

/* ── «¿Le ponemos fotos?» ─────────────────────────────────────────────────────
   Se pregunta una vez, y se ve que es una pregunta y no un pendiente: sin
   fondo, con el borde a rayas, igual que lo que todavía no existe. */

.tarjeta-grande--pregunta,
.tarjeta--pregunta {
  border-style: dashed;
  background: none;
  box-shadow: none;
}

.tarjeta--pregunta {
  border: 1px dashed var(--linea-fuerte);
}

/* Una ayuda que va suelta, fuera de su campo. */
.campo__ayuda--suelta {
  display: block;
  margin: -0.4em 0 1.2em;
}

/* El sitio de un recuerdo, cuando lo tuvo: los planes que ya bajaron. */
.entrada__lugar {
  font-family: var(--letra-sans);
  font-size: 0.8em;
  letter-spacing: 0.04em;
  color: var(--texto-tenue);
}


/* ── EL JARDÍN ────────────────────────────────────────────────────────────────
   El campo es un lienzo; lo que va debajo es el papel donde se lee lo que
   escribió al tocar un lirio. Nada de marcos ni de sombras: el jardín tiene que
   parecer que está sobre el mismo papel de la página, no dentro de una caja. */

.jardin {
  position: relative;
  margin: 1.6rem 0 0;
}

.jardin__campo {
  display: block;
  width: 100%;
  /* Alto por proporción y no por píxeles, para que no cambie de forma al girar
     el teléfono. Un poco más alto que ancho en móvil: es donde se ve el campo. */
  aspect-ratio: 4 / 5;
  max-height: 62vh;
  border-radius: 20px;
  background: linear-gradient(180deg, var(--marfil), #ffffff);
  border: 1px solid var(--linea);
  touch-action: manipulation;
}

@media (min-width: 40rem) {
  .jardin__campo {
    aspect-ratio: 16 / 10;
  }
}

/* El papel que sale al tocar un lirio. Aparece con opacidad, nunca abriéndose
   hueco: mover el alto empujaría media pantalla justo cuando está leyendo. */
.jardin__papel {
  margin: 1rem 0 0;
  padding: 1.2em 1.3em;
  border-radius: 16px;
  background: var(--papel);
  border: 1px solid var(--linea);
  opacity: 0;
  transition: opacity 420ms ease;
}

.jardin__papel.se-ve {
  opacity: 1;
}

.jardin__texto {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: 1.2em;
  line-height: 1.5;
  white-space: pre-wrap;
}

.jardin__cuando {
  margin: 0.6em 0 0;
  font-size: 0.82em;
  letter-spacing: 0.1em;
  color: var(--texto-tenue);
}

.jardin__sembrar {
  margin-top: 1.6rem;
}

.jardin__lista {
  margin: 1.2rem 0 0;
  padding: 0;
  list-style: none;
}

.jardin__lista li {
  padding: 0.85em 0;
  border-bottom: 1px solid var(--linea);
  white-space: pre-wrap;
}

.jardin__lista li:last-child {
  border-bottom: 0;
}

/* ── LAS LUCIÉRNAGAS ──────────────────────────────────────────────────────────
   Una ventana a la noche dentro de una casa de día. Es la misma noche de la
   declaración, y por eso se reconoce. */

.noche {
  position: relative;
  margin: 1.6rem 0 0;
}

.noche__campo {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  max-height: 66vh;
  border-radius: 20px;
  background: var(--noche);
  touch-action: manipulation;
}

@media (min-width: 40rem) {
  .noche__campo {
    aspect-ratio: 16 / 10;
  }
}

/* La palabra atrapada, sobre la noche. Va dentro del lienzo, abajo, para que no
   haya que apartar la vista del juego para leerla. */
.noche__papel {
  position: absolute;
  left: 1.2rem;
  right: 1.2rem;
  bottom: 1.4rem;
  text-align: center;
  opacity: 0;
  transition: opacity 520ms ease;
  pointer-events: none;
}

.noche__papel.se-ve {
  opacity: 1;
}

/* Son FRASES enteras, no palabras sueltas —«Te elegí despacio, y a propósito.»—,
   así que el tamaño se baja un punto: a 2,1 rem una frase de treinta letras se
   parte en tres renglones y deja de leerse de un vistazo. */
.noche__palabra {
  margin: 0;
  font-family: var(--letra-serif);
  font-size: clamp(1.25rem, 0.8vw + 1.3vh, 1.75rem);
  line-height: 1.3;
  color: var(--marfil);
  text-wrap: balance;
}

.noche__nota {
  margin: 0.35em 0 0;
  font-size: 0.95em;
  line-height: 1.5;
  color: var(--tinta-tenue);
}

.noche__final {
  margin: 1.6rem 0 0;
  text-align: center;
}

.noche__final p {
  margin: 0 0 0.9em;
  font-family: var(--letra-serif);
  font-size: 1.15em;
  color: var(--texto-tenue);
}

/* Las que le faltan viven en la página para que el guion las lea, y no se ven
   nunca: destriparlas sería quitarle el juego. */
.sueltas {
  display: none;
}

.cesta {
  margin: 1.8rem 0 0;
}

.cesta__titulo {
  margin: 0 0 0.8em;
  font-family: var(--letra-serif);
  font-weight: 400;
  font-size: 1.05em;
  color: var(--texto-tenue);
}

.cesta__lista {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cesta__palabra {
  padding: 0.4em 0.95em;
  border: 1px solid var(--linea-fuerte);
  border-radius: 999px;
  font-size: 0.92em;
}

/* ── MEMORIA ─────────────────────────────────────────────────────────────────
   Cartas cuadradas en una rejilla. El volteo es `rotateY` y nada más: ni una
   propiedad que obligue al navegador a rehacer la página. */

.niveles {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  margin: 1.4rem 0 0;
  font-size: 0.9em;
}

.niveles__nombre {
  color: var(--texto-tenue);
  letter-spacing: 0.1em;
}

.niveles__uno {
  color: var(--texto-tenue);
  text-decoration: none;
  padding-bottom: 0.15em;
  border-bottom: 1px solid transparent;
}

.niveles__uno.es-actual {
  color: var(--texto);
  border-bottom-color: var(--linea-fuerte);
}

.memoria {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7rem;
  margin: 1.2rem 0 0;
  /* Sin el guion las cartas no se pueden voltear: se dice bajándoles la tinta,
     no escondiéndolas. La rejilla sigue enseñando que aquí había un juego. */
  opacity: 0.5;
  transition: opacity 400ms ease;
}

.memoria--lista {
  opacity: 1;
}

@media (min-width: 34rem) {
  .memoria {
    grid-template-columns: repeat(4, 1fr);
    gap: 0.9rem;
  }
}

.carta-memoria {
  position: relative;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 14px;
  cursor: pointer;
  /* Es lo que hace que el volteo se vea de canto y no como un cambio de imagen. */
  transform-style: preserve-3d;
  transition: transform 420ms ease;
  -webkit-tap-highlight-color: transparent;
}

.carta-memoria.vuelta,
.carta-memoria.hallada {
  transform: rotateY(180deg);
}

.carta-memoria__dorso,
.carta-memoria__cara {
  position: absolute;
  inset: 0;
  border-radius: 14px;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.carta-memoria__dorso {
  background: linear-gradient(160deg, #ffffff, var(--marfil));
  border: 1px solid var(--linea);
}

.carta-memoria__cara {
  transform: rotateY(180deg);
  border: 1px solid var(--linea);
}

.carta-memoria__cara img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Encontrada: se queda a la vista y se aparta un poco, sin desaparecer. No se
   marca con un color de acierto — aquí no hay aciertos ni fallos. */
.carta-memoria.hallada {
  cursor: default;
}

.carta-memoria.hallada .carta-memoria__cara {
  opacity: 0.62;
}

.memoria__final {
  margin: 1.6rem 0 0;
  text-align: center;
  opacity: 0;
  transition: opacity 520ms ease;
}

.memoria__final.se-ve {
  opacity: 1;
}

.memoria__final p {
  margin: 0 0 0.9em;
  font-family: var(--letra-serif);
  font-size: 1.2em;
}


@media print {
  body.dia {
    background: #ffffff;
  }

  .navegacion,
  .botones,
  .pie-app,
  .refugio__aparte {
    display: none !important;
  }

  .hoja {
    width: auto;
    padding: 0;
  }

  .acta {
    border: 0;
    box-shadow: none;
    break-inside: avoid;
  }
}

/* Con «reducir movimiento» puesto, la carta aparece y ya. Marear a alguien que
   ha entrado aquí con ansiedad sería el peor final posible. */
@media (prefers-reduced-motion: reduce) {
  .carta.abriendo,
  .carta.abriendo .floron,
  .grabadora__boton--grabando::before {
    animation: none;
  }

  .carta.abriendo .floron {
    opacity: 0;
  }

  .contigo__boton,
  .sobre__boton,
  .voz__boton,
  .grabadora__boton,
  .viene,
  .jardin__papel,
  .noche__papel,
  .memoria,
  .memoria__final {
    transition: none;
  }

  /* La carta cambia de cara sin girar: el giro es lo que marea. */
  .carta-memoria {
    transition: none;
  }
}

/* ── El visor de una foto ─────────────────────────────────────────────────── */
/*
   La foto a pantalla completa, dentro de la casa. Ver public/js/visor.js para
   el porqué de cada cosa; aquí, lo que hace que NO se salga nunca de la
   pantalla y que nada de la casa se asome por encima.
*/

.visor {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  /* NUNCA `vh`. En el móvil, `vh` es la altura del área visible con la barra
     del navegador ESCONDIDA: mientras la barra está puesta —que es casi
     siempre— la caja sale más alta de lo que de verdad se ve y la foto se va
     por debajo del borde. `dvh` es la que se mueve con la barra, que es
     exactamente lo que hace falta aquí.

     El orden de las tres declaraciones es el repuesto: quien no entienda `dvh`
     se queda en `svh` (la altura MÍNIMA, con las barras puestas: se ve un poco
     de más, nunca de menos), y quien no entienda ninguna de las dos se queda
     con los píxeles que le escribe el JavaScript desde `innerHeight`. */
  height: 100vh;
  height: var(--alto-visor, 100vh);
  height: 100svh;
  height: 100dvh;
  background: rgba(20, 19, 17, 0.97);
  opacity: 0;
  transition: opacity 300ms ease;
}

.visor.abierto {
  opacity: 1;
}

.visor[hidden] {
  display: none;
}

/* El área donde cabe la foto: lo que queda después del relleno y de las zonas
   seguras del teléfono. Es lo que mide el JavaScript, y por eso el relleno vive
   aquí y no en la foto. */
.visor__area {
  flex: 1 1 auto;
  /* Sin esto, un hijo de flex no baja de su tamaño de contenido y el área se
     haría más alta que la pantalla en cuanto la foto fuera grande. */
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(3.6rem, calc(env(safe-area-inset-top) + 3.2rem))
    max(0.75rem, env(safe-area-inset-right))
    max(3.4rem, calc(env(safe-area-inset-bottom) + 3rem))
    max(0.75rem, env(safe-area-inset-left));
}

/* El marco lo mide el JavaScript en píxeles, con la proporción guardada en la
   base ANTES de pedir la foto. Sin transición de `width` ni de `height`: se
   escriben una vez y ya (regla 3.8, que prohíbe ANIMAR el tamaño, no medirlo). */
.visor__marco {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  max-height: 100%;
}

/* La red de seguridad. Aunque la cuenta del JavaScript fallara, aunque el ancho
   guardado fuera mentira, aunque no hubiera ninguno: con esto la foto se mete
   ENTERA y centrada dentro de la caja, y no puede salirse. `contain` y jamás
   `cover` — `cover` es recortar para rellenar, y aquí se vino a ver la foto
   entera, no un trozo. */
.visor__foto {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* Mientras se ve la miniatura en el hueco de la grande, un pelo de desenfoque
   para que se lea como «está llegando» y no como «esta foto es mala». Va en la
   caja definitiva y con `contain`, así que lo que crece al llegar la grande es
   la NITIDEZ y no el tamaño: no hay salto. No se anima (regla 3.8): se pone y
   se quita. */
.visor__foto--previa {
  filter: blur(8px);
}

/* Pasar de foto: entra desde el lado hacia el que se deslizó. Solo `transform`
   y `opacity` (regla 3.8). */
@keyframes visor-entra-der {
  from { opacity: 0; transform: translate3d(7%, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes visor-entra-izq {
  from { opacity: 0; transform: translate3d(-7%, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.visor__marco--der { animation: visor-entra-der 260ms ease-out; }
.visor__marco--izq { animation: visor-entra-izq 260ms ease-out; }

/* ── Los mandos ───────────────────────────────────────────────────────────── */
/*
   Palabras, no iconos (regla 3.7). Y se desvanecen solos a los tres segundos:
   lo que se vino a ver es la foto. Vuelven al tocar la pantalla.
*/

.visor__mandos {
  position: absolute;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
  display: flex;
  gap: 0.6rem;
}

.visor__pie {
  position: absolute;
  left: 0;
  right: 0;
  bottom: max(1rem, env(safe-area-inset-bottom));
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 max(0.75rem, env(safe-area-inset-left));
  flex-wrap: wrap;
}

.visor__accion {
  padding: 0.6em 1.4em;
  border: 1px solid rgba(240, 234, 222, 0.3);
  border-radius: 999px;
  background: rgba(20, 19, 17, 0.5);
  color: var(--tinta-clara);
  font-family: var(--letra-sans);
  font-weight: 300;
  font-size: 0.92rem;
  letter-spacing: 0.14em;
  text-transform: lowercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 400ms ease, background-color 400ms ease;
}

.visor__accion:hover,
.visor__accion:focus-visible {
  border-color: rgba(240, 234, 222, 0.55);
  background: rgba(20, 19, 17, 0.75);
}

.visor__accion[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* Quietos: los mandos se han ido solos. `visibility` para que no se pueda tocar
   un botón invisible, y con retraso para que le dé tiempo a desvanecerse antes
   de desaparecer del todo. */
.visor--quieto .visor__mandos,
.visor--quieto .visor__pie {
  opacity: 0;
  visibility: hidden;
  transition: opacity 500ms ease, visibility 0s linear 500ms;
}

.visor__mandos,
.visor__pie {
  opacity: 1;
  visibility: visible;
  transition: opacity 260ms ease, visibility 0s;
}

/* Si algo de aquí tiene el foco, NO se esconde: el teclado se quedaría
   escribiendo a ciegas sobre un botón que no se ve. */
.visor__mandos:focus-within,
.visor__pie:focus-within {
  opacity: 1 !important;
  visibility: visible !important;
  transition: opacity 260ms ease, visibility 0s !important;
}

/* ── La ficha ─────────────────────────────────────────────────────────────── */

.visor__ficha {
  position: absolute;
  left: 50%;
  bottom: max(4.6rem, calc(env(safe-area-inset-bottom) + 4.2rem));
  z-index: 1;
  width: min(22rem, calc(100% - 2rem));
  /* La mitad del ancho a la izquierda: centrado sin `left`/`margin` que haya
     que recalcular al girar el teléfono. */
  transform: translateX(-50%);
  padding: 1.1rem 1.3rem;
  border-radius: 16px;
  background: rgba(20, 19, 17, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--tinta-clara);
  text-align: left;
}

.visor__ficha[hidden] {
  display: none;
}

.visor__dato {
  margin: 0 0 0.45em;
  font-size: 0.95rem;
  line-height: 1.5;
}

.visor__dato:last-child {
  margin-bottom: 0;
}

.visor__dato span {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

/* Un dato sin rótulo —la zona horaria, que va pegada a la fecha— no deja el
   hueco de un rótulo vacío encima. */
.visor__dato span:empty {
  display: none;
}

/* ── Lo de fuera, mientras el visor está abierto ──────────────────────────── */

/* La página de detrás no se mueve. */
body.con-visor {
  overflow: hidden;
}

/*
   Y la barra de abajo se va.

   En su captura, «hoy · historia · rincón · perfil» se veía por encima de la
   foto a pantalla completa. El z-index ya la dejaba por debajo (20 contra 60),
   pero el fondo del visor es 0.97 y no 1, y la barra lleva `backdrop-filter`,
   que crea su propio contexto de apilamiento y la levanta en algunos
   navegadores. Se esconde y punto: el visor es pantalla completa DE VERDAD, sin
   nada de la casa asomando.

   Con `opacity` + `visibility` y no con `display:none`, porque display no se
   puede transicionar y la barra volvería de golpe al cerrar la foto.
*/
body.con-visor .navegacion {
  opacity: 0;
  visibility: hidden;
  transition: opacity 220ms ease, visibility 0s linear 220ms;
}

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

  .visor__marco--der,
  .visor__marco--izq {
    animation: none;
  }

  .visor__mandos,
  .visor__pie,
  body.con-visor .navegacion {
    transition: none;
  }
}
