/**Styles for virtual select */
/* vendor sets sans-serif (select) / Lato (toast). drew off-brand font. inherit
   page font. body prefix wins any sheet order. */
body .vscomp-wrapper,
body .iziToast,
body .iziToast-rtl {
  font-family: inherit;
}

.vscomp-ele {
  max-width: 100% !important;
}

/*
Reduce month selector font
 */
.flatpickr-current-month {
  font-size: 22px !important;
  padding-bottom: 5px !important;
}
.dataTables_length {
  margin-top: 1.5%;
  margin-bottom: 1.5%;
}
/* role-perm + user-role pickers (_pick_panes.pug). list fill screen.
   offset = chrome above list. */
.perm-panes {
  max-width: 60rem;
}
.perm-list {
  --perm-list-offset: 24rem;
  max-height: 12.5rem; /* fallback. no max()/dvh */
  max-height: max(12.5rem, calc(100vh - var(--perm-list-offset)));
  max-height: max(12.5rem, calc(100dvh - var(--perm-list-offset)));
  overflow-y: auto;
}

/*.filepond--action-process-item{*/
/*  visibility:hidden;*/
/*}*/

.dt-buttons {
  display: inline-block;
  width: 15px;
}

.vscomp-wrapper.has-clear-button .vscomp-toggle-button {
  height: 48px;
}

/* -- Sidebar/topbar compositing isolation --------------------------------- */
/* iziToast animates capsule height (layout-triggering) on dismiss, which
   causes a reflow that briefly misplaces fixed-position elements. Promoting
   these two navbars to their own GPU layers isolates them from that reflow. */
.navbar-vertical,
.navbar-top {
  will-change: transform;
}

/* iziToast-body's children (.iziToast-texts, .iziToast-buttons) are floated
   with no clearfix, so the body never grows for a wrapped multi-line message
   -- title and buttons render outside the card's visible bounds. Clearfix
   restores normal box height for any message longer than one line. */
.iziToast-body::after {
  content: '';
  display: block;
  clear: both;
}

/* Every iziToast.question()/toast() call in this app hardcodes zindex:999
   (well below .navbar-vertical's 1060 / .navbar-top's 1020). With
   position:'center' the toast spans the full page width, so its left
   portion (icon/title/message start) renders underneath the fixed sidebar.
   Force the wrapper above all fixed chrome regardless of any per-call
   zindex option, so every dialog in the app is fixed at once. */
.iziToast-wrapper {
  z-index: 10000 !important;
}

/* toast sizes to its text: long message ran edge to edge (988 of 1033px
   centred; full width in the corner, covering the topbar). cap it inside the
   wrapper (genie_util.js fits the centre wrapper to the main display). wrapper
   text-align places a capped toast left/centre/right. a call's own maxWidth is
   inline and still wins. */
.iziToast-wrapper .iziToast {
  max-width: min(520px, calc(100% - 2rem));
}
/* long corner-toast message scrolls inside the card, not off the screen.
   centred confirm dialogs keep their own height. */
.iziToast-wrapper:not(.iziToast-wrapper-center)
  .iziToast
  > .iziToast-body
  .iziToast-message {
  max-height: 40vh;
  overflow-y: auto;
  overflow-wrap: anywhere;
}

/* toast look (vendor = loud pastel slabs, black PNG icons). white card, thin
   tinted edge, coloured accent bar. --izt = accent per colour.
   [class] bumps specificity over vendor .iziToast.iziToast-color-*. */
