/* gentelella-adapter.css — bridges Bootstrap patterns used in existing views
   to work with Gentelella v4's CSS framework.

   Gentelella v4 uses many of the same class names as Bootstrap (btn, card,
   table, form-control, etc.) but has its own grid, lacks Bootstrap's utility
   classes, and has different alert/tab/nav markup. This file fills those gaps
   so the existing Razor views keep working without rewrites. */

/* ── Bootstrap-style grid system ───────────────────────────────────────
   Gentelella uses row.col-3 / row.col-2 / row.col-8-4 for its grid.
   Bootstrap's .row > .col-* needs to work for existing views. */
.container, .container-fluid {
  width: 100%;
  margin: 0 auto;
}
/* Gentelella's own .row is `display:grid; gap:16px`. Switching it to flex kept that 16px gap,
   and a gap is added ON TOP of the column widths — so any pair that sums to 100% (col-md-6 +
   col-md-6, col-sm-3 + col-sm-9) overflowed and wrapped, stacking side-by-side layouts. Rows here
   follow Bootstrap instead: no gap, horizontal gutters as padding inside each column (--g-x),
   cancelled at the row edges by a negative margin, so column widths add up exactly.
   The g-2 / g-3 classes below only change the gutter size. */
.row {
  --g-x: 1.5rem;
  --g-y: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  row-gap: var(--g-y);
  margin-left: calc(var(--g-x) / -2);
  margin-right: calc(var(--g-x) / -2);
}
.row > * {
  padding-left: calc(var(--g-x) / 2);
  padding-right: calc(var(--g-x) / 2);
}
/* The mobile-first default: every column full width until a col-<tier>-N rule says otherwise.
   :where() gives this rule zero specificity — written as a plain `.row > [class*="col-"]` it
   out-ranked every single-class .col-md-6 / .col-sm-3 rule below, so NO column ever got its
   width and every multi-column layout in the app silently stacked. */
:where(.row) > :where([class*="col-"]) { flex-shrink: 0; width: 100%; max-width: 100%; }
/* Plain .col = equal-width share of the row (gps-edit.js's lat/long pair). */
.row > .col { flex: 1 0 0%; min-width: 0; }
.col-1  { flex: 0 0 auto; width: 8.33333333%; }
.col-2  { flex: 0 0 auto; width: 16.66666667%; }
.col-3  { flex: 0 0 auto; width: 25%; }
.col-4  { flex: 0 0 auto; width: 33.33333333%; }
.col-5  { flex: 0 0 auto; width: 41.66666667%; }
.col-6  { flex: 0 0 auto; width: 50%; }
.col-7  { flex: 0 0 auto; width: 58.33333333%; }
.col-8  { flex: 0 0 auto; width: 66.66666667%; }
.col-9  { flex: 0 0 auto; width: 75%; }
.col-10 { flex: 0 0 auto; width: 83.33333333%; }
.col-11 { flex: 0 0 auto; width: 91.66666667%; }
.col-12 { flex: 0 0 auto; width: 100%; }
@media (min-width: 768px) {
  .col-md-1  { flex: 0 0 auto; width: 8.33333333%; }
  .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-5  { flex: 0 0 auto; width: 41.66666667%; }
  .col-md-6  { flex: 0 0 auto; width: 50%; }
  .col-md-7  { flex: 0 0 auto; width: 58.33333333%; }
  .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%; }
  .col-md-11 { flex: 0 0 auto; width: 91.66666667%; }
  .col-md-12 { flex: 0 0 auto; width: 100%; }
}
/* Small (≥576px) and large (≥992px) tiers — views use col-sm-* (details <dl> label/value pairs,
   admin forms) and col-lg-*. Without these every such column fell back to the full-width rule
   above, so labels and values stacked on separate lines. */
