/* Base de diseño compartida por la landing y por la app.
   Vive acá y no en landing.css para que las dos usen los MISMOS tokens: si el
   color o la tipografía se definieran dos veces, se separarían al primer
   cambio. landing.css y sitio.css cargan este archivo antes que el propio.

   Los tokens y su contraste están documentados abajo, junto a :root. */

/* ── Fuentes vendorizadas ───────────────────────────────────────────────────
   Archivo (variable 400-800) y Spline Sans Mono (variable 300-700), las dos
   SIL OFL 1.1 — redistribuibles en producto comercial. Subsets latin y
   latin-ext: U+0000-00FF cubre ñ á é í ó ú ü ¿ ¡, verificado leyendo el cmap
   de cada archivo. Ver static/fonts/LEEME.txt

   Spline Sans Mono reemplazó a IBM Plex Mono. Se eligió midiendo el avance
   por em en el propio archivo, porque las celdas de la planilla y los nombres
   de archivo están ajustados al ancho: Plex 0.600, Spline 0.600 (idéntico),
   Sometype 0.580, Reddit 0.5625, Martian 0.700 (+17%, habría desbordado).
   Al ser variable, un archivo cubre los pesos 400/500/600 que antes eran
   tres. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 75% 100%;
  font-display: swap;
  src: url("../fonts/archivo-400_800-latin.2f7ea45bad3a.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 75% 100%;
  font-display: swap;
  src: url("../fonts/archivo-400_800-latin-ext.cde95d2797df.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
                 U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
                 U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Spline Mono";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/spline-sans-mono-300_700-latin.4ebf124f4aa2.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Spline Mono";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/spline-sans-mono-300_700-latin-ext.b7a3170e5df9.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
                 U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
                 U+2C60-2C7F, U+A720-A7FF;
}

/* ── Tokens ─────────────────────────────────────────────────────────────────
   Los neutros llevan un toque del verde de marca (croma 0.003-0.014 en OKLCH):
   un gris perfectamente neutro al lado de un verde saturado se lee apagado.
   Están escritos en hex, no en oklch(), porque el valor se convirtió una vez y
   así no depende del soporte del navegador.

     token     OKLCH                    hex      contraste sobre blanco/lienzo
     blanco    oklch(99.5% 0.003 165)   #FCFEFD  —
     lienzo    oklch(97.2% 0.007 165)   #F2F7F4  —
     raya      oklch(91.2% 0.008 165)   #DDE4E0  —
     tinta     oklch(21.5% 0.014 165)   #131C18  17.18 / 16.06
     cuerpo    oklch(44.5% 0.012 165)   #4E5652   7.47 /  6.98
     apagado   oklch(53.5% 0.013 165)   #67706B   5.05 /  4.72

   Todos calculados, no tanteados. --apagado es el que vive al filo: en 56.5%
   daba 4.20 sobre lienzo y NO pasaba AA; por eso está en 53.5%. Cualquier
   intento de aclararlo tiene que recalcularse. */

