.bootstrap-datetimepicker-widget {
    background-color: #444 !important;
}

.select2-results {
    color: #444 !important;
}

/* Let a flex/grid child shrink below its content's intrinsic width, instead of the default
   min-width:auto growing it to fit its content. Applied to the club sidebar column in base.html.
   Note this does NOT make text-truncate work on a child of a wrapping flex container -- see
   club_sidebar_nav.html and "Truncating text inside a flex column" in style_reference.md. */
.min-w-0 {
    min-width: 0 !important;
}

@media (min-width: 1200px) {
    .nowrap {
        white-space: nowrap !important;
    }
}

a {
    color: #2fa4e7;
}

a:hover {
    color: #727d83;
}

a.ad:hover {
    color: inherit;
    text-decoration: none;
}


.carousel-control-prev-icon {
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%232fa4e7' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E") !important;
   }

   .carousel-control-next-icon {
     background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%232fa4e7' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E") !important;
   }

.carousel-indicators li {
    background-color: rgb(131, 131, 131);
  }

  .carousel-indicators .active {
    background-color: #2fa4e7;
  }

  .ui-autocomplete {
    z-index: 9999;
  }

  .modal {
    overflow-y:auto;
    overflow:auto;
    z-index: 1050;
  }

  select.modelselect2 {
    display: none !important;
  }

  .select2-dropdown {
    z-index: 1060;
  }

/* --- select2 pickers are the same box as every other input ---------------
   Two things are wrong with a django-autocomplete-light picker as it ships, and they compound
   into "the text in this box is offset".

   dal starts select2 with `containerCssClass: ':all:'`, which copies every class off the
   original <select> onto the box select2 draws -- and crispy's bootstrap5 field template, like
   add_bootstrap_classes(), puts `form-select` on any Select widget.  Despite the option's name
   the classes land on `.select2-selection`, the visible box, and not on the container: so that
   box is a Bootstrap dropdown *and* a select2 selection at once, wearing both sets of padding
   (Bootstrap's 0.75rem on the box, select2's 0.75rem on the text span inside it -- 25px of inset
   where every other field on the form has 13) and both carets, drawn two pixels apart.  That is
   the offset, and it is why deleting the select2 classes in devtools looks like the fix: what is
   left is the Bootstrap box on its own.  The clear x jumps to the left of the text at the same
   time, because select2 prepends it into the text span and only select2's stylesheet floats it
   back to the right.

   The second thing is the size: select2's *default* theme, which is the one dal renders, is a
   28px box with 8px of text padding, where Bootstrap's .form-control beside it is 38px with 12px.

   So Bootstrap's padding and caret come off wherever those copied classes land, and select2's own
   box is dressed to match .form-control instead -- one definition, which the pickers that dal did
   not build (three pages start select2 themselves) get as well.

   Nothing here changes the colours: Darkly's inputs really are white with dark text.

   Prefixed with `body` on purpose.  Those three pages load their own copy of select2's stylesheet
   in the extra_js block, and {{ form.media }} loads dal's and the admin's after this file as
   well, so a rule of equal specificity would lose on exactly the pages this is for.  One element
   selector is enough to win everywhere without !important. */
body .select2-selection.form-select,
body .select2-selection.form-select-sm,
body .select2-selection.form-select-lg,
body .select2-selection.form-control,
body .select2-selection.form-control-sm,
body .select2-selection.form-control-lg {
    /* The text span inside carries the padding.  Bootstrap's would be a second helping of it. */
    padding: 0;
    /* Bootstrap's caret; select2 draws its own in an element of its own, on top of it. */
    background-image: none;
}

body .select2-container--default .select2-selection--single {
    height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
    border: var(--bs-border-width) solid #222;
    border-radius: var(--bs-border-radius);
}

body .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: #303030;
    /* The box less its two borders, so one line of text sits in the middle of it. */
    line-height: calc(1.5em + 0.75rem);
    padding-left: 0.75rem;
    /* Room for the caret, the same gap .form-select leaves for its own. */
    padding-right: 2.25rem;
}

/* 0.625rem puts the middle of select2's 8px triangle where the middle of Bootstrap's 16px chevron
   is, 20px in from the right edge, so a picker and a plain <select> line up down the form. */
body .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: calc(1.5em + 0.75rem);
    right: 0.625rem;
}

