/* ==========================================================================
   boostrapoverride.css — the only project stylesheet.

   The UI is Bootstrap 5.3 components and utilities. This file holds what they
   cannot express, and nothing else:

     1. The Prevebsa module delta over stock Bootstrap 5.3.8, copied verbatim
        from docs/PREVEBSA-STYLE-REFERENCE.md §9.2 so Analytics renders as the
        same product as Prevebsa.Analytics. When V2 changes, replace section 1
        from the reference rather than editing it here.
     2. Analytics additions: chart colour tokens read by echartsInterop.js, the
        47px app bar and navigation rail, and the Blazor error bar.

   Before adding a class here, check the Bootstrap utilities first. A new rule
   needs a reason a utility cannot meet, written next to it.

   MUST load after bootstrap.min.css.
   ========================================================================== */


/* ==========================================================================
   1. Prevebsa module delta (docs/PREVEBSA-STYLE-REFERENCE.md §9.2)
   ========================================================================== */

/* ---- Tokens ------------------------------------------------------------ */

[data-bs-theme="light"] {
  --bs-body-bg: #fcfcfc;
  --bs-body-bg-rgb: 252, 252, 252;
  --bs-warning: #ff910a;
  --bs-warning-rgb: 250, 111, 12;
  --bs-info: #3793c4;
  --bs-info-rgb: 72, 224, 255;
}

:root {
  --bs-font-sans-serif: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --bs-body-font-family: var(--bs-font-sans-serif);

  --pv-brand-navy: #242e5d;
  --pv-brand-yellow: #ffc629;

  --pv-project-1-bg: #242e5d; --pv-project-1-fg: #ffffff; /* FACTURACION ATI */
  --pv-project-2-bg: #e52e38; --pv-project-2-fg: #ffffff; /* PERPE */
  --pv-project-3-bg: #ffc629; --pv-project-3-fg: #000000; /* EBSA */
  --pv-project-4-bg: #242e5d; --pv-project-4-fg: #ffffff; /* SUBESTACIONES */
  --pv-project-default-bg: #c3f2a5; --pv-project-default-fg: #000000;

  --pvb-barrier-control: #00a98a;
  --pvb-barrier-safety: #00688d;
  --pvb-barrier-support: #f47121;
}

/* ---- Base --------------------------------------------------------------- */

html, body {
  letter-spacing: -0.025rem;
  background-color: var(--bs-body-bg);
}

html { height: 100%; }
body { height: 100dvh; margin: 0; display: flex; flex-direction: column; }

h1, h2, h3, h4, h5, h6 { margin-bottom: 0; line-height: 1; padding: 0; }
p { line-height: 1; }

.fs-6875 { font-size: 0.875rem !important; }
.fs-65   { font-size: 0.8rem !important; }
.fs-7    { font-size: 0.75rem !important; }
.fs-8    { font-size: 0.7rem !important; }
.fs-9    { font-size: 0.65rem !important; }

.material-symbols-outlined {
  font-variation-settings: "FILL" 0, "wght" 250, "GRAD" 0, "opsz" 24;
}

*:focus-visible {
  outline: 1px solid var(--bs-emphasis-color);
  outline-offset: 0.2rem;
  border-radius: 3px;
}

.btn:focus, .btn:active:focus, .btn.active:focus,
.form-control:focus, .form-select:focus {
  outline: none;
  box-shadow: none;
}

::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, 0.5); border-radius: 0; }
::-webkit-scrollbar-track { background: transparent; }

/* ---- Controls ----------------------------------------------------------- */

.btn-primary {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: var(--bs-border-color);
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-hover-bg: var(--bs-secondary-bg);
  --bs-btn-hover-border-color: var(--bs-border-color);
  --bs-btn-focus-shadow-rgb: 49, 132, 253;
  --bs-btn-active-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--bs-tertiary-bg);
  --bs-btn-active-border-color: var(--bs-border-color);
  --bs-btn-disabled-color: var(--bs-secondary-color);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--bs-border-color);
}

.btn-warning {
  --bs-btn-color: #fff;
  --bs-btn-bg: #ff910a;
  --bs-btn-border-color: #ff910a;
  --bs-btn-hover-color: #000;
  --bs-btn-hover-bg: #ffb257;
  --bs-btn-hover-border-color: #ffb257;
  --bs-btn-active-color: #000;
  --bs-btn-active-bg: #ff910a;
  --bs-btn-active-border-color: #ffb257;
  --bs-btn-disabled-color: #000;
  --bs-btn-disabled-bg: #ffb257;
  --bs-btn-disabled-border-color: #ffb257;
}

