/* ==========================================================================
   Shared grid-page skin — Inspections / Inspectors / Observations
   ----------------------------------------------------------------------------
   Scoped via `body.page-grid` (set in Default.Master.cs when the request
   targets any grid-style page). Covers ModuleTemplateV2 chrome, FleetVessel
   filter dropdowns, GridSearch box, PopupMenu ellipsis, ASPxGridView grid,
   and the DevExpress pager. Column widths and page-specific CTA labels live
   in per-page files (inspections.css, inspectors.css, observations.css).

   Design tokens come from the Figma "Q88 Specs" file.
   ========================================================================== */

body.page-grid {
    --q88-grid-fg: var(--foreground);
    --q88-grid-muted: #f5f5f5;
    --q88-grid-muted-fg: #475569;
    --q88-grid-placeholder: #475569;
    --q88-grid-border: #e2e8f0;
    --q88-grid-card: var(--card-raised);
    --q88-grid-primary: var(--primary);                       /* QEN-8831: brand-driven (indigo on Q88, teal on Milbros) instead of hardcoded teal */
    --q88-grid-primary-hover: var(--button-primary-hover);    /* = base on Q88 (hover is the opacity fade below); milbros-dark on Milbros */
    --q88-grid-primary-fg: #ffffff;
    --q88-grid-row-hover: #f8fafc;
    --q88-grid-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* ==========================================================================
   0. Legacy <table.ContentPane> chain release
   ----------------------------------------------------------------------------
   The DNN portal wraps every module in a `<table class="ContentPane">` chain
   that shrink-wraps to its widest child. On data-grid pages, the DevExtreme
   grid's intrinsic column total can push that chain past the .q88-content
   right edge — at which point our card's `width: calc(100% - 96px)` no longer
   subtracts the gutters from the content area, it subtracts them from the
   bloated table. The page then horizontally overflows.

   Clamp the chain to 100% of .q88-content so the card's calc() works against
   the right reference width. Any grid content wider than the card scrolls
   inside the card via the DX grid's own horizontal scroller — not the page.
   ========================================================================== */
body.sidebar-nav.page-grid .q88-content .ContentPane,
body.sidebar-nav.page-grid .q88-content .ContentPaneBody,
body.sidebar-nav.page-grid .ContentPane .MainTableContent > td.ContentPaneBody {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
}

/* ==========================================================================
   1. Module wrapper — flatten V2 chrome into a clean card surface
   ========================================================================== */

body.page-grid .modV2 {
    background: var(--q88-grid-card);
    border: 1px solid var(--q88-grid-border);
    border-radius: 8px;
    box-shadow:
        0 1px 3px 0 rgba(0, 0, 0, 0.06),
        0 1px 2px -1px rgba(0, 0, 0, 0.05);
    padding: 16px;
    font-family: var(--q88-grid-font);
    color: var(--q88-grid-fg);
    /* 48 px L/R gutter matches the shared `.q88-card` rule in components.css.
       Grid pages can't use `width: calc(100% - 96px)` because a wide
       DevExtreme grid expands the legacy `<table.ContentPane>` chain past
       q88-content's right edge — calc'ing from that bloated parent
       produces a card that overflows. Clamp via viewport math instead:
       100vw minus 256 px sidebar minus 96 px gutters minus 15 px vertical
       scrollbar = card width regardless of the parent's intrinsic size.
       Inner overflow scrolls inside the card via overflow-x: auto. */
    box-sizing: border-box;
    width: 100%;
    max-width: calc(100vw - 367px);
    margin: 24px 48px;
    overflow-x: auto;
    overflow-y: hidden;
}

/* QEN-8865 — GridCustomColumns' "Columns" picker (.popupMenuV2StandardWidth)
   renders position:absolute *inside* .modV2, so the overflow-y: hidden above
   clips its bottom rows / "Apply Changes" once the checkbox list is tall
   enough to reach the card's clipped edge — clicks/scroll on that trailing
   strip silently fall through to the page content underneath instead of
   hitting the popup. AjaxControlToolkit's PopupControlExtender toggles
   `visibility: visible` (not display) while open, confirmed by inspecting
   the live style attribute, so key off that. Scoped to
   .popupMenuV2StandardWidth (the Columns picker specifically) — other
   .modV2 popups sharing the base .popupMenuV2 class (row-action menus,
   filter menus) don't carry this modifier and are unaffected. */
body.page-grid .modV2:has(.popupMenuV2StandardWidth[style*="visibility: visible"]) {
    overflow: visible;
}

body.page-grid .modV2TitleContainer {
    background: transparent !important;
    background-image: none !important;
    border: 0 !important;
    padding: 0 !important;
    margin: 0 0 16px 0 !important;
    height: auto !important;
    min-height: 40px;
}

/* Hide the V2 decorative title pipes / backgrounds if any */
body.page-grid .modV2TitleContainer > div:empty,
body.page-grid .modV2TitleContainer > span:empty {
    display: none !important;
}

/* ==========================================================================
   2. Title bar — page label + fleet/vessel/view filters (left)
                  search + actions + Create New + ellipsis (right)
   ========================================================================== */

body.page-grid .modV2TitleContainer > table,
body.page-grid .modV2TitleContainer > table > tbody,
body.page-grid .modV2TitleContainer > table > tbody > tr {
    display: contents !important;
}

body.page-grid .modV2TitleContainer {
    display: flex !important;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-width: 0 !important;
    min-height: 40px;
}

/* Every child of the title bar rows must vertical-center to the same axis
   so the page label, the filter dropdowns, the search box and
   the Create New button all share the same baseline. */
body.page-grid [id$='_pnlTitleLeft'] > *,
body.page-grid [id$='_pnlTitleRight'] > * {
    align-self: center;
}

body.page-grid [id$='_pnlTitleLeft'] table,
body.page-grid [id$='_pnlTitleRight'] table {
    height: 40px !important;
}

/* Title cell (inner <td class="modV2Title">). The OUTER div#pnlTitleLeft
   also has class .modV2Title but we handle it separately as a flex shell.
   The ancestor <table>/<tr> use `display: contents`, so this <td> becomes
   a flex item directly in `.modV2TitleContainer`. `vertical-align: middle`
   only centers content inside a real table cell — once the td is a flex
   item, that property is inert and the 24px line of text sits flush-top
   inside the 40px box. Make the cell itself a flex container so its
   text centers on the same axis as the 32px-tall filter dropdowns.
   Figma leaves ~24px breathing room between the label and the first filter
   pill (no divider). The selector is keyed with the panel ID so it beats
   the generic `#pnlTitleLeft table td { padding: 0 4px !important }` rule
   further up (matching ID count, higher class count). */
body.page-grid [id$='_pnlTitleLeft'] td.modV2Title {
    font-family: var(--q88-grid-font);
    font-size: 16px !important;
    font-weight: 600 !important;
    line-height: 24px !important;
    color: var(--q88-grid-fg) !important;
    padding: 0 24px 0 0 !important;
    margin: 0 !important;
    background: transparent !important;
    height: 40px !important;
    white-space: nowrap;
    letter-spacing: 0;
    text-transform: none;
    position: relative;
    display: inline-flex !important;
    align-items: center !important;
    vertical-align: middle !important;
}

/* Neutralise the heading styles inherited from the wrapping div.modV2Title
   (since the wrapper carries the same class but is our flex container). */
body.page-grid div.modV2Title {
    font-weight: inherit !important;
    font-size: inherit !important;
    color: inherit !important;
    padding: 0 !important;
    background: transparent !important;
    max-height: none !important;
    overflow: visible !important;
}

/* Collapse nested title tables into a flex row */
body.page-grid [id$='_pnlTitleLeft'],
body.page-grid [id$='_pnlTitleRight'] {
    display: flex !important;
    align-items: center;
    gap: 8px;
    padding: 0 !important;
    background: transparent !important;
    float: none !important;
    border: 0 !important;
    width: auto !important;
    min-width: 0 !important;
    flex-wrap: nowrap;
    /* MainWhiteout sets .modV2 .modV2TRight { position: absolute; right: 0 }
       which pins the right side to the container's right edge regardless of
       flex direction — so it overlaps the left on narrow viewports.
       Reset to static so flex controls the layout. */
    position: static !important;
    right: auto !important;
    top: auto !important;
}

body.page-grid [id$='_pnlTitleLeft'] {
    flex: 1 1 auto;
    min-width: 0;
}

body.page-grid [id$='_pnlTitleRight'] {
    flex: 0 0 auto;
    margin-left: auto;
}

/* Title bar stays on ONE row matching Figma. At the worst observed card
   inner width (~1121px at 1440 viewport with sidebar), content is:
   label ~110 + 3×150 filters + 8gap×2 + search ~230 + ellipsis 30 +
   Create New 110 ≈ 1020px, so it fits. Below ~1100 we fall through to
   the narrow-viewport rule further down. */

body.page-grid [id$='_pnlTitleLeft'] table,
body.page-grid [id$='_pnlTitleRight'] table {
    border: 0 !important;
    border-spacing: 0 !important;
    background: transparent !important;
    margin: 0 !important;
}

body.page-grid [id$='_pnlTitleLeft'] table td,
body.page-grid [id$='_pnlTitleRight'] table td {
    padding: 0 4px !important;
    background: transparent !important;
    border: 0 !important;
    vertical-align: middle;
    height: 22px !important;
    line-height: normal !important;
}

body.page-grid [id$='_pnlTitleLeft'] table td:first-child,
body.page-grid [id$='_pnlTitleRight'] table td:first-child {
    padding-left: 0 !important;
}

body.page-grid [id$='_pnlTitleLeft'] table td:last-child,
body.page-grid [id$='_pnlTitleRight'] table td:last-child {
    padding-right: 0 !important;
}

/* ==========================================================================
   3. Filter dropdowns (Fleet / Vessel / View)
   Figma: 32px tall, 173px wide, 1px #e5e5e5 border, 8px radius,
          white bg, Inter Regular 14px, muted-fg (#737373) placeholder.
   ========================================================================== */

body.page-grid .modV2TRight-FleetVessel {
    display: inline-flex !important;
    align-items: center;
    gap: 8px;
    padding: 0 !important;
    background: transparent !important;
}

/* Native <select> on grid pages now inherits the canonical skin from
   components.css §12.5 (DESIGN.md §9.6 ⭐). Only width is grid-specific —
   set it via the FleetVessel container alone, NOT on the select itself. */
body.page-grid .modV2TRight-FleetVessel select {
    width: 170px !important;
    min-width: 170px !important;
    max-width: 170px !important;
}

/* GridViewSelector custom <dl> dropdown skin lifted to components.css
   §12.5.2 (DESIGN.md §9.6.8) so non-page-grid hosts (Inspection Container,
   Heat Map, Officer Matrix List, Scheduled Reports, etc.) inherit the
   canonical look without per-page CSS. Only the page-grid #_pnlTitleLeft
   table-reset stays here — it is a page-grid-specific quirk. */

/* Reset the legacy IE-era <table><tr><td> wrapper that GridViewSelector puts
   around each <a.jqCusDdlText>. The `dd` list is positioned absolutely but
   remains a descendant of `#pnlTitleLeft`, so the title-bar rules higher up
   (height: 40px, td padding 0 4px) were reaching these inner item tables
   and creating a phantom 11px bottom gap under every dropdown item. We
   match the same ID here to win the specificity battle against those
   rules without touching them. */
body.page-grid [id$='_pnlTitleLeft'] .dropDownCusGrp dd ul li table,
body.page-grid [id$='_pnlTitleLeft'] .dropDownCusGrp dd ul li tbody,
body.page-grid [id$='_pnlTitleLeft'] .dropDownCusGrp dd ul li tr {
    height: auto !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-spacing: 0 !important;
    background: transparent !important;
}

body.page-grid [id$='_pnlTitleLeft'] .dropDownCusGrp dd ul li td {
    height: auto !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    line-height: normal !important;
    vertical-align: middle;
}

/* ==========================================================================
   4. Search box
   Figma: 32px tall, 240px wide, icon inside left, Inter Regular 14px,
          placeholder #475569.
   ========================================================================== */

body.page-grid .searchBoxDiv {
    position: relative;
    padding: 0 !important;
    background: var(--q88-grid-card) !important;
    border: 1px solid var(--q88-grid-border) !important;
    border-radius: 8px !important;
    height: 32px;
    width: 260px;
    display: inline-flex;
    align-items: center;
    overflow: hidden;
    box-shadow: none !important;
}

body.page-grid .searchBoxDiv input[type='text'] {
    flex: 1 1 auto;
    height: 30px;
    padding: 0 8px 0 36px;
    border: 0 !important;
    background: transparent !important;
    color: var(--q88-grid-fg);
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    outline: none !important;
}

body.page-grid .searchBoxDiv input[type='text']::placeholder,
body.page-grid .searchBoxDiv input.WaterMarkText {
    color: var(--q88-grid-muted-fg);
}

body.page-grid .searchBoxDiv input.WaterMarkText {
    font-style: normal !important;
}

/* Inline Figma-style magnifying glass */
body.page-grid .searchBoxDiv::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 50%;
    width: 16px;
    height: 16px;
    transform: translateY(-50%);
    pointer-events: none;
    background-color: var(--q88-grid-muted-fg);
    -webkit-mask: var(--icon-search) center / contain no-repeat;
            mask: var(--icon-search) center / contain no-repeat;
}

