/* ============================================================
   Utilazo — hoja de estilos unica, organizada por secciones.
   Sin preprocesador ni paso de compilacion.

   Direccion visual: bloques. Papel crema, tinta negra, bordes
   gruesos y sombras duras (sin difuminar). El caracter esta en el
   contorno y en el color plano, no en degradados ni en brillos.
   ============================================================ */

/* --- 0. Tipografia --------------------------------------
   Space Grotesk servida desde aqui, NO desde fonts.googleapis.com.

   Dos motivos. El primero es el invariante del proyecto: nada de CDN en
   tiempo de ejecucion. La fuente era la unica excepcion que quedaba, y
   ademas era la unica peticion a un tercero en todo el sitio.

   El segundo es de privacidad: pedirla a Google transmite la IP de cada
   visitante antes de que haya consentido nada. Un juzgado de Munich lo
   considero infraccion del RGPD en enero de 2022. Es primera instancia
   alemana, no jurisprudencia europea, pero el sitio se dirige a Espana y
   presume de no rastrear a nadie: sostener eso con una peticion a Google en
   cada carga era contradictorio.

   Es una fuente VARIABLE: un solo archivo cubre de 300 a 700, asi que pesa
   menos que los tres pesos estaticos que se pedian antes. Los unicode-range
   son los mismos que sirve Google, para que el navegador solo baje el
   subconjunto que necesite. El vietnamita no se incluye.

   Licencia: SIL Open Font License 1.1, que permite alojarla.
   --------------------------------------------------------- */
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;   /* texto visible desde el primer momento */
  src: url("lib/fonts/space-grotesk-latin.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: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("lib/fonts/space-grotesk-latin-ext.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;
}

/* --- 1. Tokens ------------------------------------------- */
:root {
  --bg: #FFFCF2;          /* papel crema */
  --bg-alt: #F7F2E4;
  --surface: #FFFCF2;
  --paper: #FFFFFF;       /* campos y zonas de entrada */
  --ink: #1B1B1B;
  --text: #1B1B1B;
  --text-soft: #4A463E;
  --text-mute: #8C8779;

  --accent: #E4572E;      /* naranja de marca */
  --accent-hover: #C6431D;
  --yellow: #FFD447;
  --ok: #1E7A47;
  --warn: #B45309;
  --err: #C42B1C;

  --border: var(--ink);
  --border-strong: var(--ink);
  --bw: 2px;              /* grosor estandar */
  --bw-lg: 3px;           /* estructura: cabecera, secciones */

  /* Sombra dura: el sello de esta direccion. Nunca difuminada. */
  --shadow: 4px 4px 0 var(--ink);
  --shadow-sm: 3px 3px 0 var(--ink);
  --shadow-lg: 6px 6px 0 var(--ink);

  /* Un color por categoria: rellenos planos, siempre con tinta encima. */
  --c-imagen: #C7E9F1;
  --c-documentos: #FFD447;
  --c-calculadoras: #FFC9B5;
  --c-generadores: #E7D3F5;
  --c-internet: #CDEBC5;

  /* Texto que va ENCIMA de un relleno de categoria o del amarillo. Los
     rellenos siguen siendo claros tambien en modo oscuro, asi que su texto
     es siempre tinta oscura: usar var(--ink) los volveria ilegibles al
     invertir el tema. */
  --on-c: #1B1B1B;

  --radius: 0px;          /* los bloques no tienen esquinas redondeadas */
  --radius-sm: 0px;
  --maxw: 980px;
  --font: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* --- 1b. Modo oscuro -------------------------------------
   No es el tema claro invertido: es el mismo lenguaje con los papeles
   cambiados. La tinta pasa a ser crema, asi que los bordes y las sombras
   duras se vuelven claros automaticamente (estan definidos con var(--ink))
   y siguen leyendose como bloques recortados sobre el fondo.

   Los rellenos de categoria NO se oscurecen: siguen siendo pastillas claras
   sobre fondo oscuro, que es lo que mantiene reconocible el sitio. Su texto
   lo fija --on-c, que no cambia con el tema.
   --------------------------------------------------------- */
/* El tema se decide asi, por orden:
     1. Lo que el visitante haya elegido (atributo data-tema en <html>, que
        guarda main.js en localStorage y aplica un script del <head> antes de
        pintar, para que no haya parpadeo).
     2. Si no ha elegido nada, lo que pida su sistema.
   Por eso cada bloque oscuro se declara DOS veces: una para el sistema
   (excluyendo a quien ha forzado claro) y otra para la eleccion explicita. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --bg: #15140F;        /* negro calido, no gris azulado: es el mismo papel */
    --bg-alt: #1D1B14;
    --surface: #15140F;
    --paper: #201E17;
    --ink: #FFFCF2;       /* la tinta ahora es crema: bordes y sombras claros */
    --text: #FFFCF2;
    --text-soft: #C4BDAC;
    --text-mute: #8C8779;

    --accent: #FF7A4D;    /* el naranja de marca se aclara para el fondo oscuro */
    --accent-hover: #FF9670;
    --ok: #4ADE80;
    --warn: #FBBF24;
    --err: #FF6B5A;
  }
}
:root[data-tema="oscuro"] {
    --bg: #15140F;        /* negro calido, no gris azulado: es el mismo papel */
    --bg-alt: #1D1B14;
    --surface: #15140F;
    --paper: #201E17;
    --ink: #FFFCF2;       /* la tinta ahora es crema: bordes y sombras claros */
    --text: #FFFCF2;
    --text-soft: #C4BDAC;
    --text-mute: #8C8779;

    --accent: #FF7A4D;    /* el naranja de marca se aclara para el fondo oscuro */
    --accent-hover: #FF9670;
    --ok: #4ADE80;
    --warn: #FBBF24;
    --err: #FF6B5A;
}

