/*
 * Density override — compacts the Vuexy template by role, not uniformly.
 * Load LAST in <head>, after core.css, theme-default.css, demo.css, and all vendor CSS.
 * No markup changes, no vendor/core file edits.
 *
 * SCOPE NOTE, so nobody is misled by the word "configuration":
 * only 8 of the 45 rules below are pure CSS-variable overrides. 6 more mix variables with a
 * font-size. The remaining 31 are DIRECT PROPERTY overrides, because Vuexy/Bootstrap 5.3 does
 * not expose a variable for what they change: .form-control padding, table cell padding,
 * .btn-icon's literal width/height square, .menu-link padding, .layout-navbar height, .avatar
 * sizing, .nav-pills padding, container padding, and the timeline point are all hardcoded
 * upstream. Roughly half of those 31 are not size changes at all but coupling repairs that the
 * size changes forced (caret clearances, form-check gutters, avatar-group overlap, the demo.css
 * navbar offset, RTL mirrors). Each one carries a comment saying what it fixes and what it
 * measured. It is still configuration in spirit — nothing here is decorative restyling — but it
 * is not the "short list of non-variable overrides" the brief imagined, and pretending otherwise
 * would hide real maintenance surface from whoever owns this next.
 *
 * Three tiers:
 *   LIGHT    — content you read (buttons, form fields, cards, tables, alerts, list content): ~15-25% tighter.
 *   MODERATE — repeated chrome you don't read word-for-word (icon buttons, nav, sidebar, navbar): ~25-55% tighter.
 *   ULTRA    — badges/pills/toggles/decorative dots, em-based: pushed hard.
 */

/* ============================== LIGHT TIER ============================== */

.btn {
  --bs-btn-padding-y: 0.45rem;
  --bs-btn-padding-x: 1rem;
  --bs-btn-font-size: 0.875rem;
}

/* The rule above is `.btn` (0,1,0) and loads AFTER core.css — which is exactly the specificity
   and order of core's own `.btn-lg` / `.btn-sm` / `.btn-xs` / `.btn-xl` variable blocks. A
   `.btn.btn-lg` therefore takes MY --bs-btn-padding-y instead of its own, and the whole size
   ladder collapses to one height. Measured before this block: .btn, .btn-xs and .btn-lg all
   rendered at exactly 32.16px. Each variant is restated below, scaled by the same ~0.75 padding
   / ~0.93 type factor as the default, so the ladder survives compaction instead of flattening.
   Ordering matters: these must follow the `.btn` rule above to win. */
.btn-xl,
.btn-group-xl > .btn {
  --bs-btn-padding-y: 0.656rem;
  --bs-btn-padding-x: 1.4rem;
  --bs-btn-font-size: 1.15rem;
}

.btn-lg,
.btn-group-lg > .btn {
  --bs-btn-padding-y: 0.63rem;
  --bs-btn-padding-x: 1.3rem;
  --bs-btn-font-size: 1rem;
}

.btn-sm,
.btn-group-sm > .btn {
  --bs-btn-padding-y: 0.31rem;
  --bs-btn-padding-x: 0.7rem;
  --bs-btn-font-size: 0.75rem;
}

.btn-xs,
.btn-group-xs > .btn {
  --bs-btn-padding-y: 0.13rem;
  --bs-btn-padding-x: 0.6rem;
  --bs-btn-font-size: 0.65rem;
}

/* line-height 1.24 is not arbitrary: it lands .form-control at 31.75px against .btn's 31.78px,
   satisfying the "buttons and inputs must resolve to the same height" constraint. Measured in
   the browser against a real button, not derived on paper. */
.form-control,
.form-select {
  padding: 0.4rem 0.75rem;
  font-size: 0.875rem;
  line-height: 1.24;
}

/* .form-select paints its dropdown caret as a 22px-wide background image at `right 0.875rem`,
   and core.css reserves room for it with padding-right: 2.45rem. The `padding` shorthand above
   would cut that to 0.75rem and let long option labels run underneath the caret. Restore the
   clearance (verified: text was overlapping the arrow by 24px before this rule). */
.form-select {
  padding-right: 2.35rem;
}

[dir=rtl] .form-select {
  padding-right: 0.75rem;
  padding-left: 2.35rem;
}