:root {
  --alto-barra: 4rem;

  --blanco:   #FCFEFD;
  --lienzo:   #F2F7F4;
  --tinta:    #131C18;
  --cuerpo:   #4E5652;
  --apagado:  #67706B;
  --raya:     #DDE4E0;
  --verde:    #0F7A52;
  --verde-tenue: #E8F3ED;

  /* Familias de documento. Cada par (fuerte, tinte) está calculado contra AA:
     el fuerte da ≥4.5 sobre su tinte Y sobre blanco, y blanco sobre el fuerte
     también pasa. No se eligió ninguno a ojo. */
  --cobro:        #0F7A52;  --cobro-tenue:        #E6F2EC;
  --operaciones:  #1D5FA8;  --operaciones-tenue:  #E7EFF9;
  --legales:      #7A3E9D;  --legales-tenue:      #F1E9F7;
  --comunicacion: #B0501A;  --comunicacion-tenue: #FBEDE3;

  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  /* La serif es de SISTEMA y no se descarga: cero bytes y cero pedidos. En
     Mac cae en New York, en Windows en Georgia, en Linux en la serif que
     haya. No es una serif de titulares con contraste alto —eso pide una
     licencia y un woff2 más— pero cambia el registro de la página, que es lo
     que hace falta: las páginas de /modelos/ son mil palabras de lectura y
     todo en Archivo se leía como una pantalla de la app. */
  --serif: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  /* La mono se usa SÓLO donde el contenido es dato: nombres de archivo, celdas
     de la planilla, la llamada a la API, las siglas de formato. Como rótulo
     decorativo es disfraz, no información. */
  --mono: "Spline Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Sombras en capas: una corta para el contacto, una larga y muy suave para
     la elevación. Reemplazan a los bordes de 1px. */
  --sombra-baja:
    0 1px 2px rgba(19, 28, 24, .05),
    0 2px 8px rgba(19, 28, 24, .04);
  --sombra-media:
    0 1px 2px rgba(19, 28, 24, .06),
    0 6px 16px rgba(19, 28, 24, .06),
    0 14px 40px rgba(19, 28, 24, .05);
  --sombra-alta:
    0 2px 4px rgba(19, 28, 24, .06),
    0 12px 28px rgba(19, 28, 24, .08),
    0 32px 68px rgba(19, 28, 24, .07);

  --ancho: 68rem;
  --canal: clamp(1.25rem, 5vw, 2.5rem);
  --radio: 12px;
}

* { box-sizing: border-box; }

