/* ============================================================
   App base styles — overrides after Bootstrap, before scoped CSS.
   Design tokens live in tokens.css; this file handles only
   Blazor template resets and form validation states.
   ============================================================ */

/* Workspace page consumes the full canvas — no padding/max-width constraint.
   The workspace's internal sections (cinta / tabs / body) handle their own
   spacing for tighter control. High-specificity selector beats scoped CSS. */
body:has(.workspace) main.main-content > div.main-canvas {
    padding: 0;
    max-width: none;
}

/* Sala (S0.30, spec §7 "Diseno de pagina"): la pagina de Sala tambien consume el canvas completo
   (conversacion + mesa + tercera columna); mismo patron y misma especificidad que el Workspace. */
body:has(.sala) main.main-content > div.main-canvas {
    padding: 0;
    max-width: none;
}

/* Humo del 27-sep: la Sala mide lo que mide la ventana. .shell solo pedia min-height: 100vh, asi que con una
   conversacion o una mesa largas crecia la pagina entera (se iba el encabezado, la barra de seleccion de la mesa
   quedaba fuera de la vista) en vez de desplazarse cada columna por dentro. Con el alto fijo y min-height: 0 en la
   cadena, .sala (height: 100%) hereda el alto real y sus columnas hacen scroll propio. Solo desde 768 px (la
   barra lateral): en telefono el aviso de la app va ENCIMA de .shell y la barra de acciones es fija abajo, asi que
   ahi se queda como estaba (verificado en el humo, paso 16). */
@media (min-width: 768px) {
    body:has(.sala) .shell {
        height: 100vh;
        height: 100dvh;
    }

    body:has(.sala) main.main-content,
    body:has(.sala) main.main-content > div.main-canvas {
        min-height: 0;
    }
}

/* ────────────────────────────────────────────────────────────────
   Main-bar slot styles — week pill + primary action button
   rendered by Workspace.razor into MainLayout's PageHeaderLeft/Right slots.
   Defined globally because Blazor scoped CSS won't apply across the
   page→layout RenderFragment boundary.
   ──────────────────────────────────────────────────────────────── */
/* Selector de semana — estilo "naked" (sin caja) ahora que vive en la fila de tabs,
   para que no parezca un 4o tab. El divisor/hairline lo pone .tabs-week (ViewTabs). */
.header-week-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    border: none;
    background: transparent;
    margin-left: 0;
}

.header-week-pill .week-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    background: transparent;
    color: var(--color-graphite-600);
    cursor: pointer;
    border-radius: 50%;
    transition: background-color 120ms ease, color 120ms ease;
}

.header-week-pill .week-nav:hover {
    background: var(--color-graphite-100);
    color: var(--color-graphite-900);
}

.header-week-pill .week-nav .msr { font-size: 18px; }

.header-week-pill .week-today {
    border: none;
    background: transparent;
    color: var(--color-graphite-800);
    font-family: var(--font-sans);
    font-size: 12px;
    font-weight: 500;
    padding: 3px 10px;
    border-radius: 12px;
    cursor: pointer;
    transition: background-color 120ms ease;
}

.header-week-pill .week-today:hover:not(:disabled) { background: var(--color-graphite-100); }
.header-week-pill .week-today:disabled { color: var(--color-graphite-400); cursor: default; }

.header-week-pill .week-label {
    font-family: var(--font-sans);
    font-size: 12px;
    color: var(--color-graphite-600);
    padding: 0 8px 0 4px;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

/* Jerarquia del label: "Sem N" en mono (dato tecnico), rango un punto mas tenue. */
.header-week-pill .week-label .wl-sem {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-graphite-700);
}

.header-week-pill .week-label .wl-range {
    color: var(--color-graphite-500);
}

.header-primary-action {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 32px;
    padding: 0 14px;
    background: var(--color-brass-700, #7A5F37);
    color: #ffffff;
    border: none;
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 120ms ease, transform 160ms ease-out;
    margin-right: 12px;
}

.header-primary-action:hover { background: var(--color-brass-800); }
.header-primary-action:active { transform: scale(0.97); }
.header-primary-action .msr { font-size: 18px; }

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem var(--color-brass-500);
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--color-success);
}

.invalid {
    outline: 1px solid var(--color-error);
}

.validation-message {
    color: var(--color-error);
}

/* Error boundary — panel sobrio (Graphite & Brass), reemplaza el rojo/amarillo
   default del template de Blazor. Acento rojo a la izquierda = senal de error. */