@media (min-width: 576px) {
  .col-sm-3  { flex: 0 0 auto; width: 25%; }
  .col-sm-4  { flex: 0 0 auto; width: 33.33333333%; }
  .col-sm-5  { flex: 0 0 auto; width: 41.66666667%; }
  .col-sm-6  { flex: 0 0 auto; width: 50%; }
  .col-sm-7  { flex: 0 0 auto; width: 58.33333333%; }
  .col-sm-8  { flex: 0 0 auto; width: 66.66666667%; }
  .col-sm-9  { flex: 0 0 auto; width: 75%; }
  .col-sm-12 { flex: 0 0 auto; width: 100%; }
}
@media (min-width: 992px) {
  .col-lg-3  { flex: 0 0 auto; width: 25%; }
  .col-lg-4  { flex: 0 0 auto; width: 33.33333333%; }
  .col-lg-5  { flex: 0 0 auto; width: 41.66666667%; }
  .col-lg-6  { flex: 0 0 auto; width: 50%; }
  .col-lg-7  { flex: 0 0 auto; width: 58.33333333%; }
  .col-lg-8  { flex: 0 0 auto; width: 66.66666667%; }
  .col-lg-12 { flex: 0 0 auto; width: 100%; }
}
/* Gutter sizes for .row (see the .row rule above): horizontal AND vertical, as in Bootstrap. */
.row.g-0 { --g-x: 0;     --g-y: 0; }
.row.g-2 { --g-x: .5rem; --g-y: .5rem; }
.row.g-3 { --g-x: 1rem;  --g-y: 1rem; }
.gap-2 { gap: .5rem; }
.gap-3 { gap: 1rem; }
.gap-4 { gap: 1.5rem; }

/* ── Flex/display utilities ─────────────────────────────────────────── */
.d-flex { display: flex !important; }
.d-inline { display: inline !important; }
.d-inline-block { display: inline-block !important; }
.d-none { display: none !important; }
.flex-grow-1 { flex: 1 1 auto !important; }
.flex-wrap { flex-wrap: wrap !important; }
.flex-column { flex-direction: column !important; }
.justify-content-between { justify-content: space-between !important; }
.justify-content-center { justify-content: center !important; }
.align-items-center { align-items: center !important; }
.align-self-start { align-self: flex-start !important; }
.text-center { text-align: center !important; }
.text-start { text-align: left !important; }
.text-end { text-align: right !important; }
.text-nowrap { white-space: nowrap !important; }