.btn-sm {
  --bs-btn-padding-y: 0.25rem;
  --bs-btn-padding-x: 0.5rem;
  --bs-btn-font-size: 0.75rem;
  text-wrap-mode: nowrap;
  height: 1.625rem;
}

.form-control { font-size: 0.75rem; }

.form-control-sm, .form-select-sm {
  height: 1.625rem;
  padding: 0.15rem 0 0.15rem 0.4rem;
  font-size: 0.75rem;
  line-height: 1.5;
  border-radius: 0.2rem;
}

.form-check-input:checked { background-color: #198754; border-color: #198754; }

/* ---- Brand and identity ------------------------------------------------- */

.app-wordmark { color: var(--pv-brand-navy); }
[data-bs-theme="dark"] .app-wordmark { color: var(--bs-body-color); }

.menu-item-active { background-color: var(--pv-brand-navy); }
.menu-item-active .material-symbols-outlined { color: #fff; }

.project-avatar   { width: 2rem; height: 2rem; flex-shrink: 0;
                    background-color: var(--pv-project-default-bg); color: var(--pv-project-default-fg); }
.project-avatar-1 { background-color: var(--pv-project-1-bg); color: var(--pv-project-1-fg); }
.project-avatar-2 { background-color: var(--pv-project-2-bg); color: var(--pv-project-2-fg); }
.project-avatar-3 { background-color: var(--pv-project-3-bg); color: var(--pv-project-3-fg); }
.project-avatar-4 { background-color: var(--pv-project-4-bg); color: var(--pv-project-4-fg); }

.chip-tint {
  background-color: color-mix(in srgb, var(--pvb-chip) 14%, transparent);
  border-color: color-mix(in srgb, var(--pvb-chip) 40%, transparent) !important; /* beats .border */
  color: var(--pvb-chip);
}
.chip-barrier-control { --pvb-chip: var(--pvb-barrier-control); }
.chip-barrier-safety  { --pvb-chip: var(--pvb-barrier-safety); }
.chip-barrier-support { --pvb-chip: var(--pvb-barrier-support); }

.filter-count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.25rem; height: 1.25rem; padding: 0;
  border-radius: 50%; font-size: 0.6875rem; line-height: 1;
}

/* ---- Lists, rows, menus ------------------------------------------------- */

.side-list-item-alert    { background-color: var(--bs-danger-bg-subtle); }
.side-list-item-selected { background-color: var(--bs-secondary-bg);
                           box-shadow: inset 0.1875rem 0 0 0 var(--bs-primary); }

.side-list-item-options {
  width: 2rem; height: 2rem;
  border-radius: var(--bs-border-radius);
  background-color: transparent;
  transition: background-color 120ms ease-in-out;
}
.side-list-item-options:hover,
.side-list-item-options:focus-visible {
  background-color: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}
@media (prefers-reduced-motion: reduce) {
  .side-list-item-options { transition: none; }
}

.context-menu { max-width: calc(100% - 1rem); max-height: calc(100% - 1rem);
                overflow-x: hidden; overflow-y: auto; }
.context-menu .dropdown-item { white-space: normal; overflow-wrap: break-word; }

.tab-button-alert {
  --bs-btn-color: var(--bs-danger-text-emphasis);
  --bs-btn-bg: var(--bs-danger-bg-subtle);
  --bs-btn-border-color: var(--bs-danger-border-subtle);
  --bs-btn-hover-color: var(--bs-danger-text-emphasis);
  --bs-btn-hover-bg: var(--bs-danger-border-subtle);
  --bs-btn-hover-border-color: var(--bs-danger-border-subtle);
  --bs-btn-active-color: var(--bs-danger-text-emphasis);
  --bs-btn-active-bg: var(--bs-danger-border-subtle);
  --bs-btn-active-border-color: var(--bs-danger-border-subtle);
}

/* ---- Layout helpers ----------------------------------------------------- */

.min-w-0 { min-width: 0; }
.min-h-0 { min-height: 0; }

.mail-list-pane   { flex: 1 1 0; min-width: 0; min-height: 0; }
.mail-detail-pane { flex: 1 1 0; min-width: 0; min-height: 0; }
@media (min-width: 768px)  { .mail-list-pane { flex: 0 0 20rem; width: 20rem; } }
@media (min-width: 768px) and (max-width: 991.98px) { .mail-list-pane-lg { flex: 1 1 0; width: auto; } }
@media (min-width: 1200px) { .mail-list-pane { flex: 0 0 24rem; width: 24rem; } }

.filter-dropdown-panel { width: min(22rem, calc(100vw - 2rem)); }
.filter-drawer.offcanvas-bottom {
  height: auto; max-height: 90dvh; overflow: hidden;
  border-top-left-radius: var(--bs-border-radius-lg);
  border-top-right-radius: var(--bs-border-radius-lg);
}
.filter-drawer .offcanvas-body { overflow-y: auto; }

/* ---- Dark-mode corrections --------------------------------------------- */

[data-bs-theme="dark"] .table-light {
  --bs-table-color: var(--bs-body-color);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--bs-border-color);
  --bs-table-striped-color: var(--bs-body-color);
  --bs-table-striped-bg: transparent;
  --bs-table-active-color: var(--bs-body-color);
  --bs-table-active-bg: transparent;
  --bs-table-hover-color: var(--bs-body-color);
  --bs-table-hover-bg: transparent;
}

