/* 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; }
/* Further Bootstrap utilities the views use (found by listing every class in the .cshtml files
   that no stylesheet defined) — without them those elements silently fell back to defaults. */
.d-block { display: block !important; }
.w-100 { width: 100% !important; }
.w-auto { width: auto !important; }
.gap-1 { gap: .25rem; }
.align-items-start { align-items: flex-start !important; }
.align-items-end { align-items: flex-end !important; }
.justify-content-end { justify-content: flex-end !important; }
.align-middle { vertical-align: middle !important; }
.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-uppercase { text-transform: uppercase !important; }
.text-decoration-none { text-decoration: none !important; }
.text-reset { color: inherit !important; }
.text-warning { color: var(--yellow) !important; }
.row-cols-1 > * { flex: 0 0 auto; width: 100%; }
@media (min-width: 576px) {
  .row-cols-sm-2 > * { flex: 0 0 auto; width: 50%; }
}
@media (min-width: 768px) {
  .d-md-flex { display: flex !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%; }
/* Narrow lists: every toolbar cell takes a full line. The search box moves to the top and fills
   its line (the most-used control, and the easiest to hit); the page-length picker and Export CSV
   share the next line, pushed to opposite ends; info and pager are centred underneath.
   "Narrow" is the LIST's width, not the screen's — a container query on .dt-container (named
   dt-list) — because a tablet with the sidebar open leaves a list as little room as a phone does.
   640px is roughly where the one-line desktop toolbar stops fitting. */
div.dt-container { container: dt-list / inline-size; }
@container dt-list (max-width: 640px) {
  div.dt-container div.row { justify-content: center; row-gap: .6rem; }
  /* "div.row >" lifts these above the width:auto rule for [class*="col-"] cells near the top. */
  div.dt-container div.row > .dt-layout-start,
  div.dt-container div.row > .dt-layout-end { margin: 0; text-align: center; width: 100%; justify-content: center; }
  div.dt-container div.row > .dt-layout-end:has(> .dt-search) { order: -1; }
  div.dt-container div.row > .dt-layout-start:has(> .dt-length) { justify-content: space-between; }
  div.dt-container .dt-search { width: 100%; }
  /* One step above DataTables' own "div.dt-container div.dt-search input { width: auto }" — that
     stylesheet loads after this one, so equal specificity would lose. */
  div.dt-container div.row div.dt-search input { width: 100%; margin-left: 0; }
  /* The toolbar cells carry Bootstrap's justify-content-between (!important above), which pushes a
     lone pager or info line to the left; auto margins centre them regardless. */
  div.dt-container .dt-paging,
  div.dt-container .dt-info { margin-left: auto; margin-right: auto; }
}

/* 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; }

/* (The space between the list and its card edge is set once, in theme.css.) */
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;
}
/* Gentelella draws a 28px bordered box on .dt-paging-button — written for DataTables' default skin,
   where that class is on the button itself. The Bootstrap-5 skin puts it on the <li> AROUND the
   .page-link button, so every page button showed two overlapping boxes. The <li> is only a wrapper. */
div.dt-container .page-item.dt-paging-button {
  min-width: 0;
  height: auto;
  padding: 0;
  border: 0;
  background: none;
  opacity: 1;
}
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; }

/* ── Responsive collapsing on phones ──────────────────────────────────────
   Responsive decides which columns to hide by measuring how wide each one needs to be. Long text
   (a title, an SQL query) wraps word by word, so it "needs" only one word's width — nothing ever
   looked too wide, nothing collapsed, and every row became a tall sliver of one-word lines.
   Keeping cells on one line in a narrow list gives Responsive their real widths, so the
   low-priority columns move into the ▶ child row, where their values wrap normally. Each cell is
   also capped at 14rem and cut with an ellipsis — otherwise one long title alone is wider than a
   phone and Responsive leaves only the Id column, which tells the reader nothing. Action cells and
   the child row itself are never cut (that would hide buttons and the very values being expanded).
   Wide lists keep wrapping, which reads better there. The table cell gets a scroll fallback for
   the rare case where even the remaining columns are wider than the list. Same dt-list container
   query as the toolbar above, so a tablet with the sidebar open gets this treatment too. */