/* `hidden` tiene que ganar SIEMPRE.

   El navegador esconde un elemento con el atributo `hidden` mediante una regla
   de su hoja por defecto —`[hidden] { display: none }`— y esa regla la pisa
   cualquier selector de clase, que tiene más especificidad. O sea que
   `.boton { display: inline-flex }` deja visible a un `<button hidden>`.

   No es hipotético: el contador de avisos del editor (`#btn-avisos`) nace con
   `hidden` y el JS lo muestra sólo cuando hay avisos. Como es un `.boton`,
   estuvo dibujándose SIEMPRE — una caja ámbar vacía en la barra de una
   plantilla sin un solo aviso. Se descubrió recién al ponerle un ícono
   adentro, porque hasta entonces la caja no tenía contenido y pasaba por un
   hueco del layout.

   Va acá arriba, con el reset, para que valga en todo el sitio y no sólo donde
   alguien se acuerde. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--blanco);
  color: var(--tinta);
  font-family: var(--display);
  font-size: 16px;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; }
img { max-width: 100%; }
::selection { background: var(--verde-tenue); color: var(--tinta); }

:focus-visible {
  outline: 2px solid var(--verde);
  outline-offset: 3px;
  border-radius: 4px;
}

.env {
  max-width: var(--ancho);
  margin: 0 auto;
  padding-inline: var(--canal);
}

section { padding-block: clamp(4rem, 9vw, 7rem); }
.tono { background: var(--lienzo); }

/* Sólo para lectores de pantalla: la cinta de formatos es decorativa. */
.oculto-visual {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.encabezado-centro { text-align: center; }
.encabezado-centro .titulo-seccion,
.encabezado-centro .bajada-seccion { margin-inline: auto; }

/* ── Tipografía ─────────────────────────────────────────────────────────── */

h1, h2, h3 { margin: 0; letter-spacing: -.025em; line-height: 1.1; }

/* El rótulo sobre un título de sección. En la landing quedó UNO solo: cuatro
   secciones seguidas con el mismo rótulo en versalitas es una muletilla, no una
   voz. Tampoco va en mono: como la palabra no es un dato, la mono ahí era
   disfraz. Ahora es la misma familia del resto, en verde y con más peso. */
.rotulo {
  margin: 0 0 .7rem;
  font-size: .8rem;
  font-weight: 650;
  letter-spacing: .02em;
  color: var(--verde);
}

.titulo-seccion {
  font-size: clamp(1.85rem, 3.6vw, 2.7rem);
  font-weight: 700;
  max-width: 20ch;
  text-wrap: balance;
}

.bajada-seccion {
  margin: 1rem 0 0;
  max-width: 46ch;
  font-size: 1.05rem;
  color: var(--cuerpo);
}

.encabezado { margin-bottom: clamp(2.5rem, 5vw, 3.75rem); }

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

.barra {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(252, 254, 253, .8);
  backdrop-filter: saturate(180%) blur(12px);
}
/* El alto de la barra sale de acá y de ningún otro lado: el editor pega su
   propia cabecera JUSTO debajo, y si el número se copia a mano las dos se
   superponen la próxima vez que alguna cambie. */
.barra-in { display: flex; align-items: center; gap: .3rem; min-height: var(--alto-barra); }

/* La barra ocupa TODO el ancho, no la columna de contenido.

   El fondo ya iba de borde a borde, pero lo de adentro heredaba el `max-width`
   de `.env` —68rem— así que en una pantalla ancha la marca arrancaba flotando
   en el medio y el botón terminaba lejos del borde derecho. Se leía como una
   isla, no como una barra.

   Además era el único elemento fijo que hacía eso: `.editor-cabecera` ya va a
   todo el ancho con el truco de los 50vw, así que al editar convivían dos
   barras pegadas una arriba de la otra con anchos distintos.

   Se conserva `padding-inline: var(--canal)` de `.env`: a todo el ancho no
   quiere decir pegado al vidrio. */
.barra .barra-in { max-width: none; position: relative; }

/* ── La barra de las páginas PÚBLICAS: una píldora que flota ───────────────
   El fondo de la barra se vuelve transparente y lo que se ve es `.barra-in`:
   blanca, redondeada, con borde y sombra, con aire alrededor. Sigue pegada
   arriba, y la píldora es opaca (.92 + blur) para que el contenido que pasa
   por atrás no ensucie los enlaces.

   Nació en la landing y vive acá desde el 31/08, para que TODAS las públicas
   —modelos, docs, legales, entrar, registro— se vean igual que ella. Antes
   había tres barras distintas: la píldora de la landing, la plana del resto
   de las públicas, y la de la app.

   `:not(.barra-app)` es lo que la deja afuera de la aplicación, a propósito:
   adentro la barra tiene que estar QUIETA y pegada al borde —es chrome de
   trabajo, no una pieza de diseño— y una píldora flotando ahí llamaría la
   atención sobre sí misma todo el día. */
.barra:not(.barra-app) {
  background: transparent;
  backdrop-filter: none;
  padding: .75rem .75rem 0;
}
.barra:not(.barra-app) .barra-in {
  max-width: 72rem;
  margin-inline: auto;
  background: rgba(252, 254, 253, .92);
  backdrop-filter: saturate(180%) blur(12px);
  border: 1px solid var(--raya);
  border-radius: 14px;
  box-shadow: var(--sombra-media);
}
@media (max-width: 640px) {
  .barra:not(.barra-app) { padding: .5rem .5rem 0; }
  .barra:not(.barra-app) .barra-in { border-radius: 11px; }
}

/* ── La barra de la app ───────────────────────────────────────────────────
   Tres cosas: la marca, el nombre de la pantalla en el medio, y la cuenta.

   El porqué es de producto y no de estilo: usar esto tiene que sentirse una
   APLICACIÓN y no una página. Una fila de enlaces arriba de la pantalla donde
   el cliente pasa el día es lo que la vuelve un sitio web. Los enlaces que
   salieron viven ahora en la home, en la landing y en /cuenta/.

   Es una grilla de tres columnas y no un flex con `margin-left:auto`, porque
   el título tiene que quedar centrado respecto de la PANTALLA y no del hueco
   que le dejan los vecinos: con flex, un correo largo en el menú lo correría
   hacia la izquierda. Las dos columnas de los costados miden lo mismo (1fr) y
   el centro se queda quieto aunque la marca y el menú midan distinto.

   `min-height` sale de --alto-barra, igual que .barra-in: el editor pega su
   cabecera JUSTO debajo con ese mismo valor, y si acá midiera otra cosa se
   superponen. No cambiar sin mirar .editor-cabecera. */
.barra-app-in {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: var(--alto-barra);
  padding-inline: var(--canal);
  position: relative;
}
.barra-app-in .marca { justify-self: start; }

.barra-titulo {
  justify-self: center;
  margin: 0;
  padding: .3rem .9rem;
  border-radius: 999px;
  background: var(--lienzo);
  color: var(--cuerpo);
  font-size: .9rem;
  font-weight: 600;
  white-space: nowrap;
}

/* El menú de la cuenta: <details>, sin JavaScript, igual que el «···». */
.menu-cuenta { justify-self: end; position: relative; }
.menu-cuenta > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; border-radius: 999px;
  color: var(--cuerpo);
}
.menu-cuenta > summary::-webkit-details-marker { display: none; }
.menu-cuenta > summary:hover { background: var(--lienzo); color: var(--tinta); }
.menu-cuenta-panel {
  position: absolute; right: 0; top: 2.6rem; z-index: 2;
  min-width: 12rem; padding: .3rem;
  background: var(--blanco); border-radius: 9px;
  box-shadow: var(--sombra-alta);
}
/* Quién sos, arriba del todo. Salió de la barra —era un enlace más— y acá
   cumple mejor: en el menú de la cuenta, decir de qué cuenta es no es
   navegación, es la respuesta a la pregunta que uno viene a hacerse. */
