/* Lignum brand: teal primary; secondary stays Tabler grey for UI chrome. */
:root,
[data-bs-theme="light"] {
  --lignum-teal: #5e7775;
  --lignum-orange: #ff9e18;
  --lignum-yellow: #ffd54a;
  --lignum-yellow-rgb: 255, 213, 74;

  --tblr-primary: var(--lignum-teal);
  --tblr-primary-rgb: 94, 119, 117;
  --tblr-primary-text-emphasis: color-mix(in oklab, var(--tblr-primary), black 40%);
  --tblr-primary-bg-subtle: color-mix(in oklab, var(--tblr-primary), white 92%);
  --tblr-primary-border-subtle: color-mix(in oklab, var(--tblr-primary), white 75%);
  --tblr-primary-lt-rgb: 239, 241, 241;

  --tblr-orange: var(--lignum-orange);
  --tblr-orange-rgb: 255, 158, 24;

  /* Extra muted colors, defined the same way Tabler defines its own
     (base + -rgb + -lt color-mix, same 10% mix as Tabler's stock colors so
     the badge backgrounds match the rest of the app). The distinction from
     neighboring hues comes from the base text color being darker/less
     saturated than Tabler's vivid ones, not from a stronger tint.
     See .text-gold/.bg-gold-lt etc. below. */
  --tblr-gold: #8a6d1f;
  --tblr-gold-rgb: 138, 109, 31;
  --tblr-gold-lt: color-mix(in oklab, var(--tblr-gold) 10%, transparent);

  --tblr-brown: #7a2e1f;
  --tblr-brown-rgb: 122, 46, 31;
  --tblr-brown-lt: color-mix(in oklab, var(--tblr-brown) 10%, transparent);

  /* Deep garnet: same hue as Tabler red but much darker/less saturated,
     so it reads apart from pink by value, not just hue (same trick as
     gold vs orange). Not reusing --tblr-red directly since red carries
     danger/delete meaning elsewhere in the app. */
  --tblr-garnet: #7e1b1b;
  --tblr-garnet-rgb: 126, 27, 27;
  --tblr-garnet-lt: color-mix(in oklab, var(--tblr-garnet) 10%, transparent);

  /* Lighter sidebar active state (Tabler default 0.2 is too strong). */
  --tblr-navbar-active-bg: rgba(0, 0, 0, 0.05);
  --tblr-navbar-active-border-color: var(--lignum-orange);

  /* Brand logos: Tabler caps .navbar-brand-image at 2rem. */
  --lignum-sidebar-logo-height: 2rem;
  --lignum-login-logo-height: 3.25rem;
}

/* .min-w-0 is a standard Bootstrap utility (lets a flex/grid item shrink
   below its content's width, the usual partner for .text-truncate) that this
   Tabler build never actually ships — dozens of templates use it assuming
   it works, so instead of truncating, that text silently overflows its
   container. Defining it here fixes every one of those at once. */
.min-w-0 {
  min-width: 0 !important;
}

/* Utility classes for the two extra colors above, matching Tabler's own
   .text-* / .bg-*-lt pattern so they behave like any other Tabler color. */
.text-gold {
  color: var(--tblr-gold) !important;
}
.bg-gold-lt {
  color: var(--tblr-gold) !important;
  background-color: var(--tblr-gold-lt) !important;
  border-color: rgba(var(--tblr-gold-rgb), 0.1) !important;
}

.text-brown {
  color: var(--tblr-brown) !important;
}
.bg-brown-lt {
  color: var(--tblr-brown) !important;
  background-color: var(--tblr-brown-lt) !important;
  border-color: rgba(var(--tblr-brown-rgb), 0.1) !important;
}

.text-garnet {
  color: var(--tblr-garnet) !important;
}
.bg-garnet-lt {
  color: var(--tblr-garnet) !important;
  background-color: var(--tblr-garnet-lt) !important;
  border-color: rgba(var(--tblr-garnet-rgb), 0.1) !important;
}

/* Tabler 1.4 ships a second `.steps` rule, for the numbered headings of its
   docs pages, that gives every steps list a left border, a left margin and
   padding, and a bottom margin. The app only uses the step indicators
   (.step-item), so those are reset once here for every steps list. */
.steps {
  margin-left: 0;
  margin-bottom: 0;
  padding-left: 0;
  border-left: 0;
}

/* A dropdown shown as a selectgroup card (icon and title, chevron on the right): the
   native select lies over the card, invisible, so a click opens its list. */
.select-box {
  position: relative;
}
.select-box-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.select-box-arrow {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  pointer-events: none;
}
.select-box:hover .form-selectgroup-label,
.select-box:focus-within .form-selectgroup-label {
  border-color: var(--tblr-primary);
}
.select-box:focus-within .form-selectgroup-label {
  box-shadow: 0 0 0 0.25rem rgba(var(--tblr-primary-rgb), 0.25);
}

/* Contract wizard: the goods' route between two delivery cards, a dashed line with the
   transport icon in the middle (green: needed; no icon: none). Vertical on small screens. */