.input-group-text {
  padding: 0.4rem 0.75rem;
  font-size: 0.875rem;
  line-height: 1.24;
}

/* .form-control-sm/-lg and .form-select-sm/-lg are plain single-class selectors, same
   specificity as the base rule above, so — same ladder bug as .btn/.btn-icon/.avatar — they'd
   silently collapse toward the base size. form-control-sm looked fine only by coincidence: its
   own untouched `min-height` formula happens to floor below our compacted base height. form-
   control-lg is NOT so lucky — its min-height floor (which recalculates off the CURRENT,
   compacted font-size, not stock) measured 42px live, higher than intended and not a value
   anyone deliberately chose. Both min-heights now set explicitly so neither is accidental. */
.form-control-sm {
  padding: 0.3rem 0.6rem;
  font-size: 0.8125rem;
  min-height: calc(1.5em + 0.4rem + calc(var(--bs-border-width) * 2));
}

.form-control-lg {
  padding: 0.5rem 0.9rem;
  font-size: 1rem;
  min-height: calc(1.5em + 0.9rem + calc(var(--bs-border-width) * 2));
}

.form-select-sm {
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
  padding-left: 0.6rem;
  font-size: 0.8125rem;
}

.form-select-lg {
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 0.9rem;
  font-size: 1rem;
}

.card {
  --bs-card-spacer-y: 1.25rem;
  --bs-card-spacer-x: 1.25rem;
  --bs-card-title-spacer-y: 0.75rem;
  --bs-card-cap-padding-y: 0.75rem;
  --bs-card-cap-padding-x: 1.25rem;
}

.card p,
.card .card-text {
  font-size: 0.875rem;
  line-height: 1.4;
}

.table > :not(caption) > * > * {
  padding: 0.45rem 1rem;
  font-size: 0.875rem;
}

/* .table-sm> :not(caption)>*>* is equal specificity (0,2,0) to the rule above, and a
   `<table class="table table-sm">` matches BOTH — so table-sm silently collapsed to the exact
   same padding as a regular table (confirmed live: both measured 47.2px). Re-declared after the
   base rule so source order breaks the tie in table-sm's favor, scaled down proportionally to
   how stock Bootstrap treats it (roughly half the padding-y of the base table). */
.table-sm > :not(caption) > * > * {
  padding: 0.2rem 0.75rem;
  font-size: 0.8125rem;
}

.alert {
  --bs-alert-padding-y: 0.45rem;
  --bs-alert-padding-x: 0.7rem;
  font-size: 0.8125rem;
}

.accordion-body {
  --bs-accordion-body-padding-y: 0.55rem;
  --bs-accordion-body-padding-x: 0.8rem;
  font-size: 0.8125rem;
}

.list-group-item {
  --bs-list-group-item-padding-y: 0.4rem;
  --bs-list-group-item-padding-x: 0.9rem;
  font-size: 0.8125rem;
}

body {
  --bs-body-font-size: 0.875rem;
}

/* ============================== MODERATE TIER ============================== */

/* .btn-icon is a literal fixed width/height square in core.css, not padding-driven — direct
   override required. Core pairs every size tier with a matching font-size (see .btn-icon.btn-sm
   / .btn-icon.btn-lg upstream) because the icon glyph doesn't scale with the box on its own —
   `.ti` in tabler-icons.css sets `font-size: 1.25rem` DIRECTLY on the `<i>` element. That means
   a font-size set on the BUTTON never reaches the icon at all: an explicit rule on an element
   always wins over an inherited value, regardless of which has higher specificity or loads
   later. (First attempt at this fix set font-size on `.btn-icon.btn-xs` itself — verified in the
   browser that the icon glyph size didn't move a single pixel, which is what exposed this.) Every
   rule below therefore targets the icon element directly via a descendant combinator, matching
   `.ti`'s specificity class-for-class but winning on the extra descendant. */
.btn-icon {
  width: calc(1.5rem + calc(var(--bs-border-width) * 2));
  height: calc(1.5rem + calc(var(--bs-border-width) * 2));
}

.btn-icon > i,
.btn-icon > span {
  font-size: 0.9rem;
}