/* ── Spacing (Bootstrap-style margin/padding utilities) ─────────────── */
.m-0 { margin: 0 !important; }
.mt-1 { margin-top: .25rem !important; }
.mt-2 { margin-top: .5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
.mt-5 { margin-top: 3rem !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-1 { margin-bottom: .25rem !important; }
.mb-2 { margin-bottom: .5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1.5rem !important; }
.ms-1 { margin-left: .25rem !important; }
.ms-2 { margin-left: .5rem !important; }
.ms-3 { margin-left: 1rem !important; }
.ms-auto { margin-left: auto !important; }
.me-1 { margin-right: .25rem !important; }
.me-2 { margin-right: .5rem !important; }
.me-3 { margin-right: 1rem !important; }
.my-2 { margin-top: .5rem !important; margin-bottom: .5rem !important; }
.my-3 { margin-top: 1rem !important; margin-bottom: 1rem !important; }
.mx-auto { margin-left: auto !important; margin-right: auto !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; }
.pt-2 { padding-top: .5rem !important; }
.pb-3 { padding-bottom: 1rem !important; }
.px-0 { padding-left: 0 !important; padding-right: 0 !important; }
.px-2 { padding-left: .5rem !important; padding-right: .5rem !important; }
.py-2 { padding-top: .5rem !important; padding-bottom: .5rem !important; }

/* ── Typography utilities ──────────────────────────────────────────── */
.text-muted { color: var(--text-muted) !important; }
.text-danger { color: var(--red) !important; }
.small { font-size: .85em !important; }
.fw-semibold { font-weight: 600 !important; }
.font-monospace { font-family: "Cascadia Code", "Fira Code", "Consolas", monospace !important; }

/* ── Table variants ────────────────────────────────────────────────────
   Gentelella's .table is clean. Add Bootstrap variants that views use. */
.table-bordered { border: 1px solid var(--border-color); }
.table-bordered th,
.table-bordered td { border: 1px solid var(--border-color); }
.table-sm th,
.table-sm td { padding: .35rem .5rem; }
.table-hover tbody tr:hover { background-color: var(--bg-subtle); }
.table-light { background-color: var(--bg-subtle); }
.table thead.table-light th { background-color: var(--bg-subtle); }

/* ── DataTables 2 layout (every list table — see wwwroot/dist/data-table.js) ────────
   The DataTables Bootstrap-5 skin renders each toolbar row as
   <div class="row mt-2 justify-content-between"> with children carrying
   "dt-layout-start col-md-auto me-auto" / "dt-layout-end col-md-auto ms-auto".
   This file's own ".row > [class*='col-'] { width: 100% }" rule (above) makes
   every one of those children full-width, which stacks them instead of
   pushing dt-layout-end (the search box) to the right. Scoped to
   div.dt-container so no other .row/.col-* view is affected. */
div.dt-container div.row > [class*="col-"] { width: auto; max-width: none; flex-shrink: 1; }
div.dt-container .dt-layout-start { margin-right: auto; }
div.dt-container .dt-layout-end { margin-left: auto; text-align: right; }
/* The table's own row holds a single "dt-layout-full col-12" cell. It also matches the
   [class*="col-"] rule above, which (being more specific) shrank it to width:auto — and since
   .row is a flex container, the cell, and the 100%-wide table inside it, collapsed to the width of
   the content, leaving a big empty band to the right of every list. Matching that rule's
   specificity and coming later puts the table back to the full card width. */
div.dt-container div.row > .dt-layout-full { width: 100%; flex: 1 1 100%; }
@media (max-width: 767px) {
  div.dt-container div.row { justify-content: center; }
  div.dt-container .dt-layout-start,
  div.dt-container .dt-layout-end { margin: 0; text-align: center; width: 100%; }
}

/* The toolbar cells hold a mix of controls (page-length select, Export CSV button, search box).
   One flex row keeps them on a shared baseline instead of stacking on the text baseline. */
div.dt-container .dt-layout-start,
div.dt-container .dt-layout-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
}
div.dt-container .dt-layout-end { justify-content: flex-end; }

/* Give the table breathing room from the card edge that .card-body.p-0 removed, and stop the
   toolbar rows from sitting flush against the card border. */
div.dt-container { padding: .75rem 1rem 0; }
div.dt-container .dt-csv-button { display: inline-flex; align-items: center; gap: .35rem; }

/* ── DataTables pagination ───────────────────────────────────────────────
   Gentelella already styles a nice pill button as `.page-link`, but it puts the active/disabled
   states on `.page-link` itself — whereas the DataTables Bootstrap-5 skin puts them on the parent
   `<li class="page-item">`. Without this bridge the current page never highlights and the
   disabled Previous/Next look identical to live ones, so the whole control reads as a flat grey
   strip. Gentelella's own `.pagination` rule also adds a top border + padding, which framed that
   strip like a footer bar; inside the DataTables toolbar we want the buttons to float free. */
div.dt-container .pagination {
  border-top: none;
  padding: 0;
  margin: 0;
  gap: .25rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
div.dt-container .page-item { list-style: none; }
div.dt-container .page-item .page-link {
  min-width: 32px;
  height: 32px;
  border-radius: var(--radius, 6px);
}
div.dt-container .page-item.active .page-link {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
div.dt-container .page-item.disabled .page-link {
  color: var(--text-disabled);
  background: transparent;
  border-color: transparent;
  opacity: .55;
  pointer-events: none;
}
/* Previous/Next carry words, not numbers — let them size to their label. */
div.dt-container .page-item:first-child .page-link,
div.dt-container .page-item:last-child .page-link { padding: 0 .7rem; }

/* ── Responsive tables: stand down once DataTables takes over ────────────
   Views wrap their tables in .table-responsive (overflow-x: auto) so a wide table scrolls when
   there is no JS. But the DataTables Responsive extension only collapses low-priority columns when
   it detects the table overflowing its parent — inside a scrolling box it never does, so instead of
   collapsing, every column squeezes down to fit. Once DataTables has wrapped the table in
   .dt-container we therefore drop the scroll box and let Responsive do the job it is there for. */
.table-responsive:has(> .dt-container) { overflow-x: visible; }

/* ── Nav tabs (used in Entity Create/Edit) ──────────────────────────── */
.nav { display: flex; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.nav-item { list-style: none; }
.nav-tabs { border-bottom: 1px solid var(--border-color); gap: 0; }
.nav-tabs .nav-link {
  display: block;
  padding: .5rem 1rem;
  margin-bottom: -1px;
  border: 1px solid transparent;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  color: var(--text-secondary);
  font-weight: 500;
  font-size: .85rem;
  background: none;
  cursor: pointer;
}
.nav-tabs .nav-link:hover { border-color: var(--bg-subtle) var(--bg-subtle) var(--border-color); }
.nav-tabs .nav-link.active {
  color: var(--primary);
  background: var(--surface);
  border-color: var(--border-color) var(--border-color) var(--surface);
}
.tab-content > .tab-pane { display: none; }
.tab-content > .tab-pane.active { display: block; }
.tab-content > .tab-pane.fade { transition: opacity .15s linear; }
.tab-content > .tab-pane.fade.active { display: block; opacity: 1; }

/* ── Branding for chrome-less pages ──────────────────────────────────────
   The sidebar/topbar (which normally carry the app name) don't render for anonymous callers,
   and slide off-screen on mobile — without this a public/mobile form just floats with no
   identity above it (_Layout.cshtml, _EmbeddedLayout.cshtml). */
.public-topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 16px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-color);
}
/* Admin-impersonation banner (_Layout.cshtml) — always visible while an admin is impersonating
   another user, regardless of theme, so it can never be mistaken for a themed/dismissible alert.
   Fixed at the very top of the page, pushing content down (see body padding rule below). */
.impersonation-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 8px 16px;
  background: #f5a623;
  color: #1a1a1a;
  font-size: .875rem;
  font-weight: 500;
}
.impersonation-banner form { margin: 0; }
body[data-impersonating="true"] { padding-top: 40px; }

/* Mobile-only brand mark inside the signed-in topbar — hidden on desktop, where the sidebar
   already shows the brand. */
.topbar-brand { display: none; font-size: 14px; font-weight: 600; color: var(--text); }
@media (max-width: 768px) {
  .topbar-brand { display: block; }
}

/* A field using the "hidden" edit type has no visible control (_EntityFormField.cshtml renders
   only the <input type="hidden">), so its container must not take up layout space either — the
   wrapper's own margin would otherwise leave a blank gap where the field would have been.
   Display:none does not stop the inputs inside from being submitted with the form.
   First selector: the Create/Edit field containers, which stamp the resolved edit type.
   Second: wrappers that don't stamp it (report parameters, master-detail rows) — recognised by
   holding nothing but the hidden input. */
[data-edit-type="hidden"],
.form-group:has(> input[type="hidden"]:only-child) {
  display: none;
}

/* A tab holding an invalid field (form-renderer.js markInvalidTab) — the tab stays put (we
   don't auto-switch, see form-renderer.js), just flagged so the user knows where to look. */
.nav-tabs .nav-link.tab-has-error {
  color: var(--red);
  border-color: var(--red-lt) var(--red-lt) var(--border-color);
}

/* Full-page overlay shown while FK dropdowns are still fetching their options
   (form-renderer.js showLoadingUntilReady). */
.entapp-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--body-bg) 70%, transparent);
}
.entapp-spinner {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 3px solid var(--border-color);
  border-top-color: var(--primary);
  animation: entapp-spin .7s linear infinite;
}
@keyframes entapp-spin { to { transform: rotate(360deg); } }

