.select2-results__option[aria-selected="true"],
.select2-results__option[aria-disabled="true"] {
  display: none;
}
.select2-container--disabled .select2-selection {
  background-color: var(--bs-gray-400) !important;
}
#sticky-filters .select2-selection__choice {
  background-color: var(--bs-green);
}

.tableSearch td {
  padding: 0.75rem;
}

#filters .select2-selection__choice {
  background-color: var(--bs-red);
}
#filters select {
  max-width: 50%;
}
#filters table {
  width: 100%;
}
#filters th {
  text-align: center;
}
#filters td {
  vertical-align: top;
}

#datasheet-tables {
  margin-left: 0;
}

/* Shared surface contract for tables, cards and product-owned standalone results. A custom entry
   can opt in with .datasheet-surface and sit directly before/after the built-in sections without
   changing border, radius, shadow or rhythm. */
#datasheet {
  --datasheet-surface-bg: var(--bs-body-bg, #fff);
  --datasheet-surface-border: var(--sl-200, var(--bs-border-color, #dee2e6));
  --datasheet-surface-radius: var(--shell-radius-lg, var(--bs-border-radius-lg, 8px));
  --datasheet-surface-shadow: 0 1px 3px rgba(0, 0, 0, .05);
  /* One rhythm between every box on a datasheet page, the header box included. A pixel value, not
     0.75rem: the theme's root size is 14.4px, and 10.8px next to the shell's 12px gaps read as uneven. */
  --datasheet-surface-gap: 12px;
}

#datasheet .datasheet-surface {
  background: var(--datasheet-surface-bg);
  border: 1px solid var(--datasheet-surface-border);
  border-radius: var(--datasheet-surface-radius);
  box-shadow: var(--datasheet-surface-shadow);
}

#datasheet-tables > .datasheet-entry {
  margin-right: 0;
  margin-bottom: var(--datasheet-surface-gap);
  margin-left: 0;
}

#datasheet-tables > .datasheet-entry:last-child {
  margin-bottom: 0;
}

/* A collection just added through "Add collection" (table.js, addCollectionToPage): scrolled to below the sticky
   header, and outlined in the primary colour for a moment so the eye finds where it went. */
#datasheet .datasheet-entry--table {
  scroll-margin-top: calc(var(--datasheet-sticky-offset, 0px) + var(--datasheet-surface-gap, 12px));
}

#datasheet .datasheet-entry--added {
  border-radius: var(--datasheet-surface-radius, 8px);
  animation: datasheet-entry-added 2.4s ease-out;
}

@keyframes datasheet-entry-added {
  0%, 60% { box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb, 255, 105, 0), .45); }
  100% { box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb, 255, 105, 0), 0); }
}

@media (prefers-reduced-motion: reduce) {
  #datasheet .datasheet-entry--added {
    animation: none;
    box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb, 255, 105, 0), .45);
  }
}

/* Tabs render their entries with wrapperClass='row' (entry-renderer.html), and Bootstrap's .row > * gutter
   padding then landed on the entry's content: every section card sat 0.75rem inside the header box on both
   sides, while a product's own block beside it (an embedded search) ran to the full width. That content is a
   .table-wrapper for a table and the .datasheet-section box for a title, card or accordion section. */
#datasheet-tables > .datasheet-entry > * {
  padding-left: 0;
  padding-right: 0;
}

#datasheet-tables > .datasheet-entry .table-wrapper,
#datasheet-tables > .datasheet-entry .datasheet-surface {
  margin-bottom: 0;
}

#datasheet .table-wrapper {
  margin-bottom: 20px;
}

#datasheet h3 {
  margin-bottom: 15px;
}

#datasheet table {
  margin-bottom: 0;
  min-width: 100%;
}

#datasheet .edit-enabled table {
  width: max-content;
}

#datasheet .table-wrapper .edit-enabled .input-group {
  display: flex;
  flex-wrap: nowrap; /* Prevent breaking into multiple lines */
  align-items: center;
  min-width: fit-content; /* Prevents excessive shrinking */

}

#datasheet .header-title {
  margin-bottom: 0;
}

#datasheet .clear-row-filters {
  cursor: pointer;
}

#datasheet .reset-row-filters {
  cursor: pointer;
}

.table > tbody > :not(caption) > * > * {
  text-align: center;
}

#datasheet .filters-section {
  margin-bottom: var(--datasheet-surface-gap);
}

#datasheet .filter-row:not(:last-child) {
  margin-bottom: 10px;
}

.filter-toggle-buttons {
  align-self: last baseline;
}

#datasheet-tables thead {
  z-index: 0 !important;
}

#datasheet-tables td:focus, td.active-cell {
  border: 3px solid var(--bs-primary) !important;
}

.table-edit-button {
  position: absolute;
  right: 0;
  top: 0;
  padding: 0.3rem;
}

.hidden {
  display: none;
}

td.edit-table-action-bar {
  width: 40px;
}

.scrollable-x {
  overflow-x: auto;
}

.scrollable-y {
  overflow-x: auto;
}

.scrollable {
  overflow: auto;
}

.cursor-pointer {
    cursor: pointer;
}

.hover-highlight:hover {
  color: var(--bs-primary);
}

.table-edit-parent {
  position: relative;
}

/* search.css sets .mdi-close to primary; reset for toolbar cancel icon */
.table-edit-button .table-edit-cancel-button {
  color: inherit;
}


/* Adjust the parent container to handle overflow */
#edit-dropdown-parent {
  position: relative;
  overflow: visible; /* Allow overflow to be visible */
}

.scrollable-class {
  overflow-x: auto;
}

.edit-table table td {
  width: auto;
  white-space: nowrap;
}

.v-select {
  background-color: white;
}

tr.table-row-highlight td {
  background-color: var(--bs-primary);
}

tr.table-row-highlight {
  background-color: var(--bs-primary);
}

td.highlight-cell {
  background-color: rgba(var(--bs-primary-rgb), 0.15);
  box-shadow: unset;
}

