/* JMH · Bosque y ciudad · patrones.css (v3): librería de patrones de Territorio, reconstruidos solo con
   tokens del sistema (2026-09-10). Requiere tokens.css + base.css antes; components.css es opcional.
   Parte A: umbral, campo de tareas (.campo/.pieza), compuerta humana, comparador, riel, motion-toggle.
   Parte B: instrumentos de servicio (dupla, máquina, ronda, onda: familia con glifo .persona compartido),
   cuaderno de verbos, nota doblada, recibo de cita, tipografía fantasma. Solo var(--…), cero hex.
   Keyframes jmh-pa-* y jmh-pb-*. Toda animación ambiental se pausa con html.motion-paused (la alterna
   .motion-toggle) y las de los instrumentos arrancan solo en viewport (.is-inview, la agrega patrones.js).
   JS: dist/patrones.js. */

/* ===================================================================== */
/* 1. UMBRAL — blob orgánico con línea de instrumento + copy              */
/* ===================================================================== */

/* .umbral: grid de 2 columnas, escenario a la izquierda, copy a la derecha */
.umbral { display: grid; grid-template-columns: minmax(240px, 380px) 1fr; gap: var(--sp-8); align-items: center; }

/* .umbral__stage: caja del blob; overflow visible a propósito, .is-abierto crece más allá de su caja */
.umbral__stage { position: relative; aspect-ratio: 4 / 5; }

/* .umbral__blob: máscara orgánica compuesta; fondo detrás de la foto (canvas de día, panel de noche) */
.umbral__blob {
  position: absolute; inset: 0; overflow: hidden;
  border-radius: 54% 46% 48% 52% / 35% 38% 62% 65%;
  background: var(--canvas); box-shadow: var(--elev-3);
  transform: scale(1); transform-origin: center;
  transition: transform var(--t-page) var(--ease-out);
}
[data-mode="noche"] .umbral__blob { background: var(--panel); }
/* .is-abierto: estado abierto, escala máxima 1.75×. Solo transform (y opacity en las capas de abajo). */
.umbral.is-abierto .umbral__blob { transform: scale(1.75); }

/* .umbral__img: dos fotos superpuestas, cruzan por opacity según [data-mode]; cero filter */
.umbral__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--t-page) var(--ease-out); }
.umbral__img--dia { opacity: 1; }
[data-mode="noche"] .umbral__img--dia { opacity: 0; }
[data-mode="noche"] .umbral__img--noche { opacity: 1; }

/* .umbral__lineas: SVG técnico encima de la foto, contorno + eje + marcas; non-scaling-stroke para que
   el trazo no engorde cuando .umbral__stage escala en .is-abierto */
.umbral__lineas { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.umbral__linea, .umbral__marca { fill: none; vector-effect: non-scaling-stroke; }
.umbral__linea--exterior { stroke: var(--glass-line); stroke-width: 1.4; }
.umbral__linea--interior { stroke: var(--line); stroke-width: .7; stroke-dasharray: 3 8; }
.umbral__linea--eje, .umbral__marca { stroke: var(--line); stroke-width: .65; }

/* .umbral__riel: "Reunir · Dar forma · Decidir", tres .lbl con punto separador */
.umbral__riel { display: flex; flex-wrap: wrap; align-items: center; margin: 0 0 var(--sp-5); }
.umbral__riel .lbl { margin: 0; }
.umbral__riel .lbl:not(:last-child)::after { content: "·"; margin-inline: var(--sp-3); color: var(--line); }

/* .umbral__titulo: serif grande, énfasis en el color que manda (es <p>, no <h1-4>: text-wrap propio) */
.umbral__titulo { font-family: var(--font-serif); font-size: var(--fs-display); line-height: var(--lh-display); letter-spacing: var(--ls-display); margin: var(--sp-3) 0 0; text-wrap: balance; }
.umbral__titulo em { font-style: normal; color: var(--leaf-fill); }
[data-mode="noche"] .umbral__titulo em { color: var(--leaf); }

@media (max-width: 700px) {
  .umbral { grid-template-columns: 1fr; }
  /* width (no max-width): .umbral__blob/.umbral__lineas son position:absolute, sin tamaño intrínseco
     propio, así que .umbral__stage necesita un ancho explícito para que aspect-ratio tenga de qué
     partir; con solo max-width + margin-inline:auto el grid rompe el stretch y la caja colapsa a 0×0 */
  .umbral__stage { width: min(100%, 320px); margin-inline: auto; }
}

/* ===================================================================== */
/* 2. CAMPO DE TAREAS — tres materialidades + hilos + rol opcional        */
/* ===================================================================== */

/* .campo: 3 columnas; align-items:start deja que cada pieza flote a su propia altura (no estiradas a la
   misma fila): sin esto los desfases verticales de abajo no se ven, la grilla las vuelve a alinear.
   .campo__hilos flota detrás en el 70% superior (donde no lo tapan las piezas) */
.campo { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); align-items: start; gap: var(--sp-6); padding-top: var(--sp-5); }
.campo__hilos { position: absolute; inset: 0 0 30% 0; width: 100%; height: 70%; z-index: -1; opacity: .55; pointer-events: none; }
.campo__hilos path { fill: none; stroke: var(--line); stroke-width: 1; stroke-dasharray: 4 7; }

/* .pieza: base compartida por las tres materialidades. Puede ser <article> o <button type="button">:
   el reset de fuente/alineación/cursor cubre el caso botón sin romper el caso article.
   --pieza-rot es la inclinación de reposo (cada .pieza--* la fija más abajo, como en Territorio); el
   keyframe de deriva parte de ese mismo ángulo, así que reposo → deriva → pausa nunca saltan entre sí. */
.pieza {
  position: relative; display: block; width: 100%; margin: 0; appearance: none;
  font: inherit; color: inherit; text-align: left; cursor: default; z-index: 1;
  background: var(--surface); border: var(--line-hair) solid var(--line);
  box-shadow: var(--elev-2); padding: var(--sp-5) var(--sp-5) var(--sp-4);
  transform: rotate(var(--pieza-rot, 0deg));
  animation: jmh-pa-deriva var(--amb-flow) var(--ease-in-out) infinite;
  transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out), opacity var(--t-base) var(--ease-out);
}
button.pieza { cursor: pointer; }
.pieza + .pieza { animation-delay: -4000ms; }
.pieza + .pieza + .pieza { animation-delay: -8000ms; }
/* deriva ≤6px + rotación mínima que se detiene en hover/focus-within: animation:none (no play-state:paused)
   a propósito. Una animación pausada sigue ganándole al transform normal en la cascada (por eso, sin esto,
   el hover se quedaba en el ángulo donde la deriva iba pasando, no en translateY(-5px) prolijo); quitar
   la animación por completo deja que el transform de abajo mande y la transition lo anime igual de suave.
   El hover conserva --pieza-rot (solo .is-elegida endereza a 0°, ver el estado elegido más abajo). */
.pieza:hover, .pieza:focus-within { animation: none; transform: translateY(-5px) rotate(var(--pieza-rot, 0deg)); box-shadow: var(--elev-3); z-index: 2; }

/* rotaciones de reposo dispersas (nunca alineadas) + desfase vertical por materialidad, como en Territorio:
   la nota queda de base, los datos bajan, el mensaje sube un poco. Mismos nombres de clase de siempre. */
.pieza--nota { --pieza-rot: -3deg; }
.pieza--datos { --pieza-rot: 2deg; margin-top: var(--sp-7); }
.pieza--mensaje { --pieza-rot: -2deg; margin-top: calc(var(--sp-4) * -1); }

/* .pieza__meta: etiqueta de rol/fecha arriba del título */
.pieza__meta { display: block; margin: 0 0 var(--sp-5); font-size: var(--fs-label); line-height: var(--lh-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--rol, var(--soft)); }
.pieza strong { display: block; font-family: var(--font-serif); font-weight: 400; font-size: var(--fs-h3); line-height: 1.15; }

