/* ═══════════════════════════════════════════════════════════════════════════
   Core 30 — base neutra

   ESTA HOJA VIAJA A TODAS LAS COPIAS. La identidad visual NO: la escribe la
   skill `disenar`, una vez por repo, en plantillas/estilo.css.

   Acá no hay ni una decisión de marca. Ni un color de acento, ni una
   tipografía elegida, ni una composición. Solo lo que hace falta para que el
   sitio se lea mientras se escribe el contenido — que es el paso más largo del
   proyecto y el que más tiempo se pasa mirando estas páginas.

   Todo lo de acá está pensado para que una piel lo pise sin pelear: valores
   sobrios, especificidad de un solo selector, cero !important.

   Se carga SIEMPRE, antes que estilo.css.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Sin color de marca a propósito. Gris neutro hasta que corra `disenar`. */
  --b-tinta:    #16181d;
  --b-cuerpo:   #33363d;
  --b-mute:     #5c6068;   /* 4.9:1 sobre --b-papel */
  --b-papel:    #ffffff;
  --b-hunde:    #f4f4f6;
  --b-pelo:     #dcdde1;
  --b-enlace:   #1b4fa8;   /* 7.4:1 sobre --b-papel */
  --b-foco:     #1b4fa8;

  --b-medida:   68ch;      /* medida de línea legible */
  --b-ritmo:    1.6;
  --b-radio:    4px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --b-tinta:  #f2f3f5;
    --b-cuerpo: #d3d5da;
    --b-mute:   #a1a5ad;   /* 7.1:1 sobre --b-papel oscuro */
    --b-papel:  #16181d;
    --b-hunde:  #1f222a;
    --b-pelo:   #333740;
    --b-enlace: #8fb4f2;   /* 7.3:1 sobre --b-papel oscuro */
    --b-foco:   #8fb4f2;
  }
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--b-papel);
  color: var(--b-cuerpo);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 1rem;
  line-height: var(--b-ritmo);
}

/* ── Ritmo vertical ────────────────────────────────────────────────────────
   El margen va SOLO hacia abajo: así dos bloques seguidos no acumulan. */
h1, h2, h3, p, ul, ol, table, figure, blockquote { margin: 0 0 1rem; }
h1, h2, h3 { margin-top: 2rem; }

h1, h2, h3 {
  color: var(--b-tinta);
  line-height: 1.25;
  font-weight: 650;
  text-wrap: balance;
}

/* El H1 lleva el ancla completa y suele ser largo: no se lo aprieta. */
h1 { font-size: 1.9rem; margin-top: 0; }
h2 { font-size: 1.45rem; }
h3 { font-size: 1.15rem; }

p { max-width: var(--b-medida); text-wrap: pretty; }

/* ── Contenedores ─────────────────────────────────────────────────────────
   Sin composición: una columna centrada. La piel decide lo demás. */
header, main, footer, section { padding-inline: 1.25rem; }

main {
  max-width: 74rem;
  margin-inline: auto;
  padding-block: 1.5rem 3rem;
}

section { padding-inline: 0; margin-block: 2.5rem; }

/* ── Enlaces y foco ───────────────────────────────────────────────────────
   El foco es visible SIEMPRE. Es lo único acá que no se negocia: sin él el
   sitio no se puede usar con teclado, y eso no espera al diseño. */
a { color: var(--b-enlace); text-underline-offset: 2px; }
a:hover { text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--b-foco);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Barra superior y pie ─────────────────────────────────────────────────── */
header, footer {
  border-color: var(--b-pelo);
  border-style: solid;
  border-width: 0;
  padding-block: 1rem;
}
header { border-bottom-width: 1px; }
footer { border-top-width: 1px; margin-top: 3rem; color: var(--b-mute); }

header nav ul, footer nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* El mapa del pie llega como el snippet que Google da para copiar: con
   `width="600" height="450"` en atributos. Sin nadie que lo mida se desborda
   del viewport en móvil, y en el pie eso rompe las ~40 páginas a la vez. Se
   mide acá para que la copia pueda pegar el embed sin editarlo. Alto y lugar
   los decide la piel; esto es solo que entre. */