/* --- 2. Base --------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

/* Movimiento reducido: se respeta lo que pide el sistema.
   Para bastante gente el movimiento en pantalla no es una cuestion de gusto,
   sino de mareo. Aqui se anula TODO de una vez -el desplazamiento suave, las
   apariciones al bajar y cualquier transicion- en lugar de ir apagandolo
   animacion por animacion y olvidarse de alguna. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Aparicion al bajar ----------------------------------
   "va-entrar" la pone main.js, nunca el HTML: si el JavaScript falla o esta
   desactivado, la clase no llega a existir y el contenido se ve entero. Un
   efecto no puede ser la razon de que alguien no pueda leer la pagina.

   Se animan solo transform y opacity, que el navegador resuelve en la GPU
   sin volver a calcular el diseno. Animar altura o margen aqui provocaria
   tirones en cuanto hubiera varios bloques a la vez. */
.va-entrar {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .5s ease-out, transform .5s cubic-bezier(.22, .8, .3, 1);
  will-change: opacity, transform;
}
.va-entrar.ya-entro {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Escalonado corto dentro de una misma rejilla: las tarjetas entran una
   detras de otra en vez de todas de golpe. Cuatro pasos bastan; mas empieza
   a parecer lento en las rejillas de veinte herramientas. */
.tool-grid > li.va-entrar:nth-child(4n+2) { transition-delay: .06s; }
.tool-grid > li.va-entrar:nth-child(4n+3) { transition-delay: .12s; }
.tool-grid > li.va-entrar:nth-child(4n+4) { transition-delay: .18s; }
body {
  margin: 0;
  overflow-x: hidden;   /* nada desplaza la pagina en horizontal */
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: var(--ink); text-underline-offset: 3px; }
a:hover { color: var(--accent); }
h1, h2, h3 { line-height: 1.05; letter-spacing: -.035em; margin: 0 0 .5em; font-weight: 700; }

/* El titulo de pagina va en MAYUSCULAS apretadas: es lo que da caracter a la
   direccion, y sin esto las paginas de herramienta parecian de otro sitio que
   la portada. Los h2 se quedan en caja normal a proposito: los titulares SEO
   son largos y una pared de mayusculas se lee mucho peor. */
h1 {
  font-size: clamp(1.75rem, 4.8vw, 2.7rem);
  text-transform: uppercase; letter-spacing: -.045em;
}
h2 { font-size: clamp(1.4rem, 3.2vw, 1.9rem); margin-top: 2em; }
h3 { font-size: 1.12rem; letter-spacing: -.02em; }
p { margin: 0 0 1em; }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }
.muted { color: var(--text-soft); }
.small { font-size: .9rem; }

/* --- 3. Cabecera / pie ----------------------------------- */
.site-header {
  border-bottom: var(--bw-lg) solid var(--ink);
  background: var(--bg);
  position: sticky; top: 0; z-index: 50;
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; height: 62px;
}
.logo {
  font-weight: 700; font-size: 1.32rem; letter-spacing: -.045em;
  text-transform: uppercase; text-decoration: none;
  color: var(--ink); display: flex; align-items: center; gap: 10px;
}
.logo-mark {
  width: 30px; height: 30px;
  border: var(--bw) solid var(--ink); background: var(--yellow);
  display: grid; place-items: center; color: var(--on-c);
  font-size: .95rem; font-weight: 700; letter-spacing: 0;
}
.tema-btn {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font: inherit; font-size: .78rem; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase;
  color: var(--ink); background: var(--bg);
  border: var(--bw) solid var(--ink); padding: 8px 12px;
  transition: transform .1s, box-shadow .1s, background .12s;
}
.tema-btn:hover { background: var(--yellow); color: var(--on-c); box-shadow: var(--shadow-sm); transform: translate(-1px, -1px); }
.tema-btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
@media (max-width: 520px) { .tema-txt { display: none; } .tema-btn { padding: 8px 10px; } }

.nav-tools {
  font-size: .82rem; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; text-decoration: none;
  color: var(--bg); background: var(--ink);
  padding: 9px 16px; border: var(--bw) solid var(--ink);
  transition: transform .1s, box-shadow .1s;
}
.nav-tools:hover {
  color: var(--bg); background: var(--accent); border-color: var(--ink);
  box-shadow: var(--shadow-sm); transform: translate(-1px, -1px);
}

/* Enlace a las guias: en secundario, para que no compita con el boton de
   herramientas, que es lo que casi todo el mundo viene buscando. */
.nav-guias {
  font-size: .82rem; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; text-decoration: none;
  color: var(--ink); padding: 9px 4px;
  border-bottom: var(--bw) solid transparent;
}
.nav-guias:hover { border-bottom-color: var(--ink); }
@media (max-width: 420px) { .nav-guias { display: none; } }

/* --- Medidas del redimensionador -------------------------
   Eran un <select> de 25 opciones. Desplegado tapaba la pantalla y, peor,
   estaba en el bloque que se oculta al cargar la imagen. Como botones se ven
   todos a la vez y se puede saltar de un tamano a otro sin volver a subir. */
.medidas-titulo { margin: 22px 0 2px; font-size: 1rem; }
.medidas { max-height: 260px; overflow-y: auto; padding-right: 4px; }
.medidas-red {
  margin: 12px 0 6px; font-size: .72rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute);
}
.medidas-red:first-child { margin-top: 0; }
.medidas-fila { display: flex; flex-wrap: wrap; gap: 6px; }

.medida {
  flex: 0 1 auto; text-align: left; cursor: pointer;
  font-family: inherit; font-size: .78rem; line-height: 1.25;
  padding: 7px 10px; background: var(--bg);
  border: var(--bw) solid var(--ink); color: var(--text);
}
.medida strong { display: block; font-weight: 700; }
.medida em { display: block; font-style: normal; font-size: .72rem; color: var(--text-mute); }
.medida:hover { background: var(--bg-alt); }
.medida.is-elegida { background: var(--ink); color: var(--bg); }
.medida.is-elegida em { color: var(--bg); opacity: .75; }

.medida-libre { margin-top: 12px; }
.crop-ayuda { text-align: center; margin: 8px 0 0; }
.controls-finos { margin-top: 12px; }
.field-corto { flex: 0 1 150px; }