/* data-rol: entrada azul, contexto cobre, acción jade, revisión amarillo (DS4: solo vive aquí y en paneles).
   El rol se lee SOLO en el texto de .pieza__meta: nunca como barra de color en un borde (dispositivo baneado el
   2026-07-10 y otra vez por Jesús el 2026-09-10: "bordes de un solo lado con color" no existen en este sistema). */
.pieza[data-rol="entrada"] { --rol: var(--blue); }
.pieza[data-rol="contexto"] { --rol: var(--copper); }
.pieza[data-rol="accion"] { --rol: var(--jade); }
.pieza[data-rol="revision"] { --rol: var(--warn); }

/* .pieza--nota: esquina doblada, papel */
.pieza--nota { border-radius: var(--r-btn) var(--r-btn) calc(var(--r-panel) * 1.3) var(--r-btn); background: var(--surface-2); }
.pieza__lineas { display: grid; gap: var(--sp-1); margin-top: var(--sp-5); }
.pieza__lineas i { display: block; height: 3px; background: var(--line); width: 85%; }
.pieza__lineas i:nth-child(2) { width: 60%; }
.pieza__lineas i:nth-child(3) { width: 73%; }

/* .pieza--datos: panel oscuro con barras; el token de rol (día) no llega a 4.5:1 sobre --panel, así que
   aquí se resuelve con la variante -fill (ya existe en el sistema, no es un color nuevo) */
.pieza--datos { border-radius: var(--r-card); background: var(--panel); color: var(--panel-ink); }
.pieza--datos .pieza__meta { color: var(--rol, var(--panel-soft)); }
.pieza--datos strong { color: var(--panel-ink); }
.pieza--datos[data-rol="entrada"] { --rol: var(--blue-fill); }
.pieza--datos[data-rol="contexto"] { --rol: var(--copper-fill); }
.pieza--datos[data-rol="accion"] { --rol: var(--jade-fill); }
.pieza--datos[data-rol="revision"] { --rol: var(--warn-fill); }
.pieza__barras { display: flex; align-items: flex-end; gap: var(--sp-1); height: 56px; margin-top: var(--sp-5); }
.pieza__barras i { flex: 1; background: var(--panel-soft); height: 35%; }
.pieza__barras i:nth-child(2n) { height: 60%; }
.pieza__barras i:nth-child(3n) { height: 80%; }
.pieza__barras i:last-child { height: 100%; background: var(--leaf-fill); }

/* .pieza--mensaje: burbuja, esquina recta hacia la cola */
.pieza--mensaje { border-radius: var(--r-panel) var(--r-panel) 0 var(--r-panel); }
.pieza__globo { display: flex; gap: var(--sp-2); align-items: center; justify-content: center; margin-top: var(--sp-5); padding: var(--sp-4) var(--sp-3); border: var(--line-hair) solid var(--line); border-radius: var(--r-btn) var(--r-btn) 0 var(--r-btn); }
.pieza__globo i { display: block; width: 5px; height: 5px; border-radius: 50%; background: var(--soft); opacity: .55; animation: jmh-pa-respirar var(--amb-breathe) var(--ease-in-out) infinite; }
.pieza__globo i:nth-child(2) { animation-delay: -1.6s; }
.pieza__globo i:nth-child(3) { animation-delay: -3.2s; }

/* .pieza__accion: línea de acción bajo cada pieza ("Explorar este proceso ↗"), como en Territorio.
   Opcional: si el markup no la trae, el resto de la pieza sigue funcionando igual. */
.pieza__accion { display: block; margin-top: var(--sp-5); padding-top: var(--sp-3); border-top: var(--line-hair) solid var(--line); font: 500 var(--fs-small) / 1.2 var(--font-mono); color: var(--soft); transition: color var(--t-fast) var(--ease-out); }
.pieza:hover .pieza__accion, .pieza:focus-within .pieza__accion { color: var(--ink); }
.pieza--datos .pieza__accion { border-top-color: var(--glass-line); color: var(--panel-soft); }
.pieza--datos:hover .pieza__accion, .pieza--datos:focus-within .pieza__accion { color: var(--panel-ink); }

/* Estado elegido: .pieza.is-elegida o [aria-pressed="true"] (patrones.js alterna el atributo en los
   <button>, radio dentro del mismo padre). Se endereza a 0°, sube y su .pieza__accion cambia de texto
   por JS (ver patrones.js): nunca contenido largo en ::before, rompe lectura de pantalla. Las piezas
   hermanas bajan a opacity .7 vía :has(), sin depender de una clase extra en el contenedor.
   animation:none, no play-state:paused: verificado con Playwright que una animación en pausa sigue
   ganándole al transform normal en la cascada (el 0° quedaba a medias, en el ángulo donde iba la deriva
   al pausarse): quitar la animación entera deja que translateY(-8px) rotate(0deg) mande de verdad. */
.pieza.is-elegida, .pieza[aria-pressed="true"] {
  --pieza-rot: 0deg; margin-top: 0; transform: translateY(-8px) rotate(0deg);
  animation: none; box-shadow: var(--elev-3); z-index: 2;
}
.pieza.is-elegida .pieza__accion, .pieza[aria-pressed="true"] .pieza__accion { color: var(--leaf-fill); }
.campo:has(.pieza.is-elegida, .pieza[aria-pressed="true"]) .pieza:not(.is-elegida):not([aria-pressed="true"]) { opacity: .7; }

@media (max-width: 700px) {
  .campo { grid-template-columns: 1fr; }
  /* se apilan pero conservan una rotación leve: nunca quedan perfectamente derechas */
  .pieza--nota { --pieza-rot: -1.5deg; margin-top: 0; }
  .pieza--datos { --pieza-rot: 1deg; margin-top: 0; }
  .pieza--mensaje { --pieza-rot: -1deg; margin-top: 0; }
}

/* ===================================================================== */
/* 3. COMPUERTA HUMANA — revisar / ajustar / aprobar                      */
/* ===================================================================== */

