#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

:root {
    font-size: var(--rz-root-font-size);
}

body {
    font-family: var(--rz-text-font-family);
    color: var(--rz-text-color);
    font-size: var(--rz-body-font-size);
    line-height: var(--rz-body-line-height);
    background-color: var(--rz-body-background-color);
}

.rz-body {
    --rz-body-padding: 0;
}

/* Cuando el sidebar está colapsado (data-attribute puesto en <html> por
   window.setSidebar(), llamado desde MainLayout.razor.cs al togglear),
   forzamos:
   - el body a margin-left/padding-left 0 + ancho completo, anulando cualquier
     residuo del var(--rz-sidebar-width) que Radzen v10 no libere al togglear.
   - el sidebar a width 0 + sin padding/border para que no ocupe espacio
     en el layout flex aunque siga existiendo en el DOM (Radzen necesita
     el nodo para trackear el bind de Expanded).

   Usamos el atributo en <html> en vez de class en RadzenLayout porque
   RadzenLayout v10 NO propaga atributos arbitrarios al root del DOM,
   entonces los selectores .end2-sidebar-closed nunca matcheaban nada.
   !important para vencer la especificidad alta de las reglas internas
   de Radzen. */
html[data-sidebar="closed"] .rz-body {
    margin-left: 0 !important;
    padding-left: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
}
html[data-sidebar="closed"] .rz-sidebar {
    width: 0 !important;
    min-width: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    overflow: hidden !important;
}

/* Force los layout containers principales (Stack y Row) dentro del body a
   ocupar el 100% del padre. Radzen v10 los deja con width:auto y el stretch
   del flex no siempre aplica cuando los hijos tienen contenido intrínseco
   menor — el resultado son títulos y grids encogidos a su ancho natural en
   monitores grandes, dejando bandas vacías a la derecha (y a la izquierda
   cuando el sidebar se colapsa). Forzar width:100% + align-items:stretch
   garantiza que todo el contenido aproveche el ancho disponible.
   Scope: solo dentro de .rz-body para no romper layouts de diálogos o
   componentes con anchos intencionalmente pequeños. */
.rz-body .rz-stack {
    width: 100%;
    align-items: stretch;
}
.rz-body .rz-stack > .rz-row,
.rz-body .rz-row {
    width: 100%;
}

a {
    color: var(--rz-link-color);
}

a:hover,
a:focus {
    color: var(--rz-link-hover-color);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: #1b6ec2;
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Loading");
}

/* === Global UI tweaks ============================================== */

/* Tipografía global: stack del SO (más nítida que Roboto default en Windows).
   Segoe UI Variable Text en Win11, Segoe UI en Win10, -apple-system en macOS,
   system-ui como genérico. No hace falta cargar fuente externa. */
:root {
    --rz-text-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", system-ui, "Helvetica Neue", Arial, sans-serif;
}

/* Borde delicado en todos los RadzenDataGrid (visible en ot_1.png). */
.rz-data-grid {
    border: 1px solid rgba(0, 0, 0, 0.25) !important;
    border-radius: 4px;
}

/* Layout helper para tener toolbar de acciones a la derecha sobre la fila del
   pager (mismo renglón, lado opuesto — ver ot_5.png).
   Combinarlo con PagerPosition="PagerPosition.TopAndBottom" en el RadzenDataGrid.
   El grid se envuelve en .grid-scroll-inner para permitir scroll horizontal
   cuando hay muchas columnas (típico de child grids jerárquicos). El overlay
   queda ANCLADO al wrapper outer (.grid-with-overlay) que mantiene width 100%
   del espacio disponible — así los botones quedan visibles a la derecha aunque
   el usuario scrollee horizontalmente dentro del grid. */
.grid-with-overlay {
    position: relative;
    width: 100%;
}
.grid-actions-overlay {
    position: absolute;
    top: 0.35rem;
    right: 0.5rem;
    z-index: 10;
}
/* Variante "izquierda" del overlay de acciones — coloca los botones (Add +
   Menu) después de los 4 botones de navegación del pager top (|< < > >|).
   Pegado al borde izquierdo del grid; aunque el operador scrollee
   horizontalmente, los botones siguen visibles. Usado en TODOS los grids
   del proyecto (top-level y nested).

   Offset 12rem:
     - 4 botones nav × ~2rem cada uno = 8rem
     - Padding del pager-pages (~1rem)
     - Respiro visual entre el >| y el +: ~3rem
   Total ≈ 12rem. Es brittle si Radzen cambia el ancho del botón pero usar
   rem hace que escale con el A-/A+ del header. Si el tema apreta más los
   botones, podemos reducir; si los expande, aumentar. */
.grid-actions-overlay.grid-actions-left {
    left: 12rem;
    right: auto;
}
.grid-scroll-inner {
    overflow-x: auto;
    max-width: 100%;
}

/* Cuando .grid-with-overlay se renderiza DENTRO de un row expandido de otro
   RadzenDataGrid jerárquico (child grid), el TD del expand abarca todas las
   columnas del padre (potencialmente 2000+ px). Sin constrain, el wrapper del
   child hereda ese ancho y empuja el toolbar overlay off-screen. position:sticky
   con left:1rem + width viewport-relativa ancla el wrapper al área visible
   sin importar lo ancho que sea el TD padre.

   El buffer depende del estado del sidebar (clase puesta en RadzenLayout
   por MainLayout.razor.cs). Con sidebar abierto: ~280px sidebar + 60px
   padding = 340px. Con sidebar cerrado: solo el padding del card = 80px. */