.blazor-error-boundary {
    background: var(--surface-elevated);
    border: 1px solid var(--border-default);
    border-left: 3px solid var(--color-error);
    border-radius: var(--radius-md);
    padding: 12px 16px;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.875rem;
    box-shadow: var(--shadow-sm);
}

.blazor-error-boundary::after {
    content: "Ocurrió un error.";
}

/* ============================================================
   Overlay de reconexion SignalR — Graphite & Brass.
   En .NET 9 Blazor exige declarar #components-reconnect-modal (no lo auto-inyecta);
   ver App.razor. Blazor alterna las clases .components-reconnect-* sobre el elemento.
   Overlay graphite sobrio, coherente con el splash de arranque "El membrete".
   Docs: learn.microsoft.com/aspnet/core/blazor/fundamentals/signalr
   ============================================================ */

#components-reconnect-modal {
    display: none;
}

/* Estados visibles: perdida, reintento, fallo, rechazo. "paused" (resume tras
   background) se queda en silencio a proposito: no es un error que mostrar. */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: var(--z-reconnect);
    background: rgba(20, 23, 31, 0.72);   /* graphite-900 scrim, lenguaje del splash */
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    animation: reconnect-scrim-in var(--dur-3) var(--ease-out-quint) both;
}

@keyframes reconnect-scrim-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.reconnect-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    min-width: 260px;
    max-width: 90vw;
    padding: 28px 32px;
    text-align: center;
    color: var(--text-on-dark);
    font-family: var(--font-sans);
    animation: reconnect-card-in var(--dur-4) var(--ease-out-quint) both;
}

@keyframes reconnect-card-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.reconnect-wordmark {
    font-family: var(--wordmark-family);
    font-weight: var(--wordmark-weight);
    letter-spacing: var(--wordmark-tracking);
    font-size: 1.5rem;
    line-height: 1;
    color: #ffffff;
}

/* Hairline brass bajo el wordmark — eco del login / main-bar */
.reconnect-wordmark::after {
    content: "";
    display: block;
    width: 40px;
    height: 2px;
    margin: 10px auto 0;
    background: linear-gradient(to right, var(--color-brass-600), transparent);
}

.reconnect-msg {
    display: none;   /* cada estado revela el suyo */
    margin: 0;
    max-width: 34ch;
    font-size: 0.9375rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.82);
}

#components-reconnect-modal.components-reconnect-show .reconnect-msg-active,
#components-reconnect-modal.components-reconnect-retrying .reconnect-msg-active {
    display: block;
}

#components-reconnect-modal.components-reconnect-failed .reconnect-msg-failed,
#components-reconnect-modal.components-reconnect-rejected .reconnect-msg-rejected {
    display: block;
}

/* Spinner: solo mientras reintenta (senal de actividad). Brass sobre aro tenue. */
.reconnect-spinner {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .reconnect-spinner,
#components-reconnect-modal.components-reconnect-retrying .reconnect-spinner {
    display: block;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.22);
    border-top-color: var(--color-brass-500);
    animation: reconnect-spin 700ms linear infinite;
}

@keyframes reconnect-spin {
    to { transform: rotate(360deg); }
}

/* Accion Recargar: solo en fallo/rechazo (en show/retrying Blazor reintenta solo). */
.reconnect-action {
    display: none;
    margin-top: 2px;
    padding: 8px 18px;
    border-radius: var(--radius-md);
    background: var(--color-brass-600);
    color: var(--color-graphite-900);
    font-weight: 600;
    font-size: 0.875rem;
    text-decoration: none;
    transition: background-color var(--dur-1) var(--ease-out-quint), transform var(--dur-1) var(--ease-out-quint);
}

#components-reconnect-modal.components-reconnect-failed .reconnect-action,
#components-reconnect-modal.components-reconnect-rejected .reconnect-action {
    display: inline-block;
}

.reconnect-action:hover {
    background: var(--color-brass-500);
}

.reconnect-action:active {
    transform: scale(0.97);   /* el boton oye el tap */
}

@media (prefers-reduced-motion: reduce) {
    #components-reconnect-modal.components-reconnect-show,
    #components-reconnect-modal.components-reconnect-retrying,
    #components-reconnect-modal.components-reconnect-failed,
    #components-reconnect-modal.components-reconnect-rejected,
    .reconnect-card {
        animation: none;
    }
    .reconnect-spinner {
        animation: none;   /* el aro brass sigue marcando estado sin girar */
    }
}
