/* bootstrap alert CSS, translated to the django-standard levels
of debug, info, success, warning, error
 */

.alert-debug {
  background-color: #fff;
  border-color: #d6e9c6;
  color: #000;
}

.alert-error {
  background-color: #f2dede;
  border-color: #eed3d7;
  color: #b94a48;
}

.no-decoration {
  text-decoration: none !important;
}

/*center the logo in mobile*/
a.navbar-brand img {
  margin: auto !important;
}

/* header */
.navbar-header {
  margin: 0 auto;
}

/* remove some spacing between the logo and Nav */
a.navbar-brand {
  margin: auto;
}

.navbar-brand img {
  width: 140px;
}

/* toggler to change to 'x' when hamburger menu shown: https://stackoverflow.com/a/59214165/2469390 */
.navbar-toggler.collapsed .close-icon {
  display: none;
}

/* hack needed to keep the logo from shifting as the 'x' is smaller*/
.navbar-toggler {
  width: 2.75em;
}

.navbar-toggler:not(.collapsed) .navbar-toggler-icon {
  display: inline;
}

/* remove border/outline https://stackoverflow.com/a/51563589/2469390 */
.navbar-toggler:focus,
.navbar-toggler:active,
.navbar-toggler-icon:focus {
  outline: none;
  -webkit-box-shadow: none;
  box-shadow: none;
}

/* forms */
/*add some space above the submit button*/
input.btn-primary {
  margin-top: 0.5em;
}

/* sticky submit button */
.sticky-button {
  position: sticky;
  bottom: 0;
  background-color: white;
  padding: 10px;
  z-index: 1000;
}

/* hide the asterisk for reuired fields (django-crispy-forms) */
.asteriskField {
  display: none;
}

.form-group {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

input.numberinput {
  max-width: 6em;
}

/* ``html5dateinput`` / ``html5timeinput`` are the crispy-applied classes for the
   native HTML5 widgets that replaced django-bootstrap-datepicker-plus; without
   them the native <input type="date"> escapes this cap and renders full-width
   (PR #1135 review). Kept alongside the legacy ``datepickerinput`` classes so
   both old and new render identically. */
input.textinput, input.urlinput, input.datepickerinput, input.datetimepickerinput, input.html5dateinput, input.html5timeinput, select.select {
  max-width: 20em;
}

small {
  font-size: 90%;
}

.warn-orange {
  color: rgb(187, 136, 39);
}

/* email input is too wide compared to text inputs */
.emailinput {
  max-width: 320px;
}

/* ALERTS LIST */
.sticky-section-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: white;
  border-bottom: 1px solid #dee2e6;
}

.sticky-section-header + .row {
  margin-top: 1rem;
}

/* SHIPMENTS LIST */

/* sticky header */
#shipments-list-headers {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: #f8f9fa; /* Ensure it's visually distinct when scrolling */
}


/* the table cell originally hidden, which expands  - needs important or shows padding*/
.expansion-cell {
  padding: 0 !important;
}

/* shipments list filters */
fieldset legend.form-label {
  font-size: 1em;
}

/* try to hide expansion-cell on landscape phone orientation */
.expansion-cell-content {
  padding: 0.75em;
}

.accordion div.row div.col {
  padding: 8px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

/* remove the bottom border on the chevron upon expansion */
.accordion-button:not(.collapsed) {
  border: none;
  background-color: inherit;
  -webkit-box-shadow: none;
  box-shadow: none;
  color: black !important;
}

.accordion-button:not(.collapsed)::after {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

/* custom checkbox styling: https://moderncss.dev/pure-css-custom-checkbox-style/ */
input[type=checkbox].shipments-list {
  margin: auto !important;
}

/* shipment filter form */
/* radio legends are too large */
fieldset legend {
  font-size: 1rem;
}

/* toggle switches */
.visually-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* to center accordion button chevron char */
.accordion-button::after {
  margin-left: 40%;
  color: green !important;
}

/* needed for mobile - too much padding by default */
.accordion-button {
  padding: 0 !important;
}

/* password input width (changed with bootstrap 5) */
.passwordinput {
  max-width: 20em;
}


/* rows */
.striped-row:nth-child(odd) {
  background-color: #ffffff; /* White background for odd rows */
}

.striped-row:nth-child(even) {
  background-color: #f2f2f2; /* Light gray background for even rows */
}

/* tooltips */
.dashed-underline {
  border-bottom: 1px dashed #000;
  cursor: help;
}

/* progress/spinnners */
.spinner-border {
  margin-right: 5px;
}

.btn:disabled {
  cursor: not-allowed;
}

#toasts {
  /* Increase z-index to be higher than other elements */
  z-index: 12000;
  /* Position it above everything */
  position: fixed;
}


/* top of page loader
 https://old.reddit.com/r/htmx/comments/1blwnc4/tip_of_the_day_unobtrusive_global_loading/
 */
.loading-bar {
  opacity: 0;
  position: fixed;
  /* required to overlay the sticky headers */
  z-index: 20;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, transparent,
    var(--bs-primary),
    transparent
  );
  /* transition for smoother opacity changes */
  transition: opacity 0.2s ease-out;
}

/* Show and animate when HTMX request is in progress */
.htmx-request.loading-bar {
  opacity: 1;
  animation: slide 0.8s ease-in-out infinite; /* Controls sliding animation */
  animation-delay: 0.5s; /* Delay before animation starts */
  /* Use transition-delay for the opacity change */
  transition-delay: 0.5s;
}