.rz-expanded-row-template .grid-with-overlay {
    position: sticky;
    left: 1rem;
}
html[data-sidebar="open"] .rz-expanded-row-template .grid-with-overlay,
.end2-sidebar-open .rz-expanded-row-template .grid-with-overlay {
    width: calc(100vw - 340px);
    max-width: calc(100vw - 340px);
}
html[data-sidebar="closed"] .rz-expanded-row-template .grid-with-overlay,
.end2-sidebar-closed .rz-expanded-row-template .grid-with-overlay {
    width: calc(100vw - 80px);
    max-width: calc(100vw - 80px);
}
/* Las clases reales de Radzen son .rz-pager (NO .rz-paginator). Verificado
   inspeccionando el DOM real con devtools en localhost:5501/ots. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-summary,
.grid-with-overlay .rz-pager:first-of-type .rz-dropdown,
.grid-with-overlay .rz-pager:first-of-type .rz-pagesize-text {
    display: none !important;
}
/* Dentro de .rz-pager-pages hay <li.rz-pager-item> con un <button> cada uno;
   el botón puede ser first/prev/page(numerico)/next/last. Escondemos solo
   los LIs cuyo botón sea .rz-pager-page (los numéricos), dejando first/prev/next/last. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-pages li:has(.rz-pager-page) {
    display: none !important;
}
/* Por default Radzen pone márgenes inline (margin-right ~422px en prev y
   margin-left ~422px en next) para empujar next/last al borde derecho del UL.
   En el pager TOP eso superpone next/last con los botones overlay (+ +☐ ≡▼).
   Forzamos margin:0 en los LIs para anular ese gap; el flex con gap:8px de la
   UL se encarga del espaciado normal. justify-content:flex-start por las dudas. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-pages {
    justify-content: flex-start !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-pages li.rz-pager-item {
    margin: 0 !important;
}
.grid-with-overlay .rz-pager:first-of-type {
    padding-right: 8px !important;
}

/* Match el ESTILO de los 4 nav buttons (|< < > >|) del pager top con los
   3 action buttons del EnhancedGridToolbar (RadzenButton Size=Small +
   Variant=Flat). El default de Radzen pinta los nav buttons en gris oscuro
   y altura grande; los action buttons son flat-primary (teal/azul claro),
   compactos. Esta regla los nivela visualmente para que se vean como una
   barra de íconos continua [|<][<][>][>|][+][≡].

   Solo aplica al pager TOP (:first-of-type) — el pager bottom queda con
   su estilo default porque tiene numéricos + dropdown de page-size y se
   ve mejor con los botones más amplios. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-paginator-element,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-first,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-prev,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-next,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-last {
    width: 2rem !important;
    min-width: 2rem !important;
    height: 2rem !important;
    min-height: 2rem !important;
    padding: 0 !important;
    border-radius: 4px !important;
    background-color: var(--rz-button-flat-primary-background-color, rgba(56, 178, 172, 0.15)) !important;
    color: var(--rz-button-flat-primary-color, #38B2AC) !important;
    border: none !important;
    box-shadow: none !important;
    margin: 0 2px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button:hover:not(:disabled),
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-paginator-element:hover:not(:disabled) {
    background-color: var(--rz-button-flat-primary-hover-background-color, rgba(56, 178, 172, 0.28)) !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button:disabled,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-paginator-element:disabled {
    opacity: 0.45 !important;
    cursor: not-allowed !important;
}
/* Iconos de los nav buttons (heredados de Material Icons / SVG) — mismo
   tamaño que los del EnhancedGridToolbar. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button .rzi,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button i,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item button svg {
    font-size: 1rem !important;
    width: 1rem !important;
    height: 1rem !important;
}

/* Por default Radzen pinta el contenido de los nav buttons como caracteres
   (|<, <, >, >|) en una fuente alternativa que no matchea el set de Material
   Icons usado en los action buttons (+, +☐, ≡). Para unificar, escondemos el
   contenido nativo con font-size:0 + color:transparent, y inyectamos los
   Material Icons via ::before sobre el button entero.

   Selectores incluyen tanto el <button> como cualquier <a> que Radzen pueda
   usar — algunas versiones del componente cambian el tag. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-first,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-prev,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-next,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-last,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-pager-first,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-pager-prev,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-pager-next,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-item .rz-pager-last {
    font-size: 0 !important;
    color: transparent !important;
    position: relative !important;
}
/* Esconde también el <span>/<i> interno si el char está adentro. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-first > *,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-prev > *,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-next > *,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-last > * {
    display: none !important;
}
/* Material Icon inyectado por ::before — uno por dirección. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-first::before {
    content: "first_page" !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-prev::before {
    content: "chevron_left" !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-next::before {
    content: "chevron_right" !important;
}
.grid-with-overlay .rz-pager:first-of-type .rz-pager-last::before {
    content: "last_page" !important;
}
/* Estilo común para los 4 ::before. Radzen 10.3.2 bundlea el icon set bajo el
   font-family EXACTO "Material Symbols" (sin "Outlined" en el nombre del
   family, aunque el archivo .woff2 se llame MaterialSymbolsOutlined.woff2).
   Verificado leyendo el @font-face del theme software-dark.css en el NuGet.
   Si en el futuro Radzen renombra el family, ajustar acá. */