body .iziToast[class] {
  --izt: #6e7891;
  background: #fff;
  border: 1px solid var(--au-glass-line, #e4e8ee);
  border-left: 4px solid var(--izt);
  border-radius: 12px;
  box-shadow:
    0 1px 2px rgba(27, 30, 51, 0.06),
    0 12px 28px -10px rgba(27, 30, 51, 0.28);
  color: #1b2430;
}
body .iziToast.iziToast-color-green {
  --izt: #1f9d55;
}
body .iziToast.iziToast-color-red {
  --izt: #c4382a;
}
body .iziToast.iziToast-color-yellow,
body .iziToast.iziToast-color-orange {
  --izt: #d6700a;
}
body .iziToast.iziToast-color-blue {
  --izt: #2a6fdb;
}
body .iziToast > .iziToast-body .iziToast-title {
  color: #1b2430;
  font-weight: 700;
}
body .iziToast > .iziToast-body .iziToast-message {
  color: #5b6675;
}
body .iziToast > .iziToast-progressbar {
  background: transparent;
}
body .iziToast > .iziToast-progressbar > div {
  background: var(--izt);
  opacity: 0.55;
}
/* confirm buttons: display font + softer corners */
body .iziToast .iziToast-buttons > button {
  font-family: var(--rc-font-display);
  border-radius: 8px;
}
/* phone: confirm buttons get 44px touch floor */
@media (max-width: 575.98px) {
  body .iziToast .iziToast-buttons > button {
    min-height: 44px;
    min-width: 72px;
  }
}

/* -- Org Context Switcher ------------------------------------------------- */
.navbar-vertical .navbar-vertical-content {
  padding-top: 0 !important;
}

.org-switcher-wrapper {
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  margin-bottom: 0.5rem;
}
.org-switcher-btn {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.5rem;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.45rem 0.75rem;
  transition: background 0.15s;
}
.org-switcher-btn:hover,
.org-switcher-btn:focus {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  box-shadow: none;
}
.org-switcher-btn::after {
  display: none;
}
.org-switcher-name {
  max-width: 130px;
}
.org-switcher-item {
  font-size: 0.82rem;
}
.view-as-member-link {
  margin-top: 0.25rem;
  text-decoration: none;
}
.view-as-member-link:hover {
  color: #fff !important;
}

/* Shared dashboard widgets (#1100) -- KPI row + donut, used by the admin
   command center and the member hub's story digest. */
/* #2086 -- .cc-metric-value marked every dashboard big-number/heading but
   carried no rule of its own -- every card relied on someone also adding
   .text-nowrap/.text-truncate by hand, and 2 real spots (Member growth,
   Dividend distribution) never got it, so a long value there could wrap
   and break the card instead of eliding. Baked directly into the class
   so every current AND future .cc-metric-value gets it automatically. */
.cc-metric-value {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* #2086 -- the "At a glance" row's cards are narrower than the main grid
   cards fs-1 (20px) was sized for -- measured live: "KES 67,000.00" needs
   135px, the card only has 122px to give it. Real shrink, not a fallback:
   17px (~15% down) clears every current value with margin to spare,
   .text-truncate/ellipsis on .cc-metric-value stays as the safety net for
   whatever's still too long after that (a much bigger balance, say). */
.cc-metric-value.cc-metric-value-compact {
  font-size: 1rem;
}
/* #2086 -- kpiRow's 5 tiles at equal-width flex-nowrap columns (fixes
   the wrap-vs-static-height problem) has its own floor: measured live
   at 375px, 5-way split left ~64px/tile, ~22px for the actual value
   after label+padding -- "KES 0.00" needs 82px, nothing left to shrink.
   min-width floor + overflow-x on the row: above the floor, unchanged
   (tiles share the row equally); below it, the row scrolls
   horizontally instead of cramming a currency value into an
   unreadable few pixels. */
.cc-kpi-row {
  overflow-x: auto;
}
.cc-kpi-col {
  min-width: 130px;
}
.dashboard-donut-arc {
  stroke: currentColor;
  transform-origin: center;
}
.dashboard-donut-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

/* Command Center customize mode (#1108). */
/* #2086 -- explicit height:100% + GridStack's own top/bottom absolute
   positioning collapses the vertical gap between rows to 0 (explicit
   height wins over bottom inset, CSS2.1 10.6.4). drop it -- GridStack
   already sizes this element via its own inline top/bottom/height, this
   rule only ever fought that. */
.grid-stack-item-content {
  position: relative;
  overflow: auto;
}
.cc-widget-remove {
  display: none;
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 5;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--phoenix-danger, #dc3545);
  background: #fff;
  color: var(--phoenix-danger, #dc3545);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
#cc-grid.cc-editing .grid-stack-item-content,
#member-grid.cc-editing .grid-stack-item-content {
  outline: 2px dashed var(--phoenix-primary, #0d6efd);
  outline-offset: 2px;
}
#cc-grid.cc-editing .cc-widget-remove,
#member-grid.cc-editing .cc-widget-remove {
  display: flex;
  align-items: center;
  justify-content: center;
}
.cc-add-widget-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  background: var(--phoenix-gray-100, #f8f9fa);
  border-radius: 6px;
  font-size: 0.85rem;
}

/* #2086 -- eye-candy pass (wayfinder map #2084, resolved via /prototype
   variant F "Unified Deck"). every dashboard card gets the same rounded/
   shadow treatment and a small colored category badge in its header --
   this is the "consistent card system" the prototype variant F answered
   with, folded into the real GridStack grid so drag/resize/remove/re-add
   customization (map's hard requirement) stays fully intact -- only the
   card content's visual treatment changed, not the grid mechanics. */
.cc-card {
  border: 0;
  border-radius: 0.75rem;
  box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.05);
}
.cc-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-size: 0.85rem;
  flex-shrink: 0;
}
.cc-cat-money {
  background: rgba(var(--phoenix-success-rgb, 0, 210, 122), 0.12);
  color: var(--phoenix-success, #00d27a);
}
.cc-cat-people {
  background: rgba(var(--phoenix-info-rgb, 39, 128, 227), 0.12);
  color: var(--phoenix-info, #2780e3);
}
.cc-cat-pools {
  background: rgba(137, 101, 224, 0.12);
  color: #8965e0;
}
.cc-cat-overview {
  background: rgba(var(--phoenix-warning-rgb, 245, 128, 62), 0.12);
  color: var(--phoenix-warning, #f5803e);
}
/* #2086 -- Portfolio drilldown (command-center-widget.js's renderDrilldown)
   table header sat right under the tab nav with no breathing room --
   the tabs deliberately touch the card (see that file's own comment on
   card-header-tabs' -24px margin), but the header text itself still
   needs its own padding, independent of that. */
.cc-drilldown-head th {
  padding-top: 0.75rem;
}
/* #2086 -- card-body is deliberately p-0 (tabs need to bleed flush to
   the card edge, see this widget's own comment above), which left the
   table's cells with only table-sm's default ~0.3rem x-padding -- every
   column crowded the card edge and each other on every tab (loans,
   shares, investments), not just the header row. */
.cc-drilldown-table th,
.cc-drilldown-table td {
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.org-switcher-item.active {
  background: rgba(var(--bs-primary-rgb), 0.12);
  color: var(--bs-primary);
  font-weight: 600;
  pointer-events: none;
}

/* -- Select Organization page --------------------------------------------- */
.org-card {
  cursor: pointer;
  border: 2px solid transparent;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}
.org-card:hover {
  border-color: var(--bs-primary);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
.org-card.active-org {
  border-color: var(--bs-success);
}

/* -- Table Action Buttons (v-hover) ------------------------------------------------- */
/* Make action buttons always visible */
table tbody tr .v-hover {
  visibility: visible;
  opacity: 1;
}
/* 24px svg in 18px inline link sat ~1px low, demo ring looked off. */
table tbody tr a.approve-btn svg,
table tbody tr a.reject-btn svg {
  vertical-align: middle;
}

/* #1629 -- filepond preview inside .avatar circle (profile page).
   plugin fit-scales canvas when imagePreviewHeight mismatch frame ->
   dark side bands + off-center photo + overlay gradient arc. force
   every preview layer to fill frame, cover-crop bitmap, kill overlay. */
.avatar .filepond--image-preview-wrapper {
  border-radius: 50%;
  overflow: hidden;
}
.avatar .filepond--image-clip,
.avatar .filepond--image-preview,
.avatar .filepond--image-canvas-wrapper,
.avatar .filepond--image-bitmap {
  position: absolute !important;
  inset: 0 !important;
  width: auto !important;
  height: auto !important;
  margin: 0 !important;
  transform: none !important;
}
.avatar .filepond--image-bitmap canvas,
.avatar .filepond--image-preview canvas {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
}
.avatar .filepond--image-preview-overlay {
  display: none !important;
}

/* #1629 pt3 -- saved-avatar img overlays pond. .avatar-5xl scope: topbar avatars share .profile_pic class, must not absolutize. */
.avatar-5xl .profile_pic {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: 50%;
  z-index: 3;
  cursor: pointer;
}

/* -- Subtle alert/badge variants (#1922), theme-completion patch --------
   ui-styling.md docs alert-subtle/badge-subtle, 6 pug files use them, but
   never shipped in theme.min.css. every "subtle" banner/badge silently
   had zero bg/border. overrides same --phoenix-alert-* props .alert base
   rule reads -- box model stays theme.min.css's, only color changes.
   .badge has no such hook, sets bg/color direct.
   note: theme.min.css also ships .alert-soft-* (same --phoenix-alert-*
   props, own hand-tuned hex, no badge equiv). kept subtle-* separate --
   distinct bg/border tint matches doc's ask closer than soft's flat
   single-color. if theme upgrade ever ships real alert-subtle-*, delete
   this block instead of letting it silently shadow the vendor's. */
.alert-subtle-primary {
  --phoenix-alert-bg: rgba(var(--phoenix-primary-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-primary-rgb), 0.35);
  --phoenix-alert-color: inherit;
}
.alert-subtle-secondary {
  --phoenix-alert-bg: rgba(var(--phoenix-secondary-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-secondary-rgb), 0.35);
  --phoenix-alert-color: inherit;
}
.alert-subtle-success {
  --phoenix-alert-bg: rgba(var(--phoenix-success-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-success-rgb), 0.35);
  --phoenix-alert-color: inherit;
}
.alert-subtle-info {
  --phoenix-alert-bg: rgba(var(--phoenix-info-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-info-rgb), 0.35);
  --phoenix-alert-color: inherit;
}
.alert-subtle-warning {
  --phoenix-alert-bg: rgba(var(--phoenix-warning-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-warning-rgb), 0.35);
  --phoenix-alert-color: inherit;
}
.alert-subtle-danger {
  --phoenix-alert-bg: rgba(var(--phoenix-danger-rgb), 0.12);
  --phoenix-alert-border-color: rgba(var(--phoenix-danger-rgb), 0.35);
  --phoenix-alert-color: inherit;
}

.badge-subtle-primary {
  background-color: rgba(var(--phoenix-primary-rgb), 0.12);
  color: var(--phoenix-primary);
  /* #3079: raw token text 2.5-3.6:1 on tint. darken, keep hue, >= 4.5:1 */
  color: color-mix(in srgb, var(--phoenix-primary) 80%, #000);
}
/* Warm accent, reserved for calling out a genuine recommendation --
   not a second brand color, see the landing page's Market Ledger palette. */
:root {
  --rc-terracotta: #c1592c;
  --rc-terracotta-rgb: 193, 89, 44;
  --rc-terracotta-dark: #9c4520;
  /* btn text is phoenix's --phoenix-btn-font-size (0.8rem/12.8px) bold --
     too small for wcag's large-text 3:1 exception, needs full 4.5:1.
     raw --rc-terracotta vs #fffcf4 text only hits 4.33:1 (code-review
     finding). this shade clears 4.5:1 w/ margin (4.80:1). badge still
     uses --rc-terracotta unchanged -- diff contrast profile (dark text
     on a light 12%-alpha backdrop), not affected. */
  --rc-terracotta-btn: #b55429;
  --rc-cream-faint: #fbf8f3;
}
.badge-subtle-terracotta {
  background-color: rgba(var(--rc-terracotta-rgb), 0.12);
  color: var(--rc-terracotta);
}
/* topbar tint: tried full --rc-cream (#f6efe0, landing page's --lm-paper)
   first, too yellow next to dashboard's plain-white body. this shade
   deliberately close to white, not a bug. body stays phoenix's own
   --phoenix-body-bg, full-page cream wash tried live + rejected same
   reason. */
.navbar-top {
  --phoenix-navbar-top-bg-color: var(--rc-cream-faint);
}
/* .btn-dark unused elsewhere in app -- repurposed as "one important
   action on this screen" CTA marker vs adding a new class.
   phoenix's theme.min.css gives .btn-dark its own --phoenix-btn-* set,
   ignores bootstrap's --bs-btn-* entirely (verified live, ghost button
   by default). override --phoenix-btn-* + raw props directly, only
   --phoenix-btn-* -- every page rendering these buttons loads
   theme.min.css via header.pug, --bs-btn-* would be dead code here. */
.btn-dark {
  --phoenix-btn-bg: var(--rc-terracotta-btn);
  --phoenix-btn-color: #fffcf4;
  --phoenix-btn-border-color: var(--rc-terracotta-btn);
  --phoenix-btn-hover-bg: var(--rc-terracotta-dark);
  --phoenix-btn-hover-color: #fffcf4;
  --phoenix-btn-hover-border-color: var(--rc-terracotta-dark);
  --phoenix-btn-active-bg: var(--rc-terracotta-dark);
  --phoenix-btn-active-color: #fffcf4;
  --phoenix-btn-active-border-color: var(--rc-terracotta-dark);
  --phoenix-btn-disabled-bg: var(--rc-terracotta-btn);
  --phoenix-btn-disabled-color: #fffcf4;
  --phoenix-btn-disabled-border-color: var(--rc-terracotta-btn);

  background-color: var(--rc-terracotta-btn) !important;
  color: #fffcf4 !important;
  border-color: var(--rc-terracotta-btn) !important;
}
.btn-dark:hover,
.btn-dark:focus {
  background-color: var(--rc-terracotta-dark) !important;
  color: #fffcf4 !important;
  border-color: var(--rc-terracotta-dark) !important;
}
.btn-dark:active,
.btn-dark.active {
  background-color: var(--rc-terracotta-dark) !important;
  border-color: var(--rc-terracotta-dark) !important;
  color: #fffcf4 !important;
}
.btn-dark:disabled,
.btn-dark.disabled {
  background-color: var(--rc-terracotta-btn) !important;
  border-color: var(--rc-terracotta-btn) !important;
  color: #fffcf4 !important;
  opacity: 0.65;
}
.badge-subtle-secondary {
  background-color: rgba(var(--phoenix-secondary-rgb), 0.12);
  color: var(--phoenix-secondary);
}
.badge-subtle-success {
  background-color: rgba(var(--phoenix-success-rgb), 0.12);
  color: var(--phoenix-success);
  /* #3079: raw token text 2.5-3.6:1 on tint. darken, keep hue, >= 4.5:1 */
  color: color-mix(in srgb, var(--phoenix-success) 65%, #000);
}
.badge-subtle-info {
  background-color: rgba(var(--phoenix-info-rgb), 0.12);
  color: var(--phoenix-info);
  /* #3079: raw token text 2.5-3.6:1 on tint. darken, keep hue, >= 4.5:1 */
  color: color-mix(in srgb, var(--phoenix-info) 70%, #000);
}
.badge-subtle-warning {
  background-color: rgba(var(--phoenix-warning-rgb), 0.12);
  color: var(--phoenix-warning);
  /* #3079: raw token text 2.5-3.6:1 on tint. darken, keep hue, >= 4.5:1 */
  color: color-mix(in srgb, var(--phoenix-warning) 65%, #000);
}
.badge-subtle-danger {
  background-color: rgba(var(--phoenix-danger-rgb), 0.12);
  color: var(--phoenix-danger);
  /* #3079: raw token text 2.5-3.6:1 on tint. darken, keep hue, >= 4.5:1 */
  color: color-mix(in srgb, var(--phoenix-danger) 80%, #000);
}

/* -- fw-semibold, theme-completion patch (#2250) --------------------------
   real Bootstrap 5.2+ utility (font-weight:600), used 260 times across 33
   pug files, never shipped in theme.min.css -- only .fw-bold(700) and
   .fw-normal(400) exist there. every fw-semibold element silently rendered
   at the browser/Bootstrap default weight instead, indistinguishable from
   surrounding body text (found live: a card header and its description
   line looked identical in weight, see #2246/#2248/#2252's history).
   same failure mode as the alert/badge-subtle-* block above (#1922) --
   documented/used class, never actually defined. if theme.min.css ever
   ships a real .fw-semibold, delete this instead of letting it shadow
   the vendor's. */
.fw-semibold {
  font-weight: 600 !important;
}

/* #2061 -- sidebar toggler lives inside topbar's always-expanded nav
   (.navbar-top.navbar-expand). theme.min.css hides ANY .navbar-toggler
   in there unconditionally (no breakpoint), so it swallows this button
   too even tho it drives the vertical sidebar's own responsive collapse.
   restore its visibility below lg -- same breakpoint the sidebar itself
   already uses via navbar-expand-lg. */
@media (max-width: 991.98px) {
  .navbar-top .navbar-toggler.navbar-toggler-humburger-icon {
    display: flex;
  }
}

/* theme.min.css fires the gray hover fill on :hover AND :focus, so a mouse
   click leaves the button focused -> fill sticks till you click elsewhere.
   its own :focus box-shadow is dead code (references an undefined css var,
   so it's a no-op). split them: hover-only fill, real ring for keyboard
   focus only. */
.navbar-toggler-humburger-icon:focus:not(:focus-visible) {
  background-color: transparent;
}
.navbar-toggler.navbar-toggler-humburger-icon:focus-visible {
  box-shadow: 0 0 0 3px rgba(var(--phoenix-primary-rgb), 0.35);
}
/* :active only matches while the mouse button is actually down, so this
   shows on press and clears itself on release -- no JS, no stuck state. */
.navbar-toggler.navbar-toggler-humburger-icon:active {
  box-shadow: 0 0 0 3px rgba(var(--phoenix-primary-rgb), 0.25);
}

/* Platform Console tables sit in a card-body.p-0 (full-bleed rows, own
   border-bottom lines) -- .table-sm's own cell padding (theme.min.css,
   .25rem .25rem) is real but too tight against the card's rounded corners
   with zero card padding backing it up. first/last child, not per-column
   classes -- several of these tables have conditional columns (canManage
   gates, org-type-specific rows), so a fixed nth-child would silently miss
   whichever column ends up first/last for a given viewer/state.

   theme.min.css itself zeroes this exact padding on the first/last cell
   of thead/tbody rows (.table>thead>tr>th:first-child{padding-left:0} and
   the tbody/td, :last-child equivalents) -- a generic ":not(caption)>*>*"
   selector LOSES that specificity fight (fewer type selectors: (0,2,1) vs
   theme's (0,2,3)), so the padding silently never applied anywhere despite
   looking right in a screenshot (fooled by the page's own outer
   .container-fluid.py-6 padding, not the table's). Mirror theme's exact
   selector shape instead -- same specificity, later in source order wins. */
.pc-table > thead > tr > th:first-child,
.pc-table > tbody > tr > td:first-child,
.pc-table > tfoot > tr > td:first-child {
  padding-left: 1rem;
}
.pc-table > thead > tr > th:last-child,
.pc-table > tbody > tr > td:last-child,
.pc-table > tfoot > tr > td:last-child {
  padding-right: 1rem;
}

/* bootstrap collapse.js animates height, assumes block target. tr is
   table-row -- mid-transition height math breaks (squashed cells).
   kill the transition, toggle instant instead. */
#pc-fs-balance-sheet-tbl tr.collapsing,
#pc-fs-income-statement-tbl tr.collapsing,
#pc-fs-equity-tbl tr.collapsing,
#pc-fs-cash-flows-tbl tr.collapsing {
  transition: none;
}

/* ── Tables: edge padding, pinned actions column, top scrollbar, column menu ──
   public/js/table-enhancer.js adds the pieces below to every table.table.

   Edge padding: theme.min.css zeroes the first/last cell padding
   (.table>thead>tr>th:first-child{padding-left:0} and the tbody/td + :last-child
   twins) so tables sit flush with a padded container. Inside cards and
   DataTables wrappers that left text touching the table edge. Mirror theme's
   exact selector shape (same specificity, later in source wins; a generic
   selector loses -- see .pc-table above). */
.table > thead > tr > th:first-child,
.table > tbody > tr > td:first-child,
.table > tfoot > tr > td:first-child {
  padding-left: 0.75rem;
}
.table > thead > tr > th:last-child,
.table > tbody > tr > td:last-child,
.table > tfoot > tr > td:last-child {
  padding-right: 0.75rem;
}
/* views put .ps-0/.pe-0 (!important) on edge cells to sit flush under the
   old zero-edge theme rule. edges padded now: override. */
.table > thead > tr > th.ps-0:first-child,
.table > tbody > tr > td.ps-0:first-child,
.table > tfoot > tr > td.ps-0:first-child {
  padding-left: 0.75rem !important;
}
.table > thead > tr > th.pe-0:last-child,
.table > tbody > tr > td.pe-0:last-child,
.table > tfoot > tr > td.pe-0:last-child {
  padding-right: 0.75rem !important;
}

.te-col-hidden {
  display: none !important;
}
/* user ticked a width-hidden (.col-opt) column on: beats the container query
   and the forced fit-hide-<col> rules below */
th.te-col-shown,
td.te-col-shown {
  display: table-cell !important;
}

/* optional list columns (#3445). hidden by default, shown by container query on
   the table wrapper (.col-fit) so the sidebar state, zoom and gutters are
   irrelevant. each px = wrapper content width where table min-content with that
   column shown (and all higher-priority ones) fits, measured + 4px slack, so Status + reason never sit under sticky Actions.
   drop order: type > invoice > created (deposits). viewport @media would
   lie: theme xxl is 1540px, not bootstrap 1400. */
.col-fit {
  container-type: inline-size;
  container-name: colfit;
}
th.col-opt,
td.col-opt {
  display: none;
}
@container colfit (min-width: 963px) {
  th.col-opt-type,
  td.col-opt-type {
    display: table-cell;
  }
}
@container colfit (min-width: 1069px) {
  th.col-opt-invoice,
  td.col-opt-invoice {
    display: table-cell;
  }
}
@container colfit (min-width: 1195px) {
  th.col-opt-created,
  td.col-opt-created {
    display: table-cell;
  }
}
@container colfit (min-width: 760px) {
  th.col-opt-notes,
  td.col-opt-notes {
    display: table-cell;
  }
}
@container colfit (min-width: 796px) {
  th.col-opt-ref,
  td.col-opt-ref {
    display: table-cell;
  }
}
/* runtime safety net (list-fit.js): real rows can be wider than the measured px
   above. wrapper gets .fit-hide-<col> to drop one optional column. higher
   specificity than the container rules, so it wins whatever their order. */
.col-fit.fit-hide-type :is(th, td).col-opt-type,
.col-fit.fit-hide-invoice :is(th, td).col-opt-invoice,
.col-fit.fit-hide-created :is(th, td).col-opt-created,
.col-fit.fit-hide-notes :is(th, td).col-opt-notes,
.col-fit.fit-hide-ref :is(th, td).col-opt-ref {
  display: none;
}
/* narrow wrapper: Status column stops fitting beside sticky Actions (#3445).
   column hides, pill + reason render as 2nd block in the identity cell. px = wrapper
   width where table min-content with the Status column fits, measured + 4px slack.
   one table class per list, thresholds differ. */
.status-inline {
  display: none;
  text-align: left;
}
/* Sort by control (list-fit.js): Status header is gone when folded, so sorting
   by Status moves here. shown only while folded. carries the list's
   .status-fold-* class so the queries below can target it. */
.list-sort {
  display: none;
  position: sticky;
  left: 0;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0;
}
/* runtime safety net: list-fit.js forces .fit-fold on the wrapper when real rows
   overflow even though the container query has not folded yet. same body. */
.col-fit.fit-fold .status-inline {
  display: block;
}
.col-fit.fit-fold .list-sort {
  display: flex;
}
.col-fit.fit-fold :is(th, td).col-status {
  display: none;
}
/* Ref folds with Status: column is table min-width that pushes under sticky
   Actions. small copy under pill + reason instead (deposits) */
.ref-inline {
  display: none;
}
.col-fit.fit-fold .ref-inline {
  display: block;
}
.col-fit.fit-fold :is(th, td).col-ref {
  display: none;
}
/* clamped long-text cells (table-enhancer) are 12rem wide min. folded table
   has no room: lower the enhancer's own --te-clamp-min token so last columns
   do not slide under sticky Actions. token, not its class internals. */
.col-fit.fit-fold {
  --te-clamp-min: 8rem;
}
@container colfit (max-width: 864px) {
  :is(.status-fold-dep) .status-inline {
    display: block;
  }
  :is(.status-fold-dep).list-sort {
    display: flex;
  }
  :is(.status-fold-dep) :is(th, td).col-status {
    display: none;
  }
  :is(.status-fold-dep) .ref-inline {
    display: block;
  }
  :is(.status-fold-dep) :is(th, td).col-ref {
    display: none;
  }
  :is(.status-fold-dep) {
    --te-clamp-min: 8rem;
  }
}
/* Withdrawals + Loans measured 682 / 692, share 692 */
@container colfit (max-width: 692px) {
  :is(.status-fold-wd, .status-fold-loan) .status-inline {
    display: block;
  }
  :is(.status-fold-wd, .status-fold-loan).list-sort {
    display: flex;
  }
  :is(.status-fold-wd, .status-fold-loan) :is(th, td).col-status {
    display: none;
  }
  :is(.status-fold-wd, .status-fold-loan) {
    --te-clamp-min: 8rem;
  }
  /* only Loans has an inline Ref (Withdrawals has no Ref column) */
  .status-fold-loan .ref-inline {
    display: block;
  }
}
/* identity / name cells: long names wrap instead of widening the table past
   the wrapper (Status would sit under sticky Actions) (#3445) */
td.col-wrap {
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
  max-width: 260px;
}
/* long refs (DECL-2026...) wrap at hyphens/spaces, break mid-token only if one
   token alone is wider than the cell */
td.col-ref-wrap {
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
  max-width: 150px;
}

/* actions column pinned to the right edge while other columns scroll.
   opaque fill (--te-bg, set per table from the nearest solid ancestor) or the
   scrolling columns show through. */
table.te-has-actions > thead > tr > th.te-actions,
table.te-has-actions > tbody > tr > td.te-actions,
table.te-has-actions > tfoot > tr > td.te-actions {
  position: sticky;
  right: 0;
  z-index: 2;
  background-color: var(--te-bg, #fff);
  box-shadow: -6px 0 6px -6px rgba(0, 0, 0, 0.18);
  white-space: nowrap;
}

/* scrollbar above the table, mirrors the real one below. sticks under the
   fixed navbar (4rem) so short screens (720px) still reach it mid-table.
   z under navbar (1020), over sticky actions cells (2). */
.te-topscroll {
  overflow-x: auto;
  overflow-y: hidden;
  margin-bottom: 2px;
  position: sticky;
  top: 4rem;
  z-index: 3;
  background-color: var(--phoenix-body-bg, #fff);
}
/* theme .scrollbar shows only on own hover. hover either bar -> show both */
.scrollbar.te-peek::-webkit-scrollbar,
.scrollbar.te-peek::-webkit-scrollbar-thumb {
  visibility: visible;
}
.te-topscroll > div {
  height: 1px;
}
/* DataTables floats its length/filter controls left/right and relies on the
   table's own clear:both -- our wrapper must clear them too or the table
   flows beside the float. */
.te-topscroll,
.te-wrapped,
.te-toolbar {
  clear: both;
}

.te-toolbar {
  display: flex;
  justify-content: flex-end;
  /* breathing room from controls above (padding: clear eats margin) */
  padding-top: 0.75rem;
  margin-bottom: 0.5rem;
}
.te-toolbar:empty {
  display: none;
}
.te-columns {
  position: relative;
}
.te-columns-menu {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 1050;
  min-width: 12rem;
  max-height: 20rem;
  overflow-y: auto;
  padding: 0.5rem 0.75rem;
  background: var(--phoenix-body-bg, #fff);
  border: 1px solid var(--phoenix-border-color, #cbd0dd);
  border-radius: 0.375rem;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
.te-columns-menu[hidden] {
  display: none;
}
.te-columns-count {
  font-size: 0.65rem;
  line-height: 1;
}
.te-columns-reset {
  display: block;
  font-size: 0.8rem;
}
.te-columns-reset[hidden],
.te-columns-count[hidden] {
  display: none;
}
.te-columns-item {
  display: flex;
  align-items: center;
  padding: 0.2rem 0;
  font-size: 0.85rem;
  white-space: nowrap;
  cursor: pointer;
}

/* row opens its record (table[data-row-open]) */
table > tbody > tr.te-row-link {
  cursor: pointer;
}
table > tbody > tr.te-row-link:hover > td {
  background-color: var(--phoenix-gray-100, #f5f7fa);
}

/* long text cell: 2 lines + "…", full text in hint. wraps even inside
   white-space-nowrap cells (that nowrap is what blew tables 500px wide). */
.te-clamp-inner {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  white-space: normal;
  /* --te-clamp-min: the fold (list rules above) lowers it from 12rem */
  min-width: var(--te-clamp-min, 12rem);
  max-width: 22rem;
  overflow-wrap: anywhere;
}

@media print {
  .te-clamp-inner {
    display: block;
    -webkit-line-clamp: unset;
    line-clamp: none;
    max-width: none;
  }
  .te-topscroll,
  .te-toolbar {
    display: none !important;
  }
  table.te-has-actions > thead > tr > th.te-actions,
  table.te-has-actions > tbody > tr > td.te-actions {
    position: static;
    box-shadow: none;
  }
}

/* DataTables on phones (#3555): each row a card instead of a table that
   scrolls sideways (Amount used to sit off screen behind the pinned Actions
   column). table-enhancer adds .te-cards to every DataTable with 3+ labelled
   columns and tags each cell: data-card = role (expander, title, amount,
   status, meta, actions), data-label = its header text. role per column:
   th[data-card-role], else guessed from the header. opt out: data-te-no-cards.
   cells a table hides on purpose (.col-opt, .col-status, .col-ref, .d-none)
   stay hidden: their value is already folded into the title cell. */
@media (max-width: 575.98px) {
  /* row actions are text/icon links: 44px tap floor */
  table.te-cards td.te-actions a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* name/ref links in a card: tap area grows, layout does not */
  table.te-cards td:not(.te-actions) a:not(.btn) {
    display: inline-block;
    padding: 0.8rem 0;
    margin: -0.8rem 0;
  }
  table.te-cards > thead {
    display: none;
  }
  table.te-cards,
  table.te-cards > tbody {
    display: block;
    width: 100% !important;
  }
  table.te-cards > tbody > tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 0.6rem;
    row-gap: 0.2rem;
    align-items: start;
    padding: 0.8rem 0.25rem;
    border-bottom: 1px solid var(--phoenix-border-color, #e3e6ed);
  }
  table.te-cards
    > tbody
    > tr
    > td[data-card]:not(.col-opt, .col-status, .col-ref, .d-none) {
    display: block;
    min-width: 0;
    padding: 0 !important;
    border: 0 !important;
    text-align: left !important;
    white-space: normal;
    width: auto !important;
    max-width: none;
  }
  table.te-cards > tbody > tr > td[data-card='expander'] {
    grid-column: 1;
    grid-row: 1;
    padding-top: 0.25rem !important;
  }
  table.te-cards > tbody > tr > td[data-card='title'] {
    grid-column: 2;
    grid-row: 1;
    font-weight: 600;
  }
  table.te-cards > tbody > tr > td[data-card='amount'] {
    grid-column: 3;
    grid-row: 1;
    text-align: right !important;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }
  table.te-cards > tbody > tr > td[data-card='empty'] {
    display: none !important;
  }
  table.te-cards > tbody > tr > td[data-card='amount'][data-cur]::before {
    content: attr(data-cur) '\00a0';
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--phoenix-secondary-color, #6e7891);
  }
  table.te-cards > tbody > tr > td[data-card='status'],
  table.te-cards > tbody > tr > td[data-card='meta'] {
    grid-column: 2 / -1;
  }
  table.te-cards
    > tbody
    > tr
    > td[data-card='meta']:not(.col-opt, .col-status, .col-ref, .d-none) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    min-width: 0;
    overflow-wrap: anywhere;
    gap: 0.15rem 0.4rem;
    font-size: 0.78rem;
    color: var(--phoenix-secondary-color, #6e7891);
  }
  table.te-cards > tbody > tr > td[data-card='meta']::before {
    content: attr(data-label) ':';
    flex: 0 0 auto;
  }
  table.te-cards > tbody > tr > td[data-card='actions'] {
    grid-column: 2 / -1;
    margin-top: 0.4rem;
    position: static;
    box-shadow: none;
    background: none;
  }
  table.te-cards > tbody > tr > td[data-card='actions'] .btn {
    min-height: 40px;
  }
  /* expanded detail row + "no data" row: one full-width cell */
  table.te-cards > tbody > tr > td[colspan] {
    display: block;
    grid-column: 1 / -1;
  }
  /* nothing to scroll or pick columns from any more */
  .te-toolbar.te-for-cards,
  .te-topscroll.te-for-cards {
    display: none !important;
  }
}

/* phone: use the width (#3555). theme gives .content 24px each side and the
   aurora list cards add 16px inside that: ~40px lost per side on a 390px
   screen. now 16px (rows with g-4 pull -16px, less overflows sideways), cards 8px. banners (.mx-4) and full-bleed rows follow the
   same edge, so headings, banners and cards line up. */
@media (max-width: 575.98px) {
  .main .content {
    padding-left: 1rem;
    padding-right: 1rem;
  }
  .main .content .container-fluid.au-page {
    padding-left: 0;
    padding-right: 0;
  }
  /* page wrappers with their own px-4 double the gutter on phones */
  .main .content .container-fluid.px-4 {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  /* group standing: hero strip is a fixed flex row. 2 x 2 grid instead. */
  .main .content .rc-hero {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 0;
    padding: 1rem;
  }
  .main .content .rc-hero .rc-metric,
  .main .content .rc-hero .rc-metric:first-child {
    padding: 0 0.75rem;
    min-width: 0;
  }
  .main .content .rc-hero .rc-metric:nth-child(odd) {
    padding-left: 0;
  }
  .main .content .rc-hero .rc-metric:nth-child(even) {
    border-right: none;
  }
  .main .content .rc-hero .rc-metric-val {
    font-size: 1.2rem;
    overflow-wrap: anywhere;
  }
  .main .content .rc-oc-summary {
    flex-wrap: wrap;
    gap: 0.75rem 1.25rem;
  }
  /* org settings rows: label | input | Save side by side overflows. stack. */
  .known-setting-row {
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0.5rem;
  }
  .known-setting-row > .known-setting-label,
  .known-setting-row > .known-setting-input {
    flex: 1 1 100%;
    min-width: 0;
  }
  .known-setting-row > .known-setting-action {
    flex: 1 1 100%;
  }
  .known-setting-row > .known-setting-action .btn {
    width: 100%;
    min-height: 44px;
  }
  .main .content .alert.mx-4 {
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  /* "add another" switch: row.ms-4 > .m-4 pushed page to 413px. */
  .main .content .row.ms-4 {
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  /* top toasts drop below the top bar. were covering the hamburger + org
     switcher, so a story step pointing at the menu button could not be tapped. */
  .iziToast-wrapper-topCenter,
  .iziToast-wrapper-topLeft,
  .iziToast-wrapper-topRight {
    top: 68px !important;
  }
  /* touch floor (docs/domain/styling.md): story steps ask the visitor to press
     small buttons (28-40px). page + dialog buttons only, not links/close. */
  .main .content .btn:not(.btn-link):not(.btn-close):not(.vscomp-toggle-button),
  .modal .btn:not(.btn-link):not(.btn-close) {
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* dialog radios/checks: label is the tap target, was 38px. */
  .modal .form-check:not(.form-switch) .form-check-label {
    min-height: 44px;
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
  }
  .modal .form-check:not(.form-switch) .form-check-input {
    margin-top: 0.45rem;
  }
  .main .content .row.ms-4 > .form-check.m-4 {
    /* left = col padding, lines up with fields above */
    margin: 1rem 0 1rem 1rem !important;
  }
  .main .content .mx-n4:not(.bg-white) {
    margin-left: -1rem !important;
    margin-right: -1rem !important;
  }
  .main .content .mx-n4.bg-white.border-y .table-responsive {
    margin: 0 0.5rem !important;
  }
  .main
    .content
    :is(.au-card, .card, .mx-n4.bg-white.border-y)
    :is(.te-toolbar, .te-wrapped) {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
  .main .content :is(.au-card, .card, .mx-n4.bg-white.border-y) .te-topscroll {
    margin-left: 0.5rem;
    margin-right: 0.5rem;
  }
}

/* Add Withdrawal form (#3555): one form, not a card inside a modal. labels all
   sit above their field, dropdown corners match the text fields. phone: Save
   is the full-width action. */
#add_withdrawal .card.theme-wizard {
  border: 0;
  box-shadow: none;
  margin-bottom: 0 !important;
}
#add_withdrawal .card.theme-wizard > .card-body,
#add_withdrawal .card.theme-wizard > .card-footer {
  padding-left: 0;
  padding-right: 0;
  background: transparent;
}
#add_withdrawal .vscomp-toggle-button,
#add_withdrawal .form-control {
  border-radius: var(--bs-border-radius, 0.375rem);
}
@media (max-width: 575.98px) {
  #add_withdrawal #submitWithdrawal {
    width: 100%;
    min-height: 44px;
  }
}

/* -- Staff sidebar: off-canvas drawer below lg ----------------------------- */
/* #navbarVerticalCollapse is a Bootstrap .offcanvas-lg (sidebar.pug): drawer
   below lg, the normal fixed vertical sidebar from lg up. Group headings are
   drawer-only; DOM order is the one order for both. */
.nav-group-heading {
  display: none;
}
.nav-drawer-close {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: #c9d1dc;
  background: transparent;
  border: 0;
  border-radius: 0.6rem;
}
.nav-drawer-close:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

@media (max-width: 991.98px) {
  /* shell has no footprint. no z-index/will-change/transform here: any of
     them traps the fixed drawer inside the shell's stacking context, under
     the body-level scrim. */
  .navbar-vertical {
    position: static;
    display: block;
    z-index: auto;
    width: 0;
    height: 0;
    padding: 0;
    border: 0;
    background: transparent;
    will-change: auto;
  }
  /* floating inset panel: gap to screen edges (+ safe areas), rounded on all
     corners. width counts the inset so panel + gap never exceed min(80vw,320px). */
  #navbarVerticalCollapse {
    --drawer-gap: 12px;
    top: calc(var(--drawer-gap) + env(safe-area-inset-top, 0px));
    bottom: calc(var(--drawer-gap) + env(safe-area-inset-bottom, 0px));
    left: calc(var(--drawer-gap) + env(safe-area-inset-left, 0px));
    z-index: 1045;
    align-items: stretch;
    width: calc(
      min(80vw, 320px) - var(--drawer-gap) - env(safe-area-inset-left, 0px)
    );
    height: auto;
    max-height: none;
    overscroll-behavior: contain;
    background: var(--phoenix-navbar-vertical-bg-color);
    border-radius: 18px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
    opacity: 0;
    transform: translateX(-110%);
    transition:
      transform 0.3s ease-in-out,
      opacity 0.3s ease-in-out;
  }
  #navbarVerticalCollapse.showing,
  #navbarVerticalCollapse.show:not(.hiding) {
    opacity: 1;
    transform: none;
  }
  #navbarVerticalCollapse:focus {
    outline: 0;
  }
  @media (prefers-reduced-motion: reduce) {
    #navbarVerticalCollapse {
      transition: none;
    }
  }

  /* menu groups are flex items of a scrolling list and theme hides their
     overflow, so they shrank to ~64px and links overlapped. never shrink. */
  #navbarVerticalCollapse .navbar-nav > .nav-item {
    flex-shrink: 0;
  }

  /* pinned header (org switcher + view as member), scrolling list, pinned footer */
  #navbarVerticalCollapse .navbar-vertical-content {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
    max-height: none;
    padding: 0;
    overflow: visible;
  }
  #navbarVerticalCollapse .org-switcher-wrapper {
    flex: none;
    padding-right: 3.5rem !important;
    padding-top: 0.75rem !important;
    margin-bottom: 0;
    border-bottom: 0;
  }
  #navbarVerticalCollapse .view-as-member-link {
    flex: none;
    min-height: 44px;
    margin: 0 0.75rem;
    padding: 0 0.75rem !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  }
  #navbarVerticalNav {
    flex: 1 1 auto;
    min-height: 0;
    padding: 0.25rem 0.75rem 0.75rem;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  #navbarVerticalCollapse .org-switcher-item {
    white-space: normal;
  }
  .nav-group-heading {
    display: block;
  }
  .nav-group-label {
    padding: 1rem 0.75rem 0.25rem;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--phoenix-navbar-vertical-label-color);
  }
  #navbarVerticalNav .nav-link {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  #navbarVerticalNav > .nav-link,
  #navbarVerticalNav > li.nav-item > .nav-link {
    padding-left: 0.75rem;
    border-radius: 0.6rem;
  }
  #navbarVerticalNav > li.nav-item {
    margin-left: 0 !important;
  }
  #navbarVerticalNav .nav-link.active {
    color: #fff;
    background: #33415a;
  }
  #navbarVerticalCollapse .navbar-vertical-footer {
    flex: none;
    gap: 0.25rem;
    height: auto;
    padding: 0.25rem 0.75rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
  }
  #navbarVerticalCollapse .navbar-vertical-footer a {
    display: inline-flex !important;
    align-items: center;
    min-height: 44px;
    padding: 0 0.6rem !important;
    font-size: 0.8rem;
    white-space: nowrap;
    font-weight: 600;
    color: var(--phoenix-navbar-vertical-link-color);
    text-decoration: none;
    border-radius: 0.6rem;
  }
  #navbarVerticalCollapse .navbar-vertical-footer-icon {
    margin-right: 0.6125rem;
  }
  #navbarVerticalCollapse .navbar-vertical-footer a:hover {
    color: var(--phoenix-navbar-vertical-link-hover-color);
  }
  .nav-drawer-close:focus-visible,
  #navbarVerticalNav .nav-link:focus-visible,
  #navbarVerticalCollapse .navbar-vertical-footer a:focus-visible,
  #navbarVerticalCollapse .org-switcher-btn:focus-visible {
    outline: 2px solid #e0b13a;
    outline-offset: -2px;
  }
}