@keyframes slide {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

/* alpinejs */
[x-cloak] { display: none !important; }

/*carrier dropdown selection*/

/* Rotate chevron when expanded */
[aria-expanded="true"] .fa-chevron-down {
  transform: rotate(180deg);
}

.fa-chevron-down {
  transition: transform 0.2s ease-in-out;
}

/* Store Filter Dropdown */
:root {
  --store-dropdown-width: 280px;
  --store-dropdown-z-index: 1050;
  --border-color-light: #dee2e6;
}

.store-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  width: var(--store-dropdown-width);
  z-index: var(--store-dropdown-z-index);
  overflow-y: auto;
  border: 1px solid var(--border-color-light);
  border-top: none;
  background-color: white;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
  border-radius: 0 0 0.375rem 0.375rem;
}

.store-dropdown-button {
  width: var(--store-dropdown-width);
}

/* Notes feature */
.notes-editor {
  animation: fadeIn 0.15s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.notes-editor textarea {
  resize: vertical;
  min-height: 80px;
}

.notes-editor textarea:focus {
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

/* The glyph's own color is set on the <i> (the state rules below carry an
   !important there), so the transition has to reach it: on the button alone
   it would animate a color nothing paints with, and hover would snap. */
.notes-icon-button,
.notes-icon-button .fa-pen-to-square {
  transition: color 0.2s ease;
}

.notes-icon-button {
  line-height: 1;
}

/* Empty ("Add note") state. gray-600 is the same resting value
   .report-status-button uses for a secondary glyph in this row, and it clears
   WCAG 1.4.11's 3:1 minimum on every background a shipment row paints: white,
   the .bg-light zebra stripe, .shipment-highlight (and its hover), and
   .report-status-row-active. test_notes_icon_contrast.py enforces that list;
   add a row background there before introducing one here.

   Both selectors carry the opacity, and the icon is a descendant of the
   button, so the two multiply: the previous 0.55 painted at 0.55 * 0.55 and
   the glyph landed around #e6e9eb, roughly 1.2:1 on a white row. Keep this at
   1 and express any de-emphasis as color, which the ratio check can see. */
.notes-icon-empty,
.notes-icon-empty .fa-pen-to-square {
  color: #6c757d !important;
  opacity: 1;
}

/* Filled state. Kept as the theme variable rather than a literal, and still
   covered: test_notes_icon_contrast.py resolves --bs-primary out of
   bootstrap.min.css and measures the resolved value. This is the thinnest
   margin of any measured state (4.50:1 on white, 3.18:1 on a hovered
   .shipment-highlight row), and it is the one an upgrade moves, so a
   Bootstrap bump that lightens the token fails that test rather than
   quietly crossing under 3:1. #1332 is the same failure from the other
   side: a color change to this glyph that nothing measured. */
.notes-icon-filled,
.notes-icon-filled .fa-pen-to-square {
  color: var(--bs-primary) !important;
  opacity: 1;
}

/* No opacity dip on hover. Fading was the old affordance, and it put both
   states under WCAG 1.4.11's 3:1 on a hovered .shipment-highlight row:
   gray-600 fell to about 2.88:1 and primary blue to about 2.85:1. Hover is
   a color change now, which the guard can measure. Keep it that way: an
   opacity on any .notes-icon rule fades a state the ratio checks think they
   have measured, so test_notes_icon_contrast.py fails on one anywhere in
   this group, not just here.

   The declaration below is a fallback the per-state rules override on
   specificity rather than on position, so reordering this file cannot change
   which color a state gets. */
.notes-icon-button:hover,
.notes-icon-button:focus,
.notes-icon-button:active {
  text-decoration: none;
  /* Covers the open state, which matches neither state rule below: both are
     bound with `!open &&` in notes_icon.html, so an open button keeps only
     .text-reset, whose `color: inherit !important` also beats
     .btn-link:hover. Without this it has no hover feedback at all, the
     opacity dip having been the only thing it ever had. !important is what
     gets past .text-reset; the per-state rules below outrank this one on
     specificity, so it reaches only the state they do not cover. */
  color: #0a58ca !important;
}

/* Darken on hover, one step per state, so the two stay distinguishable while
   pressed. Both clear 3:1 on every row background test_notes_icon_contrast.py
   enumerates.

   The button-targeting selectors name .notes-icon-button as well as the state
   class, purely for specificity: that makes them (0,3,0) against the fallback
   rule's (0,2,0), so they win from anywhere in the file rather than by sitting
   after it. Both classes are always on the button together, one static and one
   bound, so the extra class costs nothing. The .fa-pen-to-square selectors
   need no such help; they target the icon, which the fallback never matches. */
.notes-icon-button.notes-icon-empty:hover,
.notes-icon-empty:hover .fa-pen-to-square,
.notes-icon-button.notes-icon-empty:focus,
.notes-icon-empty:focus .fa-pen-to-square {
  color: #495057 !important;
}

.notes-icon-button.notes-icon-filled:hover,
.notes-icon-filled:hover .fa-pen-to-square,
.notes-icon-button.notes-icon-filled:focus,
.notes-icon-filled:focus .fa-pen-to-square {
  color: #0a58ca !important;
}

/* Shipment highlight for new/changed shipments */
.shipment-rows-container .row.shipment-highlight,
.shipment-rows-container .row.shipment-highlight.bg-light {
  background-color: rgba(13, 110, 253, 0.15); /* Bootstrap primary blue with transparency */
  transition: background-color 0.3s ease;
}

.shipment-rows-container .row.shipment-highlight:hover,
.shipment-rows-container .row.shipment-highlight.bg-light:hover {
  background-color: rgba(13, 110, 253, 0.25);
}