.grid-with-overlay .rz-pager:first-of-type .rz-pager-first::before,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-prev::before,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-next::before,
.grid-with-overlay .rz-pager:first-of-type .rz-pager-last::before {
    font-family: 'Material Symbols', 'Material Symbols Outlined', 'Material Icons' !important;
    font-weight: normal !important;
    font-style: normal !important;
    font-size: 1.15rem !important;
    line-height: 1 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    color: var(--rz-button-flat-primary-color, #38B2AC) !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
    font-feature-settings: 'liga';
    position: absolute !important;
    inset: 0 !important;
    /* Cancela el font-size:0 / color:transparent que pusimos en el button
       padre (necesario para esconder los chars nativos). El ::before tiene
       su propio color/tamaño definidos arriba. */
    text-indent: 0 !important;
}

/* Scroll horizontal en la barra de solapas del row expandido de OT.
   Sin esto, las 13 solapas se rompen a multiples renglones cuando no entran
   en el ancho disponible. Scopeado a .ot-children-tabs para no afectar otros
   RadzenTabs (eg. el del ItemOtFormDialog que tiene solo 3 tabs).

   Truco: el ul .rz-tabview-nav crece a su contenido por default. Forzamos
   display:block para que respete el max-width:100% del padre y le metemos
   white-space:nowrap + overflow-x:auto al PADRE (.rz-tabview-nav-container
   o .ot-children-tabs como fallback). */
/* Wrapper anclado a viewport-relative cuando esta dentro de un row expandido
   del RadzenDataGrid padre (mismo razonamiento que .grid-with-overlay).
   Buffer ajustado al estado del sidebar para no desperdiciar espacio cuando
   el operador colapsa el menú. */
.rz-expanded-row-template .ot-children-tabs {
    position: sticky;
    left: 1rem;
}
html[data-sidebar="open"] .rz-expanded-row-template .ot-children-tabs,
.end2-sidebar-open .rz-expanded-row-template .ot-children-tabs {
    width: calc(100vw - 340px);
    max-width: calc(100vw - 340px);
}
html[data-sidebar="closed"] .rz-expanded-row-template .ot-children-tabs,
.end2-sidebar-closed .rz-expanded-row-template .ot-children-tabs {
    width: calc(100vw - 80px);
    max-width: calc(100vw - 80px);
}
/* El RadzenTabs por dentro no debe expandirse mas alla del wrapper. */
.ot-children-tabs > .rz-tabview {
    width: 100%;
    max-width: 100%;
}
/* SOLO la nav (lista de pestanias) scrollea horizontal. El contenido del tab
   activo queda con su propio scroll independiente. */
.ot-children-tabs .rz-tabview-nav {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden;
    scrollbar-width: thin;
}
.ot-children-tabs .rz-tabview-nav > li {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* === Filtro general en sidebar ====================================== */
/* Bloque que aparece entre el logo "END2" y el RadzenPanelMenu cuando hay
   al menos un filtro activo. Estilos compactos para que no robe verticales
   del menú principal y se integren con el tema actual del sidebar. */
.end-filter-bar {
    padding: 0.5rem 0.75rem;
    border-bottom: var(--rz-panel-menu-item-border);
    background: var(--rz-sidebar-background-color);
}
.end-filter-bar-title {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--rz-sidebar-color);
    opacity: 0.7;
    margin-bottom: 0.4rem;
}
.end-filter-chip {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.5rem;
    margin-bottom: 0.25rem;
    background: rgba(255,255,255,0.08);
    border-radius: 4px;
    color: var(--rz-sidebar-color);
    font-size: 0.8rem;
}
.end-filter-chip-x {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    border: none;
    background: rgba(255,255,255,0.12);
    color: var(--rz-sidebar-color);
    border-radius: 50%;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
}
.end-filter-chip-x:hover {
    background: rgba(220,53,69,0.55);
    color: #fff;
}
.end-filter-chip-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* === Modo lectura del modal Edit (acción Ver) ======================
   Cada RadzenCarouselItem envuelve su contenido en <fieldset disabled>
   cuando isReadOnly=true. Los botones de paginación del carousel quedan
   FUERA del fieldset, así que siguen funcionando.
   No reducimos opacidad ni cambiamos background — los valores tienen
   que verse claros y completos. Solo cambiamos el cursor a default
   para que el operador note que no puede editar. */
.end-readonly-fieldset[disabled] {
    cursor: default;
}
.end-readonly-fieldset[disabled] input,
.end-readonly-fieldset[disabled] textarea,
.end-readonly-fieldset[disabled] select,
.end-readonly-fieldset[disabled] .rz-textbox,
.end-readonly-fieldset[disabled] .rz-textarea,
.end-readonly-fieldset[disabled] .rz-numeric input,
.end-readonly-fieldset[disabled] .rz-dropdown,
.end-readonly-fieldset[disabled] .rz-datepicker {
    background-color: #fff !important;
    color: #333 !important;
    opacity: 1 !important;
    -webkit-text-fill-color: #333 !important; /* Safari muestra inputs disabled en gris */
}

/* === Pagina OtDetail (Hito 6 - Ver Maestro/Detalle) ===================
   Aesthetic: modern enterprise dashboard. Inter Tight (UI premium) +
   JetBrains Mono (metricas tecnicas). Paleta blanco/negro contraste alto
   con un solo accent saturado (electric blue). KPIs prominentes, cards
   con depth sutil, charts con peso visual. Hereda font-size raiz de
   MainLayout (A-/A+) — todas las dimensiones en rem. */
.ot-detail {
    --bg:           #FFFFFF;
    --surface:      #FFFFFF;
    --surface-2:    #F7F8FA;
    --surface-3:    #EFF2F6;
    --line:         #E4E7EC;
    --line-strong:  #CFD3DA;
    --text:         #0B0F19;
    --text-2:       #4B5363;
    --text-3:       #8089A0;
    --accent:       #2563EB;       /* electric blue */
    --accent-soft:  #DBEAFE;
    --accent-dark:  #1E40AF;
    --success:      #059669;
    --success-soft: #D1FAE5;
    --danger:       #DC2626;
    --danger-soft:  #FEE2E2;
    --warning:      #D97706;
    --warning-soft: #FEF3C7;
    --muted:        #6B7280;
    --muted-soft:   #F3F4F6;
    --shadow-sm:    0 1px 2px rgba(11, 15, 25, 0.04), 0 0 0 1px rgba(11, 15, 25, 0.06);
    --shadow:       0 1px 3px rgba(11, 15, 25, 0.06), 0 1px 2px rgba(11, 15, 25, 0.04), 0 0 0 1px rgba(11, 15, 25, 0.05);

    max-width: 80rem;
    margin: 0 auto;
    padding: 1.5rem 1.75rem 4rem;
    color: var(--text);
    background: var(--bg);
    font-family: 'Inter Tight', system-ui, -apple-system, sans-serif;
    font-size: 0.9375rem;
    line-height: 1.55;
    font-feature-settings: "cv11", "ss03", "cv02";
}
.ot-detail-loading {
    text-align: center;
    padding: 6rem 1rem;
    color: var(--text-3);
}

/* === Toolbar ================================================== */
.ot-detail-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0 1.5rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.72rem;
    color: var(--text-3);
}
.ot-detail-toolbar > span { letter-spacing: 0.01em; }

/* === Edit mode badge + actions (D2) ============================ */
.ot-edit-badge {
    background: #f59f00;
    color: #fff;
    padding: 0.2rem 0.6rem;
    border-radius: 0.25rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    box-shadow: 0 0 0 2px rgba(245, 159, 0, 0.18);
}
.ot-header-edit-actions {
    margin-top: 1rem;
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}
/* Pencil icon embebido en summaries — solo visible en modo edición.
   Cliqueable sin gatillar el toggle del <details> gracias a stopPropagation
   en el Razor. Hover-state ámbar para llamar la atención. */
.ot-edit-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 0.4rem;
    background: rgba(245, 159, 0, 0.12);
    color: #f59f00;
    cursor: pointer;
    margin-left: 0.5rem;
    transition: background 0.15s, transform 0.15s;
    flex-shrink: 0;
}
.ot-edit-pencil:hover {
    background: rgba(245, 159, 0, 0.28);
    transform: scale(1.06);
}
.ot-edit-pencil .rzi { font-size: 1.05rem; }

/* Variante destructiva del pencil de summary — mismo tamaño que el de edit
   pero en rojo. Usado para cascade-delete del ItemOt. */
.ot-delete-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 0.4rem;
    background: rgba(220, 53, 69, 0.12);
    color: #dc3545;
    cursor: pointer;
    margin-left: 0.4rem;
    transition: background 0.15s, transform 0.15s;
    flex-shrink: 0;
}
.ot-delete-pencil:hover {
    background: rgba(220, 53, 69, 0.28);
    transform: scale(1.06);
}
.ot-delete-pencil .rzi { font-size: 1.05rem; }

/* Variante "agregar" del pencil de summary — verde (acción positiva).
   Usado para Add de OT children en master/detail. */
.ot-add-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 0.4rem;
    background: rgba(40, 167, 69, 0.14);
    color: #28a745;
    cursor: pointer;
    margin-left: 0.5rem;
    transition: background 0.15s, transform 0.15s;
    flex-shrink: 0;
}
.ot-add-pencil:hover {
    background: rgba(40, 167, 69, 0.30);
    transform: scale(1.06);
}
.ot-add-pencil .rzi { font-size: 1.1rem; font-weight: 700; }

/* Pencil de fila — versión compacta para tablas .data-table y bloques IV.
   Más chico que el pencil de summary para no inflar el alto de la fila. */
.ot-row-edit-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 0.3rem;
    background: rgba(245, 159, 0, 0.10);
    color: #f59f00;
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
}
.ot-row-edit-pencil:hover {
    background: rgba(245, 159, 0, 0.26);
    transform: scale(1.08);
}
.ot-row-edit-pencil .rzi { font-size: 0.95rem; }

/* Trash de fila — mismo tamaño que el pencil pero en rojo (acción destructiva).
   Va siempre al lado del pencil de edición; el gap horizontal lo da .edit-col. */
