/* =============================================================================
   ID Services · Base y componentes compartidos
   Los mismos componentes en landings y panel. Ver docs/04-DESIGN-SYSTEM.md §4.
   ============================================================================= */

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

* { margin: 0; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
}

img, svg, video { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--text);
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); letter-spacing: -0.01em; }

p { text-wrap: pretty; }

a { color: var(--accent-strong); text-decoration: none; }
a:hover { text-decoration: underline; }

ul, ol { padding-left: 1.25rem; }

/* Foco visible SIEMPRE. Quitarlo rompe la navegación por teclado. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

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

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

/* Salto al contenido: aparece solo al tabular. */
.skip-link {
    position: absolute; left: -9999px; top: var(--space-2);
    background: var(--accent); color: var(--accent-contrast);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-sm); z-index: 100;
}
.skip-link:focus { left: var(--space-4); }

/* =============================================================================
   Layout
   ============================================================================= */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-6);
}

.container--sm { max-width: var(--container-sm); }

.stack > * + * { margin-top: var(--space-4); }
.stack-lg > * + * { margin-top: var(--space-8); }

.row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }

.grid { display: grid; gap: var(--space-6); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

/* Exactamente dos columnas, no "las que quepan".
   `auto-fit` está bien para tarjetas homogéneas, pero con CUATRO elementos
   mete tres arriba y deja uno solo abajo, que se lee como un error. Con dos
   fijas, cuatro apps caen en dos filas parejas. */
.grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 720px) {
    .grid--pair { grid-template-columns: 1fr; }
}

/* Selector de apps (landing y panel): con un número de apps que no es
   múltiplo parejo de la columna —hoy 5— una grilla fija deja la última fila
   pegada a la izquierda, que se lee como un error de layout. Flex con
   `justify-content:center` no tiene ese problema: la fila que sobra —sean 1 o
   2 tarjetas— se centra sola, sin tener que fijar "3 arriba, 2 abajo" a mano
   ni recalcular cada vez que se agregue o quite una app.

   El ancho de cada tarjeta es una FRACCIÓN EXACTA del contenedor —no un
   mínimo con `flex-grow`— a propósito: con un mínimo, una pantalla ancha de
   escritorio mete 4 en la primera fila y dejaba 1 sola abajo, que es
   exactamente el error que esto existe para evitar. Con la fracción exacta,
   nunca entra una cuarta tarjeta aunque sobre espacio. */
.grid--apps {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-6);
}
.grid--apps > * {
    flex: 0 1 calc((100% - 2 * var(--space-6)) / 3);
    min-width: 260px;
}

@media (max-width: 900px) {
    .grid--apps > * { flex-basis: calc((100% - var(--space-6)) / 2); }
}

@media (max-width: 560px) {
    .grid--apps > * { flex-basis: 100%; }
}

.grid--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

/* =============================================================================
   Tipografía auxiliar
   ============================================================================= */

.kicker {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--accent-strong);
}

.lead { font-size: var(--text-lg); color: var(--text-muted); }
.muted { color: var(--text-muted); }
.soft { color: var(--text-soft); }
.small { font-size: var(--text-sm); }
.tiny { font-size: var(--text-xs); }
.strong { font-weight: 600; }
.center { text-align: center; }
.mono { font-family: var(--font-mono); font-size: .875em; }

/* Números que no bailan al actualizarse. */
.tabular { font-variant-numeric: tabular-nums; }

/* =============================================================================
   Botones
   ============================================================================= */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1;
    padding: 0 var(--space-5, 1.25rem);
    height: 44px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transition), border-color var(--transition),
                transform var(--transition), box-shadow var(--transition);
}

.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

.btn--primary {
    background: var(--accent);
    color: var(--accent-contrast);
}
.btn--primary:hover { background: var(--accent-strong); }

.btn--secondary {
    background: transparent;
    border-color: var(--border-strong);
    color: var(--text);
}
.btn--secondary:hover { border-color: var(--accent); color: var(--accent-strong); }

.btn--ghost { background: transparent; color: var(--text-muted); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }

.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { filter: brightness(.92); }

.btn--lg { height: 52px; font-size: var(--text-base); padding-inline: var(--space-8); }
.btn--sm { height: 36px; font-size: var(--text-xs); padding-inline: var(--space-3); }
.btn--block { width: 100%; }

.btn[disabled], .btn--disabled {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

/* =============================================================================
   Tarjetas
   ============================================================================= */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: var(--space-6);
}

