/* La luz de la hora.
 *
 * El fondo de esta aplicación ES la hora del día: arranca en un azul mineral con
 * luz y termina en un índigo profundo. La escalada de avisos dice "el día se
 * acaba" con palabras; la luz lo dice sin regañar, que es justo lo que hace
 * falta aquí y lo contrario de lo que hace un contador en rojo.
 *
 * Todo cuelga de UNA variable, `--t`, entre 0 y 1, que pone el guion al cargar y
 * refresca cada cinco minutos. El resto se deriva con `color-mix()`: sin
 * animaciones en bucle, sin `requestAnimationFrame`, sin gastar batería.
 *
 * Nada se carga de fuera del dominio. Las dos fuentes viven en `fuentes/`.
 */

/* --- Tokens -------------------------------------------------------------- */

:root {
  /* La rampa de la hora azul. Cuatro paradas, no un degradado continuo:
     interpolar entre dos vecinas basta y se lee mejor en pantallas OLED. */
  --hora-0: #C9D4DE;   /* mediodía tardío: azul mineral, frío, con luz */
  --hora-1: #A9AEC6;   /* tarde larga */
  --hora-2: #444460;   /* violeta de anochecer */
  --hora-3: #1E2140;   /* índigo profundo, las once de la noche */

  --tinta-clara: #12162B;   /* texto cuando el fondo está claro */
  --tinta-oscura: #E7E3F0;  /* texto cuando el fondo está oscuro */

  /* El único color cálido de toda la aplicación. Es la luz de la lámpara con la
     que escribes, y por eso aparece exactamente en tres sitios: el botón de
     guardar, la marca del día de hoy y el anillo del foco. Si aparece en un
     cuarto, sobra. */
  --lampara: #F0B357;

  /* Antes de que el guion diga la hora: de noche. Es cuando más se abre esto, y
     un destello oscuro molesta mucho menos que un destello blanco. */
  --t: 1;

  --serif: "Fraunces", ui-serif, "New York", Georgia, serif;
  --sans: "Instrument Sans", ui-sans-serif, -apple-system, system-ui, sans-serif;

  --margen: max(1.25rem, env(safe-area-inset-left));
  --hairline: color-mix(in oklab, var(--tinta) 12%, transparent);
}

/* --- La derivación de la hora -------------------------------------------- */
/*
 * Tres tramos, y el del medio no es un desvanecido: es un salto.
 *
 * Un fondo de luminancia intermedia —el gris violáceo que saldría a mitad de
 * camino entre la tarde y el anochecer— NO llega a 7:1 con ninguna tinta, ni
 * clara ni oscura: como mucho da 3,7. Es geometría de la fórmula del contraste,
 * no una elección de paleta, así que la única forma de cumplir el suelo de 7:1
 * en toda la rampa es no quedarse nunca ahí. Por eso el tramo del cruce dura
 * 0,002 de `--t` —bastante menos que los cinco minutos con que el guion refresca
 * la hora— y la tinta cambia de golpe en el mismo punto.
 *
 * A cambio, una vez al día y alrededor de las seis de la tarde, el fondo da un
 * paso más grande que los demás. Es lo que hace la luz de verdad al anochecer.
 */
:root {
  --p0: clamp(0, calc(var(--t) / 0.499), 1);
  --p1: clamp(0, calc((var(--t) - 0.499) / 0.002), 1);
  --p2: clamp(0, calc((var(--t) - 0.501) / 0.499), 1);
  --paso: clamp(0, calc((var(--t) - 0.4995) / 0.001), 1);

  --f0: color-mix(in oklab, var(--hora-1) calc(var(--p0) * 100%), var(--hora-0));
  --f1: color-mix(in oklab, var(--hora-2) calc(var(--p1) * 100%), var(--f0));
  --fondo: color-mix(in oklab, var(--hora-3) calc(var(--p2) * 100%), var(--f1));
  --tinta: color-mix(in oklab, var(--tinta-oscura) calc(var(--paso) * 100%),
                     var(--tinta-clara));
  --tinta-suave: color-mix(in oklab, var(--tinta) 62%, transparent);
}