/* Floated right inside the text span, so the padding above is what keeps it clear of the caret;
   it needs no margin of its own. */
body .select2-container--default .select2-selection--single .select2-selection__clear {
    line-height: calc(1.5em + 0.75rem);
    margin-right: 0;
    color: #6c757d;
}

body .select2-container--default .select2-selection--multiple {
    min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
    border: var(--bs-border-width) solid #222;
    border-radius: var(--bs-border-radius);
    padding-left: 0.375rem;
}

/* --- and the text inside a multi-select is dark, like every other input -----
   select2's default theme paints the box white and the chips #e4e4e4 but sets a colour on
   *neither*, so both inherit whatever the page's text colour is -- which on this site is Darkly's
   #dee2e6.  Light grey on white and light grey on #e4e4e4 is 1.1:1: the picked categories, and
   everything typed into the box, were there the whole time and unreadable.  The Bootstrap 3 skin
   this page used to load happened to set those colours, which is why dropping the skin is what
   exposed it; the colours belong here now, with the rest of the sizing, so a page that starts
   select2 itself cannot lose them again.

   Values are the ones Bootstrap 5 uses inside a .form-control on this theme: #303030 for text,
   #6c757d for the placeholder and the little x. */
body .select2-container--default .select2-selection--multiple .select2-selection__rendered {
    color: #303030;
}

body .select2-container--default .select2-selection--multiple .select2-selection__choice {
    background-color: #e9ecef;
    border-color: #adb5bd;
    color: #303030;
}

body .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: #6c757d;
}

body .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
    color: #303030;
}

body .select2-container--default .select2-selection--multiple .select2-selection__clear {
    color: #6c757d;
}

/* Two different boxes you can type into: the one inside a multi-select (`--inline`, transparent
   over the white selection box) and the search field at the top of an open dropdown.  Neither sets
   a colour of its own either, so both were light-on-white as well -- on every picker on the site,
   not just this page. */
body .select2-container--default .select2-search--inline .select2-search__field,
body .select2-container--default .select2-search--dropdown .select2-search__field {
    color: #303030;
}

body .select2-container--default .select2-search--inline .select2-search__field::placeholder,
body .select2-container--default .select2-search--dropdown .select2-search__field::placeholder {
    color: #6c757d;
    opacity: 1;
}

/* The same focus ring .form-control:focus draws, so tabbing across a form doesn't change shape. */
body .select2-container--default.select2-container--focus .select2-selection--single,
body .select2-container--default.select2-container--open .select2-selection--single,
body .select2-container--default.select2-container--focus .select2-selection--multiple {
    border-color: #9badbf;
    box-shadow: 0 0 0 0.25rem rgba(55, 90, 127, 0.25);
}

/* crispy marks a field that failed validation by adding .is-invalid, which rides along on the copy
   above -- but the border it paints is the one the rules here have just overwritten, so the red
   has to be put back after them. */
body .select2-selection.is-invalid {
    border-color: var(--bs-form-invalid-border-color, #e74c3c);
}

/* dal ships `min-width: 20em`, which is wider than a narrow column on a phone: the box then
   overflowed its container to the right, which is the other half of "the text looks offset".
   Every picker on the site sets its own width, so capping this at the container costs nothing. */
body .select2-container {
    min-width: min(20em, 100%);
    max-width: 100%;
}

.modal-backdrop {
    z-index: 1040 !important;
}

/* A <form> wrapping the body and footer of a scrollable modal hides the footer.
   Bootstrap makes .modal-content a flex column with `max-height:100%; overflow:hidden` and lets
   .modal-body scroll inside it. That only works while the body and footer are flex children of
   .modal-content: a <form> between them is one flex item whose automatic minimum size is its full
   content height, so a long body pushes it past the content box and .modal-content's overflow
   clips whatever is at the bottom -- the footer, buttons and all. Nothing looks broken; the Send
   and Copy buttons simply are not on the screen, and only on the dialogs with enough text to
   overflow. Making the form the flex column .modal-content expected puts the scrolling back on
   .modal-body and pins the footer where it belongs. */
.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.magic {
  animation: magic_animation 1s linear infinite .5s;
}

@keyframes magic_animation {
  70% {
    text-shadow: 0 0 10px rgba(180, 157, 26, 0.907);
  }

}

/* ==========================================================================
   Site theme overrides (see /style_reference.md before editing)
   Darkly 5.3.3 is a compiled theme: component classes carry literal colors in
   their own CSS vars, so overriding :root alone is not enough. Each affected
   component is re-declared below.
   ========================================================================== */

/* --- Darker danger / warning palette ------------------------------------- */
/* Danger base #a93226 (darker red, same hue as #e74c3c).
   Warning base #b9770e (darker amber, same hue as #f39c12). */
:root {
    --bs-danger: #a93226;
    --bs-danger-rgb: 169, 50, 38;
    --bs-warning: #b9770e;
    --bs-warning-rgb: 185, 119, 14;
}

/* --bs-danger-rgb / --bs-warning-rgb drive .bg-* and .text-* utilities.
   On the dark body, red/amber text needs a lighter shade than the solid-fill
   color to stay legible, so text utilities are decoupled to a lighter tint. */
.text-danger {
    color: #e2756a !important;
}

.text-warning {
    color: #d99f3f !important;
}

/* Solid danger fills keep white text (contrast ~6.6:1 on #a93226). */
.btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: #a93226;
    --bs-btn-border-color: #a93226;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #902b20;
    --bs-btn-hover-border-color: #87281e;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #87281e;
    --bs-btn-active-border-color: #7f261d;
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: #a93226;
    --bs-btn-disabled-border-color: #a93226;
}