.card--flush { padding: 0; overflow: hidden; }
.card--soft { background: var(--surface-2); box-shadow: none; }

a.card, .card--link {
    display: block;
    color: inherit;
    transition: transform var(--transition), box-shadow var(--transition),
                border-color var(--transition);
}
a.card:hover, .card--link:hover {
    text-decoration: none;
    transform: translateY(-2px);
    box-shadow: var(--shadow);
    border-color: var(--accent);
}

.card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-6);
    border-bottom: 1px solid var(--border);
}

.card__title { font-size: var(--text-base); font-weight: 600; }
.card__body { padding: var(--space-6); }

/* Nota al pie de una tarjeta: el porqué de lo que se acaba de ver, sin
   competir con el contenido. Va después de una tabla, no antes. */
.card__footer {
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}

/* =============================================================================
   Insignias y estados
   ============================================================================= */

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1;
    padding: 5px 10px;
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text-muted);
    white-space: nowrap;
}

.badge--accent  { background: var(--accent-soft);  color: var(--accent-strong); }
.badge--success { background: var(--success-soft); color: var(--success); }
.badge--warning { background: var(--warning-soft); color: var(--warning); }
.badge--danger  { background: var(--danger-soft);  color: var(--danger); }
.badge--info    { background: var(--info-soft);    color: var(--info); }

/* El color nunca es el único portador de información: todo estado lleva texto
   (docs/04-DESIGN-SYSTEM.md §7). El punto es refuerzo, no el mensaje. */
.badge__dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}

/* =============================================================================
   Avatar
   ============================================================================= */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px; height: 40px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-weight: 700;
    font-size: var(--text-sm);
    flex-shrink: 0;
    overflow: hidden;
}

.avatar--sm { width: 32px; height: 32px; font-size: var(--text-xs); }
.avatar--lg { width: 64px; height: 64px; font-size: var(--text-lg); }

/* =============================================================================
   Formularios
   ============================================================================= */

.field { display: block; margin-bottom: var(--space-4); }

.field__label {
    display: block;
    font-size: var(--text-sm);
    font-weight: 600;
    margin-bottom: var(--space-2);
    color: var(--text);
}

.field__hint {
    display: block;
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-top: var(--space-2);
}

.field__error {
    display: block;
    font-size: var(--text-xs);
    color: var(--danger);
    margin-top: var(--space-2);
    font-weight: 500;
}

.input, .select, .textarea {
    width: 100%;
    height: 48px;
    padding: 0 var(--space-4);
    font-family: var(--font-body);
    font-size: var(--text-base);
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.textarea { height: auto; min-height: 120px; padding: var(--space-3) var(--space-4); resize: vertical; }

.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: var(--ring);
}

.input::placeholder, .textarea::placeholder { color: var(--text-soft); }
.input[aria-invalid="true"] { border-color: var(--danger); }

.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-4) center;
    padding-right: var(--space-8);
}

.checkbox { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; }
.checkbox input { width: 18px; height: 18px; margin-top: 2px; accent-color: var(--accent); flex-shrink: 0; }

/* =============================================================================
   Avisos
   ============================================================================= */

.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
    border-radius: var(--radius);
    border: 1px solid transparent;
    font-size: var(--text-sm);
    line-height: 1.5;
}

.alert--success { background: var(--success-soft); border-color: var(--success); color: #12602f; }
.alert--warning { background: var(--warning-soft); border-color: var(--warning); color: #8a4b00; }
.alert--error   { background: var(--danger-soft);  border-color: var(--danger);  color: #a01919; }
.alert--info    { background: var(--info-soft);    border-color: var(--info);    color: #17439c; }

[data-theme="dark"] .alert--success,
[data-theme="dark"] .alert--warning,
[data-theme="dark"] .alert--error,
[data-theme="dark"] .alert--info { color: var(--text); }

/* =============================================================================
   Estado vacío — nunca un texto solo (docs/04-DESIGN-SYSTEM.md §4)
   ============================================================================= */

.empty {
    text-align: center;
    padding: var(--space-12) var(--space-6);
    color: var(--text-muted);
}

.empty__icon {
    width: 56px; height: 56px;
    margin: 0 auto var(--space-4);
    display: grid; place-items: center;
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-soft);
}

.empty__title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--text-lg);
    color: var(--text);
    margin-bottom: var(--space-2);
}

/* =============================================================================
   Tablas
   ============================================================================= */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.table th {
    text-align: left;
    font-weight: 600;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.table td {
    padding: var(--space-4);
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }

/* =============================================================================
   Marca
   ============================================================================= */

.brandmark {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
}

.brandmark:hover { text-decoration: none; }

.brandmark__glyph {
    width: 36px; height: 36px;
    border-radius: 10px;
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--accent), var(--accent-strong));
    color: #fff;
    font-size: var(--text-sm);
    font-weight: 800;
    letter-spacing: -0.03em;
    flex-shrink: 0;
}