/* Element history (AP-6009). "Show changes" off: a past revision reads like a plain datasheet. */
html.datasheet-history-hide-changes td.highlight-cell,
html.datasheet-history-hide-changes .table-cell.highlight-cell {
  background-color: transparent;
}
/* Comparing two revisions: "old → new" in a changed cell. */
.datasheet-history-old {
  text-decoration: line-through;
  opacity: 0.7;
}
.element-history-table .rev-no,
.element-history-table .rev-when {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.element-history-table .rev-no {
  font-weight: 600;
}
.element-history-table tr.selected > td {
  background-color: rgba(var(--bs-primary-rgb), 0.08);
}
.element-history-table tr.shown > td:first-child {
  box-shadow: inset 3px 0 0 var(--bs-primary);
}

/* extra */
   /* Ensure custom styles have higher specificity */
.datasheet-collection .card {
   border: 1px solid var(--datasheet-surface-border);
   border-radius: var(--datasheet-surface-radius);
   box-shadow: var(--datasheet-surface-shadow);
   margin-bottom: 20px;
 }
.datasheet-collection .card-header {
  padding-top: 16px;
  padding-bottom: 0px;
  padding-left: 16px;
  padding-right: 16px;
  border-bottom: none;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  background-color: var(--bs-body-bg, #ffffff);
}
.datasheet-collection .card-title {
  font-size: 1.25rem;
  color: var(--t-ink-strong, #333);
  margin-bottom: 0;
  font-weight: 600;
}
.datasheet-collection .card-body {
  padding: 0;
}
.datasheet-collection .table-responsive {
  overflow-x: auto;
}
.datasheet-collection .table {
  width: 100%;
  margin-bottom: 1rem;
  color: var(--t-ink-strong, #212529);
  border-collapse: collapse;
  border-spacing: 0;
}
.datasheet-collection .table thead {
  background-color: transparent;
}
.datasheet-collection .table thead th {
  border-bottom: 2px solid var(--bs-border-color, #e0e0e0);
  padding: 12px;
  vertical-align: bottom;
  text-align: left;
  font-weight: 500;
  color: var(--bs-secondary-color, #444);
}
.datasheet-collection .table tbody tr {
  border-bottom: 1px solid var(--bs-border-color, #e0e0e0);
}
.datasheet-collection .table tbody tr:last-child {
  border-bottom: none;
}
.datasheet-collection .table tbody td {
  padding: 0.5rem;
  vertical-align: top;
}
.datasheet-collection .table-striped tbody tr:nth-of-type(odd) {
  background-color: var(--t-stripe, rgba(0, 0, 0, 0.05));
}

/* Custom CSS Classes */
.datasheet-collection table.custom-table-class {
  border-radius: 5px;
}
.datasheet-collection table.custom-table-class thead th.custom-header-class{
  background-color: var(--bs-gray-100, #f8f9fa);
  color: #0c3001;
}
.datasheet-collection table.custom-table-class tbody td.custom-cell-class {
  color: #084a91;
}
.datasheet-collection table.custom-table-class  b.custom-footnote-class{
  color: #b81111;
  font-weight: bolder;
}
.datasheet-collection table.custom-table-class  td.custom-footnote-text{
  font-size: 0.8rem;
}
.datasheet-collection table.custom-table-class  span.custom-footnote-index{
  font-size: 1rem;
}

/* Sticky Header */
.datasheet-collection thead.custom-sticky-header {
  position: sticky;
  top: 0;
  z-index: 1;
  background-color: var(--bs-gray-300);
}

:not(.table-transposed) tbody tr:last-child > td {
  border-bottom: unset;
}

:not(.table-transposed) tbody tr td:first-child, :not(.table-transposed) thead tr th:first-child {
  border-left: unset;
}

:not(.table-transposed) tbody tr td:last-child, :not(.table-transposed) thead tr th:last-child {
  border-right: unset;
}

.table-transposed tbody th {
  border-left: unset;
}

.table-transposed tbody tr td:last-child {
  border-right: unset;
}

.table-transposed tbody tr:last-child th, .table-transposed tbody tr:last-child td {
  border-bottom: unset;
}

.datasheet-collection .edit-enabled.table-transposed tfoot tr td:first-child, .datasheet-collection .edit-enabled.table-transposed tfoot tr th:first-child {
  border-left: unset;
}

.datasheet-collection .edit-enabled.table-transposed tfoot tr td:last-child, .datasheet-collection .edit-enabled.table-transposed tfoot tr th:last-child {
  border-right: unset;
}

.datasheet-collection .edit-enabled.table-transposed tfoot tr td, .datasheet-collection .edit-enabled.table-transposed tfoot tr th {
  border-bottom: unset;
  border-top: 1px solid var(--bs-body-bg, #fff);
}

#datasheet-header {
  z-index: 3;
  position: fixed;
  top:70px;
  width: 90%;
}

/*
 * On the page shell (template-v3) the header sticks instead of being fixed.
 *
 * The fixed version above is measured against Minton's chrome: a 70px fixed topbar, and a width
 * sticky-header-handler.js computes as "viewport minus the sidebar", plus a padding-top on the
 * content to make room for a header that left the flow. None of that holds on the shell - its
 * topbar is --shell-topbar-h (56px) tall, the sidebar collapses to a 64px rail and is an off-canvas
 * drawer below 768px whose offsetWidth still reads 232px - so the fixed header left a gap under
 * the topbar and was the wrong width at every breakpoint but one.
 *
 * The shell's document scrolls and .shell-content clips rather than hides overflow, so sticky
 * works against the viewport: the header stays in the flow (no padding compensation, which the
 * handler skips on the shell) and takes the width of the content column at any sidebar state.
 * The fallback matches shell.css.
 */
body.shell #datasheet-header {
  position: sticky;
  top: var(--shell-topbar-h, 56px);
  width: auto !important;
}

/*
 * The datasheet on the dense shell layout (datasheet.html sets shellDense; searchui-library shell.css).
 *
 * The shell's gutter is 6px there (--shell-pad); these take the datasheet's own spacing down to the same
 * 6px. Before, a section sat inside four layers of it: the header row's 8px and its card's 16px below
 * the header, the outer white card's 16px padding plus the tab content's 20px top margin, and 60px
 * between two sections (custom.css's 20px above .datasheet-collection, 20px below its card and 20px
 * below .table-wrapper). Now:
 *
 *  - the header row spans exactly the content column (no gutter overhang); as a sticky element it still
 *    sits flush under the topbar, and the page's ground behind it - including the 0.75rem below its
 *    box, which is padding rather than margin for that reason - keeps rows from showing through;
 *  - the outer card that wrapped every tab is no longer drawn: each section is its own box on the page
 *    ground, drawn exactly like the header's box (the shell's .card: slate-200 border, 8px radius, its
 *    shadow), with the same left and right edges, and --datasheet-surface-gap (12px) from the next box -
 *    the same gap as between the header box and the first section. A product block a tab embeds (the
 *    search table of an order's tests) and the cards of a product tab (approval, documents) keep that
 *    look and rhythm too, so a tab reads as one column of aligned cards;
 *  - inside a card the heading and the first and last table column sit 16px from its edge, the inset
 *    of an embedded search's controls, while the table's header band and rules run to the card's edge;
 *  - the section heading is the template-v1 one again. Its size already matched (1.35rem bold in a
 *    44px line with 0.5rem padding, 24px action icons); what read as bigger was the shell's typeface and
 *    slate colour, so the heading and the transpose label take the theme's body font and colour, which
 *    is what template-v1 drew them in, and the toggle gets v1's 1.5 line box. A 0.25rem gap separates
 *    the heading line from its table.
 *
 * body.shell.shell-dense outranks every datasheet rule it overrides here, including body.shell ones and
 * the section card of the table style (body.shell .datasheet-collection .card).
 */
/* Printed, the topbar is gone (shell.css) but top: 56px still pushed the sticky header that far down the
   first page, over the first section's heading. On paper it is simply the top of the page. */
@media print {
  body.shell #datasheet-header {
    position: static;
  }
}

/* !important: the header row carries .pb-2, an !important utility, so the 0.75rem that stood here never
   applied and the first section sat 7px under the header box instead. */
body.shell.shell-dense #datasheet-header {
  margin: 0;
  padding-bottom: var(--datasheet-surface-gap) !important;
  background: var(--bs-gray-100, #f8f9fa);
}

body.shell.shell-dense #datasheet-header > .col-12 {
  padding-left: 0;
  padding-right: 0;
}

body.shell.shell-dense #datasheet-header .card {
  margin-bottom: 0;
}

body.shell.shell-dense #datasheet-header .card-body {
  padding: 8px 12px 0;
}

body.shell.shell-dense .datasheet-content {
  margin-left: 0;
  margin-right: 0;
}

body.shell.shell-dense .datasheet-content > .col-12 {
  padding-left: 0;
  padding-right: 0;
}

body.shell.shell-dense .datasheet-content > .col-12 > .card {
  margin-bottom: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body.shell.shell-dense .datasheet-content > .col-12 > .card > .card-body {
  padding: 0;
}

body.shell.shell-dense .tab-content.datasheet {
  margin-top: 0;
}

body.shell.shell-dense #datasheet .table-wrapper {
  margin-top: 0;
  margin-bottom: 0;
}

/* Cards a product tab stacks with Bootstrap's .mt-3 (1rem, an !important utility) keep the page's rhythm. */
body.shell.shell-dense .tab-content.datasheet .card.mt-3 {
  margin-top: var(--datasheet-surface-gap) !important;
}

/*
 * A search table a tab embeds (<search-table> from searchui-library, e.g. the tests of an order) is drawn as
 * one more section card: the datasheet's border, radius and shadow instead of Bootstrap's .border/.rounded,
 * its controls 16px in, and its result grid running to the card's edges like a datasheet table.
 *
 * Two ids: search.css's body.shell-dense #searchTable .search-page__table sets 8px !important padding, and
 * it has to keep doing that on the search page itself.
 */
body.shell.shell-dense #datasheet #datasheet-tables .search-page__table {
  background: var(--datasheet-surface-bg);
  border: 1px solid var(--datasheet-surface-border) !important;
  border-radius: var(--datasheet-surface-radius) !important;
  box-shadow: var(--datasheet-surface-shadow);
  padding: 12px 16px !important;
}

body.shell.shell-dense #datasheet #datasheet-tables .search-page__table .search-table {
  width: calc(100% + 32px);
  max-width: none;
  margin-left: -16px;
  margin-right: -16px;
}

/*
 * Sections (components/datasheet/section-*.html) in the same column of cards.
 *
 * Measured on a Digilab LCF test's results tab: every section style carries .mb-4 (1.5rem, !important), so two
 * sections were 34px apart - that plus the entry's own gap - and an accordion kept Bootstrap's look (grey
 * border, 5px radius, no shadow) with 18px of body padding around its tables, which were cards of their own.
 *
 *  - title:     the heading on the page ground, its entries below it as cards, one gap apart;
 *  - card and accordion: the section is the card. Its header (the toggle, for an accordion) takes the
 *    heading's 16px inset, and what it holds runs to its edges: a table inside is not a second card but
 *    part of this one, separated from its neighbour by a rule; a diagram or custom block gets 16px.
 */
body.shell.shell-dense #datasheet .datasheet-entry > .datasheet-section {
  margin-bottom: 0 !important;
}

