/* =====================================================================
   TRACKVY — Accendo brand layer (single source of truth)
   Loaded LAST (after style.css + style-preset.css) so it wins the cascade.
   No SCSS build exists: we remap Bootstrap (--bs-*) and Mantis (--pc-*)
   runtime variables onto the brand tokens defined below. Change a colour
   ONCE here and it propagates everywhere. Do not hardcode hexes in rules
   below — reference the tokens.
   ===================================================================== */

:root {
    /* ===== Brand tokens — the ONLY place raw hexes live ===== */
    --brand-navy: #15243C;          /* primary: buttons, active nav, headings, key figures (Accendo navy) */
    --brand-navy-600: #101C30;      /* hover  (~6% darker) */
    --brand-navy-700: #0C1525;      /* active (~12% darker) */
    --brand-ink: #161A22;           /* strongest text / headings (Accendo ink — cool) */
    --brand-blue-deep: #2C5A82;     /* interactive accent: links, focus ring, secondary (AA ~5.9:1) */
    --brand-blue-deep-600: #244A6B; /* blue-deep hover */
    --brand-blue: #498DBE;          /* logo blue — DECORATIVE only (fails AA for text) */
    --brand-blue-bright: #6EA4CB;   /* light accent on dark surfaces (Accendo hero accent) — decorative */

    /* ===== Accendo data-viz spectrum — for charts only (cool, desaturated) ===== */
    --brand-indigo: #393664;        /* deepest brand hue */
    --brand-teal: #10658C;
    --brand-teal-mid: #257396;
    --brand-sage: #85ADA3;          /* calm green-grey — tertiary chart hue */

    /* ===== Calm positive (success/in-stock/live) — replaces the vivid emerald
       everywhere EXCEPT the logo and the dashboard AI highlight. Sage/teal-leaning,
       desaturated, AA on its own tint; pairs with the desaturated danger red. ===== */
    --brand-positive: #2F7A5B;          /* calm positive solid (dots, fills, chart slice) */
    --brand-positive-600: #266449;      /* hover/active */
    --brand-positive-tint: #E7F0EB;     /* soft positive fill (rest state) */
    --brand-positive-tint-border: #CCE0D6;
    --brand-positive-text: #1E6B52;     /* AA positive text on the soft tint */
    --brand-positive-rgb: 47, 122, 91;

    --brand-green: #17CC98;         /* Trackvy vivid emerald — RESERVED: logo + dashboard AI highlight ONLY */
    --brand-navy-tint: #E7EDF3;     /* light navy fill behind navy text (replaces #e8f4ff) */
    --brand-navy-tint-border: #CBD8E5;
    /* (the old green success/hover/tint tokens were retired — success now uses the
       calm-positive family above; vivid --brand-green is logo + AI highlight only.) */
    --brand-danger-tint: #F6E4E0;   /* soft danger fill (matches danger alert) */
    --brand-danger-tint-border: #E8C9C2;

    /* Tinte de aviso (warn), calmo, no alarmante. Reemplaza hexes sueltos en .status-pill.is-warn. */
    --brand-warn-tint: #F6EEDD;
    --brand-warn-text: #8A6418;
    --brand-warn-border: #E8D9B6;

    /* Tokens de pill neutro (estado por defecto de .status-pill y de los iconos de fila en reposo). */
    --brand-pill-neutral-text: #6B6B66;
    --brand-pill-neutral-border: #E0E0DC;

    --brand-body: #4F555E;          /* body copy (cool — Accendo) */
    --brand-muted: #878C94;         /* labels, meta, captions, placeholders (cool) */
    --brand-line: #E6E8EC;          /* borders, dividers, table rules (cool) */
    --brand-line-soft: #EFF1F4;     /* lighter inner rules / zebra base (cool) */
    --brand-paper: #F7F8FB;         /* raised surface, table header fill, zebra rows (cool) */
    --brand-canvas: #F2F5F9;        /* recessed page canvas behind white cards (cool) */
    --brand-row-hover: #E7EDF3;     /* table row hover (navy tint — reads on the gray canvas) */
    --brand-th-bg: #FAFBFC;         /* very light grey table-header fill */
    --brand-white: #FFFFFF;

    /* semantic — desaturated to sit with the palette */
    --brand-success: var(--brand-positive);
    --brand-info: var(--brand-blue-deep);
    --brand-warning: #B5852A;
    --brand-danger: #A6402F;

    /* rgb helpers for rgba() alpha use */
    --brand-navy-rgb: 21, 36, 60;
    --brand-blue-deep-rgb: 44, 90, 130;

    /* categorical chart palette — an all-blue ramp (Accendo blues), ordered with
       alternating light/dark so adjacent slices stay distinguishable. Point Chart.js
       / ApexCharts at these; both cycle the ramp when there are more series than
       tones (e.g. tenant-defined extra states). */
    --chart-1: #2C5A82;   /* blue-deep — dominant slice */
    --chart-2: #7FB0D6;   /* light blue */
    --chart-3: #10658C;   /* teal-deep blue */
    --chart-4: #4E8CBE;   /* blue */
    --chart-5: #1C3E5E;   /* deep slate-blue */
    --chart-6: #A7C8E0;   /* pale blue */
    --chart-grid: var(--brand-line-soft);

    /* Rampa de OCUPACIÓN (heat) del plano de planta: secuencial cálida (gris-arena -> oro de marca) deliberadamente
       FUERA de la familia navy/azul, porque trazos y selección de zona son navy y el heat debe leerse aparte. Calma
       y desaturada (nunca alarmante): es densidad de etiquetas, no un estado de error. La usa js/location/map.js. */
    --heat-1: #EAE3D4;   /* arena pálida — ocupación mínima */
    --heat-2: #DCC79A;
    --heat-3: #CBA862;
    --heat-4: #B5852A;   /* oro de marca (--brand-warning) */
    --heat-5: #8A6315;   /* oro profundo — ocupación máxima */

    /* fonts */
    --brand-font-sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --brand-font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

    /* measures */
    --border-radius: 0.375rem;      /* 6px — crisp, not pill */
    --padding: 0.3125rem;           /* 5px */
    --pc-sidebar-width: 260px;      /* Mantis sidebar — chrome offset for header/content/footer */

    /* ===== Legacy aliases — keep old class/var names working, recoloured.
       The 56 templates using .btn-trackvy / .btn-secondary-trackvy etc.
       recolour automatically through these. ===== */
    --black-trackvy-color: var(--brand-ink);
    --blue-gray: var(--brand-body);
    --main-color: var(--brand-navy);
    --main-color-hover: var(--brand-navy-600);
    --secondary-color: var(--brand-blue-deep);
    --secondary-color-hover: var(--brand-blue-deep-600);
    --secondary-text: var(--brand-muted);
    --title-color: var(--brand-ink);
    --orange-red: #FE5621;          /* legacy orange — not part of unification */

    /* ===== Map Bootstrap global vars onto brand ===== */
    --bs-body-color: var(--brand-body);
    --bs-body-bg: var(--brand-white);
    --bs-border-color: var(--brand-line);
    --bs-font-sans-serif: var(--brand-font-sans);
    --bs-body-font-family: var(--brand-font-sans);
    --bs-font-monospace: var(--brand-font-mono);
    --bs-focus-ring-color: rgba(var(--brand-blue-deep-rgb), .35);

    /* Mantis chrome */
    --pc-heading-color: var(--brand-ink);
    --pc-sidebar-active-color: var(--brand-navy);
}

/* ===== Re-skin the active Mantis preset (body has data-pc-preset="preset-1").
   Scoped to the same selector so we match preset specificity and, loaded
   last, win. ===== */
[data-pc-preset="preset-1"] {
    --bs-primary: var(--brand-navy);
    --bs-primary-rgb: var(--brand-navy-rgb);
    --bs-primary-light: var(--brand-paper);
    --bs-blue: var(--brand-navy);

    --bs-link-color: var(--brand-blue-deep);
    --bs-link-color-rgb: var(--brand-blue-deep-rgb);
    --bs-link-hover-color: var(--brand-navy);
    --bs-link-hover-color-rgb: var(--brand-navy-rgb);

    --bs-success: var(--brand-positive);
    --bs-success-rgb: var(--brand-positive-rgb);

    --pc-sidebar-active-color: var(--brand-navy);
    --dt-row-selected: var(--brand-navy-rgb);
}

[data-pc-preset="preset-1"] .btn-primary {
    --bs-btn-bg: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-hover-bg: var(--brand-navy-600);
    --bs-btn-hover-border-color: var(--brand-navy-600);
    --bs-btn-active-bg: var(--brand-navy-700);
    --bs-btn-active-border-color: var(--brand-navy-700);
    --bs-btn-disabled-bg: var(--brand-navy);
    --bs-btn-disabled-border-color: var(--brand-navy);
    --bs-btn-focus-shadow-rgb: var(--brand-blue-deep-rgb);
}

/* Success button — soft calm-positive tint at rest (AA positive text), fills the
   calm positive solid on hover (white text). A matched soft->solid pair with
   .btn-danger. Vivid emerald is no longer used here (reserved for logo + AI). */
[data-pc-preset="preset-1"] .btn-success {
    --bs-btn-color: var(--brand-positive-text);
    --bs-btn-bg: var(--brand-positive-tint);
    --bs-btn-border-color: var(--brand-positive-tint-border);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--brand-positive);
    --bs-btn-hover-border-color: var(--brand-positive);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: var(--brand-positive-600);
    --bs-btn-active-border-color: var(--brand-positive-600);
    --bs-btn-disabled-color: var(--brand-positive-text);
    --bs-btn-disabled-bg: var(--brand-positive-tint);
    --bs-btn-disabled-border-color: var(--brand-positive-tint-border);
}

/* Danger button — soft, alert-style tint by default; fills solid on hover.
   Calm at rest, unmistakable on intent. */
[data-pc-preset="preset-1"] .btn-danger {
    --bs-btn-color: var(--brand-danger);
    --bs-btn-bg: var(--brand-danger-tint);
    --bs-btn-border-color: var(--brand-danger-tint-border);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--brand-danger);
    --bs-btn-hover-border-color: var(--brand-danger);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: var(--brand-danger);
    --bs-btn-active-border-color: var(--brand-danger);
    --bs-btn-disabled-color: var(--brand-danger);
    --bs-btn-disabled-bg: var(--brand-danger-tint);
    --bs-btn-disabled-border-color: var(--brand-danger-tint-border);
}

[data-pc-preset="preset-1"] .btn-outline-primary {
    --bs-btn-color: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-hover-bg: var(--brand-navy);
    --bs-btn-hover-border-color: var(--brand-navy);
    --bs-btn-active-bg: var(--brand-navy);
    --bs-btn-active-border-color: var(--brand-navy);
}

[data-pc-preset="preset-1"] .link-primary {
    color: var(--brand-blue-deep) !important;
}

/* Success / danger badges — soft tints matching the buttons & status pills,
   so the whole success/danger language is consistent (scoped to .badge only,
   so other .bg-success/.bg-danger fills are unaffected). */
[data-pc-preset="preset-1"] .badge.bg-success {
    background-color: var(--brand-positive-tint) !important;
    color: var(--brand-positive-text) !important;
}

[data-pc-preset="preset-1"] .badge.bg-danger {
    background-color: var(--brand-danger-tint) !important;
    color: var(--brand-danger) !important;
}

[data-pc-preset="preset-1"] .bg-light-primary {
    background: var(--brand-navy-tint);
    color: var(--brand-navy);
}

/* Components that hardcode the preset blue and aren't reached by --bs-primary.
   (form-check/switch, .bg-primary, success/danger badges already follow the
   --bs-* remaps above, so they're intentionally omitted.) */
[data-pc-preset="preset-1"] .progress {
    --bs-progress-bar-bg: var(--brand-navy);
}

[data-pc-preset="preset-1"] .nav-pills {
    --bs-nav-pills-link-active-bg: var(--brand-navy);
}

[data-pc-preset="preset-1"] .nav {
    --bs-nav-link-hover-color: var(--brand-navy);
}

[data-pc-preset="preset-1"] .list-group {
    --bs-list-group-active-bg: var(--brand-navy);
    --bs-list-group-active-border-color: var(--brand-navy);
}

[data-pc-preset="preset-1"] .list-group-item-primary {
    color: var(--brand-navy);
    background-color: var(--brand-navy-tint);
}

[data-pc-preset="preset-1"] .pagination {
    --bs-pagination-hover-color: var(--brand-navy);
    --bs-pagination-focus-color: var(--brand-navy);
    --bs-pagination-focus-box-shadow: 0 0 0 0.2rem rgba(var(--brand-blue-deep-rgb), 0.25);
    --bs-pagination-active-bg: var(--brand-navy);
    --bs-pagination-active-border-color: var(--brand-navy);
}

/* Align icon + label inside every button AND unify the icon/text spacing.
   inline-flex centres the Tabler glyph on the text baseline; a single `gap`
   gives identical icon-to-text spacing everywhere, and we neutralise the
   ad-hoc me-1/me-2 margins (applied inconsistently across templates) so the
   gap is the one source of truth. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
}

.btn > i,
.btn > svg {
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* don't double-space before the dropdown caret (gap already spaces it) */
.btn.dropdown-toggle::after {
    margin-left: 0;
}

/* ===== Brand button classes (used across ~56 templates) ===== */
.btn-trackvy {
    background-color: var(--brand-navy);
    border-color: var(--brand-navy);
    color: var(--brand-white);
}

.btn-trackvy:hover {
    background-color: var(--brand-navy-600);
    border-color: var(--brand-navy-600);
    color: var(--brand-white);
}

.btn-secondary-trackvy {
    background-color: var(--brand-blue-deep);
    border-color: var(--brand-blue-deep);
    color: var(--brand-white);
}

.btn-secondary-trackvy:hover {
    background-color: var(--brand-blue-deep-600);
    border-color: var(--brand-blue-deep-600);
    color: var(--brand-white);
}

/* ===== Forms ===== */
.form-control {
    color: var(--brand-body);
    font-size: 14px;
}

.form-control:focus {
    border-color: var(--brand-blue-deep);
    box-shadow: 0 0 0 .2rem rgba(var(--brand-blue-deep-rgb), .25);
}

.required_field:after {
    color: var(--bs-danger);
    content: "*";
    font-size: 1rem;
    margin-right: 0.25rem;
    padding-left: 0.25rem;
}

/* ===== Sidebar active state ===== */
.pc-sidebar .pc-navbar > .pc-item.active > .pc-link {
    color: var(--brand-navy);
}

.pc-sidebar .pc-navbar > .pc-item.active:not(.pc-hasmenu) > .pc-link::after {
    background: var(--brand-navy);
}

/* ===== Layout helpers ===== */
.container {
    padding-left: 0;
    padding-right: 0;
}

.border-radius {
    border-radius: var(--border-radius);
}

.custom-padding {
    padding: 15px 15px;
}

.card .card-header {
    border-bottom: none;
    border-radius: var(--border-radius);
}

/* Unified badge: same size/shape/weight as Bootstrap .badge and .status-pill */
.custom-badge {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    padding: 0.35em 0.65em;
    border-radius: 0.375rem;
    border: 1px solid var(--brand-navy-tint-border);
    color: var(--brand-navy);
    background: var(--brand-navy-tint);
}

a {
    color: var(--brand-ink);
}

.nowrap {
    white-space: nowrap;
}

/* ===== Typography utilities ===== */
/* Mono uppercase overline — the signature label treatment */
.eyebrow,
.overline {
    font-family: var(--brand-font-mono);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.18em;   /* matched to the Accendo eyebrow tracking */
    text-transform: uppercase;
    color: var(--brand-muted);
}

/* Numerals in context: money, counts, dates, metrics.
   Stays in Geist SANS (readable across many tables) but uses tabular figures
   so numeric columns still align. Use this for the bulk of numeric cells. */
.num {
    font-variant-numeric: tabular-nums;
}

/* Explicit monospace — reserve for where fixed-width genuinely helps scanning:
   EPC serials, long codes/IDs. Low volume, deliberate "engineered" signal. */
.mono {
    font-family: var(--brand-font-mono);
    font-variant-numeric: tabular-nums;
}

/* KPI stat figure — the restrained "navy total band" energy */
.kpi-figure {
    font-family: var(--brand-font-mono);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    font-size: 1.875rem;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--brand-navy);
}

/* KPI card icon chip — shared primitive (dashboard KPI band + entity-detail metric banners) */
.kpi-icon {
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--brand-th-bg);
    color: var(--brand-muted);
    font-size: .95rem;
}

/* =====================================================================
   Airy data table (MBB style) — generous vertical rhythm, hairline rows,
   mono-uppercase header under a strong rule, no zebra/no vertical grid,
   sticky header. Apply `.table table-airy` to dense data tables and put
   `.num` on ID / code / date / numeric cells for tabular alignment.
   ===================================================================== */
.table-airy {
    --bs-table-bg: transparent;
    --bs-table-hover-bg: var(--brand-row-hover);
    margin-bottom: 0;
    color: var(--brand-body);
    border-color: var(--brand-line-soft);
}

.table-airy > thead > tr > th {
    background: var(--brand-th-bg);
    color: var(--brand-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    padding: 1rem 1.15rem;
    border-bottom: 2px solid var(--brand-ink);
    position: sticky;
    top: 0;
    z-index: 2;
}

.table-airy > tbody > tr > td {
    padding: 1.05rem 1.15rem;
    vertical-align: middle;
    border-top: 0;
    border-bottom: 1px solid var(--brand-line-soft);
    white-space: nowrap;
}

.table-airy > tbody > tr:last-child > td {
    border-bottom: 0;
}

/* Primary identifier cell (serial / code) — Geist sans, emphasis via WEIGHT +
   navy colour (no mono: long hex EPCs are far more legible in sans). */
.table-airy .cell-id,
.table-airy a.cell-id {
    color: var(--brand-navy);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
    text-decoration: none;
}

.table-airy .cell-id:hover,
.table-airy a.cell-id:hover {
    color: var(--brand-blue-deep);
}

/* Secondary numerics / dates — Geist sans, tabular figures, quiet weight */
.table-airy .num {
    color: var(--brand-body);
    font-weight: 400;
}

/* Right-align numeric/money columns */
.table-airy .text-end,
.table-airy th.text-end {
    text-align: right;
}

/* Status pill — calm lifecycle states (NOT error signals).
   Same size/feel as .badge / .custom-badge. Default = neutral.
   Variants are soft tints; red is intentionally absent (reserved for
   destructive actions, never for a valid state like RETIRED). */
.status-pill {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.02em;
    padding: 0.35em 0.65em;
    border-radius: 0.375rem;
    /* neutral / archived (e.g. RETIRED) — gray, calm */
    background: var(--brand-line-soft);
    color: var(--brand-pill-neutral-text);
    border: 1px solid var(--brand-pill-neutral-border);
}

/* active / in-stock (e.g. INVENTORY) — calm positive (sage/teal-leaning) */
.status-pill.is-ok {
    background: var(--brand-positive-tint);
    color: var(--brand-positive-text);
    border-color: var(--brand-positive-tint-border);
}

/* in-motion / assigned (e.g. TRANSITION, LENT) — calm navy-blue */
.status-pill.is-info {
    background: var(--brand-navy-tint);
    color: var(--brand-navy);
    border-color: var(--brand-navy-tint-border);
}

/* needs attention (NOT an error) — calm amber */
.status-pill.is-warn {
    background: var(--brand-warn-tint);
    color: var(--brand-warn-text);
    border-color: var(--brand-warn-border);
}

/* estado "en curso" (in-flight): punto pulsante discreto antes del texto.
   Combinable con cualquier variante de color (is-ok/is-info/is-warn); el
   punto hereda currentColor para no atarse a un tono fijo. */
.status-pill.is-live {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
}

.status-pill.is-live::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: status-pill-pulse 1.8s infinite;
}

@keyframes status-pill-pulse {
    0% { opacity: 1; }
    50% { opacity: .3; }
    100% { opacity: 1; }
}

/* =====================================================================
   Airy table — static enhancements (no JS): zebra, sticky header,
   frozen first/last columns, muted empty placeholder.
   Scroll viewport enables sticky header (vertical) + frozen cols (horizontal).
   ===================================================================== */
/* Scroll region for big grids: frozen columns (overflow-x) + a sticky header
   that floats down on vertical scroll. Height fills the viewport, so short
   tables show fully (no clipping) and only tables taller than the screen scroll
   INSIDE the region — which is what lets the header stick. Tune --grid-offset
   to the chrome above the table (top nav + page header + breadcrumb). */
.grid-scroll {
    --grid-offset: 230px;
    position: relative;   /* + z-index:0 => own stacking context, so the bottom */
    z-index: 0;           /* fade overlay sits above the pinned columns too */
    overflow: auto;
    max-height: calc(100vh - var(--grid-offset));
    /* thin, brand-tinted scrollbars (Firefox — only these two props apply there) */
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--brand-navy-rgb), 0.4) transparent;
}

/* thin, brand-tinted scrollbars (WebKit/Chromium) */
.grid-scroll::-webkit-scrollbar {
    width: 9px;
    height: 9px;
}

.grid-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.grid-scroll::-webkit-scrollbar-thumb {
    background-color: rgba(var(--brand-navy-rgb), 0.22);
    border-radius: 9px;
    border: 2px solid transparent;
    background-clip: content-box;
}

.grid-scroll::-webkit-scrollbar-thumb:hover {
    background-color: rgba(var(--brand-navy-rgb), 0.4);
}

.grid-scroll::-webkit-scrollbar-corner {
    background: transparent;
}

/* Soft zebra striping */
.table-airy.is-striped > tbody > tr:nth-child(even) > td {
    background: var(--brand-paper);
}