/* Casilla con su etiqueta al lado. El <label> envuelve al <input>, asi que
   pulsar el texto tambien marca: no hace falta el atributo for. */
.check {
  display: flex; align-items: center; gap: 8px;
  font-weight: 500; cursor: pointer;
}
.check input { width: 17px; height: 17px; accent-color: var(--ink); cursor: pointer; }

/* --- Selector de idioma ----------------------------------
   No se pinta mientras el sitio sea de un solo idioma: build.py solo emite
   este bloque cuando la pagina existe de verdad en mas de uno. El estilo se
   deja escrito para que el dia que se active no haga falta tocar nada. */
.selector-idioma { display: inline-flex; border: var(--bw) solid var(--ink); }
.selector-idioma a {
  font-size: .74rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; text-decoration: none;
  padding: 7px 10px; color: var(--text-soft); background: var(--bg);
}
.selector-idioma a + a { border-left: var(--bw) solid var(--ink); }
.selector-idioma a:hover { background: var(--bg-alt); color: var(--ink); }
.selector-idioma a[aria-current] { background: var(--ink); color: var(--bg); }

/* --- Listas de guias ------------------------------------- */
.lista-guias { list-style: none; padding: 0; margin: 18px 0; display: grid; gap: 10px; }
.lista-guias a { text-decoration: none; color: inherit; }
.lista-guias > li > a { text-decoration: underline; }

.lista-guias-grande { gap: 14px; }
.lista-guias-grande > li > a {
  display: block; text-decoration: none;
  background: var(--paper); border: var(--bw) solid var(--ink);
  box-shadow: var(--shadow); padding: 16px 18px;
  transition: transform .1s, box-shadow .1s;
}
.lista-guias-grande > li > a:hover {
  transform: translate(-2px, -2px); box-shadow: var(--shadow-lg);
  background: var(--bg-alt);
}
.lista-guias-grande strong { display: block; font-size: 1.05rem; margin-bottom: 4px; }
.lista-guias-grande span { display: block; font-size: .9rem; color: var(--text-soft); }

.site-footer {
  margin-top: 60px; border-top: var(--bw-lg) solid var(--ink);
  background: var(--bg); padding: 26px 0; font-size: .85rem;
  font-weight: 500; color: var(--text-soft);
}
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 10px 22px; justify-content: space-between; }
.site-footer a { color: var(--ink); text-decoration: none; }
.site-footer a:hover { color: var(--accent); }

/* Barra de categorias: se desplaza en horizontal en el movil en lugar de
   partirse en varias filas y comerse media pantalla. */
.cat-bar { border-bottom: var(--bw-lg) solid var(--ink); background: var(--bg-alt); }
.cat-bar .wrap {
  display: flex; gap: 0; align-items: stretch;
  overflow-x: auto; scrollbar-width: none;
}
.cat-bar .wrap::-webkit-scrollbar { display: none; }
.cat-item { position: relative; flex: 0 0 auto; }
/* Cada boton lleva SU color de relleno, no un fondo neutro: la barra es la
   primera muestra de que este sitio va de bloques de color, y con todo en
   crema no se distinguia de cualquier otra web de herramientas. */
.cat-link {
  display: inline-flex; align-items: center; gap: 8px; height: 100%;
  white-space: nowrap; text-decoration: none; cursor: pointer;
  font: inherit; font-size: .84rem; font-weight: 700; letter-spacing: -.01em;
  color: var(--on-c); padding: 11px 18px;
  background: var(--c, var(--yellow)); border: 0;
  border-right: var(--bw) solid var(--ink);
  transition: background .12s, color .12s;
}
.cat-item:first-child .cat-link { border-left: var(--bw) solid var(--ink); }

/* Nombre largo en pantalla ancha, corto en movil. Los cinco largos suman
   841 px: en un movil de 390 no caben ni encogiendolos, y la barra se cortaba
   por la derecha con aspecto de rota. Con los cortos y menos relleno entra
   casi todo y el ultimo asoma, que es lo que se lee como "hay mas, desliza". */
.cat-corto { display: none; }
@media (max-width: 640px) {
  .cat-largo { display: none; }
  .cat-corto { display: inline; }
  .cat-link { padding: 11px 12px; font-size: .8rem; gap: 6px; }
  .cat-chevron { display: none; }   /* 12 px que se ganan por cada categoria */
  .cat-ico svg { width: 16px; height: 16px; }
}

/* Al pasar por encima y al estar abierta o activa se invierte a tinta: es el
   contraste mas fuerte disponible y no depende del color de la categoria. */
.cat-link:hover { background: var(--ink); color: var(--bg); }

/* Cada categoria tiene su relleno plano. */
[data-cat="imagen"]        { --c: var(--c-imagen); }
[data-cat="documentos"]    { --c: var(--c-documentos); }
[data-cat="calculadoras"]  { --c: var(--c-calculadoras); }
[data-cat="generadores"]   { --c: var(--c-generadores); }
[data-cat="internet"]      { --c: var(--c-internet); }

.cat-link.is-activa,
.cat-link[aria-expanded="true"] { background: var(--c, var(--yellow)); }
.cat-ico { display: inline-flex; }
.cat-ico svg { width: 17px; height: 17px; }
.cat-chevron { width: 12px; height: 12px; transition: transform .15s; }
.cat-link[aria-expanded="true"] .cat-chevron { transform: rotate(180deg); }

/* Panel desplegable de cada categoria.

   position: FIXED, no absolute. La barra usa overflow-x:auto para deslizarse
   en movil, y un contenedor con overflow recorta a sus hijos posicionados:
   el panel salia cortado a los pocos pixeles. Con position:fixed escapa del
   recorte, y main.js le calcula la posicion a partir del boton. */