@container dt-list (max-width: 640px) {
  table.dataTable > thead > tr > th,
  table.dataTable > tbody > tr > td { white-space: nowrap; }
  table.dataTable > tbody > tr:not(.child) > td:not(.table-actions) {
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  table.dataTable > tbody > tr.child > td,
  table.dataTable > tbody > tr.child .dtr-data { white-space: normal; overflow-wrap: anywhere; }
  div.dt-container .dt-layout-table > div { overflow-x: auto; }
}

/* The ▶ expand control sits in the first column. When that column is numeric (an Id), DataTables
   right-aligns it, which put the arrow and the number at opposite ends of a wide empty cell. */
table.dataTable.collapsed > * > tr > .dt-type-numeric:first-child { text-align: left; }
/* ...and keep the arrow on the same line as the value next to it, at any width. */
table.dataTable > tbody > tr > td.dtr-control { white-space: nowrap; }

/* ── 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);
}
/* Gentelella's .brand-name is white for the dark sidebar; on this light bar it would be invisible. */
.public-topbar .brand-name { color: var(--text); }
/* 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. */

/* ── Form sizes and variants the views use that Gentelella does not define ─ */
.form-control-sm,
.form-select-sm { height: 30px; min-height: 30px; padding-top: 0; padding-bottom: 0; font-size: 12.5px; }
textarea.form-control-sm { height: auto; padding-top: 4px; padding-bottom: 4px; }
.form-control-plaintext {
  display: block;
  width: 100%;
  padding: .45rem 0;
  border: 0;
  background: transparent;
  color: var(--text);
}
.form-check-inline { display: inline-flex; align-items: center; gap: .35rem; margin-right: 1rem; }
.btn-dark { background: #1e2633; border-color: #1e2633; color: #fff; }
.btn-dark:hover { background: #2b3546; border-color: #2b3546; color: #fff; }

/* ── Phones: 16px form text ───────────────────────────────────────────────
   iOS Safari zooms the whole page in whenever a focused field's text is under 16px, and does not
   zoom back out — on every tap into a field the layout jumped sideways. Gentelella's fields are
   13px, so on phone widths they are lifted to 16px (the size phones' own forms use anyway). */
@media (max-width: 767.98px) {
  input:not([type=checkbox]):not([type=radio]):not([type=range]),
  select,
  textarea,
  .form-control,
  .form-select,
  .select2-container .select2-selection,
  .select2-container .select2-search__field { font-size: 16px !important; }
}

/* ── 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;
}

/* Scroll cue for wide tables that are NOT DataTables (e.g. the Role Permissions matrix): phones show
   no scrollbar, so columns past the edge looked simply missing. A soft shadow appears on whichever
   side has more to scroll to. Pure CSS, the well-known "scroll shadows" technique: the two
   surface-coloured covers scroll WITH the content (background-attachment: local) and hide the
   shadows (which stay put with the box) whenever that edge is reached. A DataTables list collapses
   its columns instead, and the rule above already turns its scroll box off. */
.table-responsive:not(:has(> .dt-container)) {
  background:
    linear-gradient(to right, var(--bg-surface) 30%, transparent) left center / 2.5rem 100% no-repeat local,
    linear-gradient(to left,  var(--bg-surface) 30%, transparent) right center / 2.5rem 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,   rgba(16, 24, 40, .22), transparent) left center / 1rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(16, 24, 40, .22), transparent) right center / 1rem 100% no-repeat scroll;
}

/* ── 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;
}

/* ── Dropdown menus ────────────────────────────────────────────────────
   Gentelella ships no dropdown styles, but bootstrap.bundle.js (loaded by every layout) drives
   Bootstrap's dropdown markup: it toggles .show on .dropdown-menu and positions the menu with
   Popper. Without these rules the menu renders as an always-open bulleted list. Used by the
   grouped EntityAction menus (entity-actions.js). Colours come from the theme variables, so dark
   mode follows automatically. */
.btn-group { position: relative; vertical-align: middle; }

/* A dropdown toggle is the only .btn in its group — the menu <ul> after it is what makes it
   "not the last child" above — so give it back its normal rounded corners. */
.btn-group > .btn[data-bs-toggle="dropdown"] { border-radius: var(--radius-sm); }

.dropdown-toggle::after {
  content: "";
  display: inline-block;
  margin-left: .35em;
  border-top: .3em solid;
  border-right: .3em solid transparent;
  border-left: .3em solid transparent;
  vertical-align: .15em;
}

.dropdown-menu {
  display: none;
  position: absolute;
  z-index: 1050;
  min-width: 11rem;
  margin: 0;
  padding: var(--space-1) 0;
  list-style: none;
  text-align: left;
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px #1e263326;
}
.dropdown-menu.show { display: block; }

.dropdown-header {
  margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: 11px;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-muted);
  white-space: nowrap;
}

.dropdown-item {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 0;
  padding: 6px var(--space-3);
  border: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  text-align: left;
  color: var(--text);
  white-space: nowrap;
  cursor: pointer;
}
.dropdown-item:hover,
.dropdown-item:focus-visible { background: var(--bg-surface-secondary); color: var(--text); outline: none; }
.dropdown-item:disabled { color: var(--text-disabled); cursor: default; background: none; }

/* ── 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;
}

/* ── DataTables Responsive child row (the ▶ details under a row) ──────────
   The collapsed columns are listed as label/value pairs. Muted labels at a fixed width line the
   values up into a column, so the eye reads them like the record details page rather than as a
   run-on of bold and plain text. */
table.dataTable > tbody > tr.child ul.dtr-details { width: 100%; }
table.dataTable > tbody > tr.child ul.dtr-details > li { display: flex; gap: .75rem; align-items: baseline; }
table.dataTable > tbody > tr.child span.dtr-title {
  flex: 0 0 7.5rem;
  min-width: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
}
table.dataTable > tbody > tr.child span.dtr-data { flex: 1 1 auto; min-width: 0; }
/* DataTables hard-codes these two in light-theme colours (a #efefef rule between child-row items, a
   50%-black ▶). Theme tokens keep them right in dark mode too. The ▶ is a CSS triangle drawn with
   borders: its left border when closed, its top border (▼) when open. The div.dt-container prefix
   outranks DataTables' own rules, whose stylesheet loads after this one. */
table.dataTable > tbody > tr.child ul.dtr-details > li { border-bottom-color: var(--border-color); }
div.dt-container table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before { border-left-color: var(--text-muted); }
div.dt-container table.dataTable.dtr-inline.collapsed > tbody > tr.dtr-expanded > td.dtr-control:before { border-left-color: transparent; border-top-color: var(--text-muted); }
