/* ---------------------------------------------------------------- Fuentes
 *
 * Self-hosted, not Google's CDN: a compliance portal should not leak a request
 * per visit to a third party (design system §1.8). Served from the binary with
 * go:embed.
 *
 * VARIABLE versions: one file per family covers every weight the spec uses
 * (Archivo 400-900, JetBrains Mono 400-500) instead of eight static ones.
 * 66 KB for both, latin subset.
 *
 * font-display: swap — text shows immediately in the fallback family and swaps
 * once loaded. On a compliance table, reading late is worse than reading in a
 * different typeface for a moment.
 */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('fonts/archivo-latin.woff2') format('woff2-variations');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('fonts/jetbrains-mono-latin.woff2') format('woff2-variations');
}

/* Porticus — design system tokens.
 *
 * A literal transcription of docs/design/design_handoff_porticus_portal/design-system.md.
 * Values are never "eyeballed": if something does not fit a screen, the spec is
 * corrected with Pedro first and this file after, never the other way round.
 *
 * A single theme file: when the handoff changes, this changes and not the views.
 */

:root {
  /* --- Marca --- */
  --navy:        #0F2A54;
  --navy-700:    #16386B;
  --navy-600:    #1c4380;
  --navy-500:    #2A4574;
  --blue:        #1F63E3;
  --blue-400:    #4A8BF0;
  --blue-200:    #9FC0F7;
  --blue-100:    #E8EEF9;

  /* --- Neutros --- */
  --bg:                  #F4F6FA;
  --surface:             #FFFFFF;
  --border:              #E5E7EB;
  --border-soft:         #EEF1F6;
  --text:                #0F2A54;
  --text-muted:          #4B5563;
  --text-subtle:         #8b95a5;
  --text-disabled:       #9CA3AF;
  --text-on-navy:        #7f9cc9;
  --text-on-navy-strong: #C9DCFF;

  /* --- Compliance states: ALWAYS a background/border/text triple.
         Nunca el color como único portador de significado: cada chip lleva
         además su etiqueta textual. --- */
  --ok-bg:     #E6F2EC;  --ok-border:     #BEDDCE;  --ok-text:     #0F7A55;
  --pend-bg:   #FDF2E2;  --pend-border:   #F3DFBD;  --pend-text:   #B4690E;
  --riesgo-bg: #FBE9E7;  --riesgo-border: #F2CFC9;  --riesgo-text: #B3261E;
  --na-bg:     #F4F6FA;  --na-border:     #E5E7EB;  --na-text:     #9CA3AF;

  /* --- Status dots of the compliance table ---
     Son tokens PROPIOS y no los *-text de arriba: aquéllos están calculados
     para leerse como TEXTO sobre el fondo claro de un chip, así que son oscuros.
     Como relleno sólido de un punto chico eso se paga caro — el ámbar #B4690E se
     ve marrón y a 8px no se distingue del rojo.
     Los de acá son un tono más vivos, y aun así todos superan 3:1 contra el
     blanco, que es lo que WCAG pide para un elemento gráfico. */
  --dot-ok:     #0F7A55;  /* 5.3:1 */
  --dot-pend:   #F59E0B;  /* 2.2:1 — ver la nota de abajo */
  --dot-riesgo: #B3261E;  /* 6.5:1 — se deja OSCURO a propósito: el ámbar es
                             claro por naturaleza, y un rojo también claro los
                             volvería a acercar. La separación entre esos dos
                             puntos es de luminancia tanto como de tono. */
  --dot-na:     #9CA3AF;

  /* On the amber's 2.2:1. An orange ONLY reads as amber when it is light: at low
     luminance the eye calls it brown, and there it stops being distinguishable
     from the red — which is the mistake to avoid. Brightness is chosen over
     contrast, and it can be, because the dot is NOT the only carrier of state:
     every cell carries the state in words in its title and for screen readers,
     and the row has its GLOBAL chip with text. WCAG's 3:1 rule applies to
     graphics required to understand the content; here the text alternative
     exists. It is the same #F59E0B the backoffice uses, so the two portals also
     speak the same visual language. */

  /* --- Alert severity --- */
  --sev-critica:      #B3261E;  --sev-critica-on-navy: #F09A8E;
  --sev-alta:         #C2571A;  --sev-alta-on-navy:    #F0C070;
  --sev-media:        #B4690E;  --sev-media-on-navy:   #F0C070;
  --sev-baja:         #4A8BF0;  --sev-baja-on-navy:    #9FC0F7;

  /* --- Sidebar percentage indicators --- */
  /* Ambar de la estrella de fijar, sobre navy. Se llamaba --pct-medio y era el
     tono medio del porcentaje del sidebar; ese porcentaje salio el 2026-09-02 y
     el token se quedo con su unico uso real. */
  --star: #F0C070;

  /* --- Typography. Two families, no exceptions.
         Regla: si es un número que se compara o un código, va en mono. --- */
  --font-ui:   'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --- Radios --- */
  --radius-xs:   2px;
  --radius-sm:   5px;
  --radius-md:   7px;
  --radius-lg:   9px;
  --radius-xl:   10px;
  --radius-2xl:  12px;
  --radius-full: 999px;

  /* --- Medidas fijas --- */
  --sidebar-w: 288px;
  --drawer-w:  460px;
  --modal-w:   560px;
  --prose-max: 720px;

  /* --- Movimiento: discreto y funcional --- */
  --t: 120ms ease;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Visible focus on every interactive element. The handoff marks it as
   "a añadir en producción"; se añade desde el principio. */
:is(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- Layout */

.layout { display: flex; min-height: 100vh; }

/* El sidebar se queda quieto: position:sticky + 100vh de alto.
   Sin esto scrollea junto con la página y en una tabla de 24 empresas la
   navegación entera desaparece de la pantalla — que es lo contrario de para qué
   existe una barra de navegación.
   Sticky y no fixed: fixed lo saca del flujo y habría que reservarle el ancho a
   mano en .main. Así la columna la sigue reservando el flex.
   El overflow propio es la válvula para una ventana baja: antes de recortar el
   menú, que scrollee él solo. */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  overflow-y: auto;
  background: var(--navy);
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 14px;
}

.sidebar__section {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-on-navy);
  padding: 16px 10px 6px;
}