.ot-row-delete-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 0.3rem;
    background: rgba(220, 53, 69, 0.10);
    color: #dc3545;
    cursor: pointer;
    margin-left: 0.3rem;
    transition: background 0.15s, transform 0.15s;
}
.ot-row-delete-pencil:hover {
    background: rgba(220, 53, 69, 0.26);
    transform: scale(1.08);
}
.ot-row-delete-pencil .rzi { font-size: 0.95rem; }

/* Add chico para sub-sub-section summaries (verde). Mismo tamaño y forma que
   ot-row-edit-pencil / ot-row-delete-pencil. */
.ot-row-add-pencil {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 0.3rem;
    background: rgba(40, 167, 69, 0.12);
    color: #28a745;
    cursor: pointer;
    margin-left: 0.5rem;
    transition: background 0.15s, transform 0.15s;
}
.ot-row-add-pencil:hover {
    background: rgba(40, 167, 69, 0.28);
    transform: scale(1.08);
}
.ot-row-add-pencil .rzi { font-size: 0.95rem; }

/* Columna trailing "edit/delete" en .data-table — angosta para los 2 iconos. */
.data-table th.edit-col, .data-table td.edit-col {
    width: 4rem;
    text-align: center;
    padding-left: 0.25rem;
    padding-right: 0.5rem;
    white-space: nowrap;
}
/* Wrapper para los iconos al tope de un bloque IV (kv-grid). */
.iv-edit-row {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.3rem;
    margin: 0.4rem 0 0.2rem;
}

/* === Header: hero block ====================================== */
.ot-detail-header {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 0.75rem;
    padding: 1.5rem 1.75rem;
    margin-bottom: 1.5rem;
    box-shadow: var(--shadow);
    position: relative;
    overflow: hidden;
}
.ot-detail-header::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 0.25rem;
    background: linear-gradient(90deg, var(--accent) 0%, var(--accent-dark) 100%);
}
.ot-header-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 2rem;
    margin-bottom: 1.25rem;
}
.ot-header-doc-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--accent);
    margin-bottom: 0.5rem;
    font-weight: 600;
}
.ot-detail-header h1 {
    font-family: 'Inter Tight', system-ui, sans-serif;
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.035em;
    color: var(--text);
    margin: 0;
}
.ot-header-stamp {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--success);
    background: var(--success-soft);
    border-radius: 0.5rem;
    padding: 0.5rem 0.85rem;
    line-height: 1.2;
    font-weight: 600;
    border: 1px solid rgba(5, 150, 105, 0.2);
    flex-shrink: 0;
    transform: none;
}
.ot-header-stamp.in-progress {
    color: var(--warning);
    background: var(--warning-soft);
    border-color: rgba(217, 119, 6, 0.2);
}
.ot-header-stamp .stamp-line {
    font-size: 0.62rem;
    color: var(--text-3);
    font-weight: 500;
    letter-spacing: 0.06em;
}

.ot-header-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 1rem 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
}
.ot-header-grid > div {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.ot-header-grid strong {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-3);
    font-weight: 500;
}
.ot-header-grid > div > :not(strong) {
    font-size: 0.95rem;
    color: var(--text);
    font-weight: 600;
}

/* === Sections principales =================================== */
.ot-detail-section {
    border: 1px solid var(--line);
    border-radius: 0.75rem;
    background: var(--surface);
    margin-bottom: 1rem;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    counter-increment: ot-section;
}
.ot-detail-section > summary {
    padding: 1.1rem 1.25rem;
    cursor: pointer;
    color: var(--text);
    font-weight: 600;
    font-size: 1.0625rem;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    transition: background 0.12s;
    user-select: none;
}
.ot-detail-section > summary:hover { background: var(--surface-2); }
.ot-detail-section > summary::-webkit-details-marker { display: none; }
.ot-detail-section > summary::before {
    content: counter(ot-section, decimal-leading-zero);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 0.375rem;
    padding: 0.3rem 0.55rem;
    font-weight: 600;
    flex-shrink: 0;
    transform: none !important;
}
.ot-detail-section > summary::after {
    content: "+";
    margin-left: auto;
    font-family: 'JetBrains Mono', monospace;
    font-size: 1.25rem;
    color: var(--text-3);
    font-weight: 300;
    width: 1.5rem;
    height: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.375rem;
    background: var(--surface-2);
}
.ot-detail-section[open] > summary::after {
    content: "−";
    background: var(--text);
    color: var(--surface);
}
.ot-detail-section > :not(summary) {
    padding: 0 1.25rem 1.25rem;
    border-top: 1px solid var(--line);
    padding-top: 1.25rem;
}

/* === Subsection (items, recepciones) ======================== */
.ot-detail-subsection {
    border: 1px solid var(--line);
    border-radius: 0.5rem;
    background: var(--surface-2);
    margin: 0.85rem 0;
    overflow: hidden;
}
.ot-detail-subsection > summary {
    padding: 0.85rem 1rem;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.ot-detail-subsection > summary:hover { background: var(--surface-3); }
.ot-detail-subsection > summary::-webkit-details-marker { display: none; }
.ot-detail-subsection > summary::before {
    content: "▸ ";
    color: var(--text-3);
    font-weight: 400;
    transition: transform 0.15s;
}
.ot-detail-subsection[open] > summary::before { content: "▾ "; }
.ot-detail-subsection > :not(summary) {
    padding: 1rem;
    background: var(--surface);
    border-top: 1px solid var(--line);
}

/* === Sub-sub (los 7 tabs internos del Item) ================= */
.ot-detail-subsub {
    border: 1px solid var(--line);
    border-radius: 0.4rem;
    margin: 0.6rem 0;
    background: var(--surface);
    overflow: hidden;
}
.ot-detail-subsub > summary {
    padding: 0.55rem 0.85rem;
    cursor: pointer;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    list-style: none;
    background: var(--surface-2);
}
.ot-detail-subsub > summary:hover { background: var(--surface-3); }
.ot-detail-subsub > summary::-webkit-details-marker { display: none; }
.ot-detail-subsub > summary::before { content: "▸ "; color: var(--text-3); }
.ot-detail-subsub[open] > summary::before { content: "▾ "; }
.ot-detail-subsub > :not(summary) {
    padding: 0.85rem;
    border-top: 1px solid var(--line);
}

/* === Key/value grid ========================================= */
.kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.85rem 1.5rem;
    font-size: 0.875rem;
}
.kv-grid > div {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    line-height: 1.4;
}
.kv-grid .lbl {
    color: var(--text-3);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 500;
}
.kv-grid > div > :not(.lbl) {
    color: var(--text);
    font-weight: 500;
}

/* === Notas largas (callout style) =========================== */
.long-notes {
    background: var(--accent-soft);
    border-left: 3px solid var(--accent);
    border-radius: 0 0.4rem 0.4rem 0;
    padding: 0.7rem 1rem;
    margin: 0.85rem 0;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text);
}
.long-notes strong {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent-dark);
    font-weight: 600;
    margin-right: 0.5rem;
    display: inline-block;
    margin-bottom: 0.2rem;
}