.cat-menu {
  position: fixed; z-index: 60;
  min-width: 300px; max-width: min(360px, calc(100vw - 24px));
  /* Fondo neutro con una franja del color arriba, en vez del relleno entero:
     un panel relleno de color obliga a texto oscuro, y en modo oscuro el
     resto de la interfaz usa texto claro. Asi el panel funciona en los dos. */
  background: var(--paper);
  border: var(--bw-lg) solid var(--ink);
  border-top: 10px solid var(--c, var(--yellow));
  box-shadow: var(--shadow-lg); padding: 8px;
}
.cat-menu a {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 8px 10px; text-decoration: none; color: var(--ink);
  white-space: normal; border: var(--bw) solid transparent;
}
/* La franja de color del borde superior no debe desplazarse al hacer scroll
   dentro del panel: se queda pegada arriba como referencia de categoria. */
.cat-menu { scrollbar-width: thin; }
.cat-menu::-webkit-scrollbar { width: 10px; }
.cat-menu::-webkit-scrollbar-thumb { background: var(--ink); }
.cat-menu::-webkit-scrollbar-track { background: var(--bg-alt); }
.cat-menu a:hover { background: var(--paper); border-color: var(--ink); box-shadow: var(--shadow-sm); }
.cat-menu .cat-ico { padding-top: 1px; }
.cat-menu .cat-ico svg { width: 19px; height: 19px; }
.cat-menu strong { display: block; font-size: .93rem; font-weight: 700; }
.cat-menu em {
  display: block; font-style: normal; font-size: .81rem;
  color: var(--text-soft); line-height: 1.4; margin-top: 1px;
}
.cat-todas {
  margin-top: 6px; border-top: var(--bw) solid var(--ink) !important;
  border-radius: 0; font-size: .8rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; justify-content: center;
}

@media (max-width: 600px) {
  .cat-menu { left: 12px !important; right: 12px; max-width: none; min-width: 0; }
}

/* Titulos de categoria en el indice */
.cat-titulo {
  display: flex; align-items: center; gap: 12px; scroll-margin-top: 130px;
  text-transform: uppercase;
}
.cat-titulo svg {
  width: 36px; height: 36px; flex: 0 0 auto; padding: 6px;
  color: var(--on-c); background: var(--c, var(--yellow));
  border: var(--bw) solid var(--ink);
}
.cat-cuenta {
  font-size: .78rem; font-weight: 700; letter-spacing: 0;
  color: var(--ink); background: var(--paper);
  border: var(--bw) solid var(--ink); padding: 2px 10px;
}

/* --- 4. Portada ------------------------------------------ */
.hero { padding: 40px 0 30px; }
.hero h1 { text-wrap: balance; margin-bottom: 14px; }
.hero p.sub { font-size: 1.05rem; color: var(--text-soft); max-width: 620px; margin: 0; }
.hero-inicio { border-bottom: var(--bw-lg) solid var(--ink); }

.hero-badge {
  display: inline-block; background: var(--yellow);
  border: var(--bw) solid var(--ink); box-shadow: var(--shadow);
  padding: 5px 13px; margin-bottom: 20px; color: var(--on-c);
  font-weight: 700; font-size: .78rem; letter-spacing: .05em; text-transform: uppercase;
}
/* Crema sobre el naranja de marca da 3,6:1. Cumple porque esto SOLO se usa en
   el H1 de portada, que es texto grande (32-50 px en negrita, donde el minimo
   es 3:1). Si alguna vez se reutiliza en texto normal, hay que oscurecer el
   fondo a var(--accent-hover), que sube a 4,9:1. */
.hero-marca { background: var(--accent); color: var(--bg); padding: 0 11px; display: inline-block; }

/* Buscador */
.buscador {
  display: flex; max-width: 680px; margin-top: 26px;
  border: var(--bw-lg) solid var(--ink); background: var(--paper);
  box-shadow: var(--shadow-lg);
}
.buscador svg { width: 21px; height: 21px; flex: 0 0 auto; }
.buscador input {
  font: inherit; font-size: 1.02rem; font-weight: 500;
  border: 0; background: transparent; color: var(--ink);
  padding: 15px 14px; flex-grow: 1; min-width: 0; outline: none;
}
.buscador input::placeholder { color: var(--text-mute); }
.buscador label { display: flex; align-items: center; padding-left: 16px; }
.buscador-btn {
  font: inherit; font-weight: 700; font-size: .88rem;
  letter-spacing: .04em; text-transform: uppercase; cursor: pointer;
  background: var(--ink); color: var(--bg); border: 0;
  padding: 0 24px; white-space: nowrap;
}
.buscador-btn:hover { background: var(--accent); }

.atajos { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 18px; }
.atajo {
  font: inherit; font-size: .84rem; font-weight: 500; cursor: pointer;
  background: var(--bg); color: var(--ink);
  border: var(--bw) solid var(--ink); box-shadow: var(--shadow-sm);
  padding: 6px 12px; transition: transform .1s;
}
.atajo:hover { background: var(--yellow); color: var(--on-c); transform: translate(-1px, -1px); }

/* Resultados de la busqueda */
.resultados { margin: 26px 0 0; }
.res-vacio {
  border: var(--bw) solid var(--ink); background: var(--bg-alt);
  padding: 18px 20px; font-weight: 500;
}

/* --- 5. Tarjeta de herramienta --------------------------- */
.tool-card {
  background: var(--paper);
  border: var(--bw-lg) solid var(--ink);
  box-shadow: var(--shadow-lg);
  padding: 26px;
  margin: 24px 0 16px;
}
.dropzone {
  display: grid; place-items: center; gap: 10px; position: relative;
  padding: 44px 20px; text-align: center; cursor: pointer;
  border: var(--bw-lg) dashed var(--ink);
  background: var(--bg); transition: background .14s;
}
/* El hover SOLO donde hay puntero de verdad. En un movil, iOS deja pegado el
   estado :hover despues de tocar, y la zona se quedaba amarilla para siempre
   con el texto secundario gris encima, ilegible. */