.route-line {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 9rem;
  gap: 0.5rem;
  color: var(--tblr-border-color);
}
.route-line::before,
.route-line::after {
  content: "";
  flex: 1;
  border-top: 2px dashed currentColor;
}
.route-line-active {
  color: var(--tblr-green);
}
@media (max-width: 767.98px) {
  .route-line {
    flex-basis: auto;
    flex-direction: column;
    min-height: 3rem;
  }
  .route-line::before,
  .route-line::after {
    border-top: 0;
    border-left: 2px dashed currentColor;
  }
}

/* Contract wizard sites: the dashed route between the loading and the unloading lists. */
.route-dash-v {
  width: 0;
  height: 0.75rem;
  border-left: 2px dashed currentColor;
}
/* Between the two sections, from the blue loading to the purple unloading. */
.wizard-sites-route {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Contract wizard: the step bar's segments link to their step. */
.wizard-steps .progress-bar:hover {
  filter: brightness(0.9);
}

/* Contract wizard: the separators between a step's parts (Producto, Cantidad…), with room
   around them. */
.wizard-section-title {
  margin-top: 2rem;
  margin-bottom: 2rem;
}

/* The first one sits right under the step's question: no extra gap there. */
.wizard-section-title:first-of-type {
  margin-top: 1.5rem;
}

/* Contract wizard: the reminder strip's product and party names shrink to "…" rather than
   push the strip wider. */
.wizard-reminder-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Contract wizard: one narrow column (no side sheet). */
.wizard-column {
  max-width: 56rem;
  margin-inline: auto;
}

/* Contract wizard review: the amounts planned per month, as bars on one scale. */
.wizard-months {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 0.375rem;
  align-items: end;
  height: 4rem;
  border-bottom: 1px solid var(--tblr-border-color);
}
.wizard-months > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  gap: 0.125rem;
  font-variant-numeric: tabular-nums;
}
.wizard-months-bar {
  width: 75%; /* wide enough that one or two months still fill the chart */
  max-width: 4.5rem;
  min-height: 2px;
  border-radius: 3px 3px 0 0;
  background: var(--tblr-primary);
}
.wizard-months-labels {
  height: auto;
  border-bottom: 0;
  font-size: 0.75rem;
  color: var(--tblr-secondary);
  text-align: center;
}

/* Contract wizard prices: the mayoraciones box, and the margin as one bar of the sale
   price split into its costs (shades of orange) and the margin (green). */
.wizard-storage-box {
  border: 1px dashed var(--tblr-border-color);
}
.wizard-clause {
  border-left: 3px solid var(--tblr-primary);
  padding-left: 0.625rem;
}
.wizard-margin-bar {
  position: relative;
  display: flex;
  gap: 2px;
  height: 0.875rem;
  border-radius: 4px;
  background: var(--tblr-bg-surface-secondary);
}
.wizard-margin-bar > span:not(.wizard-margin-sale) {
  height: 100%;
  min-width: 3px;
}
.wizard-margin-bar > span:first-child {
  border-radius: 4px 0 0 4px;
}
.wizard-margin-sale {
  position: absolute;
  top: -0.25rem;
  bottom: -0.25rem;
  width: 2px;
  background: var(--tblr-body-color);
}
.wizard-margin-freight {
  background: color-mix(in srgb, var(--tblr-orange) 65%, var(--tblr-bg-surface));
}
.wizard-margin-fees {
  background: color-mix(in srgb, var(--tblr-orange) 35%, var(--tblr-bg-surface));
}
.wizard-margin-key {
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 3px;
  margin-right: 0.3rem;
}

/* Workflow status panel: cap the step meter's width so it reads as a fixed
   indicator instead of stretching to fill the row on entities with few steps. */
.wf-meter {
  max-width: 500px;
}

/* Workflow status panel: terminal-state icon (cancelled/completed/returned). */
.wf-terminal-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  flex-shrink: 0;
}
.wf-terminal-icon .icon {
  width: 1.1rem;
  height: 1.1rem;
}

/* Workflow status panel: always-visible history/requests/corrections actions,
   replacing a kebab dropdown whose items stayed hidden behind a click. */
.wf-toolbar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.35rem;
}
.wf-toolbar-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.35rem 0.6rem 0.4rem;
  color: var(--tblr-secondary);
  background: transparent;
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius);
}
.wf-toolbar-cell:hover {
  background: var(--tblr-bg-surface-secondary, #f6f8fb);
  color: var(--tblr-body-color);
}
.wf-toolbar-cell .icon {
  width: 1rem;
  height: 1rem;
}
.wf-toolbar-label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  /* Fixed floor (not "equal to my siblings") so a lone button (e.g.
     contracts' single Historial cell) matches the width it would have
     next to the app's longest label ("Correcciones", trucks) even when
     there are no siblings here to equalize against. */
  min-width: 12ch;
  text-align: center;
}
.wf-toolbar-badge {
  position: absolute;
  top: 0.05rem;
  right: 0.15rem;
}

.navbar-vertical .navbar-brand-image {
  height: var(--lignum-sidebar-logo-height);
  width: auto;
}
.sidebar-brand-icon {
  display: none;
  height: var(--sidebar-icon-slot);
}

.page-center .login-brand-image {
  display: block;
  height: var(--lignum-login-logo-height);
  width: auto;
  max-width: min(100%, 15rem);
  margin-inline: auto;
}

/* Global readonly field styling:
   mimic disabled appearance while preserving form submission. */
