/* ─────────────────────────────────────────────────────────────
   FIFÍ DE PUEBLO · capa de tokens
   Luxury Chiapas Textile Editorial

   Se carga DESPUÉS de _ds/classical-…/styles.css y sólo añade
   lo que el sistema Classical no trae: la paleta de tierras de
   Chiapas, los cinco hilos del telar, la sans de interfaz y los
   tokens de movimiento.

   Retícula, espaciado, radios, sombras y componentes siguen
   saliendo de Classical. Aquí no se redefine nada de eso.
   ───────────────────────────────────────────────────────────── */

html, body {
  background: #f5f1ea;
  color: #241f1b;
  margin: 0;
}

@font-face {
  font-family: 'Jost fallback';
  src: local('Helvetica Neue'), local('Helvetica'), local('Arial');
  size-adjust: 92%;
  ascent-override: 95%;
  descent-override: 24%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Cormorant fallback';
  src: local('Times New Roman'), local('Times'), local('Georgia');
  size-adjust: 97%;
  ascent-override: 115%;
  descent-override: 30%;
  line-gap-override: 0%;
}

:root {
  /* ── TIERRAS ─────────────────────────────────────────────── */
  --marfil:      #f5f1ea;   /* fondo de página */
  --beige:       #e8e0d4;   /* paspartú de fotografía */
  --carbon:      #241f1b;   /* tinta */
  --piedra:      #6b635c;   /* texto secundario · 5.2:1 sobre marfil */
  --espresso:    #231a14;   /* bandas oscuras: hero, pie, panel */

  /* ── DORADO ENVEJECIDO · sólo como trazo, nunca relleno ──── */
  --oro:         #b68235;   /* bordes, filetes, rombos, numerales */
  --oro-texto:   #7d5411;   /* dorado legible en texto pequeño sobre marfil */
  --oro-claro:   #e1ad66;   /* dorado sobre espresso */

  /* ── LOS CINCO HILOS DEL TELAR ───────────────────────────── */
  --hilo-tinta:  var(--carbon);  /* estructura */
  --hilo-ocre:   var(--oro);     /* Cultura y fiestas */
  --hilo-grana:  #8c2f2a;        /* Gastronomía */
  --hilo-anil:   #2a3f5c;        /* Lugares — tinte histórico del Soconusco */
  --hilo-jade:   #4a6b4a;        /* Biodiversidad */

  /* sobre espresso los hilos suben un paso de luminosidad */
  --hilo-grana-claro: #c96a62;
  --hilo-anil-claro:  #7d9ac4;
  --hilo-jade-claro:  #8fae6b;

  /* acentos disponibles, sin papel asignado todavía */
  --terracota:   #a85c3c;
  --maiz:        #c9a227;

  /* ── FILETES ─────────────────────────────────────────────── */
  --filete:        color-mix(in srgb, var(--carbon) 16%, transparent);
  --filete-oscuro: rgba(245, 241, 234, 0.18);

  /* ── TIPOGRAFÍA ──────────────────────────────────────────── */
  /* display: Cormorant Garamond, de Classical (--font-heading) */
  --font-ui: 'Jost', 'Jost fallback', system-ui, -apple-system, sans-serif;

  --ts-microtexto: 10px;   /* antetítulos, etiquetas en versalitas */
  --ts-aparato:    11.5px; /* metadatos, cifras, franja de referencia */
  --ts-menor:      13px;
  --ts-cuerpo:     15.5px;
  --ts-guia:       clamp(17px, 1.5vw, 21px);
  --ts-titulo:     clamp(22px, 2.6vw, 40px);
  --ts-capitulo:   clamp(26px, 3vw, 44px);
  --ts-display:    clamp(56px, 12vw, 168px);

  --peso-ligero: 300;
  --peso-normal: 400;
  --peso-medio:  500;

  --track-display:   -0.025em;
  --track-titulo:    -0.015em;
  --track-cuerpo:    0;
  --track-aparato:   0.13em;
  --track-versalita: 0.24em;

  --interlinea-display: 1;
  --interlinea-titulo:  1.05;
  --interlinea-cuerpo:  1.62;
  --interlinea-guia:    1.5;

  /* ── MOVIMIENTO ──────────────────────────────────────────── */
  /* easing orgánico: sale rápido y se asienta, nunca lineal */
  --ease-organico: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-trama:    cubic-bezier(0.22, 1, 0.36, 1);
  --ease-suave:    cubic-bezier(0.4, 0, 0.2, 1);

  --mo-micro:      220ms;   /* hover, foco, cambio de estado */
  --mo-ui:         340ms;   /* apertura, filtros, pestañas */
  --mo-editorial:  850ms;   /* entrada de sección */
  --mo-cine:       1200ms;  /* hero, transición de página */
  --mo-textil:     1600ms;  /* cenefa, trama, ambiente */
  --mo-ambiente:   2400ms;  /* pulso, respiración */

  /* ── PROFUNDIDAD ─────────────────────────────────────────── */
  --z-base:    1;
  --z-cenefa:  2;
  --z-nav:     10;
  --z-visor:   50;
  --z-dialogo: 90;

  /* ── REMAPEO DE CLASSICAL ────────────────────────────────────
     Sin esto conviven dos paletas: los componentes de Classical
     (.btn, .card, .plate, .tag, .input, .table, .nav) y todo lo
     que herede de body saldrían en gris cal y Lora junto al
     marfil y el espresso.

     No se redefine la retícula, el espaciado, los radios ni las
     sombras de Classical: sólo el color y la familia de cuerpo.
     ───────────────────────────────────────────────────────────── */
  --color-bg:          var(--marfil);
  --color-text:        var(--carbon);
  --color-surface:     var(--beige);
  --color-neutral-700: var(--piedra);
  --color-divider:     var(--filete);
  --font-body:         var(--font-ui);
  --font-heading:      'Cormorant Garamond', 'Cormorant fallback', Georgia, serif;
  /* --color-accent ya es #b68235 = --oro */
}