@media (hover: hover) {
  .dropzone:hover { background: var(--yellow); color: var(--on-c); }
}
.dropzone.is-over { background: var(--yellow); color: var(--on-c); }
/* Sobre amarillo, el gris apagado no se lee: el texto secundario hereda. */
.dropzone.is-over .muted { color: inherit; }
@media (hover: hover) { .dropzone:hover .muted { color: inherit; } }
.dropzone svg { width: 40px; height: 40px; color: currentColor; }
.dropzone strong { font-size: 1.05rem; font-weight: 700; }
/* NUNCA display:none en un input de archivo: iOS Safari se salta la activacion
   de un input que no esta en el flujo y la foto no llega nunca al change. Se
   esconde a la vista pero se queda en la caja. */
.dropzone input[type=file], .file-oculto {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  pointer-events: none; clip-path: inset(50%); overflow: hidden;
  border: 0; padding: 0; margin: -1px;
}

/* maquina de estados */
.tool-card [data-when] { display: none; }
.tool-card[data-state="idle"]    [data-when~="idle"],
.tool-card[data-state="engine"]  [data-when~="engine"],
.tool-card[data-state="working"] [data-when~="working"],
.tool-card[data-state="done"]    [data-when~="done"],
.tool-card[data-state="error"]   [data-when~="error"] { display: block; }

/* --- 6. Controles ---------------------------------------- */
.controls { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 18px; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: 6px; flex: 1 1 170px; }
.field label {
  font-size: .78rem; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-soft);
}
select, input[type=number], input[type=text], input[type=date], textarea {
  font: inherit; font-size: .95rem; font-weight: 500; padding: 10px 12px;
  border: var(--bw) solid var(--ink); background: var(--paper);
  color: var(--ink); width: 100%; border-radius: 0;
}
select:focus, input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
input[type=range] { width: 100%; accent-color: var(--accent); }
input[type=color] { border: var(--bw) solid var(--ink); background: var(--paper); }

.btn {
  font: inherit; font-weight: 700; font-size: .92rem;
  letter-spacing: .03em; text-transform: uppercase; cursor: pointer;
  padding: 13px 24px; border: var(--bw) solid var(--ink); border-radius: 0;
  background: var(--ink); color: var(--bg);
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  text-decoration: none; transition: transform .1s, box-shadow .1s, background .12s;
}
.btn:hover { background: var(--accent); box-shadow: var(--shadow); transform: translate(-2px, -2px); }
.btn:active { box-shadow: none; transform: none; }
.btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; transform: none; background: var(--ink); }
.btn-lg { width: 100%; padding: 16px; font-size: 1rem; }
.btn-ghost { background: var(--bg); color: var(--ink); }
.btn-ghost:hover { background: var(--yellow); color: var(--on-c); }
.link-reset {
  display: inline-block; margin-top: 14px; font-size: .88rem; font-weight: 600;
  color: var(--text-soft); background: none; border: 0; cursor: pointer;
  text-decoration: underline; font-family: inherit;
}
.link-reset:hover { color: var(--accent); }

/* --- 7. Progreso / estados ------------------------------- */
.progress {
  height: 14px; background: var(--paper); overflow: hidden;
  border: var(--bw) solid var(--ink); margin: 14px 0 8px;
}
.progress > i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .25s; }
.state-msg { text-align: center; color: var(--text-soft); font-size: .94rem; font-weight: 500; }
.error-box {
  border: var(--bw) solid var(--ink); background: #FBE3E0;
  color: var(--on-c); padding: 14px 16px; font-size: .94rem; font-weight: 500;
  box-shadow: var(--shadow-sm);
}