/* phones: topbar (logo block 15.875rem wide + icon row) was wider than the
   screen, pushing the avatar off the right edge. */
@media (max-width: 575.98px) {
  .navbar-top .navbar-logo {
    flex: 0 1 auto;
    width: auto;
    min-width: 0;
    padding-left: 0;
  }
  .navbar-top .navbar-brand img {
    height: 36px;
  }
  .navbar-top .navbar-collapse {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    padding-right: 0.75rem;
    padding-left: 0;
  }
  .navbar-top #navbarDropdownUser {
    margin-left: 0.25rem !important;
  }
}
@media (max-width: 359.98px) {
  .navbar-top .navbar-brand img {
    height: 30px;
  }
}

/* #3183 breadcrumbs: lg+ full trail + Back link; below lg one compact label. */
.topbar-crumbs {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
  margin: 0 0.5rem;
  font-size: 0.8125rem;
}
.topbar-crumbs[hidden] {
  display: none;
}
.topbar-crumbs .breadcrumb {
  flex-wrap: nowrap;
  white-space: nowrap;
  margin: 0;
}
.topbar-crumbs .breadcrumb-item.active {
  color: var(--phoenix-body-emphasis-color, #1f2937);
  font-weight: 600;
}
.topbar-crumbs a {
  color: var(--phoenix-secondary-color, #6c7a91);
  text-decoration: none;
}
.topbar-crumbs a:hover {
  color: var(--phoenix-primary);
}
.topbar-crumbs-back {
  white-space: nowrap;
  font-weight: 600;
}
.topbar-crumbs-compact {
  display: none;
}
/* lg+: trail yields (ellipsis on current page) before icons do. */
@media (min-width: 992px) {
  .topbar-crumbs {
    flex: 0 1 auto;
    overflow: hidden;
  }
  .topbar-crumbs .topbar-crumbs-full {
    min-width: 0;
    flex: 0 1 auto;
    overflow: hidden;
  }
  .topbar-crumbs .breadcrumb-item {
    flex: none;
  }
  .topbar-crumbs .breadcrumb-item.active {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .topbar-crumbs-back {
    flex: none;
  }
}
@media (max-width: 991.98px) {
  .topbar-crumbs .topbar-crumbs-full,
  .topbar-crumbs .topbar-crumbs-back {
    display: none;
  }
  /* same scale as .topbar-org so the two read as one row. */
  .topbar-crumbs {
    flex: 0 1 auto;
    min-width: 0;
  }
  .topbar-crumbs-compact {
    display: block;
    min-width: 0;
    max-width: 8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.8125rem;
    line-height: 1.25;
    font-weight: 600;
  }
}

/* org name in topbar: below lg only (d-lg-none), 1 line + ellipsis. */
.topbar-org {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex: 1 1 0;
  min-width: 5.5rem;
  /* long name never widens row past icons. */
  overflow: hidden;
  min-height: 44px;
  margin: 0 0.25rem;
  padding: 0 0.5rem;
  background: transparent;
  border: 0;
  border-radius: 0.5rem;
  color: var(--phoenix-body-color, #31374a);
  font-size: 0.8125rem;
  line-height: 1.25;
  font-weight: 700;
  text-align: left;
}
.topbar-org:hover {
  background: rgba(0, 0, 0, 0.05);
}
.topbar-org:focus-visible {
  outline: 2px solid #e0b13a;
  outline-offset: -2px;
}
.topbar-org-name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.topbar-org-chevron {
  flex: none;
}
/* below lg: logo block + icon cluster size to content, name button takes the rest. */
@media (max-width: 991.98px) {
  .navbar-top .navbar-logo {
    flex: 0 0 auto;
    width: auto;
  }
  .navbar-top.navbar-expand .navbar-collapse {
    flex: 0 0 auto;
    width: auto;
    padding-left: 0;
  }
  /* theme's 2.5rem/2rem gutters ate the room the name needs. */
  .navbar-top #navbarDropdownUser {
    margin-left: 0.5rem !important;
  }
}
/* tablet-ish: room for a longer crumb, but org name keeps a readable floor. */
@media (min-width: 576px) and (max-width: 991.98px) {
  .topbar-org {
    min-width: 8.5rem;
  }
  .topbar-crumbs-compact {
    max-width: 14rem;
  }
}
/* phones: squeeze chrome so the name gets most of the row. */
@media (max-width: 575.98px) {
  .navbar-top .navbar-collapse {
    padding-right: 0.5rem !important;
  }
  .navbar-top .navbar-brand {
    margin-right: 0 !important;
  }
  .navbar-top .navbar-brand img {
    height: 30px;
  }
  .navbar-top .navbar-nav-icons .nav-link {
    padding-left: 0.45rem !important;
    padding-right: 0.45rem !important;
  }
  .navbar-top #navbarDropdownUser {
    padding: 0 !important;
    margin-left: 0.15rem !important;
  }
  .navbar-top #navbarDropdownUser .avatar {
    width: 32px;
    height: 32px;
  }
  .topbar-org {
    margin: 0;
    padding: 0 0.1rem;
    gap: 0.15rem;
    min-width: 4.5rem;
  }
  .topbar-crumbs {
    margin: 0 0.25rem;
  }
  .topbar-crumbs-compact {
    max-width: 5.5rem;
  }
}

/* theme draws the 1px bottom rule on .navbar-logo + .navbar-collapse only,
   so crumbs/org in between left a notch. one rule on the bar instead. */
.navbar-top::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--phoenix-gray-300, #cbd0dd);
  pointer-events: none;
}
.navbar-top.navbar-expand .navbar-logo,
.navbar-top.navbar-expand .navbar-collapse {
  border-bottom: 0;
}
/* icons row: centre items vertically. */
.navbar-top .navbar-nav-icons {
  align-items: center;
}