/* Insignia con el logo oficial en vez del glifo genérico.
   Fondo blanco fijo, no --surface: el emblema trae líneas negras (el
   estetoscopio de My Nurse, el escudo de Mechanical FIX) que se pierden
   sobre un fondo oscuro. El chip blanco garantiza legibilidad sin
   importar el tema, igual que un ícono de app en la tienda. */
.brandmark__glyph--logo {
    background: #FFFFFF;
    border: 1px solid var(--border);
    padding: 5px;
}

.brandmark__glyph--logo img { width: 100%; height: 100%; object-fit: contain; }

/* Sello de pertenencia. Es el ÚNICO elemento con color fijo en las cinco
   marcas: índigo de ID Services, pase lo que pase con el acento local. */
.ecosystem-seal {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    font-weight: 600;
    color: #4F6BED;
}

.ecosystem-seal::before {
    content: '';
    width: 8px; height: 8px;
    background: #4F6BED;
    transform: rotate(45deg);
    border-radius: 2px;
}

/* =============================================================================
   Utilidades
   ============================================================================= */

/* =============================================================================
   Formularios largos y acciones de tarjeta
   =============================================================================
   Se agregaron el 2026-08-31 con la pantalla de pasarelas, que fue la primera
   con formularios de más de cuatro campos y con acciones de riesgo separadas
   del guardado. Están aquí y no en panel.css porque no tienen nada de panel:
   cualquier formulario largo los va a querer.
   ============================================================================= */

/* Rejilla de campos.
   `.field` trae su propio `margin-bottom` para los formularios en columna.
   Dentro de una rejilla con `gap`, ese margen se SUMA al gap y las filas
   quedan separadas de más y de forma desigual — que es exactamente cómo se
   veía la pantalla de pasarelas antes de esto. Aquí se anula. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-4) var(--space-6);
    align-items: start;
}

.form-grid .field { margin-bottom: 0; }

/* Un campo que debe ocupar la fila completa (una URL larga, un textarea). */
.form-grid .field--wide { grid-column: 1 / -1; }

/* Barra de acciones al pie de una tarjeta.
   La línea superior no es adorno: separa «guardar lo que escribí» de las
   acciones que cambian el estado del sistema (probar, encender, pasar a live).
   Sin ella los botones flotan y se leen como si fueran todos lo mismo. */
.card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

/* Empuja lo que siga hasta la derecha: la acción destructiva lejos del resto,
   para que no se aprete por inercia. */
.card__actions .push { margin-left: auto; }

/* Casilla con etiqueta y explicación debajo. */
.field--check {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    cursor: pointer;
    margin-bottom: 0;
}

.field--check input {
    width: 18px;
    height: 18px;
    margin-top: 3px;
    accent-color: var(--accent);
    flex-shrink: 0;
}

/* Campo compacto: para tablas editables, donde el alto normal de 48px hace
   que una tabla de cinco renglones no quepa en pantalla. */
.input--sm { height: 38px; font-size: var(--text-sm); padding-inline: var(--space-3); }

/* Un valor literal que hay que copiar tal cual: una URL de webhook, un id.
   Sin fondo se confunde con el texto de alrededor, y estos son justo los
   valores en los que un carácter de más rompe la integración. */
code {
    font-family: var(--font-mono);
    font-size: .875em;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: .1em .4em;
    word-break: break-all;
}

/* Bloque para copiar: la URL sola, en su renglón, seleccionable de un golpe. */
.copyable {
    display: block;
    width: 100%;
    padding: var(--space-3) var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    color: var(--text);
    word-break: break-all;
    user-select: all;
}

.divider { height: 1px; background: var(--border); border: 0; margin: var(--space-6) 0; }
.hide { display: none !important; }

@media (max-width: 768px) {
    .hide-mobile { display: none !important; }
    :root { --text-display: 2rem; --text-h1: 1.625rem; --text-h2: 1.25rem; }
    .container { padding-inline: var(--space-4); }
}

@media (min-width: 769px) {
    .hide-desktop { display: none !important; }
}