.menu-cuenta-quien {
  margin: 0; padding: .45rem .6rem .55rem;
  font-size: .78rem; color: var(--apagado);
  overflow-wrap: anywhere;
}
.menu-cuenta-panel .menu-opcion {
  display: block; width: 100%; padding: .5rem .6rem;
  border: 0; border-radius: 6px; background: none;
  color: var(--tinta); font: inherit; font-size: .88rem;
  text-align: left; text-decoration: none; cursor: pointer;
}
.menu-cuenta-panel .menu-opcion:hover { background: var(--lienzo); }
.menu-cuenta-panel form { margin: 0; }

/* En el teléfono el título se va: entre la marca y la cuenta no queda ancho
   para las tres cosas, y de las tres la que menos falta hace es la que dice
   dónde estás — ya lo dice la pantalla. */
@media (max-width: 34rem) {
  .barra-titulo { display: none; }
}

/* ── El menú del teléfono ─────────────────────────────────────────────────
   Sin JavaScript, con una casilla y su etiqueta.

   No es capricho: la landing no carga un solo <script> —toda la animación es
   CSS— y por eso tampoco tiene banner de cookies ni un solo error de consola.
   Meterle JS para abrir un menú tira esa propiedad por un desplegable.

   Se usa la casilla y no <details> porque el navegador esconde el contenido de
   un <details> cerrado por su cuenta, y las versiones nuevas de Chrome lo hacen
   con `content-visibility` sobre un pseudoelemento, que el CSS de la página ya
   no puede revertir para mostrarlo en línea en pantalla ancha. Con la casilla
   el control es del CSS y de nadie más.

   Antes de esto, a menos de 40rem los enlaces simplemente se escondían
   (`.barra .solo-ancho { display: none }`) y no había NINGUNA forma de llegar
   a precios ni a la galería desde el teléfono. */
.menu-check {
  /* Visualmente oculta pero enfocable: es el control real, y esconderla con
     `display:none` la sacaría del tabulador. */
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.menu-boton { display: none; }
.menu-enlaces { display: flex; align-items: center; gap: .3rem; }

@media (max-width: 40rem) {
  .menu-boton {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    /* 44px: el mínimo táctil de iOS. El resto de la barra ya lo respeta. */
    min-height: 44px;
    padding: .5rem .7rem;
    font-size: .9rem;
    color: var(--cuerpo);
    cursor: pointer;
    user-select: none;
    /* El «☰» y la palabra van juntos: sin esto el icono quedaba en un renglón
       y «Menú» en el de abajo, y la barra volvía a crecer de alto. */
    white-space: nowrap;
  }
  /* El foco tiene que verse: la casilla está oculta, así que el anillo lo
     dibuja la etiqueta. */
  .menu-check:focus-visible + .menu-boton {
    outline: 2px solid var(--verde);
    outline-offset: 2px;
    border-radius: .3rem;
  }

  .menu-enlaces {
    display: none;
    position: absolute;
    top: 100%;
    right: var(--canal);
    left: var(--canal);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: .35rem;
    background: var(--blanco);
    border: 1px solid var(--borde);
    border-radius: .5rem;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .12);
  }
  .menu-check:checked ~ .menu-enlaces { display: flex; }
  .menu-enlaces > * { min-height: 44px; display: flex; align-items: center; }
}