.site-footer__mapa { max-width: 34rem; margin-bottom: 1rem; }
.site-footer__mapa iframe {
  display: block;
  width: 100%;
  height: 260px;
  border: 0;
  border-radius: var(--b-radio);
}

/* El teléfono es la conversión del rubro: se ve antes que el diseño exista. */
.tel, a[href^="tel:"] { font-weight: 650; white-space: nowrap; }

/* ── Medios ───────────────────────────────────────────────────────────────── */
img, svg, video { max-width: 100%; height: auto; display: block; }
figure { margin-inline: 0; }
figcaption { color: var(--b-mute); font-size: .9rem; }

/* ── Tablas y código: que no desborden la página ──────────────────────────── */
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: .5rem .75rem; border-bottom: 1px solid var(--b-pelo); }
pre { overflow-x: auto; background: var(--b-hunde); padding: 1rem; border-radius: var(--b-radio); }

/* ── Formulario ───────────────────────────────────────────────────────────── */
label { display: block; margin-bottom: .25rem; color: var(--b-tinta); }

input, select, textarea, button {
  font: inherit;
  color: inherit;
  max-width: 100%;
}

input, select, textarea {
  width: 100%;
  padding: .6rem .7rem;
  background: var(--b-papel);
  border: 1px solid var(--b-pelo);
  border-radius: var(--b-radio);
  margin-bottom: 1rem;
}

/* El placeholder necesita el mismo contraste que el cuerpo: se lee con sol de
   costado en un teléfono, que es exactamente cuando se usa. */
::placeholder { color: var(--b-mute); opacity: 1; }

button, .boton {
  display: inline-block;
  padding: .6rem 1.1rem;
  background: var(--b-tinta);
  color: var(--b-papel);
  border: 1px solid var(--b-tinta);
  border-radius: var(--b-radio);
  text-decoration: none;
  cursor: pointer;
  /* Área táctil mínima. */
  min-height: 44px;
}

/* ── Grillas ──────────────────────────────────────────────────────────────
   auto-fit y no un número fijo de columnas: una categoría con un solo hijo
   no puede dejar la grilla huérfana. */
.grilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1rem;
  padding: 0;
  list-style: none;
}

.grilla > * {
  border: 1px solid var(--b-pelo);
  border-radius: var(--b-radio);
  padding: 1rem;
}

/* ── Fila de specs del hero ───────────────────────────────────────────────
   La dibuja el parcial `hero` cuando la página declara `spec_1`. Acá va lo
   mínimo para que la fila se lea como fila: sin esto son cuatro <dt>/<dd>
   apilados, que es peor que no tenerla. La piel de cada cliente la pisa con
   un selector y le pone su tipografía; esto no elige ninguna.

   auto-fit y no `repeat(4, …)`: la fila acepta de dos a cuatro pares —el
   parcial los dibuja condicionales— y con cuatro columnas fijas dos pares
   dejan media fila vacía. */
.hero__specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  gap: 0;
  margin: 1.5rem 0 0;
  border-top: 1px solid var(--b-pelo);
}

.hero__spec {
  padding: .85rem 1rem;
  border-right: 1px solid var(--b-pelo);
}

.hero__spec:last-child { border-right: 0; }
.hero__spec dt { color: var(--b-mute); font-size: .75rem; }
.hero__spec dd { margin: .25rem 0 0; color: var(--b-tinta); font-weight: 650; }

