/* components.css — componentes de Palma (plan §7.8). Todos usan solo tokens.
   Estado nunca solo por color: icono + texto. Objetivos >= var(--target); separación >= var(--gap-min). */

@layer components {

  /* ---------- Icono (sprite propio, trazo uniforme) ---------- */
  .icon {
    inline-size: 1.25em;
    block-size: 1.25em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* ---------- Botón ---------- */
  .btn {
    --btn-bg: var(--surface);
    --btn-fg: var(--accent-strong);
    --btn-bd: var(--border-strong);
    --btn-bg-hover: var(--accent-bg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-block-size: var(--target);
    min-inline-size: var(--target);
    padding-inline: var(--space-5);
    border: 1px solid var(--btn-bd);
    border-radius: var(--radius-1);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-size: var(--text-base);
    font-weight: 650;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition), border-color var(--transition), transform var(--transition);
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
  }
  .btn:hover { background: var(--btn-bg-hover); }
  .btn:active { transform: translateY(1px); }           /* respuesta inmediata al toque */

  .btn--primary {
    --btn-bg: var(--accent);
    --btn-fg: var(--on-accent);
    --btn-bd: var(--accent);
    --btn-bg-hover: var(--accent-hover);
  }
  .btn--primary:hover { border-color: var(--accent-hover); }

  .btn--danger {
    --btn-bg: var(--danger);
    --btn-fg: var(--on-danger);
    --btn-bd: var(--danger);
    --btn-bg-hover: var(--danger-hover);
  }
  .btn--danger:hover { border-color: var(--danger-hover); }

  .btn--ghost {                                          /* discreto: sin relleno ni borde en reposo */
    --btn-bg: transparent;
    --btn-bd: transparent;
    --btn-fg: var(--accent-strong);
  }

  .btn--block { inline-size: 100%; }

  /* Desactivado: se lee igual, no responde. Se usa aria-disabled cuando debe conservar el foco. */
  .btn:disabled,
  .btn[aria-disabled="true"] {
    --btn-bg: var(--sunken);
    --btn-fg: var(--muted);
    --btn-bd: var(--border);
    cursor: not-allowed;
    transform: none;
  }
  .btn:disabled:hover, .btn[aria-disabled="true"]:hover { background: var(--sunken); }

  /* "Enviando…": bloqueado, con texto; ui.js pone aria-busy y el rótulo */
  .btn[aria-busy="true"] { cursor: progress; transform: none; }
  .btn[aria-busy="true"].btn--primary { --btn-bg: var(--accent-hover); --btn-bd: var(--accent-hover); --btn-fg: var(--on-accent); }
  .btn[aria-busy="true"].btn--danger { --btn-bg: var(--danger-hover); --btn-bd: var(--danger-hover); --btn-fg: var(--on-danger); }
  .btn[aria-busy="true"]:hover { background: var(--btn-bg); }
  .btn[aria-busy="true"]::before {
    content: "";
    inline-size: 1em; block-size: 1em;
    border: 2px solid currentColor;
    border-inline-end-color: transparent;
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
  }
  @keyframes spin { to { transform: rotate(360deg); } }

  /* Grupo de botones: separación >= 8 px; en 375 px se apilan a todo el ancho */
  .btn-group { display: flex; flex-wrap: wrap; gap: var(--gap-min) var(--space-3); }
  @media (max-width: 29.99rem) {
    .btn-group--stack { flex-direction: column; }
    .btn-group--stack > .btn { inline-size: 100%; }
  }

  /* ---------- Interruptor "Modo oscuro" (RF-229) ----------
     El estado se lee por la perilla (posicion), el icono (sol/luna) y aria-checked; el color solo la refuerza. */
  .theme-slot { display: flex; align-items: center; }
  .theme-switch {
    --track-w: 3.5rem;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-block-size: var(--target);
    padding-inline: var(--space-3);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-1);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--text-base);
    font-weight: 650;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color var(--transition);
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
  }
  .theme-switch:hover { background: var(--accent-bg); }
  .theme-switch__label { min-inline-size: 0; }
  .theme-switch__track {
    --knob: 1.5rem;
    flex: none;
    display: flex;
    align-items: center;
    inline-size: var(--track-w);
    block-size: 2rem;
    padding: 0.1875rem;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--sunken);
    transition: background-color var(--transition), border-color var(--transition);
  }
  .theme-switch__knob {
    display: grid;
    place-items: center;
    inline-size: var(--knob);
    block-size: var(--knob);
    border-radius: 50%;
    background: var(--surface);
    color: var(--muted);
    box-shadow: var(--shadow-1);
    transition: translate var(--transition);
  }
  .theme-switch__knob .icon { inline-size: 1rem; block-size: 1rem; }
  .theme-switch[aria-checked="true"] .theme-switch__track { background: var(--accent); border-color: var(--accent); }
  .theme-switch[aria-checked="true"] .theme-switch__knob { translate: calc(var(--track-w) - 2px - 0.375rem - var(--knob)) 0; color: var(--accent-strong); }
  [dir="rtl"] .theme-switch[aria-checked="true"] .theme-switch__knob { translate: calc(-1 * (var(--track-w) - 2px - 0.375rem - var(--knob))) 0; }

  /* ---------- Campo de formulario ---------- */
  .field { display: flex; flex-direction: column; gap: var(--space-1); min-inline-size: 0; }
  .field__label { font-weight: 650; }
  .field__help { color: var(--muted); }
  .field__counter { margin: 0; }
  .field__counter[data-state="ok"] { color: var(--ok); }
  .field__error {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    color: var(--err);
    font-weight: 600;
  }
  .field__error .icon { margin-block-start: 0.15em; }
  .field__error[hidden] { display: none; }

  .input, .select, .textarea {
    inline-size: 100%;
    min-block-size: var(--target);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-strong);                /* >= 3:1 contra la superficie */
    border-radius: var(--radius-1);
    background: var(--surface);
    color: var(--text);
    font-size: var(--text-base);
    line-height: 1.4;
    transition: border-color var(--transition);
  }
  .textarea { min-block-size: calc(var(--target) * 2); }
  .select { padding-inline-end: var(--space-2); }
  .input:hover, .select:hover, .textarea:hover { border-color: var(--text); }
  .input:disabled, .select:disabled, .textarea:disabled {
    background: var(--sunken);
    color: var(--muted);
    border-color: var(--border);
    cursor: not-allowed;
  }
  .input[readonly] { background: var(--sunken); }
  .input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] {
    border-color: var(--err);
    box-shadow: inset 0 0 0 1px var(--err);
  }
  .field:has([aria-invalid="true"]) .field__label { color: var(--err); }

  /* Casilla y opción: la etiqueta entera es la zona de toque */
  .check {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-block-size: var(--target);
    cursor: pointer;
  }
  .check input {
    inline-size: 1.5rem; block-size: 1.5rem;
    flex: none;
    margin: 0;
    cursor: pointer;
  }
  .check:has(input:disabled) { color: var(--muted); cursor: not-allowed; }
  .check:has(input:disabled) input { cursor: not-allowed; }
  .check:has(input[aria-invalid="true"]) { color: var(--err); }
  .choice-group { display: flex; flex-direction: column; gap: var(--gap-min); }

  /* Resumen de errores del formulario: "Hay 2 datos por corregir" */
  .error-summary {
    padding: var(--space-4);
    border: 1px solid var(--err-bd);
    border-radius: var(--radius-2);
    background: var(--err-bg);
    color: var(--text);
  }
  .error-summary__title {
    display: flex; align-items: center; gap: var(--space-2);
    color: var(--err);
    font-size: var(--text-lg);
    font-weight: 650;
    margin: 0;
  }
  .error-summary ul { margin-block-start: var(--space-2); }
  .error-summary a {
    display: inline-block;
    padding-block: var(--space-1);
    color: var(--text);
  }

  /* ---------- Aviso persistente (borde completo, icono y título; sin franja lateral) ---------- */
  .alert {
    --alert-fg: var(--info);
    --alert-bg: var(--info-bg);
    --alert-bd: var(--info-bd);
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--alert-bd);
    border-radius: var(--radius-2);
    background: var(--alert-bg);
    color: var(--text);
  }
  .alert > .icon { color: var(--alert-fg); inline-size: 1.5rem; block-size: 1.5rem; }
  .alert__title { margin: 0; font-size: var(--text-lg); font-weight: 650; color: var(--alert-fg); line-height: 1.3; }
  .alert__body { grid-column: 2; margin: 0; }
  .alert__body > * + * { margin-block-start: var(--space-2); }
  .alert__actions { grid-column: 2; margin-block-start: var(--space-2); }
  .alert--success { --alert-fg: var(--ok); --alert-bg: var(--ok-bg); --alert-bd: var(--ok-bd); }
  .alert--warning { --alert-fg: var(--warn); --alert-bg: var(--warn-bg); --alert-bd: var(--warn-bd); }
  .alert--error { --alert-fg: var(--err); --alert-bg: var(--err-bg); --alert-bd: var(--err-bd); }

  /* ---------- Cinta de estado (barra completa: "Sin conexión", "Su sesión va a expirar") ---------- */
  .status-bar {
    --alert-fg: var(--warn); --alert-bg: var(--warn-bg); --alert-bd: var(--warn-bd);
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-3) var(--page-gutter, var(--space-4));
    border-block-end: 1px solid var(--alert-bd);
    background: var(--alert-bg);
    color: var(--text);
    font-weight: 600;
  }
  .status-bar > .icon { color: var(--alert-fg); margin-block-start: 0.2em; }
  .status-bar > :not(.icon) { grid-column: 2; }
  .status-bar > .icon + :not(.icon) { grid-column: 2; grid-row: 1; }
  .status-bar--error { --alert-fg: var(--err); --alert-bg: var(--err-bg); --alert-bd: var(--err-bd); }
  .status-bar--info { --alert-fg: var(--info); --alert-bg: var(--info-bg); --alert-bd: var(--info-bd); }

  /* ---------- Etiqueta de estado (insignia): icono + texto ---------- */
  .badge {
    --badge-fg: var(--muted);
    --badge-bg: var(--sunken);
    --badge-bd: var(--border-strong);
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0.125rem var(--space-2);
    border: 1px solid var(--badge-bd);
    border-radius: var(--radius-1);
    background: var(--badge-bg);
    color: var(--badge-fg);
    font-size: var(--text-base);
    font-weight: 650;
    line-height: 1.4;
    white-space: nowrap;
  }
  .badge .icon { inline-size: 1em; block-size: 1em; }
  .badge--success { --badge-fg: var(--ok); --badge-bg: var(--ok-bg); --badge-bd: var(--ok-bd); }
  .badge--warning { --badge-fg: var(--warn); --badge-bg: var(--warn-bg); --badge-bd: var(--warn-bd); }
  .badge--error { --badge-fg: var(--err); --badge-bg: var(--err-bg); --badge-bd: var(--err-bd); }
  .badge--info { --badge-fg: var(--info); --badge-bg: var(--info-bg); --badge-bd: var(--info-bd); }
  .badge--accent { --badge-fg: var(--accent-strong); --badge-bg: var(--accent-bg); --badge-bd: var(--accent); }

  /* ---------- Tabla densa con desplazamiento propio ---------- */
  .table-wrap {
    --shade: rgb(19 36 43 / 0.16);
    overflow: auto;
    max-inline-size: 100%;
    border: 1px solid var(--border);
    border-radius: var(--radius-2);
    background:                                           /* sombra de borde solo cuando hay más por desplazar */
      linear-gradient(to right, var(--surface) 30%, transparent) left / 2rem 100% no-repeat local,
      linear-gradient(to left, var(--surface) 30%, transparent) right / 2rem 100% no-repeat local,
      linear-gradient(to right, var(--shade), transparent) left / 0.75rem 100% no-repeat scroll,
      linear-gradient(to left, var(--shade), transparent) right / 0.75rem 100% no-repeat scroll,
      var(--surface);
    overscroll-behavior-x: contain;
  }
  :root[data-theme="dark"] .table-wrap { --shade: rgb(0 0 0 / 0.55); }
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .table-wrap { --shade: rgb(0 0 0 / 0.55); } }
  .table-wrap--tall { max-block-size: 22rem; }
  .table-wrap:focus-visible { outline-offset: -1px; }

  .table {
    inline-size: 100%;
    min-inline-size: 42rem;                               /* a 375 px desplaza dentro de su contenedor */
    font-size: var(--text-base);
  }
  .table caption {
    padding: var(--space-3) var(--space-4);
    text-align: start;
    font-weight: 650;
    caption-side: top;
  }
  .table th, .table td {
    padding: var(--space-3) var(--space-4);
    text-align: start;
    vertical-align: middle;
    border-block-end: 1px solid var(--border);
    block-size: 3.25rem;                                  /* fila >= 52 px */
  }
  .table thead th {
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
    background: var(--sunken);
    font-weight: 650;
    white-space: nowrap;
    border-block-end: 1px solid var(--border-strong);
  }
  .table tbody th { font-weight: 650; }
  .table tbody tr:last-child > * { border-block-end: 0; }
  .table tbody tr:hover > * { background: var(--accent-bg); }
  .table td.num, .table th.num { text-align: end; }

  /* ---------- Estados vacío, cargando y error (textos de RF-168) ---------- */
  .state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-6) var(--space-5);
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-2);
    background: var(--surface);
  }
  .state__title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-lg); font-weight: 650; margin: 0; }
  .state__text { color: var(--muted); margin: 0; }
  .state--error { border-style: solid; border-color: var(--err-bd); background: var(--err-bg); }
  .state--error .state__title { color: var(--err); }
  .state--error .state__text { color: var(--text); }
  .skeleton { display: grid; gap: var(--space-2); inline-size: 100%; }
  .skeleton__row { block-size: 1.25rem; border-radius: var(--radius-1); background: var(--sunken); }
  .skeleton__row:nth-child(2) { inline-size: 80%; }
  .skeleton__row:nth-child(3) { inline-size: 60%; }

  /* ---------- Diálogo modal (nativo <dialog>; ui.js añade foco atrapado y atajos) ---------- */
  .dialog {
    inline-size: min(36rem, calc(100% - 2 * var(--space-4)));
    max-block-size: calc(100dvh - 2 * var(--space-4));
    overflow: auto;
    padding: var(--space-5);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-2);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-2);
  }
  dialog.dialog { margin: auto; }
  dialog.dialog::backdrop { background: rgb(10 18 21 / 0.6); }
  dialog.dialog[open] { transition: opacity var(--transition), translate var(--transition); }
  @starting-style { dialog.dialog[open] { opacity: 0; translate: 0 0.5rem; } }
  .dialog__title { font-size: var(--text-xl); margin: 0; }
  .dialog__body { margin-block-start: var(--space-3); display: grid; gap: var(--space-3); }
  .dialog__body > * { margin: 0; }
  .dialog__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    justify-content: flex-end;
    margin-block-start: var(--space-5);
  }
  @media (max-width: 29.99rem) {
    .dialog__actions { flex-direction: column; }
    .dialog__actions > .btn { inline-size: 100%; }
  }
  .dialog__timer { font-size: var(--text-xl); font-weight: 650; }
  /* Vista fija del mismo diálogo para el inventario (no es modal) */
  .dialog--preview { box-shadow: var(--shadow-1); max-inline-size: 36rem; }

  /* ---------- Superficie neutra fija para logos y vistas previas (ambos temas) ---------- */
  .logo-surface {
    display: grid;
    place-items: center;
    min-block-size: 6rem;
    padding: var(--space-4);
    border: 1px solid var(--logo-border);
    border-radius: var(--radius-2);
    background: var(--logo-surface);
    color: #13242b;
  }

  /* Logos de marca (pie, encabezado, ingreso): un PNG transparente se ve SIN caja (sin fondo, borde, relleno ni radio).
     Solo en tema oscuro, una placa clara sutil y ajustada al logo para que no se pierdan las letras oscuras. */
  .logo-surface.credit__logo, .logo-surface.shell-brand__mark, .logo-surface.auth__logo {
    --logo-pad: 0px;
    display: inline-grid; inline-size: auto; block-size: auto; min-block-size: 0;
    padding: 0; border: 0; border-radius: 0; background: transparent;
  }
  :root[data-theme="dark"] .logo-surface.credit__logo, :root[data-theme="dark"] .logo-surface.shell-brand__mark, :root[data-theme="dark"] .logo-surface.auth__logo {
    --logo-pad: 0.125rem; padding: var(--logo-pad); border-radius: 0.375rem; background: var(--logo-surface);
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .logo-surface.credit__logo, :root:not([data-theme="light"]) .logo-surface.shell-brand__mark, :root:not([data-theme="light"]) .logo-surface.auth__logo {
      --logo-pad: 0.125rem; padding: var(--logo-pad); border-radius: 0.375rem; background: var(--logo-surface);
    }
  }

  /* ---------- Crédito del desarrollador (pie de todas las pantallas; T50, RF-23) ----------
     Jerarquía baja: color atenuado y sin peso; la letra no baja de la base (RNF-9), así que lo discreto lo da el color,
     el logo de 40 px y el aire. Los enlaces conservan su subrayado y el alto táctil. */
  .credit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-min) var(--space-5);
    color: var(--muted);
  }
  .credit__who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; min-inline-size: 0; }
  .credit__logo { flex: none; min-block-size: 0; display: inline-grid; padding: var(--space-1); border-radius: var(--radius-1); }
  .credit__logo img { block-size: var(--logo-credit-h); inline-size: auto; max-inline-size: var(--logo-credit-w); object-fit: contain; }   /* 40 px, hasta 160 px */
  .credit__links { display: flex; flex-wrap: wrap; gap: var(--gap-min) var(--space-4); margin: 0; margin-inline-start: calc(-1 * var(--space-1)); padding: 0; list-style: none; }
  .credit__links li { display: flex; margin: 0; }
  .credit__links a { display: inline-flex; align-items: center; justify-content: center; min-block-size: var(--target); min-inline-size: var(--target); padding-inline: var(--space-1); }
  .credit a[aria-current="page"] { color: var(--text); text-decoration-thickness: 0.14em; }
}