.empty {
    color: var(--text-3);
    font-style: italic;
    padding: 0.85rem 1rem;
    font-size: 0.9rem;
    text-align: center;
    background: var(--surface-2);
    border: 1px dashed var(--line);
    border-radius: 0.4rem;
}
.muted {
    color: var(--text-3);
    font-weight: 500;
    font-size: 0.85em;
    margin-left: 0.4rem;
}

/* === Data tables ============================================ */
.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin: 0.6rem 0;
    color: var(--text);
}
.data-table th {
    background: var(--surface-2);
    padding: 0.65rem 0.85rem;
    text-align: left;
    border-bottom: 1px solid var(--line);
    font-family: 'JetBrains Mono', monospace;
    font-weight: 600;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-2);
}
.data-table td {
    padding: 0.65rem 0.85rem;
    border-bottom: 1px solid var(--line);
    color: var(--text);
}
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--surface-2); }
.data-table { border: 1px solid var(--line); border-radius: 0.5rem; overflow: hidden; }

/* === Item de la OT — summary destacado en OtDetail ============
   El header del <details class="item-block"> antes era texto inline
   apagado; ahora es un banner con titulo grande, descripcion en negro
   legible al centro y badges/pencils empujados a la derecha. */
.item-block > summary.item-block-summary {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    flex-wrap: wrap;
    padding: 0.75rem 1rem;
    border-left: 4px solid var(--rz-primary, #0ea5e9);
    background: linear-gradient(90deg, rgba(14,165,233,0.10), rgba(14,165,233,0.02) 60%, transparent);
    border-radius: 4px;
    cursor: pointer;
}
.item-block > summary.item-block-summary .item-num {
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--rz-primary, #0ea5e9);
    letter-spacing: 0.01em;
}
.item-block > summary.item-block-summary .item-order {
    font-size: 0.78rem;
    color: #475569;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(148,163,184,0.18);
    padding: 0.1rem 0.45rem;
    border-radius: 4px;
}
.item-block > summary.item-block-summary .item-desc {
    flex: 1 1 auto;
    min-width: 200px;
    font-size: 0.95rem;
    color: #0f172a;
    font-weight: 600;
}
.item-block > summary.item-block-summary .apto-pill {
    margin-left: auto;
}

/* === Pills (apto / status) ================================== */
.apto-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    border: 1px solid;
    border-radius: 999px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    vertical-align: middle;
    line-height: 1.4;
}
.status-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    background: var(--success-soft);
    color: var(--success);
    margin-left: 0.4rem;
}

/* === Fotos ================================================== */
.fotos-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.85rem;
    margin: 0.85rem 0;
}
.foto-card {
    border: 1px solid var(--line);
    border-radius: 0.5rem;
    padding: 0.3rem;
    background: var(--surface);
    text-align: center;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.foto-card img {
    max-width: 14rem;
    max-height: 14rem;
    display: block;
    object-fit: contain;
    border-radius: 0.35rem;
}
.foto-card .foto-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-3);
    margin-top: 0.4rem;
    padding-bottom: 0.2rem;
    font-weight: 500;
}

/* === KPI Dashboard — premium tech dashboard ================== */
.kpi-dashboard {
    margin-bottom: 1.5rem;
    padding: 1.5rem;
    background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
    border: 1px solid var(--line);
    border-radius: 0.75rem;
    position: relative;
    overflow: hidden;
}
.kpi-dashboard::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 0.2rem;
    background: linear-gradient(90deg, var(--accent) 0%, var(--success) 50%, var(--accent-dark) 100%);
}
.kpi-section-title {
    margin: 0 0 1.5rem;
    font-family: 'Inter Tight', system-ui, sans-serif;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.025em;
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.kpi-section-title::before {
    content: "";
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 999px;
    background: var(--success);
    box-shadow: 0 0 0 0.2rem var(--success-soft);
    flex-shrink: 0;
}
.kpi-group {
    margin-bottom: 1.5rem;
}
.kpi-group:last-child { margin-bottom: 0; }
.kpi-group-title {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--text-3);
    margin-bottom: 0.85rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.kpi-group-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

.kpi-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.85rem;
}
.kpi-cards.gauges {
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}

.kpi-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 0.6rem;
    padding: 1rem 1.1rem;
    box-shadow: var(--shadow-sm);
    text-align: left;
    transition: transform 0.12s, box-shadow 0.12s;
}
.kpi-card:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow);
}
.kpi-value {
    font-family: 'Inter Tight', system-ui, sans-serif;
    font-size: 1.85rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}
.kpi-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-3);
    margin-top: 0.55rem;
    font-weight: 500;
}
.kpi-sublabel {
    font-size: 0.7rem;
    color: var(--text-3);
    font-family: 'JetBrains Mono', monospace;
    margin-top: 0.15rem;
}
.kpi-card.kpi-success { background: linear-gradient(135deg, var(--surface) 0%, var(--success-soft) 200%); border-color: rgba(5,150,105,0.15); }
.kpi-card.kpi-success .kpi-value { color: var(--success); }
.kpi-card.kpi-danger { background: linear-gradient(135deg, var(--surface) 0%, var(--danger-soft) 200%); border-color: rgba(220,38,38,0.15); }
.kpi-card.kpi-danger .kpi-value { color: var(--danger); }
.kpi-card.kpi-warning { background: linear-gradient(135deg, var(--surface) 0%, var(--warning-soft) 200%); border-color: rgba(217,119,6,0.15); }
.kpi-card.kpi-warning .kpi-value { color: var(--warning); }
.kpi-card.kpi-muted { background: var(--muted-soft); border-color: var(--line); }
.kpi-card.kpi-muted .kpi-value { color: var(--text-3); }

/* === Gauge donut con ring + center value premium ============== */
.kpi-gauge {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 0.6rem;
    padding: 1.1rem 0.85rem 1rem;
    text-align: center;
    box-shadow: var(--shadow-sm);
    transition: transform 0.12s, box-shadow 0.12s;
    position: relative;
    overflow: hidden;
}
.kpi-gauge:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow);
}
.gauge-svg {
    width: 7rem;
    height: 7rem;
    margin: 0 auto 0.6rem;
    display: block;
}
.gauge-svg .gauge-track {
    stroke: var(--line);
    stroke-width: 2.6;
    fill: none;
}
.gauge-svg .gauge-fill {
    stroke-width: 2.6;
    fill: none;
    stroke-linecap: round;
    filter: drop-shadow(0 0 0.1rem rgba(0,0,0,0.06));
}
.gauge-svg .gauge-ticks line {
    stroke: var(--line-strong);
    stroke-width: 0.35;
    opacity: 0.4;
}
.gauge-svg .gauge-pct {
    font-family: 'Inter Tight', system-ui, sans-serif;
    font-size: 0.55rem; /* SVG viewbox units */
    font-weight: 700;
    fill: var(--text);
    letter-spacing: -0.03em;
}
.gauge-svg .gauge-pct-decimal {
    font-size: 0.32rem;
    fill: var(--text-3);
    font-weight: 500;
}
.kpi-gauge .gauge-title {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text);
    font-weight: 600;
    margin-top: 0.1rem;
}
.kpi-gauge .gauge-subtitle {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.62rem;
    color: var(--text-3);
    margin-top: 0.2rem;
    letter-spacing: 0.04em;
}