/* ─────────────────────────────────────────────────────────────
   ESTADOS COMPARTIDOS

   Foco e interacción viven aquí, no en cada página: es lo que
   hace que los once archivos compartan interacciones sin
   repetir una regla. Es también lo único que no se puede
   escribir en un atributo `style` — pseudoclases y consultas
   de medio.
   ───────────────────────────────────────────────────────────── */

/* Un solo anillo de foco en todo el sitio. El outline no se
   suprime nunca sin sustituirlo: es la única pista de posición
   para quien navega con teclado. */
:focus-visible {
  outline: 2px solid var(--oro);
  outline-offset: 3px;
}

/* sobre espresso el dorado sube un paso para mantener contraste */
footer :focus-visible,
[data-sobre-espresso] :focus-visible {
  outline-color: var(--oro-claro);
}

/* Objetivo táctil de 44px sólo con puntero grueso: en escritorio
   los botones se quedan compactos y refinados, como pide la
   dirección; en teléfono crecen hasta ser alcanzables. */
@media (pointer: coarse) {
  nav a,
  nav button,
  footer a,
  button,
  [role="button"],
  input,
  select,
  textarea {
    min-height: 44px;
  }

  nav a,
  footer a {
    display: inline-flex;
    align-items: center;
  }
}

/* ═════════════════════════════════════════════════════════════
   TEJIDO — un solo lenguaje de movimiento

   Todo lo que se revela en este sitio barre de izquierda a
   derecha, como la lanzadera del telar: el titular del hero, el
   separador y la cenefa. No hay un segundo gesto.
   ═════════════════════════════════════════════════════════════ */

@keyframes tejer-trama {
  from { clip-path: inset(0 70% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* La cenefa se teje al entrar en vista, con la barra de scroll
   como reloj — sin JavaScript ni observadores. El peor caso de
   un navegador sin soporte es la cenefa entera visible, y el
   peor caso con soporte es el 30% visible: nunca desaparece. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-tejer] {
      animation: tejer-trama linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 95%;
    }
  }
}

/* La pieza se teje en dos tiempos: primero la estructura —urdimbre,
   orillo y guardas—, después el campo de módulos. Hilo → trama →
   módulo, con el mismo barrido de izquierda a derecha que el resto
   del sitio. El reposo de las dos capas es VISIBLE: sin soporte de
   animation-timeline la pieza se ve entera. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-capa] {
      animation: tejer-trama linear both;
      animation-timeline: view();
    }
    [data-capa="estructura"] { animation-range: entry 6% entry 62%; }
    [data-capa="campo"]      { animation-range: entry 34% entry 96%; }
  }
}

/* El borde de la tarjeta se teje al pasar el puntero: el mismo
   barrido, a escala de microinteracción. */
[data-tejer-borde] {
  background-image: url(textil-marco.svg);
  background-repeat: repeat-x;
  background-size: 144px 24px;
  background-position: left center;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 620ms cubic-bezier(.16, 1, .3, 1);
}
a:hover [data-tejer-borde],
a:focus-visible [data-tejer-borde] {
  clip-path: inset(0 0 0 0);
}

/* ─────────────────────────────────────────────────────────────
   PRECISIÓN TIPOGRÁFICA

   Nada de esto añade un efecto: corrige cómo caen las líneas.
   Es la diferencia entre texto puesto en la página y texto
   compuesto, y es lo primero que se nota en un sitio caro.
   ───────────────────────────────────────────────────────────── */