/* ── Alerts ────────────────────────────────────────────────────────────
   Gentelella doesn't have Bootstrap-style alerts. Add them. */
.alert {
  position: relative;
  padding: .75rem 1.25rem;
  margin-bottom: 1rem;
  border-radius: 10px;
  font-size: .875rem;
  border: 1px solid transparent;
}
.alert-success {
  color: #1f6b58;
  background-color: #e9f5f1;
  border-color: #cde9e1;
}
.alert-danger {
  color: #b4453f;
  background-color: #fdeeee;
  border-color: #f6d4d4;
}
.alert-warning {
  color: #98661f;
  background-color: #fbf1e3;
  border-color: #f3e0c4;
}
.alert-info {
  color: #1a6a8a;
  background-color: #e5f4fa;
  border-color: #cce8f2;
}
.alert-dismissible { padding-right: 2.5rem; }
.alert-dismissible .btn-close {
  position: absolute;
  top: 0; right: 0;
  padding: .75rem 1rem;
  background: none;
  border: none;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  opacity: .5;
}
.alert-dismissible .btn-close:hover { opacity: .75; }
.btn-close {
  box-sizing: content-box;
  width: 1em;
  height: 1em;
  color: inherit;
  background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;
  border: 0;
  border-radius: 4px;
  opacity: .5;
  cursor: pointer;
}
.fade { transition: opacity .15s linear; }
.fade:not(.show) { opacity: 0; }