/* --- Las dos fuentes ------------------------------------------------------ */
/*
 * Serif para lo que él escribe, sans para la maquinaria. La asignación
 * significa algo: las entradas se van a leer dentro de diez años; los botones
 * no se releen nunca.
 */
@font-face {
  font-family: "Fraunces";
  src: url("fuentes/fraunces-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Instrument Sans";
  src: url("fuentes/instrument-sans-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* --- Armazón -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  background-color: var(--fondo);
  /* La transición es larga porque el cambio es de hora, no de estado: si se
     nota, deja de ser luz ambiente y pasa a ser un efecto. */
  transition: background-color 1.2s linear;
}

body {
  margin: 0;
  /* Columna de aplicación y no documento que se desplaza: lo escrito se mueve
     dentro de `main` mientras el compositor y el menú se quedan quietos abajo.
     Con el documento entero desplazándose había que sostener el campo con
     `sticky` y calcular a mano el hueco del menú, y en iOS eso baila con el
     teclado. */
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  color: var(--tinta);
  background-color: transparent;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
  /* Nada de scroll horizontal en ningún ancho, empezando por 320px. */
  overflow-x: hidden;
  -webkit-text-size-adjust: 100%;
}

/* Franja opaca bajo la barra de estado. En una aplicación instalada con
   `black-translucent`, la vista web empieza en el píxel cero y el texto se
   desplaza POR DEBAJO del reloj y la batería, donde iOS lo difumina a medias: se
   lee media frase borrosa. El relleno superior solo lo arregla con la página sin
   desplazar. Esto tapa esa franja con el color de la hora, así que el texto
   desaparece limpio en vez de quedarse a medio difuminar. */
body::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: env(safe-area-inset-top);
  background-color: var(--fondo);
  z-index: 20;
  pointer-events: none;
}

/* La barra de carga. Sin ella, tocar «antes» con mala cobertura no da ninguna
   señal: la pantalla se queda igual y no se sabe si el toque ha contado. Va
   justo debajo de la franja de la barra de estado y solo se ve mientras el
   navegador está pidiendo la página siguiente. */
.cargando {
  position: fixed;
  top: env(safe-area-inset-top);
  left: 0; right: 0;
  height: 2px;
  z-index: 21;
  background-color: transparent;
  overflow: hidden;
  pointer-events: none;
}

.cargando::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--lampara);
  transform: translateX(-100%);
}

body.navegando .cargando::after {
  animation: cargando 1.1s ease-in-out infinite;
}

@keyframes cargando {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(0); }
  100% { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin animación sigue habiendo señal: una línea quieta que dice que algo está
     pasando. Quitarla del todo dejaría a quien pide menos movimiento sin saber
     si su toque ha contado. */
  body.navegando .cargando::after { animation: none; transform: none; opacity: 0.5; }
}

.sin-conexion {
  flex: none;
  margin: 0;
  padding: calc(max(0.5rem, env(safe-area-inset-top)) + 0.4rem) var(--margen) 0.5rem;
  /* Tinte neutro y no el ámbar de la lámpara: ese color es el de LO QUE TÚ
     HACES —guardar, el día de hoy, el foco— y esto es el estado de la red.
     Mezclarlos le quita significado al único color cálido que hay. */
  background-color: color-mix(in oklab, var(--tinta) 14%, var(--fondo));
  color: var(--tinta);
  font-size: 0.875rem;
  text-align: center;
}

/* Con el banner arriba, la franja de la barra de estado sobra: la ocupa él. */
body:has(.sin-conexion:not([hidden]))::before { display: none; }

/* La pantalla de arranque. En iOS, una aplicación instalada tarda un momento en
   pintar y mientras se ve un rectángulo del color de fondo, sin nada: parece que
   no ha abierto. Esto es lo mismo que se ve al abrir —la luz de la marca— y se
   quita solo cuando el documento está listo. */
.arranque {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--fondo);
  transition: opacity 260ms ease-out, visibility 260ms;
}