/* Solid warning fills use dark text (contrast ~5.7:1 on #b9770e, vs 3.7:1 for
   white) — see message-type standard: warning always pairs with dark text. */
.btn-warning {
    --bs-btn-color: #000;
    --bs-btn-bg: #b9770e;
    --bs-btn-border-color: #b9770e;
    --bs-btn-hover-color: #000;
    --bs-btn-hover-bg: #9d650c;
    --bs-btn-hover-border-color: #945f0b;
    --bs-btn-active-color: #000;
    --bs-btn-active-bg: #945f0b;
    --bs-btn-active-border-color: #8b590b;
    --bs-btn-disabled-color: #000;
    --bs-btn-disabled-bg: #b9770e;
    --bs-btn-disabled-border-color: #b9770e;
}

/* Success fill is unchanged (#00bc8c) but needs dark text, not the theme's
   white (white on #00bc8c is only ~2.5:1). */
.btn-success {
    --bs-btn-color: #000;
    --bs-btn-hover-color: #000;
    --bs-btn-active-color: #000;
    --bs-btn-disabled-color: #000;
}

/* Text-on-fill utility classes (badges, .text-bg-*). */
.text-bg-danger {
    background-color: #a93226 !important;
    color: #fff !important;
}

.text-bg-warning {
    background-color: #b9770e !important;
    color: #000 !important;
}

.text-bg-success {
    color: #000 !important;
}

/* Legacy pattern: `.badge.bg-*` / `.btn.bg-*` set a fill but not text color, so
   they inherit the light body color. Scoped to leaf components only (never a
   blunt `.bg-success{color}` that would cascade into nested content). */
.badge.bg-success,
.badge.bg-warning,
.btn.bg-success,
.btn.bg-warning {
    color: #000;
}

/* Alerts, retuned to the darker palette ------------------------------------
   These used to set `--bs-alert-bg` and `--bs-alert-color` only, which did
   nothing: Bootstrap's `.alert` reads those variables, but Darkly then writes a
   *direct* `.alert-warning{background-color:#f39c12}` (and one per variant) far
   later in its stylesheet, and a plain declaration on an equally specific
   selector beats a variable the earlier rule read.  So every alert on the site
   was still Darkly's bright fill with `.alert{color:#fff}` on top of it --
   white on #f39c12 is 2.2:1 and white on #00bc8c is 2.5:1, the two worst
   pairings on the site.

   Set the background and the text colour outright, in the pairings the palette
   documents: the darkened danger fill with white on it, and dark text on the
   fills that are too light for white. */
.alert-danger {
    background-color: #a93226;
    color: #fff;
}

.alert-warning {
    background-color: #b9770e;
    color: #000;
}

.alert-success {
    color: #000;
}

/* Darkly makes every link inside an alert white (`.alert .alert-link,.alert a`),
   which is the same 2.2:1 problem one level down -- and it is usually the link
   that says what to do about the alert.  Dark text alerts get dark links. */
.alert-warning a,
.alert-warning .alert-link,
.alert-success a,
.alert-success .alert-link {
    color: #000;
}