body.shell.shell-dense #datasheet .datasheet-section-title > .datasheet-section-heading {
  margin: 0 0 8px;
}

body.shell.shell-dense #datasheet .datasheet-section-content > .datasheet-entry + .datasheet-entry {
  margin-top: var(--datasheet-surface-gap);
}

body.shell.shell-dense #datasheet .datasheet-section-accordion > .accordion-item,
body.shell.shell-dense #datasheet .datasheet-section-card > .card {
  margin-bottom: 0;
  overflow: hidden;
  background: var(--datasheet-surface-bg);
  border: 1px solid var(--datasheet-surface-border);
  border-radius: var(--datasheet-surface-radius);
  box-shadow: var(--datasheet-surface-shadow);
}

body.shell.shell-dense #datasheet .datasheet-section-accordion .accordion-button {
  padding: 10px 16px;
  border-radius: 0;
  box-shadow: none;
}

body.shell.shell-dense #datasheet .datasheet-section-accordion .accordion-button:not(.collapsed) {
  border-bottom: 1px solid var(--datasheet-surface-border);
}

body.shell.shell-dense #datasheet .datasheet-section-card > .card > .card-header {
  padding: 10px 16px;
}

body.shell.shell-dense #datasheet .datasheet-section-accordion .accordion-body,
body.shell.shell-dense #datasheet .datasheet-section-card > .card > .card-body {
  padding: 0;
}

body.shell.shell-dense #datasheet :is(.accordion-body, .datasheet-section-card .card-body) .datasheet-collection .card {
  margin-bottom: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

body.shell.shell-dense #datasheet :is(.accordion-body, .datasheet-section-card .card-body) > .datasheet-entry + .datasheet-entry {
  border-top: 1px solid var(--datasheet-surface-border);
}

body.shell.shell-dense #datasheet :is(.accordion-body, .datasheet-section-card .card-body) > :is(.datasheet-entry--diagram, .datasheet-entry--custom) {
  padding: 12px 16px;
}

/* A lazy accordion's spinner, and its empty or error text, keep their room inside the now unpadded body. */
body.shell.shell-dense #datasheet .datasheet-section-accordion .datasheet-lazy-section-placeholder {
  padding-left: 16px;
  padding-right: 16px;
}

body.shell.shell-dense .datasheet-collection {
  margin-top: 0;
}

/* The header box's look, from the same custom properties shell.css draws body.shell .card with. */
body.shell.shell-dense .datasheet-collection .card {
  margin-bottom: var(--datasheet-surface-gap);
  background: var(--datasheet-surface-bg);
  border: 1px solid var(--datasheet-surface-border);
  border-radius: var(--datasheet-surface-radius);
  box-shadow: var(--datasheet-surface-shadow);
}