.arranque[hidden] {
  display: flex;          /* `hidden` no puede esconderlo de golpe: se desvanece */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.arranque span {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background-color: var(--lampara);
  box-shadow: 0 0 3.5rem 1.75rem color-mix(in oklab, var(--lampara) 28%, transparent);
  animation: latido 1.6s ease-in-out infinite;
}

@keyframes latido {
  0%, 100% { opacity: 0.55; transform: scale(0.94); }
  50%      { opacity: 1;    transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .arranque span { animation: none; opacity: 1; }
}

main {
  width: 100%;
  max-width: 38rem;
  margin: 0 auto;
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: calc(max(1.25rem, env(safe-area-inset-top)) + 1.5rem) var(--margen) 1.25rem;
  /* Lo que sube se desvanece antes de llegar al reloj, en vez de cortarse de
     golpe o quedarse a medio difuminar bajo la barra de estado. El relleno de
     arriba deja lo primero por debajo del desvanecido, así que en reposo no hay
     nada difuminado: solo al desplazar. */
  mask-image: linear-gradient(to bottom, transparent 0,
              #000 calc(max(1.25rem, env(safe-area-inset-top)) + 1.5rem));
  -webkit-mask-image: linear-gradient(to bottom, transparent 0,
              #000 calc(max(1.25rem, env(safe-area-inset-top)) + 1.5rem));
}

a { color: inherit; }

/* El foco siempre visible. No es negociable: sin él, quien navegue con teclado
   —o con un teclado externo en el iPad— no sabe dónde está. */
:focus-visible {
  outline: 2px solid var(--lampara);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Cualquier movimiento de esta aplicación es prescindible. Si el sistema pide
   quietud, se le hace caso entero y sin excepciones. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
  }
}

/* --- Tipografía ----------------------------------------------------------- */

/* La cejilla: la fecha, o la hora a la que quedó guardado. Minúsculas y español
   natural —"viernes 21 de agosto"—, nunca "21/08/2026": esto es un diario, no
   un albarán. */
.cejilla {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: var(--tinta-suave);
  margin: 0 0 1.5rem;
  /* 240 ms para pasar de la fecha a "guardado a las 23:41". Es el único
     movimiento de la aplicación al guardar: ni confeti, ni contador que sube. */
  transition: opacity 240ms ease;
}

.cejilla.cambiando { opacity: 0; }

h1 {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 400;
  font-variation-settings: "opsz" 60, "SOFT" 30, "WONK" 1;
  margin: 0 0 1rem;
}

h2 {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: var(--tinta-suave);
  margin: 2.25rem 0 0.75rem;
}

p { margin: 0 0 0.9rem; }

.sereno { color: var(--tinta-suave); font-size: 0.9375rem; }

.oculto {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Escribir ------------------------------------------------------------- */
/*
 * No hay formulario. Ni caja, ni borde, ni sombra, ni esquinas redondeadas
 * alrededor del texto: lo que se ve tiene que parecer una carta empezando, no
 * un campo que rellenar.
 */
.escribir {
  display: block;
  width: 100%;
  border: none;
  background: transparent;
  color: inherit;
  padding: 0;
  margin: 0;
  resize: none;
  overflow: hidden;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 5.5vw, 2rem);
  font-weight: 400;
  font-variation-settings: "opsz" 72, "SOFT" 30;
  letter-spacing: -0.01em;
  line-height: 1.35;
}

/* El campo empieza en UNA línea y sube según se escribe, sin pasar de media
   pantalla: a partir de ahí se desplaza por dentro. Ocupar el alto entero desde
   el principio, que es como estuvo un rato, dejaba un vacío enorme entre la
   primera línea y los botones. */
/* Empieza en UNA línea y sube con lo escrito, sin pasar de media pantalla: a
   partir de ahí se desplaza por dentro. Aquí vivía un `min-height: 40vh` del
   diseño anterior, cuando el campo ocupaba la hoja entera; con el compositor
   abajo, ese mínimo dejaba 264 px de campo vacío empujando los botones fuera de
   la pantalla. Medido, no supuesto. */
.escribir {
  max-height: 45dvh;
  overflow-y: auto;
}

.escribir::placeholder { color: var(--tinta-suave); }
.escribir:focus { outline: none; }

/* La línea va aquí arriba, en el compositor entero, y no debajo del campo:
   lo que se separa de lo escrito es el bloque de escribir, no los botones. */
.carta {
  border-top: 1px solid var(--hairline);
  padding-top: 0.75rem;
  width: 100%;
  max-width: 38rem;
  margin: 0 auto;
  padding: 0 var(--margen);
  display: flex;
  flex-direction: column;
  flex: none;
}

/* La barra baja se pega al fondo y sube con el teclado. El botón queda siempre
   a un dedo del pulgar, que es la distancia que decide si esto se usa. */
.barra {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.adjuntar,
.boton {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  /* 44×44 como mínimo. Esto se usa medio dormido y con una mano. */
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.6rem 1.25rem;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: opacity 240ms ease;
}

.adjuntar { border: none; padding-left: 0; color: var(--tinta-suave); }

.guardar {
  margin-left: auto;
  background: var(--lampara);
  color: #1A1508;
  border-color: transparent;
}

.guardar[disabled] { opacity: 0.45; cursor: default; }

.elegido {
  font-size: 0.8125rem;
  color: var(--tinta-suave);
  margin: 0.5rem 0 0;
}

/* --- Leer ----------------------------------------------------------------- */

.entrada { margin: 0 0 1.75rem; }

.entrada .texto {
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 400;
  font-variation-settings: "opsz" 24, "SOFT" 30;
  line-height: 1.55;
  /* Los saltos de línea que alguien escribió son parte de cómo lo dijo. */
  white-space: pre-wrap;
  margin: 0;
}

.entrada .marca {
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--tinta-suave);
  margin: 0 0 0.3rem;
}

.adjuntos { margin-top: 0.9rem; display: grid; gap: 0.5rem; }
.adjuntos img, .adjuntos video { width: 100%; border-radius: 6px; display: block; }
.adjuntos audio { width: 100%; }

.recuerdo {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
}

/* Un enlace pequeño, nunca un botón grande: añadir otra entrada no compite con
   haber cerrado el día. */
.anyadir {
  font-size: 0.875rem;
  color: var(--tinta-suave);
  margin-top: 2rem;
}

.anyadir summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.dia-timeline { margin-bottom: 2.5rem; }
.mas { margin-top: 2rem; }

/* --- Calendario ----------------------------------------------------------- */

.meses {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
  font-size: 0.875rem;
}

.calendario { width: 100%; border-collapse: collapse; table-layout: fixed; }

.calendario th {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--tinta-suave);
  padding-bottom: 0.5rem;
}

.calendario td { padding: 1px; }

.dia {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  min-height: 44px;
  font-size: 0.9375rem;
  text-decoration: none;
  border-radius: 6px;
}

/* Un día escrito se ve; uno en blanco, simplemente menos. Ni verde ni rojo: los
   huecos no son faltas. */
.dia.cubierto { background: color-mix(in oklab, var(--tinta) 14%, transparent); }
.dia.hueco { opacity: 0.35; }
.dia.futuro { opacity: 0.18; }

/* El punto de hoy va en un atributo aparte y no en la clase para que la clase
   siga diciendo solo una cosa: si el día está escrito o no. */
.dia[data-hoy]::after {
  content: "";
  position: absolute;
  bottom: 5px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--lampara);
}

.leyenda { font-size: 0.8125rem; color: var(--tinta-suave); margin-top: 1.25rem; }

/* --- Buscar --------------------------------------------------------------- */

.buscador { display: flex; gap: 0.75rem; margin-bottom: 1.5rem; }

.buscador input,
.campo {
  flex: 1;
  min-width: 0;
  font-family: var(--sans);
  /* 1rem o más: por debajo de eso Safari hace zoom al enfocar y la pantalla da
     un salto justo al empezar a escribir. */
  font-size: 1rem;
  padding: 0.7rem 0.9rem;
  min-height: 44px;
  color: inherit;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 8px;
}

.resultados { list-style: none; padding: 0; margin: 0; }
.resultados li { padding: 1rem 0; border-bottom: 1px solid var(--hairline); }

.fragmento {
  font-family: var(--serif);
  font-size: 1.0625rem;
  font-variation-settings: "opsz" 20, "SOFT" 30;
  margin: 0.35rem 0 0;
}

mark {
  background: color-mix(in oklab, var(--tinta) 18%, transparent);
  color: inherit;
  border-radius: 3px;
  padding: 0 0.1em;
}

.enlace-suave {
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--tinta-suave);
  text-decoration: none;
}