.btn-icon.btn-sm,
.btn-group-sm > .btn-icon.btn {
  width: calc(1.0625rem + calc(var(--bs-border-width) * 2));
  height: calc(1.0625rem + calc(var(--bs-border-width) * 2));
}

.btn-icon.btn-sm > i,
.btn-icon.btn-sm > span,
.btn-group-sm > .btn-icon.btn > i,
.btn-group-sm > .btn-icon.btn > span {
  font-size: 0.8125rem;
}

.btn-icon.btn-xl,
.btn-group-xl > .btn-icon.btn {
  width: calc(2.3rem + calc(var(--bs-border-width) * 2));
  height: calc(2.3rem + calc(var(--bs-border-width) * 2));
}

.btn-icon.btn-xl > i,
.btn-icon.btn-xl > span,
.btn-group-xl > .btn-icon.btn > i,
.btn-group-xl > .btn-icon.btn > span {
  font-size: 1.1rem;
}

.btn-icon.btn-lg,
.btn-group-lg > .btn-icon.btn {
  width: calc(2.09rem + calc(var(--bs-border-width) * 2));
  height: calc(2.09rem + calc(var(--bs-border-width) * 2));
}

.btn-icon.btn-lg > i,
.btn-icon.btn-lg > span,
.btn-group-lg > .btn-icon.btn > i,
.btn-group-lg > .btn-icon.btn > span {
  font-size: 1rem;
}

/* .btn-icon.btn-xs is NOT scaled by the same ~0.665 ratio as the other tiers. At that ratio the
   box lands at ~11px, which cannot hold a legible icon glyph at any font-size — the same floor
   this session already hit once with the toggle switch. Held near its STOCK size instead
   (15.89px box / 11.04px icon) since xs was already close to the practical minimum for a
   recognizable icon before any of this compaction started. */
.btn-icon.btn-xs,
.btn-group-xs > .btn-icon.btn {
  width: calc(0.85rem + calc(var(--bs-border-width) * 2));
  height: calc(0.85rem + calc(var(--bs-border-width) * 2));
}

.btn-icon.btn-xs > i,
.btn-icon.btn-xs > span,
.btn-group-xs > .btn-icon.btn > i,
.btn-group-xs > .btn-icon.btn > span {
  font-size: 0.69rem;
}

.pagination .page-link {
  --bs-pagination-padding-y: 0.2rem;
  --bs-pagination-padding-x: 0.5rem;
  --bs-pagination-font-size: 0.8125rem;
  line-height: 1.2;
}

/* Two real bugs found auditing this, not one:
   1) .pagination-sm/.pagination-lg set --bs-pagination-* on the ANCESTOR <ul>, but the rule
      above sets the same variables directly on .page-link (matching `.pagination .page-link`,
      which matches sm/lg too since they still carry the base .pagination class). A direct
      declaration on an element always wins over an inherited one — confirmed live: numbered
      items in pagination-sm AND pagination-lg both measured the exact same 22px as the base
      tier. Fixed by re-declaring the variables for sm/lg specifically, after the rule above so
      source order breaks the specificity tie in their favor.
   2) The Prev/Next/First/Last arrow buttons use a SEPARATE, higher-specificity selector
      (.page-item.first/.last/.next/.prev/.previous .page-link, 3 classes) with literal
      padding-top/bottom that ignores the variables entirely — at every one of the three size
      tiers. Confirmed live: in one base-size pagination row, numbered items measured 22px while
      the Prev/Next/First/Last buttons measured 37.9px in the SAME row — a visibly broken,
      misaligned pagination bar. Matched below for all three tiers. */
.pagination-sm .page-link {
  --bs-pagination-padding-y: 0.15rem;
  --bs-pagination-padding-x: 0.4rem;
  --bs-pagination-font-size: 0.75rem;
  line-height: 1.2;
}

.pagination-lg .page-link {
  --bs-pagination-padding-y: 0.3rem;
  --bs-pagination-padding-x: 0.6rem;
  --bs-pagination-font-size: 0.875rem;
  line-height: 1.2;
}

.page-item.first .page-link,
.page-item.last .page-link,
.page-item.next .page-link,
.page-item.prev .page-link,
.page-item.previous .page-link {
  padding-top: 0.2rem;
  padding-bottom: 0.2rem;
}