/* Hide the existing search icon link — it lived inside the input */
body.page-grid .searchBoxDiv a[id*='lbGridSearch'] {
    position: absolute !important;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: auto;
}

body.page-grid .searchBoxDiv:focus-within {
    border-color: var(--q88-grid-primary) !important;
    box-shadow: 0 0 0 3px rgba(var(--primary-tint), 0.12) !important;
}

/* ==========================================================================
   5. Primary action button — any CTA marked `.Img-Std Img-Std-Add` anywhere
   in a grid-page body. The label text (`::before { content: ... }`) is
   supplied per-page in inspections.css / inspectors.css / observations.css.

   Covers two markup patterns:
     Inspections:  <a class="Img-Std Img-Std-Add" id="...lbNewInspection">   (LinkButton)
     Inspectors:   <a id="lnkNewInspector"><img class="Img-Std Img-Std-Add">  (anchor + img)
   Both render a 36px teal pill with the per-page label text.

   Not scoped to .modV2TitleContainer: pages like OfficerMatrixVessel place
   their primary CTA in a custom header toolbar outside the V2 title bar.
   Safe to broaden because `Img-Std-Add` is reserved for primary-add CTAs
   (row-level actions use Img-Std-Edit, Img-Std-Delete, etc.).
   ========================================================================== */