[data-bs-theme="dark"] .signature-image { filter: invert(1) hue-rotate(180deg); }


/* ==========================================================================
   2. Analytics additions
   ========================================================================== */

/* ---- Tokens ------------------------------------------------------------- */

:root {
  /* App bar height and rail width (§3.2). No Bootstrap utility sets a fixed size. */
  --pv-bar-size: 47px;
}

/* Chart colours. ECharts draws to canvas and cannot use classes, so
   echartsInterop.js reads these by name when it draws. Status entries follow the
   five-level scale (§2.4): the solid role colours on light, the text-emphasis
   values on dark where solid fills are too heavy. The single-series colour mirrors
   the wordmark: navy on light, body text on dark, where navy disappears (§2.2). */
[data-bs-theme="light"] {
  --pv-chart-series: #242e5d;
  --pv-chart-secondary: #6c757d;
  --pv-chart-info: #3793c4;
  --pv-chart-success: #198754;
  --pv-chart-warning: #ff910a;
  --pv-chart-danger: #dc3545;
}

[data-bs-theme="dark"] {
  --pv-chart-series: #dee2e6;
  --pv-chart-secondary: #a7acb1;
  --pv-chart-info: #6edff6;
  --pv-chart-success: #75b798;
  --pv-chart-warning: #ffda6a;
  --pv-chart-danger: #ea868f;
}

/* ---- Blazor error bar --------------------------------------------------- */

/* Blazor reveals the bar by setting display: block inline, so it cannot start
   hidden with .d-none (!important would keep it hidden for good). It sits above
   the offcanvas layers (1045). Position and padding are V2's (app.css); the
   colours are theme tokens rather than V2's template lightyellow, so the bar is
   legible in dark mode too. */
#blazor-error-ui {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 1060;
  box-sizing: border-box;
  width: 100%;
  padding: 0.6rem 1.25rem 0.7rem 1.25rem;
  color: var(--bs-danger-text-emphasis);
  background-color: var(--bs-danger-bg-subtle);
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: 0.75rem;
  top: 0.5rem;
}

/* ---- #app and the loading screen (V2 app.css) --------------------------- */

/* body > #app > .page > main > article is one viewport-tall flex column; #app is
   a link in that chain. Without it .page cannot fill the screen and main stops
   being the scroll container. */
#app {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* img/img_hlogo.png is white on transparent, so it is drawn as a mask over
   currentColor: the markup gives it .app-wordmark, which is navy on light and the
   title gray on dark. The ratio is the PNG's own (617 × 197). Used on the loading
   screen, in the top bar and on the account screens (Login, AuthPanel). */
.loading-logo,
.top-bar-logo,
.auth-panel-logo {
    display: block;
    aspect-ratio: 617 / 197;
    background-color: currentColor;
    -webkit-mask: url("../img/img_hlogo.png") center / contain no-repeat;
    mask: url("../img/img_hlogo.png") center / contain no-repeat;

}

.top-bar-wordmark span:first-child {
    margin-right: 0.25rem;
}

.loading-logo {
  width: min(16rem, 70vw);
}

/* Sized by height so it sits in the 47px bar like the 22px icon it replaced. */
.top-bar-logo {
    position: relative;
    top: -2.9px;
    margin-right: 0.5rem;
    height: 30px;
}

/* Centred by the flex column around it in index.html, so no viewport margin. */
.loading-progress {
  position: relative;
  display: block;
  width: 8rem;
  height: 8rem;
}