input[readonly],
textarea[readonly],
.form-control[readonly],
.form-select[readonly] {
  background-color: var(--tblr-disabled-bg, #f1f3f5);
  color: var(--tblr-secondary-color, #6c757d);
  border-color: var(--tblr-border-color, #d9dee3);
  cursor: not-allowed;
  opacity: 1;
}

input[readonly]:focus,
textarea[readonly]:focus,
.form-control[readonly]:focus,
.form-select[readonly]:focus {
  box-shadow: none;
  border-color: var(--tblr-border-color, #d9dee3);
}

.form-selectgroup-input:checked + .form-selectgroup-label .selectgroup-state-icon {
  color: var(--tblr-primary);
}

/* Shared pill height for ui_badge (badge + status dot).
   Tabler .status defaults to height: 1.5rem; .badge has no fixed height — normalize both. */
.ui-badge.badge,
.ui-badge.status {
  --tblr-status-height: 1.5rem;
  --tblr-badge-padding-y: 0;
  --tblr-badge-padding-x: 0.55rem;
  --tblr-badge-font-size: 0.75rem;
  height: 1.5rem;
  min-height: 1.5rem;
  padding: 0 0.55rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.5rem;
  gap: 0.35rem;
  box-sizing: border-box;
  vertical-align: middle;
}

.ui-badge.badge:not(.ui-badge-has-icon):not(.ui-badge-icon-only) {
  justify-content: center;
}

.ui-badge-icon-only.badge {
  --tblr-badge-padding-x: 0.35rem;
  padding: 0 0.35rem;
  justify-content: center;
}

/* compact variant: same pill, one notch smaller (truck card, schedule board) */
.ui-badge-sm.badge,
.ui-badge-sm.status {
  --tblr-status-height: 1.25rem;
  --tblr-badge-padding-x: 0.4rem;
  --tblr-badge-font-size: 0.6875rem;
  height: 1.25rem;
  min-height: 1.25rem;
  padding: 0 0.4rem;
  font-size: 0.6875rem;
  line-height: 1.25rem;
  gap: 0.25rem;
}

.ui-badge-sm.ui-badge-icon-only.badge {
  --tblr-badge-padding-x: 0.25rem;
  padding: 0 0.25rem;
}

.ui-badge {
  display: inline-flex;
  align-items: center;
}

/* <button>/<a> badges must render identically to <span> ones */
button.ui-badge,
a.ui-badge {
  appearance: none;
  border: 0;
  font: inherit;
  text-decoration: none;
  background-image: none;
  cursor: pointer;
}

.ui-badge .icon {
  width: 0.875rem;
  height: 0.875rem;
  font-size: 0.875rem;
  line-height: 1;
}

.ui-badge-sm .icon {
  width: 0.75rem;
  height: 0.75rem;
  font-size: 0.75rem;
}

.ui-badge .ui-badge-dot,
.ui-badge .status-dot {
  flex-shrink: 0;
  width: 0.4rem;
  height: 0.4rem;
  margin: 0;
}

.table-scroll-panel {
  height: calc(100dvh - 13rem);
}

/* Scrollable regions in app modals (link search, characteristics, etc.). */
.modal-scroll-panel {
  height: calc(100dvh - 24rem);
  overflow-y: auto;
  overflow-x: hidden;
}

/* App modal: size via data-modal-size on #appModalContent. */
#appModalDialog:has(#appModalContent[data-modal-size="sm"]) {
  max-width: 400px;
}

#appModalDialog:has(#appModalContent[data-modal-size="md"]) {
  max-width: 650px;
}

#appModalDialog:has(#appModalContent[data-modal-size="lg"]) {
  max-width: 800px;
}

#appModalDialog:has(#appModalContent[data-modal-size="xl"]) {
  max-width: 1140px;
}

/* Document preview modals: tall dialog; iframe fills remaining body space. */
#appModalDialog:has(.modal-preview-fill) {
  height: 90dvh;
  min-height: 36rem;
  max-height: max(95dvh, 36rem);
}

#appModalDialog:has(.modal-preview-fill) .modal-content {
  height: 100%;
  display: flex;
  flex-direction: column;
}

#appModalDialog:has(.modal-preview-fill) #appModalContent {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
}

#appModalDialog:has(.modal-preview-fill) .modal-header,
#appModalDialog:has(.modal-preview-fill) .modal-footer {
  flex-shrink: 0;
}

#appModalDialog:has(.modal-preview-fill) .modal-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-preview-fill {
  flex: 1 1 auto;
  min-height: max(40dvh, 18rem);
}

/* Email HTML body preview in the shared outbound email modal. */
.email-message-preview {
  height: max(40dvh, 18rem);
}

/* Contract review: stacked on small screens; matches left column height at lg+. */
.contract-review-preview {
  height: max(40dvh, 18rem);
}

@media (min-width: 992px) {
  .contract-review-preview {
    height: auto;
    min-height: 0;
    flex: 1 1 auto;
  }
}