body.page-grid a.Img-Std-Add,
body.page-grid a:has(> img.Img-Std-Add) {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px !important;
    min-width: 0;
    padding: 0 16px !important;
    background: var(--q88-grid-primary) !important;
    background-image: none !important;
    color: var(--q88-grid-primary-fg) !important;
    border: 1px solid var(--q88-grid-primary) !important;
    border-radius: 8px !important;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    font-weight: 500;
    text-decoration: none !important;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
    box-shadow: 0 1px 2px 0 rgba(var(--primary-tint), 0.25);
    width: auto !important;
    text-indent: 0 !important;
    box-sizing: border-box !important;
    vertical-align: middle;
}

body.page-grid a.Img-Std-Add > img,
body.page-grid a:has(> img.Img-Std-Add) > img {
    display: none !important;
}

body.page-grid a.Img-Std-Add:hover,
body.page-grid a:has(> img.Img-Std-Add):hover {
    background: var(--q88-grid-primary-hover) !important;
    border-color: var(--q88-grid-primary-hover) !important;
}

body.page-grid a.Img-Std-Add:active,
body.page-grid a:has(> img.Img-Std-Add):active {
    transform: translateY(1px);
    box-shadow: none;
}

/* ==========================================================================
   6. Options ellipsis (popup menu trigger)
   Figma: 24x24 icon, no button chrome.
   ========================================================================== */

body.page-grid a[id$='_popMenuActions_lbPopupMenu'].Img-Std-Options {
    width: 32px !important;
    height: 32px !important;
    padding: 0 !important;
    background: transparent !important;
    background-image: none !important;
    border: 1px solid transparent !important;
    border-radius: 6px !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    color: var(--q88-grid-fg);
    text-indent: 0 !important;
    position: relative;
    box-sizing: border-box !important;
    vertical-align: middle;
}

body.page-grid a[id$='_popMenuActions_lbPopupMenu'].Img-Std-Options::before {
    content: '';
    display: block;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--q88-grid-fg);
    box-shadow:
        0 -7px 0 0 var(--q88-grid-fg),
        0  7px 0 0 var(--q88-grid-fg);
}

body.page-grid a[id$='_popMenuActions_lbPopupMenu'].Img-Std-Options:hover {
    background: var(--q88-grid-muted) !important;
    border-color: var(--q88-grid-border) !important;
}

/* ==========================================================================
   7. DevExpress grid — clean Figma table look
   Figma: Header 48px tall, bg #f5f5f5, Inter Semi Bold 14px,
          rows 42px tall, bg white, 1px #e5e5e5 bottom border.
   ========================================================================== */

body.page-grid .dxgvControl,
body.page-grid .dxgvControl.dxgv {
    border-collapse: separate !important;
    /* Card wrapper (.modV2) already provides the outer border — drop the
       inner grid border per design review. overflow:hidden + border-radius
       still clip rows to rounded corners. */
    border: 0 !important;
    border-radius: 8px !important;
    overflow: hidden;
    font-family: var(--q88-grid-font);
    background: var(--q88-grid-card) !important;
    /* DX renders the outer table with an inline pixel width equal to the
       sum of its column widths (~1218px). On wide viewports that shrinks
       the grid into a tiny strip. Force full-width so it fills the card
       like every other content block on the page. */
    width: 100% !important;
    min-width: 100% !important;
    box-sizing: border-box !important;
}

/* Inner DXMainTable + scroll container must match the outer grid width.
   We keep DX's table-layout:fixed (its default) so header and body tables
   share identical column widths. Armature row widths get converted from
   pixels to percentages so columns scale together and stay aligned. */
body.page-grid #grd_DXMainTable,
body.page-grid table[id$='_DXMainTable'],
body.page-grid table[id$='_DXHeaderTable'] {
    width: 100% !important;
    min-width: 100% !important;
    table-layout: fixed !important;
}