.marca {
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-weight: 650;
  font-size: 1.03rem;
  letter-spacing: -.02em;
  text-decoration: none;
}
/* El glifo de marca: el abanico en verdes (01/09) — tres hojas abriéndose,
   una plantilla y sus copias. Elegido en la exploración de logos; la fuente
   vive en disenio/assets-propuesta/logos/final/marca.svg y este data URI es
   ESA marca, embebida para no costar un pedido. Tres colores, así que va
   como imagen y no como pseudoelementos pintados. */
.glifo {
  width: 1.55rem;
  height: 1.55rem;
  flex: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none'%3E%3Cg transform='rotate(28 10 25.5)'%3E%3Crect x='10' y='6.5' width='13' height='19' rx='2' fill='%239ED7BC'/%3E%3C/g%3E%3Cg transform='rotate(14 10 25.5)'%3E%3Crect x='10' y='6.5' width='13' height='19' rx='2' fill='%233FB183'/%3E%3C/g%3E%3Crect x='10' y='6.5' width='13' height='19' rx='2' fill='%230F7A52'/%3E%3Crect x='13' y='11.5' width='7' height='2' rx='1' fill='%23FCFEFD'/%3E%3Crect x='13' y='16' width='5' height='2' rx='1' fill='%23FCFEFD' opacity='.65'/%3E%3C/svg%3E") no-repeat center / contain;
}

.enlace {
  padding: .5rem .7rem;
  font-size: .9rem;
  color: var(--cuerpo);
  text-decoration: none;
  border-radius: 6px;
  transition: color .15s, background-color .15s;
}
.enlace:hover { color: var(--tinta); background: var(--lienzo); }

/* Cambio de idioma. El globo dice «esto es idioma»; la palabra —el idioma
   destino escrito en su propio idioma— dice hacia dónde vas. Nunca banderas:
   una bandera representa un país, y el público es de toda Latinoamérica. */