/* Los titulares reparten sus líneas en vez de dejar una palabra
   sola al final. Un titular de 118px con la última línea huérfana
   es la marca más visible de texto sin componer. */
h1, h2, h3, h4,
[data-titular] {
  text-wrap: balance;
}

/* La prosa evita viudas sin descuadrar el resto del párrafo.
   `pretty` sólo retoca las últimas líneas; `balance` aquí
   estrecharía la medida. */
p, li, dd, blockquote, figcaption {
  text-wrap: pretty;
}

/* Comillas y guiones de apertura cuelgan al margen, como en un
   libro: el borde de la columna queda óptimamente recto en vez
   de matemáticamente recto. Silencioso donde no se soporta. */
blockquote, [data-cita] {
  hanging-punctuation: first last;
}

/* Cormorant a tamaño de display: el trazo fino se engorda con el
   suavizado por defecto de macOS. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-optical-sizing: auto;
}

/* Ligaduras y alternancias contextuales en el display, donde
   Cormorant las tiene dibujadas. */
h1, h2 {
  font-variant-ligatures: common-ligatures contextual;
}

/* ── REDUCCIÓN ADAPTATIVA EN TELÉFONO ────────────────────────
   No es el diseño de escritorio encogido: se retiran capas y
   cambia la composición de los capítulos.
   ───────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  /* el grano sobre la fotografía es una capa de composición extra */
  [data-grano] { display: none; }

  /* el numeral del capítulo pasa a ir ENCIMA del contenido: la canal
     lateral se comía 44px de una pantalla de 390 */
  [data-capitulo] {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: var(--space-3);
  }
  [data-capitulo] > div:first-child {
    flex-direction: row !important;
    align-items: center !important;
    gap: 10px;
    padding-bottom: 0 !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --mo-micro: 1ms;
    --mo-ui: 1ms;
    --mo-editorial: 1ms;
    --mo-cine: 1ms;
    --mo-textil: 1ms;
    --mo-ambiente: 1ms;
  }

  /* Los tokens solos no bastan: las animaciones CSS declaradas en línea
     (rise, hair, breathe) llevan duración fija y no leen --mo-*. Esta
     guarda global las cubre todas, incluidas las infinitas, y es la
     única palanca de apagado del sitio. */
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}


/* ═════════════════════════════════════════════════════════════
   MOTION · la capa de comportamiento

   El aspecto vive en los estilos en línea de cada plantilla.
   Aquí viven los ESTADOS que un atributo `style` no puede
   escribir —pseudoclases, pseudoelementos, consultas de medio—
   y los pinta assets/motion.js marcando atributos. Ningún
   archivo .dc.html cambia para recibir esto.

   Un solo gesto: barrido de izquierda a derecha. El subrayado
   se teje desde la izquierda, la sección se destapa desde la
   izquierda, el hilo de avance crece desde la izquierda.
   ═════════════════════════════════════════════════════════════ */

/* ── Enlace · el subrayado se teje ───────────────────────────
   Sólo a los enlaces que no llevan ya su propio filete: el
   marcado de motion.js los descarta, y aquí no se dobla. */
@media (hover: hover) {
  [data-enlace] { position: relative; }
  [data-enlace]::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -3px;
    height: 1px;
    background: currentColor;
    opacity: .7;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 420ms var(--ease-organico);
  }
  [data-enlace]:hover::after { transform: scaleX(1); }
}
[data-enlace]:focus-visible::after { transform: scaleX(1); }

/* ── Botón · responde y vuelve ───────────────────────────────
   Un píxel de elevación y la flecha que se adelanta dos. El
   movimiento es pequeño a propósito: aquí el color es trazo, y
   el relleno no entra ni en hover. */
[data-boton] {
  transition:
    border-color     var(--mo-micro) var(--ease-suave),
    color            var(--mo-micro) var(--ease-suave),
    background-color var(--mo-micro) var(--ease-suave),
    transform        var(--mo-ui)    var(--ease-organico);
}
[data-boton] svg,
[data-boton] [data-micro] { transition: transform var(--mo-ui) var(--ease-organico); }
@media (hover: hover) {
  [data-boton]:hover { transform: translateY(-1px); }
  [data-boton]:hover svg { transform: translateX(2px); }
  [data-boton]:hover [data-micro] { transform: translateX(3px); }
}
[data-boton]:active { transform: translateY(0) scale(.99); }

/* ── Tarjeta · profundidad, no salto ─────────────────────────
   La fotografía ya tiene su propio zoom de 2,2% en la
   plantilla. Aquí se añade la sombra —un susurro, como pide
   Classical— y el titular pasa a dorado. La tarjeta sube tres
   píxeles: ni uno más. */