/* DevExpress client scroll container (.dxgvCSD) inlines width + height; the
   width holds it to the column-sum (1235px). Stretch to the grid width and
   use `scrollbar-gutter: stable` so the body always reserves 15px on the
   right whether the scrollbar is shown or not — matching DX's 15px
   padding-right on the header wrapper so columns stay aligned.

   Vertical sizing: the markup ships an inline `height: NNNpx` on .dxgvCSD
   driven by each page's `VerticalScrollableHeight=` attribute (typically
   340–480). That fixed height leaves a wide blank strip below the grid on
   tall viewports and pushes the pager up the page. Override with a calc
   keyed off `--grid-page-vertical-offset` so the scroll body fills the
   viewport down to the pager + card chrome.

   Default budget (340px) covers: site header, card top margin + padding,
   title row, grid header chrome, pager (~49px), card bottom padding +
   margin and a small viewport gap — tuned for simple list pages with
   only the title bar above the grid (Inspections, Inspectors, Observations).
   Pages whose card holds extra content below the grid (status meta row,
   comments, action buttons — e.g. OfficerMatrixVessel) override the
   variable in their own scope. */
body.page-grid {
    --grid-page-vertical-offset: 340px;
}

body.page-grid .dxgvCSD {
    width: 100% !important;
    scrollbar-gutter: stable !important;
    height: calc(100vh - var(--grid-page-vertical-offset)) !important;
    min-height: 240px !important;
}

/* Horizontal scroll / data container wrappers DX writes around the grid.
   The header wrapper already has an inline `padding-right: 15px` from
   DX to reserve space for a vertical scrollbar in the body area. We
   keep that reservation and mirror it on the body (via `scrollbar-
   gutter: stable` on .dxgvCSD) so both tables leave exactly the same
   space on the right and columns line up. */
body.page-grid .dxgvHSDC,
body.page-grid .dxgvBSDC {
    width: 100% !important;
    box-sizing: border-box !important;
}

body.page-grid .dxgvHSDC > div {
    width: 100% !important;
}

/* Grid outer cell — the <td> that ASPxGridView wraps around its table(s).
   Without this it keeps its natural (narrow) width and clips the grid. */
body.page-grid .dxgvControl > tbody > tr > td {
    width: 100% !important;
}

body.page-grid .dxgvTable {
    font-family: var(--q88-grid-font);
}

/* Header row — Figma target 48px. Padding 14 top + 20 line-height + 14
   bottom = 48. DX wraps caption in a nested <table class="tblColHeader">
   that adds its own line-height, so we lean on padding + line-height:20.

   GridWhiteout.css forces `text-align: center !important` on every header,
   which ignores DX's per-column inline alignment. Reset to `inherit` so
   the inline `text-align:Left` / `text-align:Center` on each <td> wins. */
body.page-grid .dxgvHeader {
    background: var(--q88-grid-muted) !important;
    background-image: none !important;
    border-top: 0 !important;
    border-bottom: 1px solid var(--q88-grid-border) !important;
    padding: 0 16px !important;
    color: var(--q88-grid-fg) !important;
    vertical-align: middle !important;
    line-height: 20px !important;
    text-align: inherit !important;
}

/* DevExpress emits HeaderStyle-HorizontalAlign as either an inline `style`
   or the legacy HTML `align` attribute on the header <td>, depending on the
   DX version. Match every form and force the override so the general
   .dxgvHeader rule above can stay !important (needed to beat the DX library's
   default `text-align: center`). The `i` flag makes the substring matches
   case-insensitive so "Right", "right", "RIGHT" all hit. */
body.page-grid td.dxgvHeader[align="right" i],
body.page-grid td.dxgvHeader[style*="text-align: right" i],
body.page-grid td.dxgvHeader[style*="text-align:right" i] {
    text-align: right !important;
}
body.page-grid td.dxgvHeader[align="center" i],
body.page-grid td.dxgvHeader[style*="text-align: center" i],
body.page-grid td.dxgvHeader[style*="text-align:center" i] {
    text-align: center !important;
}

/* Column alignment follows the column's data type via DX's own classes:
     - text columns    -> td.dx-al  (left)
     - date columns    -> td.dx-ac  (center)
     - numeric columns -> td.dx-ar  (right)
   DX writes these classes on data cells. Headers stay left-aligned (label
   style) via the inherit reset on .dxgvHeader above, EXCEPT for the per-
   column inline overrides matched by the attribute-selector rules just
   above. The very last column (edit/action icons) is always centered
   regardless of DX tag. */
body.page-grid .dxgvHeader .tblColHeader,
body.page-grid .dxgvHeader .tblColHeader td {
    text-align: inherit !important;
}

body.page-grid .dxgvDataRow td.dx-al {
    text-align: left !important;
}

body.page-grid .dxgvDataRow td.dx-ac {
    text-align: center !important;
}

body.page-grid .dxgvDataRow td.dx-ar {
    text-align: right !important;
}

body.page-grid .dxgvHeader:last-of-type,
body.page-grid .dxgvDataRow > td:last-child {
    text-align: center !important;
}

/* Blank the last column's header text (edit/action column). Every page-grid
   grid puts its row-action icons (Edit pencil, Action chevrons, etc.) in
   the trailing column. Designs call for icons only — no header label. We
   keep the caption in the DOM (sort/aria semantics intact) and hide it
   visually so it works regardless of how the caption is populated (DB
   tblGridColumn.DisplayName, static markup Caption="Edit", or
   GridViewDataTextColumn programmatic). */
body.page-grid .dxgvHeader:last-of-type .tblColHeader td > div,
body.page-grid .dxgvHeader:last-of-type .tblColHeader td > a {
    color: transparent !important;
}

body.page-grid .dxgvHeader td,
body.page-grid .dxgvHeader .tblColHeader td {
    background: transparent !important;
    color: var(--q88-grid-fg) !important;
    border: 0 !important;
    padding: 0 !important;
    height: auto !important;
    vertical-align: middle;
}

/* Align header caption to the same 16px indent as data cells. The outer
   dxgvHeader carries the 16px; the inner tblColHeader/div/a stay flush. */
body.page-grid td.dxgvHeader {
    padding: 11px 16px !important;
}

body.page-grid .dxgvHeader > table.tblColHeader,
body.page-grid .dxgvHeader .tblColHeader td,
body.page-grid .dxgvHeader .tblColHeader td > div {
    padding: 0 !important;
    margin: 0 !important;
}

/* Header text — anchor selectors cover sortable columns (DX renders a sort
   link inside the cell); the bare `.dxgvHeader` selector catches columns
   with `Settings-AllowSort="False"` which render as plain text in a <div>
   instead of an <a>. The `*` descendant catches inner DX-injected wrappers
   (e.g. the <div> DX places inside every non-anchor header cell) because
   DXR.axd sets a non-inheriting `font: tahoma 12px` directly on that div. */