/* `.text-dark` is #303030, not black, and style_reference.md's numbers for a
   warning fill are black's (5.7:1, against 3.6:1 for #303030).  The markup that
   pairs an alert with `text-dark` is following the message-type standard, so it
   should not come out darker-on-dark than the alert's own colour: inside an
   alert, resolve the utility to the black the palette meant. */
.alert.text-dark {
    color: #000 !important;
}

/* --- Outline buttons legible on the dark background ----------------------- */
/* Darkly outline buttons use the fill color as their resting text color, which
   is unreadable for the dark grays (and, after darkening, for danger/warning).
   Give each a light resting text color; hover/active keep the filled look. */
.btn-outline-secondary {
    --bs-btn-color: #dee2e6;
    --bs-btn-border-color: #6c757d;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #6c757d;
    --bs-btn-hover-border-color: #6c757d;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #6c757d;
    --bs-btn-active-border-color: #6c757d;
    --bs-btn-disabled-color: #adb5bd;
    --bs-btn-disabled-border-color: #6c757d;
}

.btn-outline-dark {
    --bs-btn-color: #dee2e6;
    --bs-btn-border-color: #adb5bd;
    --bs-btn-hover-color: #000;
    --bs-btn-hover-bg: #dee2e6;
    --bs-btn-hover-border-color: #dee2e6;
    --bs-btn-active-color: #000;
    --bs-btn-active-bg: #dee2e6;
    --bs-btn-active-border-color: #dee2e6;
    --bs-btn-disabled-color: #adb5bd;
    --bs-btn-disabled-border-color: #adb5bd;
}

.btn-outline-danger {
    --bs-btn-color: #ec8b80;
    --bs-btn-border-color: #a93226;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #a93226;
    --bs-btn-hover-border-color: #a93226;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #a93226;
    --bs-btn-active-border-color: #a93226;
    --bs-btn-disabled-color: #ec8b80;
    --bs-btn-disabled-border-color: #a93226;
}

.btn-outline-warning {
    --bs-btn-color: #d9a441;
    --bs-btn-border-color: #b9770e;
    --bs-btn-hover-color: #000;
    --bs-btn-hover-bg: #b9770e;
    --bs-btn-hover-border-color: #b9770e;
    --bs-btn-active-color: #000;
    --bs-btn-active-bg: #b9770e;
    --bs-btn-active-border-color: #b9770e;
    --bs-btn-disabled-color: #d9a441;
    --bs-btn-disabled-border-color: #b9770e;
}

/* --- Pagination: neutral grays instead of Darkly's success green --------- */
/* Fixes the htmx table next/previous/page controls site-wide. */
.pagination {
    --bs-pagination-color: #fff;
    --bs-pagination-bg: #444;
    --bs-pagination-hover-color: #fff;
    --bs-pagination-hover-bg: #5a5a5a;
    --bs-pagination-focus-color: #fff;
    --bs-pagination-focus-bg: #5a5a5a;
    --bs-pagination-active-color: #fff;
    --bs-pagination-active-bg: #6c757d;
    --bs-pagination-active-border-color: #6c757d;
    --bs-pagination-disabled-color: #888;
    --bs-pagination-disabled-bg: #2b2b2b;
}

/* --- Voice input on the set-winners page (mobile app) -------------------- */
/* Three states, and the middle one is the point: a field the app filled but isn't sure it heard
   right is neither valid nor invalid, so it can't borrow Bootstrap's green or red. Amber dashed
   says "this is a guess, look at it" without claiming the server rejected it -- and it survives
   handleServerResponse clearing is-valid/is-invalid, because it's a separate class.
   Amber is the light text tint (#d99f3f), not the fill (#b9770e), which is too dark to read as a
   border on the dark body. */
.form-control.voice-unsure-field {
    border: 2px dashed #d99f3f;
}

.voice-unsure {
    margin-top: 0.35rem;
    font-size: 0.875rem;
    color: #d99f3f;
}

/* Mic level meter. Without it, a dead microphone and a bad match look identical. */
.voice-level {
    display: inline-block;
    width: 3rem;
    height: 0.4rem;
    margin-left: 0.5rem;
    background: #444;
    border-radius: 0.2rem;
    overflow: hidden;
    vertical-align: middle;
}

.voice-level > span {
    display: block;
    width: 0;
    height: 100%;
    background: #00bc8c;
    transition: width 0.1s linear;
}