.table-scroll-region {
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

.table-sticky-head th {
  position: sticky;
  top: 0;
  z-index: 2;
  background-color: var(--tblr-bg-surface);
}

/* Denser data tables: index list tables use .table-sm.card-table. */
.table.table-sm.card-table {
  font-size: var(--tblr-font-size-sm, 0.8rem);
}

.table-hover {
  --tblr-table-hover-bg: rgba(var(--tblr-emphasis-color-rgb), 0.025);
}

.table.table-sm.card-table > :not(caption) > * > * {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
  min-height: 2rem;
  vertical-align: middle;
}

/* Keep row height stable whether the action is Manage or a ⋮ menu. */
.table.table-sm.card-table .btn-sm {
  line-height: 1.25;
  padding-top: 0.2rem;
  padding-bottom: 0.2rem;
}

.table.table-sm.card-table .btn-ghost-secondary.btn-icon {
  padding: 0;
}

/* Tabler card-table clears top/side borders but not the last row bottom border,
   which stacks with the card edge. Mirror Tabler's first-row rules for last row. */
.card .table.card-table tbody tr:last-child,
.card .table.card-table tfoot tr:last-child {
  border-bottom: 0;
}

.card .table.card-table tbody tr:last-child > *,
.card .table.card-table tfoot tr:last-child > * {
  border-bottom: 0 !important;
}

/* Flush tables in zero-padding card bodies (quality review, tab tables, etc.). */
.card > .card-body.p-0 .table.card-table tbody tr:last-child > *,
.card > .card-body.p-0 .table.card-table tfoot tr:last-child > * {
  border-bottom: 0 !important;
}

[id^="contract-"][id$="-picker"] .picker-card {
  min-height: 60px;
}

/* ── Sidebar collapse ─────────────────────────────────────────────────────── */
:root {
  --sidebar-width: 15rem;
  --sidebar-icon-slot: 1.75rem;
  --sidebar-nav-padding-x: 1rem;
  --sidebar-mini-width: calc(
    var(--sidebar-nav-padding-x) * 2 + var(--sidebar-icon-slot)
  );
  --sidebar-transition: 0.22s ease;
}

/* Smooth transitions; hide scrollbar that eats into sidebar width */
.navbar-vertical {
  transition: width var(--sidebar-transition) !important;
  overflow-y: auto !important;
  scrollbar-width: none !important;
}
.navbar-vertical::-webkit-scrollbar {
  display: none;
}
@media (min-width: 992px) {
  .page-wrapper {
    transition: margin-left var(--sidebar-transition) !important;
  }
}

/* Header: logo centered with a separator below */
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 0.875rem 0.75rem;
  min-height: 3.75rem;
  border-bottom: 1px solid var(--tblr-border-color);
  margin-bottom: 0.25rem;
}

/* Sidebar fills viewport; footer pinned to bottom */
.navbar-vertical .container-fluid {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding-inline: 0;
}
#sidebar-menu {
  min-height: 0;
}