/* .compuerta: panel oscuro en los dos modos; el color de rol vive solo aquí adentro (DS4) */
.compuerta { position: relative; background: var(--panel); color: var(--panel-ink); border-radius: var(--r-card); padding: var(--sp-5); }
.compuerta__estado { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); font-size: var(--fs-label); line-height: var(--lh-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--panel-soft); }
.compuerta__punto { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--panel-soft); }
/* el punto respira solo en "revisar"; en los otros dos estados se queda quieto */
.compuerta[data-estado="revisar"] .compuerta__punto { background: var(--warn-fill); animation: jmh-pa-respirar var(--amb-breathe) var(--ease-in-out) infinite; }
.compuerta[data-estado="ajustar"] .compuerta__punto { background: var(--copper-fill); }
.compuerta[data-estado="aprobar"] .compuerta__punto { background: var(--leaf-fill); }
.compuerta__titulo { font-family: var(--font-serif); font-weight: 400; font-size: var(--fs-h4); line-height: 1.25; margin: 0 0 var(--sp-4); color: var(--panel-ink); }
.compuerta__acciones { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.compuerta__btn { font-family: var(--font-mono); font-size: 12px; font-weight: 500; border: var(--line-hair) solid var(--glass-line); background: transparent; color: var(--panel-ink); border-radius: var(--r-btn); padding: 6px var(--sp-3); margin: 0; cursor: pointer; transition: background-color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
.compuerta__btn[aria-pressed="true"] { border-color: transparent; color: var(--panel); }
.compuerta[data-estado="revisar"] .compuerta__btn[aria-pressed="true"] { background: var(--warn-fill); }
.compuerta[data-estado="ajustar"] .compuerta__btn[aria-pressed="true"] { background: var(--copper-fill); }
.compuerta[data-estado="aprobar"] .compuerta__btn[aria-pressed="true"] { background: var(--leaf-fill); }

/* .compuerta--forma: sin color de rol, para pantallas donde el amarillo no puede vivir (home).
   Los selectores llevan [data-estado] a propósito: igualan la especificidad de las reglas de estado de
   arriba (que sí pintan el punto y el botón) y, por venir después, ganan. Sin eso el amarillo se colaba. */
.compuerta--forma[data-estado] .compuerta__punto { background: transparent; border: 1.5px dashed var(--panel-soft); }
.compuerta--forma[data-estado="revisar"] .compuerta__punto { animation: jmh-pa-respirar var(--amb-breathe) var(--ease-in-out) infinite; }
.compuerta--forma[data-estado] .compuerta__btn[aria-pressed="true"] { background: transparent; color: var(--panel-ink); border: 1.5px dashed var(--panel-ink); }

/* ===================================================================== */
/* 4. COMPARADOR — dos imágenes con corte arrastrable                     */
/* ===================================================================== */

.comparador { --corte: 50%; position: relative; height: 380px; overflow: hidden; border-radius: var(--r-panel); isolation: isolate; touch-action: pan-y; cursor: ew-resize; user-select: none; }
.comparador__panel { position: absolute; inset: 0; }
.comparador__panel img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; -webkit-user-drag: none; }
/* los DOS paneles se recortan en el corte: sin esto el rótulo del panel A (z-index propio) se veía encima del panel B
   cuando el corte iba a la izquierda (hallazgo de Jesús en la home v3, 2026-09-10) */
.comparador__panel--a { clip-path: inset(0 calc(100% - var(--corte)) 0 0); }
.comparador__panel--b { clip-path: inset(0 0 0 var(--corte)); }
/* el scrim del rótulo siempre oscurece (color-mix con --panel), porque el texto del rótulo es claro en los dos modos;
   --scrim de día es claro y lavaba los rótulos sobre fotos claras (hallazgo home v3, 2026-09-10) */
.comparador__panel::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, color-mix(in oklab, var(--panel) 74%, transparent) 0%, transparent 46%); pointer-events: none; }
.comparador__rotulo { position: absolute; z-index: 1; left: var(--sp-5); bottom: var(--sp-5); color: var(--panel-ink); }
.comparador__panel--b .comparador__rotulo { left: auto; right: var(--sp-5); text-align: right; }
.comparador__rotulo .lbl { color: var(--panel-soft); }
.comparador__rotulo strong { display: block; margin-top: var(--sp-2); font-family: var(--font-serif); font-weight: 400; font-size: var(--fs-h2); color: var(--panel-ink); }
/* .comparador__manija: vidrio de tamaño fijo (no escala con el scroll), por eso sí puede llevar backdrop-filter */
.comparador__manija { position: absolute; z-index: 2; left: var(--corte); top: 50%; transform: translate(-50%, -50%); width: 48px; height: 48px; border-radius: 50%; border: var(--line-hair) solid var(--glass-line); background: var(--glass); backdrop-filter: blur(12px) saturate(1.15); -webkit-backdrop-filter: blur(12px) saturate(1.15); color: var(--ink); font-size: 20px; line-height: 1; cursor: ew-resize; touch-action: none; }
.comparador__manija:focus-visible { outline: 2px solid var(--blue-fill); outline-offset: 3px; }
.comparador__control { display: block; margin-top: var(--sp-4); text-align: center; }
.comparador__control input { display: block; width: 100%; height: 28px; margin-top: var(--sp-2); cursor: ew-resize; }
.comparador__control input[type="range"] { -webkit-appearance: none; appearance: none; background: transparent; }
.comparador__control input[type="range"]::-webkit-slider-runnable-track { height: 3px; background: var(--line); border-radius: var(--r-pill); }
.comparador__control input[type="range"]::-moz-range-track { height: 3px; background: var(--line); border-radius: var(--r-pill); }
.comparador__control input[type="range"]::-moz-range-progress { height: 3px; background: var(--leaf-fill); border-radius: var(--r-pill); }
.comparador__control input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; margin-top: -7px; width: 17px; height: 17px; border-radius: 50%; background: var(--leaf-fill); border: var(--line-hair) solid var(--surface); box-shadow: var(--elev-2); }
.comparador__control input[type="range"]::-moz-range-thumb { width: 17px; height: 17px; border-radius: 50%; background: var(--leaf-fill); border: var(--line-hair) solid var(--surface); box-shadow: var(--elev-2); }

@media (max-width: 700px) {
  .comparador { height: 460px; }
  .comparador__rotulo strong { font-size: var(--fs-h3); }
  .comparador__panel--a .comparador__rotulo { top: var(--sp-6); bottom: auto; }
  .comparador__panel--a::after { background: linear-gradient(to bottom, color-mix(in oklab, var(--panel) 74%, transparent) 0%, transparent 46%); }
}

/* ===================================================================== */
/* 5. RIEL — progreso vertical ambiental, decorativo                      */
/* ===================================================================== */

/* align-items: stretch (no center): .riel__linea no lleva alto propio, así que toma el alto real que
   ocupan las tres palabras y la línea de progreso queda a la par de "Reunir" arriba y "Decidir" abajo,
   no flotando a la mitad */
.riel { display: flex; align-items: stretch; gap: var(--sp-3); min-height: var(--sp-9); }
.riel__palabras { writing-mode: vertical-rl; margin: 0; }
.riel__palabras .lbl { margin: 0; }
.riel__palabras .lbl:not(:last-child)::after { content: "·"; margin-inline-end: var(--sp-2); color: var(--line); }
/* .riel__linea: 1px, se rellena con --leaf-fill según --riel-p (0 a 1) sobre --line */
.riel__linea { display: block; width: 1px; background: linear-gradient(to bottom, var(--leaf-fill) calc(var(--riel-p, 0) * 100%), var(--line) 0); transition: background var(--t-base) var(--ease-out); }

@media (max-width: 860px) { .riel { display: none; } }

/* ===================================================================== */
/* 6. MOTION-TOGGLE — pausa manual de todo movimiento ambiental           */
/* ===================================================================== */

.motion-toggle {
  position: fixed; right: 14px; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 300;
  display: inline-flex; align-items: center; gap: .5em; margin: 0;
  padding: 8px 14px; background: var(--surface); color: var(--ink);
  border: var(--line-hair) solid var(--line); border-radius: var(--r-pill); box-shadow: var(--elev-2);
  font: 12px/1.2 var(--font-mono); cursor: pointer;
}
.motion-toggle:hover { border-color: var(--soft); }
.motion-toggle:disabled { opacity: .55; cursor: not-allowed; }

/* ≤860px: círculo de 40px con glifos (no emojis), para no tapar contenido con el texto completo del
   botón. Idéntico a lo que ya corre en styles-v3.css de la home, llevado a la fuente (2026-09-10). */
@media (max-width: 860px) {
  .motion-toggle { width: 40px; height: 40px; padding: 0; border-radius: 50%; font-size: 0; display: grid; place-items: center; right: 14px; }
  .motion-toggle::before { content: "▮▮"; font: 500 10px/1 var(--font-mono); letter-spacing: -1px; color: var(--ink); }
  .motion-toggle[aria-pressed="true"]::before { content: "▶"; letter-spacing: 0; }
}

/* pausa todo lo que sea @keyframes en cualquier patrón (deriva de .pieza, respirar de .compuerta__punto
   y .pieza__globo i); las transiciones puntuales (hover, apertura del umbral) no son animation, siguen igual */
html.motion-paused *, html.motion-paused *::before, html.motion-paused *::after { animation-play-state: paused !important; }

/* ===================================================================== */
/* KEYFRAMES (prefijo jmh-pa-; solo transform/opacity, CONTRATO §2.9)     */
/* base.css ya apaga todo esto bajo prefers-reduced-motion                */
/* ===================================================================== */
@keyframes jmh-pa-respirar { 0%, 100% { opacity: .45; transform: scale(.9); } 50% { opacity: 1; transform: scale(1); } }
@keyframes jmh-pa-deriva { 0%, 100% { transform: translateY(0) rotate(var(--pieza-rot, 0deg)); } 50% { transform: translateY(-6px) rotate(calc(var(--pieza-rot, 0deg) + .7deg)); } }