body.page-grid .dxgvHeader,
body.page-grid .dxgvHeader *,
body.page-grid .dxgvHeader a,
body.page-grid .dxgvHeader .tblColHeader td a {
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    line-height: 20px !important;
    font-weight: 500 !important;
    color: var(--q88-grid-fg) !important;
    text-decoration: none !important;
    letter-spacing: 0;
}

body.page-grid .dxgvHeader a:hover {
    color: var(--q88-grid-primary) !important;
}

/* Header column divider pipe */
body.page-grid .dxgvHeader + .dxgvHeader,
body.page-grid td.dxgvHeader {
    border-left: 1px solid var(--q88-grid-border) !important;
}

body.page-grid td.dxgvHeader:first-child {
    border-left: 0 !important;
}

/* Data rows — 36px tall (8 top + 20 line-height + 8 bottom). No explicit
   height: with content-box sizing tables add padding on top of height, so
   a fixed 36px would inflate rows. Force a single line via
   `white-space: nowrap` so rows never wrap on narrow columns. */
body.page-grid .dxgvDataRow td,
body.page-grid tr.dxgvDataRow > td {
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    line-height: 20px !important;
    font-weight: 400 !important;
    color: var(--q88-grid-fg) !important;
    background: var(--q88-grid-card) !important;
    border-top: 0 !important;
    border-bottom: 1px solid var(--q88-grid-border) !important;
    padding: var(--raw-space-4) var(--raw-space-8) !important;
    height: auto !important;
    vertical-align: middle;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.page-grid .dxgvDataRow:hover td,
body.page-grid tr.dxgvDataRow:hover > td {
    background: var(--q88-grid-row-hover) !important;
}

/* Alt / Version3 row — Figma is flat so match .dxgvDataRow */
body.page-grid .dxgvDataRow_Version3 td,
body.page-grid .dxgvAlternateRow td {
    background: var(--q88-grid-card) !important;
}

/* Last row drops bottom border to avoid double line against container */
body.page-grid tr.dxgvDataRow:last-of-type > td {
    border-bottom: 0 !important;
}

/* Figma spec calls for 16px horizontal padding on ALL cells including
   first/last — kept uniform across edges to match the design review.
   (Earlier POC used 8px on edges for narrow-column resizing; design spec
   overrides that trade-off.) */
body.page-grid td.dxgvHeader:first-child,
body.page-grid tr.dxgvDataRow > td:first-child {
    padding-left: 16px !important;
}
body.page-grid td.dxgvHeader:last-child,
body.page-grid tr.dxgvDataRow > td:last-child {
    padding-right: 16px !important;
}

/* Sort indicator */
body.page-grid .dxgvHeader .dxgvSortedHeaderContent,
body.page-grid .dxgvHeader img[src*='sort'] {
    color: var(--q88-grid-primary) !important;
}

/* Edit-pencil column — the row-action anchor is a fixed-size, centered icon
   button. Several grids stretch this anchor to the full cell width — either
   the code-behind emits an inline `width:100%` (OfficerMatrixList,
   LoadLineList) or the bare-anchor rule below did (`a:has(> img.Img-Std-Edit)`
   at (0,3,4) beat the old 20px rule). A full-width anchor made the :hover tint
   (below) fill the whole column instead of sitting behind the pencil — the
   wider the action column, the more it read as "the whole column highlights".
   Pin the anchor to a 28px square so the hover highlight is always a contained
   button regardless of cell width. `!important` on the box metrics beats the
   inline `width:100%` and the `:has()`-boosted specificity. This is the single
   source of truth for the anchor box — it also covers the bare-anchor variants
   the old rule below handled. */
body.page-grid .dxgvDataRow td .jqEdit,
body.page-grid .dxgvDataRow td a[id*='lbEdit'],
body.page-grid .dxgvDataRow td a:has(> img.Img-Std-Edit),
body.page-grid .dxgvDataRow td a:has(> img.Img-Std-EditDisabled),
body.page-grid .dxgvDataRow td a:has(> img.Img-Std-Add) {
    color: var(--q88-grid-muted-fg);
    text-decoration: none;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 28px !important;
    min-width: 28px;
    height: 28px !important;
    border-radius: 6px;
    vertical-align: middle;
    line-height: 0;
}

body.page-grid .dxgvDataRow td .jqEdit img,
body.page-grid .dxgvDataRow td a[id*='lbEdit'] img,
body.page-grid .dxgvDataRow td a > img.Img-Std-Edit,
body.page-grid .dxgvDataRow td a > img.Img-Std-EditDisabled,
body.page-grid .dxgvDataRow td a > img.Img-Std-Add {
    width: 16px !important;
    height: 16px !important;
    vertical-align: middle !important;
    display: inline-block;
}

/* Bare-anchor case (no .jqEdit, no id*='lbEdit') is now folded into the 28px
   icon-button rule above — it no longer stretches to `width:100%`, which is
   what caused the full-column hover tint. The pencil centers via the anchor's
   own flex centering, so no per-cell text-align is needed here. */

/* Replace the legacy Img-Std sprite (bitmap pencil in a spritesheet) with
   the thin Figma pencil outline. The <img> src is a 1x1 clearpixel.gif, so
   masking the element's background-color yields a crisp vector glyph that
   recolors via currentColor on hover/disabled without separate assets.
   Covers all three states emitted by ColumnCustomEditTemplate:
   Img-Std-Edit (active), Img-Std-EditDisabled (read-only), Img-Std-Add
   (planned row with no inspectionID yet).

   Two markup variants:
     • Inspections / Inspectors: <a class="jqEdit"><img class="Img-Std-Edit">
     • LoadLines (and similar):  <a id="*hlkEdit*"><img class="Img-Std-Edit">
   Both handled here without requiring .jqEdit / id*='lbEdit' on the anchor. */
body.page-grid .dxgvDataRow td .jqEdit img.Img-Std-Edit,
body.page-grid .dxgvDataRow td .jqEdit img.Img-Std-EditDisabled,
body.page-grid .dxgvDataRow td .jqEdit img.Img-Std-Add,
body.page-grid .dxgvDataRow td a > img.Img-Std-Edit,
body.page-grid .dxgvDataRow td a > img.Img-Std-EditDisabled,
body.page-grid .dxgvDataRow td a > img.Img-Std-Add {
    background-image: none !important;
    background-color: currentColor !important;
    -webkit-mask: var(--icon-square-pen) no-repeat center / contain;
            mask: var(--icon-square-pen) no-repeat center / contain;
    border: 0 !important;
}

/* Read-only state for the bare-anchor markup (LoadLines and similar):
   dim the disabled pencil so it's distinct from active. Scoped to the
   bare-anchor pattern only — Inspections (.jqEdit wrapper) keeps its
   existing treatment where active/disabled share the same muted color. */
body.page-grid .dxgvDataRow td a > img.Img-Std-EditDisabled {
    opacity: 0.45;
}

body.page-grid .dxgvDataRow td .jqEdit:hover,
body.page-grid .dxgvDataRow td a[id*='lbEdit']:hover,
body.page-grid .dxgvDataRow td a:hover > img.Img-Std-Edit,
body.page-grid .dxgvDataRow td a:hover > img.Img-Std-Add {
    color: var(--q88-grid-primary);
}

/* Contained hover tint behind the pencil. Now that the anchor is a 28px box
   (above), this fills only the button, never the column. Bare-anchor edit/add
   variants get the same treatment for consistency; read-only (EditDisabled) is
   intentionally excluded so it offers no clickable affordance. */
body.page-grid .dxgvDataRow td .jqEdit:hover,
body.page-grid .dxgvDataRow td a[id*='lbEdit']:hover,
body.page-grid .dxgvDataRow td a:hover:has(> img.Img-Std-Edit),
body.page-grid .dxgvDataRow td a:hover:has(> img.Img-Std-Add) {
    background: rgba(var(--primary-tint), 0.08);
}

/* Any sprite image in a data cell sits on the baseline by default, which
   adds phantom descent space under text-only rows. Aligning to middle
   restores a 42px row height. */
body.page-grid .dxgvDataRow td img {
    vertical-align: middle;
}

/* ==========================================================================
   8. Pager — right-aligned navigation matching the Figma chip layout.

   DX renders: First | Prev | [input] of N | Next | Last ... Show 15 25 50
   Figma shows only: < Previous | 1 | 2 | 3 | ... | Next >
   We strip the controls Figma doesn't show (First, Last, "Show NN" sizes,
   extra pager text) and keep Prev + page-number pill + "of N" + Next.
   ========================================================================== */

body.page-grid .GridPager,
body.page-grid .dxgvPagerBottomPanel {
    background: #f5f5f5 !important; /* Figma base/muted */
    background-image: none !important;
    border-top: 1px solid var(--q88-grid-border) !important;
    padding: 6px 16px !important;
    min-height: 48px;
    box-sizing: border-box;
    font-family: var(--q88-grid-font);
    color: var(--q88-grid-fg);
    font-size: 14px;
}

/* Outer pager table — full width, but content right-aligned via TD align. */
body.page-grid .GridPager > div {
    padding: 0 !important;
}

body.page-grid .GridPager table {
    border: 0 !important;
    border-collapse: collapse !important;
    background: transparent !important;
}

body.page-grid .GridPager table td {
    background: transparent !important;
    padding: 0 !important;
    border: 0 !important;
    font-family: var(--q88-grid-font);
    vertical-align: middle !important;
    color: var(--q88-grid-muted-fg);
    white-space: nowrap;
}

/* Right-align the nav + page size sections; hide the extra empty TDs that
   DX pads the outer pager table with.
   NOTE: use `[id*=...]` (contains) so we match both DX naming conventions —
   Inspections.aspx emits `_tdPagerButtons_0`, every other ASPxGridView in the
   solution emits bare `_tdPagerButtons`. */
body.page-grid .GridPager > div > table > tbody > tr > td[id*='_tdExtraPagerText'] {
    width: 0 !important;
    padding: 0 !important;
}

/* Pager strip layout: split row — "Show [N ▾]" left, Prev/Next/page-input right.
   The GridPager.ascx markup emits the size cell AFTER the buttons cell, so we
   re-order via flex (`order: -1` on tdPageSizeOptions) and let `margin-right:
   auto` push the buttons cell to the far right. Defeating the markup
   `align="center"` / `align="right"` with explicit text-align overrides. */
body.page-grid .GridPager > div > table > tbody > tr {
    display: flex !important;
    align-items: center !important;
    width: 100% !important;
}

body.page-grid .GridPager > div > table > tbody > tr > td[id*='_tdPageSizeOptions'] {
    order: -1 !important;
    margin-right: auto !important;
    width: auto !important;
    text-align: left !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

body.page-grid .GridPager > div > table > tbody > tr > td[id*='_tdPagerButtons'] {
    width: auto !important;
    text-align: right !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

body.page-grid .GridPager > div > table > tbody > tr > td[id*='_tdPagerText'] {
    width: auto !important;
    padding-right: 12px !important;
    text-align: right !important;
}

/* Inner button table — natural inline flow inside the left cell. */
body.page-grid .GridPager td[id*='_tdPagerButtons'] > table {
    display: inline-table !important;
}

body.page-grid .GridPager td[id*='_tdPagerButtons'] > table td {
    padding: 0 2px !important;
}

/* Navigation arrow sprites — replace background sprite with text labels so
   buttons read "Prev" / "Next" instead of rendering as tiny icons. */
body.page-grid .GridPager a.Img-Pgr {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: auto !important;
    height: 32px !important;
    min-width: 36px;
    padding: 0 10px !important;
    background-image: none !important;
    background-color: var(--q88-grid-card) !important;
    border: 1px solid var(--q88-grid-border) !important;
    border-radius: 6px !important;
    color: var(--q88-grid-fg) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important; /* beats GridWhiteout.css `.dxgvControl a { font-size: 12px !important }` */
    font-weight: 500 !important;
    line-height: 20px !important;
    text-decoration: none !important;
    box-sizing: border-box !important;
    vertical-align: middle;
    text-indent: 0 !important;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

body.page-grid .GridPager a.Img-Pgr:hover {
    background-color: var(--q88-grid-muted) !important;
    border-color: #cbd5e1 !important;
}

/* Symbol + label via ::before/::after */
/* Figma shows only Previous and Next — hide First and Last completely.
   Hide the wrapping <td> too via :has(), not just the <a> — otherwise the
   GridPager.ascx markup leaves an empty TD with `&nbsp;` and `padding: 0 2px`
   in front of Prev (and after Next) that produces ~7px phantom whitespace
   on each side. (`:has()` is supported in Edge 105+ / Chrome 105+ / Safari 15.4+.)
   NOTE: target via class prefix (Img-PgrFirst, Img-PgrLast) instead of ID
   suffix — Inspections.aspx emits `_pagerFirst_0` but every other
   ASPxGridView in the solution emits bare `_pagerFirst`. Class-based
   selectors cover both. */
body.page-grid .GridPager a[class*='Img-PgrFirst'],
body.page-grid .GridPager a[class*='Img-PgrLast'],
body.page-grid .GridPager td[id*='_tdPagerButtons'] > table td:has(> a[class*='Img-PgrFirst']),
body.page-grid .GridPager td[id*='_tdPagerButtons'] > table td:has(> a[class*='Img-PgrLast']) {
    display: none !important;
}

/* Previous / Next chip styling — text-only, muted outline per Figma. */
body.page-grid .GridPager a[class*='Img-PgrPrev']::before { content: '‹'; margin-right: 6px; font-size: 16px; line-height: 1; color: var(--q88-grid-muted-fg); }
body.page-grid .GridPager a[class*='Img-PgrPrev']::after  { content: 'Previous'; }

body.page-grid .GridPager a[class*='Img-PgrNext']::before { content: 'Next'; }
body.page-grid .GridPager a[class*='Img-PgrNext']::after  { content: '›'; margin-left: 6px; font-size: 16px; line-height: 1; color: var(--q88-grid-muted-fg); }

/* Prev/Next are shadcn "ghost" pills in Figma: transparent until hover,
   rounded-md 8px, h-36, 14px medium text. */
body.page-grid .GridPager a[class*='Img-PgrPrev'],
body.page-grid .GridPager a[class*='Img-PgrNext'] {
    border: 0 !important;
    background: transparent !important;
    height: 36px !important;
    padding: 0 12px !important;
    border-radius: 8px !important;
    color: var(--q88-grid-fg) !important;
    font-weight: 500 !important;
}

body.page-grid .GridPager a[class*='Img-PgrPrev']:hover,
body.page-grid .GridPager a[class*='Img-PgrNext']:hover {
    background: #e5e7eb !important;
    border: 0 !important;
    color: var(--q88-grid-fg) !important;
}

/* Disabled state for First/Prev when on page 1 */
body.page-grid .GridPager a.Img-PgrFirstDis,
body.page-grid .GridPager a.Img-PgrPrevDis,
body.page-grid .GridPager a.Img-PgrNextDis,
body.page-grid .GridPager a.Img-PgrLastDis {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

/* Page input styled as the "active page chip" per Figma: 36x36 square,
   white bg, 1px #e5e5e5 border, rounded-md, 14px medium centered. */
body.page-grid .GridPager input#txtPage,
body.page-grid .GridPager input[id*='txtPage'] {
    width: 36px !important;
    height: 36px !important;
    padding: 0 !important;
    margin: 0 4px;
    border: 1px solid #e5e5e5 !important;
    border-radius: 8px !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    color: var(--q88-grid-fg) !important;
    text-align: center;
    box-sizing: border-box !important;
    background: #ffffff !important;
}

body.page-grid .GridPager input#txtPage:focus {
    outline: 2px solid var(--q88-grid-primary);
    outline-offset: -1px;
    border-color: var(--q88-grid-primary) !important;
}

/* Hide the unused extra-pager-text / pager-text slots emitted by the
   GridPager.ascx skin (LegendContent / pnlPagerLeft) — they are typically
   empty and would only add whitespace inside our 49h strip.
   Note: tdPageSizeOptions intentionally NOT hidden — it carries the
   "Show [15 ▾] results per page" select rendered by GridPager.ascx for
   PortalId 0/1/2 (Q88, Baltic99, Milbros). See §5.6.1. */
body.page-grid .GridPager td[id*='_tdExtraPagerText'],
body.page-grid .GridPager td[id*='_tdPagerText'] {
    display: none !important;
}

/* "Page" and "of N" text around the page input — mute and shrink so they
   read as supplementary to the pill, matching Figma's "1 | 2 | 3" chips. */
body.page-grid .GridPager td[id*='_tdPagerButtons'] > table > tbody > tr > td:nth-child(3) {
    color: var(--q88-grid-muted-fg) !important;
    font-size: 14px !important;
    padding: 0 4px !important;
}

/* ==========================================================================
   8c. Rows-per-page selector (DESIGN.md §5.6.1)
   GridPager.ascx renders "Show <select> results per page" inside
   td[id*='_tdPageSizeOptions'] for Q88/Baltic99/Milbros portals
   (PortalId 0/1/2 — see GridPager.ascx.cs:131-156). Skin the native
   <select> to match §9.6.1 plain-select aesthetic and mute the bracket
   text so the focal element is the select itself.
   ========================================================================== */

body.page-grid .GridPager td[id*='_tdPageSizeOptions'] .grdRecordsToShow {
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    color: var(--q88-grid-muted-fg) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    line-height: 20px;
    white-space: nowrap;
}

body.page-grid .GridPager select#dlGridPageSizes,
body.page-grid .GridPager td[id*='_tdPageSizeOptions'] select {
    height: 32px;
    min-width: 64px;
    padding: 0 28px 0 10px !important;
    margin: 0 !important;
    border: 1px solid var(--q88-grid-border) !important;
    border-radius: 8px !important;
    background-color: var(--q88-grid-card, #ffffff) !important;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--q88-grid-muted-fg) 50%),
        linear-gradient(-45deg, transparent 50%, var(--q88-grid-muted-fg) 50%) !important;
    background-position:
        right 12px center,
        right 7px center !important;
    background-size: 5px 5px, 5px 5px !important;
    background-repeat: no-repeat !important;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    color: var(--q88-grid-fg) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 20px !important;
    cursor: pointer;
    box-sizing: border-box;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

body.page-grid .GridPager select#dlGridPageSizes:hover,
body.page-grid .GridPager td[id*='_tdPageSizeOptions'] select:hover {
    background-color: var(--q88-grid-muted) !important;
    border-color: #cbd5e1 !important;
}

body.page-grid .GridPager select#dlGridPageSizes:focus,
body.page-grid .GridPager td[id*='_tdPageSizeOptions'] select:focus {
    outline: 2px solid var(--q88-grid-primary);
    outline-offset: -1px;
    border-color: var(--q88-grid-primary) !important;
}

/* ==========================================================================
   8b. Filter bar — "Create Filter" link styled as a secondary outline button
   ASPxGridView renders the filter builder link inside `.dxgvFilterBar` (old)
   or `.dx-datagrid-filter-panel` (newer DX). Match both so the CTA reads as
   a pill button instead of an underlined blue hyperlink. Design spec:
   - Default: transparent fill, 1px secondary-foreground border, teal text
   - Hover:   alpha/80 base/secondary fill, no text underline
   ========================================================================== */

body.page-grid .dxgvFilterBar,
body.page-grid .dx-datagrid-filter-panel {
    background: var(--q88-grid-muted) !important;
    background-image: none !important;
    border-top: 1px solid var(--q88-grid-border) !important;
    padding: 8px 12px !important;
    font-family: var(--q88-grid-font);
    color: var(--q88-grid-fg);
}

body.page-grid .dxgvFilterBar a,
body.page-grid .dx-datagrid-filter-panel a,
body.page-grid .dx-datagrid-filter-panel .dx-datagrid-filter-panel-text,
body.page-grid .dx-datagrid-filter-panel .dx-icon-filter {
    display: inline-flex !important;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 12px !important;
    background: transparent !important;
    border: 1px solid var(--q88-grid-border) !important;
    border-radius: 8px !important;
    color: var(--q88-grid-primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 20px !important;
    text-decoration: none !important;
    cursor: pointer;
    box-sizing: border-box !important;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

body.page-grid .dxgvFilterBar a:hover,
body.page-grid .dx-datagrid-filter-panel a:hover,
body.page-grid .dx-datagrid-filter-panel .dx-datagrid-filter-panel-text:hover {
    background: rgba(245, 245, 245, 0.8) !important; /* alpha/80 on base/secondary */
    border-color: #cbd5e1 !important;
    text-decoration: none !important;
}

/* Inline filter icon — thin outline funnel, keyed off the anchor so we
   don't depend on DX's sprite image. */
body.page-grid .dxgvFilterBar a::before,
body.page-grid .dx-datagrid-filter-panel a::before {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polygon points='22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3'/></svg>") center / contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polygon points='22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3'/></svg>") center / contain no-repeat;
    flex: 0 0 14px;
}

/* Hide DX's built-in filter icon sprite since we draw our own via mask. */
body.page-grid .dxgvFilterBar a img,
body.page-grid .dx-datagrid-filter-panel .dx-icon-filter::before {
    display: none !important;
}

/* ==========================================================================
   9. Quiet noisy legacy inline styles
   ========================================================================== */

/* Remove the underline and dashed 1px border FleetVessel's V2 layer adds */
body.page-grid .modV2TRight-FleetVessel select {
    border-bottom-width: 1px !important;
}

/* Label must not reserve extra width at tight widths — let it shrink so the
   filter dropdowns fit on the same row with titleRight. */
body.page-grid td.modV2Title {
    min-width: 0;
    overflow: hidden;
    text-overflow: clip;
    padding-right: 12px !important;
}

/* ==========================================================================
   9b. Page background — subtle bathymetric pattern
   Figma App Background (node 252:16356): full-width bathymetric image tiled
   vertically behind page content. Reuses /images/page/bathymetric-pattern.png
   (same asset the Questionnaire refresh uses). Painted directly on body so
   it's fixed on scroll, and a 70% white linear-gradient veil is composited
   on top to simulate the Figma "opacity 30%" on the pattern — this way a
   full-density PNG still reads as subtle.
   ========================================================================== */

body.page-grid {
    background-color: #ffffff;
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.7)),
        url('/images/page/bathymetric-pattern.png');
    background-repeat: no-repeat, repeat-y;
    background-size: cover, 100% auto;
    background-position: center top, center top;
    background-attachment: fixed, fixed;
}

/* Let the page-level pattern bleed through the classic ContentPaneBody <td>
   that wraps every page's content. Without this override the TD's opaque
   white background paints over the body background and hides the pattern
   entirely. The card (.modV2) keeps its own white background so the
   pattern only shows in the gutter around the card. */
body.page-grid .ContentPaneBody {
    background: transparent !important;
}

/* ==========================================================================
   10. Responsive — wrap the right-side controls on narrower viewports
   ========================================================================== */

@media (max-width: 1200px) {
    body.page-grid [id$='_pnlTitleRight'] {
        flex-wrap: wrap;
        justify-content: flex-end;
        row-gap: 8px;
    }

    body.page-grid .searchBoxDiv {
        width: 220px;
    }
}

@media (max-width: 900px) {
    body.page-grid .modV2 {
        margin: 12px;
        padding: 12px;
    }

    body.page-grid .modV2TitleContainer {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

    body.page-grid [id$='_pnlTitleLeft'],
    body.page-grid [id$='_pnlTitleRight'] {
        flex-wrap: wrap;
    }

    body.page-grid [id$='_pnlTitleRight'] {
        margin-left: 0;
    }
}

/* ==========================================================================
   9. Certificate Settings — per-page deltas (page-certificate-settings)
   --------------------------------------------------------------------------
   The Type in-row cell wraps its <select class="qDdl"> in a legacy
   <div class="qDiv"> that carries its own 1px slate border, 4px radius and
   6px left padding. The inner shimmed <select.qDdl> already paints canonical
   form-control chrome (§9.6.1 + select-shim), producing the "input inside an
   input" double border — see MEMORY [legacy-qdiv-wrapper-trap.md]. Flatten
   ONLY the qDiv wrappers that contain a shimmed select so the inner chrome
   shows alone. The Code column also uses qDiv > <input type="text"> but the
   bare input has no chrome of its own — the qDiv IS its visible container,
   so we leave that variant alone.

   Longhand `border-width` + `background-color` (NOT shorthand) to avoid the
   `background:` / `border:` shorthand+var()+!important parser trap from
   MEMORY [css-shorthand-var-important-parser-trap.md].
   ========================================================================== */

body.page-certificate-settings .dxgvDataRow td .qDiv:has(> select.qDdl),
body.page-certificate-settings tr[class*='dxgvDataRow'] td .qDiv:has(> select.qDdl) {
    border-width: 0 !important;
    border-radius: 0 !important;
    background-color: transparent !important;
    background-image: none !important;
    padding: 0 !important;
}

/* Native checkbox tint is now global on body.sidebar-nav — see
   components.css `--- Native checkboxes ---` block. No per-page rule
   needed here. */