body.shell.shell-dense .datasheet-collection .datasheet-table-header {
  margin-bottom: 0.25rem;
  /* .p-2 is !important; the vertical 0.5rem stays. */
  padding-left: 16px !important;
  padding-right: 16px !important;
}

/* The first and last column line up with the heading. Not while editing: the first column is then the
   40px edit-menu column. */
body.shell.shell-dense .datasheet-collection :not(.edit-enabled) > .standardTable > table > * > tr > :first-child,
body.shell.shell-dense .datasheet-collection .transposedTable:not(.edit-enabled) > table > * > tr > :first-child {
  padding-left: 16px;
}

body.shell.shell-dense .datasheet-collection :not(.edit-enabled) > .standardTable > table > * > tr > :last-child,
body.shell.shell-dense .datasheet-collection .transposedTable:not(.edit-enabled) > table > * > tr > :last-child {
  padding-right: 16px;
}

body.shell.shell-dense .datasheet-collection .datasheet-table-header .collection-name,
body.shell.shell-dense .datasheet-collection .datasheet-table-header__toggles .form-check-label {
  font-family: var(--bs-body-font-family);
  color: var(--bs-body-color, #746660);
}

body.shell.shell-dense .datasheet-collection .datasheet-table-header__toggles .form-check {
  min-height: 1.5em;
}

body.shell.shell-dense .datasheet-collection .datasheet-table-header__toggles .form-check-label {
  line-height: 1.5;
}

.datasheet-tab-link {
  background-color: var(--bs-body-bg, #fff) !important;
}

.right-panel {
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: var(--bs-body-bg, #fff);
    box-shadow: -2px 0 5px rgba(0, 0, 0, 0.3);
    overflow-y: auto;
    z-index: 10000; /* Ensures it overlaps other elements */
    display: none;
}

.right-panel.active {
    display: block; /* Show the panel when clicked */
}

.resizer {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 12px;
    cursor: ew-resize;
    display: flex;
    align-items: center;
    justify-content: center;
}

.resizer:hover {
    border-left: 2px solid var(--bs-primary);
}

.resizer::before {
    content: '⋮⋮'; /* Vertical dots symbol */
    font-size: 1rem;
    color: var(--t-ink-strong, rgba(0, 0, 0, 0.8));
    font-weight: bold;
}

/*
 * Footer overlap fix.
 * The app footer is position:absolute; bottom:0 inside .content-page, which only
 * reserves 55px of bottom padding (app.min.css). With the extra "Version" and
 * "Server" lines this footer is taller than that, so it overlaps the last page
 * content (the "Add New Collection" button) and the fixed jump-to-top button.
 * Reserve enough space and lift the floating button clear of the footer.
 */
.content-page {
    padding-bottom: 110px !important;
}

/* Only where it still positions itself - a layout without the shell's floating actions. In the stack the
   stack places it, and an id rule here would outrank the stack's own !important placement. */
#jumpToTopBtn:not(.shell-floating-action) {
    position: fixed;
    right: 30px;
    bottom: 100px;
    z-index: 1040;
}

/* ---------------------------------------------------------------------------
 * Round floating buttons: jump to top and add collection (datasheet.html,
 * new-collection-modal.html). On the shell both sit in the floating actions
 * stack, above the assistant's launcher; see searchui-library docs/page-shell.md.
 * 36px with an 18px icon, 32px with a 16px icon on a phone - the smallest
 * comfortable hit area, and deliberately smaller than the assistant's launcher
 * (40px) below them, which stays the anchor of the stack.
 * ------------------------------------------------------------------------- */
.datasheet-fab {
    width: 36px;
    height: 36px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.datasheet-fab .mdi {
    color: #fff;
    font-size: 18px;
    line-height: 1;
}

@media (max-width: 575.98px) {
    .datasheet-fab {
        width: 32px;
        height: 32px;
    }

    .datasheet-fab .mdi {
        font-size: 16px;
    }

    /* Centred over the assistant's 40px launcher circle rather than flush with its right edge. */
    .shell-floating-actions > #jumpToTopBtn,
    .shell-floating-actions > .datasheet-action-menu {
        margin-right: 4px;
    }
}

/* z-index: the open drop-up is drawn over the jump-to-top above it in the stack. */
.datasheet-action-menu {
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: flex-end;
}

.datasheet-action-menu[hidden] {
    display: none !important;
}

/* A layout without the floating actions: where the old button was, at the end of the content. */
.datasheet-action-menu--inline {
    margin-top: 8px;
}

/* The drop-up: above the button, right-aligned with it, so it opens into the page rather than off the
   right edge. The script caps max-height to the room above the button; the list scrolls past that. */
.datasheet-action-menu-list {
    position: absolute;
    top: auto;
    left: auto;
    right: 0;
    bottom: calc(100% + 8px);
    min-width: 220px;
    max-width: min(320px, calc(100vw - 24px));
    max-height: 60vh;
    overflow-y: auto;
    margin: 0;
}

.datasheet-action-menu-list .dropdown-item {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* An entry that is shown but unavailable (add_collection.unavailable_hint_key): muted like Bootstrap's .disabled, but
   still hoverable and focusable so its title tooltip and aria-describedby hint reach the user. */
.datasheet-action-menu-list .dropdown-item[aria-disabled="true"] {
    color: var(--bs-secondary-color, #6c757d);
    cursor: not-allowed;
}

.datasheet-action-menu-list .dropdown-item[aria-disabled="true"]:hover,
.datasheet-action-menu-list .dropdown-item[aria-disabled="true"]:active {
    background-color: transparent;
    color: var(--bs-secondary-color, #6c757d);
}

/* The menu's only action shown as the button itself, and unavailable: muted, but still hoverable for its hint. */
.datasheet-action-menu-toggle[aria-disabled="true"] {
    opacity: 0.65;
    cursor: not-allowed;
}

@media print {
    #jumpToTopBtn,
    .datasheet-action-menu {
        display: none !important;
    }
}

.vs--searchable .vs__dropdown-toggle {
    height: 30px;
}

/* ---------------------------------------------------------------------------
 * Bounded table scrolling and sticky headers
 *
 * The old sticky header (thead.custom-sticky-header, further up) sticks against
 * the PAGE: the page scrolls vertically, so top:0 worked, but horizontal
 * scrolling happens inside .table-responsive, which the page knows nothing
 * about. Scroll sideways and the header slid out from over its own columns.
 *
 * Making the table's own wrapper the scroll container fixes both axes at once,
 * because then the header and the body scroll together in one box. That only
 * works if the box has a height to scroll within, which is what the max-height
 * is for - the table stops growing the page and scrolls instead.
 *
 * --datasheet-table-max-height is set per table from the resolved
 * TableViewOptions.maxHeight; the fallback here matches the Java default.
 *
 * On top of that the box never grows taller than the room under the sticky
 * datasheet header: --datasheet-sticky-offset is the header's bottom edge,
 * published by sticky-header-handler.js, and --datasheet-table-below is what the
 * table draws under its box (the pagination bar). Scroll the page until the
 * table's box meets the header and the whole box is on screen - its last rows,
 * and above all its horizontal scrollbar, which a fixed 70vh left below the fold.
 * The 12rem floor keeps a usable box on a short landscape phone.
 *
 * --datasheet-table-gap is what stays free below the box. It is not decoration:
 * the page carries a floating jump-to-top button in that corner, and a box that
 * ends one hairline above the fold reads as a table that did not fit. A product
 * that wants the box tighter to the edge sets the variable; a table that wants it
 * shorter still sets its own max_height.
 * ------------------------------------------------------------------------- */
/* Every custom property below carries a literal fallback on purpose: the theme ships a
   Bootstrap 5.1 build, which has no --bs-border-color, and a declaration referencing an
   undefined custom property is dropped in full - producing no border rather than a default
   one, silently. */
.datasheet-table-scroll {
    overflow: auto;
    max-height: var(--datasheet-table-max-height, 100vh);
    max-height: min(var(--datasheet-table-max-height, 100vh),
                    max(12rem, calc(100vh - var(--datasheet-sticky-offset, 0px) - var(--datasheet-table-below, 0px) - var(--datasheet-table-gap, 3rem))));
    /* dvh where supported: the mobile browser's collapsing address bar is not part of the room. */
    max-height: min(var(--datasheet-table-max-height, 100dvh),
                    max(12rem, calc(100dvh - var(--datasheet-sticky-offset, 0px) - var(--datasheet-table-below, 0px) - var(--datasheet-table-gap, 3rem))));
}

/* Transposed, the headers are the first column. Pin it on the left edge so a
   table with many rows - drawn as many columns - keeps its labels in view while
   scrolling sideways. The cells carry Bootstrap's .position-relative, an
   !important utility, so only an !important sticky beats it; sticky still
   anchors the edit menu that is absolutely positioned inside the cell. */
.datasheet-table-scroll.transposedTable > table > tbody > tr > th {
    position: sticky !important;
    left: 0;
    z-index: 1;
    box-shadow: inset -1px 0 0 var(--bs-gray-300, #dee2e6);
}

.datasheet-table-scroll.transposedTable > table > thead > tr > th {
    position: sticky !important;
}

.datasheet-table-scroll.transposedTable > table > thead > tr > th:first-child {
    left: 0;
    z-index: 3;
}

.datasheet-table-scroll > table > thead > tr > th {
    position: sticky;
    top: 0;
    /* Above the cells, below the filter modal and any dropdown a header opens. */
    z-index: 2;
    /* Headers are .table-secondary, which is translucent; without an opaque
       background the rows scroll through visibly underneath. */
    background-color: var(--bs-gray-200, #e9ecef);
}

/* The transposed layout draws the same headers as the first column of tbody, where the rule above
   never reaches. They kept .table-secondary's own (warm) grey and, being in tbody, also took the
   striped and hover shades from table_classes - so pressing "Transpose" visibly recoloured every
   header. Give them the standard header's colour, and no row accent. */
.transposedTable > table > tbody > tr > th.table-secondary {
    background-color: var(--bs-gray-200, #e9ecef);
    --bs-table-accent-bg: transparent;
}

/* With border-collapse: collapse - what Bootstrap's .table uses, and what every
   existing datasheet table is drawn with - a collapsed border belongs to the
   table grid rather than to the cell, so it scrolls away from under a sticky
   header and leaves it floating. Painting the line inside the cell instead
   keeps it attached. Changing border-collapse would have been the other fix,
   and would have altered the look of every table on every datasheet. */
.datasheet-table-scroll > table > thead > tr > th {
    box-shadow: inset 0 -1px 0 var(--bs-border-color, var(--bs-gray-300, #dee2e6));
}

/* ---------------------------------------------------------------------------
 * The header title: cut with an ellipsis instead of stacking, like the search table's (search.js
 * draws its header label in a .text-truncate).
 *
 * A wrapping title stacks as many lines as its column is narrow: on a physical-properties table
 * "Mean Coefficient of Thermal Expansion (reference 20°C) [10^-6*K^-1]" took four of them, and a
 * header row 161px tall - a fifth of the screen - before a single value was in view. Two lines
 * take that to 64px.
 *
 * Two rather than one because a column is only as wide as its VALUES (see below), and a column of
 * three-digit numbers gives a title about ten characters: at one line this table read "Mean…",
 * "Thermal…", "Mean…", "Thermal…". The second line is what tells two neighbouring columns apart.
 *
 * The line box is what is clamped, NOT the wrapping: white-space stays normal, so the title still
 * contributes only its longest WORD to the column's intrinsic width, and the column is as wide as
 * its values need it to be. `white-space: nowrap` with text-overflow would read the same on screen
 * and cost the opposite: the title's whole length becomes the column's minimum, which on the same
 * table made it 2124px wide against 1447px - a horizontal scrollbar bought with nothing.
 *
 * The full title stays one hover away - the element carries it as its title attribute - and
 * --datasheet-header-lines takes a header to one line, or to three, without touching anything else.
 *
 * min-width: 0 is for the other direction: the title sits in a flex row next to the filter and
 * sort controls, and a flex item does not shrink below its content unless it is allowed to, so
 * without it a dragged-narrow column would push its controls out of the cell instead of cutting
 * the text.
 * ------------------------------------------------------------------------- */
.standardTable thead th .datasheet-column-title {
    display: -webkit-box;
    -webkit-line-clamp: var(--datasheet-header-lines, 2);
    line-clamp: var(--datasheet-header-lines, 2);
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-width: 0;
    /* Explicit, because the clamp needs the text to wrap to have a second line to cut at - and a
       table_classes list that carries DataTables' `nowrap` would otherwise take that away. */
    white-space: normal;
    /* Only a long single word can push a column wider than this - nothing else reaches it. */
    max-width: var(--datasheet-header-max-width, 12rem);
}

/* The column filter control. It sits INSIDE the header cell, so every pixel it takes is a pixel
   the table gets wider by - a column is only ever as narrow as its header. Bootstrap's .btn brings
   a line-height, a font-size and vertical padding that together add roughly a line of text to the
   header row; stripping them back leaves an icon about as tall as the header's own text, so the
   control costs the column its icon's width and the row nothing at all. */
.standardTable thead th .datasheet-column-filter {
    flex: 0 0 auto;
    line-height: 1;
    vertical-align: middle;
    background: none;
    box-shadow: none;
}

.standardTable thead th .datasheet-column-filter .mdi {
    font-size: 1rem;
    line-height: 1;
    vertical-align: middle;
}

/* Greyed out, not gone: a column the other filters have narrowed to a single value keeps its
   control so the header does not reflow under the reader while they are filtering. Bootstrap's
   own :disabled opacity is on the button, which would fade the whole thing to near-invisible at
   this size - the icon alone is faded instead, and the cursor says why. */
.standardTable thead th .datasheet-column-filter:disabled {
    opacity: 1;
    cursor: default;
    pointer-events: auto;
}

.standardTable thead th .datasheet-column-filter:disabled .mdi {
    opacity: .35;
}

.datasheet-table-pagination .entry-info {
    white-space: nowrap;
}

/* Printing and PDF capture must not show one page of a paginated table inside a
   70vh window - both want the whole thing, laid out flat. */
@media print {
    .datasheet-table-scroll {
        max-height: none;
        overflow: visible;
    }

    .datasheet-table-pagination {
        display: none !important;
    }
}

/* ---------------------------------------------------------------------------
 * Datasheet tables on the page shell (template-v3)
 *
 * The shell's shell.css restyles every card and table on the page for its admin lists:
 *
 *   body.shell .card-body                   { padding: 16px }
 *   body.shell .table                       { font-size: 12.5px; color: slate }
 *   body.shell .table > thead > tr > th     { 10px uppercase, slate-50 ground, 10px 12px padding,
 *                                             nowrap }
 *   body.shell .table > tbody > tr > td     { 10px 12px padding, vertical-align: middle,
 *                                             slate-100 borders }
 *   body.shell .table-hover > tbody > tr:hover > * { background: slate-50 }
 *   body.shell .card                        { slate border, 12px radius, other shadow }
 *
 * Each of those is one element and one class heavier than the datasheet's own rules above
 * (.datasheet-collection .card-body and friends), so on the shell they won: the table sat 16px
 * inside its card, the header went small caps, and every row got taller. Minton's app.min.css is
 * not the cause - the old look came from bootstrap.min.css plus this file, and bootstrap.min.css is
 * still loaded.
 *
 * So the rules below put back, for datasheet tables only, exactly what bootstrap.min.css and this
 * file gave them before - values measured from the template-v1 page, not re-designed. Other shell
 * tables (admin lists) keep the shell's look. Every selector starts with body.shell
 * .datasheet-collection, which outranks the shell's rule for the same element and is inert on the
 * old layout.
 * ------------------------------------------------------------------------- */
body.shell .datasheet-collection .card {
    border: 1px solid var(--datasheet-surface-border);
    border-radius: var(--datasheet-surface-radius);
    box-shadow: var(--datasheet-surface-shadow);
    margin-bottom: 20px;
}

body.shell .datasheet-collection .card-body {
    padding: 0;
}

body.shell .datasheet-collection .table {
    font-size: var(--bs-body-font-size, 0.9rem);
    color: var(--t-ink-strong, #212529);
}

body.shell .datasheet-collection .table > thead > tr > th {
    padding: 12px;
    font-size: inherit;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    color: var(--bs-secondary-color, #444);
    /* bootstrap's own: .table-secondary and friends colour a header through this variable. */
    background: var(--bs-table-bg);
    border-bottom: 2px solid var(--bs-border-color, #e0e0e0);
    white-space: normal;
    vertical-align: bottom;
}

/* The bounded-scroll header's opaque ground (see .datasheet-table-scroll above), which the reset
   above would otherwise outrank.
 *
 * EVERY header cell, with no exemption. This used to spare .custom-header-class so that a header
 * could keep a colour of its own - but the only selector that gives it one,
 * `.datasheet-collection table.custom-table-class thead th.custom-header-class`, is itself
 * outranked by the reset above (same three classes, one element fewer), so on this layout the
 * exemption handed the cell `background: var(--bs-table-bg)` - which bootstrap declares as
 * `transparent` on .table. The footnote column's header is the one header this renderer draws with
 * custom-header-class and no .table-secondary: it was see-through, and the rows scrolling under the
 * sticky header showed through it, "1) 2) 1)" printed across the column titles.
 *
 * The custom colour still applies on every layout that is not the shell, where the reset does not
 * exist and the custom rule outranks the sticky-header one. */
body.shell .datasheet-collection .datasheet-table-scroll > table > thead > tr > th {
    background-color: var(--bs-gray-200, #e9ecef);
}

body.shell .datasheet-collection .table > tbody > tr > td {
    padding: 0.5rem;
    vertical-align: top;
    border-color: inherit;
}

/* Hover through bootstrap's accent variable again, not a painted background - which also leaves a
   highlighted row or cell (table-row-highlight, highlight-cell) its own colour while hovered. */
body.shell .datasheet-collection .table-hover > tbody > tr:not(.table-row-highlight):hover > :not(.highlight-cell) {
    background: var(--bs-table-bg);
}

body.shell .datasheet-collection .transposedTable > table > tbody > tr > th.table-secondary {
    background-color: var(--bs-gray-200, #e9ecef);
}

/* ---------------------------------------------------------------------------
 * The table's header line: heading, toggles, actions
 *
 * The actions used to be absolutely positioned over the right end of the line (.table-edit-button
 * above), so a long heading ran underneath them. They are in the flow now: the heading truncates,
 * and table.js folds the actions into a three-dots menu group by group once the heading would get
 * too short (planHeaderCollapse). Without script - or before it has measured - the actions wrap
 * onto a second line instead, so nothing overlaps either way.
 * ------------------------------------------------------------------------- */
.datasheet-table-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.datasheet-table-header__title {
    flex: 0 1 auto;
    min-width: 0;
}

.datasheet-table-header__title .collection-name {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* collapsible_header: the whole header line hides and shows the table (Table.onHeaderClick in table.js). */
.datasheet-table-header--collapsible {
    cursor: pointer;
}

.datasheet-table-header__collapse {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
    max-width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.datasheet-table-header__collapse:focus-visible {
    outline: 2px solid rgba(var(--bs-primary-rgb, 255, 105, 0), 0.5);
    outline-offset: 2px;
    border-radius: 4px;
}

.datasheet-table-header__chevron {
    flex: 0 0 auto;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--bs-gray-600, #6c757d);
    transition: color 0.15s ease;
}

.datasheet-table-header--collapsible:hover .datasheet-table-header__chevron {
    color: var(--bs-primary, #ff6900);
}

/* Collapsed, the card is just its header line: no gap left where the table was. */
body.shell.shell-dense .datasheet-collection .datasheet-table-header--collapsed {
    margin-bottom: 0;
}

.datasheet-table-header__toggles {
    flex: 0 0 auto;
}

/* Centre the switch and its label on the heading. Bootstrap floats the input and gives it a top
   margin, and the label a line box of its own, which put the switch a few pixels above the
   heading's middle. */
.datasheet-table-header__toggles .form-check {
    display: flex;
    align-items: center;
    gap: 0.4em;
    min-height: 0;
    margin: 0;
    padding-left: 0;
}

.datasheet-table-header__toggles .form-switch .form-check-input,
.datasheet-table-header__toggles .form-check-input {
    float: none;
    margin: 0;
    flex: 0 0 auto;
}

.datasheet-table-header__toggles .form-check-label {
    line-height: 1.2;
}

.datasheet-table-header__actions {
    flex: 0 0 auto;
    margin-left: auto;
    min-width: 0;
}

.datasheet-table-header .table-edit-button {
    position: static;
    padding: 0;
}

/* line-height 1: the 24px icons would otherwise make a 36px line box, and the header line 7px
   taller than it was while they floated over it. */
.datasheet-table-header .table-edit-actions {
    flex-wrap: wrap;
    line-height: 1;
}

/* Measured by script: one line, and whatever does not fit is in the menu. */
.datasheet-table-header--managed .table-edit-actions {
    flex-wrap: nowrap;
}

.datasheet-table-header .table-edit-actions > [role="button"]:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: -2px;
    border-radius: 4px;
}

.datasheet-table-header__collapsed {
    display: none !important;
}

/* The menu. Same shape as the v2 search's column header menu (.table-header__menu in
   searchui-library's search.css), so the two read as one control. */
.datasheet-table-header__more {
    position: relative;
    display: flex;
    align-items: center;
}

.datasheet-table-header__more-toggle {
    padding: 0 0.1rem;
    line-height: 1;
    border: 0;
    color: inherit;
}

body.shell .datasheet-table-header__more-toggle {
    padding: 0 0.1rem;
    box-shadow: none;
}

.datasheet-table-header__more-toggle:hover,
.datasheet-table-header__more-toggle[aria-expanded="true"] {
    color: var(--bs-primary);
}

.datasheet-table-header__menu {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 10;
    min-width: 11rem;
    /* A phone-width card: never wider than the screen. Labels ellipsize instead. */
    max-width: calc(100vw - 24px);
    padding: 0.25rem 0;
    background-color: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, var(--bs-gray-300, #dee2e6));
    border-radius: 0.25rem;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    text-align: left;
}

.datasheet-table-header__menu-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.35rem 0.75rem;
    border: 0;
    background: none;
    font-weight: 400;
    text-align: left;
    white-space: nowrap;
    /* literal fallback, like every other --bs-* reference in this file: a declaration whose custom property
       is undefined is dropped whole, so a menu item would have no colour at all rather than a default one. */
    color: var(--bs-body-color, #6c757d);
}

.datasheet-table-header__menu-item > .mdi {
    font-size: 1.15rem;
    line-height: 1;
}

.datasheet-table-header__menu-item > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.datasheet-table-header__menu-item:hover,
.datasheet-table-header__menu-item:focus-visible,
.datasheet-table-header__menu-item:focus {
    background-color: var(--bs-gray-100, #f8f9fa);
    outline: 0;
}

.datasheet-table-header__menu-item[aria-checked="true"] > .mdi {
    color: var(--bs-primary);
}

.datasheet-table-header__menu-item:disabled {
    opacity: 0.5;
    cursor: default;
}

@media print {
    .datasheet-table-header__more {
        display: none !important;
    }
}

/* ---------------------------------------------------------------------------
 * The revision history modal (Table in table.js)
 *
 * The size is set here rather than inline on the dialog, so it holds on both layouts and below
 * 576px, where an inline width would have had nothing capping it.
 *
 * Wide - the table is the point of the dialog - and at most 85vh tall. The two panes scroll on their
 * own: the table in both directions, the change log vertically. On a phone the panes stack, the
 * table first, and the dialog body scrolls.
 * ------------------------------------------------------------------------- */
.revision-history-modal .modal-dialog.revision-history__dialog {
    width: min(1600px, calc(100vw - 3rem));
    max-width: none;
    margin: 1.5rem auto;
    min-height: calc(100% - 3rem);
}

/* A fixed height rather than a maximum: hiding the change log or picking a version with fewer rows
   would otherwise resize the centred dialog and move its header under the pointer. */
.revision-history__dialog .modal-content {
    height: calc(100vh - 3rem);
    height: min(85vh, calc(100vh - 3rem));
    overflow: hidden;
}

.revision-history__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.revision-history__panes {
    display: flex;
    gap: 1rem;
    flex: 1 1 auto;
    min-height: min(420px, 60vh);
}

.revision-history__table-pane,
.revision-history__log-pane {
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
    background-color: var(--bs-body-bg, #fff);
}

/* The table takes whatever the change log does not - all of it when the log is hidden. */
.revision-history__table-pane {
    flex: 1 1 auto;
}

.revision-history__log-pane {
    flex: 0 0 22rem;
}

.revision-history__pane-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-width: 0;
}

.revision-history__table-scroll,
.revision-history__log-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

.revision-history__log-list {
    overflow-x: hidden;
}

/* Columns wrap their text but never below a readable width: many columns scroll sideways inside the
   pane instead of being squeezed to a word each. */
.revision-history__table-scroll > .table {
    width: auto;
    min-width: 100%;
}

.revision-history__table-scroll > .table th,
.revision-history__table-scroll > .table td {
    min-width: 8rem;
}

/* A shade along the right edge says there is more table than fits. Over the cells, which paint their
   own backgrounds, so it is a pseudo-element rather than a background of the scroller. */
.revision-history__table-pane {
    position: relative;
}

.revision-history__table-pane--overflowing::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 14px;
    pointer-events: none;
    border-radius: 0 var(--bs-border-radius, 0.25rem) var(--bs-border-radius, 0.25rem) 0;
    background: linear-gradient(to left, var(--datasheet-scroll-shadow, rgba(0, 0, 0, 0.12)), transparent);
}

@media (max-width: 767.98px) {
    .revision-history-modal .modal-dialog.revision-history__dialog {
        width: auto;
        margin: 0.5rem;
        min-height: calc(100% - 1rem);
    }

    .revision-history__dialog .modal-content {
        height: auto;
        max-height: calc(100vh - 1rem);
    }

    .revision-history__body {
        overflow-y: auto;
    }

    .revision-history__panes {
        flex-direction: column;
        min-height: 0;
    }

    .revision-history__table-pane {
        flex: 0 0 auto;
    }

    .revision-history__table-scroll {
        max-height: 60vh;
    }

    .revision-history__log-pane {
        flex: 0 0 auto;
    }

    .revision-history__log-list {
        overflow: visible;
    }

    .revision-history__table-scroll > .table th,
    .revision-history__table-scroll > .table td {
        min-width: 7rem;
    }
}

/* ---------------------------------------------------------------------------
 * The table configuration modal: ColumnChooser in table.js
 *
 * The dialog is .modal-dialog-scrollable, so the body scrolls inside the viewport; the search, the
 * "all columns" checkbox and the counter stick to its top while the list scrolls under them. Every row
 * is its label, so the whole line toggles the column.
 * ------------------------------------------------------------------------- */
.column-chooser-dialog .modal-body {
    padding-top: 0;
}

.column-chooser__toolbar {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 -1rem 0.5rem;
    padding: 0.75rem 1rem 0.5rem;
    background-color: var(--bs-body-bg, #fff);
    border-bottom: 1px solid var(--bs-border-color, var(--bs-gray-300, #dee2e6));
}

.column-chooser__search {
    margin-bottom: 0.5rem;
}

.column-chooser__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.column-chooser__count {
    font-size: 0.85em;
    color: var(--bs-secondary-color, var(--bs-gray-600, #6c757d));
    white-space: nowrap;
}

.column-chooser__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.column-chooser__item {
    display: flex;
    align-items: center;
    min-height: 0;
    margin: 0;
    padding: 0 0 0 0.5rem;
    border-radius: var(--bs-border-radius, 0.25rem);
}

.column-chooser__item:hover {
    background-color: var(--bs-gray-100, #f8f9fa);
}

.column-chooser__item .form-check-input {
    float: none;
    flex: 0 0 auto;
    margin: 0;
}

/* The label fills the row, including the gap next to the checkbox. */
.column-chooser__item .form-check-label {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.45rem 0.5rem 0.45rem 0.6rem;
    cursor: pointer;
    overflow-wrap: anywhere;
}

.column-chooser__item--hidden .form-check-label {
    color: var(--bs-secondary-color, var(--bs-gray-600, #6c757d));
}

.column-chooser__item .form-check-input:disabled ~ .form-check-label {
    cursor: default;
    opacity: 1;
}

.column-chooser__empty,
.column-chooser__hint {
    margin: 0.5rem 0 0;
    font-size: 0.85em;
    color: var(--bs-secondary-color, var(--bs-gray-600, #6c757d));
}

/* ---------------------------------------------------------------------------
 * The dark theme.
 *
 * Almost nothing is needed here, and that is by design. searchui-library's
 * theme-dark.css defines --bs-body-bg, --bs-body-color, --bs-border-color,
 * --bs-secondary-color, --bs-table-striped-bg and the --bs-gray-* ramp under
 * [data-bs-theme="dark"]. This file already writes `var(--bs-..., <literal>)`
 * almost everywhere - not for theming, but because the theme ships Bootstrap
 * 5.1, which does not define those variables at all, and a declaration that
 * references an undefined custom property is dropped in full (see the comment
 * above .datasheet-table-scroll). Defining them in the dark theme turns that
 * defensive habit into the theming mechanism: every one of those call sites
 * switches with no edit here.
 *
 * What is left is the handful of colours the library cannot know about.
 *
 * The datasheet page is on the page shell (template-v3), which is the only
 * layout that loads theme-dark.css, so the attribute is only ever set on a
 * page where these rules have their counterparts.
 * ------------------------------------------------------------------------- */

/*
 * The custom-table-class inks. These are configuration-facing: a datasheet
 * config names custom-header-class, custom-cell-class and custom-footnote-class
 * and gets these colours. They are chosen to carry on white and are close to
 * black on a dark ground, so each is lightened to the same hue rather than
 * replaced - a footnote that is red in light mode stays red.
 */
[data-bs-theme="dark"] .datasheet-collection table.custom-table-class thead th.custom-header-class {
    color: #7bd66a;
}

[data-bs-theme="dark"] .datasheet-collection table.custom-table-class tbody td.custom-cell-class {
    color: #6fb2f0;
}

[data-bs-theme="dark"] .datasheet-collection table.custom-table-class b.custom-footnote-class {
    color: #ff8d98;
}

/*
 * The shadow marking that the table scrolls further right. It is painted with
 * black at 12%, which over a dark table is invisible - and this shadow is the
 * only thing telling the reader there are more columns. White at a low alpha
 * reads as the same "there is more" cue on a dark ground.
 */
[data-bs-theme="dark"] {
    --datasheet-scroll-shadow: rgba(255, 255, 255, 0.16);
}

/*
 * The right panel floats over the page, so it takes the raised surface rather
 * than the body ground - the same one step of elevation modals and dropdowns
 * get in theme-dark.css - and a hard shadow, because a soft black one does not
 * separate two dark surfaces.
 */
[data-bs-theme="dark"] .right-panel {
    background-color: var(--sl-surface-2, #1c242a);
    box-shadow: -2px 0 12px rgba(0, 0, 0, 0.6);
}

/*
 * "Copy from..." (AP-5157).
 *
 * The wizard puts a source list, a row/column picker and a side-by-side diff in one dialog and
 * needs more room than modal-xl gives, so it says so itself.
 */
.modal-dialog.copy-wizard-dialog {
    width: 1180px;
    /* Override the datasheet's generic .modal-dialog 60vw !important limit. */
    max-width: 94vw !important;
}

/* Let wide tables scroll inside the dialog instead of expanding its flex children. */
.copy-wizard-dialog .modal-body,
.copy-wizard-dialog .card,
.copy-wizard-dialog .card-body,
.copy-wizard-dialog [class^="col-"] {
    min-width: 0;
}

.copy-wizard-dialog .table-responsive {
    max-width: 100%;
    overflow-x: auto;
}

.copy-wizard-dialog .table th,
.copy-wizard-dialog .table td {
    min-width: 5rem;
    overflow-wrap: anywhere;
}

/* Keep text readable; extra columns scroll inside the dialog instead of squeezing long remarks. */
.copy-wizard-dialog .copy-cell-preview {
    min-width: 12rem;
    max-width: 24rem;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    line-height: 1.4;
    max-height: 4.2em;
    overflow: hidden;
    white-space: normal;
    overflow-wrap: anywhere;
}

.copy-wizard-dialog .table td {
    vertical-align: top;
}

/* The +/- column of the diff. Everything else is table-danger / table-success from the theme. */
.copy-wizard-dialog .table .copy-diff-gutter {
    width: 1.6rem;
    min-width: 1.6rem;
    text-align: center;
    user-select: none;
}

/* End of styles.css */