.pagination-sm > .page-item.first .page-link,
.pagination-sm > .page-item.last .page-link,
.pagination-sm > .page-item.next .page-link,
.pagination-sm > .page-item.prev .page-link,
.pagination-sm > .page-item.previous .page-link {
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
}

.pagination-lg > .page-item.first .page-link,
.pagination-lg > .page-item.last .page-link,
.pagination-lg > .page-item.next .page-link,
.pagination-lg > .page-item.prev .page-link,
.pagination-lg > .page-item.previous .page-link {
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
}

.menu-vertical .menu-item .menu-link {
  padding: 0.3rem 0.7rem;
  font-size: 0.8125rem;
}

/* .menu-vertical .menu-sub .menu-link (3 classes) is the SAME specificity (0,3,0) as the
   shorthand rule above (also 3 classes: .menu-vertical, .menu-item, .menu-link) — every submenu
   link matches both selectors, since a submenu <li class="menu-item"> always lives inside a
   <ul class="menu-sub">. The `padding` shorthand loading later silently wiped out core's
   `padding-left: 2.875rem` indent, collapsing every submenu label back to the sidebar's left
   edge — visually reading as the label sitting on top of / under the parent item's icon column
   (confirmed live: submenu text left edge matched the icon's left edge instead of sitting to its
   right). Re-assert the indent after the rule above so source order breaks the tie back in its
   favor. Value unchanged from core — this is a layout offset, not a density concern. */
.menu-vertical .menu-sub .menu-link {
  padding-left: 2.875rem;
}

[dir=rtl] .menu-vertical .menu-sub .menu-link {
  padding-right: 2.875rem;
  padding-left: 1rem;
}

/* Submenu parents carry BOTH .menu-link and .menu-toggle, and the toggle caret is painted
   absolutely at `right: 1rem`. Core reserves room via
   `.menu-vertical .menu-item .menu-toggle { padding-right: calc(1rem + 1.26em) }` — same
   specificity as the rule above, so the shorthand loading later silently wiped that clearance
   and the label ran under the caret (measured: 21.2px of overlap). Re-assert clearance against
   the new 0.7rem gutter and pull the caret in to match. */
.menu-vertical .menu-item .menu-toggle {
  padding-right: calc(0.7rem + 1.26em);
}

.menu-vertical .menu-item .menu-toggle::after {
  right: 0.7rem;
}

[dir=rtl] .menu-vertical .menu-item .menu-toggle {
  padding-right: 0.7rem;
  padding-left: calc(0.7rem + 1.26em);
}

[dir=rtl] .menu-vertical .menu-item .menu-toggle::after {
  right: auto;
  left: 0.7rem;
}

.layout-navbar {
  height: 2.75rem;
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
}

.container-p-y {
  padding-top: 0.75rem !important;
  padding-bottom: 0.75rem !important;
}

@media (min-width: 992px) {
  .container,
  .container-fluid,
  .container-sm,
  .container-md,
  .container-lg,
  .container-xl,
  .container-xxl {
    padding-right: 0.75rem;
    padding-left: 0.75rem;
  }
}

.dropdown-menu {
  --bs-dropdown-padding-y: 0.3rem;
  --bs-dropdown-font-size: 0.8125rem;
}

.dropdown-item {
  --bs-dropdown-item-padding-y: 0.25rem;
  --bs-dropdown-item-padding-x: 0.75rem;
}

.accordion-button {
  --bs-accordion-btn-padding-y: 0.45rem;
  --bs-accordion-btn-padding-x: 0.7rem;
  font-size: 0.8125rem;
}

.breadcrumb {
  --bs-breadcrumb-item-padding-x: 0.5rem;
}

.breadcrumb-item {
  font-size: 0.8125rem;
}

.nav-tabs .nav-link,
.nav-pills .nav-link {
  --bs-nav-link-padding-y: 0.3rem;
  --bs-nav-link-padding-x: 0.75rem;
  font-size: 0.8125rem;
}

/* .nav.nav-pills .nav-link in core.css sets padding-top/bottom as literal properties,
   bypassing --bs-nav-link-padding-y entirely — needs a direct match, not just the variable. */
.nav.nav-pills .nav-link {
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}

.avatar {
  width: 1.7rem;
  height: 1.7rem;
}