/* === Print rules para OtDetail ============================ */
@media print {
    /* Esconde sidebar / header / botones para que solo se imprima el contenido */
    .rz-sidebar, .rz-header, .print-hide,
    .end-filter-bar { display: none !important; }

    .rz-body, .rz-layout { background: #fff !important; }

    /* Abre todos los details (las flechas pueden mostrarse fijas) */
    details { display: block !important; }
    details > summary { cursor: default !important; }
    details:not([open]) > *:not(summary) { display: block !important; }
    details > summary::before { transform: rotate(90deg) !important; }

    /* Tamaño A4 con márgenes razonables */
    @page {
        size: A4;
        margin: 14mm 12mm;
    }

    .ot-detail {
        max-width: 100% !important;
        padding: 0 !important;
    }

    .ot-detail-section, .ot-detail-subsection, .ot-detail-subsub {
        break-inside: avoid;
        page-break-inside: avoid;
    }
    .kpi-card { break-inside: avoid; }

    /* Reduce un poco las fuentes para que entren más datos por página */
    body, .ot-detail { font-size: 11pt; }
    .kpi-value { font-size: 1.3rem; }
    .ot-detail-section > summary { font-size: 0.9rem; }
}

/* Tablas compactas usadas en el dashboard (Estado actual > Antiguedad y Demoras).
   No usar RadzenDataGrid porque solo son 5 filas estaticas, sin paginado ni filtros. */
.dashboard-mini-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}
.dashboard-mini-table th,
.dashboard-mini-table td {
    padding: 0.4rem 0.5rem;
    border-bottom: 1px solid var(--rz-border-light);
}
.dashboard-mini-table th {
    text-align: left;
    color: var(--end2-accent);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 0.72rem;
    background: rgba(var(--end2-accent-rgb), 0.12);
    border-bottom: 1px solid rgba(var(--end2-accent-rgb), 0.35);
}
.dashboard-mini-table tr.row-vencido td {
    background-color: rgba(220, 53, 69, 0.22) !important;
    color: #842029 !important;
}

/* Highlight para registros declarados NO APTO. Mismo patron que row-vencido
   pero por una propiedad de calidad (Item.NoApto = true en /items y el
   DropDownDataGrid del form ItemOt). Vive global aca para que cualquier grid
   futuro que quiera el mismo estilo lo herede sin duplicar el bloque. */
.rz-grid-table tr.row-no-apto td,
.rz-grid-table tr.row-no-apto:hover td {
    background-color: rgba(220, 53, 69, 0.22) !important;
    color: #842029 !important;
}

/* Highlight informativo (azul) para filas que referencian un Item de
   catalogo ya existente. Usado en el nested grid de RecepcionItems
   cuando ItemYaRegistrado tiene valor > 0.
   Fondo azul saturado + texto blanco — garantiza contraste alto en
   tema light Y dark (en dark, el rgba sobre var(--rz-base-100) oscuro
   daba un gris-azulado y el texto oscuro #052c65 quedaba ilegible). */
.rz-grid-table tr.row-item-existente td,
.rz-grid-table tr.row-item-existente:hover td {
    background-color: rgba(13, 110, 253, 0.55) !important;
    color: #ffffff !important;
    font-weight: 500 !important;
}

/* =====================================================================
   Dialogs de declaracion de conformidad QA/QC (Item Apto Nivel 1 +
   OT Finalizada Nivel 2). Paleta "documento legal" con colores
   explicitos para legibilidad en cualquier tema. Compartidos por los
   dos dialogs — viven aqui porque si el <style> bloque vive solo en
   uno de los .razor, no se carga cuando el OTRO dialog abre solo.
   ===================================================================== */

.declaracion-dialog {
    padding: 1rem 1.25rem;
    min-width: 560px;
    max-width: 720px;
    width: 100%;
    box-sizing: border-box;
    background: #ffffff;
    color: #1e293b;
    border-radius: 8px;
}

.declaracion-title {
    font-size: 1.15rem;
    font-weight: 700;
    color: #0f172a;          /* slate-900 */
    margin-bottom: 0.4rem;
}
.declaracion-subtitle {
    font-size: 0.88rem;
    color: #475569;          /* slate-600 */
    line-height: 1.45;
    margin-bottom: 1rem;
}
.declaracion-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0 0.4rem;
}
.declaracion-section-title {
    font-weight: 600;
    font-size: 0.95rem;
    color: #1e293b;
}
.declaracion-hint {
    font-size: 0.82rem;
    color: #64748b;          /* slate-500 */
    margin-top: 0.35rem;
    padding-left: 0.25rem;
}

/* Caja de contadores compactos (Total / Aptos / NoAptos / SinDefinir
   en el Nivel 1, o Total / Finalizados / NoFinalizados en Nivel 2). */