.sidebar__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
  color: var(--text-on-navy-strong);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: background var(--t), color var(--t);
}
.sidebar__item:hover            { background: var(--navy-700); color: #fff; }
.sidebar__item[aria-current]    { background: var(--blue);     color: #fff; }

.sidebar__divider { height: 1px; background: var(--navy-500); margin: 12px 10px; }

/* --- Collapsible menu groups ---
   Native <details>/<summary>: collapsing a menu needs no JavaScript, and the
   keyboard and screen reader already know what this is. */
.sidebar__group { }

.sidebar__summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
  color: var(--text-on-navy-strong);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background var(--t), color var(--t);
  /* The default marker is removed in both engines: the chevron takes its
     place, which can be aligned and rotated. */
  list-style: none;
}
.sidebar__summary::-webkit-details-marker { display: none; }
.sidebar__summary:hover { background: var(--navy-700); color: #fff; }
/* Keyboard focus must be visible: the summary IS the control that expands. */
.sidebar__summary:focus-visible { outline: 2px solid var(--blue-200); outline-offset: -2px; }

.sidebar__chevron {
  margin-left: auto;
  display: flex;
  color: var(--text-on-navy);
  transition: transform var(--t);
}
.sidebar__group[open] .sidebar__chevron { transform: rotate(180deg); }

/* A group's items are indented to where the summary's TEXT starts (10 padding
   + 16 icon + 10 gap), so they read as children and not as another row at the
   same level. */
.sidebar__group .sidebar__item { padding-left: 36px; font-weight: 500; }

/* Inherits the text colour, so it works over the navy and over a light background. */
.icon { width: 16px; height: 16px; flex-shrink: 0; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 40px;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.content { padding: 32px 40px 72px; display: flex; flex-direction: column; gap: 24px; }

/* ------------------------------------------------------------ Tipografía */

.page-title  { font-size: 29px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.05; margin: 0; }
.card-title  { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-subtle);
}
.muted  { color: var(--text-muted); }
.prose  { max-width: var(--prose-max); text-wrap: pretty; }

/* Bajada de una tarjeta: la línea que explica en lenguaje llano lo que muestra
   la tabla de abajo.
   NO lleva el tope de medida de .prose. Dentro de una tarjeta que ocupa todo el
   ancho de la pantalla, un párrafo cortado en 720px deja media tarjeta vacía y
   se lee como un error de maquetación, no como una decisión tipográfica.
   text-wrap: pretty evita que la última línea quede con una sola palabra. */
/* La estrella del encabezado: el mismo control que la del sidebar, en el tamaño
   del título. Va a la DERECHA del nombre: a la izquierda desalineaba el título
   respecto de la bajada de arriba. */
.page-title-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.page-pin {
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
  line-height: 1;
  font-size: 22px;
  color: var(--text-subtle);
  transition: color 120ms ease;
}
.page-pin:hover { color: var(--blue); }
.page-pin--on   { color: var(--dot-pend); }
.page-pin:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }

.card__intro {
  margin: -8px 0 0;
  font-size: 13px;
  color: var(--text-muted);
  text-wrap: pretty;
}
.mono   { font-family: var(--font-mono); }

/* ---------------------------------------------------------------- Piezas */

/* Flat interface: a 1px border, never a shadow. */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 26px 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-family: var(--font-ui);
  font-size: 13.5px;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--t), border-color var(--t), color var(--t);
}
.btn--primary            { background: var(--blue); color: #fff; font-weight: 700; }
.btn--primary:hover      { background: var(--navy); }
.btn--secondary          { background: var(--surface); color: var(--text); border-color: var(--border); font-weight: 600; }
.btn--secondary:hover    { border-color: var(--blue-200); }

/* Status chip: colour + label. The label is NOT decorative — it is what
   hace legible el estado sin depender del color. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--radius-full);
  border: 1px solid;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.chip--ok     { background: var(--ok-bg);     border-color: var(--ok-border);     color: var(--ok-text); }
.chip--pend   { background: var(--pend-bg);   border-color: var(--pend-border);   color: var(--pend-text); }
.chip--riesgo { background: var(--riesgo-bg); border-color: var(--riesgo-border); color: var(--riesgo-text); }
.chip--na     { background: var(--na-bg);     border-color: var(--na-border);     color: var(--na-text); }

/* --------------------------------------------------------------- Wordmark */

/* Wordmark según docs/design/Porticus Manual de Marca.dc.html. Los números no
   son de gusto: salen de las proporciones que el manual repite en sus cinco
   variantes (cuerpos 29, 32 y 53 px).

   - Cuerpo 22px porque el manual fija un MÍNIMO: "wordmark nunca por debajo de
     15 px de altura de mayúscula". La Archivo tiene un cap height de 0.686 em,
     así que 15 / 0.686 = 21.9. Con los 19px anteriores la mayúscula medía
     13.0px y estábamos bajo el mínimo.
   - Peso 800, no 900. El manual lo dice como regla aparte: "No cambiar el peso
     del wordmark: siempre 800". El 900 es solo para el monograma del tile.
   - Tracking -0.04em y interlineado 0.82, como las tres variantes claras.
   - Punto al 23% del cuerpo (5px) y separado un 18% (4px), alineado abajo con
     el mismo respiro de ~7% que usa el manual. */
.brand { display: inline-flex; align-items: flex-end; gap: 4px; text-decoration: none; }
.brand__name { font-size: 22px; font-weight: 800; letter-spacing: -0.04em; line-height: 0.82; color: #fff; }
/* El punto del wordmark es CUADRADO, no redondo: el manual de marca lo dice en
   la definición ("el wordmark Porticus con punto cuadrado") y en las cinco
   variantes que dibuja. Estuvo redondo hasta el 2026-09-02.
   El azul cambia con el fondo, también según el manual: #4A8BF0 sobre navy,
   #1F63E3 sobre claro. */
.brand__dot  { width: 5px; height: 5px; background: var(--blue-400); margin-bottom: 2px; }
.brand--on-light .brand__name { color: var(--navy); }
.brand--on-light .brand__dot  { background: var(--blue); }

/* ------------------------------------------------------------------ HTMX */

/* In-flight request indicator. Pattern inherited from Petrus (HTMX.md): without
   una acción lenta no da señal y el usuario vuelve a hacer clic. */
.htmx-indicator { opacity: 0; transition: opacity var(--t); }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }

/* ----------------------------------------------------------------- Login */

.login {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: var(--navy);
  padding: 24px;
}
.login__card {
  background: var(--surface);
  border-radius: var(--radius-2xl);
  padding: 40px;
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  text-align: center;
}

/* El icono del dominio junto al nombre de la fila. gap chico y alineado a la
   base del texto: el icono acompaña al nombre, no lo encabeza. */
/* El nombre de la fila y su bajada. Se llamaban .dt__name y .dt__sub, del
   prefijo de ObligationsTable, y quedaron huérfanas cuando esa tabla salió del
   portal (2026-09-02): ahora llevan el prefijo de quien las usa. */
.heatmap__title { font-size: 14px; font-weight: 700; letter-spacing: -0.01em; }
.heatmap__sub   { font-size: 12px; color: var(--text-subtle); }

/* --------------------------------------- Ficha de sociedad: dos columnas */

/* Izquierda quién ES la sociedad, derecha cómo VA. La derecha se lleva algo más
   de ancho porque el heatmap son doce celdas y una ficha de datos se apila sin
   sufrir.
   Cada columna es un CONTAINER: así el heatmap decide su tamaño de etiqueta por
   el ancho que realmente tiene y no por el de la ventana, que es lo que un
   media query no sabe distinguir. */
.company-split {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  gap: 16px;
  align-items: start;
}
.company-split > * { min-width: 0; container-type: inline-size; }
/* Bajo 1200px el heatmap no cabe en media pantalla: vuelven a apilarse. */
@media (max-width: 1199px) {
  .company-split { grid-template-columns: 1fr; }
}
/* --------------------------------------------------------- Fichas (facts) */

/* Grilla que se acomoda a las tarjetas que haya. auto-fit + minmax deja que
   bajen de línea solas: estas tarjetas tienen altura variable —una identidad
   son cinco líneas y los socios pueden ser treinta— y forzarlas a una fila
   compartida las estiraría todas a la más alta. */
.fact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 16px;
  align-items: start;
}

