/* utilities.css
 *
 * Replaces wwwroot/bootstrap/bootstrap.min.css (Wave 3a, issue #43).
 * Every rule below is copied verbatim from bootstrap.min.css for the 105 classes
 * confirmed in live use across the 97 Razor components (audit: 2026-08-05, see
 * issue #43). Declarations, !important flags, and media-query breakpoints are
 * unchanged from Bootstrap's own output, so removing the 162KB Bootstrap file
 * introduces zero visual diff at any of the 2,151 call sites.
 *
 * Do not add a class here to make a new call site work. That is scope creep;
 * either the class already exists in this file (case-sensitive, exact match)
 * or the new markup should use a native MudBlazor prop instead. See Wave 3b
 * (issue #44) for the opportunistic migration off these classes entirely.
 *
 * .row>* is included alongside .row: Bootstrap's grid gives row's direct
 * children their gutter padding through this companion selector, not through
 * .row itself. Omitting it would remove column gutters app-wide.
 *
 * Reviewed by two independent Tier-3 adversarial passes (2026-08-05, issue
 * #43) before merge: one on CSS fidelity/completeness against Bootstrap
 * 5.1.0's real output, one on visual-regression and variable-scoping risk
 * in the surrounding diff. One real defect came out of that review and is
 * fixed in this file: the responsive breakpoint rules (`*-md-*`, `*-lg-*`)
 * were originally drafted next to their base flex/spacing sections, which
 * put them before some of their own base counterparts in source order and
 * would have let the base value win at the breakpoint instead of the
 * responsive override, at live call sites in IncidentGroups.razor,
 * Scenarios.razor, and Admin.razor. See the note on that block below.
 */

:root{
  /* Only the three custom properties our extracted rules actually reference
     (text-white, text-danger, bg-black), copied from bootstrap.min.css's
     own :root block. Without this, those three rules would resolve to
     rgba(,,,N), invisible or black, instead of white/red/black. */
  --bs-white-rgb:255,255,255;
  --bs-black-rgb:0,0,0;
  --bs-danger-rgb:220,53,69
}

/* Reboot layer: bare element resets, not class-based, so the audit above
 * (which only matched classes referenced in markup) could not see this
 * dependency. MudBlazor.min.css applies its own universal reset
 * (*{box-sizing:border-box;margin:0;padding:0;...}), which already covers
 * box-sizing and zeroes every element's margin, so bootstrap.min.css's own
 * box-sizing and body-margin rules are redundant and not ported. What is
 * NOT already covered is Bootstrap's Reboot re-adding margin and font
 * styling on top of that universal zero for headings, paragraphs, and hr.
 * Confirmed live use via grep: h1/h2/h3/h5/h6 in 8 components (Error.razor,
 * Access-Denied.razor, EnableSmsDialog.razor, DisableSmsDialog.razor,
 * IncidentGroups.razor, FloorMapPopOut.razor, IncidentMap.razor), 19 bare
 * <p> tags, 2 <hr> tags. Values copied verbatim from bootstrap.min.css;
 * the .h1-.h6 utility classes are omitted since grep found zero call sites. */
h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}
h1{font-size:calc(1.375rem + 1.5vw)}
h2{font-size:calc(1.325rem + .9vw)}
h3{font-size:calc(1.3rem + .6vw)}
h4{font-size:calc(1.275rem + .3vw)}
h5{font-size:1.25rem}
h6{font-size:1rem}
@media (min-width:1200px){
  h1{font-size:2.5rem}
  h2{font-size:2rem}
  h3{font-size:1.75rem}
  h4{font-size:1.5rem}
}
p{margin-top:0;margin-bottom:1rem}
hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}
hr:not([size]){height:1px}

/* Flex container */
.d-flex{display:flex!important}
.flex-row{flex-direction:row!important}
.flex-column{flex-direction:column!important}
.flex-wrap{flex-wrap:wrap!important}