/* Frozen columns — opaque bg so scrolled content doesn't show through,
   plus an edge shadow so they read as pinned. */
.table-airy th.col-pin-left,
.table-airy td.col-pin-left {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--brand-white);
}

.table-airy th.col-pin-right,
.table-airy td.col-pin-right {
    position: sticky;
    right: 0;
    z-index: 2;
    background: var(--brand-white);
}

/* Edge shadows appear ONLY when there's hidden content to scroll to
   (classes toggled by js/common/table-grid.js). Left-pin shadow when scrolled
   right; right-pin shadow while content is still hidden beneath it. */
/* Side (pin) shadows on BODY cells only — the header keeps a single continuous
   bottom shadow instead of fighting per-corner side shadows. */
.grid-scroll.is-scrolled-x .table-airy td.col-pin-left {
    box-shadow: 6px 0 6px -4px rgba(14, 42, 69, 0.18);
}

.grid-scroll.has-more-right .table-airy td.col-pin-right {
    box-shadow: -6px 0 6px -4px rgba(14, 42, 69, 0.18);
}

/* Floating-header shadow once you've scrolled down — one fluid line across the
   whole header row, corners included (they no longer carry a side shadow). */
.grid-scroll.is-scrolled-y .table-airy thead th {
    box-shadow: 0 6px 6px -5px rgba(14, 42, 69, 0.18);
}

/* "More rows below" cue — a soft bottom fade, shown only while content is hidden
   below the fold. The overlay lives on .grid-wrap (injected by table-grid.js) so
   it stays put regardless of scroll direction. */
.grid-wrap {
    position: relative;
}

.grid-fade-bottom {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3rem;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s;
    /* transparent — the chevron alone signals "more below"; no white band over
       the last row */
    background: transparent;
}

/* explicit down-chevron — unmistakable "more below", even where a fade is too faint */
.grid-fade-bottom::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 9px;
    width: 10px;
    height: 10px;
    border-right: 2px solid var(--brand-body);
    border-bottom: 2px solid var(--brand-body);
    transform: translateX(-50%) rotate(45deg);
}

.grid-scroll.has-more-below + .grid-fade-bottom {
    opacity: 1;
}

/* gentle downward bob while there's more below — a live "scroll down" cue */
.grid-scroll.has-more-below + .grid-fade-bottom::after {
    animation: grid-chevron-bob 1.5s ease-in-out infinite;
}

@keyframes grid-chevron-bob {
    0%, 100% { transform: translateX(-50%) translateY(0) rotate(45deg); }
    50%      { transform: translateX(-50%) translateY(4px) rotate(45deg); }
}

@media (prefers-reduced-motion: reduce) {
    .grid-scroll.has-more-below + .grid-fade-bottom::after {
        animation: none;
    }
}

/* When the grid has a horizontal scrollbar, lift the fade + chevron above it
   (toggled by table-grid.js) so they don't sit on the scrollbar track. */
.grid-scroll.has-x-overflow + .grid-fade-bottom {
    bottom: 0.9rem;
}

/* ===== Responsive: on phones, DON'T freeze columns — the pinned column eats
   the small viewport. Let the grid scroll normally; keep the floating header. */
@media (max-width: 767.98px) {
    /* body cells: fully unpin */
    .table-airy td.col-pin-left,
    .table-airy td.col-pin-right {
        position: static;
        box-shadow: none !important;
    }
    /* header cells: KEEP sticky-top (so Serial/Acciones don't vanish on vertical
       scroll) — only drop the horizontal pin offsets */
    .table-airy th.col-pin-left,
    .table-airy th.col-pin-right {
        left: auto;
        right: auto;
    }
}

/* header corners above both the header row and the pinned body cells, and
   tinted to match the grey header (overrides the white pin background) */
.table-airy thead th.col-pin-left,
.table-airy thead th.col-pin-right {
    z-index: 4;
    background: var(--brand-th-bg);
}

/* pinned cells follow the stripe + hover so the freeze looks continuous */
.table-airy.is-striped > tbody > tr:nth-child(even) > td.col-pin-left,
.table-airy.is-striped > tbody > tr:nth-child(even) > td.col-pin-right {
    background: var(--brand-paper);
}

/* Non-pinned cells get hover from Bootstrap's inset box-shadow (--bs-table-hover-bg).
   Pinned cells carry their OWN box-shadow (the edge shadow when scrolled), which
   overrides Bootstrap's — so give them the hover colour explicitly via background. */
.table-airy.table-hover > tbody > tr:hover > td.col-pin-left,
.table-airy.table-hover > tbody > tr:hover > td.col-pin-right {
    background: var(--brand-row-hover);
}

/* muted placeholder for empty cells (reads better than a blank gap) */
.cell-empty {
    color: var(--brand-muted);
}

/* wrapping description cell (overrides table-airy nowrap) — e.g. report catalog */
.table-airy td.report-desc {
    white-space: normal;
    min-width: 240px;
    max-width: 460px;
    color: var(--brand-muted);
}

/* celda con truncado multilinea (clamp a 2 lineas), reemplaza el patron de
   max-width + ellipsis en linea repetido en varias vistas. --cell-clip-width
   es el ancho por defecto, redefinible por celda si hace falta. */
.cell-clip {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    max-width: var(--cell-clip-width, 280px);
    white-space: normal;
}

/* Compact density (toggled by the grid toolbar / table-controls.js): fila mas
   baja y tipografia ligeramente menor, para tablas embebidas en pestañas de detalle. */
.table-airy.is-compact > thead > tr > th,
.table-airy.is-compact > tbody > tr > td {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    font-size: 0.8125rem;
}

/* Column show/hide menu */
.grid-col-menu {
    max-height: 320px;
    min-width: 12rem;
    overflow: auto;
}

/* row action icons — calm (NOT disabled) at rest, full-strength on row hover,
   circular paper hit-target on icon hover. Works for both <a> and <button>. */
.table-airy .row-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border: 0;                       /* kills default <button> box */
    background: transparent;
    border-radius: 50%;
    color: var(--brand-pill-neutral-text);   /* clearly an icon at rest */
    font-size: 1rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

/* only the hovered icon lights up (not its siblings); the row background
   already marks the active row, so no row-level wake is needed */
/* the icon itself hovered → paper circle so the hit target is obvious */
.table-airy .row-action:hover {
    background: var(--brand-paper);
    color: var(--brand-navy);
}

.table-airy .row-action.is-danger:hover {
    background: var(--brand-paper);
    color: var(--brand-danger);
}

/* ===== Tables ===== */
.table thead th {
    text-align: center;
    white-space: nowrap;
}

.table thead tr th {
    color: var(--brand-muted);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* Bootstrap datetimepicker fix */
.collapse.in {
    display: block !important;
}

.table-condensed > tbody > tr > td,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > td,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > thead > tr > th {
    padding: 5px;
}

/* ===== Pagination ===== */
.page-link {
    color: var(--brand-blue-deep);
    background-color: var(--brand-white);
    border-color: var(--brand-line);
}

.page-link:hover {
    color: var(--brand-navy);
    background-color: var(--brand-paper);
    border-color: var(--brand-line);
}

.page-item.active .page-link {
    color: var(--brand-white);
    background-color: var(--brand-navy);
    border-color: var(--brand-navy);
}

.page-item.disabled .page-link {
    color: var(--brand-muted);
    background-color: var(--brand-white);
    border-color: var(--brand-line);
}

/* ===== Cards ===== */
.card-hover-fx {
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.card-hover-fx:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05) !important;
}

/* ===== Tabs ===== */
.mantis-line-tabs {
    border-bottom: 1px solid var(--brand-line);
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}

.mantis-line-tabs::-webkit-scrollbar {
    display: none;
}

.mantis-line-tabs .nav-link {
    color: var(--brand-body);
    border: none;
    border-bottom: 2px solid transparent;
    padding: 12px 20px;
    font-weight: 500;
    background: transparent;
    transition: all 0.3s ease;
}

.mantis-line-tabs .nav-link.active {
    color: var(--brand-navy) !important;
    border-bottom: 2px solid var(--brand-navy) !important;
}

/* ===== Detail sidebar items ===== */
.sidebar-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 1.25rem;
}

.sidebar-item i {
    font-size: 1.25rem;
    color: var(--brand-navy);
    margin-right: 1rem;
    margin-top: 0.2rem;
}

.sidebar-item-content .title {
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--brand-muted);
    font-weight: 600;
    margin-bottom: 0.1rem;
}

.sidebar-item-content .value {
    font-size: 0.95rem;
    color: var(--brand-ink);
    font-weight: 500;
}

/* ===== Sidebar scrollable ===== */
.pc-sidebar .navbar-content {
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
}

/* ===== Bottom footer links — muted, navy on hover ===== */
.pc-footer a {
    color: var(--brand-muted);
    text-decoration: none;
}

.pc-footer a:hover {
    color: var(--brand-navy);
}

.pc-sidebar .navbar-content::-webkit-scrollbar {
    width: 4px;
}

.pc-sidebar .navbar-content::-webkit-scrollbar-track {
    background: transparent;
}

.pc-sidebar .navbar-content::-webkit-scrollbar-thumb {
    background-color: rgba(0, 0, 0, 0.15);
    border-radius: 4px;
}

.pc-sidebar .navbar-content::-webkit-scrollbar-thumb:hover {
    background-color: rgba(0, 0, 0, 0.3);
}

/* ===========================
   Mantis Sidebar Arrow Fix
   =========================== */
.pc-sidebar .pc-arrow > i {
    font-size: 14px;
    line-height: 1;
    display: inline-block;
    vertical-align: middle;
    transition: transform 0.2s ease-in-out;
}

/* El giro al abrir lo hace YA el tema sobre el <span> contenedor (style.css: .pc-arrow con
   rotate(90deg)), y el icono de dentro gira con el. Aqui habia un segundo giro de 90 grados sobre
   la <i>, asi que sumaban 180: el chevron que apunta a la derecha acababa apuntando a la IZQUIERDA
   al abrir el submenu, cuando lo natural es que apunte hacia ABAJO, hacia lo que acaba de
   desplegarse. Se quita el giro sobrante; el del tema basta. */

/* ===========================================================================
   AI INSIGHTS — dashboard panel + /analytics/ai report
   All colors reference brand tokens. The vivid emerald is reserved for the
   single largest (positive) state slice; everything else is calm navy/blue.
   =========================================================================== */
.ai-spark { color: var(--brand-blue-deep); }

/* brief hero — navy accent rail + soft wash so the summary reads as the centerpiece */
.ai-hero {
    position: relative;
    border: 0 !important;
    border-left: 3px solid var(--brand-blue-deep) !important;
    background: linear-gradient(115deg, var(--brand-navy-tint) 0%, var(--brand-white) 60%);
    overflow: hidden;
}
.ai-hero::after {
    content: "\f6d7"; /* ti ti-sparkles */
    font-family: "tabler-icons"; position: absolute; top: -18px; right: -10px;
    font-size: 130px; line-height: 1; color: var(--brand-blue-deep); opacity: .05; pointer-events: none;
}
.ai-hero .card-body { position: relative; z-index: 1; }

.insight-brief { font-size: .95rem; line-height: 1.5; color: var(--brand-ink); }
.insight-brief--lg { font-size: 1.15rem; line-height: 1.55; font-weight: 500; color: var(--brand-navy); }

/* dashboard-panel highlight rows */
.hl { display: flex; gap: .55rem; align-items: flex-start; padding: .45rem 0; font-size: .85rem; color: var(--brand-body); }
.hl .dot { width: 8px; height: 8px; border-radius: 50%; margin-top: .4rem; flex: 0 0 auto; background: var(--brand-blue-deep); }
.hl.ok .dot { background: var(--brand-positive); }
.hl.warn .dot { background: var(--brand-warning, #B5852A); }
.hl.info .dot { background: var(--brand-blue-deep); }

.ai-meta { font-size: .7rem; color: var(--brand-muted); }
.ai-foot a { color: var(--brand-blue-deep); text-decoration: none; font-weight: 600; font-size: .8rem; }
.ai-foot a:hover { color: var(--brand-navy); }

/* Accendo-style sliding-arrow micro-gesture — text links only (buttons stay still
   per the design rule). The trailing arrow nudges right on hover. */
.ai-foot a i, .link-nudge i { transition: transform .25s ease; }
.ai-foot a:hover i, .link-nudge:hover i { transform: translateX(4px); }

/* dashboard AI panel — thin top accent (fixed, no hover lift — matches the other cards) */
.ai-panel { position: relative; overflow: hidden; }
.ai-panel::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
    background: linear-gradient(90deg, var(--brand-green), var(--brand-blue-deep));
}

/* "Basado en" figures */
.snap .v { font-size: 1.25rem; font-weight: 600; color: var(--brand-navy); font-family: var(--brand-font-mono); }
.snap .l { font-size: .625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--brand-muted); }

/* =====================================================================
   Editorial report narrative (markdown -> HTML via commonmark).
   Styles whatever structure the model emits: sections, lead, lists,
   ranked priorities (<ol>), key-takeaway callout (<blockquote>).
   ===================================================================== */
.report-body { font-family: var(--brand-font-sans); }
.report-body > :first-child { margin-top: 0; }

/* lead paragraph — the first paragraph reads larger, in navy ink */
.report-body > p:first-of-type { font-size: 1.02rem; line-height: 1.7; color: var(--brand-ink); }

/* section headers — eyebrow style over a hairline rule, with an accent tick */
.report-body h2, .report-body h3 {
    display: flex; align-items: center; gap: .5rem;
    font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
    color: var(--brand-blue-deep);
    margin: 1.7rem 0 .7rem; padding-top: 1rem;
    border-top: 1px solid var(--brand-line-soft);
}
.report-body h2::before, .report-body h3::before {
    content: ''; flex: 0 0 auto; width: 6px; height: 6px; border-radius: 2px;
    background: var(--brand-blue-deep);
}
.report-body h4, .report-body h5, .report-body h6 {
    font-size: .95rem; font-weight: 700; color: var(--brand-ink); margin: 1.1rem 0 .35rem;
}
.report-body p { font-size: .9rem; line-height: 1.7; color: var(--brand-body); margin-bottom: .7rem; }
.report-body strong { color: var(--brand-navy); font-weight: 600; }

/* unordered list — quiet accent dot markers */
.report-body ul { list-style: none; padding-left: 0; margin-bottom: .8rem; }
.report-body ul li {
    position: relative; padding-left: 1.1rem; margin-bottom: .4rem;
    font-size: .9rem; line-height: 1.55; color: var(--brand-body);
}
.report-body ul li::before {
    content: ''; position: absolute; left: 0; top: .55em;
    width: 5px; height: 5px; border-radius: 50%; background: var(--brand-blue);
}

/* ordered list — numbered priority chips */
.report-body ol { list-style: none; counter-reset: pri; padding-left: 0; margin-bottom: .8rem; }
.report-body ol li {
    counter-increment: pri; position: relative; padding-left: 2.1rem;
    margin-bottom: .55rem; min-height: 1.5rem;
    font-size: .9rem; line-height: 1.5; color: var(--brand-body);
}
.report-body ol li::before {
    content: counter(pri); position: absolute; left: 0; top: -.05em;
    width: 1.45rem; height: 1.45rem; border-radius: 50%;
    background: var(--brand-navy-tint); color: var(--brand-navy);
    font-family: var(--brand-font-mono); font-size: .72rem; font-weight: 600;
    display: flex; align-items: center; justify-content: center;
}

/* blockquote — key-takeaway callout */
.report-body blockquote {
    margin: 1.1rem 0; padding: .8rem 1rem;
    border-left: 3px solid var(--brand-blue-deep);
    background: var(--brand-paper); border-radius: 0 8px 8px 0;
}
.report-body blockquote p { margin: 0; font-size: .92rem; line-height: 1.6; color: var(--brand-ink); }
.report-body blockquote > :last-child { margin-bottom: 0; }

/* "Instantánea" mini-viz (renders the snapshot, not the dashboard charts) */
.viz-label { font-size: .625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--brand-muted); margin-bottom: .4rem; }
.ai-stack { display: flex; height: 14px; border-radius: 7px; overflow: hidden; background: var(--brand-line-soft); }
.ai-stack span { display: block; height: 100%; }

/* state-distribution donut (CSS conic-gradient — no chart lib on this page) */
.ai-donut {
    width: 168px; height: 168px; border-radius: 50%;
    margin: .25rem auto .25rem; position: relative;
}
.ai-donut__hole {
    position: absolute; inset: 32px; border-radius: 50%; background: var(--brand-white);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    box-shadow: inset 0 0 0 1px var(--brand-line-soft);
}
.ai-donut__num { font-family: var(--brand-font-mono); font-size: 1.5rem; font-weight: 600; color: var(--brand-navy); line-height: 1; }
.ai-donut__lbl { font-size: .6rem; text-transform: uppercase; letter-spacing: .08em; color: var(--brand-muted); margin-top: .2rem; }
.viz-legend { display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin-top: .5rem; font-size: .7rem; color: var(--brand-body); }
.viz-legend i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; margin-right: 4px; vertical-align: middle; }
.mini .r { display: flex; align-items: center; gap: .5rem; margin: .35rem 0; font-size: .75rem; color: var(--brand-body); }
.mini .r .lbl { width: 72px; color: var(--brand-muted); }
.mini .track { flex: 1; height: 10px; background: var(--brand-line-soft); border-radius: 5px; overflow: hidden; }
.mini .fill { height: 100%; border-radius: 5px; }
.mini .val { font-family: var(--brand-font-mono); width: 40px; text-align: right; }

/* state-slice palette: calm positive = largest/positive, rest calm blues/neutral */
.ai-seg--pos { background: var(--brand-positive); }
.ai-seg--1 { background: var(--brand-blue-deep); }
.ai-seg--2 { background: var(--brand-blue); }
.ai-seg--3 { background: var(--brand-navy-tint-border); }
.ai-seg--4 { background: var(--brand-muted); }

@media print {
    .pc-sidebar, .pc-header, .pc-footer, .btn, nav.breadcrumb, .breadcrumb { display: none !important; }
    .pc-container, .pcoded-content { margin: 0 !important; }

    /* Impresion aislada del QR (tag/detail): con body.is-printing-qr solo se imprime la tarjeta
       marcada .tag-qr-printable; visibility (no display) preserva el flujo y evita colapsos de layout. */
    body.is-printing-qr * { visibility: hidden; }
    body.is-printing-qr .tag-qr-printable, body.is-printing-qr .tag-qr-printable * { visibility: visible; }
    body.is-printing-qr .tag-qr-printable { position: absolute; left: 0; top: 0; width: 100%; }
}

/* ===========================================================================
   APP CHROME — "canvas ladder": a recessed gray page behind white cards, with
   the sidebar as the single raised white surface. header / content / footer are
   the gray base (--brand-canvas); cards keep their soft shadow and float on it.
   The header is ABSOLUTE (not fixed) so it scrolls away with the content instead
   of pinning over it — only the sidebar stays fixed.
   =========================================================================== */
body { background: var(--brand-canvas); }

.pc-container,
.pc-header,
.pc-footer { background: var(--brand-canvas); }

.pc-header {
    position: absolute;
    top: 0;
    left: var(--pc-sidebar-width);
    right: 0;
    box-shadow: none;
    border-bottom: 1px solid var(--brand-line);
}

/* elegant lift: a crisp hairline + soft shadow separates the white menu from the beige canvas */
.pc-sidebar {
    box-shadow: 1px 0 0 var(--brand-line), 7px 0 22px -10px rgba(14, 42, 69, 0.16);
    z-index: 1029;
}

/* Desktop sidebar collapse — footer/content/header must shed the sidebar offset */
@media (min-width: 1025px) {
    .pc-sidebar.pc-sidebar-hide {
        width: 0;
        box-shadow: none;
    }

    .pc-sidebar.pc-sidebar-hide ~ .pc-header { left: 0; }

    .pc-sidebar.pc-sidebar-hide ~ .pc-container,
    .pc-sidebar.pc-sidebar-hide ~ .pc-footer { margin-left: 0; }

    /* body class toggled by pcoded.js — backup when sibling selectors miss */
    body.is-sidebar-hidden .pc-header { left: 0; }

    body.is-sidebar-hidden .pc-container,
    body.is-sidebar-hidden .pc-footer { margin-left: 0; }
}

/* sidebar menu hover — navy tint so it reads against the gray (was near-invisible grey) */
.pc-sidebar .pc-navbar .pc-item .pc-link:hover {
    background: var(--brand-navy-tint);
    color: var(--brand-navy);
}

/* ===========================================================================
   SHARED CHROME & COMPONENTS — moved here from inline styles in shared
   partials/fragments (layout, progress modal, grid toolbar, search). DRY.
   =========================================================================== */
/* sidebar icons/arrows are decorative — clicks fall through to the link */
.pc-micon i, .pc-micon svg, .pc-arrow i, .pc-arrow svg { pointer-events: none; }
/* grid toolbar page-size select shouldn't stretch to fill the bar */
.grid-page-size { width: auto; }
/* search fragment row-count select */
.limit-select { max-width: 90px; }

/* ===========================================================================
   DASHBOARD: / (exec overview). Scoped under .dashboard-page so generic
   selectors (.card-header, .state-container, .filter-group) don't leak app-wide.
   Moved here from the page's inline <style> (DRY: styles live in CSS).
   =========================================================================== */
.dashboard-page .kpi-card { transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; }
.dashboard-page .kpi-card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(14, 42, 69, .06) !important; }

/* Affordance generica para tarjetas KPI clicables (detalle de auditoria, etc.): el hover comunica que
   la tarjeta navega. Solo aplica cuando la tarjeta es o esta dentro de un enlace, para no sugerir
   clic en tarjetas KPI puramente informativas (p. ej. metricas de tag/detail). */