.facts { margin: 0; display: flex; flex-direction: column; }
/* La línea separadora va ENTRE filas y no debajo de la última: un borde
   colgando bajo el último dato se lee como una fila vacía. */
.facts__row + .facts__row { border-top: 1px solid var(--border-soft); }
.facts__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 0;
}
/* El bloque de la izquierda se lleva el ancho sobrante, para que quede UN solo
   canal de aire entre lo que se lee y el dato que cierra (regla de columnas,
   cabecera de styleguide.templ). */
.facts__head { min-width: 0; flex: 1 1 auto; }
.facts__label {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
}
.facts__note {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
}
.facts__value {
  margin: 0;
  flex: 0 0 auto;
  text-align: right;
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
}
.facts__value.mono { font-family: var(--font-mono); font-size: 12px; }

.facts__more { margin-top: 4px; border-top: 1px solid var(--border-soft); }
.facts__more > summary {
  cursor: pointer;
  padding: 9px 0 0;
  font-size: 12px;
  color: var(--text-muted);
}
.facts__more > summary:hover { color: var(--blue); }

/* --------------------------------------------------------------- Errores */

/* Comparte .login__card: es la misma pieza —tarjeta blanca centrada sobre
   navy— y forkearla para cambiar tres textos es justo lo que el catálogo
   existe para evitar. Sólo se ensancha, porque acá hay dos frases y no un
   botón. */
.err { max-width: 520px; gap: 16px; }

/* El código va chico y arriba: es lo que sirve para reportar el problema, no
   lo que la persona necesita leer primero. El 404 gigante de otros sitios le
   da todo el peso visual justo a lo único sobre lo que no puede hacer nada. */
.err__code {
  margin: 0 0 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--text-subtle);
}
/* Archivo 800 con tracking −3 % e interlineado 1,05: el titular del manual de
   marca, sin inventarle una escala propia a esta pantalla. */