/* .avatar-xs/-sm/-md/-lg/-xl are ALL plain single-class selectors, same specificity (0,1,0) as
   the base .avatar rule above. Before this fix, only .avatar and .avatar-sm had a matching
   override — xs/md/lg/xl fell through to nothing of their own, and since the base .avatar rule
   above has equal specificity and loads later, it silently won for every one of them. Confirmed
   live on extended-ui-avatar.html: xs, md, lg, and xl all measured the exact same 27.2px as the
   base tier — a full size ladder collapsed to one size, same bug class as the .btn/.btn-icon
   ladders found earlier. Each tier restored below at roughly the same ~0.72 compaction ratio as
   the base avatar, including its own .avatar-initial font-size and status-dot size, which are
   ALSO untouched per-tier rules that would otherwise stay stock-sized next to a compacted circle. */
.avatar-xs {
  width: 1.17rem;
  height: 1.17rem;
}

.avatar-xs .avatar-initial {
  font-size: 0.45rem;
}

.avatar-xs.avatar-online:after,
.avatar-xs.avatar-offline:after,
.avatar-xs.avatar-away:after,
.avatar-xs.avatar-busy:after {
  width: 0.23rem;
  height: 0.23rem;
}

.avatar-sm {
  width: 1.5rem;
  height: 1.5rem;
}

.avatar-md {
  width: 2.16rem;
  height: 2.16rem;
}

.avatar-md .avatar-initial {
  font-size: 0.81rem;
}

.avatar-md.avatar-online:after,
.avatar-md.avatar-offline:after,
.avatar-md.avatar-away:after,
.avatar-md.avatar-busy:after {
  width: 0.43rem;
  height: 0.43rem;
}

.avatar-lg {
  width: 2.88rem;
  height: 2.88rem;
}

.avatar-lg .avatar-initial {
  font-size: 1.08rem;
}

.avatar-lg.avatar-online:after,
.avatar-lg.avatar-offline:after,
.avatar-lg.avatar-away:after,
.avatar-lg.avatar-busy:after {
  width: 0.58rem;
  height: 0.58rem;
}

.avatar-xl {
  width: 3.24rem;
  height: 3.24rem;
}

.avatar-xl .avatar-initial {
  font-size: 1.35rem;
}

.avatar-xl.avatar-online:after,
.avatar-xl.avatar-offline:after,
.avatar-xl.avatar-away:after,
.avatar-xl.avatar-busy:after {
  width: 0.65rem;
  height: 0.65rem;
}

/* Stacked-avatar overlap is a fixed rem offset tuned for the stock 2.375rem / 2rem circles.
   Against the smaller circles above, the same offset hides ~47-50% of each face instead of
   ~34-37%. Rescaled to preserve the original overlap ratio.
   (.avatar-group .avatar:first-child { margin-left: 0 } in core is more specific and still wins.) */
.avatar-group .avatar {
  margin-left: -0.57rem;
}

.avatar-group .avatar-sm {
  margin-left: -0.56rem;
}

/* Same overlap-ratio coupling as .avatar-group .avatar above, now applied to the xs/md/lg/xl
   tiers being fixed for the first time in this pass — each rescaled to preserve its own original
   overlap ratio (e.g. xl was -1.75rem over a 4.5rem circle = 38.9%; kept at 38.9% of the new
   3.24rem circle) rather than reusing the base avatar's ratio, since stock Vuexy already varies
   this ratio per tier (30-41%) and there's no reason to flatten that here. */
.avatar-group .avatar-xs {
  margin-left: -0.47rem;
}

.avatar-group .avatar-md {
  margin-left: -0.65rem;
}

.avatar-group .avatar-lg {
  margin-left: -1.08rem;
}

.avatar-group .avatar-xl {
  margin-left: -1.26rem;
}

.progress {
  --bs-progress-height: 0.5rem;
  --bs-progress-font-size: 0.65rem;
}

/* demo.css hardcodes a navbar-offset fallback (64px/78px) tuned for the stock 62px navbar.
   The JS in helpers.js recalculates this at runtime and wins, but these are the pre-JS values —
   recomputed proportionally for the new 44px navbar to avoid a layout flash on load. */
.layout-navbar-fixed .layout-wrapper:not(.layout-without-menu) .layout-page {
  padding-top: 46px !important;
}