/* ---------- Ayuda "Crear acceso directo" (T94; RF-200, RF-201, RNF-16) ----------
   Dentro del diálogo informativo: dirección en bloque que se parte en líneas (nunca desplaza), botones de .btn (56 px), pasos en lista numerada. */
@layer components {
  .shortcut-help { display: grid; gap: var(--space-3); min-inline-size: 0; }
  .shortcut-help > * { margin: 0; }
  .shortcut-help__label { color: var(--muted); font-weight: 600; }
  .shortcut-help__url {
    display: block;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-1);
    background: var(--sunken);
    overflow-wrap: anywhere;
    word-break: break-all;
    user-select: all;
  }
  .shortcut-help__steps { margin: 0; display: grid; gap: var(--space-2); }
  .shortcut-help__steps > li + li { margin-block-start: 0; }
  .shortcut-help__notice, .shortcut-help__text, .shortcut-help__fail, .shortcut-help__status:not([hidden]) {
    display: flex; align-items: flex-start; gap: var(--space-2);
  }
  .shortcut-help__notice > .icon, .shortcut-help__text > .icon, .shortcut-help__fail > .icon { flex: none; margin-block-start: 0.2em; }
  .shortcut-help__fail[hidden] { display: none; }
  .shortcut-help__fail { color: var(--err); }
  .shortcut-help__status:focus-visible { outline-offset: 2px; }
}

/* ---- Reglas de la contraseña como lista que se va cumpliendo (RF-112) y pantalla "Cambiar contraseña" (T105, RF-114) ---- */
@layer components {
  .rules { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
  .rule { display: flex; align-items: flex-start; gap: var(--space-2); color: var(--muted); }
  .rule .icon, .rule__ring { margin-block-start: 0.15em; }
  .rule__ring {
    flex: none;
    inline-size: 1.25em;
    block-size: 1.25em;
    border: 2px solid var(--border-strong);
    border-radius: 50%;
  }
  .rule--met { color: var(--ok); }

  .pwd-panel, .pwd-form { max-inline-size: 36rem; }
  .pwd-feedback:empty { display: none; }
  .pwd-note { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0; }
  .pwd-note > .icon { flex: none; margin-block-start: 0.2em; }
}