.err__title {
  margin: 0;
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--text);
  text-wrap: balance;
}
/* La línea técnica es DATO: va en mono, para copiarla y pegarla en un mensaje.
   break-all porque una URL larga sin cortes desborda la tarjeta. */
.err__detail {
  margin: 0;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  word-break: break-all;
  text-align: left;
}
.err__actions { display: flex; flex-direction: column; gap: 10px; }

/* ------------------------------------------------------------------- KPI */

/* La fila de KPIs se reparte entre LAS TARJETAS QUE HAY, no entre cuatro
   columnas fijas. Era repeat(4, 1fr) y ninguna pantalla tenia cuatro: todas
   dejaban un hueco a la derecha que se leia como algo que no cargo (Pedro,
   2026-09-02). Con flex, tres tarjetas ocupan la fila completa y dos tambien.
   El basis de 240px es el que decide cuando bajan de linea, asi que no hace
   falta un media query. */
.kpi-grid { display: flex; flex-wrap: wrap; gap: 16px; }
.kpi-grid > * { flex: 1 1 240px; }

.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.kpi__value { font-size: 32px; font-weight: 800; letter-spacing: -0.03em; line-height: 1; }
/* An amount needs less weight than a count; a text value, much less: at 32px
   un nombre de régimen ocupa tres líneas y desproporciona la fila entera. */
.kpi__value--amount { font-size: 27px; }
.kpi__value--text   { font-size: 19px; line-height: 1.2; letter-spacing: -0.02em; text-wrap: balance; }
.kpi__value--good   { color: var(--ok-text); }
.kpi__value--warn   { color: var(--pend-text); }
.kpi__value--bad    { color: var(--riesgo-text); }
.kpi__value--accent { color: var(--blue); }
.kpi__note { font-size: 12.5px; color: var(--text-muted); line-height: 1.4; text-wrap: pretty; }

/* --------------------------------------------------------------- Tablas */

/* Container with its own scroll: the page body never scrolls
   horizontal, la tabla sí (README del handoff, §Responsive). */
.table-scroll { overflow-x: auto; }

/* -------------------------------------------------------------- Heatmap */

/* The heatmap and the compliance table share a PALETTE and differ in SHAPE.
   Shape encodes what the axis is: contiguous cells for a continuous axis —twelve
   months in a row, where what you read is the streak— and separate dots for
   indicators unrelated to each other, where suggesting continuity would lie.
   The colour, on the other hand, has to be the same in both or the user learns
   two languages for the same thing.

   The cells used to carry the chip-background pastels, and at that lightness the
   "on time" green and the "not applicable" grey looked nearly identical. */
/* The cells are elastic and take up ALL the available width. The minmax(0, 1fr)
   is what guarantees there is never a horizontal scrollbar: without that 0 the
   implicit minimum is the content, and a single month label is enough to
   overflow the grid. That is also why the heatmap is not wrapped in
   .table-scroll — having no scroll is a property of the layout, not something
   papered over with overflow. */
.heatmap { display: grid; grid-template-columns: 190px repeat(12, minmax(0, 1fr)); gap: 4px; align-items: center; }
.heatmap__corner {}
.heatmap__month { font-size: 9.5px; letter-spacing: 0.02em; color: var(--text-subtle); text-align: center; padding-bottom: 6px; overflow: hidden; }
.heatmap__label { padding: 6px 12px 6px 0; }
/* Light fill + SATURATED border. The border carries the state's identity —it is
   the same colour as the table's dot, so the palette stays one— and the fill
   stays quiet.
   Filling the whole cell with the saturated colour worked too, but at 26px × 12
   months a good year ended up shouting as loudly as a bad one, and green is
   precisely the news you do not need to deliver. */
.heatmap__cell  { height: 26px; border-radius: var(--radius-sm); border: 1px solid; }
.heatmap__cell--ok     { background: var(--ok-bg);     border-color: var(--dot-ok); }
.heatmap__cell--pend   { background: var(--pend-bg);   border-color: var(--dot-pend); }
.heatmap__cell--riesgo { background: var(--riesgo-bg); border-color: var(--dot-riesgo); }
/* "Not applicable" is the only state that is NOT news: it goes without a
   coloured border, like an empty slot. Its pale grey used to be nearly identical
   to the pale green of "on time" — the saturated border on the others is exactly
   what separates them now. */
.heatmap__cell--na     { background: var(--na-bg);     border-color: var(--na-border); }

/* On narrow screens the obligation label is what gives, not the cells: a name
   is still readable truncated, an 8px month is not readable at all. */
@media (max-width: 900px) {
  .heatmap { grid-template-columns: 120px repeat(12, minmax(0, 1fr)); gap: 3px; }
  .heatmap__label .heatmap__sub { display: none; }
}

/* La columna estrecha: la etiqueta cede, las celdas no. Un nombre truncado se
   sigue leyendo; un mes de 8px no. */
@container (max-width: 660px) {
  .heatmap { grid-template-columns: 120px repeat(12, minmax(0, 1fr)); gap: 3px; }
}
/* Y si ni con eso alcanza, lo que cede es la BAJADA de la fila, no las celdas:
   un nombre sin su detalle se sigue entendiendo; doce meses ilegibles, no. */
@container (max-width: 460px) {
  .heatmap { grid-template-columns: 96px repeat(12, minmax(0, 1fr)); gap: 2px; }
  .heatmap__label .heatmap__sub { display: none; }
}


/* --- Domain strip of a company's page ---
   It comes first on the screen because it answers the question you arrive with
   —"how is this company doing?"— before drilling into the month. Each block
   leads to its domain's table, with the rest of the companies alongside. */