/* ── Galería de trabajos: el carrusel sin JavaScript ──────────────────────
   Cuatro piezas a la vez en escritorio, con flechas; una tira que se desliza
   con el dedo en móvil. Ningún script: la página activa la guarda un radio y
   estas reglas leen su `:checked`. El HTML está en _componentes.html.

   EL 4 DE `repeat(4, 1fr)` ES LA MISMA CONSTANTE QUE GALERIA_POR_PAGINA en
   scripts/build.py. Si una cambia y la otra no, cada clic corre la pista por
   una fracción de columna. Están las dos porque el CSS no sabe partir listas.

   Acá tampoco hay marca: proporciones, tokens neutros y nada más. Una piel
   pisa esto con un solo selector, que es la regla de toda la hoja. */
.galeria__estado {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.galeria__cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 1rem;
}

/* Móvil primero: la tira se desliza y las flechas no existen. Un carrusel con
   botones de 44px en una pantalla de 360 es un pulgar tapando la foto. */
.galeria__flechas { display: none; }

.galeria__viewport {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
}

.galeria__pista { display: flex; gap: 1rem; }

.galeria__pagina {
  display: flex;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.galeria__item {
  flex: 0 0 min(78vw, 22rem);
  scroll-snap-align: start;
}

.galeria__figura { margin: 0; }

.galeria__figura img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--b-radio);
}

.galeria__pie { display: block; margin-top: .5rem; }
.galeria__titulo { display: block; color: var(--b-tinta); }
.galeria__detalle { color: var(--b-mute); font-size: .9rem; }

@media (min-width: 60rem) {
  /* La pista pasa a ser una fila de PÁGINAS, cada una del ancho exacto del
     viewport. Por eso `gap: 0` acá: con separación entre páginas, un
     translateX(-100%) queda corto por ese gap y el desfase se acumula. */
  .galeria__viewport { overflow: hidden; }

  .galeria__pista {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 100%;
    gap: 0;
    transition: transform .45s ease;
  }

  .galeria__pagina { display: grid; grid-template-columns: repeat(4, 1fr); }

  .galeria__flechas { display: flex; }
  .galeria__nav { display: none; gap: .5rem; }

  .galeria__flecha {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: 0;
    border: 1px solid var(--b-pelo);
    border-radius: 50%;
    background: var(--b-papel);
    color: var(--b-tinta);
    cursor: pointer;
  }

  /* La flecha del extremo no se saca: se apaga. Sacarla mueve la otra de lugar
     en cada clic, y un control que salta es un control que no se aprende. */
  .galeria__flecha--off { opacity: .35; cursor: default; }

  /* ── El estado ──────────────────────────────────────────────────────────
     Una regla por página, escritas a mano hasta GALERIA_PAGINAS_MAX = 4.
     `:nth-of-type` cuenta entre los <input> hermanos, que son solo estos. */
  .galeria__estado:nth-of-type(2):checked ~ .galeria__viewport .galeria__pista { transform: translateX(-100%); }
  .galeria__estado:nth-of-type(3):checked ~ .galeria__viewport .galeria__pista { transform: translateX(-200%); }
  .galeria__estado:nth-of-type(4):checked ~ .galeria__viewport .galeria__pista { transform: translateX(-300%); }

  .galeria__estado:nth-of-type(1):checked ~ .galeria__cabecera .galeria__nav:nth-child(1),
  .galeria__estado:nth-of-type(2):checked ~ .galeria__cabecera .galeria__nav:nth-child(2),
  .galeria__estado:nth-of-type(3):checked ~ .galeria__cabecera .galeria__nav:nth-child(3),
  .galeria__estado:nth-of-type(4):checked ~ .galeria__cabecera .galeria__nav:nth-child(4) { display: flex; }

  /* El radio es invisible y sigue siendo lo ÚNICO que el teclado alcanza: los
     <label> no reciben foco. Sin esto, tabular hasta el carrusel no se ve, y
     las flechas del teclado cambian de página sin que nada lo muestre. */
  .galeria__estado:focus-visible ~ .galeria__cabecera .galeria__flechas {
    outline: 2px solid var(--b-foco);
    outline-offset: 4px;
    border-radius: 2px;
  }
}

/* ── Accesibilidad ────────────────────────────────────────────────────────── */
.visualmente-oculto {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