/* ── Soft status pills ────────────────────────────────────────────────────
   solid .badge.bg-* (bootstrap) too loud next to theme's soft
   .badge-phoenix-*. same palette here so every pill reads soft. bg-* are
   !important utilities: match with !important + higher specificity. */
.badge.bg-success {
  background-color: #d9fbd0 !important;
  color: #1c6c09 !important;
  border: 1px solid #bee8b4;
}
.badge.bg-danger {
  background-color: #ffe0db !important;
  color: #b81800 !important;
  border: 1px solid #fabcb3;
}
.badge.bg-warning {
  background-color: #ffefca !important;
  color: #bc3803 !important;
  border: 1px solid #ffcc85;
}
.badge.bg-info {
  background-color: #c7ebff !important;
  color: #005585 !important;
  border: 1px solid #96d9ff;
}
.badge.bg-primary {
  background-color: #e5edff !important;
  color: #003cc7 !important;
  border: 1px solid #adc5ff;
}
.badge.bg-secondary {
  background-color: #e3e6ed !important;
  color: #141824 !important;
  border: 1px solid #cbd0dd;
}

/* free-text column (e.g. notification message): keep readable width so
   nowrap neighbours can't squeeze it into a tall thin strip */
.table th.te-text-col,
.table td.te-text-col {
  min-width: 18rem;
}

