/* app-utilities.css -- what house-ui 4's ds.css does not already declare.

   It began as the Bootstrap 5.3.3 subset that replaced the vendored bootstrap-5.3.3.min.css
   (233 KB). ds.css 4 now declares most of that reboot, the utilities and the badge and
   list-group components itself, so this sheet carries only the rules ds.css lacks (or
   declares differently) for the classes web/*.py and the house_ui components still emit.
   tests/test_app_utilities_stylesheet.py keeps the emitted classes declared and fails if a
   rule here is declared identically in ds.css. Values are Bootstrap's own spacing, type and
   radius steps so nothing moves; every colour is a house ds token.

   It sits in the slot Bootstrap sat in -- before ds.css -- so ds.css still wins on equal
   specificity. Utilities keep Bootstrap's !important for the same reason: app CSS
   (picks.css, staging-workqueue.css) was written against it. Bare h1-h4 font-size steps are
   deliberately absent: ds.css drops them so the page's visually-hidden <h1> is never sized.

   The last section is the other kind of gap: layout for a class a house_ui component emits
   that ds.css does not lay out (each names its upstream issue).

   A class not declared here or in ds.css renders unstyled. New layout should reach for ds-
   primitives or feature CSS first; add a utility here only when the source scan test asks. */

/* ── Element reset (Bootstrap reboot subset) ─────────────────────────────── */
::after, ::before { box-sizing: border-box; }
@media (prefers-reduced-motion: no-preference) { :root { scroll-behavior: smooth; } }
body { margin: 0; line-height: 1.5; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
.h5, .h6, h1, h2, h3, h4, h5, h6 { margin-top: 0; margin-bottom: .5rem; font-weight: 500; line-height: 1.2; }
.h5, h5 { font-size: 1.25rem; }
.h6, h6 { font-size: 1rem; }
mark { padding: .1875em; color: var(--ink); background-color: var(--warn-bg); }
kbd { padding: .1875rem .375rem; font-size: .875em; color: var(--bg); background-color: var(--ink); border-radius: .25rem; }
kbd kbd { padding: 0; font-size: 1em; }
table { caption-side: bottom; border-collapse: collapse; }
th { text-align: inherit; text-align: -webkit-match-parent; }
td, th { border-color: inherit; border-style: solid; border-width: 0; }
select { word-wrap: normal; }
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { display: none !important; }
::-moz-focus-inner { padding: 0; border-style: none; }
legend { float: left; width: 100%; padding: 0; margin-bottom: .5rem; font-size: calc(1.275rem + .3vw); line-height: inherit; }
@media (min-width: 1200px) { legend { font-size: 1.5rem; } }
::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-text, ::-webkit-datetime-edit-year-field { padding: 0; }
::-webkit-inner-spin-button { height: auto; }
[type=search] { -webkit-appearance: textfield; outline-offset: -2px; }
::-webkit-search-decoration { -webkit-appearance: none; }
::-webkit-color-swatch-wrapper { padding: 0; }
::-webkit-file-upload-button { font: inherit; -webkit-appearance: button; }
::file-selector-button { font: inherit; -webkit-appearance: button; }

/* ── Form controls: the base ds.css re-skins (colour, border, radius, padding) ── */
.form-label { margin-bottom: .5rem; }
.form-control, .form-select {
  display: block; width: 100%; padding: .375rem .75rem; font-size: 1rem; font-weight: 400; line-height: 1.5;
  color: var(--ink); appearance: none; background-color: var(--surface); background-clip: padding-box;
  border: 1px solid var(--line-control); border-radius: .375rem;
  transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.form-select { padding-right: 2.25rem; }
.form-select[multiple], .form-select[size]:not([size="1"]) { padding-right: .75rem; }
.form-control:focus, .form-select:focus { border-color: var(--blue); outline: 0; }
.form-control::placeholder { color: var(--text-3); opacity: 1; }
.form-control:disabled, .form-select:disabled { background-color: var(--surface-2); opacity: 1; }
.form-control[type=file] { overflow: hidden; }
.form-control::-webkit-date-and-time-value { min-width: 85px; height: 1.5em; margin: 0; }
.form-control::-webkit-datetime-edit { display: block; padding: 0; }
.form-control-sm { min-height: calc(1.5em + .5rem + 2px); padding: .25rem .5rem; font-size: .875rem; border-radius: .25rem; }
.form-control-lg { min-height: calc(1.5em + 1rem + 2px); padding: .5rem 1rem; font-size: 1.25rem; border-radius: .5rem; }
textarea.form-control { min-height: calc(1.5em + .75rem + 2px); }
textarea.form-control-sm { min-height: calc(1.5em + .5rem + 2px); }
textarea.form-control-lg { min-height: calc(1.5em + 1rem + 2px); }
@media (prefers-reduced-motion: reduce) { .form-control, .form-select { transition: none; } }

/* ── Components still emitted by markup ──────────────────────────────────── */
/* The badge and list-group components are declared by house-ui 4's ds.css, and nothing
   emits a nav link any more. */
.spinner-border { display: inline-block; width: 2rem; height: 2rem; vertical-align: -.125em; border: .25em solid currentcolor;
  border-right-color: transparent; border-radius: 50%; animation: .75s linear infinite app-spin; }
@keyframes app-spin { to { transform: rotate(360deg); } }

/* ── Grid (the picks cockpit wave board) ─────────────────────────────────── */
.row { --app-gutter-x: 1.5rem; --app-gutter-y: 0; display: flex; flex-wrap: wrap;
  margin-top: calc(-1 * var(--app-gutter-y)); margin-right: calc(-.5 * var(--app-gutter-x)); margin-left: calc(-.5 * var(--app-gutter-x)); }
.row > * { flex-shrink: 0; width: 100%; max-width: 100%; padding-right: calc(var(--app-gutter-x) * .5);
  padding-left: calc(var(--app-gutter-x) * .5); margin-top: var(--app-gutter-y); }
.g-3 { --app-gutter-x: 1rem; --app-gutter-y: 1rem; }

/* ── Utilities (Bootstrap names and values, !important as upstream) ──────── */
.visually-hidden { width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important;
  overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }
.translate-middle { transform: translate(-50%, -50%) !important; }

.font-monospace { font-family: var(--mono) !important; }
.text-muted { color: var(--mut) !important; }
.rounded-pill { border-radius: 50rem !important; }

/* ── house_ui component layout ds.css omits ─────────────────────────────── */
/* ui.ds_rot_tab_bar() emits .ds-rot-tab-bar, which ds.css 4.0.1 does not lay out, so its
   pills render edge to edge (EDI, Console). picks.css carried this for Picks and Sorting
   only. Drop both copies once house-ui#359 ships the rule (af#503). */
.ds-rot-tab-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }

/* The filter row on Operations (By Order, By Kit, Low Stock) and Inventory (Search,
   Warehouse), af#508. house_ui's multiselect() is a 32px outline button with its label
   inside, beside labelled fields that are taller, so the row sat ragged (and on a phone
   wrapped into a staircase). Controls share the bottom edge and one height (the field
   height, 45px, which is also the coarse-pointer floor); under 576px each takes its own
   full-width line, so every left edge is the same. */
.ds-filter-row { align-items: flex-end; }
.ds-filter-row > .ds-dd > summary { display: inline-flex; align-items: center; box-sizing: border-box; height: 2.8125rem; }
@media (max-width: 575.98px) {
  .ds-filter-row > :not(.d-inline-flex) { flex: 1 1 100%; }  /* not Low Stock's trailing busy ring */
  .ds-filter-row { position: relative; }
  /* Low Stock's loading ring: out of flow at the row's top-right (the label line of the
     first field is empty there), so it neither wraps onto a blank line nor disappears. */
  .ds-filter-row > .d-inline-flex { position: absolute; top: 0; right: 0; }
  .ds-filter-row > .ds-dd { display: block; }
  .ds-filter-row > .ds-dd > summary { display: flex; }
}