/* Voice settings panel. Capped rather than full-bleed: it is read on a phone held in one hand
   while an auction runs, and a slider stretched across a tablet in landscape makes a 0.01 step
   into a pixel of travel. */
.voice-settings {
    max-width: 28rem;
}

/* The end labels are the slider's only reading -- it shows no number on purpose -- so keep them
   tight under the track rather than floating between it and the help text. */
.voice-settings .form-range {
    margin-bottom: 0.25rem;
}

/* --- Command palette: voice + assist -------------------------------------- */

/* The microphone lives inside the palette (see command_palette.html for its styles); there is
   deliberately no navbar mic — the brand opens the palette and the mic is one click further in. */

/* Countdown card shown before a database-changing action runs. */
#command-palette-results .cp-countdown .progress {
    height: 0.4rem;
}

#command-palette-results .cp-countdown .progress-bar {
    transition: width 0.1s linear;
}

/* Progress strip while an assist request is in flight.

   An assist call can take the better part of twenty seconds, so this narrates what the server is
   actually doing (each step arrives from the stream) instead of showing one frozen line. Completed
   steps stay above the current one, muted, so the path taken is visible.

   The results underneath are dimmed rather than removed: whatever was already clickable stays
   clickable, which matters because the assistant may well come back with nothing better. */
#command-palette-results .cp-thinking {
    font-size: 0.9rem;
    border-left: 2px solid var(--bs-border-color);
}

#command-palette-results .cp-thinking-step {
    line-height: 1.6;
}

#command-palette-results .cp-thinking-step::before {
    content: "\2713";  /* check mark: this step finished */
    margin-right: 0.4rem;
    opacity: 0.7;
}

/* Each new line fades in, which reads as progress rather than as a flicker. */
#command-palette-results .cp-thinking-step,
#command-palette-results .cp-thinking > div:last-child {
    animation: cp-thinking-in 0.25s ease-out;
}

@keyframes cp-thinking-in {
    from { opacity: 0; transform: translateY(0.15rem); }
    to { opacity: 1; transform: none; }
}

/* Results stay on screen and stay clickable while we think — see "Unavailable actions stay
   clickable" in style_reference.md. This is a visual de-emphasis only, not pointer-events: none. */
#command-palette-results.cp-dimmed .cp-item,
#command-palette-results.cp-dimmed .list-group {
    opacity: 0.45;
    transition: opacity 0.2s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    #command-palette-results .cp-thinking-step,
    #command-palette-results .cp-thinking > div:last-child {
        animation: none;
    }

    #command-palette-results.cp-dimmed .cp-item,
    #command-palette-results.cp-dimmed .list-group {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Speaker directory detail panel

   Slides in from the right on desktop and covers the screen on mobile.  Built
   here rather than with Bootstrap's offcanvas because the panel's content is
   swapped in by htmx and the URL is pushed alongside it, and offcanvas' own JS
   lifecycle fights being opened from an htmx:afterSwap handler.
   --------------------------------------------------------------------------- */

/* The four offsets are spelled out rather than using `inset: 0`.  An engine that doesn't
   know the shorthand (Safari below 14.1, iOS below 14.5, older Android WebViews -- the app
   renders this page in one) drops the whole declaration, and a fixed box with auto offsets
   sits at its static position: the panel then renders in the flow at the bottom of the page,
   below the table, instead of over it.  Nothing else in this file uses `inset`, so this was
   the only feature that broke that way. */
.speaker-panel-shell {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1045;
}

.speaker-panel-shell[hidden] {
    display: none;
}

.speaker-panel-backdrop {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    transition: opacity 0.25s ease-out;
}

.speaker-panel-shell.is-open .speaker-panel-backdrop {
    opacity: 1;
}

.speaker-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    /* width + max-width rather than min(): same result, and the vendor Bootstrap build uses
       neither min() nor inset, so this file shouldn't be the one thing an older engine trips on. */
    width: 38rem;
    max-width: 100%;
    background: #303030;
    border-left: 1px solid #444;
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform 0.25s ease-out;
}

.speaker-panel-shell.is-open .speaker-panel {
    transform: none;
}

.speaker-panel-inner {
    padding: 1rem;
}

/* Below lg the panel is the whole screen — a 38rem drawer on a phone is just a
   cramped page with a sliver of unusable backdrop next to it. */