/* table with clamped cells: drop datatables' inline px widths (measured
   from full unclamped text) so columns fit what is actually shown. view
   min-widths still apply. */
table.te-clamped {
  width: 100% !important;
}
table.te-clamped > thead > tr > th {
  width: auto !important;
}

/* label column pinned left (opt in: table[data-te-pin-first]) — wide
   statements keep line-item names in view while numbers scroll. */
table[data-te-pin-first] > thead > tr > :first-child,
table[data-te-pin-first] > tbody > tr > :first-child,
table[data-te-pin-first] > tfoot > tr > :first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background-color: var(--te-bg, #fff);
  box-shadow: 6px 0 6px -6px rgba(0, 0, 0, 0.18);
}
@media print {
  table[data-te-pin-first] > * > tr > :first-child {
    position: static;
    box-shadow: none;
  }
}

/* .badge-soft-* used (org list, portfolio) but never defined anywhere:
   white text on transparent = invisible "Pending Setup". same soft palette. */
.badge.badge-soft-success {
  background-color: #d9fbd0;
  color: #1c6c09;
  border: 1px solid #bee8b4;
}
.badge.badge-soft-warning {
  background-color: #ffefca;
  color: #bc3803;
  border: 1px solid #ffcc85;
}
.badge.badge-soft-info {
  background-color: #c7ebff;
  color: #005585;
  border: 1px solid #96d9ff;
}
.badge.badge-soft-secondary {
  background-color: #e3e6ed;
  color: #141824;
  border: 1px solid #cbd0dd;
}
.badge.badge-soft-danger {
  background-color: #ffe0db;
  color: #b81800;
  border: 1px solid #fabcb3;
}

