/* renfy_pool -- estilo propio, inspirado en la administración de conjuntos
   residenciales, no calcado de ninguna pantalla existente. */

:root {
  --ink: #1b2320;
  --ink-soft: #4a5650;
  --line: #dde3de;
  --paper: #f6f5f0;
  --card: #ffffff;
  --brand: #1f5e4d;
  --brand-dark: #163f34;
  --brand-soft: #e4efe9;
  --accent: #c4692f;
  --accent-soft: #fbeada;
  --ok: #1f7a4d;
  --ok-soft: #e3f3ea;
  --warn: #b5790a;
  --warn-soft: #fbf0da;
  --bad: #b23b2f;
  --bad-soft: #fbe6e2;
  --mut: #7c887f;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(20, 30, 25, 0.06), 0 6px 20px -8px rgba(20, 30, 25, 0.12);
  font-variant-numeric: tabular-nums;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 14px/1.5 -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

h1, h2, h3 { font-weight: 650; letter-spacing: -0.01em; text-wrap: balance; }
h1 { font-size: 1.5rem; margin: 0; }
h2 { font-size: 1.15rem; margin: 0 0 4px; }
h3 { font-size: 0.95rem; margin: 0; }
a { color: var(--brand); }
code { background: var(--brand-soft); padding: 1px 5px; border-radius: 5px; font-size: 0.9em; }

button {
  font: inherit;
  cursor: pointer;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  padding: 7px 13px;
}
button:hover { border-color: var(--brand); }
button.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
button.primary:hover { background: var(--brand-dark); }
button.danger { color: var(--bad); }
button.danger:hover { border-color: var(--bad); }
button.mini { padding: 4px 10px; font-size: 0.85em; }
button:disabled { opacity: 0.5; cursor: not-allowed; }

input, select, textarea {
  font: inherit;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand); outline-offset: -1px; }
label { display: flex; flex-direction: column; gap: 4px; font-size: 0.85em; color: var(--ink-soft); }

/* ── Login ─────────────────────────────────────────────────────────── */