/* Las tarjetas son de CONEXIONES, y sus nombres son largos y desparejos:
   "SII" al lado de "Dirección del Trabajo". El minmax de 190px las partía en
   dos líneas y dejaba la fecha cortada en "1 sep / 2026". A 240px el nombre
   más largo entra completo, y las que sobran bajan de fila solas. */
.domain-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}
.domain-strip__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--text);
  transition: border-color var(--t), background var(--t);
}
/* Ya no es un enlace: el hover que insinuaba que se podía entrar a alguna
   parte salió junto con el href. */
.domain-strip__head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
/* La fecha va DEBAJO del nombre y no al lado: es el dato secundario de la
   tarjeta, y en línea competiría con el chip por el mismo canal de aire. */
.domain-strip__note {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  font-weight: 400;
  letter-spacing: 0;
  /* La fecha no se parte: "1 sep" arriba y "2026" abajo se lee como dos datos. */
  white-space: nowrap;
  color: var(--text-subtle);
}
.domain-strip__head .icon { color: var(--text-subtle); }
.domain-strip__item:hover .domain-strip__head .icon { color: var(--blue); }

/* ------------------------------------------- Multi-company compliance table */

/* One row per company and one column per obligation. With 24 companies and up
   to 12 indicators, two decisions carry all the legibility: the company stays
   frozen during horizontal scroll, and the rows are ordered by severity (that
   is SortComplianceRows' job, not the CSS's). */
.ct {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

.ct thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--text-subtle);
  text-align: center;
  padding: 0 8px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

/* The company column stays put: without this, scrolling across to see
   Contribuciones leaves you not knowing whose row it is. */
.ct__company {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  text-align: left !important;
  font-weight: 400;
  min-width: 240px;
  padding: 10px 16px 10px 0;
  border-bottom: 1px solid var(--border);
}
.ct thead .ct__company { z-index: 3; }

.ct tbody tr:hover .ct__company,
.ct tbody tr:hover td { background: var(--bg); }
/* El periodo del detalle es un <th> y no lleva .ct__company, asi que quedaba
   fuera del hover y la banda empezaba en la segunda columna. */
.det tbody tr:hover th { background: var(--bg); }

.ct__link { display: block; text-decoration: none; color: inherit; }
.ct__name {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}
.ct__link:hover .ct__name { color: var(--blue); }
.ct__meta { display: flex; gap: 8px; font-size: 10.5px; color: var(--text-subtle); margin-top: 2px; }

.ct__global { width: 96px; padding: 10px 8px; border-bottom: 1px solid var(--border); text-align: center; }
.ct__ind    { width: 58px; padding: 10px 8px; border-bottom: 1px solid var(--border); text-align: center; }

/* A dot instead of a chip: in a grid of up to 12 columns the label does not
   fit. What it does carry —and the backoffice does not— is the state in words,
   in the title and for screen readers: colour cannot be the only thing.
   8px, the same as the backoffice. 10px was tried to help tell the hue apart and
   came out worse: it fattens the row without fixing anything, because the
   problem was the colour and not the size. */
.ct__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  vertical-align: middle;
}
.ct__dot--ok     { background: var(--dot-ok); }
.ct__dot--pend   { background: var(--dot-pend); }
.ct__dot--riesgo { background: var(--dot-riesgo); }
.ct__dot--na     { background: var(--dot-na); }

/* El punto que abre el detalle. El area de click de 8px es inaceptable —y el
   minimo tactil son 24—, asi que el enlace se agranda con un pseudo-elemento
   transparente en vez de con padding: padding movería el punto dentro de la
   celda y desalinearia la columna. */
a.ct__dot--link { position: relative; cursor: pointer; }
a.ct__dot--link::after {
  content: "";
  position: absolute;
  inset: -8px;
}
a.ct__dot--link:hover  { box-shadow: 0 0 0 4px var(--blue-100); }
a.ct__dot--link:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* ------------------------------------------------------------ Modal

   El detalle de un indicador, encima de la tabla. <dialog open> pintado por el
   servidor: sin showModal() no está en el top layer, asi que el z-index y el
   scrim son nuestros. A cambio no hay una linea de JavaScript y el ✕ es un
   enlace, que funciona igual sin HTMX. */
/* Cerrado por el navegador (Escape o click afuera) solo se oculta el <dialog>:
   esta capa seguiría fija encima, oscureciendo y bloqueando la pagina. Con
   :has() desaparece junto con el. El ✕ es otro camino —vacia el hueco entero—
   y no necesita esta regla, pero tampoco le estorba. */
.modal:not(:has(dialog[open])) { display: none; }
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}
/* El scrim es SOLO el fondo oscuro, un <div> inerte. Cerrar al hacer click
   afuera lo pone el navegador con closedby="any" en el <dialog>: siendo un
   enlace hacia una peticion al servidor para cerrar algo que ya estaba en
   pantalla. */