/* --- La banda de los días -------------------------------------------------- */
/*
 * Un trazo por día en lugar de una cuadrícula de casillas. La cuadrícula es lo
 * que hace todo el mundo y convierte cada hueco en una acusación; leída de
 * lejos, la banda parece el sismógrafo de una vida, que es exactamente lo que
 * es.
 */
.banda { margin-bottom: 1.5rem; }

.banda svg {
  display: block;
  width: 100%;
  height: 2.25rem;
  color: var(--tinta);
}

.banda .pie {
  font-size: 0.8125rem;
  color: var(--tinta-suave);
  margin: 0.35rem 0 0;
}

.cifra {
  font-family: var(--sans);
  font-size: 2.5rem;
  font-weight: 300;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  margin: 0;
}

/* --- Ajustes, entrar, exportar --------------------------------------------- */

.ajuste { margin-bottom: 2.5rem; }
.lista { list-style: none; padding: 0; margin: 0 0 1rem; }

.lista li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  min-height: 44px;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.9375rem;
}

.en-linea { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }
/* Los párrafos no llevan margen superior (ver la regla de `p`), así que un texto
   justo debajo de uno de estos formularios se pega al campo y toca el anillo de
   foco. Se separa aquí, con el selector de hermano adyacente, en vez de tocar
   `.sereno` o `p`: esos salen en media aplicación y esto es un caso concreto. */
