/* ==========================================================================
     VIGÍA — el vigía de la baliza. Recoge cada caso que llega, apunta lo que
     importa y deja el parte listo (mismo formato que el brief de Fase 1).
     ========================================================================== */

  /* Con el tema claro, --ink-faint (#a3a099) sobre el papel se queda en 2,4:1 de
     contraste: por debajo del 4,5:1 que pide WCAG AA para texto. Aquí dentro hay
     mucha micro-etiqueta, así que se corrigen los dos tonos SOLO dentro del vigía
     —sin tocar la paleta global— manteniendo los dos niveles de jerarquía:
       dim   #55534e → 6,7:1
       faint #6f6d68 → 4,6:1
     Si la paleta global se arregla, esto se puede quitar y volver a medir. */
  .vg-hail, .vg-nudge, .vg-panel {
    --ink-dim: #55534e;
    --ink-faint: #6f6d68;
  }

  /* ---- la llamada: se aviva al bajar la torre ---- */
  .vg-hail {
    position: fixed; z-index: 70;
    right: clamp(1rem, 3vw, 2.2rem); bottom: clamp(1rem, 3vh, 2.2rem);
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.72rem 1.1rem 0.72rem 0.8rem; cursor: pointer;
    background: rgba(20,23,26,0.92); border: 1px solid rgba(209,0,94,0.34);
    color: var(--ink); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 14px 34px rgba(20,23,26,0.12);
    opacity: 0; transform: translateY(14px); pointer-events: none;
    transition: opacity 0.5s cubic-bezier(0.23,1,0.32,1), transform 0.5s cubic-bezier(0.23,1,0.32,1),
                border-color 0.25s ease, color 0.25s ease;
  }
  .vg-hail.up { opacity: 1; transform: translateY(0); pointer-events: auto; }
  .vg-hail:hover { border-color: var(--accent); color: var(--accent); }
  .vg-hail:active { transform: scale(0.98); }
  .vg-hail .lamp { position: relative; width: 26px; height: 26px; display: grid; place-items: center; flex: none; color: var(--accent); }
  .vg-hail .lamp svg { width: 22px; height: 22px; }
  .vg-hail .lamp::after {
    content: ""; position: absolute; inset: -5px; border: 1px solid rgba(209,0,94,0.4);
    border-radius: 50%; animation: vgSweep 3.4s ease-out infinite;
  }
  @keyframes vgSweep { 0% { transform: scale(0.6); opacity: 0.9; } 100% { transform: scale(1.5); opacity: 0; } }
  .vg-hail .txt { display: grid; gap: 0.2rem; text-align: left; }
  .vg-hail .txt b { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; font-weight: 500; }
  .vg-hail .txt span { font-size: 0.72rem; color: var(--ink-faint); font-weight: 300; }
  .vg-hail.stowed { opacity: 0; transform: translateY(14px) scale(0.94); pointer-events: none; }
  @media (prefers-reduced-motion: reduce) { .vg-hail .lamp::after { animation: none; opacity: 0.35; } }
  @media (max-width: 560px) { .vg-hail .txt span { display: none; } }

  /* ---- el aviso, una sola vez ---- */
  .vg-nudge {
    position: fixed; z-index: 71;
    right: clamp(1rem, 3vw, 2.2rem); bottom: calc(clamp(1rem, 3vh, 2.2rem) + 78px);
    width: min(268px, 78vw); padding: 0.95rem 2.1rem 0.95rem 1rem;
    background: rgba(20,23,26,0.96); border: 1px solid var(--hair);
    border-left: 1px solid var(--accent);
    font-size: 0.8rem; line-height: 1.65; color: var(--ink-dim); font-weight: 300;
    box-shadow: 0 14px 34px rgba(20,23,26,0.12);
    opacity: 0; transform: translateY(8px); pointer-events: none;
    transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.23,1,0.32,1);
  }
  .vg-nudge.up { opacity: 1; transform: translateY(0); pointer-events: auto; }
  .vg-nudge b { color: var(--ink); font-weight: 400; }
  .vg-nudge .x {
    position: absolute; top: 0.4rem; right: 0.4rem; width: 24px; height: 24px;
    display: grid; place-items: center; background: none; border: 0; cursor: pointer;
    color: var(--ink-faint); font-size: 0.9rem; line-height: 1;
  }
  .vg-nudge .x:hover { color: var(--accent); }

  /* ---- la consola ---- */
  .vg-panel {
    position: fixed; z-index: 90;
    right: clamp(1rem, 3vw, 2.2rem); bottom: clamp(1rem, 3vh, 2.2rem);
    width: min(800px, 94vw); height: min(650px, 84vh);
    /* la fila se fija a la altura del panel: si no, crece con el cuaderno y lo desborda */
    display: grid; grid-template-columns: minmax(0, 1fr) 252px; grid-template-rows: minmax(0, 1fr);
    overflow: hidden;
    background: rgba(247,245,240,0.975); border: 1px solid rgba(209,0,94,0.28);
    box-shadow: 0 30px 80px rgba(20,23,26,0.18), 0 0 0 1px rgba(20,23,26,0.06);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    transform-origin: bottom right;
    opacity: 0; transform: translateY(20px) scale(0.965); pointer-events: none;
    transition: opacity 0.34s ease, transform 0.52s cubic-bezier(0.23,1,0.32,1);
  }
  .vg-panel.open { opacity: 1; transform: none; pointer-events: auto; }
  .vg-panel[hidden] { display: none; }
  @media (prefers-reduced-motion: reduce) { .vg-panel { transition: opacity 0.2s ease; transform: none; } }

  .vg-main { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; min-width: 0; min-height: 0; }

  .vg-head {
    display: flex; align-items: center; gap: 1rem; justify-content: space-between;
    padding: 1rem clamp(1rem, 2.4vw, 1.5rem); border-bottom: 1px solid var(--hair);
  }
  .vg-who { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
  .vg-who .lamp { width: 30px; height: 30px; display: grid; place-items: center; border: 1px solid rgba(209,0,94,0.3); color: var(--accent); flex: none; }
  .vg-who .lamp svg { width: 17px; height: 17px; }
  .vg-who b { display: block; font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.22em; font-weight: 500; }
  .vg-who span { display: block; font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); margin-top: 0.28rem; }
  .vg-prog { display: flex; align-items: center; gap: 0.6rem; }
  .vg-prog b, .vg-prog i { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.14em; font-style: normal; }
  .vg-prog b { color: var(--accent); font-weight: 500; }
  .vg-prog i { color: var(--ink-faint); }
  .vg-prog .bar { width: 54px; height: 1px; background: var(--hair); position: relative; }
  /* escala en vez de ancho: mismo resultado, sin tocar layout al avanzar de bloque */
  .vg-prog .bar u {
    position: absolute; inset: 0 auto 0 0; width: 100%; height: 1px; background: var(--accent);
    transform: scaleX(0.25); transform-origin: left;
    transition: transform 0.5s cubic-bezier(0.23,1,0.32,1);
  }
  @media (max-width: 560px) { .vg-prog .bar { display: none; } }
  .vg-x {
    width: 32px; height: 32px; flex: none; display: grid; place-items: center; cursor: pointer;
    background: none; border: 1px solid var(--hair); color: var(--ink-dim);
    transition: color 0.25s ease, border-color 0.25s ease;
  }
  .vg-x svg { width: 12px; height: 12px; }
  .vg-x:hover { color: var(--accent); border-color: var(--accent-dim); }

  /* ---- el cuaderno ---- */
  .vg-log {
    overflow-y: auto; overscroll-behavior: contain;
    padding: 1.4rem clamp(1rem, 2.4vw, 1.5rem) 0.6rem;
    display: flex; flex-direction: column; gap: 1.05rem;
    scrollbar-width: thin; scrollbar-color: rgba(20,23,26,0.16) transparent;
  }
  .vg-log::-webkit-scrollbar { width: 5px; }
  .vg-log::-webkit-scrollbar-thumb { background: rgba(20,23,26,0.14); }
  /* con poco texto la conversación se apoya en la barra de respuesta, como una charla de verdad;
     el margen automático se resuelve a 0 en cuanto hay scroll, así que no recorta nada */
  .vg-log > *:first-child { margin-top: auto; }

  .vg-line { opacity: 0; transform: translateY(9px); animation: vgIn 0.5s cubic-bezier(0.23,1,0.32,1) forwards; }
  @keyframes vgIn { to { opacity: 1; transform: translateY(0); } }
  @media (prefers-reduced-motion: reduce) { .vg-line { animation: none; opacity: 1; transform: none; } }

  /* el vigía habla */
  .vg-line.said { display: grid; grid-template-columns: 12px minmax(0, 1fr); gap: 0.85rem; max-width: 46ch; }
  .vg-line.said .tick { width: 2px; height: 13px; background: var(--accent); margin-top: 0.4rem; }
  .vg-line.said p { font-size: 0.9rem; line-height: 1.8; color: var(--ink); font-weight: 300; }
  .vg-line.said.aside p { color: var(--ink-dim); font-size: 0.85rem; }
  .vg-line.said.aside .tick { background: var(--accent-dim); }

  /* el visitante responde */
  .vg-line.mine { margin-left: auto; max-width: 40ch; }
  .vg-line.mine p {
    font-size: 0.86rem; line-height: 1.7; color: var(--ink); font-weight: 300; text-align: right;
    padding: 0.6rem 0.9rem; border: 1px solid rgba(209,0,94,0.26); background: rgba(209,0,94,0.05);
  }

  /* escribiendo */
  .vg-typing { display: flex; align-items: center; gap: 5px; padding-left: 27px; height: 14px; }
  .vg-typing s { width: 4px; height: 4px; background: var(--accent-dim); display: block; text-decoration: none; animation: vgBlink 1.25s ease-in-out infinite; }
  .vg-typing s:nth-child(2) { animation-delay: 0.15s; }
  .vg-typing s:nth-child(3) { animation-delay: 0.3s; }
  @keyframes vgBlink { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
  @media (prefers-reduced-motion: reduce) { .vg-typing s { animation: none; opacity: 0.6; } }

  /* ---- el veredicto ---- */
  .vg-verdict { border: 1px solid rgba(209,0,94,0.26); padding: 1.15rem 1.2rem; margin-top: 0.3rem; }
  .vg-verdict.soft { border-color: var(--hair); }
  .vg-verdict .head { display: flex; align-items: baseline; gap: 0.6rem; }
  .vg-verdict .head b { font-size: 1.15rem; font-weight: 400; color: var(--accent); letter-spacing: -0.01em; }
  .vg-verdict.soft .head b { color: var(--ink); }
  .vg-verdict .head span { font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); }
  .vg-verdict > p { margin-top: 0.8rem; font-size: 0.87rem; line-height: 1.8; color: var(--ink-dim); font-weight: 300; }
  .vg-plan { margin-top: 1.2rem; border-top: 1px solid var(--hair); }
  .vg-plan .r { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.6rem 0; border-bottom: 1px solid var(--hair); }
  .vg-plan .r b { display: flex; align-items: center; gap: 0.6rem; font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.14em; font-weight: 500; color: var(--ink); }
  .vg-plan .r b em { width: 5px; height: 5px; background: var(--hair); flex: none; font-style: normal; }
  .vg-plan .r.done b em { background: var(--accent); }
  .vg-plan .r span { font-size: 0.76rem; color: var(--ink-faint); font-weight: 300; text-align: right; }
  .vg-fine { margin-top: 0.9rem; font-size: 0.74rem; line-height: 1.7; color: var(--ink-faint); font-weight: 300; }

  /* qué hace falta para arrancar: cierra el hueco entre "encajas" y "y ahora qué" */
  .vg-arranque { margin-top: 1.3rem; padding: 0.95rem 1rem; border: 1px solid var(--hair); background: rgba(255,255,255,0.02); }
  .vg-arranque b {
    display: block; font-family: var(--mono); font-size: 0.56rem; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--ink); font-weight: 500;
  }
  .vg-arranque p { margin-top: 0.35rem; font-size: 0.79rem; line-height: 1.65; color: var(--ink-faint); font-weight: 300; }
  .vg-arranque ul { margin: 0.7rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.42rem; }
  .vg-arranque li {
    font-size: 0.84rem; line-height: 1.6; color: var(--ink-dim); font-weight: 300;
    padding-left: 0.95rem; position: relative;
  }
  .vg-arranque li::before { content: ""; position: absolute; left: 0; top: 0.62em; width: 4px; height: 1px; background: var(--accent); }

  /* lo que se lleva puesto: la parte del cierre que no habla de nosotros sino de él */
  .vg-advice { margin-top: 1.3rem; display: grid; gap: 1rem; }
  .vg-advice > div { padding-left: 0.9rem; border-left: 1px solid var(--accent-dim); }
  .vg-advice > div:last-child { border-left-color: var(--hair); }
  .vg-advice b {
    display: block; font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--accent); font-weight: 500;
  }
  .vg-advice > div:last-child b { color: var(--ink-dim); }
  .vg-advice p { margin-top: 0.45rem; font-size: 0.85rem; line-height: 1.8; color: var(--ink); font-weight: 300; }

  /* ---- la barra de respuesta ---- */
  .vg-compose { padding: 0.9rem clamp(1rem, 2.4vw, 1.5rem) 1.1rem; border-top: 1px solid var(--hair); }
  .vg-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
  .vg-chip {
    font-family: var(--sans); font-size: 0.78rem; font-weight: 300; line-height: 1;
    padding: 0.62rem 0.9rem; cursor: pointer; color: var(--ink-dim);
    background: transparent; border: 1px solid var(--hair);
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, transform 0.16s cubic-bezier(0.23,1,0.32,1);
  }
  .vg-chip:hover { color: var(--accent); border-color: var(--accent-dim); }
  .vg-chip:active { transform: scale(0.97); }
  .vg-chip.on { color: var(--accent); border-color: var(--accent-dim); background: rgba(209,0,94,0.08); }
  .vg-chip.on::before { content: "✓ "; }
  .vg-chip.go { border-color: var(--accent); background: var(--accent); color: #ffffff; font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; padding: 0.68rem 1.1rem; }
  .vg-chip.go:hover { background: #a8004b; color: #ffffff; }
  .vg-chip[disabled] { opacity: 0.35; cursor: not-allowed; }
  .vg-chip[disabled]:hover { color: var(--ink-dim); border-color: var(--hair); }
  .vg-chip.ghost { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase; }

  /* los huecos de agenda: se leen como horas, no como opciones sueltas */
  .vg-slots { padding-bottom: 0.85rem; margin-bottom: 0.85rem; border-bottom: 1px solid var(--hair); }
  .vg-slots .vg-chip { font-variant-numeric: tabular-nums; }

  .vg-field { display: flex; align-items: flex-end; gap: 0.8rem; }

  /* el campo para responder escribiendo, bajo los botones */
  .vg-libre { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.85rem; }
  .vg-libre input {
    flex: 1; min-width: 0; font-family: var(--sans); font-size: 0.86rem; font-weight: 300;
    color: var(--ink); background: transparent; border: 0; border-bottom: 1px solid var(--hair);
    padding: 0.45rem 0; transition: border-color 0.25s ease;
  }
  .vg-libre input::placeholder { color: var(--ink-faint); }
  .vg-libre input:focus { outline: none; border-bottom-color: var(--accent); }
  .vg-libre .vg-send { width: 34px; height: 34px; }
  .vg-libre .vg-send svg { width: 13px; height: 13px; }
  .vg-field textarea {
    flex: 1; min-width: 0; resize: none; font-family: var(--sans); font-size: 0.9rem; font-weight: 300;
    line-height: 1.7; color: var(--ink); background: transparent;
    border: 0; border-bottom: 1px solid var(--hair); padding: 0.5rem 0; max-height: 118px;
    transition: border-color 0.25s ease;
  }
  .vg-field textarea::placeholder { color: var(--ink-faint); }
  .vg-field textarea:focus { outline: none; border-bottom-color: var(--accent); }
  .vg-send {
    flex: none; width: 40px; height: 40px; display: grid; place-items: center; cursor: pointer;
    background: transparent; border: 1px solid rgba(20,23,26,0.22); color: var(--ink);
    transition: border-color 0.24s ease, color 0.24s ease, background 0.24s ease, transform 0.16s cubic-bezier(0.23,1,0.32,1);
  }
  .vg-send svg { width: 15px; height: 15px; }
  .vg-send:hover { border-color: var(--accent); color: var(--accent); }
  .vg-send:active { transform: scale(0.96); }
  .vg-send[disabled] { opacity: 0.32; cursor: not-allowed; }
  .vg-send[disabled]:hover { border-color: rgba(20,23,26,0.22); color: var(--ink); }
  .vg-skip { margin-top: 0.7rem; display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }

  /* ejemplos del sector: se ofrecen para editar, no para elegir — de ahí que no
     parezcan opciones sino frases a medio escribir */
  .vg-egs { margin-top: 0.85rem; }
  .vg-egs > span {
    display: block; font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.16em;
    text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.5rem;
  }
  .vg-egs .row { display: flex; flex-direction: column; gap: 0.3rem; align-items: flex-start; }
  .vg-eg {
    max-width: 100%; text-align: left; cursor: pointer;
    font-family: var(--sans); font-size: 0.79rem; font-weight: 300; line-height: 1.5;
    color: var(--ink-faint); background: none; border: 0; padding: 0.18rem 0;
    border-bottom: 1px dashed rgba(255,255,255,0.14);
    transition: color 0.2s ease, border-color 0.2s ease;
  }
  .vg-eg::before { content: "«"; opacity: 0.5; }
  .vg-eg::after  { content: "»"; opacity: 0.5; }
  .vg-eg:hover { color: var(--accent); border-bottom-color: var(--accent-dim); }

  .vg-back {
    font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-faint); background: none; border: 0; padding: 0.5rem 0.2rem; cursor: pointer;
    transition: color 0.2s ease;
  }
  .vg-back:hover { color: var(--accent); }
  .vg-sep { flex: 1; }
  .vg-err { margin-top: 0.6rem; font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase; color: #b3261e; }
  .vg-done { font-size: 0.8rem; color: var(--ink-faint); font-weight: 300; line-height: 1.7; }
  .vg-done b { color: var(--accent); font-weight: 400; }

  /* ---- el parte, rellenándose en vivo ---- */
  .vg-ficha {
    border-left: 1px solid var(--hair); padding: 1rem 1.15rem;
    display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 0.9rem;
    background: rgba(20,23,26,0.012); min-width: 0; min-height: 0;
  }
  .vg-ficha > .label { color: var(--ink-faint); }
  .vg-rows { overflow-y: auto; scrollbar-width: thin; scrollbar-color: rgba(20,23,26,0.14) transparent; }
  .vg-rows::-webkit-scrollbar { width: 4px; }
  .vg-rows::-webkit-scrollbar-thumb { background: rgba(20,23,26,0.12); }
  .vg-rows .r {
    padding: 0.62rem 0; border-bottom: 1px solid var(--hair);
    opacity: 0; animation: vgIn 0.45s cubic-bezier(0.23,1,0.32,1) forwards;
  }
  @media (prefers-reduced-motion: reduce) { .vg-rows .r { animation: none; opacity: 1; } }
  .vg-rows .r b { display: block; font-family: var(--mono); font-size: 0.53rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); font-weight: 500; }
  .vg-rows .r span {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
    font-size: 0.79rem; line-height: 1.6; color: var(--ink); margin-top: 0.32rem; font-weight: 300;
  }
  .vg-hint { font-size: 0.7rem; line-height: 1.65; color: var(--ink-faint); font-weight: 300; }
  .vg-hint b { color: var(--accent-dim); font-weight: 400; }

  /* ---- móvil: la consola ocupa la pantalla ---- */
  @media (max-width: 860px) {
    .vg-panel {
      inset: 0; right: 0; bottom: 0; width: auto; height: auto; max-height: none;
      grid-template-columns: minmax(0, 1fr); border: 0;
    }
    .vg-ficha { display: none; }
    .vg-log { padding-top: 1.1rem; }
    .vg-line.said, .vg-line.mine { max-width: 100%; }
  }
  /* ---- the reticle: the pointer becomes part of the instrument ---- */
  @media (pointer: fine) {
    body.reticle, body.reticle a, body.reticle button { cursor: none; }
  }
  .reticle-el {
    position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none;
    width: 46px; height: 46px; margin: -23px 0 0 -23px; opacity: 0;
    transition: opacity 0.3s ease;
    will-change: transform;
  }
  body.reticle .reticle-el { opacity: 1; }
  .reticle-el .ring {
    position: absolute; inset: 0; border: 1px solid rgba(209,0,94,0.5); border-radius: 50%;
    transform: scale(0.42);
    transition: transform 0.34s cubic-bezier(0.23,1,0.32,1), border-color 0.34s ease, background 0.34s ease;
  }
  .reticle-el .cross::before, .reticle-el .cross::after {
    content: ""; position: absolute; background: rgba(209,0,94,0.85);
  }
  .reticle-el .cross::before { left: 50%; top: 40%; width: 1px; height: 20%; transform: translateX(-50%); }
  .reticle-el .cross::after  { top: 50%; left: 40%; height: 1px; width: 20%; transform: translateY(-50%); }
  .reticle-el .read {
    position: absolute; left: 32px; top: 14px; white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.16em; color: rgba(209,0,94,0.75);
  }
  /* over something you can act on, it opens up and announces itself */
  body.reticle-hot .reticle-el .ring { transform: scale(1); border-color: var(--accent); background: rgba(209,0,94,0.08); }
  .reticle-el .verb {
    position: absolute; left: 50%; top: 52px; transform: translateX(-50%); white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.2em; color: var(--accent);
    opacity: 0; transition: opacity 0.28s ease;
  }
  body.reticle-hot .reticle-el .verb { opacity: 1; }
  @media (prefers-reduced-motion: reduce), (pointer: coarse) { .reticle-el { display: none; } }

  /* ---- the reticle: the pointer becomes part of the instrument ---- */
  @media (pointer: fine) {
    body.reticle, body.reticle a, body.reticle button { cursor: none; }
  }
  .reticle-el {
    position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none;
    width: 46px; height: 46px; margin: -23px 0 0 -23px; opacity: 0;
    transition: opacity 0.3s ease;
    will-change: transform;
  }
  body.reticle .reticle-el { opacity: 1; }
  .reticle-el .ring {
    position: absolute; inset: 0; border: 1px solid rgba(209,0,94,0.5); border-radius: 50%;
    transform: scale(0.42);
    transition: transform 0.34s cubic-bezier(0.23,1,0.32,1), border-color 0.34s ease, background 0.34s ease;
  }
  .reticle-el .cross::before, .reticle-el .cross::after {
    content: ""; position: absolute; background: rgba(209,0,94,0.85);
  }
  .reticle-el .cross::before { left: 50%; top: 40%; width: 1px; height: 20%; transform: translateX(-50%); }
  .reticle-el .cross::after  { top: 50%; left: 40%; height: 1px; width: 20%; transform: translateY(-50%); }
  .reticle-el .read {
    position: absolute; left: 32px; top: 14px; white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.16em; color: rgba(209,0,94,0.75);
  }
  /* over something you can act on, it opens up and announces itself */
  body.reticle-hot .reticle-el .ring { transform: scale(1); border-color: var(--accent); background: rgba(209,0,94,0.08); }
  .reticle-el .verb {
    position: absolute; left: 50%; top: 52px; transform: translateX(-50%); white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.2em; color: var(--accent);
    opacity: 0; transition: opacity 0.28s ease;
  }
  body.reticle-hot .reticle-el .verb { opacity: 1; }
  @media (prefers-reduced-motion: reduce), (pointer: coarse) { .reticle-el { display: none; } }

  /* the real thing, before it becomes a drawing */
  /* ---- the reticle: the pointer becomes part of the instrument ---- */
  @media (pointer: fine) {
    body.reticle, body.reticle a, body.reticle button { cursor: none; }
  }
  .reticle-el {
    position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none;
    width: 46px; height: 46px; margin: -23px 0 0 -23px; opacity: 0;
    transition: opacity 0.3s ease;
    will-change: transform;
  }
  body.reticle .reticle-el { opacity: 1; }
  .reticle-el .ring {
    position: absolute; inset: 0; border: 1px solid rgba(209,0,94,0.5); border-radius: 50%;
    transform: scale(0.42);
    transition: transform 0.34s cubic-bezier(0.23,1,0.32,1), border-color 0.34s ease, background 0.34s ease;
  }
  .reticle-el .cross::before, .reticle-el .cross::after {
    content: ""; position: absolute; background: rgba(209,0,94,0.85);
  }
  .reticle-el .cross::before { left: 50%; top: 40%; width: 1px; height: 20%; transform: translateX(-50%); }
  .reticle-el .cross::after  { top: 50%; left: 40%; height: 1px; width: 20%; transform: translateY(-50%); }
  .reticle-el .read {
    position: absolute; left: 32px; top: 14px; white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.16em; color: rgba(209,0,94,0.75);
  }
  /* over something you can act on, it opens up and announces itself */
  body.reticle-hot .reticle-el .ring { transform: scale(1); border-color: var(--accent); background: rgba(209,0,94,0.08); }
  .reticle-el .verb {
    position: absolute; left: 50%; top: 52px; transform: translateX(-50%); white-space: nowrap;
    font-family: var(--mono); font-size: 0.52rem; letter-spacing: 0.2em; color: var(--accent);
    opacity: 0; transition: opacity 0.28s ease;
  }
  body.reticle-hot .reticle-el .verb { opacity: 1; }
  @media (prefers-reduced-motion: reduce), (pointer: coarse) { .reticle-el { display: none; } }

  /* the real thing, before it becomes a drawing */
  /* Seven photographs, one per leg. The drawing that used to fill this space was
     seven variations on the same lines; a real change of shot does the work now. */
  .stage { position: fixed; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
  /* the copy sits on a legible ground whichever photograph is behind it */
  .stage::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, rgba(247,245,240,0.3) 0%, rgba(247,245,240,0.42) 38%, rgba(247,245,240,0.78) 66%, rgba(247,245,240,0.9) 100%);
  }
  .stage.flip::after {
    background: linear-gradient(270deg, rgba(247,245,240,0.3) 0%, rgba(247,245,240,0.42) 38%, rgba(247,245,240,0.78) 66%, rgba(247,245,240,0.9) 100%);
  }
  @media (max-width: 900px) {
    .stage::after, .stage.flip::after {
      background: linear-gradient(180deg, rgba(247,245,240,0.5) 0%, rgba(247,245,240,0.82) 45%, rgba(247,245,240,0.93) 100%);
    }
  }
  /* ---- the thread: one signal line running the whole page ---- */
  #thread {
    position: absolute; inset: 0; width: 100%; height: 100%;
    pointer-events: none; z-index: 5; overflow: visible;
  }
  #threadPath { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round;
                filter: drop-shadow(0 0 7px rgba(179,34,31,0.5)); }
  #threadGhost { fill: none; stroke: rgba(26,26,26,0.13); stroke-width: 1.2; stroke-dasharray: 3 6; }
  #threadHead { fill: var(--accent); }
  #threadHalo { animation: beat 2s ease-in-out infinite; }
  #threadHalo { fill: var(--accent); opacity: 0.18; }

  /* ---- scroll: cada sección lleva su propio progreso ----
     --p va de -1 (aún por debajo) a 1 (ya arriba); --e es la entrada, 0 a 1.
     Se anima con `translate`/`scale`, nunca con `transform`, porque varios
     grupos del dibujo ya llevan su propio transform como atributo. */
  .beat { --p: 0; --e: 1; }

  /* en pantalla estrecha el plano necesita su propio ancho: encogido a 390px
     las cotas caen a 4px y no se leen. Rueda dentro de su caja, nunca la página. */
  @media (max-width: 760px) {
    .beat:not(#s1) .plate {
      overflow-x: auto; overflow-y: hidden;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
    }
    .beat:not(#s1) .plate::-webkit-scrollbar { display: none; }
    .beat:not(#s1) .plate-svg { width: 680px; max-width: none; min-height: 0; }
  }

  @media (prefers-reduced-motion: no-preference) {
    /* el texto y la lámina viajan a distinta velocidad: eso es la profundidad */
    .say   { translate: 0 calc(var(--p) * -30px); }
    .plate { translate: 0 calc(var(--p) * 54px); }

    /* la torre se posa sobre el agua al entrar la sección */
    .tower { translate: 0 calc((1 - var(--e)) * 36px); }
    /* el mar corre, y las marcas lejanas al revés: parallax de horizonte */
    .water     { translate: calc(var(--p) * 30px) 0; }
    .mark-icon { translate: calc(var(--p) * -44px) 0; }

    /* las anotaciones se escriben en orden conforme avanzas */
    .beat .plate-svg text.lb, .beat .plate-svg .leader, .beat .plate-svg .dim,
    .beat .plate-svg .fix, .beat .plate-svg .compass, .beat .plate-svg .mark-icon,
    .beat .plate-svg .node {
      opacity: calc((var(--e) - var(--k, 0)) * 5);
      transition: none;
    }
    /* el filete del epígrafe se dibuja solo */
    .say .eyebrow i { width: calc(26px * var(--e)); }

    /* la sección se apaga al quedar atrás: el recorrido se lee como uno solo */
    .beat { opacity: calc(1 - max(0, var(--p)) * 0.45); }

    /* la foto de apertura respira al alejarte de ella */
    #s1 .plate { translate: none; overflow: hidden; }
    #s1 .plate-svg { scale: calc(1.04 + var(--p) * 0.035); }
  }
  main { position: relative; }