.modal__scrim {
  position: absolute;
  inset: 0;
  background: rgba(15, 42, 84, 0.32);
  backdrop-filter: blur(2px);
}
.modal__box {
  position: relative;
  /* --modal-w (560px) es el ancho de un modal de FORMULARIO, que es para lo
     que el sistema lo definio. Este es un modal de TABLA: cuatro columnas y una
     de ellas con parrafos del SII de cinco lineas. A 960 se veia apretado; 1200
     deja el mensaje en tres lineas y sigue por debajo del limite de largo de
     linea legible. Mas ancho no: la prosa empieza a costar seguirla. */
  width: min(1200px, 100%);
  max-height: calc(100vh - 80px);
  overflow: auto;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--surface);
  box-shadow: 0 24px 64px rgba(15, 42, 84, 0.18);
  color: inherit;
}
.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 24px 28px 18px;
  border-bottom: 1px solid var(--border);
}
.modal__title { font-size: 20px; font-weight: 800; letter-spacing: -0.025em; margin: 0; }
.modal__sub   { font-size: 12px; color: var(--text-muted); margin: 4px 0 0; }
.modal__scope { font-size: 12px; color: var(--text-subtle); margin: 6px 0 0; }
.modal__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-md);
  color: var(--text-muted);
  text-decoration: none;
  font-size: 14px;
}
.modal__close:hover { background: var(--bg); color: var(--text); }

/* El modal de FORMULARIO, que es para lo que --modal-w se definio: una columna
   de campos, no una tabla. El de tabla es el ancho por defecto de .modal__box
   por historia —fue el primero— y no al reves. */
.modal__box--form { width: min(var(--modal-w), 100%); }

/* --- Lista de sociedades desconectadas ------------------------------------
   Una lista y no una tabla: son pocas filas y solo hay dos datos por fila, asi
   que las lineas de una tabla serian ruido. La causa va a la derecha porque es
   lo que se compara entre filas; el nombre se lleva el ancho sobrante. */
/* Un bloque por organismo. El rotulo va arriba y no en cada fila porque el
   arreglo es POR ORGANISMO: "se cayo Previred" se resuelve de una vez para las
   tres sociedades, y repetirlo en cada fila haria leer el mismo problema tres
   veces. */
.conn-group { margin-top: 18px; }
.conn-group:first-of-type { margin-top: 10px; }
.conn-group__source {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.conn-list { margin: 4px 0 0; padding: 0; list-style: none; }
.conn-list__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-top: 1px solid var(--border-soft);
}
.conn-list__name { display: flex; align-items: baseline; gap: 10px; font-weight: 600; color: var(--text); text-decoration: none; }
.conn-list__name:hover { color: var(--blue); }
.conn-list__id { font-size: 12px; color: var(--text-muted); font-weight: 400; }

/* --- Formulario de soporte ------------------------------------------------
   Una sola columna, porque son tres campos y ponerlos en dos hace que la vista
   tenga que decidir por donde entra. */
.sup { display: flex; flex-direction: column; gap: 20px; padding: 22px 28px 26px; margin: 0; }
.sup__label { display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.sup__optional { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--text-subtle); }
.sup__field { display: flex; flex-direction: column; gap: 8px; }
.sup__hint { font-size: 12px; color: var(--text-muted); line-height: 1.5; }
.sup__error {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--riesgo-border);
  border-radius: var(--radius-md);
  background: var(--riesgo-bg);
  color: var(--riesgo-text);
  font-size: 13px;
}
/* Los dos tipos son TARJETAS y no un <select>: con dos opciones un desplegable
   esconde la mitad de la pregunta detras de un click, y la ayuda de cada una
   —que es lo que evita que se elija mal— no cabria adentro. */
.sup__types { display: flex; flex-direction: column; gap: 8px; border: 0; padding: 0; margin: 0; }
.sup__types .sup__label { margin-bottom: 4px; padding: 0; }
.sup__type {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color var(--t), background var(--t);
}
.sup__type:hover { border-color: var(--blue-200); }
/* :has() y no una clase que ponga el servidor: quien esta elegido lo sabe el
   input, y pintarlo desde Go obligaria a repintar el formulario en cada click. */
.sup__type:has(input:checked) { border-color: var(--blue); background: var(--blue-100); }
.sup__type input { margin-top: 2px; accent-color: var(--blue); }
.sup__type-name { display: block; font-size: 14px; font-weight: 600; }
.sup__type-hint { display: block; margin-top: 2px; font-size: 12px; color: var(--text-muted); }
.sup__text {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
  resize: vertical;
}
.sup__text:focus-visible, .sup__file:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
.sup__file { font-size: 13px; color: var(--text-muted); }
.sup__actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.sup__sending { font-size: 12px; color: var(--text-muted); }
.sup__done { margin: 0; font-size: 16px; font-weight: 700; }

/* La tabla del detalle. Hereda de .ct el cuerpo y solo redefine anchos y
   alineacion: DETALLE se lleva el espacio porque es la unica columna con prosa.

   Se llama `det` y NO `dt`: `.dt` ya era la grilla de ObligationsTable
   (display: grid, mas arriba en este archivo). Reusar el nombre convirtio esta
   tabla en una grilla y le partio las columnas — cabecera y cuerpo cada una por
   su lado. Antes de inventar un prefijo, buscarlo acá. */
/* El aire lateral va en el contenedor con scroll, no en la <table>:
   padding sobre una tabla no lo respetan igual todos los motores. */
.modal__box .table-scroll { padding: 0 28px 24px; }
.modal__empty { padding: 24px 28px 28px; }
/* table-layout: fixed y anchos declarados. En automatico el navegador reparte
   segun el CONTENIDO, y los cinco indicadores tienen contenidos opuestos: el
   F22 trae parrafos del SII y las contribuciones una sola palabra ("VENCIDA").
   El resultado era que en contribuciones DETALLE se llevaba 800px vacios y la
   direccion se apilaba en cinco lineas en una columna de 110px. Con anchos
   fijos la tabla se ve igual en los cinco, que es de lo que se trata tener un
   componente y no cinco. */