.enlace-idioma { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
/* El `grayscale(1)` que había acá era para el emoji 🌐, que salía en color: lo
   apagaba en reposo y lo devolvía a color al pasar por encima. Ahora el globo
   es de trazo y hereda `currentColor`, así que el filtro no filtra nada. Queda
   sólo el cambio de opacidad, que sigue diciendo lo mismo con menos. */
.globo { line-height: 0; opacity: .7; transition: opacity .15s; }
.enlace-idioma:hover .globo { opacity: 1; }

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

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .78rem 1.4rem;
  border: 0;
  border-radius: 8px;
  background: var(--tinta);
  color: var(--blanco);
  font-family: inherit;
  font-size: .95rem;
  font-weight: 550;
  letter-spacing: -.005em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--sombra-baja);
  transition: transform .14s cubic-bezier(.3,.7,.4,1),
              box-shadow .14s, background-color .14s;
}
.boton:hover { background: #2A2A30; transform: translateY(-1px); box-shadow: var(--sombra-media); }
.boton:active { transform: translateY(0); }
.boton-chico { padding: .55rem 1rem; font-size: .88rem; border-radius: 7px; }
.boton-liso {
  background: var(--blanco);
  color: var(--tinta);
  box-shadow: inset 0 0 0 1px var(--raya), var(--sombra-baja);
}
.boton-liso:hover { background: var(--lienzo); }
/* Acciones destructivas: rojo verificado a 6.54 sobre blanco. */
.boton-peligro { background: #B3261E; }
.boton-peligro:hover { background: #8C1D18; }


/* ── Pie ────────────────────────────────────────────────────────────────── */

.pie { border-top: 1px solid var(--raya); padding-block: 2.25rem 2.75rem; }
.pie-in { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.pie-nav { margin-left: auto; display: flex; gap: .15rem; flex-wrap: wrap; }
/* La firma de snaplabs. El lockup se dibuja chico (18px de alto) y con el
   ancho que le corresponde por su viewBox 330×100: nunca estirado. Es el
   único lugar del sitio con el índigo de otra marca, así que va apagado en
   reposo y a color completo al pasar por encima — firma, no reclamo. */
.pie-firma {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;   /* centrada en la página, no pegada al margen */
  gap: .6rem;
  margin: 1.75rem 0 0;
  font-size: .88rem;
  color: var(--apagado);
}
.pie-firma a { display: inline-flex; align-items: center; border-radius: 4px; }
.pie-firma img {
  height: 30px;              /* legible: a 18px la palabra no se leía */
  width: auto;
  display: block;
  opacity: .8;
  transition: opacity .15s;
}
.pie-firma a:hover img { opacity: 1; }
.pie-firma a:focus-visible { outline: 2px solid var(--verde); outline-offset: 3px; }


/* ── El fondo de planilla ────────────────────────────────────────────────────
   La caja de login estaba sola en un lienzo vacío y no decía de qué es el
   producto. Ahora atrás hay una planilla: celdas en hairline que se desvanecen
   hacia abajo.

   Se dibuja con gradientes y no con una imagen: cero pedidos, cero bytes, y
   escala a cualquier pantalla sin verse borrosa.

   Va en un pseudoelemento y no en el `background` del body por el DESVANECIDO.
   Sin él, las líneas llegan hasta el pie y la pantalla se lee como una tabla
   de verdad —con el pie adentro de una celda— en vez de como un fondo. El
   `mask-image` es lo que la apaga antes de llegar abajo, y una máscara sobre
   el body es incómoda de acotar.

   Vive en base.css y no en sitio.css porque lo usan la landing —que no carga
   sitio.css— y las seis pantallas de la familia del login. */
.fondo-planilla { background: var(--lienzo); }

.fondo-planilla::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;                 /* detrás de todo, y sin robar clicks */
  pointer-events: none;
  background-image:
    radial-gradient(60% 45% at 50% 0%, rgba(15, 122, 82, .08), transparent 70%),
    repeating-linear-gradient(to right, rgba(19, 28, 24, .055) 0 1px, transparent 1px 8.5rem),
    repeating-linear-gradient(to bottom, rgba(19, 28, 24, .055) 0 1px, transparent 1px 2.5rem);
  /* Fuerte arriba, nada a los dos tercios. La caja del formulario queda en la
     parte viva y el pie en el lienzo limpio. */
  mask-image: linear-gradient(to bottom, #000 0%, #000 22%, transparent 68%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 22%, transparent 68%);
}

/* ── Íconos ─────────────────────────────────────────────────────────────────
   Trazo, no emoji. El sprite vive en templates/partes/iconos.html y ahí está el
   porqué. Acá van el tamaño y la alineación.

   Vive en base.css y no en sitio.css porque la landing no carga esa hoja, y el
   globo del cambio de idioma es de la landing.

   `vertical-align` y no flex: el ícono casi siempre va DENTRO de un renglón de
   texto, y alinearlo por la caja lo deja flotando alto. Los -3px lo bajan a la
   altura de la x. */
.ic {
  width: 1em;
  height: 1em;
  flex: none;
  vertical-align: -.18em;
  /* Sin esto, un ícono adentro de un botón se estira cuando el botón crece. */
  min-width: 1em;
}
/* Tamaños fijos para cuando el ícono NO acompaña texto (un botón de sólo
   ícono, o una fila donde todos tienen que medir igual). */
.ic-14 { width: 14px; height: 14px; min-width: 14px; }
.ic-16 { width: 16px; height: 16px; min-width: 16px; }
.ic-18 { width: 18px; height: 18px; min-width: 18px; }
.ic-20 { width: 20px; height: 20px; min-width: 20px; }

/* Texto sólo para lectores de pantalla.

   Vive acá y no en sitio.css porque la landing no carga esa hoja. Las tres
   plantillas con <head> propio —base.html, landing.html y el formulario
   público— cargan base.css, así que es el único lugar donde una definición
   sola alcanza para todas. */
.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