/* --- 8. Resultados --------------------------------------- */
.file-row {
  display: flex; align-items: center; gap: 14px; padding: 13px 0;
  border-bottom: var(--bw) solid var(--ink);
}
.file-row:last-child { border-bottom: 0; }
.file-thumb {
  width: 52px; height: 52px; object-fit: cover;
  border: var(--bw) solid var(--ink); background: var(--bg-alt); flex: 0 0 auto;
}
.file-meta { flex: 1 1 auto; min-width: 0; }
.file-name {
  font-weight: 700; font-size: .95rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.file-sizes { font-size: .87rem; color: var(--text-soft); font-weight: 500; }
.saved { color: var(--ok); font-weight: 700; }
.btn-dl {
  font: inherit; font-size: .82rem; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; text-decoration: none;
  background: var(--ink); color: var(--bg); padding: 9px 15px;
  border: var(--bw) solid var(--ink); cursor: pointer; white-space: nowrap;
  transition: transform .1s, box-shadow .1s, background .12s;
}
.btn-dl:hover { background: var(--accent); box-shadow: var(--shadow-sm); transform: translate(-1px, -1px); }

/* --- 9. Privacidad + limites ----------------------------- */
.privacy-ico { color: var(--on-c); flex: 0 0 auto; line-height: 0; padding-top: 1px; }
.privacy-ico svg { width: 20px; height: 20px; }
.privacy {
  display: flex; align-items: flex-start; gap: 11px;
  font-size: .92rem; font-weight: 500; color: var(--on-c);
  background: var(--yellow); border: var(--bw) solid var(--ink);
  box-shadow: var(--shadow-sm); padding: 14px 16px; margin-bottom: 10px;
}
.limits { font-size: .85rem; color: var(--text-soft); margin-bottom: 8px; font-weight: 500; }

/* --- 10. Huecos de anuncio (placeholders — invariante 8) - */
.ad-slot {
  min-height: 100px; margin: 34px 0; display: grid; place-items: center;
  border: var(--bw) dashed var(--ink); background: var(--bg-alt);
  color: var(--text-mute); font-size: .74rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
@media (min-width: 760px) { .ad-slot { min-height: 120px; } }

/* --- 11. Contenido: pasos, FAQ, rejilla ------------------ */
.steps { display: grid; gap: 14px; grid-template-columns: 1fr; margin: 20px 0; padding: 0; list-style: none; }
@media (min-width: 700px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li {
  background: var(--paper); border: var(--bw) solid var(--ink);
  box-shadow: var(--shadow); padding: 20px;
}
.steps svg { width: 26px; height: 26px; color: var(--accent); margin-bottom: 8px; }
.steps strong { display: block; margin-bottom: 4px; font-weight: 700; }
.steps span { font-size: .92rem; color: var(--text-soft); }

.faq details {
  border: var(--bw) solid var(--ink); padding: 14px 18px;
  margin-bottom: 10px; background: var(--paper);
}
.faq details[open] { box-shadow: var(--shadow-sm); }
.faq summary { cursor: pointer; font-weight: 700; }
.faq details[open] summary { margin-bottom: 8px; }
.faq p { margin: 0; color: var(--text-soft); font-size: .94rem; }

.tool-grid { display: grid; gap: 14px; grid-template-columns: 1fr; padding: 0; list-style: none; }
@media (min-width: 640px) { .tool-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .tool-grid { grid-template-columns: repeat(3, 1fr); } }
.tool-grid a {
  display: block; height: 100%; text-decoration: none; color: var(--ink);
  background: var(--paper); border: var(--bw) solid var(--ink);
  box-shadow: var(--shadow); padding: 18px; transition: transform .1s, box-shadow .1s, background .12s;
}
.tool-grid a:hover {
  background: var(--c, var(--yellow)); color: var(--on-c);
  box-shadow: var(--shadow-lg); transform: translate(-2px, -2px);
}
.tool-grid .t-icon {
  color: var(--on-c); width: 42px; height: 42px; margin-bottom: 12px;
  display: grid; place-items: center;
  background: var(--c, var(--yellow)); border: var(--bw) solid var(--ink);
}
.tool-grid a:hover .t-icon { background: var(--paper); color: var(--ink); }
.tool-grid .t-icon svg { width: 22px; height: 22px; }
.tool-grid strong { display: block; font-size: 1rem; font-weight: 700; margin-bottom: 4px; letter-spacing: -.015em; }
.tool-grid span { font-size: .88rem; color: var(--text-soft); }
.tool-grid a:hover span { color: var(--on-c); }

/* --- 12. Paginas legales --------------------------------- */
.prose { max-width: 720px; margin: 30px auto; }
.prose h2 { margin-top: 1.8em; }
.todo {
  background: var(--yellow); border: var(--bw) solid var(--ink);
  color: var(--on-c); padding: 2px 8px; font-size: .85rem; font-weight: 700;
}

/* --- 13. Recorte / redes --------------------------------- */
.crop-stage {
  position: relative; width: 100%; max-width: 520px; margin: 18px auto 0;
  background: var(--bg-alt); border: var(--bw) solid var(--ink);
  overflow: hidden; touch-action: none; cursor: grab;
}
.crop-stage.is-drag { cursor: grabbing; }
.crop-stage canvas { display: block; width: 100%; height: auto; }

/* --- 13b. Rejilla de iconos del QR ----------------------- */
.emoji-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 6px; }
.emoji-op {
  font-size: 1.25rem; line-height: 1; padding: 8px 0; cursor: pointer;
  background: var(--paper); color: inherit;
  border: var(--bw) solid var(--ink); transition: background .12s;
}
.emoji-op:hover { background: var(--yellow); color: var(--on-c); }

/* --- 13c. Escaner: acciones de pagina y editor de bordes -- */
.pag-acciones { display: flex; flex-wrap: wrap; gap: 6px; flex: 0 0 auto; justify-content: flex-end; }
/* En movil los seis botones no caben al lado de la miniatura: la fila exigia
   mas ancho que la pantalla y empujaba la PAGINA ENTERA en horizontal, con la
   cabecera cortada y el texto exprimido en una columna de dos palabras. Aqui
   la botonera baja a su propia linea. */
@media (max-width: 640px) {
  .file-row { flex-wrap: wrap; }
  .file-meta { flex: 1 1 120px; }
  .pag-acciones { flex: 1 1 100%; justify-content: flex-start; }
  /* Sin crecer: con `1 1 auto` el ultimo boton de cada linea se estiraba a
     todo el ancho y la papelera acababa siendo una barra de 290 px. */
  .btn-mini { flex: 0 0 auto; }
}
.btn-mini {
  font: inherit; font-size: .78rem; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; cursor: pointer;
  padding: 7px 11px; border: var(--bw) solid var(--ink); border-radius: 0;
  background: var(--bg); color: var(--ink); transition: background .12s;
}
.btn-mini:hover:not(:disabled) { background: var(--yellow); color: var(--on-c); }
.btn-mini:disabled { opacity: .38; cursor: not-allowed; }

/* El editor tapa la pagina entera a proposito: ajustar cuatro esquinas con el
   dedo necesita toda la pantalla del movil, que es de donde viene el trafico. */
.editor-bordes {
  position: fixed; inset: 0; z-index: 120; display: flex;
  align-items: center; justify-content: center; padding: 14px;
  background: rgba(0, 0, 0, .62);
}
.editor-caja {
  background: var(--surface); border: var(--bw-lg) solid var(--border);
  box-shadow: var(--shadow-lg); padding: 18px;
  width: 100%; max-width: 640px; max-height: 94vh; overflow: auto;
}
.editor-titulo { font-size: 1.05rem; margin: 0 0 4px; }
.editor-lienzo {
  position: relative; margin: 14px 0; line-height: 0;
  touch-action: none; -webkit-user-select: none; user-select: none;
}
/* Solo la foto, NO la lupa. Con `.editor-lienzo canvas` a secas esta regla
   tambien alcanzaba a la lupa: le imponia width:100% -mas especifica que
   .editor-lupa, asi que ganaba- y ademas display:block, que anula el atributo
   hidden. Resultado: la lupa siempre visible y estirada a todo el ancho,
   tapando la foto con un zoom gigante. */
.editor-lienzo > canvas:not(.editor-lupa) {
  display: block; width: 100%; height: auto;
  border: var(--bw) solid var(--ink);
}
.editor-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.editor-svg polygon { fill: rgba(228, 87, 46, .16); stroke: var(--accent); stroke-width: 3; }
/* Cuadrados, no circulos: aqui no se redondea nada, y un cuadrado amarillo
   sobre borde de tinta se ve igual de bien contra una foto clara u oscura. */
.editor-punto {
  position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px;
  background: var(--yellow); border: var(--bw) solid #1B1B1B;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, .45);
  cursor: grab; touch-action: none;
}
.editor-punto.is-drag { cursor: grabbing; background: var(--accent); }

/* Tirador de lado: mueve el borde entero, las dos esquinas a la vez. Es plano
   y alargado a proposito, para que no se confunda con una esquina. Se gira
   para alinearse con su lado; en una foto torcida, uno horizontal sobre un
   borde inclinado se lee como que no pertenece a ese borde. */
.editor-lado {
  position: absolute; width: 44px; height: 16px;
  background: var(--bg); border: var(--bw) solid #1B1B1B;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, .45);
  cursor: grab; touch-action: none;
}
.editor-lado.is-drag { cursor: grabbing; background: var(--accent); }

/* Lupa. El dedo tapa justo el punto que hay que colocar: es EL problema de
   ajustar esquinas en una pantalla tactil. Se ancla arriba, en el lado
   contrario al que se arrastra, asi que nunca queda debajo de la mano. */
.editor-lupa {
  position: absolute; top: 8px; left: 8px; width: 132px; height: 132px;
  border: var(--bw-lg) solid #1B1B1B; box-shadow: 3px 3px 0 rgba(0, 0, 0, .45);
  background: #fff; pointer-events: none; z-index: 3;
}
.editor-lupa.a-la-derecha { left: auto; right: 8px; }
.editor-lupa[hidden] { display: none; }

/* Vista de la pagina a tamano util. Los selectores van por CLASE y nunca por
   tipo: `.editor-lienzo canvas` a secas ya nos estiro la lupa una vez. */
.vista-caja { max-width: 780px; }
.vista-lienzo {
  margin: 12px 0; padding: 10px; display: flex; justify-content: center;
  background: var(--bg-alt); border: var(--bw) solid var(--ink);
}
/* Se ve la pagina ENTERA, que es lo que hace falta para juzgar el recorte.
   El borde fino la separa del fondo: un folio en blanco y negro sobre papel
   crema, sin borde, parece que flota. */
.vista-img {
  display: block; width: auto; height: auto;
  max-width: 100%; max-height: 58vh;
  border: 1px solid var(--text-mute); background: #fff;
}

@media (max-width: 420px) {
  .editor-lupa { width: 104px; height: 104px; }
}
.editor-botones { margin-top: 4px; }
@media (pointer: coarse) {
  .editor-punto { width: 38px; height: 38px; margin: -19px 0 0 -19px; }
}

/* --- 13d. Extraer audio: ficha y salidas ------------------ */
.meta-panel { border: var(--bw) solid var(--ink); background: var(--paper); }
.meta-fila {
  display: flex; justify-content: space-between; gap: 14px; align-items: baseline;
  padding: 10px 14px; border-bottom: var(--bw) solid var(--ink); font-size: .92rem;
}
.meta-fila:last-child { border-bottom: 0; }
.meta-fila span { color: var(--text-soft); font-weight: 500; }
.meta-fila strong { text-align: right; word-break: break-word; }
/* Una salida por bloque, no botones sueltos: cada formato necesita su nota
   explicando que se gana y que se pierde, y sin ella la gente elige MP3 por
   costumbre cuando el .m4a es mejor en casi todos los casos. */
.salidas { display: grid; gap: 14px; margin-top: 18px; }
.salida-op {
  border: var(--bw) solid var(--ink); background: var(--bg-alt); padding: 14px;
}
.salida-op .btn { width: 100%; }
.salida-op p { margin: 9px 0 0; }
.salida-op select { margin-top: 8px; }

/* --- 13e. Rejilla de paginas (girar / borrar / reordenar) - */
/* Miniaturas de todas las paginas. La pregunta del usuario siempre es "cual
   era la pagina 7": con una rejilla se ve, con una caja de numeros se adivina. */
.pag-rejilla {
  display: grid; gap: 14px; margin-top: 16px;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
}
.pag-caja {
  border: var(--bw) solid var(--ink); background: var(--bg-alt);
  padding: 8px; display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.pag-img {
  display: block; max-width: 100%; height: auto; background: #fff;
  border: 1px solid var(--text-mute); transition: transform .15s;
}
/* Una pagina girada 90 grados es mas ancha que alta: sin esto se sale de su
   caja y pisa a la de al lado. */
.pag-img.de-lado { max-width: 76%; }
.pag-num {
  font-size: .82rem; font-weight: 700; min-width: 26px; text-align: center;
  border: var(--bw) solid var(--ink); background: var(--paper); padding: 1px 7px;
}
.pag-botones { display: flex; gap: 5px; flex-wrap: wrap; justify-content: center; }
/* Quitada: se sigue viendo, pero apagada. Ocultarla del todo haria imposible
   recuperarla, y equivocarse al borrar una pagina es facil. */
.pag-caja.esta-fuera { opacity: .38; }
.pag-caja.esta-fuera .pag-img { filter: grayscale(1); }
.pag-resumen { margin-top: 14px; font-size: .93rem; font-weight: 500; color: var(--text-soft); }
.pag-globales { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

/* --- 13f. Word a PDF: vista del documento e impresion ----- */
.doc-vista {
  margin-top: 16px; padding: 12px; overflow: auto; max-height: 70vh;
  background: var(--bg-alt); border: var(--bw) solid var(--ink);
}
/* docx-preview pinta cada hoja como un bloque blanco con su tamano real. */
.doc-vista .docx-wrapper { background: transparent; padding: 0; }
.doc-vista .docx { box-shadow: var(--shadow-sm); margin: 0 auto 14px; }

/* Impresion. El PDF lo genera el motor del navegador a partir de esta vista:
   por eso conserva texto seleccionable, vectores e imagenes, cosa que no hace
   rasterizar la pagina. Aqui solo hay que dejar EL DOCUMENTO y esconder el
   resto del sitio.

   Se usa visibility y no display: display:none en un antecesor ocultaria
   tambien el documento, que esta dentro de la tarjeta. */
@media print {
  body.imprimiendo * { visibility: hidden !important; }
  body.imprimiendo .doc-vista,
  body.imprimiendo .doc-vista * { visibility: visible !important; }
  body.imprimiendo .doc-vista {
    position: absolute; left: 0; top: 0; width: 100%;
    max-height: none; overflow: visible;
    margin: 0; padding: 0; border: 0; background: #fff;
  }
  body.imprimiendo .doc-vista .docx { box-shadow: none; margin: 0 auto; }
}

/* Vista previa del texto extraido (PDF a Word) */
.texto-previo {
  margin-top: 14px; padding: 14px; max-height: 320px; overflow: auto;
  background: var(--paper); border: var(--bw) solid var(--ink);
  font-size: .88rem; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
}

/* --- 14. Metadatos --------------------------------------- */
.meta-table { width: 100%; border-collapse: collapse; font-size: .92rem; margin-top: 8px; }
.meta-table th, .meta-table td {
  text-align: left; padding: 9px 10px;
  border-bottom: var(--bw) solid var(--ink); vertical-align: top;
}
.meta-table thead th, .meta-table thead td { background: var(--ink); color: var(--bg); font-weight: 700; }
.meta-table th { font-weight: 700; width: 42%; }
.gps-warn {
  border: var(--bw) solid var(--ink); background: #FFE9C7; color: var(--on-c);
  box-shadow: var(--shadow-sm); padding: 14px 16px; margin-top: 14px;
  font-size: .93rem; font-weight: 500;
}
.gps-warn strong { color: var(--on-c); }
.ico-aviso { width: 17px; height: 17px; vertical-align: -3px; margin-right: 3px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* --- 15. Franja de prueba (portada) ---------------------- */
.franja {
  background: var(--ink); color: var(--bg);
  padding: 30px 0; border-bottom: var(--bw-lg) solid var(--ink);
}
.franja .wrap { display: flex; align-items: center; gap: 24px; }
.franja-cifra {
  font-size: 3.1rem; font-weight: 700; letter-spacing: -.05em;
  line-height: 1; color: var(--yellow);
}
.franja strong { display: block; font-size: 1.15rem; font-weight: 700; margin-bottom: 2px; }
.franja span { font-size: .92rem; opacity: .75; }

@media (max-width: 560px) {
  .franja .wrap { flex-direction: column; align-items: flex-start; gap: 12px; }
  .buscador { flex-wrap: wrap; }
  .buscador-btn { width: 100%; padding: 13px; border-top: var(--bw) solid var(--ink); }
}


/* --- 16. Ajustes de componente en modo oscuro ------------
   Van AL FINAL a proposito. Los tokens de :root pueden declararse arriba
   porque var() se resuelve al calcular el valor, pero una anulacion de
   componente con la misma especificidad solo gana si va DESPUES de la regla
   que corrige. Puesta arriba, la franja seguia saliendo crema.
   --------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  /* Fondos claros fijos, suavizados para que no deslumbren sobre oscuro */
  :root:not([data-tema="claro"]) .error-box { background: #F6C9C2; }
  :root:not([data-tema="claro"]) .gps-warn { background: #F5DDB4; }

  /* En claro es un bloque negro sobre crema; invertirlo daria un bloque
     crema cegador a media pagina. Aqui se queda oscuro. */
  :root:not([data-tema="claro"]) .franja { background: var(--bg-alt); color: var(--text); }
  :root:not([data-tema="claro"]) .franja span { opacity: .78; }

  /* El lienzo de firma es blanco SIEMPRE (se firma sobre un PDF, que es
     blanco). Solo se ajusta lo que lo rodea. */
  :root:not([data-tema="claro"]) .crop-stage { background: var(--paper); }

  /* El boton invertido pasa a crema con texto oscuro; su hover naranja
     necesita texto oscuro para seguir legible. */
  :root:not([data-tema="claro"]) .btn:hover, :root:not([data-tema="claro"]) .btn-dl:hover, :root:not([data-tema="claro"]) .nav-tools:hover { color: var(--on-c); }
}

  /* Fondos claros fijos, suavizados para que no deslumbren sobre oscuro */
:root[data-tema="oscuro"] .error-box { background: #F6C9C2; }
:root[data-tema="oscuro"] .gps-warn { background: #F5DDB4; }

/* En claro es un bloque negro sobre crema; invertirlo daria un bloque
   crema cegador a media pagina. Aqui se queda oscuro. */
:root[data-tema="oscuro"] .franja { background: var(--bg-alt); color: var(--text); }
:root[data-tema="oscuro"] .franja span { opacity: .78; }

/* El lienzo de firma es blanco SIEMPRE (se firma sobre un PDF, que es
   blanco). Solo se ajusta lo que lo rodea. */
:root[data-tema="oscuro"] .crop-stage { background: var(--paper); }

/* El boton invertido pasa a crema con texto oscuro; su hover naranja
   necesita texto oscuro para seguir legible. */
:root[data-tema="oscuro"] .btn:hover, :root[data-tema="oscuro"] .btn-dl:hover, :root[data-tema="oscuro"] .nav-tools:hover { color: var(--on-c); }


/* --- 17. Objetivos tactiles ------------------------------
   Solo en dispositivos de dedo (pointer: coarse). Un raton apunta con
   precision de pixel y no necesita 44 px; el dedo si, y los atajos de la
   portada se quedaban en 36. El minimo de 44x44 es el estandar de Apple y
   el criterio 2.5.5 de WCAG.

   Va al final para ganar por orden a las reglas de cada componente. */
@media (pointer: coarse) {
  .atajo, .tema-btn, .nav-tools, .btn-ghost, .btn-dl, .emoji-op {
    min-height: 44px;
  }
  .atajo, .tema-btn, .nav-tools {
    display: inline-flex; align-items: center;
  }
  /* Los enlaces del pie eran de 18 px: se les da area sin moverlos de sitio */
  .site-footer a {
    display: inline-block; padding: 12px 0; margin: -12px 0;
  }
  .logo { padding: 6px 0; }
}
