/* ═══════════════════════════════════════════════════════════════════════════
   COSMERIUM ERA III · NCRT-3
   reset.css — Normalización sobria. Se carga DESPUÉS de tokens.css y ANTES
   de chrome.css.

   Criterio: este fichero no decide nada de estética. Solo (a) borra los
   defaults del navegador que estorban, (b) impone las tres reglas de
   accesibilidad que DESIGN declara obligatorias en toda la aplicación
   —tabular-nums, :focus-visible ámbar y cursores sensatos—, y (c) cierra la
   puerta al scroll horizontal del body.

   Casi todo va envuelto en :where() a propósito: eso deja la especificidad
   del reset en 0,0,0 y garantiza que cualquier regla de components.css o de
   una página gane siempre, sin peleas ni !important.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ───────────────────────── CAJA ───────────────────────── */

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


/* ───────────────────────── RAÍZ ─────────────────────────
   overflow-x: clip, NO hidden. Es la diferencia entre que funcione el chasis
   y que no: `overflow-x: hidden` fuerza overflow-y a auto y convierte al body
   en contenedor de scroll, lo que rompe todos los position:sticky del
   producto —la cabecera de .reg-table (§6.5), el raíl izquierdo y el raíl de
   derivadas del expediente (§10.4), el índice del MOC (§10.11)—. `clip` no
   crea contenedor de scroll: recorta y punto. Ese es el arreglo.
   La regla dura de §6.5 se cumple igual: el <body> no hace scroll horizontal
   jamás; el desbordamiento lo gestiona cada tabla en su propio contenedor. */

html{
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;   /* anulado bajo prefers-reduced-motion en tokens.css */

  /* DESIGN §4.5: el cero rasgado de IBM Plex Mono. Se declara en la raíz y no
     componente a componente porque la regla es "los números de un expediente
     no bailan" y eso no admite excepciones por descuido. De las seis familias
     del stack, ss01 solo existe en IBM Plex Mono; las otras cinco ignoran la
     petición sin efecto secundario. Y como aquí solo se nombra ss01, el
     tabular-nums de abajo (feature `tnum`) sigue aplicándose. */
  font-feature-settings: "ss01";
}


/* ───────────────────────── CUERPO ─────────────────────────
   100dvh y nunca 100vh (Anexo B.13): en iOS Safari 100vh incluye la barra de
   direcciones, y con el teclado virtual abierto recorta el formulario sin
   posibilidad de scroll. Ese bug ya existía en el portal antiguo. */

body{
  margin: 0;
  min-height: 100dvh;
  overflow-x: clip;

  background-color: var(--bg);
  color: var(--text);

  font-family: var(--ff-ui);
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: var(--lh-ui);

  /* Obligatorio en TODA la aplicación (§4.5). Al heredarse desde el body,
     cualquier cifra de cualquier pantalla queda en ancho fijo por defecto y
     una tabla de 744 ítems no tiembla al pasar de página. */
  font-variant-numeric: tabular-nums;

  /* Hueso claro sobre carbón engorda el trazo en macOS. Antialiased lo
     devuelve al peso con el que está diseñada la escala tipográfica. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /* §11.2: se elimina el `cursor: crosshair` global del repo antiguo. En una
     web mayoritariamente de formularios rompía la selección de texto y
     contradecía la ficción de documento oficial. */
  cursor: default;

  /* El transporte del viraje rojo→cian del sellado (§10.7). Solo color: no se
     transiciona background-color del body porque repinta el lienzo entero. */
  transition: color var(--d-heavy) var(--ez-term);
}


/* ───────────── MÁRGENES Y BLOQUES DE TEXTO ─────────────
   Se anulan todos. La composición la decide el layout, nunca el user agent.
   Los títulos no heredan tamaño ni peso del navegador: la escala modular de
   §4.2 es la única fuente de tamaños, y así un <h3> mal elegido por semántica
   no arrastra un cuerpo equivocado. */

:where(h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd,pre,fieldset){ margin: 0; }

:where(h1,h2,h3,h4,h5,h6){
  font-size: inherit;
  font-weight: inherit;
  line-height: var(--lh-display);
  text-wrap: balance;   /* titulares sin viudas; degrada sin efecto donde no exista */
}

:where(p,li,dd){ text-wrap: pretty; }

:where(ul,ol){ margin: 0; padding: 0; }

/* Se quita la viñeta solo cuando el autor declara role="list": así Safari
   con VoiceOver sigue anunciando "lista" y no perdemos la semántica. */
:where(ul[role="list"],ol[role="list"]){ list-style: none; }

:where(fieldset){ padding: 0; border: 0; }
:where(legend){ padding: 0; }

:where(hr){
  border: 0;
  border-top: var(--bw-hair) solid var(--line);
  margin: 0;
}

:where(address){ font-style: normal; }


/* ───────────────────────── ENLACES ─────────────────────────
   Subrayado conservado por defecto y separado de la línea base: en prosa un
   enlace sin subrayar solo se distingue por color, y el rojo Arasaka sobre
   carbón está a 4.3:1 — insuficiente como única señal. El chrome y los
   componentes que sí llevan otra afordancia (nav, botones) lo quitan. */

:where(a[href]){
  color: var(--accent);
  text-decoration-thickness: var(--bw-hair);
  text-underline-offset: .22em;
  cursor: pointer;
}
:where(a[href]:hover){ color: var(--accent-brt); }


/* ───────────────────────── MEDIOS ─────────────────────────
   Imágenes fluidas. display:block elimina el hueco fantasma de la línea base
   que descuadra los marcos del .mugshot y de las tarjetas de screamsheet.
   El <svg> queda fuera de display:block porque la mayoría son glifos en línea
   dentro de botones y sellos. */