.loading-progress circle {
  fill: none;
  stroke: var(--bs-secondary-bg);
  stroke-width: 0.2rem;
  transform-origin: 50% 50%;
  transform: rotate(-90deg);
}

.loading-progress circle:last-child {
  stroke: var(--bs-secondary-color);
  stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
  transition: stroke-dasharray 0.05s ease-in-out;
}

/* The percentage in the middle of the ring. */
.loading-progress-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.loading-progress-text:after {
  content: var(--blazor-load-percentage-text, "Cargando");
}

/* ---- App shell, top bar and navigation rail ----------------------------- */

/* Copied from Prevebsa.FrontendV2 — the shell chain from wwwroot/css/app.css, the
   bars from boostrapoverride.css — so Layout/MainLayout.razor and Shared/Bars render
   exactly as V2's. Keep in step with V2 rather than editing. */

/* body > #app > .page > main > article: every link sets min-height: 0 so a child
   that overflows scrolls inside itself. #app carries its flex classes in
   index.html. */
.page {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: row;
}

/* flex-basis 0 so a wide page never squeezes the 47px rail; clip on x so the
   shell cannot scroll sideways on its own. */
main {
  flex: 1 1 0;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: clip;
}

/* Pages own their scrolling (h-100 overflow-y-auto on the page root). clip, not
   hidden: hidden would make this a scroll container without a scrollbar. */
article {
  height: 100%;
  min-width: 0;
  min-height: 0;
  overflow: clip;
}

@media (min-width: 768px) {
  .sidebar {
    position: sticky;
    top: 0;
  }
}

/* The profile menu's project / zone line. */
.fs-10 {
  font-size: 0.6rem !important;
}

.btn-basic:hover {
  background-color: var(--bs-secondary-bg);
  box-shadow: none;
}

.navbar {
  height: 47px;
  /* No padding on the leading edge: the menu button and the logo are full-height
     targets that meet the corner, and the rail below lines up with them. */
  padding: 0 0.75rem 0 0;
  flex-shrink: 0;
}

/* Collapsed, the rail never scrolls. overflow-x: hidden on its own makes the
   browser compute overflow-y as auto, so on a short screen the few pixels the
   47px items overflow by showed a scrollbar — and the scrollbar took its width
   out of the 47px column, pushing the icons out of line. It becomes scrollable
   only expanded (below), where a very short window may genuinely need it. */