/* ===================================================================== */
/* INSTRUMENTOS DE SERVICIO                                              */
/* base compartida: panel oscuro + tag + nota + cta (fuera del panel)    */
/* ===================================================================== */

.instrumento { position: relative; min-height: 380px; border: var(--line-hair) solid var(--line); border-radius: var(--r-panel); background: var(--panel); color: var(--panel-ink); overflow: hidden; }

.instrumento__tag { position: absolute; z-index: 2; padding: var(--sp-1) var(--sp-2); border: var(--line-hair) solid var(--glass-line); font: var(--fs-label) / var(--lh-label) var(--font-mono); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--panel-soft); background: var(--panel); }
.instrumento__tag--entrada { left: 4%; bottom: 12%; }
.instrumento__tag--entrega { right: 4%; top: 12%; }

.instrumento__nota { position: absolute; z-index: 2; left: var(--sp-5); bottom: var(--sp-4); right: var(--sp-5); margin: 0; color: var(--panel-soft); }

/* fuera del panel: enlace con el nombre del servicio, subrayado en el color que manda */
.instrumento__cta { display: inline-flex; gap: var(--sp-2); align-items: center; margin-top: var(--sp-5); font: 500 var(--fs-small) / 1.2 var(--font-mono); border-bottom: 1px solid var(--leaf-fill); padding-bottom: var(--sp-1); text-decoration: none; color: var(--ink); }
.instrumento__cta span { color: var(--leaf-fill); font-size: 1.3em; transition: transform var(--t-fast) var(--ease-out); }
.instrumento__cta:hover span, .instrumento__cta:focus-visible span { transform: translate(3px, -3px); }
.instrumento__cta:focus-visible { outline: 2px solid var(--blue-fill); outline-offset: 3px; }

/* pieza compartida: punto de acento que respira (lente/módulos/onda/órbita) */
.instrumento__punto { display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--leaf-fill); }

/* pieza compartida: anillo que se expande y se apaga (onda/ronda/dupla) */
.instrumento__anillo { position: absolute; border: 1.5px solid var(--leaf-fill); border-radius: 50%; pointer-events: none; }

/* ===================================================================== */
/* GLIFO COMPARTIDO: .persona (cabeza + hombros, currentColor)           */
/* hilo de la familia: yo con cuántos. Lee como persona a 16px y a 48px. */
/* ===================================================================== */
.persona { --persona-w: 22px; position: relative; display: inline-block; flex: none; width: var(--persona-w); height: calc(var(--persona-w) * 1.15); color: var(--panel-ink); }
.persona::before { content: ""; position: absolute; left: 50%; top: 0; width: 42%; aspect-ratio: 1; transform: translateX(-50%); border-radius: 50%; background: currentColor; }
.persona::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 48%; border-radius: 50% 50% 3px 3px / 90% 90% 3px 3px; background: currentColor; }
.persona--yo { color: var(--leaf-fill); }
.persona--tu { color: var(--panel-ink); }

/* .instrumento__figura: una .persona + rótulo opcional, centrada en su punto de anclaje (%, ver §6) */
.instrumento__figura { position: absolute; z-index: 1; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); }
.instrumento__figura .lbl { margin: 0; color: var(--panel-soft); }

/* .instrumento__nodo: caja de proceso con rótulo mono, mismo look que el módulo de v2. "Encendido" es
   un anillo --leaf-fill que aparece encima (::after, animado solo en opacity, CONTRATO §2.9): nunca un
   cambio de color de borde animado por keyframes. --mini reduce la caja para el pentágono de la ronda. */
.instrumento__nodo { position: absolute; z-index: 1; transform: translate(-50%, -50%); display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border: var(--line-hair) solid var(--glass-line); border-radius: var(--r-field); background: var(--panel); color: var(--panel-ink); font: 500 var(--fs-label) / var(--lh-label) var(--font-mono); letter-spacing: var(--ls-label); text-transform: uppercase; white-space: nowrap; }
.instrumento__nodo::after { content: ""; position: absolute; inset: -1px; border: 1.5px solid var(--leaf-fill); border-radius: inherit; opacity: 0; pointer-events: none; }
.instrumento__nodo--on::after { opacity: 1; }
.instrumento__nodo--mini { padding: 3px 6px; font-size: 8px; width: 56px; text-align: center; white-space: normal; line-height: 1.15; }

/* .instrumento__cable--traza/--flujo: dos trazos superpuestos por tramo. Traza es la línea base, siempre
   visible (legible en reposo, CONTRATO §2.4); flujo es el acento de dato corriendo (color y ventana de
   opacidad se ajustan por instrumento más abajo), igual que --punto/--anillo puede arrancar en opacity 0. */
.instrumento__cable--traza { fill: none; stroke: var(--panel-soft); stroke-width: 1.2; stroke-dasharray: 3 8; opacity: .45; }
.instrumento__cable--flujo { fill: none; stroke: var(--blue-fill); stroke-width: 1.6; stroke-dasharray: 5 7; opacity: 0; animation: jmh-pb-flujo 1300ms linear infinite; animation-play-state: paused; }

/* .instrumento__pila/__registro: hoja de datos apiladas (automatizaciones); cada registro se apaga hacia
   la máquina. Posición/rotación por registro vienen inline (generadas, ver guía); la clase solo da forma. */
.instrumento__pila { position: absolute; z-index: 1; }
.instrumento__registro { position: absolute; left: 0; top: 0; width: 26px; height: 18px; border: var(--line-hair) solid color-mix(in oklab, var(--panel-soft) 55%, transparent); border-radius: 2px; background: var(--panel); }

/* .instrumento__maquina: la caja ya terminada que corre sola, con su punto que respira mientras procesa */
.instrumento__maquina { position: absolute; z-index: 1; transform: translate(-50%, -50%); width: 160px; padding: var(--sp-3); border: var(--line-hair) solid var(--leaf-fill); border-radius: var(--r-field); background: var(--panel); text-align: center; }
.instrumento__maquina strong { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); font: 500 var(--fs-small) / 1.2 var(--font-mono); font-style: normal; color: var(--panel-ink); }
.instrumento__maquina .lbl { display: block; margin-top: var(--sp-1); color: var(--panel-soft); }

/* .instrumento__tabla/__celda: grid que se llena solo. El relleno es un ::after en opacity (nunca
   background animado, CONTRATO §2.9); el borde de la celda vacía queda siempre visible (grid legible). */
.instrumento__tabla { position: absolute; z-index: 1; transform: translate(-50%, -50%); display: grid; grid-template-columns: repeat(3, 24px); grid-auto-rows: 12px; gap: 3px; }
.instrumento__celda { position: relative; border: var(--line-hair) solid color-mix(in oklab, var(--panel-ink) 18%, transparent); }
.instrumento__celda::after { content: ""; position: absolute; inset: 0; background: var(--blue-fill); opacity: 0; }