/* Flex alignment */
.align-items-center{align-items:center!important}
.align-items-start{align-items:flex-start!important}
.align-self-center{align-self:center!important}
.align-self-start{align-self:flex-start!important}
.justify-content-between{justify-content:space-between!important}
.justify-content-center{justify-content:center!important}
.justify-content-end{justify-content:flex-end!important}
.justify-content-start{justify-content:flex-start!important}

/* Flex child */
.flex-grow-0{flex-grow:0!important}
.flex-grow-1{flex-grow:1!important}
.flex-shrink-0{flex-shrink:0!important}
.flex-shrink-1{flex-shrink:1!important}

/* Grid (row/col)
 * Order matters here and must match Bootstrap's own source order: .row>*
 * sets width:100% on every direct child as the pre-grid default, and the
 * .col-N rules below it override that default down to their own percentage.
 * Both selectors carry identical specificity (one class), so with no
 * override the later rule in the file wins. Bootstrap's real stylesheet
 * places .row>* before .col-1 through .col-12 for exactly this reason; if
 * .col-N is moved above .row>* again, every base (non-responsive) row/col
 * pairing collapses to full width and stacks instead of sitting side by
 * side. This exact ordering bug shipped once already for the *-md-* / *-lg-*
 * breakpoint block (see the file header) and a second time here at the
 * base layer, breaking the Access Groups, Permission Groups, and Scenarios
 * list/add-button header row (PR #45 review, 2026-08-13). */
.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}
.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}
.col-2{flex:0 0 auto;width:16.66666667%}
.col-6{flex:0 0 auto;width:50%}
.col-10{flex:0 0 auto;width:83.33333333%}
.col-12{flex:0 0 auto;width:100%}
@media (min-width:576px){
  .col-sm-12{flex:0 0 auto;width:100%}
}
@media (min-width:768px){
  .col-md-2{flex:0 0 auto;width:16.66666667%}
  .col-md-3{flex:0 0 auto;width:25%}
  .col-md-4{flex:0 0 auto;width:33.33333333%}
  .col-md-6{flex:0 0 auto;width:50%}
  .col-md-8{flex:0 0 auto;width:66.66666667%}
  .col-md-9{flex:0 0 auto;width:75%}
  .col-md-10{flex:0 0 auto;width:83.33333333%}
}
@media (min-width:1200px){
  .col-xl-2{flex:0 0 auto;width:16.66666667%}
  .col-xl-3{flex:0 0 auto;width:25%}
  .col-xl-9{flex:0 0 auto;width:75%}
  .col-xl-10{flex:0 0 auto;width:83.33333333%}
}

/* Spacing (margin/padding/gap) */
.m-0{margin:0!important}
.m-2{margin:.5rem!important}
.m-4{margin:1.5rem!important}
.mt-0{margin-top:0!important}
.mt-1{margin-top:.25rem!important}
.mt-2{margin-top:.5rem!important}
.mt-4{margin-top:1.5rem!important}
.mb-2{margin-bottom:.5rem!important}
.mb-3{margin-bottom:1rem!important}
.mb-4{margin-bottom:1.5rem!important}
.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}
.ms-3{margin-left:1rem!important}
.ms-auto{margin-left:auto!important}
.me-2{margin-right:.5rem!important}
.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}
.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}
.p-0{padding:0!important}
.p-1{padding:.25rem!important}
.p-2{padding:.5rem!important}
.p-3{padding:1rem!important}
.p-4{padding:1.5rem!important}
.p-5{padding:3rem!important}
.pt-0{padding-top:0!important}
.pt-2{padding-top:.5rem!important}
.pb-3{padding-bottom:1rem!important}
.ps-2{padding-left:.5rem!important}
.ps-4{padding-left:1.5rem!important}
.pe-2{padding-right:.5rem!important}
.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}
.gap-1{gap:.25rem!important}
.gap-2{gap:.5rem!important}
.gap-3{gap:1rem!important}
.gap-4{gap:1.5rem!important}