a.kpi-card, a .kpi-card { transition: transform .2s ease, box-shadow .2s ease; }
a.kpi-card:hover, a .kpi-card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(14, 42, 69, .06); }

/* Popups del mapa del dashboard (dashboardmap.js): globales a proposito, mapbox monta los popups en
   document.body, fuera del alcance de .dashboard-page. Contrato de clases con dashboardmap.js. */
.dash-map-popup { font-family: var(--brand-font-sans); min-width: 190px; color: var(--brand-ink); }
.dash-map-popup-wide { min-width: 210px; }
.dash-map-popup-meta { font-size: .78rem; color: var(--brand-body); margin-bottom: 6px; }
.dash-map-popup-meta-bordered { border-top: 1px solid var(--brand-line-soft); padding-top: 6px; margin-bottom: 0; }
.dash-map-popup-link { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--brand-navy); font-weight: 600; }
.dash-map-popup-link-split { justify-content: space-between; padding: 6px 0; border-top: 1px solid var(--brand-line-soft); gap: 0; }
.dash-map-popup-inline-link { color: var(--brand-blue-deep); }
.dashboard-page .kpi-card .card-body { padding: .6rem .95rem .3rem; }
.dashboard-page .kpi-card .kpi-figure { font-size: 1.5rem; margin-top: .1rem !important; line-height: 1; }
.dashboard-page .card-header { padding-top: .8rem; padding-bottom: .8rem; }

/* KPI count-up skeleton + emerald liveness pulse */
.dashboard-page .kpi-skeleton {
    display: inline-block; width: 58px; height: 1.4rem; border-radius: 6px; vertical-align: -2px;
    background: linear-gradient(90deg, var(--brand-line-soft) 25%, #F3F3F0 37%, var(--brand-line-soft) 63%);
    background-size: 400% 100%; animation: kpiShimmer 1.3s ease-in-out infinite;
}
.dashboard-page .live-badge {
    display: inline-flex; align-items: center; gap: 7px; font-size: .7rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .07em; color: var(--brand-muted);
}
.dashboard-page .live-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--brand-positive); }
.dashboard-page .live-dot::after {
    content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--brand-positive);
    animation: livePulse 1.9s ease-out infinite;
}
@keyframes kpiShimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@keyframes livePulse { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(3.2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .dashboard-page .kpi-skeleton,
    .dashboard-page .live-dot::after { animation: none; }
}

/* chart cards + scrollable activity lists */
.dashboard-page .chart-box { position: relative; height: 230px; }
.dashboard-page .state-container { min-height: 240px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.dashboard-page .dash-scroll {
    max-height: 392px; overflow-y: auto; overflow-x: hidden;
    scrollbar-width: thin; scrollbar-color: rgba(14, 42, 69, .25) transparent;
}
.dashboard-page .dash-scroll::-webkit-scrollbar { width: 6px; }
.dashboard-page .dash-scroll::-webkit-scrollbar-thumb { background: rgba(14, 42, 69, .22); border-radius: 6px; }

/* chart-card metric caption (top-right count + label) */
.dashboard-page .metric-count { font-size: 1.15rem; line-height: 1; }
.dashboard-page .metric-cap { font-size: .625rem; letter-spacing: .08em; color: var(--brand-muted); }

/* map shell + Handlebars-rendered activity rows */
.dashboard-page .map-shell { min-height: 440px; }
.dashboard-page .list-group-item .avtar { width: 40px; height: 40px; }
.dashboard-page .act-title { font-size: .9rem; }

/* map search + state filter overlay (hidden per request; styled if re-enabled) */
.dashboard-page .filter-group {
    display: none !important;
    font-family: var(--brand-font-sans); font-size: 12px; font-weight: 600;
    position: absolute; top: 16px; right: 16px; z-index: 1000; border-radius: 8px; width: 160px;
    background: var(--brand-white); box-shadow: 0 4px 15px rgba(0, 0, 0, .15); overflow: hidden;
}
.dashboard-page .filter-group input[type='checkbox'] { display: none; }
.dashboard-page .filter-group input[type='checkbox'] + label {
    display: block; cursor: pointer; padding: 8px 12px; border-bottom: 1px solid var(--brand-line-soft);
    margin: 0; text-transform: capitalize; color: var(--brand-body); transition: background-color .2s;
}
.dashboard-page .filter-group label:last-of-type { border: none; }
.dashboard-page .filter-group input[type='checkbox']:checked + label { background: var(--brand-navy-tint); color: var(--brand-navy); font-weight: 700; }
.dashboard-page .filter-group input[type='checkbox']:checked + label:before { content: '\2713'; margin-right: 8px; }

/* ===========================================================================
   TAG DETAIL — /tags/{serial}. The reference entity-detail layout; scoped under
   .tag-detail-page. Moved here from inline style attrs (DRY).
   =========================================================================== */
.tag-detail-page .product-img { height: 200px; object-fit: contain; }
.tag-detail-page .col-icon { width: 45px; }
.tag-detail-page .cell-desc { max-width: 300px; }

/* --- Smart fields: tarjeta de solo lectura (pestaña consulta, no edición) --- */
.tag-detail-page .sfv-read-card {
    padding: 0.75rem 1rem;
    border: 1px solid var(--brand-line);
    border-radius: var(--bs-border-radius, 0.375rem);
    background: var(--brand-paper);
    height: 100%;
}

.tag-detail-page .sfv-read-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--brand-muted);
    margin-bottom: 0.25rem;
}

.tag-detail-page .sfv-read-value {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--brand-ink);
    word-break: break-word;
}

/* Ayuda fija de smartfield (p.ej. tipo Numerico). El JS la inserta DESPUES de la fila del campo, asi
   queda en su propia linea debajo del input (nunca apretada junto al boton de la fila). */
.sfv-hint {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: var(--brand-muted);
}

.sfv-error {
    margin-top: 0.35rem;
    font-size: 0.75rem;
}

/* =====================================================================
   PHOSPHOR DUOTONE — arreglo de la fuente (bloqueante para TODOS los iconos)
   La hoja del set (fonts/phosphor/duotone/style.css, importada por el tema)
   trae un bug: fija font-family "Poppins" con !important, asi que ningun
   glifo se renderiza. Aqui se devuelve a la fuente real. custom.css carga
   de ultimo, y con !important gana el empate.
   Cada icono se dibuja en dos capas (:before al 20% + :after encima), que
   es justo el efecto duotone; no hace falta marcado extra.
   ===================================================================== */
.ph-duotone {
    font-family: "Phosphor-Duotone" !important;
}

/* Cuanto relleno lleva un icono.
   El set dibuja cada icono en DOS capas: :before es la silueta rellena y :after el trazo encima.
   La hoja del set fija el relleno en 0.2, que es el aspecto "duotono" de fabrica y se lee cargado
   al lado de una tipografia fina. Aqui se baja a un apunte de color: se nota la profundidad y el
   icono sigue leyendose como un trazo.
   Para cambiar el aspecto de TODA la aplicacion basta este numero:
     0     trazo puro, sin relleno
     0.08  el valor de la casa, un apunte
     0.2   el duotono de fabrica
   Ojo: el relleno se apaga con opacidad, nunca con display:none. La capa :before ocupa su ancho y
   el trazo se le monta encima con un margen negativo; si se quita del flujo, los iconos se parten. */
:root {
    --brand-icon-fill: 0.08;
}

/* !important por lo mismo que la familia de arriba: la hoja del set fija el relleno por icono con
   DOS clases (.ph-duotone.ph-nombre:before), que gana en especificidad a una sola clase por muy
   tarde que cargue este fichero. */
.ph-duotone:before {
    opacity: var(--brand-icon-fill) !important;
}

/* ===================== SELECT2: acentos de marca sobre el tema oficial bootstrap-5 =====================
   El tema bootstrap-5 aporta la estructura (CDN online / self-hosted air-gapped, ver common_header). Aqui
   solo re-tenimos sus azules de Bootstrap (#0d6efd / #86b7fe) a la paleta Accendo y damos una sombra suave
   al menu. Se igualan los selectores del tema en especificidad; custom.css carga despues y gana el empate. */

/* Foco/abierto: borde y anillo de marca */
.select2-container--bootstrap-5.select2-container--focus .select2-selection,
.select2-container--bootstrap-5.select2-container--open .select2-selection {
    border-color: var(--brand-blue-deep);
    box-shadow: 0 0 0 0.25rem rgba(var(--brand-blue-deep-rgb), 0.25);
}

/* Menu como tarjeta flotante bien definida: borde completo del MISMO tono que el control (coherencia),
   esquinas redondeadas, ligera separacion y sombra suave. El tema bootstrap-5 "pega" el menu al control
   quitando el borde superior (variantes --below/--above); lo restauramos para que sea una tarjeta y no un
   bloque blanco sin borde. overflow:hidden recorta el resaltado de opciones a las esquinas redondeadas. */
.select2-container--bootstrap-5 .select2-dropdown,
.select2-container--bootstrap-5 .select2-dropdown--below,
.select2-container--bootstrap-5 .select2-dropdown--above {
    border: 1px solid var(--brand-line);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 12px 32px -12px rgba(var(--brand-navy-rgb), 0.30), 0 2px 8px rgba(var(--brand-navy-rgb), 0.06);
}

.select2-container--bootstrap-5 .select2-dropdown--below { margin-top: 4px; }
.select2-container--bootstrap-5 .select2-dropdown--above { margin-bottom: 4px; }

/* Opcion resaltada (hover/teclado): tono de marca calmado + texto navy (en vez del gris del tema) */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--highlighted {
    color: var(--brand-navy);
    background-color: rgba(var(--brand-blue-deep-rgb), 0.12);
}

/* Opcion seleccionada: navy de marca en vez del azul de Bootstrap */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--selected,
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[aria-selected=true]:not(.select2-results__option--highlighted) {
    color: #fff;
    background-color: var(--brand-navy);
}

/* Campo de busqueda del menu: integrado en la tarjeta (borde sutil coherente con el menu + mismo radio).
   Antes su borde resaltaba sobre un menu casi sin borde; ahora ambos comparten el mismo lenguaje visual. */
.select2-container--bootstrap-5 .select2-search--dropdown {
    padding: 8px 8px 4px;
}

.select2-container--bootstrap-5 .select2-search--dropdown .select2-search__field {
    border: 1px solid var(--brand-line);
    border-radius: 8px;
    padding: 7px 10px;
}

.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field:focus {
    border-color: var(--brand-blue-deep);
    box-shadow: 0 0 0 0.2rem rgba(var(--brand-blue-deep-rgb), 0.18);
}

/* Altura de la seleccion multiple: el tema pone el buscador en linea a ancho completo, asi que la
   primera etiqueta elegida lo empuja a un segundo renglon y la caja crece al doble. Se deja que el
   contenido fluya y que el buscador ocupe solo el hueco restante: una fila, altura de campo normal. */
.select2-container--bootstrap-5 .select2-selection--multiple {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered {
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
}

.select2-container--bootstrap-5 .select2-selection--multiple .select2-search--inline {
    flex: 1 1 4em;
    width: auto;
    min-width: 4em;
}

/* Chips (seleccion multiple): tono de marca */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
    margin: 0;
    padding-top: .05rem;
    padding-bottom: .05rem;
    color: var(--brand-navy);
    background-color: rgba(var(--brand-blue-deep-rgb), 0.10);
    border-color: rgba(var(--brand-blue-deep-rgb), 0.20);
}

/* --- Paginación client-side (jquery.simplePagination) alineada al patrón Bootstrap 5 de la plantilla --- */
.tag-detail-page .pagination.simple-pagination {
    display: flex;
    flex-wrap: wrap;
    padding-left: 0;
    gap: 0;
}

.tag-detail-page .pagination.simple-pagination > li {
    list-style: none;
}

.tag-detail-page .pagination.simple-pagination > li > a.page-link,
.tag-detail-page .pagination.simple-pagination > li > span.current,
.tag-detail-page .pagination.simple-pagination > li > span.ellipse {
    position: relative;
    display: block;
    min-width: 2rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    line-height: 1.25;
    text-align: center;
    color: var(--brand-blue-deep);
    background-color: var(--brand-white);
    border: 1px solid var(--brand-line);
    text-decoration: none;
    margin-left: -1px;
}

.tag-detail-page .pagination.simple-pagination > li:first-child > a.page-link,
.tag-detail-page .pagination.simple-pagination > li:first-child > span.current,
.tag-detail-page .pagination.simple-pagination > li:first-child > span.ellipse {
    margin-left: 0;
    border-top-left-radius: var(--bs-pagination-border-radius, 0.375rem);
    border-bottom-left-radius: var(--bs-pagination-border-radius, 0.375rem);
}

.tag-detail-page .pagination.simple-pagination > li:last-child > a.page-link,
.tag-detail-page .pagination.simple-pagination > li:last-child > span.current,
.tag-detail-page .pagination.simple-pagination > li:last-child > span.ellipse {
    border-top-right-radius: var(--bs-pagination-border-radius, 0.375rem);
    border-bottom-right-radius: var(--bs-pagination-border-radius, 0.375rem);
}

.tag-detail-page .pagination.simple-pagination > li > a.page-link:hover {
    z-index: 2;
    color: var(--brand-navy);
    background-color: var(--brand-paper);
    border-color: var(--brand-line);
}

.tag-detail-page .pagination.simple-pagination > li.active > span.current {
    z-index: 3;
    color: var(--brand-white);
    background-color: var(--brand-navy);
    border-color: var(--brand-navy);
}

.tag-detail-page .pagination.simple-pagination > li.disabled > span.current,
.tag-detail-page .pagination.simple-pagination > li.disabled > span.ellipse {
    color: var(--brand-muted);
    background-color: var(--brand-white);
    border-color: var(--brand-line);
    pointer-events: none;
}

/* --- QR del EPC: tarjeta centrada con marco suave; el QR hereda el navy de marca --- */
.tag-qr-card .eyebrow { color: var(--brand-muted); }
.tag-qr {
    width: 100%;
    max-width: 196px;
    aspect-ratio: 1 / 1;
    padding: 14px;
    border: 1px solid var(--brand-line);
    border-radius: 14px;
    background: #fff;
    box-shadow: inset 0 0 0 1px rgba(21, 36, 60, .015);
}
.tag-qr svg { display: block; width: 100%; height: 100%; }
/* el fondo blanco del SVG se mantiene; sólo recoloreamos los módulos al navy de marca */
.tag-qr svg path { fill: var(--brand-navy); }
.tag-qr-epc {
    font-family: var(--brand-font-mono);
    font-size: .8rem;
    letter-spacing: .02em;
    color: var(--brand-ink);
    word-break: break-all;
    user-select: all;
}
.tag-qr-copy.is-copied { color: var(--brand-success); border-color: currentColor; }


/* ===========================================================================
   SNAPSHOTS — /analytics/snapshots (KPI cards + airy grouped table)
   =========================================================================== */
.snap-asof { font-size: .78rem; color: var(--brand-body); }
.snap-asof b { color: var(--brand-navy); font-weight: 600; }