/* #3070 bulk-assign bar: sticks under the fixed navbar (4rem) so it stays
   reachable while scrolling a 50-row page on a 720px screen. Not on phones:
   stacked it is ~300px tall and would eat the viewport. */
@media (min-width: 576px) {
  .unassigned-bar {
    position: sticky;
    top: 4rem;
    z-index: 3;
  }
}
.unassigned-bar .unassigned-manager {
  flex: 1 1 14rem;
  max-width: 24rem;
  min-width: 12rem;
}
.unassigned-bar .unassigned-manager .vscomp-ele {
  max-width: 100%;
}
.unassigned-check {
  width: 2.5rem;
}
@media (max-width: 575.98px) {
  .unassigned-bar .btn {
    min-height: 44px;
  }
  .unassigned-bar .btn-link {
    min-height: 0;
  }
  .unassigned-bar #bulkModes {
    width: 100%;
  }
  .unassigned-bar #bulkModes .btn {
    flex: 1 1 50%;
  }
  .unassigned-bar #bulkSubmit {
    width: 100%;
  }
  .unassigned-bar .unassigned-manager {
    flex-basis: 100%;
    max-width: none;
  }
}

/* -- Staffing mobile + accessibility pass (#3079) -------------------------
   chip text contrast, tap targets on phones, no clipped/overflowing rows.
   .staffing-a11y wraps each Staffing page, card and modal. */