@media (hover: hover) {
  [data-tarjeta] [data-trama] { transition: box-shadow 520ms var(--ease-suave); }
  [data-tarjeta]:hover [data-trama] { box-shadow: 0 24px 46px -28px rgba(35, 26, 20, .5); }
  [data-tarjeta] h3 { transition: color var(--mo-micro) var(--ease-suave); }
  [data-tarjeta]:hover h3 { color: var(--oro-texto); }
}

/* ── Cursor propio ───────────────────────────────────────────
   El atributo lo pone motion.js sólo cuando el cursor se monta
   de verdad. Si el script no llega, la flecha del sistema se
   queda donde estaba. Los campos de formulario conservan su
   cursor: ahí la posición del caret es información. */
@media (pointer: fine) {
  body[data-cursor-propio], body[data-cursor-propio] * { cursor: none; }
  body[data-cursor-propio] input,
  body[data-cursor-propio] textarea,
  body[data-cursor-propio] select,
  body[data-cursor-propio] [contenteditable] { cursor: auto; }
}

/* ── Entrada de la fotografía del hero ───────────────────────
   Sólo opacidad: la escala la escribe motion.js en el mismo
   transform del parallax, y dos manos sobre la misma propiedad
   se pelean a mitad de la entrada. El reposo es visible. */
@keyframes velar-fondo { from { opacity: .3 } to { opacity: 1 } }
@media (prefers-reduced-motion: no-preference) {
  [data-plano="fondo"] { animation: velar-fondo 1900ms var(--ease-suave) both; }
}

/* ── Costura entre bandas ────────────────────────────────────
   El paso de marfil a espresso era un corte a hueso. Aquí las
   dos telas engranan: 36px a caballo del canto, seis hileras de
   puntada de 6px —la unidad del sistema—, cada una más rala
   según se aleja del canto y desplazada media puntada respecto
   a la de enfrente, de modo que los dientes de una tela caen en
   los huecos de la otra.

   Las dos tintas las escribe motion.js leyendo el fondo real de
   cada banda, así que la costura sirve a cualquier par sin
   saber nada de la paleta. No lleva movimiento a propósito: una
   costura es estructura, no acontecimiento, y lo que no se
   anima no puede quedarse invisible. */
[data-costura] {
  position: absolute;
  left: 0;
  right: 0;
  height: 36px;
  background-repeat: repeat-x;
  background-size: 48px 6px, 24px 6px, 12px 6px, 12px 6px, 24px 6px, 48px 6px;
  background-position: 24px 0, 12px 6px, 0 12px, 6px 18px, 18px 24px, 30px 30px;
  background-image:
    linear-gradient(90deg, var(--costura-abajo) 0 6px, transparent 6px),
    linear-gradient(90deg, var(--costura-abajo) 0 6px, transparent 6px),
    linear-gradient(90deg, var(--costura-abajo) 0 6px, transparent 6px),
    linear-gradient(90deg, var(--costura-arriba) 0 6px, transparent 6px),
    linear-gradient(90deg, var(--costura-arriba) 0 6px, transparent 6px),
    linear-gradient(90deg, var(--costura-arriba) 0 6px, transparent 6px);
}
/* a 390px la hilera rala es ruido: se cose sólo el engranaje */
@media (max-width: 600px) {
  [data-costura] {
    height: 24px;
    background-size: 24px 6px, 12px 6px, 12px 6px, 24px 6px;
    background-position: 12px 0, 0 6px, 6px 12px, 18px 18px;
    background-image:
      linear-gradient(90deg, var(--costura-abajo) 0 6px, transparent 6px),
      linear-gradient(90deg, var(--costura-abajo) 0 6px, transparent 6px),
      linear-gradient(90deg, var(--costura-arriba) 0 6px, transparent 6px),
      linear-gradient(90deg, var(--costura-arriba) 0 6px, transparent 6px);
    margin-top: 6px;
  }
}

/* ── Revelado de sección ─────────────────────────────────────
   Va al final del archivo a propósito: su transición tiene que
   ganar a la de la tarjeta mientras la sección entra.

   El estado oculto es un ATRIBUTO, y lo pone motion.js sólo a
   lo que está bajo el pliegue. Si esta hoja no llega, el
   atributo no pinta nada y el contenido se ve. El reposo de
   todo elemento es visible. */
[data-oculto] {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  clip-path: inset(0 100% 0 0);
  filter: blur(3px);
}
[data-revelando] {
  transition:
    opacity    780ms var(--ease-organico),
    transform  920ms var(--ease-organico),
    clip-path 1120ms var(--ease-organico),
    filter     620ms var(--ease-suave);
}
/* en teléfono el velo de desenfoque se retira: es la capa más
   cara del revelado y la que menos se lee a 390px */
@media (max-width: 760px) {
  [data-oculto] { filter: none; }
}