.det { table-layout: fixed; }
.det thead th {
  text-align: left;
  padding: 14px 20px 10px 0;
  /* La cabecera comparte las clases de ancho con el cuerpo, pero NO su
     tipografia: manda el estilo de .ct thead th. */
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  color: var(--text-subtle);
}

.det td,
.det tbody th {
  /* Arriba y no al medio: el estado tiene que quedar a la altura de la PRIMERA
     linea del mensaje. Centrado, en una fila de cinco lineas, el chip flota en
     el medio y deja de leerse como el estado de ese periodo. */
  vertical-align: top;
  padding: 16px 20px 16px 0;
  border-top: 1px solid var(--border);
}


.det__period {
  /* ANCHOS EN PORCENTAJE, no pixeles. Con table-layout fixed el sobrante se
     reparte proporcionalmente entre las columnas que declaran ancho, asi que en
     pixeles el aire quedaba esparcido por toda la fila. Acá hay UNA columna en
     `auto` —la ultima de la izquierda— que se lleva todo el sobrante, y el
     resultado es un solo canal de aire entre el grupo izquierdo y el derecho. */
  width: 26%;
  text-align: left;
  /* La identidad de la fila: es lo que se busca con la vista antes de leer. */
  font-size: 14px;
  font-weight: 700;
  color: var(--navy);
}
.det__state  { width: 13%; }
.det__date   { width: 14%; color: var(--text-muted); font-size: 12px; }
.det__detail { line-height: 1.5; }

/* --- Quien absorbe el sobrante: la ULTIMA columna de la izquierda que exista.
   Dárselo a la primera dejaba el chip a media fila de su propio concepto. --- */
.det--prose .det__detail { width: auto; }
.det--prose .det__period { width: 14%; }  /* con prosa, la identidad es un año */
.det--dated .det__date   { width: auto; }
.det:not(.det--prose):not(.det--dated) .det__state { width: auto; }

/* --- El grupo de la derecha. Números y fechas de cierre, alineados a la
   derecha para que los digitos cuadren y la tabla cierre contra el borde. --- */
.det__amount {
  width: 15%;
  text-align: right;
  /* El padding de .det td es a la izquierda; acá tiene que ir a la derecha o el
     numero queda pegado a la columna siguiente. */
  padding-right: 24px;
  font-size: 13px;
}
.det__updated {
  width: 15%;
  white-space: nowrap;
  text-align: right;
  padding-right: 0;
  color: var(--text-muted);
  font-size: 12px;
}
/* Las columnas de descarga: el icono centrado bajo su rotulo, y un canal a la
   IZQUIERDA para separarlas de ACTUALIZADO —que esta alineado a la derecha y
   sin el quedaba pegado a "CERTIFICADO" en la cabecera—. Van al final, asi que
   la ultima cierra contra el borde. */
.det__file { width: 9%; text-align: center; padding-right: 0; padding-left: 14px; }
/* La cabecera hereda la alineacion de su columna, NUNCA el tamaño de letra:
   .ct thead th la fija en 10px mono, y redefinirla dejaba un encabezado mas
   grande que los demas. */
.det thead .det__amount  { text-align: right; padding-right: 24px; }
.det thead .det__updated { text-align: right; padding-right: 0; }
.det thead .det__file    { text-align: center; padding-right: 0; padding-left: 14px; }

.det__dl {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-md);
  color: var(--text-muted);
}
.det__dl:hover { background: var(--bg); color: var(--blue); }
.det__dl:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* La celda sin dato. Ni "$0" ni en blanco: el guion dice que se miro y no habia,
   que no es lo mismo que una celda que no se pinto. */
.det__none { color: var(--text-disabled); }

/* --- Un hallazgo repetido: el mensaje una vez, los sujetos al desplegar. --- */
.det__finding + .det__finding { margin-top: 8px; }
.det__finding > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.det__finding > summary::-webkit-details-marker { display: none; }
/* El triangulo lo dibujamos nosotros para poder girarlo y alinearlo con la
   linea base del texto; el nativo cambia de forma entre navegadores. */
.det__finding > summary::before {
  content: "›";
  flex: none;
  color: var(--text-subtle);
  transition: transform var(--t);
}
.det__finding[open] > summary::before { transform: rotate(90deg); }
.det__count {
  flex: none;
  padding: 1px 7px;
  border-radius: var(--radius-full);
  background: var(--bg);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
}
/* Los RUT: monoespaciados para que se comparen y se copien, y con el sangrado
   del triangulo para que se lean colgando de su mensaje. */
.det__who {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.6;
}
.det__finding[open] > .det__who { padding: 6px 0 2px 18px; }

@media (max-width: 720px) {
  .modal { padding: 0; align-items: flex-end; }
  .modal__box { width: 100%; max-height: 88vh; border-radius: var(--radius-2xl) var(--radius-2xl) 0 0; }
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------- Sidebar v2 */

.sidebar__search {
  background: var(--navy-700);
  border: 1px solid var(--navy-500);
  color: #fff;
  border-radius: var(--radius-md);
  padding: 9px 12px;
  font-family: var(--font-ui);
  font-size: 13px;
  width: 100%;
}
.sidebar__search::placeholder { color: var(--text-on-navy); }

/* The search box is Active Search: while the request is in flight the border is
   marked and "Buscando…" appears over the input. It is position:absolute so it
   reserves no height: an indicator that pushes the list down every 150 ms of
   typing feels worse than having no indicator at all. */
.sidebar__searchbox { position: relative; display: flex; }
.sidebar__searchbox.htmx-request .sidebar__search { border-color: var(--blue); }
.sidebar__searching {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-200);
  pointer-events: none;
}