/* Responsive flex/spacing/justify (breakpoint variants).
 * Positioned after every unqualified base rule above, not next to the base
 * flex/spacing sections where they were originally drafted. Verified by
 * Tier-3 adversarial review (2026-08-05): with equal specificity and
 * matching !important flags, a later same-specificity rule wins on source
 * order regardless of the media query, so a breakpoint override placed
 * before its own base rule gets silently reverted at the breakpoint.
 * Confirmed live call sites that combine a base and responsive class on one
 * element: IncidentGroups.razor:30 and Scenarios.razor:33 (`m-2 m-md-5`),
 * Admin.razor:14 (`gap-4 gap-md-2`). Both need the *-md-* or *-lg-* value to
 * win at width, which only holds if this block stays last.
 *
 * Correction (2026-08-06, PR #45 review, PS Solutions): the sentence above
 * originally combined the two breakpoint tokens with a slash between them,
 * with no space on either side. That put a star immediately before the
 * slash, which is the two-character sequence that ends a CSS comment, so
 * the comment closed there instead of at its intended end. Everything after
 * that point through the block's own intended closing mark was then parsed
 * as invalid CSS, and the browser discarded it together with the entire
 * @media (min-width:768px) block below (flex-md-row, justify-content-md-
 * center, gap-md-2, m-md-5, p-md-4), none of which ever took effect in any
 * browser. That silently undid the cascade-order fix this comment exists to
 * document: Admin.razor, AccessGroups.razor, and PermissionGroups.razor's
 * list+detail split never received flex-direction:row at any width, so the
 * detail panel always rendered stacked under the list and overflowed the
 * vh-100/h-100-bounded parent instead of sitting beside it. Confirmed by
 * loading the real MudBlazor.min.css and this file into a browser and
 * reading the parsed CSSOM: this exact block was absent from
 * document.styleSheets, with parsing resuming cleanly at the next rule
 * (@media (min-width:992px) .flex-lg-row). No other comment in this file
 * contains an early-closing star-slash; this was the only one. */
@media (min-width:768px){
  .flex-md-row{flex-direction:row!important}
  .justify-content-md-center{justify-content:center!important}
  .gap-md-2{gap:.5rem!important}
  .m-md-5{margin:3rem!important}
  .p-md-4{padding:1.5rem!important}
}
@media (min-width:992px){
  .flex-lg-row{flex-direction:row!important}
  .justify-content-lg-end{justify-content:flex-end!important}
  .justify-content-lg-between{justify-content:space-between!important}
  .m-lg-5{margin:3rem!important}
}
@media (min-width:1200px){
  .flex-xl-row{flex-direction:row!important}
}

/* Border / radius */
.border{border:1px solid #dee2e6!important}
.border-1{border-width:1px!important}
.border-dark{border-color:#212529!important}
.border-bottom{border-bottom:1px solid #dee2e6!important}
.rounded{border-radius:.25rem!important}
.rounded-2{border-radius:.25rem!important}
.rounded-pill{border-radius:50rem!important}
.rounded-circle{border-radius:50%!important}

/* Text / color / weight */
.text-break{word-wrap:break-word!important;word-break:break-word!important}
.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}
.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}
.text-center{text-align:center!important}
.text-nowrap{white-space:nowrap!important}
.fw-bold{font-weight:700!important}
.fs-2{font-size:calc(1.325rem + .9vw)!important}
.fst-italic{font-style:italic!important}
@media (min-width:1200px){
  .fs-2{font-size:2rem!important}
}

/* Sizing */
.w-100{width:100%!important}
.w-75{width:75%!important}
.w-50{width:50%!important}
.w-25{width:25%!important}
.h-100{height:100%!important}
.h-75{height:75%!important}
.h-auto{height:auto!important}
.vh-100{height:100vh!important}

/* Position / overflow */
.position-relative{position:relative!important}
.position-absolute{position:absolute!important}
.overflow-auto{overflow:auto!important}
.overflow-hidden{overflow:hidden!important}

/* Background */
.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}