.layout-navbar-fixed .layout-wrapper:not(.layout-horizontal):not(.layout-without-menu) .layout-page {
  padding-top: 60px !important;
}

/* ============================== ULTRA TIER ============================== */

.badge {
  --bs-badge-padding-y: 0.18em;
  --bs-badge-padding-x: 0.35em;
  --bs-badge-font-size: 0.7em;
}

/* Shrinking the control alone strands its label. Core reserves the gutter on the WRAPPER
   (.form-check padding-left 1.7em, .form-switch 2.5em) with a matching negative margin on the
   input — both sized for the stock 1.2em box / 2em switch. Left alone, the control-to-label gap
   grew from 7.5px to 10.5px (checkbox) and 14px (switch): visibly looser, the opposite of the
   goal. Re-tighten both gutters to preserve the stock ~0.5em gap.
   Order matters below — .form-switch rules must follow .form-check rules (equal specificity,
   and a switch matches both). */
.form-check-input {
  width: 0.95em;
  height: 0.95em;
}

.form-check {
  padding-left: 1.45em;
}

.form-check .form-check-input {
  margin-left: -1.45em;
}

.form-switch {
  padding-left: 2em;
}

.form-switch .form-check-input {
  width: 1.5em;
  margin-left: -2em;
}

/* core.css scopes this to .timeline .timeline-item .timeline-point (3 classes) —
   matching the same ancestor chain, not just .timeline-point, so this actually wins. */
.timeline .timeline-item .timeline-point {
  height: 0.5rem;
  width: 0.5rem;
}

/* ============================== VENDOR-SPECIFIC FIXES ============================== */

/* DataTables' own CSS sets literal padding + a min-width on its pagination links via
   a much higher-specificity selector than plain .pagination .page-link, so the Moderate-tier
   pagination override above is silently ignored inside any DataTables-driven table unless
   matched here. Confirmed via live measurement on tables-datatables-basic.html (was ~37px,
   stock size, despite the general pagination override being active on the same page). */
div.dataTables_wrapper div.dataTables_paginate ul.pagination .page-link {
  padding: 0.2rem 0.5rem;
  min-width: calc(1.0625rem + 0px);
  font-size: 0.8125rem;
  line-height: 1.2;
}

/* select2's own CSS hardcodes its selection box height with the SAME formula Bootstrap uses for
   stock (uncompacted) form-controls: height: calc(1.5em + 0.844rem + border*2). That formula
   references body font-size (which does track our compaction, 15px -> 14px) but the 0.844rem
   padding term is a literal constant select2 ships, never tied to our --bs-btn/.form-control
   overrides at all. Result measured live on forms-selects.html: select2 boxes render at 36.5px
   while a plain .form-control on the same page is 32.6px — a visible height mismatch in any row
   that mixes a real input with a select2 dropdown. Matched to the same specificity
   (.light-style .select2-container--default ...) so source order (this file loads last) wins. */
.light-style .select2-container--default .select2-selection--single {
  height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

.light-style .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

.light-style .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: calc(1.5em + 0.625rem);
  padding-left: 0.75rem;
}

.light-style .select2-container--default .select2-selection--multiple {
  min-height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

/* select2.css repeats the exact same stock-height formula a second time under a `.dark-style`
   prefix for dark-mode color theming. The light-mode fix above does nothing once dark mode is
   toggled (Vuexy swaps the html class to dark-style, not just a CSS variable) — same rules,
   dark-mode selector, so the sizing fix isn't silently lost when the user switches themes. */
.dark-style .select2-container--default .select2-selection--single {
  height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

.dark-style .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

.dark-style .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: calc(1.5em + 0.625rem);
  padding-left: 0.75rem;
}

.dark-style .select2-container--default .select2-selection--multiple {
  min-height: calc(1.5em + 0.625rem + calc(var(--bs-border-width) * 2));
}

/* The min-height fixes above are a floor — actual height in multi-select mode is really driven
   by the tag chips inside (Ultra-tier candidate, same role as a Bootstrap badge). Their own
   padding/margins are still stock, so with 2+ chips the box was measured at 37.6px despite the
   33px floor above. Compacted like the other Ultra-tier chips in this file. */
.light-style .select2-selection--multiple .select2-selection__rendered,
.dark-style .select2-selection--multiple .select2-selection__rendered {
  padding: 0 0.25rem 0.2rem 0.25rem;
}

.light-style .select2-selection--multiple .select2-selection__choice,
.dark-style .select2-selection--multiple .select2-selection__choice {
  margin-right: 0.2rem;
  margin-top: 0.2rem;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
  padding: 0.2rem 0.4rem;
  font-size: 0.75rem;
}

/* The chip's "x" remove glyph is absolutely positioned with a fixed font-size (1.1875rem) and
   top offset (0.25rem) tuned for the STOCK chip height. Shrinking the chip above without this
   left the x overflowing past the chip's own bottom edge (measured: bottom edge 3.7px past the
   chip). Re-centered for the new ~17px chip height. */
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
  font-size: 0.8rem;
  top: 0.05rem;
}