.en-linea + p { margin-top: 0.9rem; }
.formulario { display: grid; gap: 0.9rem; margin-bottom: 1.5rem; }
.casilla { display: flex; align-items: center; gap: 0.6rem; min-height: 44px; }

.centrada {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.aviso {
  font-size: 0.9375rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
}

/* --- Lo que quedó sin salir ------------------------------------------------ */
/*
 * Arriba del todo y con contraste. En iOS no hay sincronización en segundo
 * plano, así que si el dueño no lo ve, la frase se queda ahí para siempre.
 */
.pendientes {
  margin: 0;
  padding: 0.75rem var(--margen);
  text-align: center;
  font-size: 0.875rem;
  background: color-mix(in oklab, var(--tinta) 88%, transparent);
  color: var(--fondo);
}

/* --- Menú ------------------------------------------------------------------ */

.menu {
  flex: none;
  display: flex;
  justify-content: space-around;
  padding: 0.35rem var(--margen) calc(0.35rem + env(safe-area-inset-bottom));
  /* El fondo NO es el de la página, y esa es la corrección: respetar el
     indicador de inicio del iPhone obliga a dejar tres centímetros de aire bajo
     los enlaces, y con el mismo color que el resto ese aire se lee como una
     banda muerta colgando del menú en vez de como parte de la barra. Un tinte
     mínimo hace que todo —enlaces y aire— sea un solo objeto. */
  background-color: color-mix(in oklab, var(--tinta) 7%, var(--fondo));
  border-top: 1px solid var(--hairline);
  /* Y el desenfoque de detrás, para que el texto que pase por debajo al hacer
     scroll no compita con las etiquetas. */
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Mientras se escribe, el menú se va. Con el teclado abierto se quedaba pegado
   justo encima, compitiendo con la barra de sugerencias de iOS, y en la pantalla
   donde no debe haber nada más que el texto y Guardar. */
body.escribiendo .menu {
  transform: translateY(110%);
  transition: transform 180ms ease-out;
}

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

.menu a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.5rem;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--tinta-suave);
  text-decoration: none;
}