.text-danger-aa {
  color: color-mix(in srgb, var(--phoenix-danger) 80%, #000);
}
.staffing-warn-text {
  color: color-mix(in srgb, var(--phoenix-warning) 65%, #000);
}
.staffing-chip-active {
  background-color: var(--phoenix-primary-600);
  border-color: var(--phoenix-primary-600);
  color: #fff;
}
.staffing-chip-active:hover,
.staffing-chip-active:focus {
  background-color: var(--phoenix-primary-600);
  border-color: var(--phoenix-primary-600);
  color: #fff;
}
.staffing-chip-count {
  color: var(--phoenix-primary-600);
}
.staffing-a11y .unassigned-hit {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}
.staffing-a11y .unassigned-hit .form-check-input {
  margin: 0;
}
/* theme drops focus ring on btn-link + plain links. force one. */
.staffing-a11y :is(a, button, .btn, [role='button']):focus-visible {
  outline: 2px solid var(--phoenix-primary-600);
  outline-offset: 2px;
}
/* VirtualSelect combobox (div.vscomp-wrapper, tabindex 0): the library gives it
   no keyboard ring. global, so every picker / bulk-assign / handover modal gets one. */
.vscomp-ele .vscomp-wrapper:focus-visible {
  outline: 2px solid var(--phoenix-primary-600);
  outline-offset: 2px;
}
/* heading focused by script. no ring needed. */
h1[tabindex='-1']:focus,
h2[tabindex='-1']:focus,
h4[tabindex='-1']:focus,
h6[tabindex='-1']:focus {
  outline: none;
}
@media (max-width: 767.98px) {
  .staffing-a11y .btn,
  .staffing-a11y .nav-link {
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .staffing-a11y .nav-link {
    justify-content: flex-start;
  }
  .staffing-a11y .form-control,
  .staffing-a11y .form-select,
  .staffing-a11y .vscomp-toggle-button {
    min-height: 44px;
  }
  .staffing-a11y
    a.is-link:not(.btn):not(.nav-link):not(.staffing-tile):not(
      .js-attention-cta
    ) {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* count + CTA row: the CTA is a real 44px box, not a pseudo-element. */
  .staffing-a11y .js-attention-groups > li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 0.35rem;
  }
  .staffing-a11y .js-attention-groups > li > ul {
    flex-basis: 100%;
  }
  .staffing-a11y a.js-attention-cta {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: 0.25rem;
  }
  .staffing-a11y .btn-close {
    box-sizing: border-box;
    min-width: 44px;
    min-height: 44px;
  }
  .staffing-tap-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }
  /* label = tap target for check/radio/switch */
  .staffing-a11y .form-check-label {
    padding-block: 0.75rem;
  }
  .staffing-a11y .js-row-select,
  .staffing-a11y .js-ls-suggest,
  .staffing-a11y #lsSuggestAll,
  .staffing-a11y #unassignedPageCheck {
    width: 1.5rem;
    height: 1.5rem;
  }
}

/* #3184 command palette. aurora tokens (vars resolve at use, fallbacks for safety). */
.palette-trigger {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: 0;
}
.palette-trigger-kbd {
  font-family: inherit;
  font-size: 0.6875rem;
  padding: 0.1rem 0.35rem;
  color: var(--au-t3, #6b6f85);
  background: var(--au-band, #faf8f3);
  border: 1px solid var(--au-line, #e6e2d9);
  border-radius: 6px;
}
.palette-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh 1rem 1rem;
  background: rgba(27, 30, 51, 0.45);
}
.palette-overlay[hidden] {
  display: none;
}
.palette-dialog {
  width: 100%;
  max-width: 560px;
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--rc-font-body);
  background: var(--au-glass, #fff);
  border: 1px solid var(--au-glass-line, #ebe8e0);
  border-radius: 16px;
  box-shadow: 0 24px 60px -18px rgba(27, 30, 51, 0.55);
}
.palette-head {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--au-line, #e6e2d9);
}
.palette-close {
  display: none;
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.9rem;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--au-t2, #3b3f58);
  background: none;
  border: 0;
  border-left: 1px solid var(--au-line, #e6e2d9);
}
.palette-close:focus-visible {
  outline: 2px solid var(--au-gold, #e0a93c);
  outline-offset: -2px;
}
.palette-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.9rem 1.1rem;
  font-size: 1rem;
  color: var(--au-t1, #1b1e33);
  background: transparent;
  border: 0;
  outline: 0;
}
.palette-input:focus-visible {
  box-shadow: inset 0 -2px 0 var(--au-gold, #e0a93c);
}
.palette-list {
  overflow-y: auto;
  padding: 0.35rem;
}
.palette-section {
  padding: 0.5rem 0.75rem 0.25rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--au-t3, #6b6f85);
}
.palette-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0.5rem 0.75rem;
  border-radius: 10px;
  cursor: pointer;
}
.palette-item.active {
  background: var(--au-warn-soft, rgba(224, 169, 60, 0.18));
}
.palette-item-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--au-t1, #1b1e33);
}
.palette-item-sub {
  font-size: 0.75rem;
  color: var(--au-t3, #6b6f85);
}
.palette-empty {
  padding: 1.25rem;
  text-align: center;
  font-size: 0.875rem;
  color: var(--au-t3, #6b6f85);
}
.palette-empty[hidden] {
  display: none;
}
.palette-foot {
  padding: 0.45rem 1rem;
  font-size: 0.6875rem;
  color: var(--au-t3, #6b6f85);
  background: var(--au-band, #faf8f3);
  border-top: 1px solid var(--au-line, #e6e2d9);
}
body.palette-open {
  overflow: hidden;
}
/* below lg: close btn + 16px input (no iOS zoom) */
@media (max-width: 991.98px) {
  .palette-close {
    display: block;
  }
  .palette-input {
    font-size: 16px;
  }
}
/* below md: full-screen sheet. md-lg stays a card so backdrop shows + tap closes */
@media (max-width: 575.98px) {
  .palette-overlay {
    padding: 0;
  }
  .palette-dialog {
    max-width: none;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
  }
}

/* #3423 caution line under sidebar Advanced group. readable on dark sidebar */
#navbarVerticalNav .nav-caution {
  padding: 0.25rem 0.75rem 0.5rem 2.25rem;
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--phoenix-navbar-vertical-link-color);
  opacity: 0.85;
}