/* Consistent nav row layout — icons stay fixed when collapsing */
.navbar-vertical .nav-link,
.navbar-vertical .sidebar-nav-btn {
  display: flex !important;
  align-items: center !important;
  gap: 0.75rem;
  padding: 0.5rem var(--sidebar-nav-padding-x) !important;
}
.navbar-vertical .nav-link-icon,
.sidebar-language-option .nav-link-icon {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: var(--sidebar-icon-slot);
  height: var(--sidebar-icon-slot);
  flex-shrink: 0;
  margin: 0 !important;
}
.navbar-vertical .nav-link-icon i {
  font-size: 1.25rem;
  line-height: 1;
}
.sidebar-nav-btn {
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

/* Footer utilities: collapse, language, profile */
.sidebar-bottom {
  flex-shrink: 0;
}
.sidebar-footer {
  border-top: 1px solid var(--tblr-border-color);
}
.sidebar-footer .nav-link,
.sidebar-footer .sidebar-nav-btn {
  color: var(--tblr-secondary-color);
}
.sidebar-footer .nav-link:hover,
.sidebar-footer .nav-link:focus,
.sidebar-footer .sidebar-nav-btn:hover,
.sidebar-footer .sidebar-nav-btn:focus {
  color: var(--tblr-body-color);
}
.sidebar-footer-profile {
  border-top: 1px solid var(--tblr-border-color);
}
.sidebar-footer-profile .nav-link {
  color: var(--tblr-body-color);
}
.sidebar-footer .country-flag,
.sidebar-language-menu .country-flag {
  width: 1.125rem;
  line-height: 1;
  border-radius: 2px;
}

/* Inline submenus: smooth vertical expand/collapse (no fade) */
.navbar-vertical .sidebar-animated-menu {
  display: grid !important;
  grid-template-rows: 0fr;
  position: static !important;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  float: none;
  transition: grid-template-rows var(--sidebar-transition);
  pointer-events: none;
}
.sidebar-animated-menu-body {
  overflow: hidden;
  min-height: 0;
}
.navbar-vertical .dropdown.show > .sidebar-animated-menu:not(.is-closing),
.navbar-vertical .sidebar-animated-menu.show:not(.is-closing) {
  grid-template-rows: 1fr;
  pointer-events: auto;
}
.navbar-vertical .sidebar-animated-menu.is-closing {
  grid-template-rows: 0fr;
  pointer-events: none;
}

.sidebar-language-option {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.5rem var(--sidebar-nav-padding-x);
  border: 0;
  background: transparent;
  color: var(--tblr-secondary-color);
  font-size: inherit;
  line-height: inherit;
  text-align: left;
  cursor: pointer;
}
.sidebar-language-option:hover,
.sidebar-language-option:focus {
  color: var(--tblr-body-color);
  background: var(--tblr-navbar-active-bg, rgba(0, 0, 0, 0.04));
}
.sidebar-language-option.active {
  font-weight: 600;
  color: var(--tblr-body-color);
  background: var(--tblr-navbar-active-bg, rgba(0, 0, 0, 0.05));
}

/* Tabler absolutely positions .navbar .navbar-nav .nav-link .badge for top-bar
   notifications — reset so sidebar counts sit inline beside the label. */
.navbar.navbar-vertical .navbar-nav .nav-link .badge {
  position: static;
  top: auto;
  right: auto;
  transform: none;
  min-width: 1.25rem;
  padding: 0.15rem 0.45rem;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1;
  flex-shrink: 0;
}

.navbar-vertical .nav-link-title--with-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* ── Collapsed state ──────────────────────────────────────────────────────── */
html.sidebar-collapsed .navbar-vertical {
  width: var(--sidebar-mini-width) !important;
  overflow: hidden !important;
}
html.sidebar-collapsed .page-wrapper {
  margin-left: var(--sidebar-mini-width) !important;
}

/* Hide sidebar link text and dropdown arrows; icons keep the same left padding.
   Scope to .navbar-vertical so page Actions/Issues dropdown carets stay visible. */
html.sidebar-collapsed .navbar-vertical .nav-link-title,
html.sidebar-collapsed .navbar-vertical .dropdown-toggle::after {
  display: none !important;
}

/* Force-close inline submenus while collapsed — with no icons, their text has
   nowhere to go in the mini width and gets cropped. State is preserved in the
   DOM (.show stays put), so they reappear automatically on decontract. */
html.sidebar-collapsed .navbar-vertical .sidebar-animated-menu {
  grid-template-rows: 0fr !important;
  pointer-events: none !important;
}

/* Swap full logo for icon mark in collapsed mode */
html.sidebar-collapsed .sidebar-brand-full {
  display: none !important;
}
html.sidebar-collapsed .sidebar-brand-icon {
  display: block;
}

/* Toggle icon rotates when collapsed */
.sidebar-collapse-icon {
  transition: transform var(--sidebar-transition);
}
html.sidebar-collapsed .sidebar-collapse-icon {
  transform: rotate(180deg);
}

/* User avatar inside nav-link icon slot */
.sidebar-avatar {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--tblr-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1;
  flex-shrink: 0;
}
.sidebar-footer-profile .nav-link-title {
  font-weight: 600;
  line-height: var(--sidebar-icon-slot);
}

/* Toolbar toggle buttons (planification board, listing filters, …). */
.planif-board-toolbar-actions {
  gap: 0;
}

.planif-board-toolbar-actions > .btn,
.planif-board-toolbar-actions > .dropdown > .btn {
  flex: 1 1 auto;
  padding-left: 0.85rem;
  padding-right: 0.85rem;
  color: var(--tblr-body-color);
}

.planif-board-toolbar-actions > .btn .icon,
.planif-board-toolbar-actions > .dropdown > .btn .icon {
  color: var(--tblr-secondary);
}

.planif-board-toolbar-actions > .btn.is-on,
.planif-board-toolbar-actions > .dropdown > .btn.is-on {
  background-color: var(--tblr-bg-surface-secondary, #f6f8fb);
  color: var(--tblr-body-color);
  box-shadow: inset 0 0 0 1px var(--tblr-border-color);
}

.planif-board-toolbar-actions > .btn.is-on .icon,
.planif-board-toolbar-actions > .dropdown > .btn.is-on .icon {
  color: var(--tblr-primary);
}

/* Planification toolbar header: a floating row of month/period selector +
   search card + filter card. Shared by the match board, schedule board,
   progress grid and product grid. */
.planif-board-header {
  margin-bottom: 0.25rem;
  --planif-header-block-width: 16rem;
  --planif-balance-block-width: 8.75rem;
}

.planif-board-header-controls {
  width: 100%;
}

.planif-board-header-left {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.planif-board-header-controls .planif-board-search-col {
  flex: 0 1 19rem;
  min-width: 12rem;
}

.planif-board-search-col .input-group-text {
  background: transparent;
}

.planif-board-header-controls .planif-board-actions-col {
  flex: 0 0 auto;
}

.planif-board-actions-col {
  min-width: 11rem;
}

.planif-board-actions-card .card-body {
  padding: 0.65rem;
}

.planif-toolbar-divider {
  width: 1px;
  align-self: stretch;
  margin: 0.15rem 0.35rem;
  background: var(--tblr-border-color);
}

/* Month / period stepper for planification toolbars: a full-height btn-group
   with prev/next icon buttons flanking a display-only centre label. Shared by
   the board month nav and the Avance year-window nav; per-context width lives
   on .planif-month-* / .progress-window-label. */
.planif-period-nav {
  display: flex;
}

.planif-period-nav > .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.planif-period-nav-label {
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.2;
}

/* Tighter dropdown menus: remove outer padding and divider gaps so item hover fills edge-to-edge. */
.dropdown-menu {
  --tblr-dropdown-padding-y: 0;
  --tblr-dropdown-divider-margin-y: 0;
  overflow: hidden;
}

.dropdown-item {
  line-height: 1.9;
}

/* Detail view underline tabs: no bold shift, orange active underline (sidebar). */
.detail-tabs-nav.nav-underline {
  --tblr-nav-underline-gap: 1.75rem;
}

.detail-tabs-nav.nav-underline .nav-link,
.detail-tabs-nav.nav-underline .nav-link.active,
.detail-tabs-nav.nav-underline .show > .nav-link {
  font-weight: 400;
}

.detail-tabs-nav.nav-underline .nav-link.active,
.detail-tabs-nav.nav-underline .show > .nav-link {
  border-bottom-color: var(--lignum-orange);
}

.detail-tabs-nav.nav-underline .nav-link:hover,
.detail-tabs-nav.nav-underline .nav-link:focus,
.detail-tabs-nav.nav-underline .nav-link:active {
  background-color: transparent;
  border-bottom-color: var(--lignum-orange);
}

/* Detail page header metadata: flex row keeps dot-separated items vertically aligned.
   Without this, the first li (no leading dot) sits higher than following items. */
.page-header ul.list-inline-dots {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.page-header ul.list-inline-dots > .list-inline-item {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.page-header ul.list-inline-dots > .list-inline-item + .list-inline-item::before {
  display: inline-flex;
  align-items: center;
  align-self: center;
  line-height: 1;
}

/* Disabled menu/button actions should look inactive (not still red/warning). */
.dropdown-item:disabled,
.dropdown-item.disabled,
button.dropdown-item:disabled,
.btn.text-danger:disabled,
.btn.text-warning:disabled,
.btn-danger:disabled,
.btn-warning:disabled {
  color: var(--tblr-secondary-color, #6c757d) !important;
  opacity: 0.65;
}
/* HTMX swap transition: htmx keeps .htmx-settling on the target briefly after
   swapping content in; removing it fades the new content in. */
.table-scroll-panel,
#planification-positions-grid {
  transition: opacity 0.15s ease-in;
}

.table-scroll-panel.htmx-settling,
#planification-positions-grid.htmx-settling {
  opacity: 0;
}

/* Native HTMX indicators (non-button spinners).
   Only the element named by hx-indicator — not descendants of any
   htmx-request ancestor (e.g. a saving form). */
.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Tabler's own .btn-loading look, driven by htmx's native .htmx-request class.
   Detached modal submit buttons (form="..." pointing at a <form> elsewhere)
   can't rely on the custom JS that used to guess-and-toggle .btn-loading for
   them; instead the form's own hx-indicator/hx-disabled-elt point straight at
   the button's id (see _app_modal_actions.html), and htmx toggles
   .htmx-request on it natively. This rule gives that the same visual as
   .btn-loading app-wide. */
.btn.htmx-request,
.dropdown-item.htmx-request {
  /* Push the label out of view without touching `color` - the spinner
     below relies on `currentColor`, which a `color: transparent` here
     would also apply to (pseudo-elements inherit color from their host),
     making the spinner invisible on every button variant. Also covers
     dropdown-item actions, which use the same hx-indicator="this" pattern
     but aren't .btn elements. */
  pointer-events: none;
  position: relative;
  overflow: hidden;
  text-indent: 200%;
  white-space: nowrap;
}
.btn.htmx-request .icon,
.dropdown-item.htmx-request .icon {
  /* text-indent only reliably pushes text out of view - a leading Tabler
     icon stays put, ending up next to the centered spinner. Hide it too. */
  opacity: 0;
}
.btn.htmx-request::after,
.dropdown-item.htmx-request::after {
  content: "";
  position: absolute;
  width: 1rem;
  height: 1rem;
  top: 50%;
  left: 50%;
  margin: -0.5rem 0 0 -0.5rem;
  text-indent: 0;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spinner-border 0.75s linear infinite;
}

/* Tabler alerts are flex row but leave align-items default (start), so the
   icon sits on the first line. Center it against the alert body everywhere. */
.alert {
  align-items: center;
}
.alert > .alert-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Contract Resumen tab dashboard (contracts/partials/resumen/*): percent
   rings, the Frecuencia-style weekly grid and the cumulative delivery chart.
   None has a stock Tabler component (no ApexCharts on this page), so they're
   hand-rolled here — everything else on the tab is stock Tabler (.card,
   .progress, .list-group, .badge, .status-dot, ...). */
.resumen-ring {
  position: relative;
  width: 96px;
  height: 96px;
}
.resumen-ring svg {
  display: block;
  width: 96px;
  height: 96px;
  transform: rotate(-90deg);
}
.resumen-ring-track,
.resumen-ring-value {
  fill: none;
  stroke-width: 15;
}
.resumen-ring-track {
  stroke: var(--tblr-secondary-bg-subtle);
}
.resumen-ring-value {
  stroke-linecap: round;
  transition: stroke-dashoffset 0.3s ease;
}
/* Ring palette: pricing = azure, planning = orange, ejecución = green.
   Empty dual-ring arcs are omitted in the template so a 0% dash doesn't
   leave a round-cap dot at the start. */
.resumen-ring-value-azure {
  stroke: var(--tblr-azure);
}
.resumen-ring-value-orange {
  stroke: var(--tblr-orange);
}
.resumen-ring-value-orange-light {
  stroke: rgba(var(--tblr-orange-rgb), 0.35);
}
.resumen-ring-value-green {
  stroke: var(--tblr-green);
}
.resumen-ring-value-green-light {
  stroke: color-mix(in srgb, var(--tblr-green) 35%, transparent);
}
.resumen-ring-legend {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.resumen-legend-swatch.ring-orange {
  background: var(--tblr-orange);
}
.resumen-legend-swatch.ring-orange-light {
  background: rgba(var(--tblr-orange-rgb), 0.35);
}
.resumen-legend-swatch.ring-green {
  background: var(--tblr-green);
}
.resumen-legend-swatch.ring-green-light {
  background: color-mix(in srgb, var(--tblr-green) 35%, transparent);
}
.resumen-legend-swatch.ring-track {
  background: var(--tblr-secondary-bg-subtle);
}
.resumen-ring-text {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.resumen-ring-pct {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
}

/* weekly grid — same coverage states and execution-marker accent as the
   planification frequency grid (planification-frequency.css), same source
   (apps.contracts.domain.execution_progress.cell_state/execution_marker);
   a different DOM shape here (a scrolling flex row, not a table) so the CSS
   itself isn't shared, but the state names and colours are kept identical. */
.resumen-grid-scroll {
  overflow-x: auto;
  padding-bottom: 4px;
}
.resumen-grid {
  display: flex;
  gap: 2px;
}
.resumen-week-cell {
  position: relative;
  flex: 1 1 0;
  min-width: 2.25rem;
  height: 3.25rem;
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 0.625rem;
}
.resumen-week-cell[data-cell-trucks-url] {
  cursor: pointer;
}
.resumen-week-cell[data-cell-trucks-url]:hover,
.resumen-week-cell.is-popover-open {
  box-shadow: inset 0 0 0 1px var(--tblr-primary);
}
.resumen-week-cell.st-pre {
  background: color-mix(in srgb, var(--tblr-azure) 8%, transparent);
}
.resumen-week-cell.st-under {
  background: color-mix(in srgb, var(--tblr-warning) 10%, transparent);
}
.resumen-week-cell.st-met {
  background: color-mix(in srgb, var(--tblr-success) 10%, transparent);
}
.resumen-week-cell.st-over {
  background: color-mix(in srgb, var(--tblr-success) 30%, transparent);
}
.resumen-week-cell.st-out {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6' viewBox='0 0 6 6'%3E%3Cpath d='M0 6L6 0H4L0 4M6 6V4L4 6' fill='%236e7681' fill-opacity='0.18'/%3E%3C/svg%3E");
  background-size: 6px 6px;
}
.resumen-week-cell .wc-t {
  color: var(--tblr-secondary-color);
  font-weight: 600;
}
.resumen-week-cell .wc-p {
  font-weight: 700;
  margin-top: 1px;
}
.resumen-week-cell.ex-started::before,
.resumen-week-cell.ex-settling::before,
.resumen-week-cell.ex-done::before,
.resumen-week-cell.ex-overdue::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: 3px 0 0 3px;
}
.resumen-week-cell.ex-started::before {
  background: var(--tblr-orange);
}
.resumen-week-cell.ex-settling::before {
  background: var(--tblr-purple);
}
.resumen-week-cell.ex-done::before {
  background: var(--tblr-green);
}
.resumen-week-cell.ex-overdue::before {
  background: var(--tblr-red);
}
/* legend swatches — same palette as the grid cells above (and as the
   Frecuencia grid's own .progress-swatch legend), just re-declared as small
   standalone squares instead of full cell backgrounds/::before accents. */
.resumen-legend-swatch {
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 2px;
  vertical-align: -2px;
  border: 1px solid var(--tblr-border-color);
  box-sizing: border-box;
}
.resumen-legend-swatch.st-pre {
  background: color-mix(in srgb, var(--tblr-azure) 8%, transparent);
}
.resumen-legend-swatch.st-under {
  background: color-mix(in srgb, var(--tblr-warning) 10%, transparent);
}
.resumen-legend-swatch.st-met {
  background: color-mix(in srgb, var(--tblr-success) 10%, transparent);
}
.resumen-legend-swatch.st-over {
  background: color-mix(in srgb, var(--tblr-success) 30%, transparent);
}
.resumen-legend-swatch.st-out {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6' viewBox='0 0 6 6'%3E%3Cpath d='M0 6L6 0H4L0 4M6 6V4L4 6' fill='%236e7681' fill-opacity='0.18'/%3E%3C/svg%3E");
  background-size: 6px 6px;
}
.resumen-legend-swatch.ex-started,
.resumen-legend-swatch.ex-settling,
.resumen-legend-swatch.ex-done,
.resumen-legend-swatch.ex-overdue {
  background: transparent;
}
.resumen-legend-swatch.ex-started {
  box-shadow: inset 3px 0 0 var(--tblr-orange);
}
.resumen-legend-swatch.ex-settling {
  box-shadow: inset 3px 0 0 var(--tblr-purple);
}
.resumen-legend-swatch.ex-done {
  box-shadow: inset 3px 0 0 var(--tblr-green);
}
.resumen-legend-swatch.ex-overdue {
  box-shadow: inset 3px 0 0 var(--tblr-red);
}
.resumen-grid-labels {
  display: flex;
  gap: 2px;
  margin-top: 4px;
}
.resumen-grid-labels span {
  flex: 1 1 0;
  min-width: 2.25rem;
  text-align: center;
  font-size: 0.625rem;
  color: var(--tblr-secondary-color);
  border-radius: 3px;
  padding: 1px 0;
}
.resumen-grid-labels span.is-today {
  background: var(--lignum-orange);
  color: var(--tblr-white);
  font-weight: 700;
}

/* Compact in-card headings used throughout the contract summary. */
.resumen-label-strong {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tblr-secondary-color);
}
/* same "whole field is one clickable target" affordance as the schedule
   board's .planif-schedule-ep-btn, sized for this card's tighter row padding
   instead of a full card-body edge-to-edge bleed. */
.resumen-field-btn {
  display: block;
  margin: -0.25rem -0.375rem;
  padding: 0.25rem 0.375rem;
  border-radius: var(--tblr-border-radius);
  transition: background-color 0.12s ease;
}
.resumen-field-btn:hover,
.resumen-field-btn:focus-visible {
  background: var(--tblr-bg-surface-secondary, #f6f8fb);
}

/* Emparejado stage — brand yellow (--lignum-yellow) */
.resumen-bar-emparejado {
  background-color: var(--lignum-yellow) !important;
}
.status-dot.resumen-dot-emparejado {
  background-color: var(--lignum-yellow);
}
.progress.resumen-progress-bar {
  height: 1rem;
}

/* cumulative delivery chart */
.resumen-cumulative-wrap {
  position: relative;
}
.resumen-cumulative-today {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed var(--tblr-secondary-color);
  pointer-events: none;
  z-index: 0;
}
.resumen-cumulative-svg {
  display: block;
  width: 100%;
  height: 5.5rem;
}
.resumen-cumulative-target {
  fill: none;
  stroke: var(--tblr-secondary-color);
  stroke-width: 2;
  stroke-dasharray: 5, 4;
  vector-effect: non-scaling-stroke;
}
.resumen-cumulative-actual {
  fill: none;
  stroke: var(--tblr-primary);
  stroke-width: 2.5;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.resumen-cumulative-gap {
  fill: var(--tblr-warning);
  fill-opacity: 0.12;
}
.resumen-cumulative-stop-start {
  stop-color: var(--tblr-primary);
  stop-opacity: 0.3;
}
.resumen-cumulative-stop-end {
  stop-color: var(--tblr-primary);
  stop-opacity: 0.02;
}
.resumen-cumulative-swatch {
  display: inline-block;
  width: 10px;
  height: 0;
  border-top: 2px dashed var(--tblr-secondary-color);
  vertical-align: middle;
}
.resumen-cumulative-point {
  position: absolute;
  z-index: 1;
  width: 0.55rem;
  height: 0.55rem;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  border: 2px solid var(--tblr-primary);
  background: var(--tblr-bg-surface, #fff);
  transform: translate(-50%, -50%);
  cursor: help;
}
.resumen-cumulative-point.kind-target {
  border-color: var(--tblr-secondary-color);
  opacity: 0.55;
}
.resumen-cumulative-point:hover,
.resumen-cumulative-point:focus-visible {
  outline: none;
  opacity: 1;
  box-shadow: 0 0 0 3px rgba(var(--tblr-primary-rgb), 0.2);
}
.resumen-cumulative-point.kind-target:hover,
.resumen-cumulative-point.kind-target:focus-visible {
  box-shadow: 0 0 0 3px rgba(var(--tblr-secondary-rgb), 0.25);
}

/* cell truck popover (cell_trucks_popover.js) — shared by the planification
   Frecuencia grid and this weekly grid; each page only adds its own cell
   affordance (.progress-cell.has-trucks / .resumen-week-cell[data-cell-trucks-url]). */
.cell-trucks-popover {
  position: fixed;
  z-index: 1050;
  min-width: 12rem;
  max-width: 90vw;
  max-height: 16rem;
  overflow-x: hidden;
  overflow-y: auto;
  padding: 0.4rem;
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius, 4px);
  background: var(--tblr-bg-surface, #fff);
  box-shadow: var(--tblr-shadow-lg, 0 0.5rem 1rem rgba(0, 0, 0, 0.15));
  font-size: 0.75rem;
}
/* one truck per line, however wide it needs to be — the popover grows rather
   than wrapping or truncating; only the panel's own max-width can clip it. */
.cell-trucks-row {
  padding: 0.2rem 0.3rem;
}
.cell-trucks-row + .cell-trucks-row {
  border-top: 1px solid var(--tblr-border-color);
}
/* the shared badge is sized for regular list rows; shrink it to match this
   popover's small text instead of towering over it. */
.cell-trucks-row .badge {
  height: 1.1rem;
  min-height: 1.1rem;
  padding: 0 0.35rem;
  font-size: 0.65rem;
  line-height: 1.1rem;
  gap: 0.2rem;
}
.cell-trucks-row .badge .icon {
  width: 0.7rem;
  height: 0.7rem;
  font-size: 0.7rem;
}
.card-footer .pagination {
  flex-wrap: wrap;
  row-gap: 0.25rem;
  justify-content: flex-end;
}