/* KPI cards */
.kpi { transition: transform .2s ease, box-shadow .2s ease; }
/* .kpi cards are fully static — no hover lift, no hover shadow (brand: no hover movement) */
.kpi .card-body { padding: .7rem .95rem .5rem; }
.kpi .lbl { font-size: .625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--brand-muted); font-weight: 600; }
.kpi .fig { font-family: var(--brand-font-mono); font-size: 1.55rem; font-weight: 600; color: var(--brand-navy); line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-kind { font-size: .55rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; padding: 1px 5px; border-radius: 4px; }
.kpi-kind.stock { color: var(--brand-blue-deep); background: var(--brand-navy-tint); }
.kpi-kind.flow { color: var(--brand-positive-text); background: rgba(var(--brand-positive-rgb), .12); }

/* trend chip. .kpi-delta es el mismo primitivo (chip pequeño junto a .kpi-figure):
   se agrupa en el mismo selector en vez de duplicar reglas. */
.trend,
.kpi-delta { display: inline-flex; align-items: center; gap: 1px; font-size: .66rem; font-weight: 700; padding: 1px 5px; border-radius: 999px; }
.trend.up,
.kpi-delta.up { color: var(--brand-positive-text); background: rgba(var(--brand-positive-rgb), .12); }
.trend.down,
.kpi-delta.down { color: var(--brand-warning, #B5852A); background: rgba(181, 133, 42, .12); }
.trend.flat,
.kpi-delta.flat { color: var(--brand-muted); background: var(--brand-line-soft); }

/* info icon + Bootstrap tooltip (brand-styled, subtle light) */
.info { color: #C9C9C2; cursor: help; font-size: .82rem; line-height: 1; vertical-align: middle; }
.info:hover { color: var(--brand-blue-deep); }
th .info { font-size: .74rem; margin-left: 3px; }
.snap-tip { --bs-tooltip-bg: #fff; --bs-tooltip-color: var(--brand-body); --bs-tooltip-opacity: 1; }
.snap-tip .tooltip-inner { max-width: 240px; text-align: left; font-family: var(--brand-font-sans); font-size: .7rem; font-weight: 400;
    line-height: 1.5; padding: .55rem .7rem; border: 1px solid var(--brand-line); border-radius: 10px; box-shadow: 0 12px 30px rgba(14, 42, 69, .14); }

/* grouped, pinned header — scoped to the snapshots table only.
   --grp-h locks the group-row height to the cols-row sticky offset so the rowspan'd
   first/last columns share the SAME bottom line as the middle columns (no 1px drift). */
#snapshotsTable thead { --grp-h: 30px; }
#snapshotsTable thead th { position: sticky; background: #fff; z-index: 5; }
#snapshotsTable thead tr.grp th { top: 0; height: var(--grp-h); box-sizing: border-box;
    border: none; font-size: .6rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 700;
    text-align: center; padding: .45rem .5rem .2rem; color: var(--brand-muted); }
#snapshotsTable thead tr.cols th { top: var(--grp-h); }
/* one continuous dark line under the WHOLE header — a real border (not a box-shadow, which gets
   clipped on the sticky FECHA/DETALLE cells), so the pinned columns get the exact same line. */
#snapshotsTable thead tr.cols th,
#snapshotsTable thead tr.grp th.col-pin-left,
#snapshotsTable thead tr.grp th.col-pin-right { border-bottom: 2px solid var(--brand-ink) !important; box-shadow: none !important; }
#snapshotsTable thead tr.grp th.g-stock { color: var(--brand-blue-deep); }
#snapshotsTable thead tr.grp th.g-flow { color: var(--brand-positive-text); }
#snapshotsTable thead tr.grp th.g-delta { color: var(--brand-navy); }
#snapshotsTable thead tr.grp th.col-pin-left, #snapshotsTable thead tr.grp th.col-pin-right { z-index: 8; will-change: transform; }

/* delta cell */
#snapshotsTable td .d { font-size: .72rem; font-weight: 700; font-variant-numeric: tabular-nums; }
#snapshotsTable td .d.up { color: var(--brand-positive-text); }
#snapshotsTable td .d.down { color: var(--brand-warning, #B5852A); }
#snapshotsTable td .d.flat { color: var(--brand-muted); font-weight: 400; }

/* Mirror, not manager: on the analytics & snapshot pages a rise/fall in a neutral stock/flow
   figure (Tags, Inventory, Lent, Movements, Returns, Errores…) is NOT good/bad. So the delta
   chips drop the emerald-up / amber-down verdict and render calm — direction is carried by the
   ▲/▼ glyph and the sign only. The base .trend/.d/.norm-dev rules stay intact for surfaces where
   the customer DID define a good direction (e.g. the dashboard). Higher specificity → wins. */
.analytics-overview-page .trend.up, .analytics-overview-page .trend.down,
.snapshot-detail-page .trend.up,    .snapshot-detail-page .trend.down,
.snapshots-page .trend.up,          .snapshots-page .trend.down,
.ai-insights-page .trend.up,        .ai-insights-page .trend.down {
    color: var(--brand-navy);
    background: var(--brand-line-soft);
}
.snapshots-page #snapshotsTable td .d.up,
.snapshots-page #snapshotsTable td .d.down {
    color: var(--brand-navy);
}
.snapshot-detail-page .norm-dev.up, .snapshot-detail-page .norm-dev.down,
.ai-insights-page .norm-dev.up,     .ai-insights-page .norm-dev.down {
    color: var(--brand-navy);
}

/* toolbar / filters */
.snap-toolbar { display: flex; flex-wrap: wrap; gap: .55rem; align-items: flex-end; }
.snap-field { display: flex; flex-direction: column; gap: 2px; }
.snap-field label { font-size: .56rem; text-transform: uppercase; letter-spacing: .06em; color: var(--brand-muted); font-weight: 600; }
.snap-field .form-control, .snap-field .form-select { font-size: .76rem; padding: .22rem .5rem; height: auto; }

/* snapshot detail view */
.detail-stats { row-gap: .5rem; }
.detail-stat { text-align: center; padding: .45rem .25rem; border-radius: 8px; background: var(--brand-paper); height: 100%; }
.detail-stat .fig { font-family: var(--brand-font-mono); font-size: 1.1rem; font-weight: 600; color: var(--brand-navy); line-height: 1.1; }
.detail-stat .lbl { font-size: .56rem; text-transform: uppercase; letter-spacing: .05em; color: var(--brand-muted); font-weight: 600; margin-top: 2px; }
.detail-churn { font-size: .82rem; }
.detail-churn th { font-size: .6rem; text-transform: uppercase; letter-spacing: .06em; color: var(--brand-muted); font-weight: 600; border-bottom: 1px solid var(--brand-line-soft); }
.detail-churn td { color: var(--brand-body); border-bottom: 1px solid var(--brand-line-soft); }
/* per-stat variation chip sits just under the figure; churn cells get a small inline gap */
.detail-stat .stat-delta { margin-top: 3px; min-height: 1rem; line-height: 1; }
.detail-stat .stat-delta .trend { font-size: .58rem; padding: 0 4px; }
.detail-churn td .trend { font-size: .58rem; padding: 0 4px; }
/* number stays left, variation chip pushed to the cell's right edge */
.detail-churn .churn-cell { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }

/* comparison caption under the detail title */
.snap-compare { font-size: .72rem; color: var(--brand-muted); margin-top: .15rem; }
/* day-to-day navigation: labelled previous/next buttons split left/right */
.snap-daynav { gap: .5rem; }
.daynav-btn { display: inline-flex; align-items: center; gap: .4rem; font-size: .82rem; font-weight: 600;
    color: var(--brand-blue-deep); text-decoration: none; padding: .4rem .8rem;
    border: 1px solid var(--brand-line); border-radius: 8px; }
.daynav-btn:hover { background: var(--brand-paper); color: var(--brand-navy); }
.snap-asof .d-block { font-size: .68rem; color: var(--brand-muted); margin-top: 1px; }

/* ApexCharts canvas in the detail cards */
.snap-chart { margin-top: .25rem; min-height: 280px; }

/* deployment-age ladder — distribution of currently-deployed (LENT) assets by time since last scan */
.age-ladder { display: flex; flex-direction: column; gap: .3rem; margin-top: .45rem; }
.age-row { display: grid; grid-template-columns: 4.6rem 1fr 3rem; align-items: center; gap: .55rem; }
.age-lbl { font-size: .62rem; text-transform: uppercase; letter-spacing: .03em; color: var(--brand-muted); font-weight: 600; }
.age-bar { height: 8px; border-radius: 4px; background: var(--brand-paper); overflow: hidden; }
.age-fill { display: block; height: 100%; border-radius: 4px; background: var(--brand-blue-deep); min-width: 2px; transition: width .3s ease; }
.age-val { font-family: var(--brand-font-mono); font-size: .78rem; color: var(--brand-navy); text-align: right; }

/* "today vs your own 30-day norm" strip — the non-obvious context (flow card) */
.norm-strip { background: var(--brand-paper); border: 1px solid var(--brand-line-soft); border-radius: 10px; padding: .55rem .7rem; margin-bottom: .85rem; }
.norm-title { display: block; margin-bottom: .4rem; }
.norm-cells { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem .9rem; }
@media (min-width: 1200px) { .norm-cells { grid-template-columns: repeat(4, 1fr); } }
.norm-cell { display: flex; flex-direction: column; line-height: 1.25; }
.norm-lbl { font-size: .56rem; text-transform: uppercase; letter-spacing: .05em; color: var(--brand-muted); font-weight: 600; }
.norm-dev { font-family: var(--brand-font-mono); font-size: .98rem; font-weight: 600; }
.norm-dev.up { color: var(--brand-positive-text); }
.norm-dev.down { color: var(--brand-warning, #B5852A); }
.norm-dev.flat { color: var(--brand-muted); }
.norm-base { font-size: .6rem; color: var(--brand-muted); }

/* analytics — time-range switch (segmented, subtle) */
.range-switch { display: inline-flex; border: 1px solid var(--brand-line); border-radius: 8px; overflow: hidden; }
.range-switch a { font-size: .72rem; font-weight: 600; color: var(--brand-muted); text-decoration: none;
    padding: .25rem .65rem; border-left: 1px solid var(--brand-line); }
.range-switch a:first-child { border-left: 0; }
.range-switch a:hover { background: var(--brand-paper); color: var(--brand-navy); }
.range-switch a.is-active { background: var(--brand-navy); color: #fff; }

/* analytics — "based on snapshots …" provenance note (muted, one line, never per-number) */
.prov-note { font-size: .68rem; color: var(--brand-muted); }
.prov-note b { color: var(--brand-navy); font-weight: 600; }

/* page intro — plain-language explainer callout at the top of a view (self-service clarity) */
.page-intro { display: flex; align-items: flex-start; gap: .6rem; background: var(--brand-paper);
    border: 1px solid var(--brand-line-soft); border-radius: 10px; padding: .65rem .85rem;
    margin-bottom: 1rem; font-size: .82rem; color: var(--brand-body); line-height: 1.5; }
.page-intro i { color: var(--brand-blue-deep); font-size: 1rem; flex: 0 0 auto; margin-top: 1px; }

/* =====================================================================
   AI INSIGHTS page (/analytics/ai) — reuses .ai-spark/.insight-brief/.hl/
   .ai-meta/.ai-foot a from the dashboard panel; only the page-specific bits here.
   ===================================================================== */
.ai-card .ai-model { font-family: var(--brand-font-mono); font-size: .58rem; color: var(--brand-muted); text-transform: uppercase; letter-spacing: .04em; }
/* AI timeline rail — profile-metric sparkline over ~30 days with the current day highlighted */
.ai-timeline-meta { min-width: 8.5rem; flex: 0 0 auto; }
.ai-timeline-metric { font-family: var(--brand-font-mono); font-size: .82rem; font-weight: 600; color: var(--brand-navy); }
.ai-timeline-spark { min-height: 56px; }
.ai-highlights { display: flex; flex-direction: column; gap: .35rem; margin: .6rem 0; }
.ai-highlights .hl { padding: .45rem .65rem; border-radius: 8px; background: var(--brand-paper);
    border: 1px solid var(--brand-line-soft); align-items: flex-start; font-size: .82rem; line-height: 1.4; }
/* dot centered on the FIRST text line regardless of type or how many lines the chip wraps to:
   line box = 1.4em, dot = 8px, so centre it at (1.4em - 8px)/2 from the top. */
.ai-highlights .hl .dot { align-self: flex-start; margin-top: calc((1.4em - 8px) / 2); }
.ai-highlights .hl span:last-child { color: var(--brand-navy); }
.ai-report { font-size: .9rem; color: var(--brand-body); line-height: 1.6; margin-top: .75rem; }
.ai-report h1, .ai-report h2 { font-size: 1rem; font-weight: 700; color: var(--brand-navy); margin: 1rem 0 .4rem; }
.ai-report h3 { font-size: .9rem; font-weight: 700; color: var(--brand-navy); margin: .8rem 0 .3rem; }
.ai-report ul, .ai-report ol { padding-left: 1.15rem; margin: .3rem 0; }
.ai-report li { margin: .15rem 0; }
.ai-report blockquote { border-left: 3px solid var(--brand-blue-deep); background: var(--brand-paper); padding: .5rem .8rem; margin: .6rem 0; border-radius: 0 6px 6px 0; color: var(--brand-navy); }
.ai-report strong { color: var(--brand-navy); }
.ai-foot { border-top: 1px solid var(--brand-line-soft); }
.ai-foot b { color: var(--brand-navy); font-weight: 600; }
.ai-disclaimer { font-size: .68rem; color: var(--brand-muted); font-style: italic; line-height: 1.4; }

/* staged generation checklist */
.ai-spinner { width: 16px; height: 16px; border: 2px solid var(--brand-line); border-top-color: var(--brand-blue-deep); border-radius: 50%; animation: ai-spin .8s linear infinite; flex: 0 0 auto; }
@keyframes ai-spin { to { transform: rotate(360deg); } }
.ai-steps { list-style: none; margin: 0; padding: 0; }
.ai-steps .ai-step { display: flex; align-items: center; gap: .5rem; padding: .35rem 0; font-size: .82rem; color: var(--brand-muted); opacity: .5; transition: opacity .25s ease, color .25s ease; }
.ai-steps .ai-step i { color: var(--brand-line); font-size: .9rem; }
.ai-steps .ai-step.is-active { opacity: 1; color: var(--brand-body); }
.ai-steps .ai-step.is-active i { color: var(--brand-positive); }
.ai-steps .ai-step.is-error i { color: var(--brand-warning, #B5852A); }

/* snapshot-truth header + date-jump */
.ai-datejump { max-width: 210px; }
.history-type-select { max-width: 110px; }
.ai-truth .detail-stat { background: var(--brand-paper); }

/* "Insights" badge on the AI card (calm — not a live indicator) */
.ai-badge { display: inline-flex; align-items: center; gap: 6px; font-size: .6rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .08em; color: var(--brand-blue-deep); }
.ai-badge-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-blue-deep); flex: 0 0 auto; }

/* recent-days scrub strip under the two columns */
.ai-recent { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; padding: .25rem 0; }
.ai-recent-chip { font-family: var(--brand-font-mono); font-size: .72rem; color: var(--brand-blue-deep);
    text-decoration: none; padding: .2rem .55rem; border-radius: 6px; border: 1px solid var(--brand-line-soft); }
.ai-recent-chip:hover { background: var(--brand-paper); }
.ai-recent-chip.is-current { background: var(--brand-navy-tint); border-color: var(--brand-navy-tint-border);
    color: var(--brand-navy); font-weight: 600; }

/* history list */
.ai-hist-item { display: block; padding: .5rem .6rem; border-radius: 8px; text-decoration: none; border: 1px solid transparent; margin-bottom: .25rem; }
.ai-hist-item:hover { background: var(--brand-paper); }
.ai-hist-item.is-current { border-color: var(--brand-navy-tint-border); background: var(--brand-navy-tint); }
.ai-hist-item .num { font-family: var(--brand-font-mono); font-size: .72rem; color: var(--brand-blue-deep); font-weight: 600; }
.ai-hist-item .brief { font-size: .78rem; color: var(--brand-body); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* =====================================================================
   Login — split-panel (navy brand left / white form right).
   Layout + skin only; reuses brand tokens and Bootstrap form/button.
   ===================================================================== */
.login-split {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;
    width: 100%;
    /* soft light from upper-centre: almost white at top, cielo blue elsewhere */
    background: radial-gradient(ellipse at 50% 0%, #FFFFFF 0%, #F4F7FB 60%);
}

/* ----- Left: navy brand panel ----- */
.login-brand {
    position: relative;
    flex: 0 0 46%;
    max-width: 46%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 52px;
    /* Accendo hero depth: a blue glow top-right + a deep-blue glow bottom-left over
       the navy — reads "blue to blue" across the panel; the wave field sits over it. */
    background:
        radial-gradient(120% 62% at 85% 6%, rgba(73, 141, 190, .32) 0%, rgba(21, 36, 60, 0) 60%),
        radial-gradient(115% 58% at 8% 100%, rgba(44, 90, 130, .42) 0%, rgba(21, 36, 60, 0) 56%),
        linear-gradient(160deg, #1B2B48 0%, #15243C 52%, #0E1A2C 100%);
    color: var(--brand-white);
    overflow: hidden;
}

.login-brand > *:not(.login-wave-field) { position: relative; z-index: 1; }
/* Accendo signature wave — the calm oscilloscope line bundle from the marketing-site
   hero, ported as an animated <canvas> (no deps, no CDN — airgap-safe; honors
   prefers-reduced-motion with a single static frame, pauses when offscreen).
   Sits BEHIND the panel content. Replaces the old login orb. */
.login-wave-field {
    position: absolute; inset: 0; z-index: 0;
    width: 100%; height: 100%; pointer-events: none;
}

.login-brand__logo { height: 68px; width: auto; }

/* whiten the (emerald) Trackvy + dark Accendo marks — no white asset exists */
.login-brand__logo--white,
.login-brand__accendo { filter: brightness(0) invert(1); }

/* eyebrow/label look — Geist sans (no mono), uppercase, tracked */
.login-eyebrow,
.login-label {
    font-family: var(--brand-font-sans);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--brand-muted);
}

.login-brand__eyebrow {
    color: rgba(255, 255, 255, .5);
    margin-bottom: 18px;
}

.login-brand__headline {
    font-family: var(--brand-font-sans);
    font-weight: 600;
    font-size: 40px;
    line-height: 1.18;
    letter-spacing: -0.02em;
    margin: 0 0 18px;
    max-width: 18ch;
    /* near-white, but a touch below pure white so the Trackvy + Accendo logos stay the true whites */
    color: rgba(255, 255, 255, .92);
}

/* second headline line — own line, light-blue accent (Accendo hero accent on navy) */
.login-brand__accent { display: block; color: var(--brand-blue-bright); font-weight: 700; }

.login-brand__support {
    color: rgba(255, 255, 255, .75);
    font-size: 17px;
    line-height: 1.6;
    margin: 0;
    max-width: 42ch;
}

.login-brand__footer {
    display: flex;
    align-items: center;
    gap: 10px;
    color: rgba(255, 255, 255, .40);
    font-size: 13px;
}

.login-brand__accendo { height: 25px; width: auto; opacity: .9; }
/* small Trackvy icon replacing the form eyebrow (≈ width of "Ingre") */
.login-form__icon { width: 52px; height: auto; display: block; margin-bottom: 10px; }

/* ----- Right: white form panel ----- */
.login-form {
    flex: 1 1 54%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 32px;
}

/* language switcher — a small segmented pill (globe + EN/ES), centered under the support link */
.login-lang {
    display: flex;
    align-items: center;
    gap: 4px;
    width: fit-content;
    margin: 18px auto 0;
    padding: 3px 5px 3px 9px;
    border: 1px solid var(--brand-line);
    border-radius: 999px;
    font-family: var(--brand-font-sans);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
}
.login-lang__icon { color: var(--brand-muted); font-size: 0.9rem; line-height: 1; }
.login-lang a {
    color: var(--brand-muted);
    text-decoration: none;
    padding: 3px 10px;
    border-radius: 999px;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}
.login-lang a:hover { color: var(--brand-navy); }
.login-lang a.is-active { color: var(--brand-navy); background: var(--brand-navy-tint); }

.login-form__inner { width: 100%; max-width: 380px; }

/* mobile-only brand marks (shown when the navy panel is hidden) — see media query below */
.login-form__logo,
.login-form__footer { display: none; }

.login-form__eyebrow { display: block; margin-bottom: 10px; }

.login-form__title {
    font-family: var(--brand-font-sans);
    font-weight: 600;
    font-size: 28px;
    letter-spacing: -0.02em;
    color: var(--brand-ink);
    margin: 0 0 6px;
}

.login-form__subtitle {
    color: var(--brand-muted);
    font-size: 14px;
    margin: 0 0 28px;
}

.login-label { display: block; margin-bottom: 7px; }

.login-field { margin-bottom: 18px; }

.login-split .form-control {
    border-color: var(--brand-line);
    border-radius: 7px;
    padding: 10px 12px;
    height: auto;
}

/* input with a leading icon + inline validation (email check / error states) */
.login-input { position: relative; }
.login-input .form-control { padding-left: 38px; }
.login-input__lead {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    color: var(--brand-muted); font-size: 1.05rem; line-height: 1; pointer-events: none;
}
.login-input:focus-within .login-input__lead { color: var(--brand-blue-deep); }
.login-field:focus-within .login-label { color: var(--brand-navy); }
.login-input__ok {
    position: absolute; right: 12px; top: 50%; transform: translateY(-50%) scale(.7);
    opacity: 0; color: var(--brand-positive, #2F7A5B);
    transition: opacity .2s ease, transform .2s ease; pointer-events: none;
}
.login-input.is-valid .login-input__ok { opacity: 1; transform: translateY(-50%) scale(1); }
.login-input.is-valid .form-control { padding-right: 38px; }
.login-input.is-error .form-control { border-color: var(--brand-danger, #A6402F); }
.login-input.is-error .form-control:focus { box-shadow: 0 0 0 3px rgba(166, 64, 47, .14); }

/* small hint line under a field (email error / caps-lock) */
.login-hint { margin: 6px 0 0; font-size: .78rem; display: flex; align-items: center; gap: 6px; color: var(--brand-muted); }
.login-hint[hidden] { display: none; }
.login-hint > i { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.login-hint--error { color: var(--brand-danger, #A6402F); }
.login-caps { color: var(--brand-blue-deep); }

/* password show/hide eye toggle */
.login-password { position: relative; }
.login-password .form-control { padding-right: 42px; }

.login-eye {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--brand-muted);
    cursor: pointer;
}
.login-eye:hover { color: var(--brand-blue-deep); }

/* primary action — navy fill, white text (matches the app's primary button) */
.login-submit {
    gap: 8px;
    padding: 11px 16px;
    font-weight: 600;
    margin-top: 4px;
    --bs-btn-bg: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-color: #ffffff;
    --bs-btn-hover-bg: var(--brand-navy-600);
    --bs-btn-hover-border-color: var(--brand-navy-600);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-active-bg: var(--brand-navy-700);
    --bs-btn-active-border-color: var(--brand-navy-700);
    --bs-btn-active-color: #ffffff;
}

/* submit: idle label swaps to a spinner while authenticating (JS toggles .is-loading) */
.login-submit__idle,
.login-submit__busy { display: inline-flex; align-items: center; gap: 8px; }
.login-submit__busy { display: none; }
.login-submit.is-loading { pointer-events: none; }
.login-submit.is-loading .login-submit__idle { display: none; }
.login-submit.is-loading .login-submit__busy { display: inline-flex; }
.login-spin { animation: login-spin .7s linear infinite; }
@keyframes login-spin { to { transform: rotate(360deg); } }

.login-support {
    color: var(--brand-muted);
    font-size: 13px;
    text-align: center;
    margin: 18px 0 0;
}
.login-support a { color: var(--brand-blue-deep); text-decoration: none; }
.login-support a:hover { color: var(--brand-navy); text-decoration: underline; }

/* pretty error alert (container only — text comes from login JS) */
.login-alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin-bottom: 22px;
    border: 1px solid var(--brand-danger-tint-border);
    border-radius: 7px;
    background: var(--brand-danger-tint);
    color: var(--brand-danger);
}
.login-alert > i { font-size: 18px; line-height: 1.4; flex: 0 0 auto; }
.login-alert p { font-size: 14px; line-height: 1.4; }
.login-alert .btn-close {
    margin-left: auto;
    padding: 2px;
    font-size: 10px;
    flex: 0 0 auto;
}

/* ----- Responsive: drop the navy panel, leave the plain white form ----- */
@media (max-width: 991.98px) {
    .login-brand { display: none; }
    .login-form { flex: 1 1 100%; padding: 40px 24px; }

    /* navy panel is gone — surface the Trackvy logo above the form and Accendo below it,
       both centered. Use the normal-colour assets (no white filter) on the light panel. */
    .login-form__logo { display: block; text-align: center; margin-bottom: 28px; }
    .login-form__logo img { height: 64px; width: auto; }

    /* el logotipo completo ya identifica la marca: ocultamos el ícono para no duplicarla */
    .login-form__icon { display: none; }

    /* "Desarrollado por" on top, Accendo logo under it, centered */
    .login-form__footer {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        margin-top: 28px;
        color: var(--brand-muted);
        font-size: 13px;
        text-align: center;
    }
    .login-form__footer img { height: 20px; width: auto; }
}

/* ── Legal document pages (/terms, /legal/*) ───────────────────────────── */
.legal-page { background: var(--brand-canvas); min-height: 100vh; font-family: var(--brand-font-sans); }

.legal-topbar {
    background: var(--brand-white);
    border-bottom: 1px solid var(--brand-line);
    padding: 1.25rem 2rem;
    display: flex;
    justify-content: center;
    align-items: center;
}
.legal-logo {
    height: 36px;
    width: auto;
}

.legal-body {
    max-width: 780px;
    margin: 2.5rem auto;
    padding: 0 1.5rem 5rem;
}

.legal-meta {
    background: var(--brand-white);
    border: 1px solid var(--brand-line);
    border-radius: var(--border-radius);
    padding: 1rem 1.5rem;
    margin-bottom: 2rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 2rem;
}
.legal-meta span {
    font-size: 0.8rem;
    color: var(--brand-muted);
}
.legal-meta span strong {
    color: var(--brand-body);
    font-weight: 600;
}

.legal-doc-title {
    font-size: 1.625rem;
    font-weight: 700;
    color: var(--brand-navy);
    line-height: 1.2;
    margin: 0 0 0.375rem;
}
.legal-doc-sub {
    font-size: 0.875rem;
    color: var(--brand-muted);
    margin: 0 0 2rem;
}

.legal-toc {
    background: var(--brand-paper);
    border: 1px solid var(--brand-line);
    border-left: 3px solid var(--brand-navy);
    border-radius: var(--border-radius);
    padding: 1.125rem 1.5rem;
    margin-bottom: 2.5rem;
}
.legal-toc .toc-label {
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--brand-muted);
    margin-bottom: 0.75rem;
}
.legal-toc ol {
    margin: 0;
    padding-left: 1.25rem;
    column-count: 2;
    column-gap: 2rem;
}
.legal-toc li { margin-bottom: 0.3rem; }
.legal-toc a {
    font-size: 0.8125rem;
    color: var(--brand-blue-deep);
    text-decoration: none;
}
.legal-toc a:hover { text-decoration: underline; }

.legal-section { margin-bottom: 2.75rem; }
.legal-section h2 {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--brand-navy);
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--brand-line);
    margin-bottom: 1.125rem;
    display: flex;
    gap: 0.625rem;
    align-items: baseline;
}
.legal-section h2 .num {
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--brand-muted);
    flex-shrink: 0;
}
.legal-section p {
    font-size: 0.9375rem;
    line-height: 1.8;
    color: var(--brand-body);
    margin-bottom: 0.875rem;
}
.legal-section ol[type="a"],
.legal-section ul {
    padding-left: 1.5rem;
    margin-bottom: 0.875rem;
}
.legal-section li {
    font-size: 0.9375rem;
    line-height: 1.8;
    color: var(--brand-body);
    margin-bottom: 0.375rem;
}

.non-waivable-banner {
    background: var(--brand-navy);
    color: #fff;
    border-radius: var(--border-radius);
    padding: 1rem 1.25rem 1rem 1.5rem;
    margin-bottom: 1.5rem;
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
}
.non-waivable-banner .nw-icon {
    font-size: 1.25rem;
    line-height: 1;
    color: var(--brand-blue-bright);
    flex-shrink: 0;
    padding-top: 0.1rem;
}
.non-waivable-banner .nw-text {
    font-size: 0.8125rem;
    line-height: 1.55;
    color: rgba(255,255,255,0.9);
}
.non-waivable-banner .nw-text strong {
    display: block;
    color: #fff;
    font-weight: 700;
    margin-bottom: 0.2rem;
    font-size: 0.875rem;
}

.legal-footer-bar {
    margin-top: 3rem;
    padding-top: 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.legal-footer-bar p {
    font-size: 0.8rem;
    color: var(--brand-muted);
    margin: 0;
}
.legal-footer-bar a { color: var(--brand-blue-deep); text-decoration: none; }
.legal-footer-bar a:hover { text-decoration: underline; }

@media (max-width: 600px) {
    .legal-toc ol { column-count: 1; }
    .legal-body { padding: 0 1rem 4rem; }
    .legal-topbar { padding: 0.875rem 1rem; }
}

/* =====================================================================
   Analytics Overview — /analytics/overview
   Pulse strip, two-column card layout, suggestion card.
   ===================================================================== */

/* Activity pulse strip — calm neutral strip (paper + hairline border, like the
   rest of the app's surfaces), only rendered when events_30d > 0. No navy block. */
.analytics-pulse-strip {
    background: var(--brand-paper);
    color: var(--brand-body);
    border: 1px solid var(--brand-line);
    border-radius: var(--border-radius);
    padding: .65rem 1.25rem;
}
.analytics-pulse-strip .kpi-figure {
    font-size: 1.15rem;
    font-family: var(--brand-font-sans);
    font-weight: 700;
    color: var(--brand-navy);
}

/* Two-column analytics card body: col-data (left) + col-narrative (right) */
.analytics-card-body {
    display: flex;
    gap: 1.75rem;
    align-items: flex-start;
}
.analytics-card-body .col-data { flex: 0 0 58%; min-width: 0; }
.analytics-card-body .col-narrative { flex: 1 1 42%; min-width: 0; }

/* Narrative column: calmer typography, brand-muted with callout emphasis */
.analytics-narrative {
    font-size: .8125rem;
    line-height: 1.65;
    color: var(--brand-muted);
    border-left: 3px solid var(--brand-line);
    padding-left: 1rem;
    margin-top: .25rem;
}
.analytics-narrative strong { color: var(--brand-body); font-weight: 600; }

/* Collapse to single column on smaller screens */
@media (max-width: 767.98px) {
    .analytics-card-body { flex-direction: column; }
    .analytics-card-body .col-data,
    .analytics-card-body .col-narrative { flex: 1 1 auto; }
    .analytics-narrative { border-left: none; padding-left: 0; border-top: 1px solid var(--brand-line); padding-top: .75rem; }
}

/* =====================================================================
   ENTITY-DETAIL HERO — shared identity header for detail pages
   (country/detail, category/detail, location/detail). Tokens only.
   ===================================================================== */
.entity-card { overflow: hidden; }
.entity-hero {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.5rem 1.5rem 1.25rem;
    background: linear-gradient(135deg, var(--brand-navy) 0%, var(--brand-indigo) 100%);
    color: var(--brand-white);
}
.entity-chip {
    width: 56px;
    height: 56px;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 14px;
    background: rgba(255, 255, 255, .12);
    color: var(--brand-white);
    font-size: 1.6rem;
}
.entity-hero-text { min-width: 0; }
.entity-hero .eyebrow { color: var(--brand-blue-bright); margin-bottom: .15rem; }
.entity-name {
    font-family: var(--brand-font-sans);
    font-weight: 600;
    font-size: 1.5rem;
    color: var(--brand-white);
    margin: 0 0 .35rem;
    line-height: 1.15;
    overflow-wrap: anywhere;
}
.entity-hero .status-pill { background: rgba(255, 255, 255, .16); color: var(--brand-white); border-color: rgba(255, 255, 255, .22); }
.entity-hero .status-pill.mono { font-family: var(--brand-font-mono); }

/* =====================================================================
   LOCATION SPATIAL MAPS — globe, floor-plan viewer, editor, dropzone.
   Indoor plan needs no tile server (air-gap safe). Brand tokens only.
   ===================================================================== */

/* --- mapa selector de coordenadas (Leaflet raster + Mapbox) del formulario de alta/edición de ubicación y del detalle.
   La altura vivía en el legacy override.css (que ya NO se carga), así que el contenedor colapsaba a ~2px y el mapa no se
   veía. Se restituye aquí (la hoja activa). --- */
.form-map { height: 320px; width: 100%; border-radius: 10px; overflow: hidden; }
.detail-map { height: 300px; width: 100%; border-radius: 10px; overflow: hidden; }

/* --- globe (Mapbox) on the locations index + GEO root detail --- */
.lmap-globe-card { overflow: hidden; }
.lmap-globe { width: 100%; height: 420px; }
.lmap-globe .mapboxgl-popup-content { border-radius: 10px; padding: .5rem .7rem; box-shadow: 0 12px 30px rgba(14, 42, 69, .16); }
.lmap-globe-pop {
    display: inline-flex; align-items: center; gap: .5rem;
    text-decoration: none; color: var(--brand-navy); font-weight: 600;
    font-family: var(--brand-font-sans);
}
.lmap-globe-pop:hover { color: var(--brand-blue-deep); }
/* "Estás aquí": pin verde de marca + etiqueta con el nombre, para distinguir la ubicación que se está viendo */
.lmap-globe-highlight {
    color: var(--brand-green);
    font-size: 2.3rem; line-height: 1; cursor: default;
    filter: drop-shadow(0 3px 6px rgba(14, 42, 69, .35));
}
.lmap-globe-hl-popup .mapboxgl-popup-content {
    background: var(--brand-green); border-radius: 8px; padding: .25rem .6rem;
    box-shadow: 0 8px 20px rgba(23, 204, 152, .35);
}
.lmap-globe-hl-popup.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip { border-top-color: var(--brand-green); }
.lmap-globe-hl-popup.mapboxgl-popup-anchor-top .mapboxgl-popup-tip { border-bottom-color: var(--brand-green); }
.lmap-globe-hl-name { color: #fff; font-weight: 700; font-size: .8rem; white-space: nowrap; }

/* --- the spatial panel shell (detail page) --- */
.lmap-panel-card { overflow: hidden; }
.lmap-panel,
.lmap-panel-card .lmap-panel { position: relative; width: 100%; height: 480px; }
.lmap-panel .lmap-globe { height: 480px; }

/* Sin plano: el panel NO ocupa la altura de un mapa vacío; se colapsa a una fila compacta (subir/aviso). */
.lmap-panel.lmap-panel--empty,
.lmap-panel-card .lmap-panel.lmap-panel--empty { height: auto; background: transparent; }
.lmap-emptyrow {
    display: flex; align-items: center; gap: .6rem;
    padding: .7rem .9rem; color: var(--brand-body); font-size: .85rem;
}
.lmap-emptyrow-icon { font-size: 1.2rem; color: var(--brand-muted); }
.lmap-emptyrow-text { font-weight: 600; color: var(--brand-navy); }
.lmap-emptyrow-hint { color: var(--brand-muted); font-size: .78rem; }
/* variante "subir": la fila entera es zona de arrastre/clic (discreta, no obliga a cargar un plano) */
.lmap-emptyrow.is-upload {
    margin: .5rem; cursor: pointer;
    border: 1.5px dashed var(--brand-line); border-radius: 10px;
    transition: border-color .15s ease, background .15s ease;
}
.lmap-emptyrow.is-upload .lmap-emptyrow-icon { color: var(--brand-blue-deep); }
.lmap-emptyrow.is-upload:hover,
.lmap-emptyrow.is-upload.is-over { border-color: var(--brand-blue-deep); background: var(--brand-navy-tint); }

/* --- the floor-plan canvas (Leaflet CRS.Simple) --- */
.lmap-panel { background: var(--brand-canvas); }
.lmap-canvas { position: absolute; inset: 0; width: 100%; height: 100%; background: var(--brand-canvas); }
.lmap-canvas.leaflet-container { font-family: var(--brand-font-sans); }
.lmap-overlay { image-rendering: auto; filter: saturate(.92); }
/* plan fades in once the overlay image loads */
.lmap-overlay { animation: lmapFade .5s ease; }
@keyframes lmapFade { from { opacity: 0; } to { opacity: 1; } }

/* zone polygons + dot markers (canvas-rendered; labels are DOM tooltips) */
.lmap-zone-label.leaflet-tooltip,
.lmap-dot-label.leaflet-tooltip {
    background: rgba(255, 255, 255, .92);
    border: 1px solid var(--brand-line);
    border-radius: 7px;
    box-shadow: 0 4px 12px rgba(14, 42, 69, .10);
    color: var(--brand-navy);
    font-family: var(--brand-font-sans);
    font-size: .72rem;
    font-weight: 600;
    padding: .15rem .45rem;
}
.lmap-zone-label.leaflet-tooltip::before,
.lmap-dot-label.leaflet-tooltip::before { display: none; }
.lmap-zone-name { color: var(--brand-navy); }
.lmap-zone-badge {
    display: inline-block; margin-left: .35rem; padding: 0 .35rem;
    border-radius: 999px; background: var(--brand-navy-tint);
    color: var(--brand-blue-deep); font-size: .64rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* branded dot pin (divIcon). El color base puede teñirse por ocupación (heat) vía --dot-heat (lo fija map.js por
   nodo); hover/activo declaran color explícito y ganan por especificidad, así el resalte sigue funcionando. */
.lmap-dot-pin {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px;
    color: var(--dot-heat, var(--brand-navy));
    font-size: 1.05rem;
    filter: drop-shadow(0 2px 3px rgba(14, 42, 69, .25));
    transition: transform .15s ease, color .15s ease;
}
.lmap-dot:hover .lmap-dot-pin { transform: scale(1.18); color: var(--brand-blue-deep); }
.lmap-dot.is-active .lmap-dot-pin { color: var(--brand-blue-deep); transform: scale(1.18); }

/* --- breadcrumb rail over the plan --- */
.lmap-crumb {
    position: absolute; bottom: 12px; left: 12px; z-index: 600;
    display: flex; align-items: center; flex-wrap: wrap; gap: .15rem;
    max-width: calc(100% - 24px);
    background: rgba(255, 255, 255, .94);
    border: 1px solid var(--brand-line);
    border-radius: 10px;
    padding: .3rem .5rem;
    box-shadow: 0 6px 18px rgba(14, 42, 69, .10);
}
.lmap-crumb-item {
    border: 0; background: transparent;
    color: var(--brand-blue-deep); font-weight: 600;
    font-size: .76rem; padding: .1rem .35rem; border-radius: 6px;
    cursor: pointer; transition: background .15s ease, color .15s ease;
}
.lmap-crumb-item:hover { background: var(--brand-navy-tint); color: var(--brand-navy); }
.lmap-crumb-item.is-current { color: var(--brand-navy); cursor: default; }
.lmap-crumb-sep { color: var(--brand-muted); font-size: .7rem; }

/* --- floating dot info card --- */
.lmap-info {
    position: absolute; right: 12px; bottom: 12px; z-index: 650;
    width: 220px;
    background: var(--brand-white);
    border: 1px solid var(--brand-line);
    border-radius: 12px;
    padding: .85rem .9rem;
    box-shadow: 0 14px 36px rgba(14, 42, 69, .16);
    animation: lmapFade .25s ease;
}
.lmap-info-close {
    position: absolute; top: .4rem; right: .4rem;
    border: 0; background: transparent; color: var(--brand-muted);
    cursor: pointer; line-height: 1; padding: .15rem;
}
.lmap-info-close:hover { color: var(--brand-navy); }
.lmap-info-name { font-weight: 600; color: var(--brand-navy); margin-bottom: .25rem; }
.lmap-info-tags { font-size: .76rem; color: var(--brand-body); margin-bottom: .6rem; }
.lmap-info-tags i { color: var(--brand-blue-deep); }
.lmap-info-link {
    display: inline-flex; align-items: center; gap: .35rem;
    text-decoration: none; color: var(--brand-blue-deep); font-weight: 600; font-size: .8rem;
}
.lmap-info-link:hover { color: var(--brand-navy); }

/* --- editor: toolbar buttons over the plan --- */
/* banda de ayuda del editor (abajo-derecha): explica las herramientas sin chocar con los botones (arriba), el
   breadcrumb (abajo-izquierda) ni el rail (arriba-derecha). La tarjeta de info no aparece en modo edición. */
.lmap-edit-help {
    position: absolute; bottom: 12px; right: 12px; z-index: 590;
    display: inline-flex; align-items: flex-start; gap: .4rem; max-width: min(60%, 420px);
    padding: .45rem .75rem; border-radius: 14px;
    background: rgba(255, 255, 255, .96); border: 1px solid var(--brand-line);
    box-shadow: 0 6px 18px rgba(14, 42, 69, .12);
    font-size: .75rem; line-height: 1.35; color: var(--brand-body);
}
.lmap-edit-help i { color: var(--brand-blue-deep); font-size: .95rem; margin-top: .05rem; flex: 0 0 auto; }
/* el texto puede ENVOLVER (antes se truncaba con puntos suspensivos y se perdía la explicación) */
.lmap-edit-help span { white-space: normal; }

.lmap-edit-toggle { position: absolute; top: 12px; right: 12px; z-index: 600; }
/* Reemplazar plano es DESTRUCTIVO (restablece/reescala posiciones): se viste como acción de peligro suave para que no
   se confunda con el toggle benigno de "Editar plano". Solo se tiñe de rojo de marca al pasar el cursor. */
.lmap-replace-plan {
    position: absolute; top: 12px; right: 130px; z-index: 600;
    border-color: var(--brand-danger-line, var(--brand-line));
    color: var(--brand-danger);
}
.lmap-replace-plan:hover { background: var(--brand-danger-tint); border-color: var(--brand-danger); color: var(--brand-danger); }
.lmap-file-hidden { display: none; }

/* --- chip "editando dentro de «zona»" (modo edición): contexto de anidación siempre visible --- */
.lmap-editing-chip {
    position: absolute; top: 12px; left: 50px; z-index: 600;
    display: inline-flex; align-items: center; gap: .4rem; max-width: 40%;
    padding: .3rem .7rem; border-radius: 999px;
    background: var(--brand-navy); color: #fff;
    font-size: .74rem; font-weight: 600;
    box-shadow: 0 6px 18px rgba(14, 42, 69, .22);
}
.lmap-editing-chip i { font-size: .9rem; opacity: .85; }
.lmap-editing-chip b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- chip de estado de guardado (debounce de persistShape): Guardando… / Guardado / error de marca --- */
.lmap-save-status {
    position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%); z-index: 610;
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .3rem .75rem; border-radius: 999px;
    background: rgba(255, 255, 255, .97); border: 1px solid var(--brand-line);
    box-shadow: 0 6px 18px rgba(14, 42, 69, .14);
    font-size: .74rem; font-weight: 600; color: var(--brand-body);
    opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.lmap-save-status.is-shown { opacity: 1; }
.lmap-save-status.is-saving { color: var(--brand-blue-deep); }
.lmap-save-status.is-saved i { color: var(--brand-positive); }
.lmap-save-status.is-error { color: var(--brand-danger); border-color: var(--brand-danger); }
.lmap-save-status .lmap-spin { animation: lmapSpin .7s linear infinite; display: inline-flex; }
@keyframes lmapSpin { to { transform: rotate(360deg); } }

/* --- capa de mapa de calor (L.imageOverlay del plano): Leaflet la posiciona/escala; sobre el plano, bajo zonas/pines --- */
.lmap-heat { pointer-events: none; }

/* --- toggle encender/apagar el mapa de calor (arriba-izquierda, bajo el zoom, sobre la leyenda) --- */
.lmap-heat-toggle {
    position: absolute; top: 84px; left: 10px; z-index: 601;
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .3rem .6rem; border-radius: 999px; cursor: pointer;
    background: rgba(255, 255, 255, .94); border: 1px solid var(--brand-line);
    box-shadow: 0 6px 18px rgba(14, 42, 69, .10);
    font-size: .72rem; font-weight: 600; color: var(--brand-muted);
    transition: color .15s ease, border-color .15s ease;
}
.lmap-heat-toggle i { font-size: .9rem; }
.lmap-heat-toggle.is-on { color: var(--brand-blue-deep); border-color: var(--brand-blue-deep); }
.lmap-heat-toggle.is-on i { color: #C93A2E; } /* la llama encendida en rojo del extremo caliente */
.lmap-heat-toggle:hover { color: var(--brand-navy); }

/* --- leyenda de ocupación (heat): escala fría->caliente. Va ARRIBA-IZQUIERDA, bajo el toggle, para no chocar con el
   breadcrumb (abajo-izq). Se oculta en edición (ese rincón lo usa la barra de Geoman) y cuando el calor está apagado. */
.lmap-legend {
    position: absolute; top: 122px; left: 10px; z-index: 600;
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .3rem .6rem; border-radius: 10px;
    background: rgba(255, 255, 255, .94); border: 1px solid var(--brand-line);
    box-shadow: 0 6px 18px rgba(14, 42, 69, .10);
    font-size: .68rem; font-weight: 600; color: var(--brand-muted);
}
.lmap-legend-bar {
    width: 96px; height: 8px; border-radius: 999px;
    /* coincide con la paleta del campo de calor (HEAT_STOPS en map.js): frío azul -> caliente rojo */
    background: linear-gradient(90deg,
        rgb(40, 92, 170), rgb(56, 162, 168), rgb(92, 178, 96),
        rgb(240, 204, 72), rgb(232, 142, 52), rgb(201, 58, 46));
}
.lmap-legend-lo, .lmap-legend-hi { font-variant-numeric: tabular-nums; }

/* --- aviso "recarga para actualizar el plano" tras crear/ubicar una ubicación en el plano (arriba-centro) --- */
.lmap-reload-notice {
    position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 660;
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .35rem .5rem .35rem .8rem; border-radius: 999px;
    background: var(--brand-navy); color: #fff;
    box-shadow: 0 10px 28px rgba(14, 42, 69, .28);
    font-size: .76rem; font-weight: 600;
    animation: lmapFade .25s ease;
}
.lmap-reload-notice > i { font-size: .95rem; opacity: .9; }
.lmap-reload-btn {
    border: 0; border-radius: 999px; cursor: pointer;
    padding: .2rem .6rem; font-size: .74rem; font-weight: 700;
    background: #fff; color: var(--brand-navy);
}
.lmap-reload-btn:hover { background: var(--brand-navy-tint); }
.lmap-reload-close {
    border: 0; background: transparent; color: rgba(255, 255, 255, .8);
    cursor: pointer; padding: .1rem; line-height: 1; display: inline-flex;
}
.lmap-reload-close:hover { color: #fff; }

/* --- "sin ubicar" rail (editor) --- */
.lmap-rail {
    position: absolute; top: 56px; right: 12px; z-index: 600;
    width: 210px; max-height: calc(100% - 80px); overflow: auto;
    background: var(--brand-white);
    border: 1px solid var(--brand-line);
    border-radius: 12px;
    box-shadow: 0 10px 28px rgba(14, 42, 69, .12);
}
.lmap-rail-head {
    display: flex; align-items: center; gap: .35rem;
    padding: .6rem .75rem; border-bottom: 1px solid var(--brand-line-soft);
    font-weight: 600; font-size: .78rem; color: var(--brand-navy);
}
.lmap-rail-count {
    margin-left: auto; padding: 0 .4rem; border-radius: 999px;
    background: var(--brand-navy-tint); color: var(--brand-blue-deep);
    font-size: .68rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.lmap-rail-body { padding: .35rem; }
.lmap-rail-item {
    display: flex; align-items: center; gap: .45rem;
    padding: .4rem .5rem; border-radius: 8px;
    font-size: .78rem; color: var(--brand-body); cursor: default;
}
.lmap-rail-item i { color: var(--brand-blue-deep); }
.lmap-rail-item:hover { background: var(--brand-paper); }
.lmap-rail-item span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lmap-rail-item.is-placed i { color: var(--brand-navy); }
/* botón "quitar del plano" (DELETE /shape): discreto, se tiñe de rojo solo en su hover */
.lmap-rail-remove {
    flex-shrink: 0; border: 0; background: transparent; cursor: pointer;
    padding: .15rem; border-radius: 6px; color: var(--brand-muted);
    display: inline-flex; align-items: center; transition: background .15s ease, color .15s ease;
}
.lmap-rail-remove:hover { background: var(--brand-danger-tint); color: var(--brand-danger); }
.lmap-rail-empty { padding: .6rem .75rem; color: var(--brand-muted); font-size: .76rem; }

/* --- panorama del edificio en la cabecera del rail: "N de M ubicadas" + barra de progreso --- */
.lmap-rail-overview {
    padding: .6rem .75rem .7rem;
    border-bottom: 1px solid var(--brand-line-soft);
    background: var(--brand-paper);
}
.lmap-rail-overview-top {
    display: flex; align-items: baseline; gap: .35rem; margin-bottom: .4rem;
    font-size: .74rem; color: var(--brand-body);
}
.lmap-rail-overview-num { font-weight: 700; color: var(--brand-navy); font-variant-numeric: tabular-nums; }
.lmap-rail-overview-bar { height: 6px; border-radius: 999px; background: var(--brand-line-soft); overflow: hidden; }
.lmap-rail-overview-fill {
    height: 100%; border-radius: 999px; background: var(--brand-positive);
    transition: width .5s cubic-bezier(.4, 0, .2, 1);
}

/* subtítulo de sección dentro del rail (zona actual / otras zonas / ubicadas aquí) */
.lmap-rail-sub {
    padding: .5rem .75rem .25rem;
    font-size: .64rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--brand-muted);
}

/* item "sin ubicar" en la zona actual: clicar lo ARMA para que el próximo dibujo lo coloque */
.lmap-rail-item.is-unplaced { cursor: pointer; }
.lmap-rail-item.is-unplaced:hover { background: var(--brand-navy-tint); }
.lmap-rail-item.is-armed {
    background: var(--brand-navy-tint);
    box-shadow: inset 0 0 0 1.5px var(--brand-blue-deep);
}
.lmap-rail-item.is-armed > i { color: var(--brand-blue-deep); }
/* item "sin ubicar" en OTRA zona del edificio: clicar baja a su zona y lo arma */
.lmap-rail-item.is-elsewhere { cursor: pointer; color: var(--brand-muted); }
.lmap-rail-item.is-elsewhere:hover { background: var(--brand-paper); color: var(--brand-body); }
.lmap-rail-item.is-elsewhere .lmap-rail-where {
    margin-left: auto; font-size: .64rem; color: var(--brand-muted); flex: 0 0 auto;
}
/* botón "eliminar nodo" del rail (DELETE /tree, borra la ubicación) — distinto de la X de "quitar del plano" */
.lmap-rail-del {
    flex-shrink: 0; border: 0; background: transparent; cursor: pointer;
    padding: .15rem; border-radius: 6px; color: var(--brand-muted);
    display: inline-flex; align-items: center; transition: background .15s ease, color .15s ease;
}
.lmap-rail-del:hover { background: var(--brand-danger-tint); color: var(--brand-danger); }

/* indicador "armado": pista de qué se está colocando, en la banda de ayuda */
.lmap-edit-help.is-arming { border-color: var(--brand-blue-deep); }
.lmap-edit-help.is-arming i { color: var(--brand-blue-deep); }

/* --- empty / no-plan state + upload dropzone --- */
.lmap-empty {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .5rem; text-align: center; padding: 1.5rem;
}
.lmap-empty-icon { font-size: 2.4rem; color: var(--brand-muted); }
.lmap-empty-text { color: var(--brand-body); margin: 0; max-width: 360px; }
.lmap-dropzone {
    display: flex; flex-direction: column; align-items: center; gap: .25rem;
    margin-top: .5rem; padding: 1.4rem 2rem;
    border: 2px dashed var(--brand-line);
    border-radius: 14px;
    background: var(--brand-paper);
    color: var(--brand-blue-deep);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.lmap-dropzone i { font-size: 1.8rem; }
.lmap-dropzone:hover,
.lmap-dropzone.is-over { border-color: var(--brand-blue-deep); background: var(--brand-navy-tint); }
.lmap-dropzone.is-over { transform: scale(1.01); }
.lmap-dropzone-title { font-weight: 600; color: var(--brand-navy); }
.lmap-dropzone-hint { font-size: .76rem; color: var(--brand-muted); }
.lmap-file { display: none; }

/* --- loading skeleton --- */
.lmap-skeleton {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .75rem; background: var(--brand-canvas);
}
.lmap-skeleton-pulse {
    width: 60%; max-width: 420px; height: 60%;
    border-radius: 14px;
    background: linear-gradient(100deg, var(--brand-line-soft) 30%, var(--brand-paper) 50%, var(--brand-line-soft) 70%);
    background-size: 200% 100%;
    animation: lmapSkeleton 1.3s ease-in-out infinite;
}
.lmap-skeleton-text { color: var(--brand-muted); font-size: .82rem; }
@keyframes lmapSkeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* Geoman toolbar adopts brand tokens (override the plugin defaults) */
.leaflet-pm-toolbar .leaflet-pm-icon { filter: none; }
.leaflet-pm-toolbar .button-container a.leaflet-buttons-control-button {
    border-color: var(--brand-line);
}
.leaflet-pm-toolbar .active .leaflet-pm-actions-container,
.leaflet-pm-toolbar .button-container.active a { background-color: var(--brand-navy-tint); }

@media (max-width: 767.98px) {
    .lmap-globe, .lmap-panel, .lmap-panel .lmap-globe { height: 320px; }
    .lmap-rail { width: 170px; }
    .lmap-info { width: 180px; }
}

/* ===================================================================
   Árbol de ubicaciones (.loc-*) — vista /locations (js/location/tree.js)
   Dos modos sobre los mismos datos: (1) la fila de la tabla que "crece"
   mostrando ascendentes + hijos, y (2) el árbol jerárquico. Paleta Accendo
   (navy + blue-deep); el verde no se usa aquí. Tokens, sin hexes sueltos.
   =================================================================== */

/* --- píldora de conteo de sububicaciones (columna de la tabla) --- */
.loc-subcount {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .1rem .5rem; border-radius: 999px;
    background: var(--brand-navy-tint); color: var(--brand-blue-deep);
    font-size: .74rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.loc-subcount i { font-size: .85rem; }

/* --- chevron que expande/colapsa la fila de la lista --- */
.loc-grow-toggle {
    border: 0; background: transparent; cursor: pointer; padding: 0;
    width: 24px; height: 24px; margin-right: .35rem; vertical-align: middle;
    border-radius: 6px; color: var(--brand-muted);
    display: inline-flex; align-items: center; justify-content: center;
    transition: background .15s ease, color .15s ease;
}
.loc-grow-toggle:hover { background: var(--brand-navy-tint); color: var(--brand-blue-deep); }

/* --- panel que aparece bajo la fila (breadcrumb de ascendentes + hijos) --- */
.loc-detail-row > td { padding: 0; background: var(--brand-paper); border-top: 0; }
.loc-detail { display: flex; flex-direction: column; gap: .9rem; padding: 1rem 1.25rem 1.15rem; }
.loc-detail-loading { color: var(--brand-muted); font-size: .85rem; }
/* En la pestaña "Estructura" del detalle el contenedor ya está dentro de un tab con padding: se anula el propio. */
.loc-detail.loc-structure { padding: 0; }
.loc-structure-path { position: static; background: transparent; padding: 0; margin-bottom: .25rem; }
.loc-structure-path .loc-crumb-self { font-size: .92rem; }

.loc-crumb { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; }
.loc-crumb-lbl {
    text-transform: uppercase; letter-spacing: .04em; font-size: .66rem; font-weight: 700;
    color: var(--brand-muted); margin-right: .25rem;
}
.loc-crumb-root { color: var(--brand-muted); font-style: italic; font-size: .8rem; }
.loc-crumb-item {
    border: 0; background: transparent; cursor: pointer; padding: .1rem .3rem; border-radius: 6px;
    color: var(--brand-blue-deep); font-weight: 600; font-size: .8rem;
    transition: background .15s ease;
}
.loc-crumb-item:hover { background: var(--brand-navy-tint); }
.loc-crumb-sep { color: var(--brand-line); font-size: .8rem; }
.loc-crumb-self { color: var(--brand-navy); font-weight: 700; font-size: .8rem; }

.loc-section { display: flex; flex-direction: column; gap: .55rem; }
.loc-section-head { display: flex; align-items: center; gap: .6rem; }
.loc-section-lbl {
    text-transform: uppercase; letter-spacing: .04em; font-size: .66rem; font-weight: 700; color: var(--brand-muted);
}
.loc-add {
    display: inline-flex; align-items: center; gap: .25rem;
    border: 1px solid var(--brand-line); background: var(--brand-white);
    color: var(--brand-blue-deep); font-weight: 600; font-size: .73rem;
    padding: .2rem .55rem; border-radius: 999px; cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}
.loc-add:hover { border-color: var(--brand-blue-deep); background: var(--brand-navy-tint); }
.loc-add i { font-size: .85rem; }

.loc-chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.loc-chip {
    display: inline-flex; align-items: center; gap: .35rem;
    border: 1px solid var(--brand-line); background: var(--brand-white);
    border-radius: 999px; padding: .28rem .65rem; cursor: pointer;
    font-size: .78rem; font-weight: 500; color: var(--brand-navy);
    transition: border-color .15s ease, background .15s ease;
}
.loc-chip:hover { border-color: var(--brand-blue-deep); background: var(--brand-navy-tint); }
.loc-chip i { color: var(--brand-blue-deep); font-size: .9rem; }
.loc-chip .n {
    margin-left: .1rem; padding: 0 .35rem; border-radius: 999px;
    background: var(--brand-navy-tint); color: var(--brand-blue-deep);
    font-size: .64rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.loc-empty { color: var(--brand-muted); font-size: .85rem; }

/* --- modo árbol jerárquico (#locTreeBody) --- */
.loc-tree { display: flex; flex-direction: column; }
.loc-tree-node { display: flex; flex-direction: column; }
.loc-tree-row {
    display: flex; align-items: center; gap: .4rem; min-height: 36px;
    padding: .3rem .5rem; border-radius: 8px; transition: background .12s ease;
}
.loc-tree-row:hover { background: var(--brand-paper); }
.loc-tree-toggle {
    flex-shrink: 0; width: 20px; height: 20px; padding: 0;
    border: 0; background: transparent; cursor: pointer; color: var(--brand-muted);
    display: inline-flex; align-items: center; justify-content: center;
}
.loc-tree-toggle:hover { color: var(--brand-blue-deep); }
.loc-tree-icon { flex-shrink: 0; color: var(--brand-blue-deep); font-size: 1rem; }
.loc-tree-name { color: var(--brand-navy); text-decoration: none; font-weight: 600; font-size: .85rem; }
.loc-tree-name:hover { color: var(--brand-blue-deep); text-decoration: underline; }
.loc-tree-count {
    padding: 0 .4rem; border-radius: 999px; background: var(--brand-navy-tint);
    color: var(--brand-blue-deep); font-size: .64rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.loc-tree-actions { margin-left: auto; display: inline-flex; gap: .15rem; opacity: 0; transition: opacity .12s ease; }
.loc-tree-row:hover .loc-tree-actions { opacity: 1; }
.loc-tree-act {
    border: 0; background: transparent; cursor: pointer; padding: .25rem; border-radius: 6px;
    color: var(--brand-muted); display: inline-flex; align-items: center;
    transition: background .15s ease, color .15s ease;
}
.loc-tree-act:hover { background: var(--brand-navy-tint); color: var(--brand-blue-deep); }
.loc-tree-act.is-danger:hover { background: var(--brand-danger-tint); color: var(--brand-danger); }
.loc-tree-children { display: flex; flex-direction: column; }
.loc-tree-loading, .loc-tree-empty { padding: .6rem .75rem; color: var(--brand-muted); font-size: .82rem; }

/* edición de estructura: arrastre de nodos (activado por "Editar estructura") */
body.loc-edit-on .loc-tree-row { cursor: grab; }
.loc-tree-row.is-dragging { opacity: .5; }
.loc-tree-row.is-dragover {
    background: var(--brand-navy-tint);
    outline: 2px dashed var(--brand-blue-deep); outline-offset: -2px;
}

/* Utilidad global para mostrar/ocultar por clase (el JS alterna .is-hidden, nunca estilos en línea). */
.is-hidden { display: none !important; }

/* ===================================================================
   Asistente de creación de inventarios (.ab-*)
   Paleta Accendo: navy + blue-deep. El verde esmeralda se reserva
   solo para éxito real, por lo que aquí NO se usa.
   =================================================================== */

.ab-stepper { display: flex; align-items: center; gap: 8px; margin-bottom: 1.75rem; }
.ab-step { display: flex; align-items: center; gap: 8px; }
.ab-step-dot {
    width: 28px; height: 28px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.82rem; background: var(--brand-paper); color: var(--brand-muted);
    border: 1px solid var(--brand-line);
}
.ab-step-label { font-size: 0.85rem; color: var(--brand-muted); }
.ab-step.is-active .ab-step-dot { background: var(--brand-navy); color: #fff; border-color: var(--brand-navy); }
.ab-step.is-active .ab-step-label { color: var(--brand-ink); font-weight: 600; }
.ab-step.is-done .ab-step-dot { background: var(--brand-navy-tint); color: var(--brand-navy); border-color: var(--brand-navy-tint-border); }
.ab-step.is-done .ab-step-label { color: var(--brand-blue-deep); }
.ab-step-line { flex: 1; height: 2px; background: var(--brand-line); border-radius: 2px; }

.ab-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.ab-grid.ab-grid-single { grid-template-columns: 1fr; }
.ab-grid.ab-grid-single .ab-main { max-width: 680px; margin: 0 auto; width: 100%; }
.ab-main { min-width: 0; }
.ab-panel-title { font-size: 1.05rem; font-weight: 600; color: var(--brand-ink); margin-bottom: 0.25rem; }
.ab-panel-sub { font-size: 0.85rem; color: var(--brand-muted); margin-bottom: 1rem; }
.ab-hint { font-size: 0.8rem; color: var(--brand-muted); margin: 0.25rem 0 0.5rem; }
.ab-inline-error { font-size: 0.82rem; color: var(--bs-danger, #a3402d); margin-top: 0.75rem; }

.ab-loc-search { position: relative; margin-bottom: 12px; }
.ab-loc-search i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--brand-muted); font-size: 16px; }
.ab-loc-search .form-control { padding-left: 34px; }

.ab-tree-wrap { position: relative; }
.ab-tree-busy {
    display: flex; align-items: center; gap: 8px; font-size: 0.82rem; color: var(--brand-navy);
    padding: 8px 10px; margin-bottom: 8px; background: var(--brand-navy-tint);
    border: 1px solid var(--brand-navy-tint-border); border-radius: 6px;
}
.ab-tree.is-processing { pointer-events: none; opacity: 0.55; }
.ab-tree { border: 1px solid var(--brand-line); border-radius: 8px; max-height: 380px; overflow-y: auto; padding: 6px; }
.ab-tree-loading { color: var(--brand-muted); font-size: 0.85rem; padding: 12px; }
.ab-tree-row { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 6px; cursor: pointer; }
.ab-tree-row:hover { background: var(--brand-paper); }
.ab-tree-row.is-busy { pointer-events: none; opacity: 0.7; }
.ab-check {
    width: 20px; height: 20px; min-width: 20px; border-radius: 4px;
    border: 1px solid var(--brand-line); display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; background: #fff;
}
.ab-check.is-checked { background: var(--brand-navy); border-color: var(--brand-navy); color: #fff; }
.ab-check.is-indeterminate { background: var(--brand-navy-tint); border-color: var(--brand-navy-tint-border); color: var(--brand-navy); }
.ab-check.is-loading { border-color: var(--brand-line); background: #fff; color: var(--brand-blue-deep); }
.ab-check.is-loading .spinner-border { width: 12px; height: 12px; border-width: 0.15em; }
.ab-caret { font-size: 15px; color: var(--brand-muted); width: 16px; text-align: center; }
.ab-caret-spacer { width: 16px; display: inline-block; }
.ab-role-icon { font-size: 17px; color: var(--brand-blue-deep); }
.ab-node-name { color: var(--brand-ink); }
.ab-node-badge {
    margin-left: auto; font-size: 0.72rem; color: var(--brand-navy);
    background: var(--brand-navy-tint); border: 1px solid var(--brand-navy-tint-border);
    padding: 1px 8px; border-radius: 6px;
}

.ab-skip-report {
    display: flex; gap: 8px; align-items: flex-start; margin-top: 12px; padding: 8px 10px;
    border-radius: 6px; font-size: 0.8rem; background: var(--brand-navy-tint); color: var(--brand-navy);
}
.ab-skip-report i { margin-top: 1px; }
.ab-skip-report.is-warn { background: rgba(181, 133, 42, 0.12); color: var(--brand-warning); }
.ab-skip-report ul { padding-left: 18px; }

.ab-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ab-state-chip {
    border: 1px solid var(--brand-line); background: #fff; color: var(--brand-ink);
    border-radius: 999px; padding: 5px 14px; font-size: 0.85rem; cursor: pointer;
}
.ab-state-chip.is-on { background: var(--brand-navy); color: #fff; border-color: var(--brand-navy); }
.ab-cat-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ab-chip {
    display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem;
    background: var(--brand-navy-tint); color: var(--brand-navy); padding: 3px 10px; border-radius: 6px;
}
.ab-chip.is-removable i { cursor: pointer; font-size: 14px; }

.ab-field-help { font-size: 0.78rem; color: var(--brand-muted); margin-top: 5px; }

.ab-review { margin: 0; }
.ab-review > div { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; }
.ab-review > div:last-child { border-top: 1px solid var(--brand-line); margin-top: 6px; padding-top: 12px; }
.ab-review dt { color: var(--brand-muted); font-weight: 400; font-size: 0.85rem; }
.ab-review dd { margin: 0; color: var(--brand-ink); text-align: right; }
.ab-rev-strong { color: var(--brand-navy); font-weight: 600; font-size: 1.05rem; }

.ab-rail { display: flex; flex-direction: column; gap: 12px; }
.ab-rail-card { background: #fff; border: 1px solid var(--brand-line); border-radius: 12px; padding: 1rem; }
.ab-rail-expected { display: flex; align-items: baseline; gap: 10px; padding-bottom: 14px; margin-bottom: 10px; border-bottom: 1px solid var(--brand-line-soft); }
.ab-rail-kpi-spinner { display: inline-flex; align-items: center; min-height: 1.9rem; }
.ab-rail-kpi-spinner .spinner-border { width: 1.35rem; height: 1.35rem; border-width: 0.18em; }
.ab-rail-kpi-figure { font-size: 1.9rem; font-weight: 600; color: var(--brand-navy); line-height: 1; }
.ab-rail-kpi-label { display: flex; flex-direction: column; font-size: 0.82rem; color: var(--brand-muted); }
.ab-rail-kpi-hint { font-size: 0.72rem; color: var(--brand-muted); }
.ab-rail-title { font-size: 0.9rem; font-weight: 600; color: var(--brand-ink); margin-bottom: 10px; }
.ab-rail-row { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; padding: 5px 0; color: var(--brand-muted); }
.ab-rail-row i { font-size: 16px; color: var(--brand-muted); }
.ab-rail-val { margin-left: auto; font-weight: 500; color: var(--brand-ink); }
.ab-rail-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--brand-line-soft); }

.ab-footer { display: flex; justify-content: space-between; align-items: center; margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--brand-line-soft); }
.ab-footer-right { display: flex; gap: 8px; margin-left: auto; }

@media (max-width: 991.98px) {
    .ab-grid { grid-template-columns: 1fr; }
    .ab-step-label { display: none; }
}

/* =====================================================================
   BARRAS DE PROGRESO EN LÍNEA — primitiva compartida
   Estructura: contenedor flex + .track (fondo gris) + .fill (color de marca) + .pct/.cnt.
   Cada variante define solo lo que la distingue: altura, color de fill, animaciones, labels.
   Cuatro variantes: wo-progress, audit-cov, picking-progress, picking-monitor-bar.
   ===================================================================== */

/* — work-order list: 6px, navy fill — */
.wo-progress { display: flex; align-items: center; gap: 8px; min-width: 120px; }
.wo-progress .cnt { font-size: 0.78rem; color: var(--brand-muted); white-space: nowrap; }

/* track + fill compartidos: wo-progress y audit-cov son idénticos (6px, navy) */
.wo-progress .track,
.audit-cov-track,
.presence-page .presence-bar .track { flex: 1; height: 6px; border-radius: 999px; background: var(--brand-line); overflow: hidden; }
.wo-progress .fill,
.audit-cov-fill,
.presence-page .presence-bar .fill { display: block; height: 100%; border-radius: 999px; background: var(--brand-navy); }

/* ===== Resultado de auditoría (cross): descripción truncada ===== */
.audit-desc {
    display: inline-block; max-width: 280px; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; vertical-align: bottom; color: var(--brand-muted);
}

/* ===== RESTORED from 149ebba79 (picking UI block dropped during the styles refactor) ===== */
/* ===========================================================================
   PICKING — Allocation Engine UI (/operations/picking)
   List KPI strip, in-row progress bar, the live "engine rail" builder preview,
   and the creation chooser. Tokens only — no hardcoded hexes.
   =========================================================================== */

/* ---- KPI strip on the list (one figure per metric) ---- */
.picking-kpi .card-body { padding: .85rem 1rem .7rem; }
.picking-kpi .lbl { font-size: .72rem; color: var(--brand-muted); display: flex; align-items: center; gap: .4rem; margin-bottom: .5rem; }
.picking-kpi .lbl i { font-size: 1rem; color: var(--brand-blue-deep); }
.picking-kpi .fig { font-family: var(--brand-font-mono); font-size: 1.6rem; font-weight: 600; color: var(--brand-ink); line-height: 1; font-variant-numeric: tabular-nums; }
.picking-kpi .fig.is-live { color: var(--brand-navy); }

/* ---- in-row progress + monitor banner: estructura compartida (ver sección barras arriba) ---- */
.picking-progress,
.picking-monitor-bar { display: flex; align-items: center; }
.picking-progress .track,
.picking-monitor-bar .track { flex: 1; border-radius: 20px; background: var(--brand-line); overflow: hidden; }
.picking-progress .fill,
.picking-monitor-bar .fill { height: 100%; border-radius: 20px; background: var(--brand-positive); }

/* — list column: 7px, pct + cnt labels — */
.picking-progress { gap: .6rem; min-width: 150px; }
.picking-progress .track { height: 7px; }
.picking-progress .pct { font-family: var(--brand-font-mono); font-size: .78rem; color: var(--brand-ink); width: 2.6rem; text-align: right; font-variant-numeric: tabular-nums; }
.picking-progress .cnt { font-family: var(--brand-font-mono); font-size: .72rem; color: var(--brand-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* — monitor banner: 10px, animated, large pct — */
.picking-monitor-bar { gap: .9rem; }
.picking-monitor-bar .track { height: 10px; }
.picking-monitor-bar .fill { transition: width 1s cubic-bezier(.4, 0, .2, 1); }
.picking-monitor-bar .pct { font-family: var(--brand-font-mono); font-size: 1.1rem; font-weight: 600; color: var(--brand-navy); font-variant-numeric: tabular-nums; }

/* strategy chip (list + manifest) */
.picking-strat { font-family: var(--brand-font-mono); font-size: .75rem; color: var(--brand-body);
    background: var(--brand-paper); border: 1px solid var(--brand-line); border-radius: 5px; padding: .12rem .5rem; }

/* .picking-live-dot retirado: los estados en curso ahora usan .status-pill.is-live (P2-6). El guard de
   reduced-motion se conserva para la pastilla viva. */
@media (prefers-reduced-motion: reduce) { .status-pill.is-live::before { animation: none; } }

/* ---- builder layout: form + sticky engine rail ---- */
.picking-builder-grid { display: grid; grid-template-columns: 1fr 400px; gap: 1.25rem; align-items: start; }
@media (max-width: 991.98px) { .picking-builder-grid { grid-template-columns: 1fr; } }

/* strategy <select> + explanation panel */
.picking-stratbox { display: flex; gap: .9rem; align-items: stretch; flex-wrap: wrap; }
.picking-stratbox .picking-stratsel { flex: 0 0 230px; max-width: 100%; }
.picking-stratexp { flex: 1; min-width: 200px; background: var(--brand-paper); border: 1px solid var(--brand-line);
    border-radius: var(--border-radius); padding: .7rem .9rem; display: flex; gap: .7rem; align-items: flex-start; }
.picking-stratexp i { font-size: 1.2rem; color: var(--brand-blue-deep); margin-top: 1px; flex-shrink: 0; }
.picking-stratexp .h { font-size: .82rem; font-weight: 600; color: var(--brand-ink); }
.picking-stratexp .d { font-size: .78rem; color: var(--brand-muted); margin-top: .15rem; line-height: 1.5; }

/* demand-line table — packing-unit reference cell */
.picking-line-ref { display: flex; align-items: center; gap: .55rem; }
.picking-line-ref .ic { width: 30px; height: 30px; border-radius: 7px; background: var(--brand-navy-tint);
    color: var(--brand-navy); display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0; }
.picking-line-ref .code { font-family: var(--brand-font-mono); font-size: .82rem; color: var(--brand-ink); font-weight: 500; }
.picking-line-ref .sub { color: var(--brand-muted); font-size: .72rem; margin-top: 1px; }
.picking-qty-input { font-family: var(--brand-font-mono); width: 4rem; text-align: right; }

/* dashed "add line" button */
.picking-addline { font-size: .82rem; font-weight: 500; color: var(--brand-blue-deep); background: transparent;
    border: 1px dashed var(--brand-navy-tint-border); border-radius: var(--border-radius); padding: .6rem .9rem;
    width: 100%; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: .45rem; transition: .18s; }
.picking-addline:hover { background: var(--brand-paper); border-color: var(--brand-blue-deep); }

/* inline hint under the line table */
.picking-help { font-size: .78rem; color: var(--brand-muted); margin-top: .65rem; display: flex; gap: .45rem; align-items: flex-start; }
.picking-help i { color: var(--brand-blue-deep); font-size: .9rem; margin-top: 1px; flex-shrink: 0; }

/* ---- engine rail (the live preview) ---- */
.picking-rail { position: sticky; top: 1.5rem; }
.picking-rail-head { background: var(--brand-navy); border-radius: 10px 10px 0 0; padding: .95rem 1.35rem;
    display: flex; justify-content: space-between; align-items: center; }
.picking-rail-head h3 { color: var(--brand-white); font-size: .9rem; margin: 0; display: flex; align-items: center; gap: .55rem; }
.picking-rail-head .live { font-size: .68rem; font-weight: 500; color: var(--brand-blue-bright);
    font-family: var(--brand-font-mono); display: flex; align-items: center; gap: .4rem; letter-spacing: .06em; }
.picking-rail-head .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--brand-green); animation: picking-rail-pulse 2s infinite; }
@keyframes picking-rail-pulse { 0% { box-shadow: 0 0 0 0 rgba(23, 204, 152, .5); } 70% { box-shadow: 0 0 0 7px rgba(23, 204, 152, 0); } 100% { box-shadow: 0 0 0 0 rgba(23, 204, 152, 0); } }
@media (prefers-reduced-motion: reduce) { .picking-rail-head .dot { animation: none; } }
.picking-rail-body { background: var(--brand-white); border: 1px solid var(--brand-line); border-top: none;
    border-radius: 0 0 10px 10px; box-shadow: 0 1px 2px rgba(var(--brand-navy-rgb), .04); }

/* feasibility headline + bar */
.picking-feas { padding: 1.25rem 1.35rem 1rem; }
.picking-feas .big { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .2rem; }
.picking-feas .big .fig { font-family: var(--brand-font-mono); font-size: 2.3rem; font-weight: 500;
    color: var(--brand-ink); letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.picking-feas .big .of { font-size: .95rem; color: var(--brand-muted); font-family: var(--brand-font-mono); }
.picking-feas .cap { font-size: .78rem; color: var(--brand-muted); margin-bottom: .9rem; }
.picking-bar { height: 9px; border-radius: 20px; background: var(--brand-line); overflow: hidden; display: flex; }
.picking-bar .fill { height: 100%; background: var(--brand-positive); width: 0; transition: width 1.1s cubic-bezier(.4, 0, .2, 1); }
.picking-bar .short { height: 100%; background: var(--brand-warning); opacity: .55; width: 0; transition: width 1.1s cubic-bezier(.4, 0, .2, 1) .1s; }
.picking-bar-labels { display: flex; justify-content: space-between; margin-top: .5rem; font-size: .72rem; color: var(--brand-muted); }

/* rail KPI trio */
.picking-rail-kpis { display: grid; grid-template-columns: repeat(3, 1fr);
    border-top: 1px solid var(--brand-line-soft); border-bottom: 1px solid var(--brand-line-soft); }
.picking-rail-kpis .k { padding: .8rem .9rem; border-right: 1px solid var(--brand-line-soft); }
.picking-rail-kpis .k:last-child { border-right: none; }
.picking-rail-kpis .k-lbl { font-size: .65rem; letter-spacing: .05em; text-transform: uppercase; color: var(--brand-muted); margin-bottom: .25rem; }
.picking-rail-kpis .k-val { font-family: var(--brand-font-mono); font-size: 1.25rem; font-weight: 500; color: var(--brand-ink); font-variant-numeric: tabular-nums; }
.picking-rail-kpis .k-val.is-warn { color: var(--brand-warning); }
.picking-rail-kpis .k-val.is-ok { color: var(--brand-positive-text); }

/* "what & why" list */
.picking-why { padding: 1rem 1.35rem .5rem; }
.picking-why .ttl { font-size: .78rem; font-weight: 600; color: var(--brand-ink); margin-bottom: .2rem; display: flex; align-items: center; gap: .45rem; }
.picking-why .ttl i { color: var(--brand-blue-deep); font-size: 1rem; }
.picking-why .sub { font-size: .72rem; color: var(--brand-muted); margin-bottom: .75rem; }
.picking-epc { display: flex; align-items: center; gap: .7rem; padding: .6rem 0; border-top: 1px solid var(--brand-line-soft); }
.picking-epc:first-of-type { border-top: none; }
.picking-epc .ord { width: 21px; height: 21px; border-radius: 50%; background: var(--brand-navy-tint); color: var(--brand-navy);
    font-family: var(--brand-font-mono); font-size: .66rem; font-weight: 500; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.picking-epc .info { flex: 1; min-width: 0; }
.picking-epc .serial { font-family: var(--brand-font-mono); font-size: .78rem; color: var(--brand-ink); font-weight: 500; }
.picking-epc .meta { font-size: .7rem; color: var(--brand-muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.picking-epc .reason { text-align: right; flex-shrink: 0; }
.picking-epc .why-pill { font-family: var(--brand-font-mono); font-size: .7rem; font-weight: 500;
    color: var(--brand-positive-text); background: var(--brand-positive-tint); padding: .18rem .55rem; border-radius: 20px; }
.picking-epc .r2 { font-size: .66rem; color: var(--brand-muted); margin-top: .2rem; }
.picking-morelink { font-size: .72rem; color: var(--brand-blue-deep); font-weight: 500; padding: .6rem 0 .25rem; display: inline-block; }

/* rail footer actions */
.picking-rail-foot { padding: .95rem 1.35rem; border-top: 1px solid var(--brand-line-soft); display: flex; gap: .6rem; }
.picking-rail-foot .btn { flex: 1; }

/* empty preview placeholder */
.picking-rail-empty { padding: 2rem 1.35rem; text-align: center; color: var(--brand-muted); font-size: .8rem; }
.picking-rail-empty i { font-size: 1.6rem; display: block; margin-bottom: .5rem; color: var(--brand-navy-tint-border); }

/* ---- creation chooser tiles (matches creation_modes look) ---- */
.picking-choice .tile { width: 54px; height: 54px; border-radius: 12px; display: flex; align-items: center;
    justify-content: center; font-size: 1.6rem; flex-shrink: 0; }
.picking-choice .tile.web { background: var(--brand-navy-tint); color: var(--brand-navy); }
.picking-choice .tile.xls { background: var(--brand-positive-tint); color: var(--brand-positive-text); }
.picking-choice .go { margin-top: .7rem; font-size: .78rem; font-weight: 500; color: var(--brand-blue-deep); display: inline-flex; align-items: center; gap: .3rem; }
/* Afordancia de hover de la tarjeta de modo de creacion activa (no aplica a la deshabilitada). */
.picking-choice { transition: box-shadow .15s ease, border-color .15s ease; }
.picking-choice:not(.is-disabled):hover { border-color: var(--brand-blue-deep); box-shadow: 0 .5rem 1.25rem rgba(14, 42, 69, .12); }
/* Modo de creacion no disponible aun (carga por Excel): tarjeta atenuada, no interactiva. */
.picking-choice.is-disabled { opacity: .6; cursor: not-allowed; }
.picking-choice.is-disabled .tile { filter: grayscale(.5); }
.picking-soon { background: var(--brand-line); color: var(--brand-muted); font-weight: 500;
    font-size: .62rem; letter-spacing: .03em; text-transform: uppercase; vertical-align: middle; }

/* .is-hidden ya definida arriba (utilidad global mostrar/ocultar): se elimina el duplicado. */

/* Picking builder — anchos de columna de la tabla de lineas (sin estilos en linea). */
#picking-lines-table { table-layout: fixed; }
#picking-lines-table .picking-col-pu   { width: 45%; }
#picking-lines-table .picking-col-qty  { width: 12%; }
#picking-lines-table .picking-col-dest { width: 33%; }
#picking-lines-table .picking-col-act  { width: 10%; }

/* ====== Detalle a escala: pestañas de estado, drill-down de seriales, paginador ====== */
/* Pestañas de filtro por estado de línea (con conteo). */
.picking-tabs,
.presence-tabs { display: flex; flex-wrap: wrap; gap: .4rem; }
.picking-tab,
.presence-tab { display: inline-flex; align-items: center; gap: .45rem; padding: .4rem .8rem; border-radius: 8px;
    border: 1px solid var(--brand-line); background: var(--brand-paper); color: var(--brand-body);
    font-size: .82rem; font-weight: 500; text-decoration: none; transition: background .12s, border-color .12s; }
.picking-tab:hover,
.presence-tab:hover { border-color: var(--brand-blue-deep); color: var(--brand-navy); }
.picking-tab.is-active,
.presence-tab.is-active { background: var(--brand-navy); border-color: var(--brand-navy); color: #fff; }
.picking-tab .n,
.presence-tab .n { font-family: var(--brand-font-mono); font-size: .72rem; padding: .04rem .4rem; border-radius: 20px;
    background: var(--brand-line); color: var(--brand-ink); font-variant-numeric: tabular-nums; }
.picking-tab.is-active .n,
.presence-tab.is-active .n { background: rgba(255, 255, 255, .22); color: #fff; }

/* Fila expandible con el drill-down de seriales de una línea. */
.picking-drill-row > td { background: var(--brand-navy-tint); padding: 0; }
.picking-drill { padding: .9rem 1.1rem; }
.picking-drill-tabs { display: inline-flex; gap: .25rem; margin-bottom: .7rem; background: var(--brand-paper);
    border: 1px solid var(--brand-line); border-radius: 8px; padding: .2rem; }
.picking-lens { border: 0; background: transparent; color: var(--brand-muted); font-size: .78rem; font-weight: 500;
    padding: .28rem .7rem; border-radius: 6px; cursor: pointer; }
.picking-lens:hover { color: var(--brand-navy); }
.picking-lens.is-active { background: var(--brand-blue-deep); color: #fff; }
.picking-drill-count { font-family: var(--brand-font-mono); font-size: .76rem; color: var(--brand-muted);
    margin-bottom: .5rem; font-variant-numeric: tabular-nums; }
.picking-drill-count strong { color: var(--brand-navy); }
.picking-drill-rows { max-height: 340px; overflow-y: auto; }
/* Filas EPC del drill como rejilla: serial | empaque | origen | nota. */
.picking-epc-row { display: grid; grid-template-columns: 1.6fr 1fr 1.2fr 1fr; gap: .6rem; align-items: center;
    padding: .32rem .2rem; border-bottom: 1px solid var(--brand-line); font-size: .8rem; }
.picking-epc-row .s { font-family: var(--brand-font-mono); color: var(--brand-navy); font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picking-epc-row .pu, .picking-epc-row .loc, .picking-epc-row .nt { color: var(--brand-body);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picking-epc-row.is-head { border-bottom: 1px solid var(--brand-line); font-size: .68rem; text-transform: uppercase;
    letter-spacing: .03em; color: var(--brand-muted); font-weight: 600; }
.picking-epc-row.is-head .s { font-family: inherit; color: var(--brand-muted); }
.picking-drill-empty, .picking-drill-loading { padding: 1rem .2rem; color: var(--brand-muted); font-size: .82rem; }
.picking-drill-loading::after { content: "…"; }

/* Paginador de líneas del detalle. */
.picking-pager { display: flex; align-items: center; justify-content: center; gap: .9rem; }
.picking-pager-btn { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
    border-radius: 8px; border: 1px solid var(--brand-line); background: var(--brand-paper); color: var(--brand-navy); }
.picking-pager-btn:hover { border-color: var(--brand-blue-deep); }
.picking-pager-btn.is-disabled { opacity: .4; pointer-events: none; }
.picking-pager-pos { font-family: var(--brand-font-mono); font-size: .82rem; color: var(--brand-muted);
    font-variant-numeric: tabular-nums; }

/* ============================================================
   Órdenes de trabajo — modelo matriz (asistente de pasos + detalle por asunto)
   ============================================================ */

/* Asistente: filas de pasos del procedimiento (instrucción + reordenar + eliminar) */
.wo-steps { margin-bottom: 4px; }
.wo-step-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.wo-step-num { flex: none; width: 26px; height: 26px; border-radius: 50%; display: inline-flex;
    align-items: center; justify-content: center; font-size: .78rem; font-weight: 600;
    background: var(--brand-blue-soft, #e8f0f7); color: var(--brand-blue-deep); font-variant-numeric: tabular-nums; }
.wo-step-input { flex: 1; }
.wo-step-controls { flex: none; display: inline-flex; align-items: center; gap: 2px; }
.wo-step-btn { flex: none; width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: var(--brand-muted); border-radius: 8px; cursor: pointer; padding: 0;
    font-size: 1.05rem; transition: background .12s ease, color .12s ease; }
.wo-step-btn:hover { background: var(--brand-wash, #eef2f6); color: var(--brand-navy); }
.wo-step-btn.is-danger:hover { background: #fbecea; color: #c0533b; }

/* Asistente: bloque de tareas POR ELEMENTO (cada elemento con su propio procedimiento) */
.wo-element { border: 1px solid var(--brand-line); border-radius: var(--border-radius-lg, 12px); padding: 14px 16px; margin-bottom: 12px; background: var(--brand-paper); }
.wo-element-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.wo-element-head .cell-id { flex: none; font-size: .92rem; }
.wo-element-head .wo-chip,
.wo-element-head .status-pill { flex: none; }
.wo-el-tasks { margin-bottom: 4px; }

/* Detalle: tarjeta de procedimiento (vista por paso) */
.wo-proc-step { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--brand-line); }
.wo-proc-step:first-of-type { border-top: 0; }
.wo-proc-num { flex: none; width: 22px; height: 22px; border-radius: 50%; display: inline-flex;
    align-items: center; justify-content: center; font-size: .72rem; font-weight: 600;
    background: var(--brand-blue-soft, #e8f0f7); color: var(--brand-blue-deep); }
.wo-proc-instr { flex: 1; font-size: .86rem; color: var(--brand-navy); overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
.wo-proc-count { flex: none; font-size: .78rem; color: var(--brand-muted); font-variant-numeric: tabular-nums; }

/* Detalle: buscador de asuntos */
.wo-search { position: relative; }
.wo-search i { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--brand-muted); font-size: 1rem; }
.wo-search input { padding-left: 32px; width: 220px; max-width: 100%; }

/* Detalle: acordeón de asuntos (matriz por asunto) */
.wo-subject-head { display: flex; align-items: center; gap: 12px; padding: 14px 18px; cursor: pointer;
    user-select: none; }
.wo-subject-head .wo-caret { color: var(--brand-muted); transition: transform .15s ease; flex: none; }
.wo-subject-head[aria-expanded="true"] .wo-caret { transform: rotate(90deg); }
.wo-subject-head .cell-id { flex: none; }
.wo-chip { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; padding: 3px 10px;
    border-radius: 999px; background: var(--brand-wash, #f4f6f8); color: var(--brand-navy); }
.wo-chip i { font-size: .9rem; color: var(--brand-muted); }
.wo-subject-progress { margin-left: auto; flex: none; font-size: .8rem; color: var(--brand-muted);
    white-space: nowrap; font-variant-numeric: tabular-nums; }
.wo-subject-bar { flex: none; width: 96px; height: 6px; border-radius: 999px; background: var(--brand-line);
    overflow: hidden; }
.wo-subject-fill { display: block; height: 100%; border-radius: 999px; background: var(--brand-emerald, #17cc98); }
.wo-subject-body { padding: 4px 18px 14px 44px; border-top: 1px solid var(--brand-line); }
.wo-exec-row { display: flex; align-items: center; gap: 12px; padding: 7px 0; font-size: .86rem; }
.wo-exec-row + .wo-exec-row { border-top: 1px dashed var(--brand-line); }
.wo-exec-num { flex: none; width: 20px; color: var(--brand-muted); font-variant-numeric: tabular-nums; }
.wo-exec-instr { flex: 1; color: var(--brand-navy); }
.wo-exec-note { color: var(--brand-muted); }
.wo-exec-when { flex: none; min-width: 200px; text-align: right; }
.wo-exec-dates { display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.wo-exec-date { display: block; font-size: .8rem; line-height: 1.35; white-space: nowrap; }
.wo-exec-date-label { font-size: .68rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: var(--brand-muted); margin-right: 6px; }
.wo-exec-by { flex: none; min-width: 90px; }

/* =====================================================================
   UTILIDADES — reglas de una línea usadas en múltiples vistas
   ===================================================================== */
.cursor-pointer { cursor: pointer; }

/* Subtitulo de seccion dentro de una tarjeta de detalle: mayusculas, negrita,
   tono oscuro, tamaño reducido. Generaliza el patron repetido con
   style="font-size: 0.85rem" + clases text-uppercase fw-bold text-dark en
   ~17 vistas de detalle (audit, business, inspection, lend, movement, etc.). */
.detail-subhead {
    text-transform: uppercase;
    font-weight: 700;
    color: var(--brand-ink);
    font-size: 0.85rem;
}

/* Detalle: medios y etiquetas (reemplazan estilos inline de las vistas de detalle, sweep P2-1).
   Alturas de mapa/imagen unificadas para consistencia entre paginas de detalle. */
.detail-cover-img { width: 100%; height: 240px; object-fit: cover; }
.detail-map { width: 100%; height: 460px; }
.detail-avatar { width: 46px; height: 46px; }
.detail-label { font-size: 0.75rem; text-transform: uppercase; font-weight: 600; color: var(--brand-muted); }
.th-fixed { width: 80px; }

/* Estado vacio de listas/tarjetas: icono centrado + mensaje, con enlace
   opcional debajo. Generaliza el bloque "card-body text-center py-5" con
   icono ti-* fs-1 text-muted + parrafo fs-5 text-muted repetido en las
   vistas all.html de audit, business, category, country, inspection, etc. */
.empty-state {
    text-align: center;
    padding: 3rem 1rem;
}

.empty-state-icon {
    font-size: calc(1.375rem + 1.5vw);
    color: var(--brand-muted);
    margin-bottom: 0.5rem;
    display: block;
}

.empty-state-text {
    font-size: 1.25rem;
    color: var(--brand-muted);
    margin-bottom: 0;
}

/* =====================================================================
   LICENSING DETAIL — /licensing/{id}. Scoped bajo .licensing-detail-page.
   Movido desde el bloque <style> del template (DRY: estilos en CSS).
   ===================================================================== */
.licensing-detail-page .table > thead th {
    font-size: 0.85rem;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--brand-muted);
}
.licensing-detail-page .alert {
    border-radius: 0.5rem;
    font-weight: 500;
}

/* =====================================================================
   SENSOR DETAIL — /sensors/{id}. .filter-group es el overlay del mapa;
   scoped aquí para evitar colisión con .dashboard-page .filter-group.
   Movido desde el bloque <style> del template (DRY: estilos en CSS).
   ===================================================================== */
.sensor-detail-page .filter-group {
    font-family: var(--brand-font-sans);
    position: absolute;
    top: 15px;
    left: 15px;
    z-index: 5;
    background: rgba(255, 255, 255, 0.95);
    padding: 12px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    width: auto;
    max-width: 90%;
    color: var(--brand-ink);
}
.sensor-detail-page .filter-group label { font-size: 0.72rem; }

/* =====================================================================
   READER DETAIL — última geolocalización reportada por el dispositivo.
   Scoped bajo .reader-detail-page para no alterar otros mapas de detalle.
   ===================================================================== */
.reader-detail-page .reader-location-card {
    overflow: hidden;
}

.reader-detail-page .reader-location-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(240px, 1fr);
    min-height: 360px;
}

.reader-detail-page .reader-location-map-shell {
    position: relative;
    min-height: 360px;
}

.reader-detail-page .reader-location-map,
.reader-detail-page .reader-location-map-state {
    width: 100%;
    min-height: 360px;
}

.reader-detail-page .reader-location-map-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 2rem;
    color: var(--brand-muted);
    background: var(--brand-paper);
    text-align: center;
}

.reader-detail-page .reader-location-map-state i {
    color: var(--brand-blue-deep);
    font-size: 2rem;
}

.reader-detail-page .reader-location-marker {
    color: var(--brand-blue-deep);
    cursor: default;
    filter: drop-shadow(0 3px 6px rgba(var(--brand-navy-rgb), 0.35));
    font-size: 2.5rem;
    line-height: 1;
}

.reader-detail-page .reader-location-facts {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 1.5rem;
    padding: 2rem;
    border-left: 1px solid var(--brand-line);
    background: var(--brand-white);
}

.reader-detail-page .reader-location-facts dt {
    color: var(--brand-muted);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.reader-detail-page .reader-location-facts dd {
    margin: 0.25rem 0 0;
    color: var(--brand-navy);
    font-weight: 600;
    overflow-wrap: anywhere;
}

@media (max-width: 767.98px) {
    .reader-detail-page .reader-location-layout {
        grid-template-columns: 1fr;
    }

    .reader-detail-page .reader-location-facts {
        border-top: 1px solid var(--brand-line);
        border-left: 0;
    }
}

/* =====================================================================
   AUDIT LIST — /audits. Select2 dentro de modales de reporte progresivo:
   ancho completo y dropdown anclado al modal (evita recorte/z-index).
   ===================================================================== */
.audit-list-page .modal .select2-container {
    width: 100% !important;
}

.audit-list-page .modal .select2-container--default .select2-selection--multiple {
    min-height: 2.5rem;
    border-color: var(--bs-border-color);
}

.audit-list-page .modal .select2-container--default.select2-container--focus .select2-selection--multiple {
    border-color: var(--brand-blue-deep);
    box-shadow: 0 0 0 0.2rem rgba(44, 90, 130, 0.15);
}

/* =====================================================================
   TIMELINE: lista vertical de eventos (historial de movimientos, prestamos).
   Estructura: punto + linea conectora + bloque de contenido (titulo/meta).
   ===================================================================== */
.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
}

.timeline-item {
    position: relative;
    padding: 0 0 1.25rem 1.75rem;
}

.timeline-item:last-child {
    padding-bottom: 0;
}

/* conector vertical: una linea continua detras de todos los puntos */
.timeline-item::before {
    content: "";
    position: absolute;
    left: 5px;
    top: 4px;
    bottom: -1.25rem;
    width: 1px;
    background: var(--brand-line);
}

.timeline-item:last-child::before {
    display: none;
}

/* punto del evento, encima del conector */
.timeline-item::after {
    content: "";
    position: absolute;
    left: 0;
    top: 4px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--brand-white);
    border: 2px solid var(--brand-blue-deep);
    z-index: 1;
}

.timeline-item.is-active::after {
    border-color: var(--brand-positive);
    background: var(--brand-positive);
}

.timeline-title {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--brand-navy);
    margin-bottom: 0.15rem;
}

.timeline-meta {
    font-size: 0.75rem;
    color: var(--brand-muted);
}

/* =====================================================================
   FILTER CHIPS: filtros activos como pildoras removibles, mas el contador
   del boton que abre el panel de filtros.
   ===================================================================== */
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.4rem 0.3rem 0.7rem;
    border-radius: 999px;
    background: var(--brand-navy-tint);
    color: var(--brand-navy);
    font-size: 0.78rem;
    font-weight: 500;
    border: 1px solid var(--brand-navy-tint-border);
}

.filter-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    height: 1.1rem;
    border: 0;
    border-radius: 50%;
    padding: 0;
    background: transparent;
    color: var(--brand-blue-deep);
    font-size: 0.7rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}

.filter-chip-remove:hover {
    background: var(--brand-white);
    color: var(--brand-navy);
}

/* contador pequeño sobre el boton "Filtros" cuando hay filtros activos */
.filter-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.1rem;
    height: 1.1rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background: var(--brand-blue-deep);
    color: var(--brand-white);
    font-size: 0.65rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

/* =====================================================================
   SORT INDICATORS: flechas de orden en encabezados de tabla (solo CSS,
   el toggle asc/desc lo controla JS agregando la clase correspondiente).
   ===================================================================== */
.th-sort {
    position: relative;
    cursor: pointer;
    padding-right: 1.1rem !important;
    user-select: none;
}

.th-sort::after {
    content: "\2195";
    position: absolute;
    right: 0.35rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.75em;
    color: var(--brand-line);
}

.th-sort.asc::after {
    content: "\2191";
    color: var(--brand-navy);
}

.th-sort.desc::after {
    content: "\2193";
    color: var(--brand-navy);
}

/* =====================================================================
   TOASTS: notificaciones flotantes (contrato de nombres con otro paquete,
   no renombrar). Pila fija abajo-derecha, tarjeta con acento de color segun
   variante, entrada animada (respeta prefers-reduced-motion).
   ===================================================================== */
.trackvy-toast-container {
    position: fixed;
    right: 1.25rem;
    bottom: 1.25rem;
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    width: 320px;
    max-width: calc(100vw - 2.5rem);
}

.trackvy-toast {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.85rem 1rem;
    border-radius: var(--border-radius);
    background: var(--brand-white);
    border: 1px solid var(--brand-line);
    border-left: 4px solid var(--brand-blue-deep);
    box-shadow: 0 12px 30px rgba(var(--brand-navy-rgb), 0.14);
    font-size: 0.85rem;
    color: var(--brand-body);
    animation: trackvy-toast-in 0.2s ease;
}

.trackvy-toast.is-success { border-left-color: var(--brand-positive); }
.trackvy-toast.is-error { border-left-color: var(--brand-danger); }
.trackvy-toast.is-info { border-left-color: var(--brand-blue-deep); }

.trackvy-toast-icon {
    flex: none;
    font-size: 1.1rem;
    line-height: 1.2;
    color: var(--brand-blue-deep);
}

.trackvy-toast.is-success .trackvy-toast-icon { color: var(--brand-positive); }
.trackvy-toast.is-error .trackvy-toast-icon { color: var(--brand-danger); }

.trackvy-toast-body { flex: 1; min-width: 0; }
.trackvy-toast-title { font-weight: 600; color: var(--brand-ink); margin-bottom: 0.1rem; }
.trackvy-toast-message { color: var(--brand-muted); }

@keyframes trackvy-toast-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .trackvy-toast { animation: none; }
}


.select2-container {
    width: 100% !important;
}

/* =====================================================================
   PRESENCIA — /analytics/presence. Todo va bajo .presence-page.
   Tablero de personas por sede y zona: tarjeta por sede, filas de zona
   sangradas por profundidad, y la ultima lectura como dato protagonista.
   La barra de cada zona reutiliza la primitiva .track/.fill (ver BARRAS
   DE PROGRESO) y las pestanas de estado reutilizan las de picking.
   ===================================================================== */

.presence-page .presence-updated { font-family: var(--brand-font-mono); font-size: .78rem; color: var(--brand-muted); }

.presence-page .presence-filter { min-width: 190px; }
.presence-page .presence-filters .eyebrow { font-size: .62rem; }

/* KPI: solo dos cifras se tinen; el resto queda navy para no gritar */
.presence-page .kpi-figure.is-inside { color: var(--brand-positive); }
.presence-page .kpi-figure.is-unconfirmed { color: var(--brand-warn-text); }

/* ---- Tarjeta de sede + filas de zona ---- */
.presence-page .presence-site-head {
    display: flex; align-items: center; gap: .6rem; padding: .9rem 1.1rem; text-decoration: none;
    border-bottom: 1px solid var(--brand-line); color: var(--brand-ink);
}
.presence-page .presence-site-head:hover { background: var(--brand-paper); }
.presence-page .presence-site-head.is-selected { background: var(--brand-navy-tint); }
.presence-page .presence-site-name { font-weight: 600; font-size: .95rem; }

.presence-page .presence-zone {
    display: flex; align-items: center; gap: .6rem; padding: .55rem 1.1rem; text-decoration: none;
    border-bottom: 1px solid var(--brand-line); color: var(--brand-body); font-size: .85rem;
}
.presence-page .presence-zone:last-child { border-bottom: 0; }
.presence-page .presence-zone:hover { background: var(--brand-paper); color: var(--brand-navy); }
.presence-page .presence-zone.is-selected { background: var(--brand-navy-tint); color: var(--brand-navy); font-weight: 500; }
.presence-page .presence-zone.is-empty { color: var(--brand-muted); }
.presence-page .presence-zone-name { flex: 1; }

/* Sangria por profundidad: el arbol se lee de un vistazo sin estilos en linea */
.presence-page .presence-zone.is-depth-1 { padding-left: 1.5rem; }
.presence-page .presence-zone.is-depth-2 { padding-left: 2.6rem; }
.presence-page .presence-zone.is-depth-3 { padding-left: 3.7rem; }
.presence-page .presence-zone.is-depth-4 { padding-left: 4.8rem; }

/* Fila plana del resumen (ranking de zonas ocupadas) y enlace "y N zonas mas" */
.presence-page .presence-zone.is-flat { padding-left: 1.5rem; }
.presence-page .presence-zone.is-more { color: var(--brand-blue-deep); font-size: .8rem; }
.presence-page .presence-zone.is-more i { font-size: .9rem; }

.presence-page .presence-readers {
    display: inline-flex; align-items: center; gap: .2rem; font-size: .72rem; color: var(--brand-muted);
    border: 1px solid var(--brand-line); border-radius: 999px; padding: .05rem .45rem;
}
.presence-page .presence-count {
    min-width: 2.2rem; text-align: right; font-weight: 600; color: var(--brand-navy); font-size: .9rem;
}
.presence-page .presence-bar { display: flex; align-items: center; width: 64px; }
.presence-page .presence-bar .fill { transition: width .8s cubic-bezier(.4, 0, .2, 1); }

.presence-page .presence-empty-sites { font-size: .8rem; color: var(--brand-muted); margin: -.4rem 0 1.4rem; }
.presence-page .presence-roster-title {
    display: flex; align-items: center; gap: .4rem; font-weight: 600; color: var(--brand-ink); margin-bottom: .8rem;
}

/* ---- Roster: ubicacion, antiguedad de la lectura y motivo ---- */
.presence-page .presence-place { display: flex; flex-direction: column; line-height: 1.25; }
.presence-page .presence-place-site { color: var(--brand-ink); }
.presence-page .presence-place-zone { font-size: .78rem; color: var(--brand-muted); }
.presence-page .presence-ago { display: block; font-size: .75rem; color: var(--brand-muted); }
.presence-page .presence-reason { display: block; font-size: .72rem; color: var(--brand-muted); margin-top: .15rem; }

/* ---- Diagnostico y alcance del dato ---- */
.presence-page .presence-diagnostics {
    display: flex; align-items: center; flex-wrap: wrap; gap: .5rem 1.1rem; margin-top: 1.4rem;
    padding: .7rem 1rem; border: 1px solid var(--brand-line); border-radius: var(--border-radius);
    background: var(--brand-paper); font-size: .82rem; color: var(--brand-body);
}
.presence-page .presence-diagnostics .is-conflict { color: var(--brand-warn-text); font-weight: 500; }
.presence-page .presence-disclaimer { margin-top: .9rem; font-size: .78rem; color: var(--brand-muted); }


/* =====================================================================
   NOTIFICACIONES — avisos IDI (.idi-uplink-*), campana del encabezado
   (.notif-*) y centro de actividad (.activity-page).
   La campana permanece discreta, con un numero del tamano del que usa el
   correo sin leer. Los avisos IDI aparecen solo al recibir una lectura.
   Ninguno usa color de alarma en reposo y todo movimiento respeta
   prefers-reduced-motion.
   ===================================================================== */

/* ---- Avisos en vivo del lector IDI ---- */
.idi-uplink-notifications {
    position: fixed;
    top: 4.5rem;
    right: 1.25rem;
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: .65rem;
    width: 22.5rem;
    max-width: calc(100vw - 2.5rem);
}

.idi-uplink-notification {
    position: relative;
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: .75rem;
    padding: .9rem 2.75rem .9rem .95rem;
    color: var(--brand-body);
    background: var(--brand-white);
    border: 1px solid var(--brand-line);
    border-left: 4px solid var(--brand-blue-deep);
    border-radius: var(--border-radius);
    box-shadow: 0 12px 30px rgba(var(--brand-navy-rgb), .14);
    animation: idi-uplink-notification-in .2s ease;
}

.idi-uplink-notification-icon {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--border-radius);
    color: var(--brand-blue-deep);
    background: var(--brand-navy-tint);
    font-size: 1.05rem;
}

.idi-uplink-notification-body { min-width: 0; }

.idi-uplink-notification-summary {
    margin: 0;
    color: var(--brand-ink);
    font-size: .84rem;
    font-weight: 600;
    line-height: 1.4;
}

.idi-uplink-notification-close {
    position: absolute;
    top: .65rem;
    right: .65rem;
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    color: var(--brand-muted);
    background: transparent;
    border: 0;
    border-radius: var(--border-radius);
    font-size: 1rem;
    line-height: 1;
}

.idi-uplink-notification-close:hover {
    color: var(--brand-blue-deep);
    background: var(--brand-paper);
}

.idi-uplink-notification-tags {
    max-height: 14rem;
    margin: .55rem 0 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
}

.idi-uplink-notification-tags:not(.is-expanded) li:nth-child(n+2) { display: none; }

.idi-uplink-notification-tags li {
    padding: .38rem .5rem;
    overflow-wrap: anywhere;
    color: var(--brand-body);
    background: var(--brand-paper);
    border: 1px solid var(--brand-line-soft);
    border-radius: var(--border-radius);
    font-family: var(--brand-font-mono);
    font-size: .72rem;
    line-height: 1.35;
}

.idi-uplink-notification-tags li + li { margin-top: .3rem; }

.idi-uplink-notification-toggle {
    margin-top: .55rem;
    padding: 0;
    color: var(--brand-blue-deep);
    background: transparent;
    border: 0;
    font-size: .76rem;
    font-weight: 600;
}

.idi-uplink-notification-toggle:hover { color: var(--brand-blue-deep-600); }

.idi-uplink-notification-close:focus-visible,
.idi-uplink-notification-toggle:focus-visible {
    outline: 2px solid var(--brand-blue-deep);
    outline-offset: 2px;
}

@keyframes idi-uplink-notification-in {
    from { opacity: 0; transform: translateY(-.4rem); }
    to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 575.98px) {
    .idi-uplink-notifications {
        top: 4.25rem;
        right: .75rem;
        width: calc(100vw - 1.5rem);
        max-width: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .idi-uplink-notification { animation: none; }
}

/* ---- La campana y su numero ---- */
.notif-bell .pc-head-link { position: relative; }

.notif-badge {
    position: absolute;
    top: .3rem;
    right: .25rem;
    min-width: 1.05rem;
    padding: 0 .28rem;
    border-radius: 999px;
    background: var(--brand-blue-deep);
    color: var(--brand-white);
    font-family: var(--brand-font-mono);
    font-size: .62rem;
    font-weight: 600;
    line-height: 1.05rem;
    text-align: center;
    animation: notif-badge-in .18s ease;
}

@keyframes notif-badge-in {
    from { opacity: 0; transform: scale(.7); }
    to { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .notif-badge { animation: none; }
}

/* ---- El desplegable ---- */
.notif-menu { width: 360px; max-width: calc(100vw - 1.5rem); padding: 0; }

.notif-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: .75rem .95rem .6rem; border-bottom: 1px solid var(--brand-line);
}

.notif-icon-btn {
    border: 0; background: none; padding: .1rem .2rem; line-height: 1;
    color: var(--brand-muted); font-size: 1rem; border-radius: var(--border-radius);
}
.notif-icon-btn:hover { color: var(--brand-blue-deep); background: var(--brand-paper); }

.notif-panel { max-height: 22rem; overflow-y: auto; }

.pc-header .notif-list { display: block; width: 100%; margin: 0; }

.notif-item { border-bottom: 1px solid var(--brand-line-soft); }
.notif-item:last-child { border-bottom: 0; }

.notif-item-body {
    display: block; padding: .6rem .95rem .6rem 1.25rem; position: relative;
    color: var(--brand-body); text-decoration: none;
}
a.notif-item-body:hover { background: var(--brand-paper); text-decoration: none; }

/* El punto de severidad: neutro por omision, y el rojo reservado para el error de verdad. */
.notif-item-body::before {
    content: ""; position: absolute; left: .6rem; top: .95rem;
    width: .35rem; height: .35rem; border-radius: 50%; background: var(--brand-pill-neutral-border);
}
.notif-item.is-warning .notif-item-body::before { background: var(--brand-warning); }
.notif-item.is-error .notif-item-body::before { background: var(--brand-danger); }
.notif-item.is-unseen .notif-item-body::before { background: var(--brand-blue-deep); }

.notif-item-title {
    display: block; font-size: .82rem; font-weight: 500; color: var(--brand-ink);
}
.notif-item.is-unseen .notif-item-title { font-weight: 600; }

.notif-item-count {
    margin-left: .35rem; font-family: var(--brand-font-mono); font-size: .7rem;
    font-weight: 500; color: var(--brand-muted);
}

.notif-item-detail {
    display: block; font-size: .76rem; color: var(--brand-body); margin-top: .1rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.notif-item-meta { display: block; font-size: .7rem; color: var(--brand-muted); margin-top: .2rem; }

.notif-empty { padding: 1.6rem .95rem; margin: 0; text-align: center; font-size: .8rem; color: var(--brand-muted); }

/* ---- Preferencias ---- */
.notif-prefs { padding: .8rem .95rem 1rem; }
.notif-prefs .form-check { margin-bottom: .35rem; }
.notif-prefs .form-check-label { font-size: .82rem; color: var(--brand-body); }
.notif-prefs-eyebrow { display: block; margin: .9rem 0 .4rem; }

.notif-back {
    display: inline-flex; align-items: center; gap: .35rem; border: 0; background: none;
    padding: 0 0 .6rem; font-size: .78rem; color: var(--brand-blue-deep);
}
.notif-back:hover { color: var(--brand-blue-deep-600); }

.notif-hint { margin: .7rem 0 0; font-size: .72rem; color: var(--brand-muted); }

/* ---- Pie ---- */
.notif-foot {
    display: flex; align-items: center; justify-content: space-between;
    padding: .55rem .95rem; border-top: 1px solid var(--brand-line); background: var(--brand-paper);
    font-size: .78rem;
}
.notif-foot a { color: var(--brand-blue-deep); text-decoration: none; }
.notif-foot a:hover { text-decoration: underline; }

.notif-link-btn { border: 0; background: none; padding: 0; font-size: .78rem; color: var(--brand-muted); }
.notif-link-btn:hover { color: var(--brand-blue-deep); }

/* ---- Centro de actividad (/analytics/activity) ---- */
.activity-page .activity-day { margin-bottom: 1.8rem; }
.activity-page .activity-day-label {
    display: block; margin-bottom: .7rem; padding-bottom: .4rem; border-bottom: 1px solid var(--brand-line);
}

.activity-page .activity-row {
    display: flex; align-items: flex-start; gap: .9rem; padding: .8rem .2rem;
    border-bottom: 1px solid var(--brand-line-soft);
}
.activity-page .activity-row:last-child { border-bottom: 0; }

.activity-page .activity-time {
    flex: none; width: 4.2rem; font-family: var(--brand-font-mono); font-size: .75rem;
    color: var(--brand-muted); padding-top: .1rem;
}
.activity-page .activity-main { flex: 1; min-width: 0; }
.activity-page .activity-title { font-weight: 500; color: var(--brand-ink); }
.activity-page .activity-detail { display: block; font-size: .82rem; color: var(--brand-body); margin-top: .15rem; }
.activity-page .activity-meta { display: flex; align-items: center; gap: .5rem; margin-top: .35rem; }
.activity-page .activity-count { font-family: var(--brand-font-mono); font-size: .72rem; color: var(--brand-muted); }
.activity-page .activity-empty { padding: 3rem 1rem; text-align: center; color: var(--brand-muted); }
.activity-page .activity-empty i { font-size: 2rem; display: block; margin-bottom: .6rem; opacity: .6; }
.activity-page .activity-note { margin-top: 1.6rem; font-size: .78rem; color: var(--brand-muted); }