/* Tagify is a different failure mode than DataTables/select2 above: it's not that no override
   existed, it's that `.tagify.form-control` (2 classes) is MORE specific than the plain
   `.form-control` rule in the Light tier, so tagify's own padding/font-size/line-height won
   regardless of load order — confirmed live on forms-selects.html, where the tagify field
   measured 37.6px while a genuinely plain .form-control on another page measures 32.6px.
   tagify__input and tagify__tag > div use a literal `line-height: 1.5rem` (not em-based, so it
   never tracked the font-size cut on its own) — that's the main height driver, reduced here
   proportionally with the rest of the light-tier compaction. */
.tagify.form-control {
  padding: 0 0.3rem 0.3rem 0.4rem;
  font-size: 0.75rem;
}

.tagify__tag > div {
  line-height: 1.2rem;
  padding: 0 0 0 0.5rem;
}

.tagify__input {
  line-height: 1.2rem;
}

/* bootstrap-select's toggle button DOES correctly track the font-size compaction (it's a plain
   .btn.dropdown-toggle, no specificity fight) — but its inner `.filter-option-inner-inner` sets
   its own `line-height: 1.5` (a unitless multiplier of ITS font-size, not tied to our
   --bs-btn-line-height variable at all). At the compacted 14px font that's 21px of content height
   versus a plain button's 15.75px (14 * our 1.125 --bs-btn-line-height), so bootstrap-select
   measured 36.1px next to a plain button's 31.78px — a real, if smaller, mismatch than the
   select2/tagify cases. Matched to the same 1.125 ratio used everywhere else in the Light tier. */
.bootstrap-select .dropdown-toggle .filter-option-inner-inner {
  line-height: 1.125;
}

/* app-invoice-print.css locks the whole .invoice-print container to a fixed 15px font via
   !important — a deliberate design choice (a printed invoice shouldn't shrink just because the
   on-screen dashboard density changed). That protection only reaches font-size set directly ON
   .invoice-print; it does NOT stop our .table > :not(caption) > * > * rule from directly
   targeting the invoice's own line-items table, since a direct rule on a descendant always wins
   over a parent's inherited value regardless of !important on the parent. Confirmed by injecting
   the real page markup: the top summary table correctly stayed at 15px, but the line-items table
   (the actual invoice content) measured 14px with compacted padding — two different text sizes
   on one printed page. Restored to the page's own intended stock values here. */
.invoice-print .table > :not(caption) > * > * {
  padding: 0.55rem 1.25rem;
  font-size: 15px;
}

/* The navbar search suggestion dropdown (typeahead.js) functions exactly like a Bootstrap
   .dropdown-menu but is a completely separate vendor component with its own hardcoded stock
   sizing (font-size: 0.9375rem, item padding: 0.42rem 1rem) — untouched by the .dropdown-menu /
   .dropdown-item fixes above, and present on all 146 pages via the shared navbar. Matched to the
   same values used for regular dropdowns for consistency. Both light and dark theme variants
   fixed, same reasoning as the select2 dark-mode gap found earlier. */
.light-style .twitter-typeahead .tt-menu,
.dark-style .twitter-typeahead .tt-menu {
  padding: 0.3rem 0;
  font-size: 0.8125rem;
}

.light-style .twitter-typeahead .tt-suggestion,
.dark-style .twitter-typeahead .tt-suggestion {
  padding: 0.25rem 0.75rem;
}