/* The company list is the fragment HTMX replaces —on search and on pin— so it
   needs to be its own element with an id. It repeats the sidebar's column layout
   because it is now one nesting level deeper. */
.sidebar__companies { display: flex; flex-direction: column; gap: 4px; }

/* The row carries the company and its star. The star sits outside the <a>
   because it is a different action: a button inside a link is not valid HTML and
   the click would be ambiguous. */
.sidebar__row { display: flex; align-items: center; gap: 2px; }
.sidebar__row > form { display: flex; }
.sidebar__row .sidebar__company { flex: 1; min-width: 0; }

.sidebar__pin {
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: var(--radius-md);
  font-size: 15px;
  line-height: 1;
  color: var(--navy-500);
  transition: color var(--t), background var(--t);
}
.sidebar__pin:hover     { color: var(--star); background: var(--navy-700); }
.sidebar__pin--on       { color: var(--star); }

.sidebar__company { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: var(--radius-md); color: var(--text-on-navy-strong); text-decoration: none; transition: background var(--t); }
.sidebar__company:hover { background: var(--navy-700); color: #fff; }
.sidebar__company[aria-current] { background: var(--blue); color: #fff; }
.sidebar__company-name { font-size: 13.5px; font-weight: 600; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar__company-meta { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 10px; color: var(--text-on-navy); }
.sidebar__company[aria-current] .sidebar__company-meta { color: var(--blue-200); }

/* The sidebar's empty state has to say something: a heading with nothing under
   lee como que la página no cargó. */
.sidebar__empty { padding: 4px 10px 8px; font-size: 12.5px; color: var(--text-on-navy); line-height: 1.4; }

/* --- Selector de año: el único control de período del portal ---
   Parece un <select> pero es un <details> con enlaces adentro: un select nativo
   necesitaría un botón de enviar o JavaScript, y así cada año sigue siendo una
   URL. Mismo idioma nativo que los grupos del menú y el menú de usuario. */
.yearsel { position: relative; }

.yearsel__current {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px 7px 12px;
  min-width: 84px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  list-style: none;
  transition: border-color var(--t);
}
.yearsel__current::-webkit-details-marker { display: none; }
.yearsel__current:hover { border-color: var(--blue-200); }
.yearsel__current:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.yearsel__current .icon { width: 14px; height: 14px; margin-left: auto; color: var(--text-subtle); transition: transform var(--t); }
.yearsel[open] .yearsel__current { border-color: var(--blue); }
.yearsel[open] .yearsel__current .icon { transform: rotate(180deg); }

/* El menú flota: si empujara el layout, abrirlo movería el título de la página. */
.yearsel__menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  min-width: 100%;
  display: flex;
  flex-direction: column;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(16, 32, 64, 0.10);
}
.yearsel__item {
  padding: 7px 10px;
  border-radius: calc(var(--radius-md) - 3px);
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--text-muted);
  text-decoration: none;
  transition: background var(--t), color var(--t);
}
.yearsel__item:hover { background: var(--bg); color: var(--text); }
.yearsel__item[aria-current] { color: var(--blue); font-weight: 600; }

/* --- Menú de usuario, al pie del sidebar ---
   margin-top:auto lo empuja abajo sin importar cuántas empresas haya arriba. */
/* El pie: soporte y la cuenta, juntos y pegados abajo. El margin-top:auto está
   acá y NO en .usermenu — ahí dentro empujaba solo la cuenta, y soporte se
   quedaba arriba con un hueco de 300px en medio. */
.sidebar__foot { margin-top: auto; }
.usermenu { position: relative; padding-top: 4px; }

.usermenu__current {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  cursor: pointer;
  list-style: none;
  transition: background var(--t);
}
.usermenu__current::-webkit-details-marker { display: none; }
.usermenu__current:hover { background: var(--navy-700); }
.usermenu__current:focus-visible { outline: 2px solid var(--blue-200); outline-offset: -2px; }
.usermenu__current .icon { width: 14px; height: 14px; margin-left: auto; color: var(--text-on-navy); flex-shrink: 0; }
.usermenu[open] .usermenu__current { background: var(--navy-700); }

.usermenu__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background: var(--blue);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
}
.usermenu__email {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-on-navy-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.usermenu__email--dark { color: var(--text); }

/* Se abre hacia ARRIBA: el bloque ya está pegado al borde inferior. */
.usermenu__menu {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(16, 32, 64, 0.18);
  overflow: hidden;
}
.usermenu__head { display: flex; align-items: center; gap: 10px; padding: 12px; border-bottom: 1px solid var(--border); }
.usermenu__item {
  display: block;
  padding: 11px 12px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  transition: background var(--t);
}
.usermenu__item:hover { background: var(--bg); }

/* Header breadcrumb */
.breadcrumb { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em; color: var(--text-subtle); text-transform: uppercase; }

/* Cabecera ordenable de la tabla de cumplimiento. Es un <a> con href: el orden
   es una URL que se puede compartir y el camino sin JavaScript sale gratis. */
.ct__sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: inherit;
  text-decoration: none;
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
}
.ct__sort:hover { color: var(--blue); background: var(--bg); }
.ct__sort:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.ct__arrow { font-size: 9px; color: var(--blue); }
/* La columna ordenada se distingue sin depender solo de la flecha. Va como
   clase y no como selector sobre aria-sort del padre, porque la tabla de
   obligaciones es un grid de divs y ahí aria-sort no aplica. */
.ct__sort--on { color: var(--blue); }