/* ── Buttons: btn-secondary maps to btn-outline ─────────────────────── */
.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  height: 32px;
  font-size: .8125rem;
  font-weight: 500;
  font-family: inherit;
  border-radius: 8px;
  border: 1px solid var(--border-color);
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background .12s, border-color .12s;
  text-decoration: none;
  white-space: nowrap;
}
.btn-secondary:hover { background: var(--bg-subtle); border-color: var(--border-color); }

/* Anchor buttons: Gentelella's .btn assumes a <button>, so strip the link underline. */
.btn { text-decoration: none; }
.btn:hover { text-decoration: none; }

/* Outline + extra button variants (Gentelella ships only .btn / .btn-primary / .btn-sm).
   They ride on Gentelella's .btn base for size/shape and just set the colours. */
.btn-outline-secondary { background: transparent; border-color: var(--border-color); color: var(--text-secondary); }
.btn-outline-secondary:hover { background: var(--bg-surface-secondary); border-color: var(--border-color); color: var(--text); }
.btn-outline-primary { background: transparent; border-color: var(--primary); color: var(--primary); }
.btn-outline-primary:hover { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-outline-dark { background: transparent; border-color: var(--border-color); color: var(--text); }
.btn-outline-dark:hover { background: var(--text); border-color: var(--text); color: #fff; }
.btn-outline-info { background: transparent; border-color: var(--blue); color: var(--blue); }
.btn-outline-info:hover { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn-outline-danger { background: transparent; border-color: var(--red); color: var(--red); }
.btn-outline-danger:hover { background: var(--red); border-color: var(--red); color: #fff; }
.btn-outline-success { background: transparent; border-color: var(--green); color: var(--green); }
.btn-outline-success:hover { background: var(--green); border-color: var(--green); color: #fff; }
.btn-warning { background: var(--yellow); border-color: var(--yellow); color: #78350f; }
.btn-warning:hover { filter: brightness(.96); color: #78350f; }
.btn-link { background: transparent; border-color: transparent; color: var(--primary); padding: 0 4px; }
.btn-link:hover { text-decoration: underline; }

/* ── Form select (Gentelella styles .form-control but not .form-select) ───────
   Mirrors .form-control (36px, same border/radius) and adds a caret. Multi-row
   selects (size > 1, e.g. the FK typeahead list) render as a plain list box. */
.form-select {
  width: 100%;
  height: 36px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background-color: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  padding: 0 32px 0 12px;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%237e8896' stroke-width='1.5'%3e%3cpath d='M4 6l4 4 4-4'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 14px;
  transition: border-color .15s, box-shadow .15s;
}
.form-select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-lt); }
.form-select[multiple],
.form-select[size]:not([size="1"]) {
  height: auto;
  padding-right: 12px;
  background-image: none;
}

/* Sidebar nav links are styled by Gentelella's own .nav-link rule (display:flex, full-width,
   dark-sidebar colours, hover/active states). We must NOT override it here — an earlier
   `aside .nav-link { display:inline-flex }` rule made the links flow horizontally and wrap into
   multiple columns. The topbar uses .tb-btn / .breadcrumb, not .nav-link, so nothing else needs it. */

/* ── Validation summary ────────────────────────────────────────────── */
.validation-summary-errors ul {
  list-style: none;
  padding: 0;
  margin: .5rem 0;
}
.field-validation-error { color: var(--red); }

/* ── Details/summary (used in admin forms) ─────────────────────────── */
details.border { border: 1px solid var(--border-color); }
details.rounded { border-radius: 8px; }
summary { cursor: pointer; font-weight: 500; padding: .5rem; }

/* ── Responsive table wrapper ──────────────────────────────────────── */
.table-responsive {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ── Status badges (Gentelella style) ─────────────────────────────────
   Used in table rows to show status (active/inactive/completed/pending).
   .status is the base, .status-color adds the hue. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 4px;
  line-height: 1.4;
}
.status::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.status-green { background: var(--green-lt); color: var(--green); }
.status-green::before { background: var(--green); }
.status-blue { background: var(--blue-lt); color: var(--blue); }
.status-blue::before { background: var(--blue); }
.status-yellow { background: var(--yellow-lt); color: #b45309; }
.status-yellow::before { background: var(--yellow); }
.status-red { background: var(--red-lt); color: var(--red); }
.status-red::before { background: var(--red); }
.status-purple { background: var(--purple-lt); color: var(--purple); }
.status-purple::before { background: var(--purple); }
.status-azure { background: var(--azure-lt); color: var(--azure); }
.status-azure::before { background: var(--azure); }

/* ── Stat cards (Gentelella dashboard pattern) ───────────────────────
   .card > .stat > .stat-icon + .stat-content > .stat-value + .stat-label */
.stat {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
}
.stat-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 18px;
}
.stat-icon.teal { background: var(--primary-lt); color: var(--primary); }
.stat-icon.blue { background: var(--blue-lt); color: var(--blue); }
.stat-icon.green { background: var(--green-lt); color: var(--green); }
.stat-icon.yellow { background: var(--yellow-lt); color: #b45309; }
.stat-icon.red { background: var(--red-lt); color: var(--red); }
.stat-icon.purple { background: var(--purple-lt); color: var(--purple); }
.stat-content { display: flex; flex-direction: column; gap: 2px; }
.stat-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -.3px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.stat-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .3px;
}
.stat-change {
  font-size: 12px;
  font-weight: 500;
}
.stat-change.up { color: var(--green); }
.stat-change.down { color: var(--red); }

/* ── Divider label (horizontal rule with embedded text) ───────────── */
.divider-label {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--text-muted);
  margin: 20px 0 14px;
}
.divider-label::before,
.divider-label::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border-color-light);
}

/* ── Form actions (button row at bottom of forms) ─────────────────── */
.form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 16px;
  margin-top: 16px;
  border-top: 1px solid var(--border-color-light);
}

/* ── Boolean cell tick / cross ─────────────────────────────────────
   Read-only true/false rendering for entity lists and detail pages, built by
   BooleanDisplayHelper. Glyphs (not an icon font) so they also work in the
   embedded layout, which does not load Font Awesome. */
.bool-yes,
.bool-no {
  font-size: 14px;
  line-height: 1;
  font-weight: 600;
}
.bool-yes { color: var(--green); }
.bool-no { color: var(--text-disabled); }

/* ── Form help text ───────────────────────────────────────────────── */
.form-help {
  display: block;
  color: var(--text-muted);
  font-size: 11.5px;
  margin-top: 4px;
}

/* Bootstrap's .form-text — same role as .form-help, emitted by JS-generated
   fields (config-form.js). Kept identical so both read the same on screen. */
.form-text {
  display: block;
  color: var(--text-muted);
  font-size: 11.5px;
  margin-top: 4px;
}

/* MVC's validation summary renders an empty container when the model is valid;
   without this it shows as a blank alert bar at the top of every form. */
.validation-summary-valid { display: none !important; }

/* ── Segmented control ────────────────────────────────────────────── */
.segmented {
  display: inline-flex;
  background: var(--bg-surface-secondary);
  border-radius: var(--radius);
  padding: 2px;
  gap: 1px;
}
.segmented .segmented-item {
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  background: none;
  border: none;
  padding: 5px 12px;
  border-radius: calc(var(--radius) - 1px);
  cursor: pointer;
  transition: background .12s, color .12s;
}
.segmented .segmented-item:hover { color: var(--text); }
.segmented .segmented-item.active {
  background: var(--bg-surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,.05);
}

/* ── Toggle switch ────────────────────────────────────────────────── */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.switch-slider {
  position: relative;
  width: 36px;
  height: 20px;
  background: var(--border-color);
  border-radius: 10px;
  transition: background .2s;
  flex-shrink: 0;
}
.switch-slider::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: white;
  border-radius: 50%;
  transition: transform .2s;
}
.switch input:checked + .switch-slider { background: var(--primary); }
.switch input:checked + .switch-slider::before { transform: translateX(16px); }
.switch-label { font-size: 13px; color: var(--text); }