.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 32px;
}
.login-card .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
}
.login-card .brand .mark {
  width: 34px; height: 34px; border-radius: 9px;
  background: var(--brand); color: #fff;
  display: grid; place-items: center; font-weight: 700;
}
.login-card form { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.login-card .hint { color: var(--mut); font-size: 0.85em; margin-top: 4px; }

/* ── App shell ─────────────────────────────────────────────────────── */

/* 14-sep-2026: grid -> flex row (.side/.main/.rf-dock) -- el riel de
   accesos rápidos necesita ser una TERCERA columna con su propio
   espacio (mismo `.layout{display:flex}` del legado: ".dock hermana de
   .cont en el mismo flex, ensancharla estrecha el contenido en vez de
   taparlo"), imposible con un grid de 2 columnas fijas. */
/* Sin align-items en .shell (stretch por defecto): .side/.main deben
   ocupar el alto completo igual que con el grid anterior (fondo oscuro
   del menú hasta abajo en páginas largas). .rf-dock opta por su propio
   align-self:flex-start -- necesita quedar del alto de SU contenido y
   sticky, no estirarse como sus hermanos. */
.shell { display: flex; min-height: 100vh; }
/* 28-sep-2026, pedido del usuario: el scroll del menú no debe mover el
   panel central. .side queda fija al alto de la ventana (sticky) y solo
   su <nav> desplaza; overscroll-behavior evita que, al llegar al final
   del menú, la rueda siga empujando la página. Reemplaza el "stretch
   hasta abajo" anterior -- con sticky el fondo oscuro siempre llena la
   ventana visible. */
.side {
  width: 220px; flex-shrink: 0;
  background: var(--brand-dark);
  color: #eef4f1;
  padding: 20px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky; top: 0; height: 100vh; align-self: flex-start;
}
.main:focus { outline: none; }
.side .brand { display: flex; align-items: center; gap: 10px; padding: 4px 8px 18px; }
.side .brand .mark {
  width: 30px; height: 30px; border-radius: 8px;
  background: #eef4f1; color: var(--brand-dark);
  display: grid; place-items: center; font-weight: 700;
}
.side .brand b { font-size: 1.02rem; }
/* Árbol de 3 niveles (Grupo → Área → Sub-grupo), mismo patrón que un
   explorador de archivos (VS Code/GitHub/Linear): cada nivel más
   adentro suma indentación PROPIA sobre la de su padre -- nunca una
   cifra fija repetida -- y una línea guía vertical conecta un
   encabezado con sus hijos, que es lo que hace leíble "esto cuelga de
   aquello" sin tener que comparar tamaños de letra. 12-sep-2026,
   segunda vuelta: la primera pasada solo cambiaba el padding y el
   usuario la devolvió ("no se diferencia el nivel superior del
   siguiente") -- la línea guía es la pieza que faltaba. */
.side nav { display: flex; flex-direction: column; gap: 1px; flex: 1; overflow-y: auto; min-height: 0; overscroll-behavior: contain; }
/* 29-sep-2026, usuario: la barra de scroll del menú "se ve muy fea".
   Sin barra; el borde por donde hay más menú se desvanece (máscara) y
   una flecha discreta abajo lo avanza. app.js::updateNavScrollHint()
   pone .more-up/.more-down según la posición. */
.side nav { scrollbar-width: none; -ms-overflow-style: none; }
.side nav::-webkit-scrollbar { display: none; }
.side nav.more-down { -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 40px), transparent); }
.side nav.more-up { -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px); mask-image: linear-gradient(to bottom, transparent, #000 28px); }
.side nav.more-up.more-down { -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 40px), transparent); }
.side .nav-more {
  align-self: center; margin: -6px 0 0; padding: 0 14px; line-height: 1;
  background: transparent; border: 0; color: #c6d8cf; font-size: 1.15rem; cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
.side.more-down .nav-more { opacity: .75; pointer-events: auto; animation: nav-more-nudge 2.4s ease-in-out infinite; }
.side .nav-more:hover { opacity: 1; color: #fff; animation: none; }
@keyframes nav-more-nudge { 0%, 70%, 100% { transform: translateY(0); } 85% { transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .side.more-down .nav-more { animation: none; } }
/* Panel plegable (<details class="panel collapsible">): el resumen es la
   cabecera clicable, con un caret que gira al abrir. */
details.collapsible > summary { cursor: pointer; list-style: none; user-select: none; }
details.collapsible > summary::-webkit-details-marker { display: none; }
details.collapsible > summary::before { content: "▸"; display: inline-block; width: 1.1em; color: var(--brand-dark); transition: transform .15s; }
details.collapsible[open] > summary::before { transform: rotate(90deg); }
.side nav a {
  display: block; color: #d7e6de; text-decoration: none;
  padding: 7px 10px; border-radius: 6px; font-size: 0.87em; line-height: 1.3;
}
/* Nivel superior (Inicio, Mi apartamento -- sin grupo) al mismo peso
   visual que un encabezado de grupo: negrita, sin indentar, sin caret
   porque no despliega nada. */
.side nav a.nav-top { font-weight: 650; font-size: 0.92em; padding-left: 10px; }
.side nav a:hover { background: rgba(255,255,255,0.08); color: #fff; }
.side nav a.on { background: #fff; color: var(--brand-dark); font-weight: 650; }

.side nav .nav-group {
  display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
  color: #cfe3d8; text-transform: uppercase; letter-spacing: .05em;
  font-size: .74em; font-weight: 800; padding: 10px 10px 10px 6px; margin-top: 6px;
  border-top: 1px solid rgba(255,255,255,0.12);
}
.side nav .nav-group:first-child { margin-top: 0; border-top: 0; }
.side nav .nav-group:hover { color: #fff; background: rgba(255,255,255,0.05); border-radius: 6px; }

/* Nivel 2: los ítems de un grupo, en su propio riel indentado con una
   línea guía a la izquierda -- se ve de un vistazo que cuelgan del
   encabezado de arriba, sin tener que leer el texto. */
.side nav .nav-items {
  display: flex; flex-direction: column; gap: 1px;
  margin-left: 14px; padding-left: 10px; border-left: 1px solid rgba(255,255,255,0.14);
}
.side nav .nav-items > a { font-size: 0.87em; font-weight: 450; }

/* Un ítem de nivel 2 que es TAMBIÉN un encabezado desplegable (ej.
   "Contratos" dentro de Operación) -- mismo tamaño que sus hermanos
   hoja, pero semi-negrita y con su propio caret, para que se note que
   esconde algo antes de tocarlo. */
.side nav .nav-sub {
  display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
  color: #c6dcd0; font-size: 0.87em; font-weight: 650; padding: 7px 10px 7px 0;
}
.side nav .nav-sub:hover { color: #fff; }

/* Nivel 3: un riel más adentro, letra un punto más chica y más clara
   -- la diferencia de tamaño ES la señal de profundidad, no un adorno. */
.side nav .nav-subitems {
  display: flex; flex-direction: column; gap: 1px;
  margin-left: 10px; padding-left: 10px; border-left: 1px solid rgba(255,255,255,0.1);
}
.side nav .nav-subitems > a { font-size: 0.82em; color: #c2d6cb; }

/* Insignia MAX/ENTERPRISE sobre un ítem de menú -- solo visible durante
   una prueba activa (ver tierBadgeHtml() en app.js), avisa qué se vuelve
   de pago cuando el trial termine y el plan vuelva a Pro. */
.nav-badge {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: 0.68em; font-weight: 800; letter-spacing: .03em; vertical-align: 1px;
}
.nav-badge-max { background: #ffe6b0; color: #7a5200; }
.nav-badge-enterprise { background: #e3d3ff; color: #4a2589; }
.side nav a.on .nav-badge-max { background: #7a5200; color: #ffe6b0; }
.side nav a.on .nav-badge-enterprise { background: #4a2589; color: #e3d3ff; }

.side nav .nav-caret {
  font-size: 0.65em; width: 0.9em; flex-shrink: 0; color: #7fa393;
  transition: color .12s;
}
.side nav .nav-group:hover .nav-caret, .side nav .nav-sub:hover .nav-caret { color: #e3f1ea; }
.side .who { padding: 10px 8px; border-top: 1px solid rgba(255,255,255,0.15); font-size: 0.82em; color: #c6d8cf; }
.side .who b { color: #fff; display: block; }
.side .who button { width: 100%; margin-top: 8px; }

.main { flex: 1; min-width: 0; padding: 26px 32px 60px; max-width: 1100px; }
.main .lead { color: var(--ink-soft); max-width: 68ch; margin: 4px 0 20px; }

/* ── Barra superior (banner) -- FIN-02, 14-sep-2026, faltante señalado por
   el usuario. Mismo `.banner`/`bn-*` del legado: sticky, se oculta al
   bajar y reaparece al subir (ver _bindBannerScroll() en app.js). */
.banner {
  display: flex; align-items: center; gap: 14px; padding: 8px 14px; margin: 0 0 18px;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  font-size: 12px; position: sticky; top: 0; z-index: 20; transition: transform .25s;
}
.banner.oculto { transform: translateY(-120%); }
.bn-i b { font-size: 14px; color: var(--ink); display: block; line-height: 1.15; }
.bn-i span { color: var(--mut); font-size: 11px; }
.bn-a { margin-left: auto; font-weight: 700; color: var(--ink-soft); }

/* Contador de días de prueba -- pedido del usuario 16-sep-2026, tras la
   prueba real del wizard ("poner en el baner... el timer con los días
   que quedan"). Verde con holgura, ámbar en la última semana, rojo los
   últimos 3 días -- mismo criterio de "escalar por urgencia" que ya usa
   el resto del sistema (ver DUNNING_SUSPEND_AFTER_DAYS/warnings). */
.bn-trial {
  display: flex; align-items: center; gap: 6px; padding: 4px 12px;
  border-radius: 999px; font-weight: 700; font-size: 11.5px; white-space: nowrap;
  background: var(--brand-soft); color: var(--brand-dark);
}
.bn-trial.bn-trial-warn { background: #ffe6b0; color: #7a5200; }
.bn-trial.bn-trial-urgent { background: #ffd4d4; color: #8a1f1f; }
.bn-u {
  display: flex; align-items: center; gap: 9px; padding: 4px 5px 4px 12px;
  border-radius: 999px; background: var(--brand-soft); color: var(--brand-dark);
  font-weight: 600; white-space: nowrap;
}
.bn-salir {
  border: 0; background: var(--brand-dark); color: #fff; border-radius: 999px;
  padding: 5px 12px; font-size: 0.85em; cursor: pointer;
}
@media (max-width: 640px) {
  .banner { flex-wrap: wrap; gap: 8px 12px; }
  .bn-a { margin-left: 0; width: 100%; order: 3; font-size: 13px; }
}

/* ── Riel de accesos rápidos (dock) -- TERCERA COLUMNA del layout, no un
   panel flotante (corregido 14-sep-2026 -- primera versión usaba
   position:fixed, el usuario la comparó contra capturas reales del
   legado: "el panel lateral derecho no flota... tiene su espacio
   propio"). Mismo `.dock`/`.dk`/`.dk-t` de rcpsecure_page.py: hermana de
   `.main` en el mismo flex, así que ensancharla estrecha el contenido
   en vez de taparlo -- con position:fixed eso es imposible, un elemento
   fuera del flujo no empuja a nadie. Solo admin/plataforma/porteria,
   mismo criterio que rcpsecure_page.py::_dock()/_tarjeta_*. */
.rf-dock {
  width: 38px; flex-shrink: 0; position: sticky; top: 14px; align-self: flex-start;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  transition: width .18s; max-height: calc(100vh - 28px); margin: 26px 20px 0 0;
}
.rf-dock.abierta { width: 240px; }
.rf-dk {
  width: 240px; background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  transition: width .18s; flex-shrink: 0;
}
.rf-dk.plegado { width: 38px; }
.rf-dk-t {
  display: flex; align-items: center; gap: 7px; width: 100%; background: none; border: 0;
  padding: 9px 12px; cursor: pointer; font: 700 10px system-ui; text-transform: uppercase;
  letter-spacing: .06em; color: var(--mut); text-align: left;
}
.rf-dk-t:hover { color: var(--ink); background: var(--paper); }
.rf-dk.plegado .rf-dk-t { writing-mode: vertical-rl; padding: 11px 10px; white-space: nowrap; justify-content: flex-start; }
.rf-dk-c { transition: transform .2s; display: inline-block; font-size: 11px; color: var(--line); }
.rf-dk.plegado .rf-dk-c { transform: rotate(90deg); }
.rf-dk.plegado .rf-dk-b { display: none; }
.rf-dk-b { overflow-y: auto; min-height: 0; max-height: 46vh; }
.rf-dk-n { margin-left: auto; background: var(--bad); color: #fff; border-radius: 999px; font-size: 10px; padding: 1px 6px; font-weight: 700; }
.dk-card { padding: 9px 12px; border-top: 1px solid var(--paper); }
.dk-card:first-child { border-top: 0; }
.dk-card b { display: block; font: 600 12px/1.3 system-ui; color: var(--ink); }
.dk-card .dk-n2 { font-size: 10px; color: var(--mut); }
.dk-card a { display: block; margin-top: 4px; font-size: 11px; font-weight: 600; color: var(--brand-dark); text-decoration: none; }
.dk-card a:hover { text-decoration: underline; }
.rf-dk-empty { padding: 12px; font-size: 12px; color: var(--mut); margin: 0; }
.rf-dk-link { display: block; padding: 8px 12px; border-top: 1px solid var(--paper); font-size: 11px; font-weight: 600; color: var(--brand-dark); text-decoration: none; text-align: right; }
.rf-dk-link:hover { background: var(--paper); }
@media (max-width: 900px) {
  /* El legado convierte el riel en un cajón deslizante en móvil (con
     overlay propio); aquí, más simple, se oculta -- el guarda de reja
     en un teléfono usa las pantallas completas (#/mail, #/visitors,
     #/contractor-gate) directamente, no está bloqueado por esto. */
  .rf-dock { display: none; }
}

/* ── Resumen de grupo (FIN-06) -- mismo `.rs`/`.rs-c` del legado
   (rcpsecure_resumen.py::render()), grilla de tarjetas con alerta. */
.rs { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; margin-bottom: 20px; }
.rs-c { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
.rs-c span { font-size: 0.8em; color: var(--mut); text-transform: uppercase; letter-spacing: 0.03em; }
.rs-c b { font-size: 1.25rem; }
.rs-c em { font-style: normal; font-size: 0.82em; color: var(--ink-soft); }
.rs-c.al { border-color: var(--bad); background: var(--bad-soft); }
.rs-c.al b { color: var(--bad); }

/* ── Building blocks ───────────────────────────────────────────────── */

.stats { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 16px; min-width: 150px;
}
.stat b { display: block; font-size: 1.3rem; }
.stat span { color: var(--mut); font-size: 0.82em; }
.stat.ok { border-color: var(--ok); background: var(--ok-soft); }
.stat.warn { border-color: var(--warn); background: var(--warn-soft); }
.stat.bad { border-color: var(--bad); background: var(--bad-soft); }

/* ── Cartelera de Inicio (COP-11) -- reel en Inicio + su administración.
   21-sep-2026, reconstruido: esto es el _CSS_REEL real del legado
   (rcpsecure_page.py::render_reel()), con las clases `crt-*` originales
   -- no la tira de tarjetas en scroll que había antes. Un carrusel de
   UNA lámina activa, ancho completo, con puntos+flechas y autoavance
   (ver arrancarReel()/startReel() en app.js). Sin foto propia se pinta
   el degradado de color del ícono -- nunca una foto de otro conjunto
   rellenando el hueco, mismo criterio del legado. */
.crt {
  position: relative; margin: 0 0 20px; border-radius: var(--radius); overflow: hidden;
  background: #0f172a; box-shadow: 0 1px 3px rgba(15,23,42,.18);
}
.crt-v { position: relative; height: 280px; }
.crt-s {
  position: absolute; inset: 0; opacity: 0; transition: opacity .5s ease;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 1.4rem 1.5rem;
}
.crt-s.on { opacity: 1; }
.crt-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.crt-s::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(2,6,23,.88) 8%, rgba(2,6,23,.15) 62%);
}
.crt-b { position: absolute; inset: 0; }
.crt-c { position: relative; z-index: 2; color: #fff; max-width: 44rem; }
.crt-c h3 {
  margin: 0 0 .35rem; font-size: 1.55rem; line-height: 1.15; font-weight: 700;
  text-shadow: 0 1px 12px rgba(2,6,23,.6);
}
.crt-c p { margin: 0 0 .6rem; font-size: 1rem; color: #e2e8f0; text-shadow: 0 1px 10px rgba(2,6,23,.6); }
.crt-d { display: inline-flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.crt-d span {
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.22);
  padding: .2rem .6rem; border-radius: 999px; font-size: .8rem; font-weight: 600;
  backdrop-filter: blur(4px);
}
.crt-d span.crt-w { background: rgba(220,38,38,.85); border-color: rgba(254,202,202,.5); }
.crt-n {
  position: absolute; bottom: .9rem; right: 1.1rem; z-index: 3; display: flex;
  align-items: center; gap: .5rem;
}
.crt-p { display: flex; gap: .4rem; }
.crt-p button {
  width: 9px; height: 9px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255,255,255,.55); background: transparent; transition: .2s;
}
.crt-p button.on { background: #fff; transform: scale(1.25); }
.crt-a {
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer; color: #fff;
  border: 1px solid rgba(255,255,255,.3); background: rgba(2,6,23,.42);
  font-size: .95rem; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.crt-a:hover, .crt-p button:hover { border-color: #fff; }
.crt-a:focus-visible, .crt-p button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (max-width: 640px) {
  .crt-v { height: 230px; }
  .crt-c h3 { font-size: 1.25rem; }
  .crt-c p { font-size: .92rem; }
}
/* Quien pidió menos movimiento no ve un carrusel que se mueve solo -- el
   JS tampoco arranca el temporizador (startReel()); esto solo quita la
   transición visual. */
@media (prefers-reduced-motion: reduce) { .crt-s { transition: none; } }

.bltn-photo-list { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.bltn-photo-thumb {
  width: 110px; text-align: center; background: var(--paper); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px; display: flex; flex-direction: column; gap: 6px;
}
.bltn-photo-thumb img { width: 100%; height: 70px; object-fit: cover; border-radius: 4px; background: var(--line); }

.posters-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.poster-card { text-align: center; margin-bottom: 0; }
.poster-qr { margin: 10px 0; }
.poster-qr svg { max-width: 180px; height: auto; }
@media print {
  .side, .stats, #posters-body > p:first-child { display: none; }
  .posters-grid { grid-template-columns: 1fr; }
  .poster-card { page-break-after: always; border: none; }
  /* 21-sep-2026: el legado AGRANDA el QR al imprimir (190px en pantalla
     -> 320px impreso, ver .cartel svg dentro de @media print en
     rcpsecure_page.py) -- un QR que se queda chico al imprimirse
     escanea peor a la distancia real desde la que alguien lo lee
     pegado en un equipo. Faltaba esta regla, se imprimía al mismo
     tamaño que en pantalla. */
  .poster-qr svg { max-width: 320px; }
}

/* ── Gantt de Proyectos/Ejecución (PRY-01), 21-sep-2026 -- matches
   _gantt() del legado: barras posicionadas por fecha (% del span
   total del proyecto), línea base en gris DEBAJO, plan vigente
   ENCIMA. Colores tomados de los tokens semánticos del tema (no
   hex fijos del legado) para que funcione igual en oscuro. */
.pry-gt { width: 100%; font-size: 0.85em; border-collapse: collapse; }
.pry-gt th, .pry-gt td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.pry-gc { position: relative; height: 1.6rem; min-width: 12rem; background: var(--paper); border-radius: 4px; }
.pry-gb { position: absolute; top: 0.3rem; height: 0.7rem; border-radius: 3px; background: var(--brand); }
.pry-gb.pry-gr { background: var(--bad); }
.pry-gp { position: absolute; top: 0.3rem; height: 0.7rem; border-radius: 3px; background: var(--ok); }
.pry-gz { position: absolute; bottom: 0.25rem; height: 0.22rem; border-radius: 3px; background: var(--mut); opacity: 0.6; }

.panel {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px; margin-bottom: 20px;
}
.panel > h3 { margin-bottom: 12px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.panel-head h3 { margin: 0; }

.sub-panel { background: var(--paper); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; margin-top: 8px; }
.pl-check { display: inline-flex; align-items: center; gap: 4px; font-size: 0.85em; margin: 0 10px 6px 0; }
.sub-panel h4 { margin: 14px 0 8px; font-size: 0.88em; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; }
.sub-panel h4:first-child { margin-top: 0; }
.sub-panel .form-row { margin-top: 8px; }
.sub-panel .form-row input, .sub-panel .form-row select { min-width: 8rem; }

.form-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: end; }
.form-row label { min-width: 140px; flex: 1; }
.form-row label.grow { flex: 2; }

table { width: 100%; border-collapse: collapse; font-size: 0.92em; }
th { text-align: left; color: var(--mut); font-weight: 600; font-size: 0.82em; text-transform: uppercase; letter-spacing: 0.03em; padding: 8px 10px; border-bottom: 1px solid var(--line); }
td { padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
tr:last-child td { border-bottom: none; }
.table-wrap { overflow-x: auto; }

.pill { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 0.8em; font-weight: 600; }
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad { background: var(--bad-soft); color: var(--bad); }
.pill.mut { background: var(--brand-soft); color: var(--brand-dark); }

.tabs { display: flex; gap: 4px; margin-bottom: 14px; flex-wrap: wrap; }
.tabs a {
  text-decoration: none; color: var(--ink-soft); padding: 6px 12px;
  border-radius: 999px; font-size: 0.88em; border: 1px solid transparent;
}
.tabs a.on { background: var(--brand-soft); color: var(--brand-dark); font-weight: 650; }
.tabs a:hover:not(.on) { border-color: var(--line); }

.actions { display: flex; gap: 6px; flex-wrap: wrap; }
.empty { color: var(--mut); font-style: italic; padding: 18px 0; }
/* 🔴 hand-added 14-sep-2026 (FIN-02) -- class="mut" era usado en toda la
   app (billing/budget incl.) pero nunca se definió: quedaba sin estilo,
   en el color de texto por defecto. Un solo lugar para arreglarlo. */
.mut { color: var(--mut); }
.msg { padding: 9px 12px; border-radius: 8px; margin: 10px 0; font-size: 0.9em; }
.msg.ok { background: var(--ok-soft); color: var(--ok); }
.msg.bad { background: var(--bad-soft); color: var(--bad); }
.msg.warn { background: var(--warn-soft); color: var(--warn); }
/* Roadmap > Prototipos (rm_proto) -- las maquetas ASCII del legado, caja
   monoespaciada oscura, mismo criterio visual que el legado (.mq-p). */
.proto-ascii { background: #0f172a; color: #e2e8f0; border-radius: 8px; padding: 12px 14px;
  overflow-x: auto; font: 12px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; margin: 8px 0; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* 15-oct-2026, celular: el menú no se veía. La regla anterior era del
   layout en grid (.shell grid-template-columns) y dejó de aplicar al pasar
   a flex + .side sticky de 220px: en el teléfono el menú quedaba como
   columna aplastando el panel o fuera de vista. Ahora, en pantallas
   angostas, .side es un cajón que entra desde la izquierda con el botón
   de menú del banner (.bn-menu) y se cierra con el velo, Escape o al
   elegir una opción (ver shell()/bindNav() en app.js). */
.bn-menu { display: none; }
.nav-velo { display: none; }
@media (max-width: 760px) {
  .side {
    position: fixed; top: 0; left: 0; bottom: 0; height: 100%; z-index: 200;
    width: min(84vw, 300px); transform: translateX(-105%); transition: transform .22s ease;
    box-shadow: 4px 0 24px rgba(0,0,0,.25);
  }
  .shell.nav-abierto .side { transform: none; }
  .shell.nav-abierto .nav-velo { display: block; position: fixed; inset: 0; z-index: 199; background: rgba(15,23,42,.45); }
  .bn-menu {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 40px; height: 40px; padding: 0; margin: -6px 0 -6px -8px; border: 0; border-radius: 8px;
    background: none; color: var(--brand-dark); cursor: pointer;
  }
  .bn-menu:hover { background: var(--brand-soft); }
  .main { padding: 12px 14px 48px; }
  .banner .bn-u { display: none; } /* usuario y Cerrar sesión ya están al pie del cajón */
  .grid-2 { grid-template-columns: 1fr; }
}
@media (max-width: 760px) and (prefers-reduced-motion: reduce) { .side { transition: none; } }

/* Gasto corriente (FIN-03, rcpsecure_presupuesto.py::_gasto_corriente()) --
   ritmo de ejecucion vs. lo esperado a la fecha, no vs. el anual. */
.gc-row { display: grid; grid-template-columns: 1fr 2fr 52px; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line); }
.gc-row:last-child { border-bottom: none; }
.gc-name span { display: block; font-size: 0.82em; color: var(--mut); }
.gc-bar { position: relative; height: 10px; background: #eee; border-radius: 5px; overflow: visible; }
.gc-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 5px; background: var(--mut); }
.gc-fill.ok { background: var(--ok); }
.gc-fill.warn { background: var(--warn); }
.gc-fill.bad { background: var(--bad); }
.gc-mark { position: absolute; top: -3px; width: 2px; height: 16px; background: var(--ink); opacity: 0.4; }
.gc-pct { text-align: right; font-weight: 650; font-size: 0.9em; }
.gc-pct.ok { color: var(--ok); }
.gc-pct.warn { color: var(--warn); }
.gc-pct.bad { color: var(--bad); }
@media (max-width: 760px) {
  .gc-row { grid-template-columns: 1fr; gap: 4px; }
}

/* Graficas sin libreria (FIN-01, rcpsecure_graficas.py) -- barras, dona,
   linea. SVG/CSS puro, mismo criterio que el legado (documento autonomo). */
.chart { margin: 4px 0; }
.chart-t { font-weight: 650; margin-bottom: 10px; }
.ch-brow { display: grid; grid-template-columns: 1fr 2fr auto 42px; gap: 10px; align-items: center; padding: 5px 0; }
.ch-be { font-size: 0.88em; }
.ch-bb { height: 10px; background: #eee; border-radius: 5px; overflow: hidden; }
.ch-bb i { display: block; height: 100%; border-radius: 5px; }
.ch-bv { font-weight: 650; font-size: 0.85em; white-space: nowrap; }
.ch-bp { color: var(--mut); font-size: 0.8em; text-align: right; }
.ch-d { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.ch-ds { width: 140px; height: 140px; flex-shrink: 0; }
.ch-dv { text-anchor: middle; font-size: 22px; font-weight: 700; fill: var(--ink); }
.ch-de { text-anchor: middle; font-size: 11px; fill: var(--mut); }
.ch-dls { display: flex; flex-direction: column; gap: 6px; }
.ch-dl { display: flex; align-items: center; gap: 6px; font-size: 0.85em; }
.ch-dl i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.ch-dl b { margin-left: 2px; }
.ch-dl span { color: var(--mut); }
/* 21-sep-2026: matches cobertura() del legado -- barra de color por
   umbral (roja <100%, naranja 100-110%, verde >=110%). */
.ch-grow { display: flex; align-items: center; gap: 10px; }
.ch-gb { flex: 1; height: 14px; background: #eee; border-radius: 7px; overflow: hidden; }
.ch-gb i { display: block; height: 100%; border-radius: 7px; }
.ch-gb i.ok { background: var(--ok); }
.ch-gb i.warn { background: var(--warn); }
.ch-gb i.bad { background: var(--bad); }
.ch-gv { font-weight: 700; white-space: nowrap; }
.ch-gn { color: var(--mut); font-size: 0.85em; margin-top: 6px; }
.ch-l { width: 100%; height: auto; }
.ch-lx { font-size: 9px; fill: var(--mut); text-anchor: middle; }
.ch-lv { font-size: 11px; fill: var(--brand-dark); font-weight: 650; }
.ch-n { color: var(--mut); font-size: 0.82em; margin-top: 4px; }
@media (max-width: 760px) {
  .ch-brow { grid-template-columns: 1fr; gap: 2px; }
  .ch-d { flex-direction: column; }
}

/* Calendario de ejecucion (FIN-03, rcpsecure_presupuesto.py::_linea_tiempo()) --
   rubros puntuales por mes, clic en un mes para reprogramar. */
.msg ul { margin: 6px 0 0; padding-left: 20px; }
.msg li { margin: 2px 0; }
.tl-wrap { overflow-x: auto; }
.tl-row { display: grid; grid-template-columns: 180px 1fr; gap: 8px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--line); min-width: 520px; }
.tl-row:last-child { border-bottom: none; }
.tl-row.late .tl-label b { color: var(--bad); }
.tl-label span { display: block; font-size: 0.8em; color: var(--mut); }
.tl-track { display: grid; grid-template-columns: repeat(12, 1fr); gap: 2px; align-items: center; }
.tl-m { text-align: center; font-size: 0.78em; color: var(--mut); }
.tl-m.past { color: var(--ink); font-weight: 650; }
.tl-c { height: 22px; display: flex; align-items: center; justify-content: center; cursor: pointer; border-radius: 4px; }
.tl-c:hover { background: var(--brand-soft); }
.tl-c::after { content: ""; display: block; border-radius: 50%; background: var(--line); width: 6px; height: 6px; }
.tl-c.on::after { background: var(--brand); }
.tl-c.on.md::after { width: 10px; height: 10px; }
.tl-c.on.lg::after { width: 14px; height: 14px; }
.tl-c.on.late::after { background: var(--bad); }
.tl-flow { border-top: 2px solid var(--line); margin-top: 4px; padding-top: 8px; }
.tl-flowtrack { align-items: flex-end; height: 40px; }
.tl-fbar { background: var(--brand-soft); border-radius: 2px 2px 0 0; min-height: 2px; }
.tl-fbar.past { background: #eee; }
@media (max-width: 760px) {
  .tl-row { grid-template-columns: 130px 1fr; min-width: 420px; }
}

.slotgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.slot { border: 1px solid var(--line); border-radius: 8px; padding: 10px; font-size: 0.88em; }
.slot.free { border-color: var(--ok); background: var(--ok-soft); }
.slot.full { background: #f1f1ee; color: var(--mut); }
.slot.past { background: #f1f1ee; color: var(--mut); text-decoration: line-through; }
.slot b { display: block; }
.slot button { margin-top: 6px; width: 100%; }

/* ── Cuenta de cobro, vista imprimible (FIN-08) -- carteles.py's own
   pattern: el navegador imprime, sin librería de PDF ni servidor. */
.cc-print { max-width: 640px; margin: 0 auto; padding: 32px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); }
.cc-head { display: flex; justify-content: space-between; align-items: start; border-bottom: 2px solid var(--ink); padding-bottom: 14px; margin-bottom: 18px; }
.cc-head h2 { margin: 0 0 4px; }
.cc-head .cc-doc { text-align: right; font-size: 0.9em; color: var(--mut); }
.cc-head .cc-doc b { display: block; font-size: 1.1em; color: var(--ink); }
.cc-rows { width: 100%; border-collapse: collapse; margin: 16px 0; }
.cc-rows td { padding: 8px 4px; border-bottom: 1px solid var(--line); }
.cc-rows td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.cc-total td { font-weight: 700; font-size: 1.15em; border-top: 2px solid var(--ink); border-bottom: none; }
.cc-actions { display: flex; gap: 10px; justify-content: center; margin-top: 20px; }
@media print {
  .side, .banner, .rf-dock, .cc-actions, .acct-actions { display: none !important; }
  .main { padding: 0; }
  .cc-print { border: 0; box-shadow: none; max-width: 100%; }
}

/* ── Nivelación de ofertas (11-oct-2026, routers/bid_leveling.py) ── */
.lev .lev-h { margin: 16px 0 6px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lev-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.lev-card { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--card); min-width: 0; }
.lev-card p { margin: 4px 0; font-size: 0.88em; color: var(--ink-soft); }
.lev-kind { font-size: 0.72em; letter-spacing: .05em; text-transform: uppercase; color: var(--warn); font-weight: 600; }
.lev-who { font-weight: 700; font-size: 1.02em; margin: 2px 0; }
.lev-card-foot { font-size: 0.82em; margin-top: 6px; word-break: break-word; }
.lev-findings { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; }
.lev-finding { border-top: 3px solid var(--bad); background: var(--card); border-radius: 0 0 8px 8px; padding: 8px 12px; box-shadow: var(--shadow); min-width: 0; }
.lev-finding h4 { margin: 0 0 4px; font-size: 0.95em; }
.lev-finding p { margin: 0 0 6px; font-size: 0.88em; }
.lev-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; font-size: 0.84em; margin: 6px 0; }
.lev-wrap { border: 1px solid var(--line); border-radius: 8px; }
.lev-matrix { min-width: 980px; border-collapse: separate; border-spacing: 0; font-size: 0.86em; }
.lev-matrix th, .lev-matrix td { vertical-align: top; text-align: left; padding: 7px 9px; border-bottom: 1px solid var(--line); }
.lev-matrix thead th { background: var(--brand-soft); border-bottom: 2px solid var(--ink); }
.lev-matrix thead th small { display: block; font-weight: normal; color: var(--mut); font-size: 0.8em; }
.lev-matrix th:first-child, .lev-matrix td.lev-act { position: sticky; left: 0; background: var(--card); z-index: 1; width: 190px; border-right: 1px solid var(--line); font-weight: 600; }
.lev-matrix thead th:first-child { background: var(--brand-soft); z-index: 2; }
.lev-matrix .lev-pert { background: #f1f5f8; width: 280px; font-size: 0.95em; }
.lev-matrix tr.lev-grp td { background: var(--paper); font-size: 0.78em; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-soft); font-weight: 600; }
.lev-matrix tr.lev-grp td:first-child { background: var(--paper); }
.lev-matrix tr.lev-editor td { background: var(--accent-soft); }
.lev-matrix td.lev-open { outline: 2px solid var(--accent); outline-offset: -2px; }
button.lev-cell { all: unset; cursor: pointer; display: block; width: 100%; text-align: left; }
button.lev-cell:hover { background: var(--brand-soft); }
button.lev-cell:focus-visible { outline: 2px solid var(--brand); }
.lev-m { font-size: 1.05em; } .lev-m.m-si { color: var(--ok); } .lev-m.m-parcial { color: var(--warn); } .lev-m.m-no, .lev-m.m-x { color: var(--mut); }
.lev-chip { display: inline-block; font-size: 0.72em; letter-spacing: .05em; text-transform: uppercase; border: 1px solid currentColor; border-radius: 4px; padding: 1px 6px; font-weight: 700; }
.lev-chip.t-ok { color: var(--ok); } .lev-chip.t-info { color: #23567a; } .lev-chip.t-warn { color: var(--warn); }
.lev-chip.t-mut { color: var(--mut); } .lev-chip.t-bad { color: var(--bad); }
.lev-radio { flex-direction: row !important; gap: 6px; align-items: center; font-weight: normal; }
.lev-radio input { width: auto; }
.lev-questions li { margin: 0 0 10px; }
.lev-owner { font-size: 0.72em; letter-spacing: .05em; text-transform: uppercase; color: #23567a; font-weight: 700; }
.lev-ans { color: var(--ok); font-size: 0.9em; margin: 3px 0; }
.lev-rel-admin { border: 1px dashed var(--line); border-radius: 8px; padding: 8px 10px; margin: 6px 0; }

/* 16-oct-2026: documentos del proyecto con anotaciones (routers/project_documents.py) */
.doc-panel .doc-item-hd { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.doc-item { border: 1px solid var(--line); border-radius: 8px; padding: 10px 14px; margin: 10px 0; background: var(--card); }
.doc-body { font-size: 0.92em; line-height: 1.5; margin-top: 6px; overflow-x: auto; }
.doc-body h1 { font-size: 1rem; margin: 6px 0; }
.doc-body h2 { font-size: 0.95rem; margin: 8px 0 4px; }
.doc-body ul, .doc-body ol { margin: 4px 0 8px 20px; }
.doc-body table { width: 100%; border-collapse: collapse; font-size: 0.9em; }
.doc-body td, .doc-body th { border-bottom: 1px solid var(--line); padding: 4px 6px; text-align: left; vertical-align: top; }
.doc-body .fase { border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px; }
.doc-body .tag { background: var(--brand-dark); color: #fff; border-radius: 4px; padding: 0 6px; font-size: 0.8em; margin-right: 6px; }
.doc-notes { margin-top: 8px; border-top: 1px dashed var(--line); padding-top: 6px; }
.doc-note { background: #fff8e6; border-left: 3px solid #d9a400; padding: 6px 10px; margin: 6px 0; border-radius: 4px; font-size: 0.9em; }
.doc-note.res { background: var(--paper); border-left-color: var(--ok); opacity: .85; }
.doc-res { margin-top: 4px; color: var(--ink-soft); }
.doc-note-form { display: flex; gap: 8px; align-items: flex-end; margin-top: 6px; }
.doc-note-form textarea { flex: 1; }
.side nav .nav-off { display: block; padding: 6px 10px; color: rgba(255,255,255,0.35); font-size: 0.87em; cursor: default; }
.side nav .nav-off.nav-top { font-weight: 650; font-size: 0.92em; }

/* 16-oct-2026: Sesiones y navegación */
.act-nav { margin: 4px 0 4px 22px; columns: 2; column-gap: 28px; font-size: 0.88em; }
.act-nav li { break-inside: avoid; padding: 1px 0; }
@media (max-width: 760px) { .act-nav { columns: 1; } }

/* 20-oct-2026: acceso directo a los documentos en la ficha del proyecto */
.pj-docs-top { margin: 10px 0 14px; padding: 10px 12px; border: 1px solid var(--line, #d8e0d8); border-left: 4px solid var(--brand, #2e6b3f); border-radius: 6px; background: var(--brand-soft, #e4efe9); }
.pj-docs-top-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: space-between; padding: 6px 0 0; }

/* 20-oct-2026: aprobación y emisión por versión */
.doc-vbox { margin: 10px 0 16px; padding: 12px; border: 1px solid var(--line); border-left: 4px solid var(--accent); border-radius: 6px; background: var(--accent-soft); }
.doc-vbox table { background: var(--card); }
.doc-approve { margin-top: 10px; padding: 10px; background: var(--card); border-radius: 6px; }

/* ── Espacio de trabajo de la licitación (6-nov-2026) ───────────────
   Menú horizontal del proyecto por bloques; cabecera con la etapa. */
.lw-panel { padding-top: 14px; }
.lw-head { margin-bottom: 10px; }
.lw-kicker { font-size: 0.74em; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.lw-title { margin: 2px 0 0; font-size: 1.25em; }
.lw-steps { display: flex; list-style: none; padding: 0; margin: 8px 0 10px; gap: 0; counter-reset: none; }
.lw-steps li { flex: 1; min-width: 0; position: relative; padding: 0 8px 0 0; font-size: 0.86em; color: var(--mut); }
.lw-steps li::before { content: ""; position: absolute; top: 12px; left: 26px; right: 4px; height: 2px; background: var(--line); }
.lw-steps li:last-child::before { display: none; }
.lw-steps li.done::before { background: var(--ok); }
.lw-steps .lw-dot { position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: var(--card); border: 2px solid var(--line); font-weight: 700; font-size: 0.85em; margin-bottom: 4px; }
.lw-steps li.done .lw-dot { background: var(--ok); border-color: var(--ok); color: #fff; }
.lw-steps li.now .lw-dot { background: var(--accent); border-color: var(--accent); color: #fff; }
.lw-steps b { display: block; color: var(--ink-soft); font-size: 0.95em; }
.lw-steps li.now b { color: var(--ink); }
.lw-steps small { display: block; line-height: 1.3; }
.lw-next { background: var(--accent-soft); border-left: 3px solid var(--accent); padding: 8px 12px; border-radius: 6px; font-size: 0.92em; }
.lw-tabs { display: flex; gap: 2px; border-bottom: 2px solid var(--line); margin: 14px 0 12px; flex-wrap: wrap; position: sticky; top: 0; background: var(--card); z-index: 5; }
.lw-tab { background: none; border: 0; border-bottom: 3px solid transparent; margin-bottom: -2px; padding: 9px 13px; font: inherit; font-size: 0.92em; color: var(--ink-soft); cursor: pointer; white-space: nowrap; }
.lw-tab:hover { color: var(--ink); background: var(--paper); }
.lw-tab.on { color: var(--brand-dark); border-bottom-color: var(--brand); font-weight: 650; }
.lw-sub { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.lw-sub button { background: var(--paper); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; font: inherit; font-size: 0.85em; color: var(--ink-soft); cursor: pointer; }
.lw-sub button:hover { border-color: var(--brand); color: var(--ink); }
.lw-sub button.on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-dark); font-weight: 650; }
.lw-badge { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 9px; background: var(--warn); color: #fff; font-size: 0.78em; text-align: center; }
.lw-badge.ok { background: var(--ok); }
.lw-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; justify-content: space-between; margin: 0 0 10px; font-size: 0.92em; }
.lw-help { color: var(--ink-soft); font-size: 0.92em; margin: 0 0 10px; max-width: 80ch; }
.lw-h { margin: 16px 0 6px; display: flex; align-items: center; gap: 10px; }
.lw-frame { width: 100%; border: 1px solid var(--line); border-radius: 6px; min-height: 200px; background: #fff; }
.lw-offer { display: grid; grid-template-columns: 210px 1fr; gap: 14px; align-items: start; }
.lw-index { position: sticky; top: 52px; max-height: calc(100vh - 70px); overflow-y: auto; display: flex; flex-direction: column; gap: 1px; font-size: 0.84em; border-right: 1px solid var(--line); padding-right: 8px; }
.lw-index a { text-decoration: none; color: var(--ink-soft); padding: 4px 6px; border-radius: 4px; }
.lw-index a:hover { background: var(--paper); color: var(--ink); }
.lw-page { border: 1px solid var(--line); border-radius: 8px; margin: 0 0 16px; overflow: hidden; scroll-margin-top: 56px; }
.lw-page-hd { background: var(--paper); padding: 6px 10px; font-size: 0.9em; border-bottom: 1px solid var(--line); }
.lw-page-img img { display: block; width: 100%; height: auto; }
.lw-page-img figcaption { display: none; }
.lw-page-img figure { margin: 0; }
.lw-page-notes { padding: 8px 10px; background: var(--card); border-top: 1px solid var(--line); }
.lw-note-form, .lw-resolve-form { display: flex; gap: 6px; align-items: flex-end; flex-wrap: wrap; margin-top: 6px; }
.lw-note-form textarea { flex: 1; min-width: 220px; }
.lw-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; }
.lw-card { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--card); }
.lw-card-who { font-weight: 700; }
.lw-card-meta { font-size: 0.85em; color: var(--ink-soft); margin: 2px 0 6px; }
.lw-card-body { font-size: 0.9em; margin-bottom: 6px; }
.lw-finding { border-left: 3px solid var(--accent); padding: 6px 10px; margin: 6px 0; background: var(--paper); border-radius: 0 6px 6px 0; }
.lw-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 0.85em; color: var(--ink-soft); margin: 0 0 8px; }
.lw-matrix { min-width: 900px; border-collapse: separate; border-spacing: 0; font-size: 0.86em; width: 100%; }
.lw-matrix th, .lw-matrix td { vertical-align: top; text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.lw-matrix thead th { background: var(--brand-soft); position: sticky; top: 0; }
.lw-matrix td.lw-act { width: 260px; font-weight: 600; }
.lw-matrix tr.lw-grp td { background: var(--paper); font-size: 0.78em; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-soft); font-weight: 650; }
.lw-matrix td.lw-pert { width: 200px; font-size: 0.92em; }
.lw-matrix th.lw-col, .lw-matrix td.lw-col { width: 21%; }
.lw-matrix tr.lw-inline td { background: var(--accent-soft); }
.lw-cell { width: 100%; text-align: left; background: none; border: 1px dashed var(--line); border-radius: 5px; padding: 4px 6px; font: inherit; color: inherit; cursor: pointer; min-height: 30px; }
.lw-cell:hover { border-color: var(--accent); background: var(--accent-soft); }
.lw-ph { color: var(--mut); font-style: italic; font-size: 0.9em; }
.lw-pencil { background: none; border: 1px solid var(--line); border-radius: 4px; cursor: pointer; padding: 0 5px; color: var(--ink-soft); }
.lw-pencil:hover { border-color: var(--accent); color: var(--accent); }
.lw-inline { background: var(--accent-soft); border-radius: 6px; padding: 8px 10px; margin: 6px 0; }
.lw-weights { display: flex; flex-direction: column; gap: 4px; margin: 0 0 8px; font-size: 0.9em; }
.lw-wbar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; background: var(--line); max-width: 520px; }
.lw-wbar .t { background: var(--brand); } .lw-wbar .e { background: var(--accent); } .lw-wbar .o { background: var(--mut); }
.lw-qs li { margin: 0 0 10px; }
tr.lw-now td { background: var(--warn-soft); }
@media (max-width: 760px) {
  .lw-steps { flex-direction: column; gap: 6px; }
  .lw-steps li::before { display: none; }
  .lw-steps li { display: flex; gap: 8px; align-items: baseline; }
  .lw-offer { grid-template-columns: 1fr; }
  .lw-tabs { position: static; }
  .lw-tab { padding: 7px 9px; }
  .lw-index { position: static; max-height: none; flex-direction: row; flex-wrap: wrap; border-right: 0; }
}