@media (max-width: 991.98px) {
    .speaker-panel {
        width: 100%;
        border-left: none;
    }
}

/* The page behind the panel shouldn't scroll while the panel is open. */
body.speaker-panel-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .speaker-panel,
    .speaker-panel-backdrop {
        transition: none;
    }
}

/* A cap for *filter* menus, where the rows are a vocabulary that can be any
   length (the speaker directory's topics, the htmx table filters) and running
   off the bottom of a phone is the likely case.

   Not for a menu of links. The auction ribbon's More menu wore this for a
   while, and a navigation menu that scrolls inside itself puts half its own
   destinations behind a scrollbar that nobody expects a menu to have. */
.dropdown-menu-scroll {
    max-height: 60vh;
    overflow-y: auto;
}

/* Help notes -------------------------------------------------------------
   The "what is this page for" sentence at the top of an admin page. It is
   guidance, not a warning, so it reads as a tinted note rather than an alert:
   a light-blue wash, a light-blue rule down the left, and no full border --
   a boxed alert at the top of every admin page turns into wallpaper nobody
   reads. Small text on purpose; it is read once and then skipped forever.
   Markup pattern and rules are in style_reference.md. */
.help-note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    /* The link accent (#2fa4e7) at low opacity: blue enough to read as
       information against #222 without competing with the page content. */
    background: rgba(47, 164, 231, 0.09);
    border-left: 3px solid rgba(47, 164, 231, 0.55);
    border-radius: 0.25rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
    font-size: 0.875rem;
    color: #dee2e6;
}

.help-note > .bi {
    color: #2fa4e7;
    line-height: 1.5;
}

/* Paragraphs inside a note shouldn't add another gap under the note itself. */
.help-note p:last-child {
    margin-bottom: 0;
}

/* Cookie/terms bar ---------------------------------------------------------
   Fixed over the bottom of every page for signed-out visitors. Two things it
   has to do on a phone that the inline styles it used to carry did not: stay
   short (a full-size alert wraps to three lines and eats a fifth of the
   screen), and get out of the way of the end of the page -- fixed elements
   are out of flow, so without the padding below it sat on top of whatever was
   last on the page with no way to scroll further. */
.tos-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    /* Under a modal (1055) and its backdrop (1050), over the page. At the 9999 it
       used to carry, the cookie bar sat on top of every dialog on the site --
       including, on a phone, the bottom of a confirm dialog's buttons. */
    z-index: 1040;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
}

body:has(.tos-banner) {
    padding-bottom: 5.5rem;
}

/* Toasts are fixed to the top right; on a narrow phone a 350px toast plus the
   20px offset overflows the viewport and drags a horizontal scrollbar onto
   every page that fires one. */
@media (max-width: 420px) {
    #toast-container {
        left: 10px;
        right: 10px;
        top: 10px;
    }

    #toast-container .toast {
        width: 100%;
        max-width: 100%;
    }
}

/* Close buttons ------------------------------------------------------------
   This is why every X on the site was invisible. Bootswatch Darkly compiles
   `.btn-close` with an already-white glyph (`fill='%23fff'`), and Bootstrap
   5.3 then adds `[data-bs-theme=dark] .btn-close { filter: invert(1) ... }`
   on top of it -- inverting the white X to black on a near-black panel. Worse,
   that rule outranks `.btn-close-white` on specificity, so the documented fix
   in the markup could not win either: offcanvas, modal, alert and toast
   dismiss buttons were all black-on-black.

   Turn the inversion off. The glyph is white to begin with, which is what a
   dark surface wants, and `.btn-close-white` in the markup stays correct
   (and would still be right if the vendor build were ever recompiled with a
   dark default glyph). */
[data-bs-theme="dark"] .btn-close,
[data-bs-theme="dark"] .btn-close-white {
    filter: none;
}

/* Darkly rests the glyph at 40% opacity, which on #303030 reads as a smudge
   rather than a control. */
.btn-close {
    --bs-btn-close-opacity: 0.75;
}

/* The one place a dark glyph is right: a light fill carrying dark text -- the
   two toast headers the toast helper in base.html paints (success and warning),
   and the alerts of those two colours, which the block above gives dark text
   for the same reason.  A white x on #b9770e is 3.7:1 and on #00bc8c 2.5:1. */