:where(img,video,canvas,picture){
  display: block;
  max-width: 100%;
  height: auto;
}
:where(svg){ max-width: 100%; }
:where(img,video){ background-color: var(--surface-2); }  /* evita el flash blanco al cargar */


/* ───────────────────────── FORMULARIOS ─────────────────────────
   El atajo `font: inherit` es imprescindible (los controles no heredan
   tipografía), pero la forma abreviada RESETEA font-variant-numeric a normal.
   Sin la línea siguiente, los tabular-nums desaparecerían exactamente en los
   sitios donde más importan: el campo de 6×4 del aval, los steppers de
   característica y las celdas editables. Por eso van las dos juntas. */

:where(input,button,textarea,select,optgroup){
  font: inherit;
  font-variant-numeric: inherit;
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
}

/* Los campos de texto nacen desnudos: cada componente pinta su propio hueco
   (§6.2 — el campo es un hueco en el formulario, no una caja flotante).
   Se excluyen checkbox y radio porque ahí el dibujo nativo es la base sobre
   la que trabajan los peines de §6.10 con appearance:none. */
:where(input:not([type="checkbox"]):not([type="radio"]),textarea,select){
  background-color: transparent;
  border: 0;
  cursor: text;
}
:where(select,button,[type="button"],[type="submit"],[type="reset"],[type="checkbox"],[type="radio"],[type="file"]){
  cursor: pointer;
}

:where(button){
  background: none;
  border: 0;
  padding: 0;
  text-align: inherit;
}

/* Vertical por defecto: redimensionar en horizontal descuadra la retícula
   ortogonal, y la regla 2 de §2.2 dice que los formularios no se desalinean. */
:where(textarea){ resize: vertical; }

/* Firefox baja la opacidad del placeholder por su cuenta y lo deja por debajo
   del suelo de contraste. Se fija a 1 y el color lo pone el token. */
:where(::placeholder){ color: var(--text-off); opacity: 1; }

:where(:disabled){ cursor: not-allowed; }

/* Anexo B.3: --text-off (2.2:1) NUNCA lleva texto informativo. Un control
   deshabilitado con opacity heredada del navegador ensucia además el trazo
   del border-image de los botones de forma imprevisible (§6.1), así que la
   opacidad nativa se anula y el estado lo comunica el componente. */
:where(:disabled,[aria-disabled="true"]){ opacity: 1; }


/* ───────────────────────── TABLAS ─────────────────────────
   Aquí viven los 65 SkillDef, los 744 objetos y las 22 heridas críticas. */

:where(table){
  border-collapse: collapse;
  border-spacing: 0;
  width: 100%;
}
:where(th){ text-align: left; font-weight: inherit; }


/* ───────────────────────── FOCO ─────────────────────────
   §11.2: :focus-visible obligatorio en todo lo interactivo. Ámbar a 13.9:1 se
   ve incluso sobre relleno de acento, y por eso el foco es ámbar en los tres
   niveles de acceso — no cambia con el tema.

   `outline: none` en :focus:not(:focus-visible) NO viola el Anexo B.9: el
   sustituto visible existe y es esta misma regla. Lo que se evita es el
   anillo pegado al ratón tras un clic, que en una interfaz de trámite
   aparecería en cada casilla marcada. */

:where(:focus:not(:focus-visible)){ outline: none; }

:where(:focus-visible){
  outline: var(--bw-2) solid var(--focus);
  outline-offset: 2px;
  animation: focus-lock var(--d-fast) var(--ez-snap);
}

/* focus-lock · §7.2 · 120ms · el anillo se cierra sobre el elemento.
   Es un disparo único sobre un solo elemento, no un bucle: no entra en el
   presupuesto de capas compuestas de §8.1. */
@keyframes focus-lock{
  from{ outline-offset: 6px; }
  to  { outline-offset: 2px; }
}


/* ───────────────────────── SELECCIÓN ─────────────────────────
   Tinta --accent-on sobre relleno de acento (§3.4.5), que además es lo que
   hace que en zona calle el texto seleccionado salga índigo sobre amarillo en
   COPIA IMPRESA sin escribir una regla más. */

::selection{
  background-color: var(--accent);
  color: var(--accent-on);
}


/* ───────────────────────── VARIOS ───────────────────────── */

/* `[hidden]` GANA SIEMPRE, Y AQUÍ SÍ VA `!important`.
   Es la segunda excepción del proyecto —la otra es el bloque de movimiento
   reducido— y se gana el sitio con hechos: `[hidden]` es (0,1,0) y lo tumbaba
   cualquier regla de clase que fijara `display`, así que fue apareciendo una
   lista de parches (`.btn[hidden]`, `.inject[hidden]`, `.efectos[hidden]`,
   `.mugshot__img[hidden]`, `.slots__panel[hidden]`…) que crecía cada vez que
   una pantalla estrenaba un elemento conmutable. Y contra un `style=` en línea
   no había parche posible: el aviso de devolución se pintaba sobre borradores
   recién abiertos, diciéndole a alguien que su expediente había sido devuelto
   antes de haberlo cursado.
   Ocultar es una decisión de estado, no de presentación: cuando el servidor o
   el JS dicen que algo no se ve, no se ve. */
[hidden]{ display: none !important; }

/* El ancla de destino de los saltos del raíl y de las notas del Verificador
   no debe quedar debajo de la banda de clasificación ni de la cabecera. */
:where(:target){ scroll-margin-top: calc(var(--bar-top) + var(--header-h) + var(--sp-5)); }