.declaracion-counters {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.7rem 1.1rem;
    margin-bottom: 1rem;
    background: #ffffff;
    border: 1px solid #cbd5e1;   /* slate-300 */
    border-radius: 6px;
    font-size: 0.95rem;
    color: #1e293b;              /* slate-800 */
}
.declaracion-counters strong { color: #0f172a; font-weight: 600; }
.declaracion-counters .cnt-aptos   { color: #047857; }   /* emerald-700 */
.declaracion-counters .cnt-noaptos { color: #b91c1c; }   /* red-700 */
.declaracion-counters .cnt-sindef  { color: #b45309; }   /* amber-700 */
.declaracion-counters .cnt-aptos   strong { color: #047857; }
.declaracion-counters .cnt-noaptos strong { color: #b91c1c; }
.declaracion-counters .cnt-sindef  strong { color: #b45309; }

/* Contenedor scrolleable del cuerpo de la declaracion. El JS de
   App.razor (window.endObserveScrollEnd) observa este div y avisa
   cuando llega al fondo para habilitar el checkbox. */
.declaracion-scroll {
    max-height: 300px;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
    margin-top: 0.4rem;
    border: 1px solid #cbd5e1;
    background: #ffffff;
    border-radius: 6px;
    font-size: 0.95rem;
    line-height: 1.6;
    color: #334155;              /* slate-700 */
}
.declaracion-scroll p { margin: 0 0 0.7rem; color: #334155; }
.declaracion-scroll strong { color: #0f172a; font-weight: 600; }

.declaracion-list {
    list-style: decimal;
    padding-left: 1.5rem;
    margin: 0.5rem 0 0.7rem;
}
.declaracion-list li {
    margin-bottom: 0.85rem;
    color: #334155;
}

/* Caja de aceptacion (checkbox + label). El selector compuesto
   .declaracion-dialog .declaracion-accept .declaracion-accept-label
   tiene alta especificidad + !important para ganarle a cualquier
   color heredado del dialog padre o del tema activo de Radzen. */
.declaracion-accept {
    margin-top: 0.95rem;
    padding: 0.85rem 1.1rem;
    background: #f1f5f9;          /* slate-100 */
    border: 1px solid #94a3b8;    /* slate-400 */
    border-radius: 6px;
    display: flex;
    align-items: center;
    transition: opacity 200ms ease;
}
.declaracion-accept-disabled { opacity: 0.6; }
.declaracion-dialog .declaracion-accept .declaracion-accept-label {
    font-size: 0.95rem;
    font-weight: 500;
    color: #0f172a !important;
    cursor: pointer;
    user-select: none;
}
.declaracion-accept-disabled .declaracion-accept-label {
    cursor: not-allowed;
}

/* =====================================================================
   Paleta END2 para features dark-themed (countdown gate + premium page)
   ---------------------------------------------------------------------
   Estas variables vivirán solo mientras el visual sea fijo (oscuro
   industrial con acento cyan corporativo). Cuando el sistema admita
   "tema claro para premium page" o branding por cliente, las redefinimos
   en :root con `@media (prefers-color-scheme)` o por clase.
   Para colores con rol semantico (danger/success/warning) usar las vars
   de Radzen (--rz-danger, --rz-success, --rz-warning) directamente.
   ===================================================================== */
:root {
    /* Brand accents */
    --end2-accent:       #38bdf8;  /* sky-400 - cyan corporativo */
    --end2-accent-2:     #22d3ee;  /* cyan-400 - segundo stop del gradiente */
    --end2-accent-rgb:   56, 189, 248;  /* para rgba(var(--end2-accent-rgb), N%) */
    --end2-accent-2-rgb: 34, 211, 238;

    /* Superficies oscuras */
    --end2-surface-darkest: #0b1220;
    --end2-surface-dark:    #0f172a;  /* slate-900 */
    --end2-surface-dark-rgb: 15, 23, 42;
    --end2-surface-dark-2-rgb: 30, 41, 59;  /* slate-800 (middle stop overlay) */

    /* Tipografia sobre fondos oscuros */
    --end2-text-bright:     #f8fafc;  /* slate-50  - titulos hero */
    --end2-text:            #f1f5f9;  /* slate-100 - card titles, body principal */
    --end2-text-soft:       #e2e8f0;  /* slate-200 - body premium page */
    --end2-text-brand-soft: #cbd5e1;  /* slate-300 - countdown brand */
    --end2-text-muted:      #94a3b8;  /* slate-400 - subtitulos, card text */
    --end2-text-muted-rgb:  148, 163, 184;
    --end2-text-faint:      #64748b;  /* slate-500 - hints, footer */
}

/* =====================================================================
   Countdown gate del dashboard (overlay full-screen, 5s default)
   ===================================================================== */
.countdown-gate-overlay {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(135deg,
        rgba(var(--end2-surface-dark-rgb), 0.92) 0%,
        rgba(var(--end2-surface-dark-2-rgb), 0.94) 50%,
        rgba(var(--end2-surface-dark-rgb), 0.92) 100%);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    animation: countdownGateFadeIn 250ms ease-out;
}

@keyframes countdownGateFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.countdown-gate-card {
    background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 16px;
    padding: 2.5rem 3rem;
    max-width: 480px;
    width: calc(100% - 2rem);
    text-align: center;
    color: var(--end2-text);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(var(--end2-accent-rgb), 0.08);
}

.countdown-gate-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--end2-text-brand-soft);
}

.countdown-gate-brand-icon {
    color: var(--end2-accent);
    font-size: 1.4rem;
}

.countdown-gate-brand-text {
    text-transform: uppercase;
    letter-spacing: 0.15em;
}

.countdown-gate-brand-accent {
    color: var(--end2-accent);
    font-weight: 700;
}

.countdown-gate-title {
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    margin-bottom: 0.4rem;
    color: var(--end2-text-bright);
}

.countdown-gate-subtitle {
    font-size: 0.95rem;
    color: var(--end2-text-muted);
    margin-bottom: 1.75rem;
    line-height: 1.45;
}

.countdown-gate-ring-wrap {
    position: relative;
    width: 140px;
    height: 140px;
    margin: 0 auto 1.5rem;
}

.countdown-gate-ring {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.countdown-gate-ring-bg {
    fill: none;
    stroke: rgba(var(--end2-text-muted-rgb), 0.2);
    stroke-width: 6;
}

.countdown-gate-ring-fg {
    fill: none;
    stroke: url(#countdownGateGrad);
    stroke: var(--end2-accent); /* fallback antes de aplicar el gradiente SVG */
    stroke-width: 6;
    stroke-linecap: round;
    transition: stroke-dashoffset 100ms linear;
    filter: drop-shadow(0 0 6px rgba(var(--end2-accent-rgb), 0.5));
}

.countdown-gate-number {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    font-size: 3.5rem;
    font-weight: 300;
    font-variant-numeric: tabular-nums;
    color: var(--end2-text-bright);
    animation: countdownGatePulse 1s ease-out;
}

@keyframes countdownGatePulse {
    0%   { transform: translate(-50%, -50%) scale(0.85); opacity: 0.4; }
    40%  { transform: translate(-50%, -50%) scale(1.05); opacity: 1; }
    100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

.countdown-gate-hint {
    margin-top: 0.75rem;
    font-size: 0.8rem;
    color: var(--end2-text-faint);
    letter-spacing: 0.04em;
}

/* =====================================================================
   Pagina Premium Info (/premium-info)
   ===================================================================== */
.premium-page {
    min-height: 100vh;
    background:
        radial-gradient(circle at 15% 10%, rgba(var(--end2-accent-rgb), 0.08) 0%, transparent 40%),
        radial-gradient(circle at 85% 90%, rgba(var(--end2-accent-2-rgb), 0.07) 0%, transparent 40%),
        linear-gradient(180deg, var(--end2-surface-darkest) 0%, var(--end2-surface-dark) 100%);
    color: var(--end2-text-soft);
    padding: 3rem 1rem 5rem;
}

.premium-hero {
    max-width: 980px;
    margin: 0 auto 4rem;
    text-align: center;
}

.premium-hero-eyebrow {
    display: inline-block;
    font-size: 0.8rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--end2-accent);
    border: 1px solid rgba(var(--end2-accent-rgb), 0.3);
    padding: 0.35rem 0.9rem;
    border-radius: 999px;
    margin-bottom: 1.5rem;
    background: rgba(var(--end2-accent-rgb), 0.05);
}

.premium-hero-title {
    font-size: clamp(2.5rem, 6vw, 4rem);
    font-weight: 200;
    letter-spacing: -0.02em;
    line-height: 1.05;
    margin-bottom: 1.25rem;
    color: var(--end2-text-bright);
}

.premium-hero-title strong {
    font-weight: 700;
    background: linear-gradient(90deg, var(--end2-accent), var(--end2-accent-2));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.premium-hero-sub {
    font-size: 1.1rem;
    line-height: 1.6;
    color: var(--end2-text-muted);
    max-width: 680px;
    margin: 0 auto 2rem;
}

.premium-hero-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: linear-gradient(90deg, var(--end2-accent), var(--end2-accent-2));
    color: var(--end2-surface-dark);
    border: none;
    padding: 0.9rem 1.75rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    letter-spacing: 0.02em;
    transition: transform 200ms ease, box-shadow 200ms ease;
    box-shadow: 0 8px 30px rgba(var(--end2-accent-rgb), 0.25);
}

.premium-hero-cta:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 40px rgba(var(--end2-accent-rgb), 0.4);
}

.premium-section {
    max-width: 1100px;
    margin: 0 auto 4rem;
}

.premium-section-title {
    font-size: 1.6rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
    color: var(--end2-text);
    text-align: center;
}

.premium-section-sub {
    text-align: center;
    color: var(--end2-text-muted);
    margin-bottom: 2.5rem;
    font-size: 1rem;
}

.premium-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.25rem;
}

.premium-card {
    background: rgba(var(--end2-surface-dark-rgb), 0.6);
    border: 1px solid rgba(var(--end2-accent-rgb), 0.12);
    border-radius: 12px;
    padding: 1.5rem;
    transition: border-color 200ms ease, transform 200ms ease;
}

.premium-card:hover {
    border-color: rgba(var(--end2-accent-rgb), 0.35);
    transform: translateY(-3px);
}

.premium-card-icon {
    width: 44px;
    height: 44px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--end2-accent-rgb), 0.12);
    color: var(--end2-accent);
    margin-bottom: 0.9rem;
    font-size: 1.5rem;
}

.premium-card-title {
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: 0.4rem;
    color: var(--end2-text);
}

.premium-card-text {
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--end2-text-muted);
}

.premium-method-tag {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    background: rgba(var(--end2-accent-rgb), 0.15);
    color: var(--end2-accent);
    margin-right: 0.35rem;
}

.premium-footer {
    max-width: 980px;
    margin: 3rem auto 0;
    text-align: center;
    padding: 2rem 1rem;
    border-top: 1px solid rgba(var(--end2-text-muted-rgb), 0.1);
    color: var(--end2-text-faint);
    font-size: 0.85rem;
    letter-spacing: 0.04em;
}

/* === Filtro general en sidebar (Cliente/OT) ====================================== */
.sici-filter-bar {
    padding: 0.5rem 0.75rem;
    border-bottom: var(--rz-panel-menu-item-border);
}
.sici-filter-bar-title {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--rz-sidebar-color);
    opacity: 0.7;
    margin-bottom: 0.4rem;
}
.sici-filter-chip {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.5rem;
    margin-bottom: 0.25rem;
    background: rgba(var(--sici-accent-rgb), 0.14);
    border: 1px solid rgba(var(--sici-accent-rgb), 0.35);
    border-radius: 4px;
    color: var(--rz-sidebar-color);
    font-size: 0.8rem;
}
.sici-filter-chip-x {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    border: none;
    background: rgba(var(--sici-accent-rgb), 0.25);
    color: var(--rz-sidebar-color);
    border-radius: 50%;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
}
.sici-filter-chip-x:hover {
    background: var(--rz-danger);
    color: #fff;
}
.sici-filter-chip-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* === Manual de usuario (diagrama de flujo + paso a paso) ============ */
.manual-page { max-width: 1100px; margin: 0 auto; padding: 0 0.5rem 3rem; }
.manual-flow {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: 0.4rem; margin: 1rem 0 2.5rem;
}
.manual-flow-node {
    flex: 1 1 140px; min-width: 120px; max-width: 190px;
    display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
    text-decoration: none; padding: 1rem 0.6rem; border-radius: 12px;
    background: rgba(var(--end2-accent-rgb), 0.06);
    border: 1px solid rgba(var(--end2-accent-rgb), 0.2);
    color: var(--end2-text-soft, #e2e8f0); transition: transform .15s ease, background .15s ease, border-color .15s ease;
}
.manual-flow-node:hover {
    background: rgba(var(--end2-accent-rgb), 0.16);
    border-color: rgba(var(--end2-accent-rgb), 0.55);
    transform: translateY(-3px);
}
.manual-flow-num {
    font-size: 0.72rem; font-weight: 700; color: var(--end2-accent);
    background: rgba(var(--end2-accent-rgb), 0.18); border-radius: 999px;
    width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
}
.manual-flow-label { font-weight: 600; text-align: center; font-size: 0.88rem; }
.manual-flow-arrow { display: flex; align-items: center; color: var(--end2-accent); opacity: 0.7; }

.manual-step { margin: 2.5rem 0; scroll-margin-top: 80px; }
.manual-step-head { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.6rem; }
.manual-step-num {
    flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%;
    background: linear-gradient(135deg, var(--end2-accent), var(--end2-accent-2));
    color: #04121f; font-weight: 800; font-size: 1.05rem;
    display: flex; align-items: center; justify-content: center;
}
.manual-step-title { font-size: 1.3rem; font-weight: 700; color: var(--end2-text-bright, #f8fafc); margin: 0; }
.manual-step-body { color: var(--end2-text-soft, #cbd5e1); line-height: 1.6; }
.manual-step-body ul { margin: 0.5rem 0 0.5rem 1.2rem; }
.manual-step-body li { margin-bottom: 0.3rem; }
.manual-step-body code {
    background: rgba(var(--end2-accent-rgb), 0.12); color: var(--end2-accent);
    padding: 0.05rem 0.35rem; border-radius: 4px; font-size: 0.85em;
}
.manual-ref { color: var(--end2-accent); text-decoration: none; border-bottom: 1px dashed rgba(var(--end2-accent-rgb), 0.5); }
.manual-ref:hover { border-bottom-style: solid; }

.manual-shot {
    margin: 1rem 0 0; border-radius: 10px; overflow: hidden;
    border: 1px solid rgba(var(--end2-accent-rgb), 0.25);
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.45);
    background: #0f172a;
}
.manual-shot-bar {
    display: flex; align-items: center; gap: 6px; padding: 8px 12px;
    background: rgba(var(--end2-accent-rgb), 0.1);
    border-bottom: 1px solid rgba(var(--end2-accent-rgb), 0.2);
}
.manual-shot-bar i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.manual-shot-bar .d1 { background: #ef4444; }
.manual-shot-bar .d2 { background: #f59e0b; }
.manual-shot-bar .d3 { background: #22c55e; }
.manual-shot-cap { font-size: 0.78rem; color: var(--end2-text-soft, #cbd5e1); margin-left: 8px; }
.manual-shot img { display: block; width: 100%; height: auto; }