[data-bs-theme="dark"] .toast-header.bg-success .btn-close,
[data-bs-theme="dark"] .toast-header.bg-warning .btn-close,
[data-bs-theme="dark"] .alert-success .btn-close,
[data-bs-theme="dark"] .alert-warning .btn-close {
    filter: invert(1);
}

/* Tables inside a card -----------------------------------------------------
   Darkly compiles `.table{--bs-table-bg:var(--bs-body-bg)}` and Bootstrap 5.3
   paints every cell with it, so a plain table carries the page's #222 with it
   wherever it goes. Inside a card that is a near-black rectangle sitting on the
   #303030 panel -- the lot page's details and bidding-history tables both read
   as a hole in the card they are in.

   Transparent instead, everywhere: on a #222 page the result is identical, and
   any other surface (card, modal, list group) is what the table should have
   been showing all along. The `.table-*` variants set their own
   `--bs-table-bg` and are untouched by this. */
.table {
    --bs-table-bg: transparent;
}

/* Embedded tutorial videos -------------------------------------------------
   `youtube_embed.html` used to size the player in JavaScript: 875x531 on
   anything 1024px and wider, 583x354 below that. 583px is wider than every
   phone in use, so every page carrying a tutorial -- the promo page, the
   auction help page, /support/ -- scrolled sideways on a phone, and the whole
   page came with it: the iframe is out of flow's reach, so nothing else could
   shrink to compensate.

   Sized here instead. The container caps at the desktop width and at 100% of
   whatever it is put in, whichever is smaller, and holds the 16:9 box that
   YouTube wants; the player fills it. The placeholder div is styled too,
   because the YouTube API replaces it with the iframe in place and the box has
   to be the right shape before the API has loaded -- and still be the right
   shape inside a `collapse` that was `display:none` when the player was
   built. */
.video-container {
    position: relative;
    width: 100%;
    max-width: 875px;
    aspect-ratio: 16 / 9;
    margin-bottom: 1rem;
}

.video-container > div,
.video-container iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    border: 0;
}

/* Progressive disclosure on the long settings forms -- see auctions/auction_form_layout.py for
   which fields end up inside one and why.

   `<details>` rather than a Bootstrap collapse: no JavaScript, keyboard-reachable and
   screen-reader-labelled with no ARIA of ours, and browser find-in-page opens it, so an organizer
   searching the page for "tax" still lands on the field. Bootswatch styles none of it, so the
   summary needs to be told it is a control: the default marker is a bare triangle that reads as
   decoration next to an `h4`. */
details.auction-advanced > summary {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid #444;
    border-radius: 0.375rem;
    background-color: #303030;
}

details.auction-advanced > summary::-webkit-details-marker {
    display: none;
}

/* The chevron is drawn here rather than left to the UA marker so it can rotate, and so it sits at
   a fixed size next to heading text. */
details.auction-advanced > summary::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid #adb5bd;
    border-bottom: 2px solid #adb5bd;
    transform: rotate(-45deg);
    transition: transform 0.15s ease-in-out;
    flex: none;
}

details.auction-advanced[open] > summary::before {
    transform: rotate(45deg);
}

details.auction-advanced > summary:hover {
    background-color: #3a3a3a;
}

details.auction-advanced > summary:focus-visible {
    outline: 2px solid #2fa4e7;
    outline-offset: 2px;
}

details.auction-advanced[open] > summary {
    margin-bottom: 1rem;
}

/* The unsaved-changes bar -- auctions/static/js/unsaved_changes.js draws it on any page with a
   form somebody has edited. Hidden until then, so it costs a page nothing.

   Fixed to the bottom of the viewport rather than the end of the form, because the point is to be
   visible at the moment somebody is about to leave, which is rarely while they are looking at the
   bottom of a four-dozen-field form. z-index sits under Bootstrap's modal backdrop (1050) so a
   dialog is never covered by it, and over everything else on the page. */
#unsaved-changes-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1040;
    display: none;
    padding: 0.75rem 1rem;
    background-color: #303030;
    border-top: 1px solid #444;
    box-shadow: 0 -0.25rem 0.75rem rgba(0, 0, 0, 0.35);
}

#unsaved-changes-bar.showing {
    display: block;
}

/* Room to scroll past the bar, so it never sits on top of the last field of the form it is about.
   Only while the bar is showing, so no page pays for it. */
body.has-unsaved-changes-bar {
    padding-bottom: 5rem;
}
