/* Brand Colors */
:root {
  --mm-green: #94cf1c;
  --mm-green-dark: #6fa312;
}

.btn-outline-mm-green {
  color: var(--mm-green-dark);
  border-color: var(--mm-green);
}

.btn-outline-mm-green:hover,
.btn-outline-mm-green:active,
.btn-outline-mm-green:focus {
  color: #fff;
  background-color: var(--mm-green);
  border-color: var(--mm-green);
}

/* Width Utilities */
.w-33 {
  width: 33.333333% !important;
}

.w-66 {
  width: 66.666667% !important;
}

.hover-row {
  transition:
    box-shadow 0.2s ease,
    background-color 0.2s ease;
  /* cursor: pointer;  optional, makes it feel clickable */
}

.hover-row:hover {
  background-color: var(--bs-light); /* light background on hover */
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); /* subtle shadow */
}

.form-check-input.switch-lg {
  width: 4em;
  height: 2em;
}

.wrapper-white-full-flex {
  background-color: white;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.fixed-modal-body {
  height: 600px; /* Set fixed height */
  overflow-y: auto; /* Scroll inside modal */
}

/* ==========================================================================
   Asset widgets
   ========================================================================== */

.asset-widget {
  border-radius: 0.5rem;
  transition:
    box-shadow 0.2s ease,
    transform 0.2s ease,
    border-color 0.2s ease;
}

.asset-widget:hover {
  box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.08);
}

.asset-widget-minheight {
  min-height: 80px;
}

/*
  Meta strip sits in normal flow above the header. Previously it was
  absolutely positioned, which let long asset labels and badges run
  underneath the title and the action buttons.
*/
.asset-meta-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
}

.asset-label {
  background: rgba(200, 200, 200, 0.8);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.75rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Title must be allowed to shrink and wrap so it never slides under the
   action buttons on narrow columns. */
.asset-title {
  overflow-wrap: anywhere;
  word-break: break-word;
}

.min-w-0 {
  min-width: 0 !important;
}

/*
  Hover-reveal for the meta strip. Collapsing max-height/margin (rather than
  only fading) means the hidden strip reserves no vertical space, so headers
  stay compact until hovered.
*/
.asset-hover-expand {
  opacity: 0;
  max-height: 0;
  padding-top: 0 !important;
  overflow: hidden;
  transform: translateY(-4px);
  transition:
    opacity 0.15s ease,
    transform 0.15s ease,
    max-height 0.15s ease,
    padding-top 0.15s ease;
  pointer-events: none;
}

/* Reveal is driven from the whole card: the meta strip is a sibling of the
   header, so a header-scoped descendant selector would never match it. */
.asset-widget:hover .asset-hover-expand,
.asset-widget:focus-within .asset-hover-expand {
  opacity: 1;
  max-height: 4rem;
  padding-top: 0.5rem !important;
  transform: translateY(0);
  pointer-events: auto;
}

.asset-footer:empty {
  display: none !important;
}

/* Collapse the meta strip when every badge in it has been suppressed, so it
   does not leave an empty padded band above the header. `:empty` cannot be
   used here - Django template whitespace leaves text nodes inside the div -
   so this keys off :not(:has(...)) instead. */
.asset-meta-strip:not(:has(> *)) {
  display: none !important;
}

/* ==========================================================================
   Reporting / list layout
   ========================================================================== */

/* Filter toolbar for the reporting screens */
.filter-container {
  background: #fff;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  padding: 1rem;
}

/*
  Single card holding the whole chart row - the charts and the status table are
  sections within it rather than three separate boxes.
*/
.report-card {
  background: #fff;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  padding: 1rem;
}

.report-card-title {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--bs-secondary-color);
  margin-bottom: 0.75rem;
}

/*
  Hairline between sections. The columns are col-xxl-5/5/2 but col-lg-6/6/12,
  so below xxl the third section wraps onto its own line - only draw the
  divider at the width where all three genuinely sit side by side, and on the
  second section from lg up where it still shares a row with the first.
*/
@media (min-width: 992px) {
  .row > .col-lg-6.report-section-divider {
    border-left: 1px solid var(--bs-border-color);
  }
}

@media (min-width: 1400px) {
  .report-section-divider {
    border-left: 1px solid var(--bs-border-color);
  }
}

/* ==========================================================================
   Filter card (variant B) - labeled field grid with a header row for
   reset/export, and a full-width search row beneath. A different rhythm to
   .filter-bar below: grouped fields with visible labels instead of a single
   wrapping strip of bare controls.
   ========================================================================== */
.filter-card {
  background: #fff;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.75rem;
  padding: 1rem 1.25rem;
}

.filter-card-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.filter-card-title {
  font-size: 0.9375rem;
  font-weight: 600;
}

.filter-card-header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.filter-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.filter-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.filter-field label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--bs-secondary-color);
}

.filter-card-search .input-group-text {
  color: var(--bs-secondary-color);
}

/*
  Compact single-strip filter bar. Every control sits on one wrapping line
  rather than the four stacked rows the reporting screens used to have, so the
  charts and list start much higher up the page.
*/
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.75rem;
  background: #fff;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  padding: 0.5rem 0.75rem;
  font-family: "Roboto", var(--bs-body-font-family);
}

/*
  The bar's own font-family is inherited by most of its contents, but form
  controls and buttons take a UA font instead of inheriting, so they have to be
  named. The rest of the app keeps the Bootstrap system stack.
*/
.filter-bar input,
.filter-bar select,
.filter-bar textarea,
.filter-bar button,
.filter-bar label,
.filter-bar .form-control,
.filter-bar .btn,
.filter-bar .input-group-text,
.filter-bar .badge {
  font-family: "Roboto", var(--bs-body-font-family);
}