/* ── Button group ─────────────────────────────────────────────────── */
.btn-group {
  display: inline-flex;
  gap: 0;
}
.btn-group .btn:not(:first-child) {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-left: -1px;
}
.btn-group .btn:not(:last-child) {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

/* ── Embedded layout (chrome-less iframe) ──────────────────────────── */
body:has(.embedded-layout) .app-wrapper,
body:has(.embedded-layout) .sidebar,
body:has(.embedded-layout) .topbar,
body:has(.embedded-layout) .footer {
  display: none !important;
}

/* ── Breadcrumb compatibility for views that use Bootstrap's breadcrumb */
.breadcrumb { display: flex; flex-wrap: wrap; list-style: none; padding: 0; }
.breadcrumb-item + .breadcrumb-item::before {
  content: "/";
  padding: 0 .5rem;
  color: var(--text-muted);
}

/* ── Select2 multi-select empty-state affordance ───────────────────────
   Select2's default theme gives a single-select combobox the same chevron
   Bootstrap's .form-select has, but draws nothing on a multi-select box —
   so an empty foreignkey-multiselect/dropdown-multiple field (the common
   case, e.g. a fresh create form) looks like a plain text input with no
   hint that it's a dropdown at all. This mirrors Bootstrap's own
   .form-select chevron (same SVG/color) onto the multi-select box. */
.select2-container--default .select2-selection--multiple {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: 16px 12px;
  padding-right: 2rem;
}

/* ── Bootstrap modal positioning ─────────────────────────────────────────
   No layout links Bootstrap's own CSS anywhere (only bootstrap.bundle.min.js, the JS behavior) —
   gentelella.css's .modal-backdrop/.modal-dialog rules exist for ITS OWN bespoke modal component,
   not real Bootstrap markup, and it defines no .modal rule at all. Bootstrap's JS still toggles
   .show and sets display:block correctly (no JS error), but the plain <div class="modal"> it
   creates has no position/z-index of its own, so it renders inline in the document while
   gentelella's .modal-backdrop (position:fixed, z-index:1200, a full-viewport blurred overlay)
   sits on top of it — the whole screen goes gray with the dialog invisible underneath.
   NOTE: Bootstrap's Modal.show() sets `style.display = 'block'` as an INLINE style, which beats
   any `.modal.show { display: flex }` class rule — so centering can't be done via flex on .modal
   itself; it has to be margin-based on .modal-dialog, same as real Bootstrap. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 1300;
  display: none;
  overflow-x: hidden;
  overflow-y: auto;
  outline: 0;
}
.modal-dialog {
  position: relative;
  margin: 1.75rem auto;
}
/* Only .modal-lg is actually used in the app (foreignkey-edit.js's "+ Add new" modal) — gentelella's
   own .modal-dialog hardcodes max-width:480px regardless of Bootstrap's size modifier classes. */
.modal-dialog.modal-lg { max-width: 800px; }
/* Real Bootstrap markup also uses .modal-dialog-centered (vertical centering) — neither stylesheet
   defines it, so it was a no-op class in the markup. */
.modal-dialog-centered {
  display: flex;
  align-items: center;
  min-height: calc(100% - 3.5rem);
}
/* .modal-content has NO rule at all in either stylesheet (confirmed by search) — it was a plain,
   unstyled div. gentelella.css's .modal-body { flex: auto; overflow-y: auto } only has any effect
   on a flex-container PARENT, so without this, .modal-body (and the "+ Add new"/FrameLink modal's
   height:100% iframe inside it) collapsed to its content's intrinsic height instead of filling the
   height set on .modal-content (e.g. the 80vh set inline by foreignkey-edit.js/nav-menu.js) — the
   "modal is too short, has to scroll" bug. display:flex + flex-direction:column is what makes
   .modal-header/.modal-body/.modal-footer's own flex rules actually take effect. */
.modal-content {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--bg-surface, #fff);
  border-radius: var(--radius, 6px);
  box-shadow: var(--shadow-card, 0 0.5rem 1rem rgba(0, 0, 0, .15));
  overflow: hidden;
}
/* gentelella.css's fade-in (opacity 0→1, translateY+scale→none) is scoped to ITS OWN nested
   .modal-backdrop > .modal-dialog structure — our real Bootstrap DOM nests .modal-dialog inside
   .modal instead, so that rule never matches and .modal-dialog is stuck at its hidden opacity:0.
   This targets the structure Bootstrap's JS actually creates. */
.modal.show .modal-dialog {
  opacity: 1;
  transform: none;
}