.nav-scrollable {
  width: 47px;
  height: 100%;
  background-color: var(--bs-body-bg);
  transition: width 0.2s ease-in-out;
  overflow-x: hidden;
  overflow-y: hidden;
  scrollbar-width: none;
  position: absolute; /* Allows it to overlap content */
  left: 0;
  border-top: 1px solid var(--bs-border-color);
  border-right: 1px solid var(--bs-border-color);
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Hover effect: only the scrollable area grows. */
.nav-scrollable:hover {
  width: 260px;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* WebKit ignores scrollbar-width; hide its 5px bar on the collapsed rail too. */
.nav-scrollable:not(:hover)::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Each 47px link row sits in a 43px item and overflows it; clip it at the item so
   the overflow never adds to the rail's scroll height. */
.nav-scrollable .nav-item {
  overflow: hidden;
}

.menu-item-active {
  background-color: var(--pv-brand-navy) !important;
  cursor: pointer;
}

.menu-item-active i {
  color: white;
}

.nav-link-item-selected {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  width: 30px;
  height: 30px;
  border-radius: 0.25rem;
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 43px;
  padding: 0rem !important;
  width: 100%;
}

.nav-link {
  color: var(--bs-secondary-color) !important;
  padding: 0rem;
  display: flex !important;
  flex-direction: column;
  align-items: center !important;
  justify-content: center;
  height: 100% !important;
  width: 100% !important;
  line-height: 1;
  font-size: 0.875rem;
}

.nav-link:hover {
  background-color: var(--bs-secondary-bg) !important;
  padding: 0rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.nav-icon-box {
  min-width: 47px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.nav-label-text {
  margin-left: 12px;
  opacity: 0;
  white-space: nowrap;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.nav-scrollable:hover .nav-label-text {
  opacity: 1;
  pointer-events: auto;
}

.nav-link-content {
  display: flex;
  align-items: center;
  height: 47px;
  width: 100%;
}

/* A fixed column that never gives its width back to a page that overflows. */
.sidebar {
  width: 47px !important;
  flex: 0 0 47px;
  position: relative;
  z-index: 100;
}

/* Hover cannot happen on touch: below md the rail steps aside for the drawer. */
@media (max-width: 767.98px) {
  .sidebar {
    display: none;
  }
}

/* Navigation drawer (below md): the same MainBar markup, full width, labels always
   visible, no hover growth. */
.nav-drawer {
  max-width: 17rem;
}

.top-bar-profile {
  background-color: transparent;
  border: var(--bs-border-width) solid var(--bs-border-color);
  color: var(--bs-body-color);
}

.top-bar-profile:hover,
.top-bar-profile:focus-visible {
  background-color: var(--bs-secondary-bg);
  border-color: var(--bs-border-color);
  color: var(--bs-body-color);
}

.top-bar-profile-avatar {
  width: 36px;
  height: 36px;
  object-fit: cover;
}

.top-bar-button {
  width: 47px;
  flex-shrink: 0;
}

/* Equal and elastic ends below md put the wordmark in the actual centre. */
.top-bar-side {
  flex: 1 1 0;
  min-width: 0;
}

.top-bar-wordmark {
  flex: 0 1 auto;
  min-width: 0;
  text-align: center;
}

/* From md the name sits beside the mark as one lockup on the leading edge. */
@media (min-width: 768px) {
  .top-bar-side {
    flex: 0 0 auto;
  }

  .top-bar-wordmark {
    flex: 1 1 auto;
    text-align: left;
  }
}

.nav-drawer .nav-scrollable,
.nav-drawer .nav-scrollable:hover {
  position: static;
  width: 100%;
  height: auto;
  align-items: stretch;
  border: 0;
  transition: none;
}

.nav-drawer .nav-label-text {
  opacity: 1;
  pointer-events: auto;
}

/* ---- Dialogs ------------------------------------------------------------ */

/* Copied from Prevebsa.FrontendV2 boostrapoverride.css. Scrim behind a modal
   rendered without Bootstrap's JS backdrop element (Shared/Dialogs/Components/
   Dialog.razor draws .modal.show.d-block from component state). */
.modal-scrim {
  background-color: rgba(var(--bs-black-rgb), 0.5);
}

/* ---- Dashboard boxes ---------------------------------------------------- */

/* Charts, the map and the alert list fill the height their dashboard row gives
   them — at least 40% of the viewport from lg, as the rows always were, and a
   readable 18rem when stacked on a phone. ECharts and Leaflet measure their
   element's pixel box and no Bootstrap utility sets a height in rem or vh, hence
   the rule. The child is pinned to the box, so its content never stretches the
   row. */
.dashboard-box {
  position: relative;
  height: 100%;
  min-height: 18rem;
}

.dashboard-box > * {
  position: absolute;
  inset: 0;
}

@media (min-width: 992px) {
  .dashboard-box {
    min-height: 40vh;
  }
}

/* ---- Account screens ---------------------------------------------------- */

/* Copied from Prevebsa.FrontendV2 wwwroot/css/boostrapoverride.css (and app.css for
   .validation-message) so Features/Auth renders exactly as V2's Pages/Auth. The
   markup there uses these names; keep them in step with V2 rather than editing. */

/* Veil over the region being replaced while a request runs (§2.8). */
.saving-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(var(--bs-body-bg-rgb), 0.9);
  z-index: 3;
  transition: all 0.3s ease;
}

/* Bootstrap's position utilities stop at 0 / 50 / 100. The login page's
   show-password button sits over the input, below its label. */
.top-75 {
  top: 75%;
}

/* Bootstrap ships min-vh-100 but no min-h-100; a page inside a scroll container
   fills it at least once and grows past it when taller. */
.min-h-100 {
  min-height: 100% !important;
}

/* AuthPanel: one short form, a readable measure. */
.auth-panel {
  max-width: 26rem;
}

/* The top bar's lockup, at the same size and with the same optical nudge, so the
   account screens read as the same product. */
.auth-panel-logo {
  position: relative;
  top: -2.9px;
  height: 30px;
}

/* Login's right-hand heading scales with the viewport; Bootstrap has no
   responsive font-size utilities. */
.landing-title {
  font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

@media (max-width: 991.98px) {
  .landing-title {
    max-width: none;
  }
}

.landing-lead {
  max-width: 52ch;
  line-height: 1.5;
}

/* Blazor's ValidationMessage renders this class. V2 paints it red; the form
   invalid colour is the same red on light and stays legible on dark. */
.validation-message {
  color: var(--bs-form-invalid-color);
}