/*
  The depot dropdown is rendered in place inside the bar, so it inherits - but
  it is listed anyway because Bootstrap will float it to the body in some
  configurations, which would break the inheritance chain.
*/
.filter-bar .dropdown-menu,
.filter-bar .dropdown-menu .dropdown-item {
  font-family: "Roboto", var(--bs-body-font-family);
}

/*
  Middle column: preset time ranges on top, depot picker and the custom date
  range beneath them.
*/
.filter-controls {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.filter-controls-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/*
  Report title + active range/depot summary. Kept as a single compact stack on
  the left of the bar rather than the full-width heading block it used to be.
*/
.filter-summary {
  display: flex;
  flex-direction: column;
  justify-content: center;
  line-height: 1.25;
  padding-right: 0.75rem;
  border-right: 1px solid var(--bs-border-color);
}

.filter-summary-title {
  font-size: 0.8125rem;
  font-weight: 600;
}

.filter-summary-meta {
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

/*
  The two search fields stack vertically so they occupy one bar-height column
  instead of a second full-width row.
*/
.filter-searches {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.375rem;
  flex: 1 1 220px;
  min-width: 180px;
  margin-left: auto;
}

.filter-bar .filter-dates .form-control {
  width: auto;
  flex: 0 1 auto;
}

/* Icon-only reset, sized to line up with the small controls beside it. */
.filter-reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 31px;
  height: 31px;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.25rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
  flex-shrink: 0;
}

.filter-reset:hover {
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

/*
  Once the bar wraps, the columns stack full width - the summary's vertical
  divider and the searches' right-alignment no longer make sense.
*/
@media (max-width: 991.98px) {
  .filter-summary {
    padding-right: 0;
    border-right: 0;
  }

  .filter-searches {
    margin-left: 0;
  }
}

/*
  Charts need a bounded height, otherwise Chart.js grows the canvas on every
  HTMX re-render and the charts overlap the content beneath them.
*/
.chart-box {
  position: relative;
  width: 100%;
  height: 260px;
}

.chart-box > canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
}

/*
  The same chart re-rendered inside the expand modal. Sized off the viewport so
  it grows on large screens, which is the whole point of expanding it. The
  canvas is pinned to the box so Chart.js sizes to it rather than the reverse.
*/
.chart-box-expanded {
  position: relative;
  width: 100%;
  height: min(70vh, 640px);
}

.chart-box-expanded > canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
}

/*
  Heading row for a chart: the existing heading on the left, the expand
  affordance on the right.
*/
.chart-heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

/* The heading inside the row keeps its own bottom margin off. */
.chart-heading-row > h6 {
  margin-bottom: 0;
}

.chart-expand-btn {
  border: 0;
  background: transparent;
  padding: 0.125rem 0.25rem;
  line-height: 1;
  border-radius: 0.25rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.chart-expand-btn:hover,
.chart-expand-btn:focus-visible {
  color: var(--bs-body-color);
  background: var(--bs-secondary-bg);
}

/* Boxed list rows */
.check-row {
  border: 0;
  border-radius: 0.5rem;
  background: #fff;
  padding: 0.75rem;
}

.check-row + .check-row {
  margin-top: 0.75rem;
}

.check-row-defects {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 0.5rem;
  align-items: stretch;
}

.check-empty-state {
  border-radius: 0.5rem;
  min-height: 100%;
}

/*
  The Checks by Status panel sits beside the two charts, so it stretches to the
  same height rather than sitting short at the top of its column. Its three
  rows then spread over that height instead of bunching under the heading.
*/
.checks-by-status {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 260px; /* matches .chart-box */
  padding-bottom: 1.5rem;
}

.checks-by-status-rows {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  flex: 1 1 auto;
}

/* Slightly larger than the default so the rows carry the extra height rather
   than leaving it as empty gaps between them. */
.checks-by-status .status-row {
  font-size: 1.0625rem;
}

.checks-by-status .status-row .fw-semibold {
  font-size: 1.125rem;
}

/* ==========================================================================
   Reporting - Checks by Status drilldown
   ========================================================================== */

/* The three status rows open a vehicle-list modal, so they have to read as
   controls rather than as static figures. */
.status-row {
  cursor: pointer;
  border-radius: 0.25rem;
  transition:
    background-color 0.15s ease,
    font-weight 0.15s ease;
}

.status-row:hover,
.status-row:focus-visible {
  background-color: var(--bs-light);
  font-weight: 600;
}

.sortable-table th.sort-col {
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
}

/* The caret is only rendered on the active column, so the slot is reserved at
   a fixed width - otherwise headers jump sideways on the first sort. */
.sortable-table th.sort-col .sort-icon {
  display: inline-block;
  width: 0.75em;
  margin-left: 0.25rem;
  color: var(--bs-secondary-color);
}

/* Defect rows expand in place to list their defects. */
.sortable-table tr.defect-row {
  cursor: pointer;
}

/* The detail row is a continuation of the row above it, so drop the border
   that would otherwise split the two apart. */
.sortable-table tr.defect-detail-row > td {
  border-top: 0;
}

/*
  Search inputs: drop Bootstrap's blue focus treatment (blue border +
  $input-focus-box-shadow glow), which read as an error/active state on what is
  just a text box. The field still shows a visible focus state - the border
  darkens to the body colour - so keyboard users keep an unambiguous target.
  Listed by id because the search boxes are plain .form-control inputs with no
  shared class of their own; the [type=search] rule covers any future ones.
*/
#vehicle_search:focus,
#driver_search:focus,
#defect_search:focus,
#depot_search:focus,
#response_search:focus,
#infringement_search:focus,
#vehicle_types_search:focus,
#employee_role_search:focus,
.form-control[type="search"]:focus {
  border-color: var(--bs-border-color);
  box-shadow: none;
  outline: 0;
}
