/* Global app-level safety overrides loaded after vendor and module CSS. */

/* Text links stay neutral, including visited links and Bootstrap color utilities.
   A named important layer keeps module/HTMX styles from restoring vendor purple.
   Controls retain their own foregrounds so filled buttons and selected tabs stay
   readable. The accent-text token is contrast-adjusted for light/dark themes. */
@layer bd-text-links {
  /* Link affordance is the pointer and theme hover color, never an underline.
     Include descendants: search results contain badges, marks, and icons with
     their own cursor/decoration rules. */
  html body :is(a, [role="link"], .btn-link),
  html body :is(a, [role="link"], .btn-link) * {
    text-decoration: none !important;
  }

  html body :is(a[href], a[hx-get], a[hx-post], [role="link"], .btn-link):not(:where(
    :disabled, .disabled, [aria-disabled="true"],
    .disabled *, [aria-disabled="true"] *
  )),
  html body :is(a[href], a[hx-get], a[hx-post], [role="link"], .btn-link):not(:where(
    :disabled, .disabled, [aria-disabled="true"],
    .disabled *, [aria-disabled="true"] *
  )) * {
    cursor: pointer !important;
  }

  html body :is(a, .btn-link):not(:where(
    .btn:not(.btn-link), .bd-btn, [class*="-btn"], [class*="button"],
    .std-btn-sample, .std-action,
    .bd-action-strip__btn, .portal-work-action, .svc-workon-command,
    .bd-btn-promote, [role="button"],
    .badge, .bd-badge, .bd-work-link-badge,
    .nav-link, .dropdown-item, .page-link, [role="tab"], [role="menuitem"],
    .active, .is-active, [aria-current], [aria-disabled="true"], .disabled,
    .nav *, .navbar *, .vertical-menu *, #sidebar-menu *,
    .bd-module-nav *, .bd-module-subnav *, .bd-settings-subnav *
  )) {
    color: inherit !important;
  }

  html body :is(a, .btn-link):not(:where(
    .btn:not(.btn-link), .bd-btn, [class*="-btn"], [class*="button"],
    .std-btn-sample, .std-action,
    .bd-action-strip__btn, .portal-work-action, .svc-workon-command,
    .bd-btn-promote, [role="button"],
    .badge, .bd-badge, .bd-work-link-badge,
    .nav-link, .dropdown-item, .page-link, [role="tab"], [role="menuitem"],
    .active, .is-active, [aria-current], [aria-disabled="true"], .disabled,
    .nav *, .navbar *, .vertical-menu *, #sidebar-menu *,
    .bd-module-nav *, .bd-module-subnav *, .bd-settings-subnav *
  )):is(:hover, :focus-visible) {
    color: var(--bd-theme-accent-text, var(--bs-body-color, #343a40)) !important;
  }
}

/* Beat Discovery's html body .bd-card > .table-responsive corner mask.
   :where() gave the old safety rule zero specificity, so overflow:hidden won.
   Keep higher-specificity open-dropdown escapes and vertical scrolling intact. */
html body :is(
  .table-responsive,
  .table-responsive-sm,
  .table-responsive-md,
  .table-responsive-lg,
  .table-responsive-xl,
  .table-responsive-xxl,
  .bd-table-responsive,
  .bd-scroll-x,
  .bd-hscroll,
  .bd-table-shell__scroll,
  .bd-table-wrap,
  .bd-table-scroll,
  .acct-table-wrap,
  .acct-table-shell,
  .inv-table-wrap,
  .settings-table-wrapper,
  [data-table-scroll],
  [data-std-table-shell],
  [data-ap-table-shell],
  [data-ar-table-shell],
  [data-acct-table-shell],
  [class$="-table-wrap"],
  [class*="-table-wrap"]
):not([data-bd-table-scroll="off"]) {
  max-width: 100% !important;
  min-width: 0 !important;
  overflow-x: auto !important;
  -webkit-overflow-scrolling: touch !important;
  overscroll-behavior-x: contain;
  /* Let vertical wheel/trackpad scrolling continue into the page at boundaries. */
  overscroll-behavior-y: auto !important;
  touch-action: auto;
  scrollbar-width: thin;
}

body :where(.bd-table-shell, .acct-table-shell) {
  max-width: 100% !important;
  min-width: 0 !important;
}

body :where(
  .table-responsive,
  .bd-table-shell__scroll,
  .bd-table-wrap,
  .bd-table-scroll,
  .acct-table-wrap,
  .acct-table-shell,
  .inv-table-wrap,
  .settings-table-wrapper,
  [data-table-scroll],
  [data-std-table-shell],
  [data-ap-table-shell],
  [data-ar-table-shell],
  [data-acct-table-shell],
  [class$="-table-wrap"],
  [class*="-table-wrap"]
) > :where(table, .table, .bd-table, .acct-table) {
  width: max-content;
  min-width: 100%;
  margin-bottom: 0 !important;
}

/* Fallback for older surfaces that put a table directly in a card/panel without
   a .table-responsive wrapper. CSS cannot create a wrapper, so the immediate
   container becomes the horizontal scroll host. */
html body :is(
  .bd-card,
  .card,
  .bd-subcard,
  .bd-tab-card__table,
  .std-work-panel,
  .modal-body,
  .offcanvas-body,
  .tab-pane
):has(> :is(table, .table, .bd-table, .acct-table)):not([data-bd-table-scroll="off"]) {
  max-width: 100% !important;
  min-width: 0 !important;
  overflow-x: auto !important;
  -webkit-overflow-scrolling: touch !important;
  overscroll-behavior-x: contain;
  /* Let vertical wheel/trackpad scrolling continue into the page at boundaries. */
  overscroll-behavior-y: auto !important;
  touch-action: auto;
}

body :where(
  .bd-card,
  .card,
  .bd-subcard,
  .bd-tab-card__table,
  .std-work-panel,
  .modal-body,
  .offcanvas-body,
  .tab-pane
):has(> :where(table, .table, .bd-table, .acct-table)) > :where(table, .table, .bd-table, .acct-table) {
  width: max-content;
  min-width: 100%;
}

.text-uppercase { text-transform: none !important; }

.menu-title, .bd-chip { text-transform: none !important; }

.text-uppercase, .menu-title, .bd-chip { letter-spacing: normal !important; }

.ts-wrapper { min-width: 0; }
.ts-wrapper .ts-control {
  min-height: 38px;
  border: 1px solid var(--bd-theme-border-strong, #111) !important;
  border-radius: .5rem !important;
  padding: .28rem 2rem .28rem .6rem !important;
  background: var(--bd-theme-surface, #fff) !important;
  color: var(--bd-theme-text, #111827) !important;
  box-shadow: none !important;
  font-size: .84rem;
}
.ts-wrapper.single .ts-control { cursor: pointer; }
.ts-wrapper.single:not(.no-caret) .ts-control::after {
  content: "\F0140";                       /* mdi-chevron-down */
  font-family: "Material Design Icons";
  position: absolute;
  right: .5rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 1.05rem;
  line-height: 1;
  color: var(--bd-theme-text-muted, #667085);
  pointer-events: none;
}
.ts-wrapper.single.dropdown-active .ts-control::after { content: "\F0143"; } /* chevron-up */
.ts-wrapper.focus .ts-control { outline: 2px solid var(--bd-theme-accent, #111); outline-offset: 1px; }
.ts-wrapper.disabled .ts-control { opacity: .55; cursor: default; }

.ts-dropdown {
  border: 1px solid var(--bd-theme-border-strong, #111) !important;
  border-radius: .5rem !important;
  background: var(--bd-theme-surface, #fff) !important;
  color: var(--bd-theme-text, #111827) !important;
  box-shadow: 0 .5rem 1.2rem var(--bd-theme-shadow-0f172a-24, rgba(15,23,42,.14)) !important;
  margin-top: 2px;
}
.ts-dropdown .option { padding: .4rem .55rem; font-size: .82rem; }
.ts-dropdown .option.active,
.ts-dropdown .option:hover { background: var(--bd-theme-accent-soft, #eef3f8) !important; color: var(--bd-theme-text, #111827) !important; }
.ts-dropdown .no-results { padding: .5rem .55rem; color: var(--bd-theme-text-muted, #667085); font-size: .8rem; }

/* A single-value select is an input, not a selected-token rail. The value stays
   plain inside the control; bordered removable rectangles belong to multi-selects. */
.ts-wrapper.single .ts-control > .item {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  color: inherit !important;
  font: inherit !important;
  line-height: 1.35 !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ts-wrapper.multi .ts-control > .item {
  border: 1px solid var(--bd-theme-border, #d0d5dd) !important;
  border-radius: .375rem !important;
  background: var(--bd-theme-surface-muted, #f8fafc) !important;
  color: var(--bd-theme-text, #111827) !important;
  font-size: .76rem;
  font-weight: 800;
}

.bd-mask-shell { position: relative; display: inline-flex; align-items: center; width: 100%; }
.bd-mask-shell > i.mdi {
  position: absolute;
  left: .55rem;
  color: var(--bd-theme-text-muted, #667085);
  font-size: 1rem;
  line-height: 1;
  pointer-events: none;
}
.bd-mask-shell.is-trailing > i.mdi { left: auto; right: .55rem; }
.bd-mask-shell > .form-control.bd-masked-input,
.bd-mask-shell > .bd-input.bd-masked-input,
.bd-mask-shell > .bd-masked-input {
  width: 100%;
  /* discovery.css gives every .form-control compact !important padding.
     The decorated-input inset must win that cascade or typed text clips the
     leading MDI glyph. */
  padding-left: 2.1rem !important;
}
.bd-mask-shell.is-trailing > .form-control.bd-masked-input,
.bd-mask-shell.is-trailing > .bd-input.bd-masked-input,
.bd-mask-shell.is-trailing > .bd-masked-input {
  padding-left: .6rem !important;
  padding-right: 2.1rem !important;
}
.bd-num-align { text-align: right; font-variant-numeric: tabular-nums; }

/* ====================================================================== */
/* ROUNDED SURFACES KEEP THEIR CORNERS                                     */
/* ====================================================================== */
.bd-card > :first-child,
.card > :first-child,
.bd-tab-card > :first-child,
.std-work-shell > :first-child,
.std-mainstay > :first-child,
.estimate-list-shell > :first-child,
.bd-work-card > :first-child {
  border-top-left-radius: inherit !important;
  border-top-right-radius: inherit !important;
}

.bd-card > :last-child,
.card > :last-child,
.bd-tab-card > :last-child,
.std-work-shell > :last-child,
.std-mainstay > :last-child,
.estimate-list-shell > :last-child,
.bd-work-card > :last-child {
  border-bottom-left-radius: inherit !important;
  border-bottom-right-radius: inherit !important;
}

.bd-card > .bd-card-head + *,
.card > .card-header + *,
.std-work-shell > .std-work-shell__head + * {
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
}

.bd-table-wrap > table > thead > tr:first-child > th:first-child,
.table-responsive > table > thead > tr:first-child > th:first-child { border-top-left-radius: inherit !important; }
.bd-table-wrap > table > thead > tr:first-child > th:last-child,
.table-responsive > table > thead > tr:first-child > th:last-child { border-top-right-radius: inherit !important; }

/* ====================================================================== */
/* LOADING ACTIVITY USES A CIRCLE, NEVER A SPINNING PICTOGRAM              */
/* ====================================================================== */
.mdi.mdi-spin {
  animation: none !important;
}

.mdi.mdi-spin::before {
  content: "" !important;
  display: block;
  width: .9em;
  height: .9em;
  box-sizing: border-box;
  border: 2px solid color-mix(in srgb, currentColor 24%, transparent);
  border-top-color: currentColor;
  border-right-color: currentColor;
  border-radius: 50%;
  animation: bd-loading-circle-spin .72s linear infinite;
}

@keyframes bd-loading-circle-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .mdi.mdi-spin::before { animation: none; }
}

/* ====================================================================== */
/* APP-WIDE LABELED ACTION CONTRACT                                        */
/* ====================================================================== */
/*
 * /standards/ defines one geometry for ordinary labeled actions regardless
 * of whether an older surface calls the component .btn, .bd-btn, or
 * .std-btn-sample. Keep row action strips and choice cards on their own
 * contracts; this adapter removes the visible size/radius drift everywhere
 * else, including HTMX fragments and modal footers.
 */
html body :is(.btn, .bd-btn, .std-btn-sample):not(.bd-action-strip__btn):not(.std-action):not([hidden]):not(.d-none) {
  min-height: 36px !important;
  border-radius: .6rem !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: .42rem !important;
  padding: .42rem .72rem !important;
  font-weight: 800 !important;
  line-height: 1.2 !important;
}

html body :is(.btn-sm, .bd-btn-sm, .std-btn-sample.is-compact):not(.bd-action-strip__btn) {
  min-height: 32px !important;
  padding: .32rem .6rem !important;
  font-size: .78rem !important;
}

html body :is(.btn-lg, .bd-btn-lg, .std-btn-sample.is-touch):not(.bd-action-strip__btn) {
  min-height: 44px !important;
  padding: .55rem .85rem !important;
}

html body :is(.btn, .bd-btn, .std-btn-sample):not(.bd-action-strip__btn) > .mdi {
  flex: 0 0 auto;
  margin: 0 !important;
  font-size: 1rem;
  line-height: 1;
}

/* Preserve a single perimeter for genuine joined Bootstrap groups after the
 * global radius adapter above. */
html body .btn-group > :is(.btn, .bd-btn):not(:first-child):not(:last-child) {
  border-radius: 0 !important;
}
html body .btn-group > :is(.btn, .bd-btn):first-child:not(:last-child) {
  border-radius: .6rem 0 0 .6rem !important;
}
html body .btn-group > :is(.btn, .bd-btn):last-child:not(:first-child) {
  border-radius: 0 .6rem .6rem 0 !important;
}

html body :is(.btn, .bd-btn, .std-btn-sample):is(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
  opacity: .55;
  cursor: default;
  pointer-events: none;
}

/* A footer is one toolbar. Local modal CSS may choose its layout, but it may
 * not silently invent another button height, radius, weight, or icon gap. */
html body .bdm2 .std-modal-foot :is(.btn, .bd-btn, .std-btn-sample),
html body .modal-footer :is(.btn, .bd-btn, .std-btn-sample) {
  min-height: 36px !important;
  border-radius: .6rem !important;
  padding: .42rem .72rem !important;
  font-weight: 800 !important;
  gap: .42rem !important;
}

@media (max-width: 767.98px), (pointer: coarse) {
  html body .bdm2 .std-modal-foot :is(.btn, .bd-btn, .std-btn-sample),
  html body .modal-footer :is(.btn, .bd-btn, .std-btn-sample) {
    min-height: 44px !important;
  }
}