/* ---------- a) dupla (consultoría 1:1): tú y yo, frente a tu proceso hasta que corre ---------- */
/* nodo 1 siempre encendido (estático, .instrumento__nodo--on); 2-4 encienden en cascada por ciclo */
.instrumento--dupla .instrumento__nodo--n2::after { animation: jmh-pb-dupla-n2 9600ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--dupla .instrumento__nodo--n3::after { animation: jmh-pb-dupla-n3 9600ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--dupla .instrumento__nodo--n4::after { animation: jmh-pb-dupla-n4 9600ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--dupla.is-inview .instrumento__nodo--n2::after,
.instrumento--dupla.is-inview .instrumento__nodo--n3::after,
.instrumento--dupla.is-inview .instrumento__nodo--n4::after { animation-play-state: running; }

/* el flujo azul aparece cuando la cadena ya quedó armada (después del 42% del ciclo) y corre hasta el 94% */
.instrumento--dupla .instrumento__cable--flujo { animation: jmh-pb-flujo 1300ms linear infinite, jmh-pb-dupla-flujo 9600ms var(--ease-out) infinite; animation-play-state: paused, paused; }
.instrumento--dupla.is-inview .instrumento__cable--flujo { animation-play-state: running, running; }

/* el punto del último nodo respira mientras el proceso corre (reutiliza jmh-pb-respira, ya existente) */
.instrumento--dupla .instrumento__nodo--n4 .instrumento__punto { display: inline-block; animation: jmh-pb-respira var(--amb-breathe) var(--ease-in-out) infinite; animation-play-state: paused; }
.instrumento--dupla.is-inview .instrumento__nodo--n4 .instrumento__punto { animation-play-state: running; }

/* mientras se traza cada tramo, un anillo corto pulsa en la cabeza de "yo" (reutiliza .instrumento__anillo) */
.instrumento--dupla .instrumento__figura .instrumento__anillo { left: 50%; top: 0; width: 26px; height: 26px; margin: -13px 0 0 -13px; opacity: 0; animation: jmh-pb-dupla-pulso 9600ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--dupla.is-inview .instrumento__figura .instrumento__anillo { animation-play-state: running; }

/* posiciones fijas (%, CONTRATO §6): centros de los 4 nodos y las dos figuras debajo de la cadena */
.instrumento--dupla .instrumento__nodo--n1 { left: 14%; top: 40%; }
.instrumento--dupla .instrumento__nodo--n2 { left: 38%; top: 40%; }
.instrumento--dupla .instrumento__nodo--n3 { left: 62%; top: 40%; }
.instrumento--dupla .instrumento__nodo--n4 { left: 86%; top: 40%; }
.instrumento--dupla .instrumento__figura--tu { left: 44%; top: 74%; }
.instrumento--dupla .instrumento__figura--yo { left: 56%; top: 74%; }
.instrumento--dupla .persona { --persona-w: 40px; }
/* aquí las dos van arriba (izquierda/derecha), a diferencia del default entrada-abajo del resto */
.instrumento--dupla .instrumento__tag--entrada { top: 12%; bottom: auto; }

/* ---------- b) máquina (automatizaciones a medida): entra volumen, sale ordenado ---------- */
/* cables: el SVG cubre el stage entero (viewBox 700×420 estirado), así los % del brief coinciden con los nodos */
.instrumento__cables { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; }

/* registros: se apagan hacia la máquina en 3 tandas de 3 (simplificación de "uno por uno" por costo de
   CSS: 9 keyframes casi idénticos no valían la pena frente a 3 tandas, que leen igual de claro).
   animation-play-state vive en una regla propia, aparte del animation-name: la tanda 2 necesita DOS
   :nth-child() para su rango y eso le gana en especificidad a .is-inview si play-state viene en el mismo
   selector (bug verificado con capturas: la tanda 2 se quedaba pausada para siempre). */
.instrumento--maquina .instrumento__registro { animation-duration: 7200ms; animation-timing-function: var(--ease-in-out); animation-iteration-count: infinite; animation-play-state: paused; }
.instrumento--maquina .instrumento__registro:nth-child(-n+3) { animation-name: jmh-pb-maquina-r1; }
.instrumento--maquina .instrumento__registro:nth-child(n+4):nth-child(-n+6) { animation-name: jmh-pb-maquina-r2; }
.instrumento--maquina .instrumento__registro:nth-child(n+7) { animation-name: jmh-pb-maquina-r3; }
.instrumento--maquina.is-inview .instrumento__registro { animation-play-state: running; }

/* tabla: las filas se llenan en 3 tandas de 2 (misma simplificación; mismo cuidado de especificidad) */
.instrumento--maquina .instrumento__celda::after { animation-duration: 7200ms; animation-timing-function: var(--ease-out); animation-iteration-count: infinite; animation-play-state: paused; }
.instrumento--maquina .instrumento__celda:nth-child(-n+6)::after { animation-name: jmh-pb-maquina-t1; }
.instrumento--maquina .instrumento__celda:nth-child(n+7):nth-child(-n+12)::after { animation-name: jmh-pb-maquina-t2; }
.instrumento--maquina .instrumento__celda:nth-child(n+13)::after { animation-name: jmh-pb-maquina-t3; }
.instrumento--maquina.is-inview .instrumento__celda::after { animation-play-state: running; }

/* el flujo corre siempre que el instrumento está en viewport (sin fase: pila→máquina→tabla es continuo) */
.instrumento--maquina.is-inview .instrumento__cable--flujo { opacity: .9; animation-play-state: running; }

.instrumento--maquina .instrumento__maquina .instrumento__punto { animation: jmh-pb-respira var(--amb-breathe) var(--ease-in-out) infinite; animation-play-state: paused; }
.instrumento--maquina.is-inview .instrumento__maquina .instrumento__punto { animation-play-state: running; }

/* posiciones fijas (%, CONTRATO §6): pila a la izquierda, máquina al centro, tabla a la derecha */
.instrumento--maquina .instrumento__pila { left: 19%; top: 40%; }
.instrumento--maquina .instrumento__maquina { left: 50%; top: 40%; }
.instrumento--maquina .instrumento__tabla { left: 81%; top: 40%; }
.instrumento--maquina .instrumento__figura--yo { left: 50%; top: 64%; }
.instrumento--maquina .instrumento__figura--tu { left: 81%; top: 74%; }
.instrumento--maquina .instrumento__tag--entrada { top: 12%; bottom: auto; }
.instrumento--maquina .persona { --persona-w: 26px; }
.instrumento__etiqueta { position: absolute; z-index: 1; transform: translateX(-50%); color: var(--panel-soft); white-space: nowrap; }
.instrumento--maquina .instrumento__etiqueta--pila { left: 19%; top: 58%; }
.instrumento--maquina .instrumento__etiqueta--tabla { left: 81%; top: 58%; }

/* ---------- c) ronda (equipos y empresas): uno a algunos, cada quien con su proceso ---------- */
/* mini nodos junto a cada persona, desplazados hacia afuera del pentágono (offset en px sobre el mismo
   punto % de su persona); encienden en su turno y SE QUEDAN encendidos (acumulan) hasta el 96% */
.instrumento--ronda .instrumento__nodo--p1 { transform: translate(-50%, calc(-50% - 30px)); }
.instrumento--ronda .instrumento__nodo--p2 { transform: translate(calc(-50% + 52px), calc(-50% - 4px)); }
.instrumento--ronda .instrumento__nodo--p3 { transform: translate(calc(-50% + 52px), calc(-50% + 4px)); }
.instrumento--ronda .instrumento__nodo--p4 { transform: translate(calc(-50% - 52px), calc(-50% + 4px)); }
.instrumento--ronda .instrumento__nodo--p5 { transform: translate(calc(-50% - 52px), calc(-50% - 4px)); }
.instrumento--ronda .instrumento__nodo--p1::after { animation: jmh-pb-ronda-n1 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda .instrumento__nodo--p2::after { animation: jmh-pb-ronda-n2 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda .instrumento__nodo--p3::after { animation: jmh-pb-ronda-n3 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda .instrumento__nodo--p4::after { animation: jmh-pb-ronda-n4 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda .instrumento__nodo--p5::after { animation: jmh-pb-ronda-n5 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda.is-inview .instrumento__nodo--mini::after { animation-play-state: running; }

/* un anillo pulsa alrededor de la persona en turno (adapta jmh-pb-participa-anillo a 5 turnos de 1440ms) */
.instrumento--ronda .instrumento__figura .instrumento__anillo { inset: -8px; opacity: 0; transform: scale(.6); animation: jmh-pb-ronda-anillo 7200ms var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--ronda .instrumento__figura--p1 .instrumento__anillo { animation-delay: 0ms; }
.instrumento--ronda .instrumento__figura--p2 .instrumento__anillo { animation-delay: 1440ms; }
.instrumento--ronda .instrumento__figura--p3 .instrumento__anillo { animation-delay: 2880ms; }
.instrumento--ronda .instrumento__figura--p4 .instrumento__anillo { animation-delay: 4320ms; }
.instrumento--ronda .instrumento__figura--p5 .instrumento__anillo { animation-delay: 5760ms; }
.instrumento--ronda.is-inview .instrumento__figura .instrumento__anillo { animation-play-state: running; }

/* cable radial de cada persona: muestra su flujo solo durante su turno (misma ventana que el anillo) */
.instrumento--ronda .instrumento__cable--flujo { animation: jmh-pb-flujo 1300ms linear infinite, jmh-pb-ronda-flujo 7200ms var(--ease-out) infinite; animation-play-state: paused, paused; }
.instrumento--ronda .instrumento__cable--flujo-2 { animation-delay: 0ms, 1440ms; }
.instrumento--ronda .instrumento__cable--flujo-3 { animation-delay: 0ms, 2880ms; }
.instrumento--ronda .instrumento__cable--flujo-4 { animation-delay: 0ms, 4320ms; }
.instrumento--ronda .instrumento__cable--flujo-5 { animation-delay: 0ms, 5760ms; }
.instrumento--ronda.is-inview .instrumento__cable--flujo { animation-play-state: running, running; }

/* posiciones fijas (%, CONTRATO §6): yo al centro, pentágono de 5 alrededor (figura y su mini nodo comparten punto) */
.instrumento--ronda .instrumento__figura--yo { left: 50%; top: 52%; }
.instrumento--ronda .instrumento__figura--p1, .instrumento--ronda .instrumento__nodo--p1 { left: 50%; top: 16%; }
.instrumento--ronda .instrumento__figura--p2, .instrumento--ronda .instrumento__nodo--p2 { left: 84%; top: 38%; }
.instrumento--ronda .instrumento__figura--p3, .instrumento--ronda .instrumento__nodo--p3 { left: 72%; top: 80%; }
.instrumento--ronda .instrumento__figura--p4, .instrumento--ronda .instrumento__nodo--p4 { left: 28%; top: 80%; }
.instrumento--ronda .instrumento__figura--p5, .instrumento--ronda .instrumento__nodo--p5 { left: 16%; top: 38%; }
.instrumento--ronda .instrumento__tag { left: 4%; top: 8%; right: auto; bottom: auto; }
.instrumento--ronda .persona--yo { --persona-w: 40px; }
.instrumento--ronda .persona--tu { --persona-w: 28px; }

/* ---------- d) onda (conferencias): un mismo proceso, toda la sala ---------- */
/* el orador ahora es una .persona de 48px; los tres anillos se centran en su CABEZA, no en el wrapper.
   Corrección 2026-09-10 (Jesús: "acércalos, expande el radio"): orador y audiencia anclan por `bottom`
   (no `top`) para que la distancia entre ambos sea un valor fijo en px sin importar cuánto crezca el
   panel por el copy vecino (el panel de "conferencias" en la home mide hasta ~820px por su ficha, vs
   380px en la guía: un top:% daba huecos completamente distintos en cada sitio). */
.instrumento__orador { position: absolute; left: 50%; bottom: 118px; z-index: 1; width: 48px; height: 55px; transform: translate(-50%, -50%); }
.instrumento__orador .instrumento__anillo { left: 50%; top: 10px; width: 60px; height: 60px; margin: -30px 0 0 -30px; opacity: 0; animation: jmh-pb-onda var(--amb-twinkle) var(--ease-out) infinite; animation-play-state: paused; }
.instrumento--onda.is-inview .instrumento__orador .instrumento__anillo { animation-play-state: running; }
.instrumento__orador .instrumento__anillo:nth-of-type(1) { animation-delay: -2400ms; }
.instrumento__orador .instrumento__anillo:nth-of-type(2) { animation-delay: -1200ms; }
.instrumento__orador .instrumento__anillo:nth-of-type(3) { animation-delay: 0ms; }

/* pausado / prefers-reduced-motion: sin esto los anillos (opacity:0 en su reposo) desaparecen y la
   audiencia se queda al .18 de opacidad de la cascada en reposo, leyendo "orador solo" (CONTRATO §2.11:
   el estado pausado muestra la composición completa). Tres anillos estáticos a distinta extensión
   (no los tres pegados al mismo radio) + audiencia a opacidad plena. Solo onda: dupla/máquina/ronda
   no se tocan. */
@media (prefers-reduced-motion: reduce) {
  .instrumento--onda .instrumento__orador .instrumento__anillo { animation: none; opacity: .5; transform: scale(3.4); }
  .instrumento--onda .instrumento__orador .instrumento__anillo:nth-of-type(2) { opacity: .28; transform: scale(6.2); }
  .instrumento--onda .instrumento__orador .instrumento__anillo:nth-of-type(3) { opacity: .14; transform: scale(9); }
  .instrumento--onda .instrumento__audiencia i { animation: none; opacity: 1; transform: translateY(0); }
}
html.motion-paused .instrumento--onda .instrumento__orador .instrumento__anillo { animation: none; opacity: .5; transform: scale(3.4); }
html.motion-paused .instrumento--onda .instrumento__orador .instrumento__anillo:nth-of-type(2) { opacity: .28; transform: scale(6.2); }
html.motion-paused .instrumento--onda .instrumento__orador .instrumento__anillo:nth-of-type(3) { opacity: .14; transform: scale(9); }
html.motion-paused .instrumento--onda .instrumento__audiencia i { animation: none; opacity: 1; }

/* la audiencia comparte período con los anillos (--amb-twinkle) para leerse como una sola onda:
   --fila (0/1/2, por :nth-child, sin tocar el markup) es el frente avanzando fila por fila; --col
   adelanta el centro de cada fila (columnas 5-6, más cerca del orador) y atrasa los bordes (1 y 10),
   como si el frente fuera curvo; --i (0-29, ya lo trae cada celda inline) solo aporta un microdesfase
   por celda para que la fila no encienda entera en un mismo frame. */
.instrumento__audiencia { position: absolute; left: var(--sp-5); right: var(--sp-5); bottom: var(--sp-7); z-index: 1; display: grid; grid-template-columns: repeat(10, 1fr); justify-items: center; gap: var(--sp-2); max-width: 420px; margin-inline: auto; }
.instrumento__audiencia .persona { --persona-w: 20px; }
.instrumento__audiencia i {
  opacity: .18;
  --fila: 0; --col: 0ms;
  animation: jmh-pb-cascada var(--amb-twinkle) var(--ease-out) infinite;
  animation-delay: calc((var(--fila) * 220ms) + var(--col) + (var(--i, 0) * 4ms));
  animation-play-state: paused;
}
.instrumento--onda.is-inview .instrumento__audiencia i { animation-play-state: running; }
.instrumento__audiencia i:nth-child(n+11) { --fila: 1; }
.instrumento__audiencia i:nth-child(n+21) { --fila: 2; }
.instrumento__audiencia i:nth-child(10n+5), .instrumento__audiencia i:nth-child(10n+6) { --col: -70ms; }
.instrumento__audiencia i:nth-child(10n+1), .instrumento__audiencia i:nth-child(10n+10) { --col: 70ms; }

@media (max-width: 700px) {
  .instrumento { min-height: 340px; }
  .instrumento__nodo { font-size: 10px; padding: 6px var(--sp-2); }
  .instrumento__nodo--mini { font-size: 7px; width: 48px; padding: 2px 4px; }
  .instrumento--dupla .persona, .instrumento--maquina .persona { --persona-w: 26px; }
  .instrumento--ronda .persona--yo { --persona-w: 28px; }
  .instrumento--ronda .persona--tu { --persona-w: 18px; }
  .instrumento__orador { --persona-w: 30px; }
  .instrumento__orador .persona { --persona-w: 30px; }
  .instrumento__audiencia { grid-template-columns: repeat(8, 1fr); bottom: var(--sp-7); }
  .instrumento__audiencia .persona { --persona-w: 16px; }
  .instrumento__tabla { grid-template-columns: repeat(3, 18px); }
}

/* ===================================================================== */
/* CUADERNO DE VERBOS                                                     */
/* ===================================================================== */

/* .cuaderno: papel con renglones horizontales tenues (paso 2.2em, como una libreta real) + una línea de
   margen vertical a la izquierda, las dos como capas de background-image (cero markup extra). Sustituye
   el rayado vertical anterior: junto con la fila-flecha-a-la-derecha de abajo leía como un menú, no
   como una libreta (rechazado por Jesús, 2026-09-10). */
.cuaderno {
  max-width: 420px; padding: var(--sp-7) var(--sp-6) var(--sp-6) calc(var(--sp-6) + var(--sp-3));
  background: var(--paper); color: var(--paper-ink); border-radius: var(--r-panel); box-shadow: var(--elev-2);
  background-repeat: no-repeat, repeat;
  background-image:
    linear-gradient(to right, transparent 0 calc(var(--sp-6) - 1px), var(--paper-line) calc(var(--sp-6) - 1px) var(--sp-6), transparent var(--sp-6)),
    repeating-linear-gradient(to bottom, transparent 0 calc(2.2em - 1px), var(--paper-line) calc(2.2em - 1px) 2.2em);
}

.cuaderno__lista { list-style: none; margin: 0; padding: 0; }

/* cada verbo es un renglón escrito a mano: indentación irregular por renglón, sin separadores entre filas */
.cuaderno__lista li:nth-child(1) { margin-left: 0; }
.cuaderno__lista li:nth-child(2) { margin-left: var(--sp-4); }
.cuaderno__lista li:nth-child(3) { margin-left: var(--sp-2); }
.cuaderno__lista li:nth-child(4) { margin-left: var(--sp-5); }

.cuaderno__item { position: relative; display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) 0; text-decoration: none; color: var(--paper-ink); transition: padding-left var(--t-base) var(--ease-out); }
.cuaderno__item:hover, .cuaderno__item:focus-visible { padding-left: var(--sp-2); }

/* marca de lista dibujada a mano: trazo SVG vía mask, recoloreado con --paper-ink (cero raster, cero
   hex visible), en vez de un guion o bullet tipográfico. Rotación distinta por renglón. */
.cuaderno__item::before {
  content: ""; flex: none; align-self: center; width: 15px; height: 10px; background-color: var(--paper-ink); opacity: .5;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 14'%3E%3Cpath d='M2 8C7 4 13 11 18 6' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 14'%3E%3Cpath d='M2 8C7 4 13 11 18 6' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
  mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; mask-position: center; -webkit-mask-position: center; mask-size: contain; -webkit-mask-size: contain;
}
.cuaderno__lista li:nth-child(2) .cuaderno__item::before { transform: rotate(8deg); }
.cuaderno__lista li:nth-child(3) .cuaderno__item::before { transform: rotate(-10deg); }
.cuaderno__lista li:nth-child(4) .cuaderno__item::before { transform: rotate(5deg); }

/* la palabra: Young Serif (nunca itálica falsa: la mano está en la rotación, no en la fuente), cada
   renglón con su propia inclinación menor */
.cuaderno__item > span:first-child { display: block; font-family: var(--font-serif); font-size: var(--fs-h3); line-height: 1.15; }
.cuaderno__lista li:nth-child(1) .cuaderno__item > span:first-child { transform: rotate(-1.2deg); }
.cuaderno__lista li:nth-child(2) .cuaderno__item > span:first-child { transform: rotate(.8deg); }
.cuaderno__lista li:nth-child(3) .cuaderno__item > span:first-child { transform: rotate(-.6deg); }
.cuaderno__lista li:nth-child(4) .cuaderno__item > span:first-child { transform: rotate(1deg); }

/* .cuaderno__flecha: ya no es un glifo gris a la derecha, es un trazo que se dibuja al pasar el mouse.
   font-size:0 esconde el glifo original (↗ ↔ ↘: se conserva en el markup por compatibilidad, aria-hidden
   ya lo saca de lectura de pantalla); ::before es el trazo en reposo (tinta tenue, el "lápiz" ya puesto),
   ::after es el mismo trazo en --leaf, revelado con clip-path de 0% a 100% al hover/focus: se "dibuja".
   Pruebo/↔ usa un trazo con gancho en las dos puntas (--flecha-svg distinto); Exploro/Aplico/Enseño
   reusan el mismo trazo de un gancho, rotado para apuntar arriba-derecha o abajo-derecha. */
.cuaderno__flecha { position: relative; flex: none; align-self: center; width: 24px; height: 16px; font-size: 0;
  --flecha-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 16'%3E%3Cpath d='M2 13C10 11 16 8 24 4M24 4L18 5.5M24 4L21.5 9.5' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.cuaderno__flecha::before, .cuaderno__flecha::after {
  content: ""; position: absolute; inset: 0;
  mask-image: var(--flecha-svg); -webkit-mask-image: var(--flecha-svg);
  mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; mask-position: center; -webkit-mask-position: center; mask-size: contain; -webkit-mask-size: contain;
}
.cuaderno__flecha::before { background-color: var(--paper-line); }
.cuaderno__flecha::after { background-color: var(--leaf); clip-path: inset(0 100% 0 0); transition: clip-path .5s var(--ease-out); }
.cuaderno__item:hover .cuaderno__flecha::after, .cuaderno__item:focus-visible .cuaderno__flecha::after { clip-path: inset(0 0 0 0); }
.cuaderno__lista li:nth-child(2) .cuaderno__flecha { --flecha-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 16'%3E%3Cpath d='M3 8C10 6.5 18 9.5 25 8M6.5 8L9.5 5M6.5 8L9.5 11M21.5 8L18.5 5M21.5 8L18.5 11' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); transform: rotate(-2deg); }
.cuaderno__lista li:nth-child(1) .cuaderno__flecha, .cuaderno__lista li:nth-child(4) .cuaderno__flecha { transform: rotate(-4deg); }
.cuaderno__lista li:nth-child(3) .cuaderno__flecha { transform: rotate(86deg); }

/* nota al margen: ya rotada -6°; se le agrega un subrayado ondulado dibujado en SVG (mask + --leaf) */
.cuaderno__nota { position: relative; width: fit-content; margin: var(--sp-7) 0 0; padding-left: var(--sp-6); font-family: var(--font-serif); font-style: normal; font-size: var(--fs-h4); color: var(--paper-ink); opacity: .75; transform: rotate(-6deg); transform-origin: left center; }
.cuaderno__nota::after {
  content: ""; position: absolute; left: var(--sp-6); right: -4px; bottom: -.3em; height: .45em; background-color: var(--leaf); opacity: .8;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 8'%3E%3Cpath d='M0 4C3 1 7 1 10 4C13 7 17 7 20 4' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 8'%3E%3Cpath d='M0 4C3 1 7 1 10 4C13 7 17 7 20 4' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  mask-repeat: repeat-x; -webkit-mask-repeat: repeat-x; mask-position: left center; -webkit-mask-position: left center; mask-size: 16px 6px; -webkit-mask-size: 16px 6px;
}

/* esquina doblada, opcional: agrega .cuaderno--doblada (mismo recurso que .nota-doblada) */
.cuaderno--doblada { position: relative; }
.cuaderno--doblada::before { content: ""; position: absolute; right: 0; bottom: 0; width: 22px; height: 22px; background: linear-gradient(45deg, var(--paper-line) 50%, var(--canvas) 50%); border-radius: 0 0 var(--r-panel) 0; }

@media (max-width: 700px) {
  .cuaderno { padding-left: calc(var(--sp-5) + var(--sp-2)); }
  .cuaderno__item > span:first-child { font-size: var(--fs-h4); }
  .cuaderno__lista li:nth-child(2) { margin-left: var(--sp-3); }
  .cuaderno__lista li:nth-child(4) { margin-left: var(--sp-3); }
}

/* ===================================================================== */
/* NOTA ADHESIVA CON ESQUINA DOBLADA                                     */
/* ===================================================================== */

.nota-doblada { position: relative; max-width: 280px; padding: var(--sp-4) var(--sp-4) var(--sp-5); background: var(--paper); color: var(--paper-ink); border-radius: var(--r-field) var(--r-field) 0 var(--r-field); box-shadow: var(--elev-2); transform: rotate(-5deg); font-family: var(--font-mono); --nota-fondo: var(--canvas); --doblez: 28px; }
.nota-doblada::before, .nota-doblada::after { content: ""; position: absolute; right: 0; bottom: 0; width: var(--doblez); height: var(--doblez); }
.nota-doblada::before { z-index: 1; background: linear-gradient(to top left, var(--nota-fondo) 50%, color-mix(in oklab, var(--paper) 84%, var(--paper-ink)) 50%); }
.nota-doblada::after { right: 3px; bottom: 3px; z-index: 0; background: linear-gradient(to top left, transparent 50%, color-mix(in oklab, var(--paper-ink) 26%, transparent) 50%); }
.nota-doblada .lbl { color: color-mix(in oklab, var(--paper-ink) 62%, transparent); }
.nota-doblada__frase { margin: var(--sp-2) 0 0; font-family: var(--font-serif); font-size: var(--fs-h4); line-height: 1.3; }

.nota-doblada--b { transform: rotate(3deg); }
.nota-doblada--c { transform: rotate(-2deg); }

/* ===================================================================== */
/* RECIBO DE CITA                                                        */
/* ===================================================================== */

.recibo { position: relative; max-width: 340px; padding: var(--sp-5) var(--sp-4) var(--sp-6); background: var(--paper); color: var(--paper-ink); font-family: var(--font-mono); border-radius: var(--r-card) var(--r-card) 0 0; box-shadow: var(--elev-2); }

.recibo__cabeza { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
.recibo__cabeza .lbl { color: color-mix(in oklab, var(--paper-ink) 60%, transparent); }

.recibo__cita { margin: var(--sp-4) 0; padding-top: var(--sp-4); border-top: 1px dashed var(--paper-line); font-family: var(--font-serif); font-style: normal; font-size: var(--fs-h4); line-height: 1.35; }

/* flex-wrap + nowrap por celda: a 390px "resultado · reporte solo" no cabe junto a "sesiones · 4" y,
   sin esto, cada frase se parte a media palabra en vez de caer completa a su propia línea. */
.recibo__total { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-1) var(--sp-3); padding-top: var(--sp-3); border-top: 1px dashed var(--paper-line); font: 500 var(--fs-data) / var(--lh-data) var(--font-mono); letter-spacing: var(--ls-data); font-variant-numeric: tabular-nums; }
.recibo__total span { white-space: nowrap; }

.recibo__autor { margin: var(--sp-4) 0 0; padding-top: var(--sp-3); border-top: 1px dashed var(--paper-line); color: color-mix(in oklab, var(--paper-ink) 60%, transparent); }

/* borde inferior dentado: dos triángulos de 45deg en mosaico, revelan lo que hay detrás */
.recibo::after { content: ""; position: absolute; left: 0; right: 0; bottom: -13px; height: 14px; pointer-events: none; background-image: linear-gradient(-45deg, var(--paper) 7px, transparent 7.5px), linear-gradient(45deg, var(--paper) 7px, transparent 7.5px); background-size: 14px 14px; background-position: left top; background-repeat: repeat-x; }

/* ===================================================================== */
/* FANTASMA (tipografía fantasma sobre foto)                             */
/* ===================================================================== */

/* .fantasma-stage: contenedor de referencia (position relative + overflow hidden) para el span fantasma */
.fantasma-stage { position: relative; overflow: hidden; border-radius: var(--r-panel); }

/* opacidad .12: dentro del rango 8-14% que documenta tokens.json (type.reglas); .1 exacto se probó
   contra guia/img/hero-day.webp y resultaba casi invisible sobre la zona de montaña/agua del horizonte. */
.fantasma { position: absolute; left: var(--sp-4); right: var(--sp-4); bottom: -0.06em; z-index: 0; margin: 0; font-family: var(--font-serif); font-size: clamp(64px, 14vw, 180px); line-height: .86; color: var(--ink); opacity: .12; pointer-events: none; text-wrap: balance; }

/* ===================================================================== */
/* KEYFRAMES (solo transform/opacity/stroke-dashoffset, CONTRATO §2.9)   */
/* base.css ya apaga todo esto bajo prefers-reduced-motion               */
/* ===================================================================== */
@keyframes jmh-pb-respira { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes jmh-pb-flujo { to { stroke-dashoffset: -32; } }
@keyframes jmh-pb-onda { 0% { transform: scale(.6); opacity: .7; } 100% { transform: scale(9); opacity: 0; } }
@keyframes jmh-pb-cascada { 0%, 55%, 100% { opacity: .18; transform: translateY(0); } 63% { opacity: 1; transform: translateY(-2px); } }

/* ---- dupla: cadena que se arma (9600ms) ---- */
@keyframes jmh-pb-dupla-n2 { 0%, 14% { opacity: 0; } 14.6%, 94% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-dupla-n3 { 0%, 28% { opacity: 0; } 28.6%, 94% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-dupla-n4 { 0%, 42% { opacity: 0; } 42.6%, 94% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-dupla-flujo { 0%, 42% { opacity: 0; } 42.6%, 94% { opacity: .9; } 100% { opacity: 0; } }
@keyframes jmh-pb-dupla-pulso { 0%, 4%, 14%, 18%, 28%, 32%, 100% { opacity: 0; transform: scale(.6); } 2%, 16%, 30% { opacity: .8; transform: scale(1.5); } }

/* ---- máquina: registros que se apagan y filas que se llenan, en 3 tandas (7200ms) ---- */
@keyframes jmh-pb-maquina-r1 { 0%, 4% { opacity: 1; transform: translateX(0); } 10%, 88% { opacity: .12; transform: translateX(10px); } 96%, 100% { opacity: 1; transform: translateX(0); } }
@keyframes jmh-pb-maquina-r2 { 0%, 22% { opacity: 1; transform: translateX(0); } 28%, 88% { opacity: .12; transform: translateX(10px); } 96%, 100% { opacity: 1; transform: translateX(0); } }
@keyframes jmh-pb-maquina-r3 { 0%, 40% { opacity: 1; transform: translateX(0); } 46%, 88% { opacity: .12; transform: translateX(10px); } 96%, 100% { opacity: 1; transform: translateX(0); } }
@keyframes jmh-pb-maquina-t1 { 0%, 15% { opacity: 0; transform: scale(.85); } 22%, 88% { opacity: .75; transform: scale(1); } 96%, 100% { opacity: 0; transform: scale(.85); } }
@keyframes jmh-pb-maquina-t2 { 0%, 38% { opacity: 0; transform: scale(.85); } 45%, 88% { opacity: .75; transform: scale(1); } 96%, 100% { opacity: 0; transform: scale(.85); } }
@keyframes jmh-pb-maquina-t3 { 0%, 61% { opacity: 0; transform: scale(.85); } 68%, 88% { opacity: .75; transform: scale(1); } 96%, 100% { opacity: 0; transform: scale(.85); } }

/* ---- ronda: 5 turnos de 1440ms sobre 7200ms; el anillo pasa, el mini nodo se queda encendido ---- */
@keyframes jmh-pb-ronda-anillo { 0%, 96%, 100% { opacity: 0; transform: scale(.6); } 10% { opacity: .8; transform: scale(.6); } 20% { opacity: 0; transform: scale(1.8); } }
@keyframes jmh-pb-ronda-flujo { 0%, 96%, 100% { opacity: 0; } 4%, 18% { opacity: .9; } }
@keyframes jmh-pb-ronda-n1 { 0% { opacity: 0; } 4%, 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-ronda-n2 { 0%, 20% { opacity: 0; } 24%, 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-ronda-n3 { 0%, 40% { opacity: 0; } 44%, 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-ronda-n4 { 0%, 60% { opacity: 0; } 64%, 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes jmh-pb-ronda-n5 { 0%, 80% { opacity: 0; } 84%, 96% { opacity: 1; } 100% { opacity: 0; } }
