/* ==========================================================================
   Manage Vessels page (vessel.aspx → VesselManagement.ascx) — full page skin.
   ----------------------------------------------------------------------------
   Scoped via `body.page-vessel-management`. Unlike the Inspections /
   Manage Users / Abbreviations skins this file does NOT layer on top of
   grid.css — VesselManagement.ascx still uses the LEGACY <uc:ModuleTemplate>
   wrapper (.modContainerLarge / .modInnerContainer / .modTLeft / .modTRight)
   and the body grid is an <asp:Repeater> rendering an HTML <table class="StdTable">,
   not the <uc:ModuleTemplateV2> + ASPxGridView combo grid.css was built for.

   So we re-implement the same visual language (white card, soft shadow,
   12px radius, 18px page title, 32px filter pills, teal #0d9488 primary CTA,
   light grid header, hover rows) directly against the legacy class names.
   Design tokens mirror grid.css so the page looks identical to Inspections
   and Manage Users at a glance.
   ========================================================================== */

body.page-vessel-management {
    --q88-grid-fg: #0a0a0a;
    --q88-grid-muted: #f5f5f5;
    --q88-grid-muted-fg: var(--text-muted);
    --q88-grid-placeholder: #737373;
    --q88-grid-border: #e5e5e5;
    --q88-grid-card: #ffffff;
    --q88-grid-primary: var(--primary);
    --q88-grid-primary-hover: var(--button-primary-hover);
    --q88-grid-primary-fg: #ffffff;
    --q88-grid-row-hover: var(--surface-card);
    --q88-grid-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    /* Non-active (deleted) vessel rows — see §5.7.
       fg: the real semantic token, the same one --q88-grid-muted-fg above already
       binds for this page's labels and the same one company-info-popup.css §11.4
       uses for the identical Disabled/DisabledAlt case. Resolves to --raw-slate-500
       (#475569) under the refresh — 7.3:1 on the band below, i.e. WCAG AAA for body
       text, so "de-emphasised" never becomes "unreadable". It is the signal.
       bg: barely-there by design (≈1.02:1 against the white card) — a hint that
       supports the fg, never a zebra stripe.
       CAVEAT on the bg: --surface-muted-subtle is NOT defined in tokens.css. It is
       referenced ~10 times across 5 refresh sheets and every one supplies this same
       #fafbfc fallback, so the literal is what actually renders — a de-facto
       convention rather than a token. Kept in that form so this page moves with the
       others if the token is ever declared for real. Unlike the fg it does NOT
       follow dark mode, but neither do --q88-grid-card / -fg / -border / -muted
       above: this skin is light-only by construction. */
    --q88-grid-deleted-fg: var(--text-muted);
    --q88-grid-deleted-bg: var(--surface-muted-subtle, #fafbfc);
}

/* ==========================================================================
   1. Module wrapper — flatten legacy ModuleTemplate chrome into a clean card.
      .modContainerLarge is a <table>, .modInnerContainer is the <div> inside.
   ========================================================================== */

body.page-vessel-management .modContainerLarge {
    background: var(--q88-grid-card);
    border: 1px solid var(--q88-grid-border);
    border-radius: 8px;
    box-shadow: none;      /* DESIGN.md §5.1 / §16.1 — grid cards are border-only, no shadow */
    font-family: var(--q88-grid-font);
    color: var(--q88-grid-fg);
    box-sizing: border-box;
    width: calc(100% - 24px);
    max-width: calc(100% - 24px);
    min-width: 0;          /* legacy 960px floor pushes off the sidebar layout */
    margin: 16px 12px;
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

/* Inner div carries a navy 1px border in MainWhiteout — neutralise it so the
   only visible edge is the outer card's #e5e5e5 stroke. Same for the alert
   variant (we keep the red stroke off this page; alerts still render via the
   inline lblHdrAlert text). */
body.page-vessel-management .modInnerContainer,
body.page-vessel-management .modInnerContainerIsAlert {
    border: 0 !important;
    background: transparent;
    padding: 16px 20px 20px;
}

/* The above/below decorative bars (modAboveLeft/Right, modBelowLeft/Right)
   ship empty on this page — collapse them so the wrapper has no extra rows. */
body.page-vessel-management .modAboveLeft,
body.page-vessel-management .modAboveRight,
body.page-vessel-management .modBelowLeft,
body.page-vessel-management .modBelowRight {
    display: none;
}

/* ==========================================================================
   2. Title bar — "Manage Vessels" label (left) + action buttons (right).
      Legacy .modTitle uses float layout and wraps two panels (.modTLeft,
      .modTRight). Convert to flex so left/right align on a single 40px row.
   ========================================================================== */

body.page-vessel-management .modTitle {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 40px;
    width: 100%;
    background: transparent;
    overflow: visible;     /* legacy `overflow:auto` clips the action pills */
    margin: 0 0 16px 0;
    padding: 0;
    font-size: inherit;    /* legacy 12px gets replaced by per-element sizes */
    font-weight: inherit;
}

body.page-vessel-management .modTLeft,
body.page-vessel-management .modTRight {
    float: none !important;     /* clear legacy float layout */
    padding: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    background: transparent;
}

body.page-vessel-management .modTLeft {
    font-family: var(--q88-grid-font);
    font-size: 18px;
    font-weight: 600;
    color: var(--q88-grid-fg);
    line-height: 28px;
    letter-spacing: 0;
    text-transform: none;
}

body.page-vessel-management .modTRight {
    margin-left: auto;
    /* The .ascx separates the three action LinkButtons with literal
       `&nbsp;&nbsp;&nbsp;&nbsp;` text runs between them. Inside a flex
       container those whitespace runs become anonymous flex items that
       (a) render at the parent font-size, consuming ~25-30px each, and
       (b) sit BETWEEN our 8px container `gap`s — so the visible spacing
       was inconsistent and oversized.
       `font-size: 0` collapses the whitespace items to 0 width; the pill
       children re-set their own 14px font-size. We then halve the
       container gap to 4px because each anonymous 0-width item still
       creates two gap boundaries between successive pills (4px × 2 = 8px
       effective gap, matching the Inspections title bar). */
    font-size: 0;
    gap: 4px;
}

/* ==========================================================================
   3. Action buttons in the title bar.
      The .ascx ships an inline `<style>` rule `.modTRight a { color: #FFF }`
      and MainWhiteout ships `.modTitle a, .modTRight a { color: var(--text-on-brand) }`.
      We need higher specificity to repaint these as page-content links.

      btnAddVessel + lnkRequestAccess + lnkManageFleet → TEXT LINKS.

      These were a filled pill (Add New Vessel) plus two ghost outline pills.
      They now render as plain links, matching how the same three look on the
      Fleet List tab of CompanyInfoPopup: those anchors carry `class="underline"`
      rather than `.LinkButton`, so they fall to company-info-popup.css:1083-1096,
      which paints `.modTRight a:not(.LinkButton)` as a --primary text link.
      Three pills competing for attention above a data grid read heavier than the
      page needs. Values mirror that rule (transparent, --primary, 14px/500,
      underline on hover). Keep the two in sync.

      They still need explicit rules despite being "just links": the inline
      `<style>` above and MainWhiteout:1489 both claim these anchors, so the
      colour must be restated at higher specificity or they render white-on-white.

      All three carry a <uc:ImageManager> icon span inside — we hide it so
      the link is text-only, matching the new visual language. The icon is
      decorative (the label text already says what the action does).
   ========================================================================== */

body.page-vessel-management .modTRight a[id$='_btnAddVessel'],
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess'],
body.page-vessel-management .modTRight a[id$='_lnkManageFleet'],
body.page-vessel-management .modTRight a[id$='_btnAddVessel']:link,
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess']:link,
body.page-vessel-management .modTRight a[id$='_lnkManageFleet']:link,
body.page-vessel-management .modTRight a[id$='_btnAddVessel']:visited,
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess']:visited,
body.page-vessel-management .modTRight a[id$='_lnkManageFleet']:visited {
    /* inline-flex (not inline) keeps the label vertically centred on the 40px
       title row now that there is no pill box doing it. */
    display: inline-flex !important;
    align-items: center;
    height: auto;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0;
    background: transparent !important;
    color: var(--q88-grid-primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 20px;
    text-decoration: none !important;
    box-shadow: none !important;
    cursor: pointer;
    transition: color 120ms ease;
}

body.page-vessel-management .modTRight a[id$='_btnAddVessel']:hover,
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess']:hover,
body.page-vessel-management .modTRight a[id$='_lnkManageFleet']:hover,
body.page-vessel-management .modTRight a[id$='_btnAddVessel']:focus,
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess']:focus,
body.page-vessel-management .modTRight a[id$='_lnkManageFleet']:focus {
    background: transparent !important;
    color: var(--q88-grid-primary-hover) !important;
    text-decoration: underline !important;
}

/* Note — the .ascx wraps each label in <uc:ImageManager> but ImageManager
   returns bare label text on this portal (ImageManager.ascx.cs:86-90 forces
   ImageIcon = NONE for PortalId < 3, then :457 returns LabelText), so there is
   no icon <img> to hide and no <span> wrapper. So we DON'T inject a `::before`
   label — that would render twice.

   These three carry class="underline", NOT .LinkButton, so the filter-row rule
   in §4 does not reach them — but they are still asp:LinkButtons and still get
   the injected `<ins>&nbsp;</ins>` spacer. Under inline-flex that nbsp is a
   ~4.5px flex item indenting each label. Hide it here too. */
body.page-vessel-management .modTRight a[id$='_btnAddVessel'] > ins,
body.page-vessel-management .modTRight a[id$='_lnkRequestAccess'] > ins,
body.page-vessel-management .modTRight a[id$='_lnkManageFleet'] > ins {
    display: none !important;
}

/* §2 collapses the literal `&nbsp;&nbsp;&nbsp;&nbsp;` runs between these three
   to zero width via `font-size: 0`, leaving only the flex `gap` (doubled,
   because each 0-width anonymous item sits between two gap boundaries). At pill
   widths 4px→8px effective was right; bare text links with no border need more
   air to read as three separate actions, so lift it to 8px→16px effective. */
body.page-vessel-management .modTitle .modTRight {
    gap: 8px;
}

/* ==========================================================================
   4. Filter / search row — table#tblAdmin
      Houses: Company:[dropdown] Go [Admin] | Vessel:[search box] [Search] [Show deleted]
      We strip the legacy borders, neutralise .SubHeaderAdmin (which paints
      a navy band on legacy pages), and re-skin each control to match the
      32px filter-pill language used in grid.css.
   ========================================================================== */

body.page-vessel-management table[id$='tblAdmin'] {
    width: 100%;
    margin: 0 0 16px 0;
    border-collapse: separate;
    border-spacing: 0;
    background: transparent;
    table-layout: fixed;
}

body.page-vessel-management table[id$='tblAdmin'] tr.SubHeaderAdmin {
    background: transparent !important;
    background-image: none !important;
}

body.page-vessel-management table[id$='tblAdmin'] td {
    background: transparent !important;
    border: 0 !important;
    padding: 6px 8px;
    /* font-family needs no !important: MainWhiteout's
       `body, input, select, textarea, td, form { font-family: var(--font-family) }`
       resolves to the SAME Inter stack on refresh pages (tokens.css rebinds
       --font-family to Inter under body.sidebar-nav), and --q88-grid-font is
       that same Inter stack — so whichever rule wins, the font is Inter.   */
    font-family: var(--q88-grid-font);
    /* Treat plain-text in any filter cell as a label (matches "Company:" /
       "Vessel:" / "Show deleted"). The `.SubHeaderAdmin td` rule in
       Q88Whiteout.css ships `font-weight: bold` (specificity 0,0,2,1) — our
       td rule has higher specificity (0,0,3,1+) so we MUST set font-weight
       explicitly here to keep it from cascading through and bolding every
       free-floating text node in the row.
       Form controls and .LinkButton anchors re-set their own 14px/normal-or-
       500 typography below. */
    font-size: 13px;
    font-weight: 500;
    color: var(--q88-grid-muted-fg);
    vertical-align: middle;
    /* line-height: 32px gives every inline child of the filter cell (text
       nodes "Company:" / "Vessel:" / "Show deleted", form controls, and
       LinkButton anchors) a uniform 32px line box. Without this, the line
       baseline is determined by the tallest natural-baseline element on the
       line, and shorter elements (select, checkbox, raw text) drift down by
       3-11px relative to the LinkButton anchors which are display:inline-flex.
       With line-height locked to 32 + vertical-align: middle on each child
       below, every interactive control + label sits on a single y-axis. */
    line-height: 32px;
}

/* Vertically center every interactive child in the 32px line box. Without
   this, native form controls and labels ride their text baseline while
   LinkButton anchors (display: inline-flex) ride the inline-flex baseline —
   different baselines produce visible shifts of 3-11px. `vertical-align:
   middle` aligns the midpoint of each box to the midpoint of the parent's
   line, making everything land on the same y. */
body.page-vessel-management table[id$='tblAdmin'] select,
body.page-vessel-management table[id$='tblAdmin'] input[type='text'],
body.page-vessel-management table[id$='tblAdmin'] input[type='checkbox'],
body.page-vessel-management table[id$='tblAdmin'] a.LinkButton,
body.page-vessel-management table[id$='tblAdmin'] label {
    vertical-align: middle;
}

/* Native <select> from <Q88:DropDownList> + <input type="text"> →
   identical 32px filter pill. */
body.page-vessel-management table[id$='tblAdmin'] select,
body.page-vessel-management table[id$='tblAdmin'] input[type='text'] {
    height: 32px;
    min-width: 220px;
    padding: 6px 12px;
    background-color: var(--q88-grid-card);
    border: 1px solid var(--q88-grid-border);
    border-radius: 8px;
    color: var(--q88-grid-fg);
    /* font-family — see the td rule above; --q88-grid-font matches what
       MainWhiteout resolves to (Inter) on refresh pages, so no !important. */
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    box-sizing: border-box;
    box-shadow: none;
    outline: none;
}

body.page-vessel-management table[id$='tblAdmin'] select {
    /* A native <select> with no explicit width sizes to its WIDEST option.
       cbxCompany's list holds long company names, so the closed control
       ballooned to ~578px — that pushed "Go" out and wrapped the "Admin"
       button onto a second line, staggering the whole filter row. Pin a
       fixed width; the closed control only ever shows the (short) selected
       company, and the option list still expands on open. */
    width: 240px;
    max-width: 100%;
    padding-right: 32px;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'><path d='M3 4.5L6 7.5L9 4.5' stroke='%23737373' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: calc(100% - 12px) 50%;
    background-size: 12px 12px;
    cursor: pointer;
}

body.page-vessel-management table[id$='tblAdmin'] input[type='text'] {
    min-width: 200px;
}

body.page-vessel-management table[id$='tblAdmin'] select:focus,
body.page-vessel-management table[id$='tblAdmin'] input[type='text']:focus {
    border-color: var(--q88-grid-primary);
    outline: 2px solid var(--q88-grid-primary);
    outline-offset: -1px;
}

/* Inline LinkButtons in the filter row — Go / Admin / Search → indigo buttons.
   MainWhiteout's `.LinkButton` already paints a solid pill, but in the legacy
   brand colour and with its own !important, so every colour has to be restated.
   Filled --q88-grid-primary (= --primary = --raw-indigo-600 #4F46E5 under the
   refresh) with white text, i.e. the same solid-primary treatment
   company-info-popup.css:1002 gives .LinkButton on the popup.
   All three stay buttons: unlike the title-bar actions in §3 (now text links),
   these operate the controls they sit against — Go applies the company
   dropdown, Search submits the vessel textbox, Admin opens User Management. */
body.page-vessel-management table[id$='tblAdmin'] a.LinkButton {
    display: inline-flex !important;
    align-items: center;
    gap: 4px;
    /* box-sizing: border-box collapses the 1px borders into the height budget,
       so the visible total height is exactly 32px — matching the
       <select> / <input> rule above (which already uses border-box). Without
       this, the anchor's content-box-sized 32px + 2*1px border rendered at
       34px total, leaving the buttons sticking 1px above the select and
       textbox. Kept even though the border is now the same colour as the fill:
       it still occupies the same 2px of the height budget. */
    box-sizing: border-box;
    height: 32px;
    padding: 0 14px !important;
    border-radius: 8px;
    background: var(--q88-grid-primary) !important;
    color: var(--q88-grid-primary-fg) !important;
    border: 1px solid var(--q88-grid-primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    font-weight: 500 !important;
    line-height: 20px;
    text-decoration: none !important;
    background-image: none !important;
    box-shadow: none !important;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}

body.page-vessel-management table[id$='tblAdmin'] a.LinkButton:hover {
    background: var(--q88-grid-primary-hover) !important;
    border-color: var(--q88-grid-primary-hover) !important;
    color: var(--q88-grid-primary-fg) !important;
}

/* Kill the `<ins>&nbsp;</ins>` spacer so the label sits centred.
   Every asp:LinkButton on this page renders one — verified in the DOM:
       <a id="…_btnGo" class="LinkButton" onkeypress="…"><ins>&nbsp;</ins>Go</a>
   It is NOT in the .ascx (which just sets Text="Go"); something server-side
   injects it along with the onkeypress handler. Harmless in the legacy inline
   layout it was written for, but these buttons are `display: inline-flex`, so
   the <ins> becomes a flex ITEM: its non-breaking space (~4.5px, and nbsp does
   not collapse) plus the 4px `gap` pushed every label ~8-9px right, reading as
   lopsided left padding. That surplus is fixed, not proportional to the label,
   which is what gave it away — Go, Admin and Search were all off by the same
   amount despite very different text widths.
   img/input[type=image] included defensively: ImageManager returns bare label
   text on Q88/Q88Dry/Milbros (ImageManager.ascx.cs:86-90 forces ImageIcon=NONE
   for PortalId < 3), but portals ≥ 3 would emit an icon plus two 5px clearpixel
   spacers into the same flex row.
   Sister rule: company-info-popup.css:1035-1041, which already does exactly
   this — the reason the popup's buttons look correctly centred. */
body.page-vessel-management table[id$='tblAdmin'] a.LinkButton > ins,
body.page-vessel-management table[id$='tblAdmin'] a.LinkButton img,
body.page-vessel-management table[id$='tblAdmin'] a.LinkButton input[type='image'] {
    display: none !important;
}

/* "Show deleted" checkbox + label.
   asp:CheckBox renders as `<input type="checkbox"><label>Show deleted</label>`
   without any wrapper. Native checkbox sits on text baseline (~3px above the
   middle of a 32px control row). Using vertical-align:middle on both pulls
   them onto the same y-axis as the 32px filter pills. */
body.page-vessel-management table[id$='tblAdmin'] input[type='checkbox'] {
    vertical-align: middle;
    margin: 0 4px 0 8px;
}

body.page-vessel-management table[id$='tblAdmin'] input[type='checkbox'] + label,
body.page-vessel-management table[id$='tblAdmin'] label {
    vertical-align: middle;
    color: var(--q88-grid-muted-fg);
    font-size: 13px;
    font-weight: 500;
    margin-left: 0;
}

/* ==========================================================================
   5. Vessel list grid — <asp:Repeater> rendering <table class="StdTable">
      with rows class="GridHeaderLight" / "GridData" and header cells
      class="tableHeader". The .ascx inline <style> block forces
      `.tableHeader { background-color:#4F72A4; position:sticky; top:0 }` —
      we override here on body+table specificity (single class beats single
      class only on declaration order, but adding `body.page-vessel-management`
      gives us 0,0,2,1 > 0,0,1,0 so the navy bar yields).
   ========================================================================== */

body.page-vessel-management .modMain {
    padding: 0;
    background: transparent;
}

body.page-vessel-management .modMain table.StdTable {
    width: 100%;
    border: 0;
    border-collapse: separate;
    border-spacing: 0;
    background: transparent;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    color: var(--q88-grid-fg);
}

/* Header row — light surface, muted-fg, 12px uppercase. Replaces the navy
   #4F72A4 inline rule. */
body.page-vessel-management .modMain table.StdTable tr.GridHeaderLight,
body.page-vessel-management .modMain table.StdTable tr.GridHeader {
    background: transparent !important;
}

body.page-vessel-management .modMain table.StdTable td.tableHeader {
    background-color: var(--q88-grid-muted);
    /* Match the canonical grid.css header (Inspections reference, DESIGN.md §5.3):
       14px / 500 / normal-case / slate-900 fg / 11px 16px pad. Was 12px/600
       uppercase muted — an outlier vs every other refreshed grid page. */
    color: var(--q88-grid-fg);
    /* font-family — see the filter-row td rule; --q88-grid-font matches the
       Inter that MainWhiteout's td rule resolves to on refresh, no !important. */
    font-family: var(--q88-grid-font);
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
    text-transform: none;
    letter-spacing: normal;
    text-align: left;
    padding: 11px 16px;
    border: 0;
    border-bottom: 1px solid var(--q88-grid-border);
    /* `position: sticky; top: 0` from .ascx is harmless inside a non-scrolling
       container — let it ride. If the Repeater ever wraps in a scroll pane
       we get a free sticky header. */
}

/* First / last header cell — match Figma's outer-edge breathing room. */
body.page-vessel-management .modMain table.StdTable td.tableHeader:first-child {
    padding-left: 20px;
    border-top-left-radius: 8px;
}
body.page-vessel-management .modMain table.StdTable td.tableHeader:last-child {
    padding-right: 20px;
    border-top-right-radius: 8px;
    text-align: center;     /* "Edit" column header */
}

/* Data rows — soft borders, hover highlight, 14px font.
   The Repeater alternates `class="GridData"` with `class="GridDataAlt"`
   automatically (DataList AlternatingItemTemplate behaviour), so EVERY
   selector targeting data rows must list both classes — without it, alt
   rows fall through to the table's `cellpadding="3"` HTML attribute and
   render with 3px padding, shifting the visible left edge of every other
   row. We don't visually distinguish the two classes (no zebra stripe);
   the modern grid look uses uniform white rows + hover highlight.

   IMPORTANT #2: ItemDataBound (VesselManagement.ascx.cs, the `StatusID != Active`
   branch) does not just alternate the class — for any such vessel it REPLACES it
   with `Disabled` / `DisabledAlt`. Those rows therefore matched NONE of the
   rules below and fell through to the legacy `.StdTable td { padding: 3px }` +
   base td font, so a deleted vessel rendered tighter, at a different font size,
   and with its left edge out of line with every active row above it — the exact
   every-other-row-is-shrunk artifact usermanagement.css §6 calls out for
   `tr.Alt2`. So every selector targeting a data cell lists all FOUR row classes;
   the deleted-specific treatment (muted fg + band + badge) is layered on top in
   §5.7, which must stay AFTER these rules.

   IMPORTANT: every row carries an inline `onmouseover="HighLight(this,'')"`
   attribute (defined in /scripts/Script.js) which sets
   `el.style.backgroundColor = '#DFDFDF'` directly on hover. Inline styles
   normally beat author CSS — but **author `!important` beats inline
   styles** in the cascade (CSS Cascading L4 §6.4.4 rule order: author
   !important > inline > author normal). So we mark our hover bg
   `!important` to keep the modern teal-tinted hover instead of the
   legacy grey #DFDFDF the script injects. */
body.page-vessel-management .modMain table.StdTable tr.GridData,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt {
    background: var(--q88-grid-card) !important;
    transition: background-color 120ms ease;
}
/* Hover applies to deleted rows too — they are still editable (the pencil opens
   the row in restore/edit mode), so they must stay a live target. `:hover` adds a
   pseudo-class, so this out-specifies §5.7's flat band regardless of source order. */
body.page-vessel-management .modMain table.StdTable tr.GridData:hover,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt:hover,
body.page-vessel-management .modMain table.StdTable tr.Disabled:hover,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt:hover {
    background: var(--q88-grid-row-hover) !important;
}

body.page-vessel-management .modMain table.StdTable tr.GridData > td,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td,
body.page-vessel-management .modMain table.StdTable tr.Disabled > td,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td {
    background: transparent;
    color: var(--q88-grid-fg);
    border: 0;
    border-bottom: 1px solid var(--q88-grid-border);
    /* 8px 16px matches grid.css data-cell density (~36px single-line row, the
       §5.4 target) instead of the old 14px (~48px). vertical-align:top is kept
       (not grid.css's `middle`) because this page's Fleet / Companies columns
       wrap to multiple lines — top-align keeps the vessel name level with the
       first line of a multi-line neighbour rather than floating mid-cell. */
    padding: 8px 16px;
    vertical-align: top;
    /* font-family — see filter-row td comment; resolves to the same Inter as
       MainWhiteout's td rule on refresh pages, so no !important needed. */
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
}

body.page-vessel-management .modMain table.StdTable tr.GridData > td:first-child,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td:first-child,
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:first-child,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:first-child {
    padding-left: 20px;
}
body.page-vessel-management .modMain table.StdTable tr.GridData > td:last-child,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td:last-child,
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:last-child,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:last-child {
    padding-right: 20px;
    text-align: center;
    width: 56px;
}

/* "Registered vessel" marker — one fixed 16px box whether or not a star shows,
   so every vessel NAME starts at the same x.
   The .ascx swaps only the src (ItemTemplate: star.png when the vessel is
   registered to this company, else the 1x1.gif spacer) and sets Width="9" on
   both. components.css:1932-1938 then forces `img[src$="/markers/star.png"]` to
   16×16 !important — but nothing touches the spacer, so it stayed 9px and the
   names on unregistered rows hung 7px to the LEFT of every starred row. That is
   the ragged first column: not a text-align problem, an icon-width problem.
   Pinning both to the same 16px box makes `icon + 6px + name` identical on every
   row, so the names left-align with no per-row compensation.

   !important because the marker's own size wins otherwise — Width="9" on an
   <asp:Image> renders as a presentational attribute or an inline style depending
   on the control's style bag, and !important clears both; it also has to match
   components.css's own !important on the star so the two never disagree.

   vertical-align: middle (was -1px): a 16px image sitting 1px BELOW the baseline
   pushes the line box past the cell's 20px line-height, which dropped the whole
   first column a couple of px relative to the plain-text columns beside it.
   Centred on the text midline, a 16px glyph fits inside a 20px line box and the
   line box stays exactly 20px — see the row-alignment note on the Edit cell. */
body.page-vessel-management .modMain table.StdTable tr.GridData > td:first-child img[id$='_imgOwner'],
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td:first-child img[id$='_imgOwner'],
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:first-child img[id$='_imgOwner'],
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:first-child img[id$='_imgOwner'] {
    width: 16px !important;
    height: 16px !important;
    margin-right: 6px;
    vertical-align: middle;
}

/* Edit pencil cell — centre it, and pin its box to the row's 20px line-height.

   ROW ALIGNMENT: the data cells are `vertical-align: top` with `line-height:
   20px`, so every column's first line lands on the same y ONLY while every
   cell's first line box is actually 20px tall. Anything inline that is taller
   inflates its own cell's line box and pushes that column down relative to its
   neighbours — which is what made the row read as not lining up.
   icon-swaps.css gives .Img-Std-EditV2 a 24×24 padded button box (4px padding
   around a 16px glyph). At 24px it overflowed the 20px line box, dropping the
   pencil ~2px below the text baseline of every other column AND stretching the
   whole row from 36px to 40px.
   Pinning the box to 20px with 2px padding keeps the SAME 16px glyph (the mask
   is sized `center / 16px 16px`, independent of the box) while bringing the line
   box back to 20px. Every column now tops out identically and the row tightens
   to 36px — the §5.4 single-line target the data-cell padding was written for.
   The trade is a 20px hit target instead of 24px; still comfortably clickable,
   and it buys exact alignment without per-column magic offsets.
   (0,0,5,5) beats icon-swaps' (0,0,3,2), so no !important. */
body.page-vessel-management .modMain table.StdTable tr.GridData > td:last-child input[type='image'],
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td:last-child input[type='image'],
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:last-child input[type='image'],
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:last-child input[type='image'] {
    display: inline-block;
    width: 20px;
    height: 20px;
    padding: 2px;
    box-sizing: border-box;
    vertical-align: middle;
}

/* "Companies with Access" cell renders raw HTML from the database
   (Eval("Access").Replace(",", "<br>")) which can include SVG markers like
   /images/icons/FaviconQ88White.svg. That file declares only
   `viewBox="0 0 100 100"` — an intrinsic ratio but no intrinsic px dimensions —
   so CSS's default sizing algorithm for replaced elements hands the <img> the
   container's available width and derives the height from the 1:1 ratio, and
   the marker dwarfs the row. Cap it to a small inline-icon size.

   Use max-* rather than height/width, and only on images that declare no size
   of their own. The old `height: 16px; width: auto` form also caught the
   `1x1.gif` indent spacers this cell uses for the "MissingCompanies" list,
   blowing a `width="9"` spacer up to 16x16 and shifting the indent (measured).
   A max-* constraint only ever shrinks something genuinely oversized.

   Note the 9x9 `star.png` "Registered vessel" marker in the same cell renders
   at 16x16 here regardless — that is components.css's deliberate global
   `body.sidebar-nav img[src$="/markers/star.png"] { width/height: 16px
   !important }`, not this rule. Don't try to "fix" it from here.

   Select on grid ROW class, not column index — the code-behind hides tdEdit
   (L746, L1271) and tdPublish (L761) per portal/permission, which moves the
   Access cell's position in the row and made `:nth-last-child(2)` unreliable.

   Ported to company-info-popup.css §12.1 — the Fleet List tab of
   CompanyInfoPopup.aspx mounts this same control under a different body class
   and gets none of this file. Keep the two in sync. */
body.page-vessel-management .modMain table.StdTable tr.GridData > td img:not([width]):not([height]),
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td img:not([width]):not([height]),
body.page-vessel-management .modMain table.StdTable tr.Disabled > td img:not([width]):not([height]),
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td img:not([width]):not([height]) {
    max-width: 16px;
    max-height: 16px;
    vertical-align: middle;
}

/* The "Companies with Access" cell carries the legacy `nowrap` HTML attribute
   (`<td ... nowrap="nowrap">`). Its content is a comma→<br> list of company
   names; a single long name can't wrap, so the column grew to ~610px and
   forced the whole page-shell (.ContentPane) into horizontal scroll at
   viewports narrower than the 1680 design width. Let long names wrap so the
   grid — and the card — stay within the viewport. */
body.page-vessel-management .modMain table.StdTable tr.GridData > td:nth-last-child(2),
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td:nth-last-child(2),
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:nth-last-child(2),
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:nth-last-child(2) {
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Links inside data rows — plain weight (§5.4 body text), not bold.
   MainWhiteout.css:111-115 paints EVERY anchor `font-weight: bold` at (0,1,1) and
   nothing in this skin overrode it, so the two anchors the grid actually contains
   rendered as the heaviest text in the row:
     • the IMO number — the <a href="/viewship.aspx?…"> that ItemDataBound builds
       into litQ88 (VesselManagement.ascx.cs, `litQ88.Text +=`)
     • any company link in "Companies with Access" — raw HTML out of Eval("Access")
   Bold made them shout over the vessel name, which is the row's actual subject.
   Same fix, same reasoning as archive.css's grid Questionnaire links.

   WEIGHT ONLY — deliberately no `color` and no `text-decoration` here:
     - colour already resolves to indigo via MainWhiteout:112 `var(--brand-primary)`;
       restating it as --q88-grid-primary would be a second source of truth for the
       same hue (they are both --raw-indigo-600 under the refresh, but --primary and
       --brand-primary DIVERGE in the base token block — cyan vs Q88 blue).
     - MainWhiteout already gives no-underline at rest (:114) and underline on hover
       (:117-119). Restating `text-decoration: none` here would out-specify that
       hover rule for :visited links and silently kill the hover underline.
   Both :link and :visited must be named — the legacy rule sets weight on each, so a
   bare `a` selector would lose to them. (0,0,5,4) clears it with no !important.

   Ported to company-info-popup.css §12.3 — the Fleet List tab mounts this same
   control and needs the same fix. Keep the two in sync. */
body.page-vessel-management .modMain table.StdTable tr.GridData > td a:link,
body.page-vessel-management .modMain table.StdTable tr.GridData > td a:visited,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td a:link,
body.page-vessel-management .modMain table.StdTable tr.GridDataAlt > td a:visited,
body.page-vessel-management .modMain table.StdTable tr.Disabled > td a:link,
body.page-vessel-management .modMain table.StdTable tr.Disabled > td a:visited,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td a:link,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td a:visited {
    font-weight: 400;
}

/* Questionnaire-freshness dot in the IMO column → the refreshed 12px circle.
   ItemDataBound (VesselManagement.ascx.cs, `litQ88.Text =`) emits a transparent
   spacer <img> carrying `statusIcon statusIcon<Green|Yellow|Red|White>`, colour
   encodes how recently the Q88/Baltic99 questionnaire was updated (≤30d green,
   ≤90d yellow, older red, never = white outline; the exact date is in the title).

   Those classes are shared, not page-local, and Q88Whiteout.css:316 styles the
   base as an 8×8 SQUARE — that is the old look this page was still getting. The
   refresh's treatment is the same classes and the same --status-dot-* tokens
   restyled to a 12×12 circle (Figma 331:4727 rounded-full); officer-matrix.css
   §1/§2 does exactly this for OfficerMatrixCompliance's grid cells and its
   compliance dialog. So this is a shape change only — no new colours, no markup
   change, and the tokens keep tracking whatever --status-dot-* resolve to.

   box-sizing: border-box rather than officer-matrix's approach of shrinking the
   White variant: .statusIconWhite adds `border: 1px solid` (!important, so it
   cannot be dropped), which under the default content-box would render that one
   state 14px against the others' 12px. border-box makes all four exactly 12px
   without needing a compensating size. Scoped per-element — never global, which
   would break the DX controls.

   No !important needed: the legacy base is a bare `.statusIcon` (0,0,1,0) and
   nothing else claims these images with !important, so (0,0,3,2) wins outright.
   Safe to scope at table level — this is the only .statusIcon on the page.

   Ported to company-info-popup.css §12.4. Keep the two in sync. */
body.page-vessel-management .modMain table.StdTable img.statusIcon {
    width: 12px;
    height: 12px;
    border-radius: 9999px;
    box-sizing: border-box;
    margin: 0 4px 0 0;
    vertical-align: middle;
}

/* Transfer-Ownership action in "Companies with Access" → Lucide refresh-cw.
   The icon is NOT emitted by this control: fn_TransferOwnership_JS (a SQL scalar
   function, reached via fn_GetDelimitedCompany → the Access column) appends
   `<a href='#' id='lnkInputTRF' onclick='…ShowModalInputPopup…'>
      <img src="/Images/clearpixel.gif" class="Img-Std Img-Std-Refresh">
    </a>`
   after each shared company. MainWhiteout.css:2313 paints that class from the
   StdIcons.png sprite at offset -64px -48px — the multi-colour raster arrow.
   Swap it for the flat glyph the same way icon-swaps.css handles Img-Std-EditV2:
   blank the sprite, mask the Lucide path, paint with currentColor.

   Masking is legitimate here (not the opaque-raster trap): the host <img> src is
   clearpixel.gif — fully transparent — so the visible pixels come only from the
   background we paint, and the mask just shapes it.

   16px inline glyph rather than icon-swaps' 24px padded button box: this icon
   sits INLINE among the company names in a data cell, not alone in an action
   column, so a 24px box would push the 20px line-height around on every shared
   row. Muted at rest (matching the Edit pencil rather than the indigo links it
   sits beside) and --q88-grid-primary on hover, which is the convention
   icon-swaps.css:236-248 sets for these swapped action icons.

   `color` is set on the IMG, not inherited: the parent <a> resolves to link
   indigo, and currentColor would otherwise paint the glyph indigo too.
   No !important — .Img-Std (0,0,1,0) loses to (0,0,3,2), and the legacy rule
   uses background-image longhand so there is no shorthand to fight.

   Ported to company-info-popup.css §12.5. Keep the two in sync. */
body.page-vessel-management .modMain table.StdTable img.Img-Std-Refresh {
    width: 16px;
    height: 16px;
    background-image: none;
    background-color: currentColor;
    color: var(--q88-grid-muted-fg);
    -webkit-mask: var(--icon-refresh-cw) no-repeat center / 16px 16px;
            mask: var(--icon-refresh-cw) no-repeat center / 16px 16px;
    vertical-align: middle;
    margin-left: 4px;
    cursor: pointer;
    transition: color 120ms ease;
}
body.page-vessel-management .modMain table.StdTable a:hover > img.Img-Std-Refresh {
    color: var(--q88-grid-primary);
}

/* --------------------------------------------------------------------------
   5.7 Deleted / non-active vessel rows  (tr.Disabled / tr.DisabledAlt)
   --------------------------------------------------------------------------
   ItemDataBound (VesselManagement.ascx.cs, the `StatusID != Active` branch) swaps
   the row class to Disabled/DisabledAlt — the rows the "Show deleted"
   filter reveals. Two things were wrong with how they read:

   (a) NO visible state at all. The legacy grey came from Q88Whiteout.css:57-60
       `background-color: var(--surface-disabled-alt) !important` — and
       `--surface-disabled-alt` is defined NOWHERE in tokens.css (nor anywhere
       else; MainWhiteout:4391/4483 reference the same dead name). An undefined
       custom property with no fallback makes the declaration invalid at
       computed-value time, so the whole thing drops and background-color falls
       back to its initial `transparent`. Net effect since tokenisation: a deleted
       vessel was painted exactly like an active one, while the footer legend
       still promised "* Gray - Deleted Vessel" — a colour that no longer
       rendered. That legend label (lblGrayBGLegend) has since been removed from
       the .ascx: the per-row badge below states the state directly, so the
       footnote had nothing left to describe.
       We do NOT resurrect the dead token here — that name is
       shared with other pages; this page states its own intent via
       --q88-grid-deleted-fg / -bg.

   (b) The only surviving difference was accidental: the legacy cell padding /
       font these rows inherited by missing §5's selectors (fixed above), which
       read as "indented, in a slightly different font" rather than as a state.

   The signal is now the muted foreground — matching company-info-popup.css §11.4,
   which solves this same Disabled/DisabledAlt gap for non-active licenses — plus
   a hairline band and a "Deleted" badge so the state does not rest on colour
   alone (WCAG 1.4.1). Colour on the CELL, not the row: `color` inherits, so the
   plain-text columns (Type / Fleet / Access) and the <asp:Label> spans inside
   them all pick it up. lblMissingCompanies keeps its own inline ForeColor="Gray".

   Ported to company-info-popup.css §12.2 for the Fleet List tab, ADAPTED: no
   band there, because that popup already spends #fafbfc on its GridDataAlt
   zebra. Keep the two in sync.
   -------------------------------------------------------------------------- */
body.page-vessel-management .modMain table.StdTable tr.Disabled,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt {
    background: var(--q88-grid-deleted-bg) !important;
    transition: background-color 120ms ease;
}

/* Later in the file than the shared `> td` rule above and the same specificity,
   so this colour wins without needing !important.

   The band above is painted on the ROW; the cells must stay see-through for it to
   show. `!important` here specifically because the legacy per-CELL fills are
   `!important` too and target `.StdTable .Disabled td` (0,0,3,0): today they are
   inert (Q88Whiteout's dead --surface-disabled-alt; MilbrosWhiteout has no rule at
   all; Baltic99's hard #909090 only ships on 404/Error). But if that Q88Whiteout
   line is ever "repaired" to a real colour, a cell-level !important fill would
   paint over this band and put slate text on mid-grey — the unreadable state this
   section exists to fix. 0,0,5,3 !important keeps that from regressing silently. */
body.page-vessel-management .modMain table.StdTable tr.Disabled > td,
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td {
    color: var(--q88-grid-deleted-fg);
    background-color: transparent !important;
}

/* The "registered vessel" star is a strong full-saturation marker; on a muted row
   it out-shouts the vessel name. Dim it in step with the text. NOT applied to the
   Edit pencil in the last cell — that is the only way to act on the row (open /
   restore), so it stays at full contrast. */
body.page-vessel-management .modMain table.StdTable tr.Disabled > td:first-child img[id$='_imgOwner'],
body.page-vessel-management .modMain table.StdTable tr.DisabledAlt > td:first-child img[id$='_imgOwner'] {
    opacity: 0.55;
}

/* "Deleted" badge after the vessel name. Driven by the `is-deleted` class that
   ItemDataBound appends for StatusID == Deleted specifically — NOT by .Disabled,
   which also covers InActive (2) and Pending (4) and would mislabel those. Same
   subtle-badge shape as company-info-popup.css §11.3. The first cell carries the
   legacy `nowrap` attribute, so the badge always stays on the name's line. */
body.page-vessel-management .modMain table.StdTable tr.is-deleted > td:first-child::after {
    content: "Deleted";
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 9999px;
    background-color: var(--surface-muted, #f1f5f9);
    color: var(--q88-grid-deleted-fg);
    font-family: var(--q88-grid-font);
    font-size: 11px;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: 0.02em;
    /* middle, not a px nudge: the badge is an 18px inline-block (16px line +
       2px padding), so a baseline-relative offset would push the first cell's
       line box past 20px and drop deleted rows out of line with active ones.
       Centred on the text midline it fits inside the 20px box. */
    vertical-align: middle;
}

/* ==========================================================================
   6. Footer legend (.modFooter2) — "Registered Vessel" key + Top link.
   ========================================================================== */

body.page-vessel-management .modFooter2 {
    background: transparent;
    border-top: 1px solid var(--q88-grid-border);
    margin-top: 8px;
    padding: 12px 4px 0;
    color: var(--q88-grid-muted-fg);
    font-family: var(--q88-grid-font);
    font-size: 13px;
}

body.page-vessel-management .modFooter2 a.LinkButton {
    /* Footer "Top" link — same ghost-outline treatment as the filter buttons. */
    display: inline-flex !important;
    align-items: center;
    gap: 4px;
    height: 28px;
    padding: 0 12px !important;
    border-radius: 8px;
    background: var(--q88-grid-card) !important;
    color: var(--q88-grid-muted-fg) !important;
    border: 1px solid var(--q88-grid-border) !important;
    font-family: var(--q88-grid-font);
    font-size: 13px;
    font-weight: 500 !important;
    text-decoration: none !important;
    background-image: none !important;
}

body.page-vessel-management .modFooter2 a.LinkButton:hover {
    background: var(--q88-grid-row-hover) !important;
    color: var(--q88-grid-primary) !important;
    border-color: var(--q88-grid-primary) !important;
}

/* ==========================================================================
   7. Edit-Vessel / Publish / Grant-Access dialog FORM BODIES + footer mapping
   --------------------------------------------------------------------------
   VesselManagement.ascx carries FOUR legacy <uc:ModuleTemplate> blocks that
   are NOT the main list module:

     modEditVessel   (pnlEditVessel)  — Edit Vessel form  (no Footer2 of its own)
     modPublish      (pnlEditVessel)  — Publish checkboxes + the SHARED Footer2
                                        for the whole edit flow
                                        (Import HVPQ / Cancel / Delete / Save)
     modGrantAccess  (pnlEditVessel)  — "Companies with access" Repeater list
     modGrantAccessB (pnlGrantAccess) — Grant-Access-to-Company form + Footer2
                                        (Cancel / Delete / Save)

   These are NOT MPE-wrapped popups — pnlEditVessel / pnlGrantAccess render
   INLINE as full-page edit forms (server-side Visible toggle from the list).
   Because they reuse the V1 .modTitle / .modMain / .modFooter2 / .modInner-
   Container class names, sections 1–6 above (written for the list module's
   .modContainerLarge) already strip the legacy navy ribbon + inner border off
   them. BUT §1's white CARD surface (bg / border / radius / shadow) is scoped
   to `.modContainerLarge` only — these four panels use the ModuleTemplate
   DEFAULT wrapper class `modContainerStd` (table#divMod), which §1 never
   targets, so without §7.0 below they render as naked, transparent, borderless
   content floating on the page bg. §7.0 repaints the card.

   What sections 1–6 do NOT cover is the FORM BODY (DESIGN.md §16.8): the text
   inputs / textareas still carry the legacy `2px inset #767676`, `radius:0`,
   `12px`/`21px-tall` chrome; the `.Label` cells render `#0a0a0a`/`12px`/bold;
   and the four Footer2 buttons all collapse to identical ghost pills (Save and
   Delete need teal / red differentiation). The Publish "?" help affordance
   (lbHelp) renders 0×0 EMPTY (ImageManager emits no glyph on Q88 + the link
   has no LabelText) — paint a Lucide circle-help so it is visible + clickable
   (its onclick="ShowHint('hint1')" is already wired; no markup change).

   SCOPE = the four ModuleTemplate panels by id-suffix (naming-container prefix
   `ctl00_cphMiddle_ctl00_…`). ID-scope rather than the body-class `.mod*`
   scope is mandatory here: the body-class .modTitle/.modMain/.modFooter2 rules
   above are shared with the list module, so re-using them would double-apply
   to the list and risk clobbering it. The list grid is NOT ModuleTemplateV2
   (no .modV2*), so the §16.12 `.modContainerStd`-scoped recipe is also unsafe
   (it would match the list-module template too). Mirrors components.css §9.11.

   Literal hex (never var()) on every border / background / button colour: the
   ModuleTemplate is buried under MainWhiteout `!important` shorthands and a
   var() inside a shorthand+!important either drops the next declaration or
   loses the cascade (DESIGN.md §32.2 / §32.3). Longhand border-side plus
   background-color declarations only — no `border:` / `background:` shorthand
   adjacent to other declarations. Palette mirrors the §9.10 resolved tokens:
   slate-200 #e2e8f0,
   text #0f172a, labels slate-600 #475569, teal #0d9488 / #0f766e, red #dc2626
   / #b91c1c, white #ffffff.
   ========================================================================== */

/* Convenience: every rule below is scoped to one of the four panels. The
   `_modEditVessel_`, `_modPublish_`, `_modGrantAccess_`, `_modGrantAccessB_`
   id-suffix selectors are repeated per-rule so the grouping reads clearly. */

/* §7.0 — Card surface. The list module (modVesselManagement) carries
   CSSClass="modContainerLarge" and is painted into a card by §1; these four
   edit panels use the ModuleTemplate DEFAULT wrapper `modContainerStd`
   (table#divMod), which §1 never targets — so they had their navy chrome
   stripped (§1–6) but no card to replace it, rendering as naked transparent
   content. Repaint the four `_divMod` tables with the same white card chrome /
   12px radius / soft shadow as §1. UNLIKE §1's full-width list card, these are
   constrained to ~820px (the old edit-modal footprint) and CENTERED — a
   stretched full-width card wastes the space for a compact label/value form,
   and the page reads as a focused edit panel (the fleet-checkbox row wraps at
   820 just as it did in the legacy modal). max-width:calc(100% - 24px) keeps it
   from overflowing narrow viewports. Scoped by the four id-suffixes (NOT bare
   `.modContainerStd`) so no other default-wrapper template on the page is
   touched. Longhand border-side + background-color (MainWhiteout
   !important-shorthand hazard, DESIGN.md §32.2 / §32.3). */
body.page-vessel-management [id$='_modEditVessel_divMod'],
body.page-vessel-management [id$='_modPublish_divMod'],
body.page-vessel-management [id$='_modGrantAccess_divMod'],
body.page-vessel-management [id$='_modGrantAccessB_divMod'] {
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: #e5e5e5;
    border-radius: 12px;
    box-shadow:
        0 1px 3px 0 rgba(0, 0, 0, 0.06),
        0 1px 2px -1px rgba(0, 0, 0, 0.05);
    box-sizing: border-box;
    width: 820px;
    max-width: calc(100% - 24px);
    margin: 16px auto;
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

/* §7.0b — "Grant Access" title-bar action (modGrantAccess card, btnAddAccess).
   §2's `body.page-vessel-management .modTRight { font-size: 0 }` (the whitespace-
   collapse trick for the list module's title pills) is page-global, so it leaks
   onto this sub-card's .modTRight and zeroes the plain <a>Grant Access</a> text
   → the button renders 0×0 invisible (the list pills survive because each re-
   sets its own 14px in §3; this plain link never did). Restore it as a ghost
   outline pill — same language as the list's Request-Access / Manage-Fleet pills
   — so it reads as the card's add action. font-size:14 !important defeats the
   inherited 0. (ImageManager emits no glyph on Q88, so the <a> is text-only —
   no icon gap / <ins> to manage.) */
body.page-vessel-management [id$='_modGrantAccess_divMod'] .modTRight a[id$='_btnAddAccess'] {
    display: inline-flex !important;
    align-items: center;
    height: 32px;
    padding: 0 14px !important;
    border-radius: 9999px;
    background-color: #ffffff !important;
    color: var(--text-link) !important;
    border-width: 1px !important;
    border-style: solid !important;
    border-color: #e5e5e5 !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 20px;
    text-decoration: none !important;
    box-shadow: none !important;
    cursor: pointer;
}
body.page-vessel-management [id$='_modGrantAccess_divMod'] .modTRight a[id$='_btnAddAccess']:hover {
    background-color: rgba(var(--primary-tint), 0.06) !important;
    border-color: var(--primary) !important;
}

/* §7.1 — Form labels (`td.Label`) → slate-600 Inter-14, medium weight. The
   legacy `.Label` is #0a0a0a / 12px / bold / right-aligned; keep the right
   alignment (the form is a 4-col label/value grid) but lift the typography to
   the refresh form-label spec. */
body.page-vessel-management [id$='_modEditVessel_divMod'] td.Label,
body.page-vessel-management [id$='_modPublish_divMod'] td.Label,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] td.Label {
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 20px !important;
    color: #475569 !important;
    vertical-align: middle;
}

/* §7.2 — Text inputs + textareas → §16.8 refresh field: white surface, 1px
   slate-200, 8px radius, 12px h-padding, 36px height (textareas auto-height
   block). Targets the named fields only (id-suffix) so the rule never reaches
   the list module. Longhand border-side + background-color declarations to
   dodge the shorthand var()/!important trap. */
body.page-vessel-management [id$='_modEditVessel_divMod'] input[type='text'],
body.page-vessel-management [id$='_modGrantAccessB_divMod'] input[type='text'] {
    height: 36px;
    box-sizing: border-box;
    padding: 0 12px;
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: #e2e8f0;
    border-radius: 8px;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: #0f172a;
    box-shadow: none;
    outline: none;
}

body.page-vessel-management [id$='_modEditVessel_divMod'] textarea,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] textarea {
    display: block;          /* release the legacy cols="20" shrink-wrap */
    box-sizing: border-box;
    min-height: 56px;
    padding: 8px 12px;
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: #e2e8f0;
    border-radius: 8px;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: #0f172a;
    box-shadow: none;
    outline: none;
    resize: vertical;
}

body.page-vessel-management [id$='_modEditVessel_divMod'] input[type='text']:focus,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] input[type='text']:focus,
body.page-vessel-management [id$='_modEditVessel_divMod'] textarea:focus,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] textarea:focus {
    border-color: var(--primary);
    outline: 2px solid var(--primary);
    outline-offset: -1px;
}

/* §7.2b — Uniform field width + vertical centering for the Edit-Vessel form.
   Two markup quirks broke column alignment (both measured, not assumed):
   (a) `txtVessel` (Vessel name) carries an inline `style="width:200px"`; every
       other text input has no width attr and lands at 225px, so Vessel name
       rendered 25px short of its column. `width:225px !important` is the ONLY
       thing that beats the inline style — without it ALL my prior input rules
       left the 200px untouched (this is the "vessel-name fix did nothing" bug).
       Now every Edit text input shares the 225px DropDownListGrouped/<select>
       width, so left + right columns line up. Scoped to modEditVessel only
       (NOT the shared §7.2 selector) so modGrantAccessB inputs keep their size;
       the Admin Comments <textarea> is excluded (input[type='text'] only).
   (b) the input ROWS rendered 57px tall with inputs off a common center — two
       separate inflators measured in the same shared <tr>:
         - right-column inputs (VIN / ENI / Official Number) each carry a TRAILING
           `<br>` (the left column has none) → a phantom ~20px line in that cell.
           `input[type='text'] + br { display:none }` (ADJACENT-sibling — only a
           <br> immediately after a text input is hit, so structural <br>s
           elsewhere on the form are untouched) drops it.
         - the IMO cell holds an INLINE CustomValidator span ("Invalid IMO number",
           visibility:hidden but IN FLOW) whose line box rode the IMO input 8px
           high. `[id$='_cvIMO'] { position:absolute }` takes it out of flow (auto
           offsets keep its static spot at the input's right edge, so the error
           text still appears in place on failure — it just no longer reserves a
           line). Same out-of-flow trick as §7.4b's `.ValTipRequired`.
       With both gone every row collapses 57px→42px and both inputs center
       (verified: all rows left 1599/1981, width 225, paired cy equal). */
body.page-vessel-management [id$='_modEditVessel_divMod'] input[type='text'] {
    width: 225px !important;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] input[type='text'] + br {
    display: none;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] [id$='_cvIMO'] {
    position: absolute;
}

/* §7.3 — Native <select> (HVPQ Variant). One uniform 225px width + 36px height
   so it sits in the same grouped trio as the two DropDownListGrouped triggers
   (§7.4) and aligns with the text inputs in the same rows. !important beats the
   global select-shim's 32px height. modGrantAccessB selects keep the 36px field
   height only (no width override — its pickers are ComponentArt comboboxes,
   sized in §7.5; forcing 225px there would squash them). */
body.page-vessel-management [id$='_modEditVessel_divMod'] select:not(.Hidden) {
    width: 225px !important;
    height: 36px !important;
    box-sizing: border-box;
}
body.page-vessel-management [id$='_modGrantAccessB_divMod'] select:not(.Hidden) {
    height: 36px;
    box-sizing: border-box;
}

/* §7.4 — Grouped ship-type / classification dropdowns (DropDownListGrouped →
   hidden <select class="Hidden"> + a <dl class="dropDownCusGrp"> widget whose
   visible trigger is the `_sel` anchor). The widget's JS writes an INLINE width
   onto the <dl> + <dt> (derived from each control's Width prop: 154px / 74px),
   which beats both the global components.css §12.5.2 170px default AND any
   non-!important width here — that's why the two grouped dropdowns rendered
   ragged (149px / 69px). Force a uniform 225px on the <dl> + <dt> + trigger
   anchor so Vessel Type / Vessel Size match each other, the plain HVPQ <select>
   (§7.3) and the text inputs. The options panel (<dd>) is content-sized + NOT
   targeted here, so widening the trigger leaves it untouched.
   Two trigger details handled below: (a) keep the global 32px RIGHT padding so
   the long ship-type label truncates (ellipsis) BEFORE the chevron instead of
   overrunning it — `!important` also beats the widget's inline `padding-top:2px`;
   (b) §7.4b takes the `.ValTipRequired` validator tip out of flow. That tip
   reserves a ~16px stacked line (its inner icon span is a fixed-height
   inline-block) which inflated the row to 56px AND — inconsistently between the
   two cells — left Vessel Size 9px above its label. `position:absolute` (auto
   offsets → it keeps its static spot and still shows the error icon, but stops
   reserving a line) collapses the row to the field height so BOTH dropdowns
   center on their labels. Do NOT add `position:relative` to the cell: the Vessel
   Type value cell carries a dormant inline `style="top:100px"` that a positioned
   cell would activate, dropping it 100px. */
body.page-vessel-management [id$='_modEditVessel_divMod'] dl.dropDownCusGrp {
    width: 225px !important;
    box-sizing: border-box;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] dl.dropDownCusGrp > dt {
    width: 225px !important;
    height: 36px !important;
    box-sizing: border-box;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] a[id$='_sel'] {
    height: 36px;
    width: 225px !important;
    min-width: 0 !important;     /* clear the widget's inline min-width:149px */
    box-sizing: border-box;
    /* display:block (NOT the global inline-flex) is REQUIRED for the ellipsis to
       work: on an inline-flex trigger the label is a flex item that overflows
       its box and spills over the chevron (overflow:hidden clips at the padding
       box, not the content box, and text-overflow:ellipsis is a no-op on a flex
       container). As a block, the long ship-type label truncates with an
       ellipsis at the content edge, leaving the 32px chevron gutter clear. */
    display: block;
    line-height: 34px;           /* vertical-center the single line in the 34px content box (36 − 2px border) */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 32px 0 12px !important;   /* 32px right = chevron gutter; !important beats the widget's inline padding-top:2px */
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: var(--border-default);
    border-radius: 8px;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    color: var(--text-primary);
}

/* §7.4b — Validator tip out of flow so the dropdown row collapses to the field
   height and both dropdowns center on their labels (see §7.4 comment, detail b).
   Scoped to the two grouped-dropdown value cells — td.NoPaddingTableCells exists
   ONLY on this row, so text-input validators elsewhere are untouched. No cell
   position:relative (the top:100px trap). */
body.page-vessel-management [id$='_modEditVessel_divMod'] td.NoPaddingTableCells .ValTipRequired {
    position: absolute;
}

/* §7.5 — ComponentArt combobox (Q88:DropDownList → ddlGrantAccessTo /
   ddlAccountAdmin in modGrantAccessB). The widget swaps its wrapper class to
   `.comboBoxHover`/`.comboBoxFocused` on interaction, so target the partial
   class (`table[class*="comboBox"]`) — never bare `.comboBox` (combo-hover
   trap). Lift the input cell to the 36px refresh field look. */
body.page-vessel-management [id$='_modGrantAccessB_divMod'] table[class*='comboBox'] {
    border-collapse: separate;
}
body.page-vessel-management [id$='_modGrantAccessB_divMod'] table[class*='comboBox'] input[type='text'] {
    height: 34px;
    border-width: 0;
    background-color: transparent;
}

/* §7.6 — Transfer-Ownership / Access-level radios (RadioButtonList
   RepeatLayout="Flow" → all <input> + <label> are siblings under ONE wrapper
   span, so the checked-state selector MUST be `input:checked + label`, never
   `:has(input:checked) label`). Native accent-color is already teal globally;
   just give the labels readable Inter-14 + spacing. */
body.page-vessel-management [id$='_modGrantAccessB_divMod'] td label {
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 400 !important;
    color: var(--text-primary) !important;
    margin-right: 12px;
    vertical-align: middle;
}
body.page-vessel-management [id$='_modGrantAccessB_divMod'] td input[type='radio'],
body.page-vessel-management [id$='_modGrantAccessB_divMod'] td input[type='checkbox'] {
    vertical-align: middle;
    margin-right: 4px;
}
body.page-vessel-management [id$='_modGrantAccessB_divMod'] td input[type='radio']:checked + label {
    color: var(--text-primary) !important;
    font-weight: 500 !important;
}

/* §7.7 — Publish "?" help affordance. lbHelp renders 0×0 EMPTY on Q88
   (ImageManager emits no glyph + the link has no LabelText). Paint a Lucide
   circle-help glyph via a currentColor mask `::before`; the anchor's
   onclick="ShowHint('hint1')" is already wired, so no markup change. Reuse the
   --icon-circle-help token (slate-500) — mask, NEVER background-image. */
body.page-vessel-management [id$='_modPublish_divMod'] .modTRight a[id$='_lbHelp'] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    color: #64748b;
    border-radius: 4px;
    text-decoration: none;
    cursor: pointer;
    vertical-align: middle;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modTRight a[id$='_lbHelp']:hover {
    color: #0f172a;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modTRight a[id$='_lbHelp']::before {
    content: "";
    display: block;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask: var(--icon-circle-help) no-repeat center / 16px 16px;
            mask: var(--icon-circle-help) no-repeat center / 16px 16px;
}

/* §7.7b — #hint1 help popover: glyph, placement, justified prose.
   The legend table inside is re-built one-row-per-item in the .ascx and the box
   sizes via the global `height:auto` once the inline height:250px is dropped.

   (1) GLYPH — the global components.css ".hint" skin leads with an amber
   AlertTriangle ::before (tuned for Q88Search VALIDATION errors). This is a
   how-to note, not an error, so swap to the slate circle-help glyph that matches
   the §7.7 "?" trigger (same precedent as customfilter.css §14 / #hint2).

   (2) PLACEMENT — the inline style (left:-510px; top:10px) opens the box DOWNWARD
   from the trigger. The Publish card is the LAST card on the page, so the box
   spilled below the fold and read as "cut off". Flip to bottom-anchored so it
   grows UP into the page and stays fully visible (top:auto + bottom beats the
   inline top); max-height + overflow-y is a safety net. The inline left:-510px
   horizontal placement is kept — it already centres the 500px box under the card.

   (3) JUSTIFY — justify the intro prose (the !important beats the inline
   text-align:left), but pin the legend cells back to left: justify on the short
   2-line descriptions would stretch their first line with ugly word gaps. */
body.page-vessel-management #hint1 {
    top: auto !important;
    bottom: 8px !important;
    max-height: 80vh !important;
    overflow-y: auto !important;
    text-align: justify !important;
}
body.page-vessel-management #hint1 td {
    text-align: left;
}
body.page-vessel-management #hint1::before {
    background-color: #64748b !important;
    -webkit-mask: var(--icon-circle-help) center / 16px 16px no-repeat !important;
            mask: var(--icon-circle-help) center / 16px 16px no-repeat !important;
}

/* §7.8 — Footer2 buttons → §9.10 dialog pills, mapped by CLASS / ROLE (NOT
   last-button-wins). The shared edit-flow footer lives in modPublish
   (lnkImportHVPQ / lnkCancel / lnkEditVesselDelete / lnkEditVesselSave); the
   grant-access footer lives in modGrantAccessB (btnCancelAccess /
   btnDeleteAccess / btnSaveAccess).

   Base = teal primary; .Secondary = ghost; the destructive Delete links get
   the red override below. !important beats MainWhiteout `.LinkButton`. */
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    height: 36px;
    min-width: 64px;
    padding: 0 16px !important;
    border-radius: 8px !important;
    background-color: var(--primary) !important;
    background-image: none !important;
    color: #ffffff !important;
    border-width: 1px !important;
    border-style: solid !important;
    border-color: var(--primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    text-decoration: none !important;
    box-shadow: none !important;
    cursor: pointer;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton:hover,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton:hover {
    background-color: var(--button-primary-hover) !important;
    border-color: var(--button-primary-hover) !important;
    color: #ffffff !important;
}

/* Ghost: .Secondary (Cancel) + the Import-HVPQ link (a non-primary action that
   carries plain .LinkButton — id-target it so it doesn't read as a 2nd teal
   primary next to Save). */
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton.Secondary,
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton[id$='_lnkImportHVPQ'],
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton.Secondary {
    background-color: #ffffff !important;
    color: var(--text-primary) !important;
    border-color: var(--border-default) !important;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton.Secondary:hover,
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton[id$='_lnkImportHVPQ']:hover,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton.Secondary:hover {
    background-color: var(--surface-muted) !important;
    border-color: var(--border-default) !important;
    color: var(--text-primary) !important;
}

/* Destructive Delete → red pill (DESIGN.md §16.7) so it reads distinct from
   the teal primary Save. */
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton[id$='_lnkEditVesselDelete'],
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton[id$='_btnDeleteAccess'] {
    background-color: var(--red-600) !important;
    border-color: var(--red-600) !important;
    color: #ffffff !important;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton[id$='_lnkEditVesselDelete']:hover,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton[id$='_btnDeleteAccess']:hover {
    background-color: #b91c1c !important;
    border-color: #b91c1c !important;
    color: #ffffff !important;
}

/* Kill the LinkButton `<ins>&nbsp;</ins>` spacer — invisible in legacy block
   layout, but a flex item under inline-flex that shifts the label off-centre. */
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 a.LinkButton > ins,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 a.LinkButton > ins {
    display: none !important;
}

/* §7.9 — Footer2 layout for these two form footers: strip any residual band,
   right-align the pill cluster with a 12px gap. modPublish's footer has a
   left-floated Import-HVPQ wrapper <div> — neutralise the float so the buttons
   sit in one flex row (Import on the left, Cancel/Delete/Save on the right). */
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2,
body.page-vessel-management [id$='_modGrantAccessB_divMod'] .modFooter2 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    background: transparent;
    border-top: 1px solid #e5e5e5;
    margin-top: 8px;
    padding: 12px 4px 0;
}
body.page-vessel-management [id$='_modPublish_divMod'] .modFooter2 > div {
    float: none !important;
    margin-right: auto;          /* push Import HVPQ to the far left */
    width: auto !important;
}

/* §7.10 — Checkbox captions. asp:CheckBox / CheckBoxList emit <input><label>;
   the labels (cblFleet fleet names in modEditVessel + the publish toggles in
   modPublish) already inherit Inter but render at the legacy 12px / #0a0a0a —
   lift to the refresh 14px / slate-900 so they match the form body and the
   modGrantAccessB checkbox/radio labels (§7.6). A bare `label` scope is safe:
   the only <label> elements inside these two panels are checkbox captions (the
   form's field labels are <td class="Label">, not <label>). */
body.page-vessel-management [id$='_modEditVessel_divMod'] label,
body.page-vessel-management [id$='_modPublish_divMod'] label {
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 400 !important;
    color: var(--text-primary) !important;
    vertical-align: middle;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] input[type='checkbox'],
body.page-vessel-management [id$='_modPublish_divMod'] input[type='checkbox'] {
    vertical-align: middle;
    margin-right: 4px;
}

/* §7.11 — Fleet checkboxes + Admin Comments span BOTH value columns. Their value
   cells already carry colspan=3 (full form width, right edge level with the card
   content edge), but the CONTENT is hard-capped at 500px in the markup: the Fleet
   CheckBoxList renders as <span id$='_cblFleet' style="display:inline-block;
   width:500px"> and the Admin Comments <textarea> ships inline width:500px. Both
   stopped ~107px short of the right column, so the checkboxes wrapped early (3
   lines) and the comments box didn't reach the right edge. width:100% !important
   beats the inline 500px so both span across both columns. Two different right
   edges on purpose:
   - Fleet CheckBoxList (`_cblFleet`): width:100% fills the colspan cell (right
     ~2227). It's a TRANSPARENT inline-block container — the checkboxes wrap at
     ≤2204 (level with the right column), so the full-cell width is invisible and
     gives the checkboxes the most room. Inline display:inline-block left alone
     (fills the cell at width:100% identically to block).
   - Admin Comments <textarea>: a VISIBLE bordered box, so its right edge must
     line up with the right-column fields (VIN / ENI / Official Number end at the
     same x). Filling the cell (width:100% → 2227) overhangs those fields by 21px
     — the colspan cell extends that far past the 225px right-column field. So
     pull it back with `calc(100% - 21px)` → right edge meets the right column
     (verified: 1599→2206, exactly level with the fields above). The 21px is the
     cell's overhang past the field edge, stable for the fixed-width (820px) card.
   Same inline-width trap as §7.2b's txtVessel. */
body.page-vessel-management [id$='_modEditVessel_divMod'] [id$='_cblFleet'] {
    width: 100% !important;
}
body.page-vessel-management [id$='_modEditVessel_divMod'] textarea {
    width: calc(100% - 21px) !important;
}

/* §7.11b — center the "Admin Comments:" label on the textarea. The value cell
   holds a hidden "Required" CustomValidator (`_cvAdminNotes`, visibility:hidden
   but IN FLOW) on its own line below the textarea, inflating the cell to 76px;
   the valign:middle label then centered on the 76px cell (cy 432) — 7px BELOW the
   textarea's center (425). Take the validator out of flow (position:absolute, auto
   offsets keep its static spot below the textarea so "Required" still shows there
   on failure) → the cell collapses to the textarea height and the label centers on
   the textarea (verified: label cy == textarea cy). Same out-of-flow trick as
   §7.2b's cvIMO / §7.4b's ValTipRequired. */
body.page-vessel-management [id$='_modEditVessel_divMod'] [id$='_cvAdminNotes'] {
    position: absolute;
}

/* ==========================================================================
   8. MPE popups — Vessel Transfer + Delete Vessel Request
   --------------------------------------------------------------------------
   Two ajaxToolkit:ModalPopupExtender popups whose PopupControlID is a hidden
   <asp:Panel class="ModuleContainer"> built from a RAW HTML <table> — NOT a
   <uc:ModuleTemplate> and NOT a <uc:Modal>. So neither the global
   components.css §9.10 .modPopPnl chrome NOR the §16.12 .modContainerStd recipe
   reaches them: they ship hardcoded legacy blue (#E5F1FD body, #C9E2FC footer,
   #DBDBDB dividers) with white-on-blue (illegible) titles.

     pnlModInput      (mpeModInput)      — "Vessel Transfer"       (≈450px)
     pnlDeleteRequest (mpeDeleteRequest) — "Delete Vessel Request" (≈550px)

   They literally carry `<td class="modTitle">` (+ Delete-Request a
   `<td class="modFooter2">`), so sections 2 + 6 above (the LIST module's
   bare-class rules) already LEAK onto them: the title inherits flex + white
   text, and the Delete-Request footer buttons collapse to ghost "Top-link"
   pills (Submit reads as non-primary). This block repaints both popups into the
   §9.10 dialog language AND corrects those leaks.

   SCOPE = the two panels by id-suffix. Literal hex (never var()) on border / bg
   / button colours — same MainWhiteout !important-shorthand hazard as §7
   (DESIGN.md §32.2 / §32.3). Close X: <uc:ImageManager ImageIcon="Close"> emits
   NO glyph on Q88 (PortalId 0/1/2) so the title <a> is 0×0 — paint a Lucide x
   via ::before; the anchor's onclick (HideModalInputPopup /
   ShowModal('mpeDeleteRequest',false)) is already wired in markup, no change.
   ========================================================================== */

/* §8.1 — Outer card. The .ModuleContainer <div> is the card surface: release
   the fixed inline height so the refreshed padding drives it, paint white
   chrome + 12px radius + shadow, clip the corners. */
body.page-vessel-management [id$='_pnlModInput'],
body.page-vessel-management [id$='_pnlDeleteRequest'] {
    height: auto !important;
    min-height: 0 !important;
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: #e2e8f0;
    border-radius: 12px;
    box-shadow:
        0 4px 6px -1px rgba(0, 0, 0, 0.10),
        0 2px 4px -2px rgba(0, 0, 0, 0.10);
    overflow: hidden;
    box-sizing: border-box;
    font-family: var(--q88-grid-font);
}

/* Inner <table> carries the legacy #E5F1FD fill + a forced 100% height — drop
   both; the cells own all the padding now. */
body.page-vessel-management [id$='_pnlModInput'] > table,
body.page-vessel-management [id$='_pnlDeleteRequest'] > table {
    height: auto !important;
    width: 100%;
    background-color: transparent !important;
    border: 0;
    border-collapse: collapse;
}

/* §8.2 — Title bar (td.modTitle). Section 2 leaks flex + white text; repaint to
   a 16/16/12 dark-on-white header row. box-sizing:border-box so the 16px side
   padding stays inside the clipped card. */
body.page-vessel-management [id$='_pnlModInput'] td.modTitle,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    /* gap:0 + margin-left:auto on the close wrapper (§8.3) left-aligns the title
       on BOTH popups: Transfer is a bare text node (2 flex items) while
       Delete-Request wraps its title in a float:left <div> (3 items) — plain
       space-between would shove Delete's title to the centre. */
    gap: 0;
    width: 100%;
    min-height: 0;
    margin: 0;
    padding: 16px 16px 12px;
    background-color: transparent !important;
    color: var(--text-primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 16px;
    font-weight: 600;
    line-height: 24px;
}

/* §8.3 — Close X. The title <a> renders empty (ImageManager emits no glyph on
   Q88). Neutralise the legacy fixed-height float wrapper <div>, size the anchor,
   and paint a Lucide x mask — onclick is already wired in markup. */
body.page-vessel-management [id$='_pnlModInput'] td.modTitle > div,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle > div {
    float: none !important;
    height: auto !important;
    padding: 0 !important;
    display: flex;
    align-items: center;
}
/* The close-X wrapper is always the last child div — push it to the far right
   so the title stays left-aligned regardless of the 2-item vs 3-item markup. */
body.page-vessel-management [id$='_pnlModInput'] td.modTitle > div:last-child,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle > div:last-child {
    margin-left: auto;
}
body.page-vessel-management [id$='_pnlModInput'] td.modTitle a,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    color: #64748b;
    text-decoration: none;
    cursor: pointer;
}
body.page-vessel-management [id$='_pnlModInput'] td.modTitle a:hover,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle a:hover {
    color: var(--text-primary);
    background-color: var(--surface-muted);
}
body.page-vessel-management [id$='_pnlModInput'] td.modTitle a::before,
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modTitle a::before {
    content: "";
    display: block;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask: var(--icon-x) no-repeat center / 16px 16px;
            mask: var(--icon-x) no-repeat center / 16px 16px;
}

/* §8.4 — Body cells (everything that is NOT the title or footer cell). Even out
   padding, lift typography to Inter-14 slate-600, drop the legacy #DBDBDB
   dividers. The Vessel-Transfer footer cell carries no .modFooter2 class — it
   is the align="right" cell, excluded here and handled in §8.5. */
body.page-vessel-management [id$='_pnlModInput'] > table td:not(.modTitle):not([align="right"]),
body.page-vessel-management [id$='_pnlDeleteRequest'] > table td:not(.modTitle):not(.modFooter2) {
    box-sizing: border-box;
    padding: 4px 16px 12px;
    background-color: transparent !important;
    border-bottom: 0 !important;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    color: var(--text-muted);
}
/* The transfer prompt message reads as the dialog's primary body copy. */
body.page-vessel-management [id$='_pnlModInput'] #divPromptMsg,
body.page-vessel-management [id$='_pnlModInput'] #divPromptMsg strong {
    color: #0f172a;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
}
/* Vessel-Transfer inline "Admin Comments:" label → its own slate-600 line. */
body.page-vessel-management [id$='_pnlModInput'] td strong {
    display: block;
    color: #475569;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    font-weight: 500;
}
/* Soften the Delete-Request pure-Red instruction to the refresh destructive red
   (the inline style="color:Red" is otherwise harsh #f00 on the new white card). */
body.page-vessel-management [id$='_pnlDeleteRequest'] span[style*="color:Red"] {
    color: #dc2626 !important;
    font-weight: 500;
}

/* §8.5 — Footer cell layout: strip the legacy blue band, flex-end pill cluster.
   Vessel-Transfer footer = the align="right" cell (no class); Delete-Request
   footer = td.modFooter2 (overrides the §6 list-footer leak). */
body.page-vessel-management [id$='_pnlModInput'] > table td[align="right"],
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modFooter2 {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin: 0;
    padding: 12px 16px 16px;
    background-color: transparent !important;
    border-top-width: 1px;
    border-top-style: solid;
    border-top-color: #e5e5e5;
}
/* Delete-Request wraps its buttons in a float:right <div> — flatten to a flex
   cluster so the 12px gap applies between Cancel and Submit. */
body.page-vessel-management [id$='_pnlDeleteRequest'] td.modFooter2 > div {
    float: none !important;
    display: flex;
    align-items: center;
    gap: 12px;
}

/* §8.6 — Footer buttons → §9.10 dialog pills, mapped by class: base = teal
   primary (Save / Submit), .Secondary = ghost (Cancel). !important beats both
   MainWhiteout .LinkButton and the §6 footer-link leak. */
body.page-vessel-management [id$='_pnlModInput'] a.LinkButton,
body.page-vessel-management [id$='_pnlDeleteRequest'] a.LinkButton {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    height: 36px;
    min-width: 64px;
    padding: 0 16px !important;
    border-radius: 8px !important;
    background-color: var(--primary) !important;
    background-image: none !important;
    color: #ffffff !important;
    border-width: 1px !important;
    border-style: solid !important;
    border-color: var(--primary) !important;
    font-family: var(--q88-grid-font);
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    text-decoration: none !important;
    box-shadow: none !important;
    cursor: pointer;
}
body.page-vessel-management [id$='_pnlModInput'] a.LinkButton:hover,
body.page-vessel-management [id$='_pnlDeleteRequest'] a.LinkButton:hover {
    background-color: var(--button-primary-hover) !important;
    border-color: var(--button-primary-hover) !important;
    color: #ffffff !important;
}
body.page-vessel-management [id$='_pnlModInput'] a.LinkButton.Secondary,
body.page-vessel-management [id$='_pnlDeleteRequest'] a.LinkButton.Secondary {
    background-color: #ffffff !important;
    color: #0f172a !important;
    border-color: #e2e8f0 !important;
}
body.page-vessel-management [id$='_pnlModInput'] a.LinkButton.Secondary:hover,
body.page-vessel-management [id$='_pnlDeleteRequest'] a.LinkButton.Secondary:hover {
    background-color: #f1f5f9 !important;
    border-color: #e2e8f0 !important;
    color: #0f172a !important;
}
/* Kill the LinkButton <ins>&nbsp;</ins> spacer (a flex item that shifts the
   label off-centre under inline-flex). */
body.page-vessel-management [id$='_pnlModInput'] a.LinkButton > ins,
body.page-vessel-management [id$='_pnlDeleteRequest'] a.LinkButton > ins {
    display: none !important;
}

/* §8.7 — Textareas → §16.8 field. Release the legacy 2px inset + fixed inline
   width/height; block-level, fill the cell, min-height floor (min-height beats
   the inline height attr, so the transfer textbox's height="30" still clears). */
body.page-vessel-management [id$='_pnlModInput'] textarea,
body.page-vessel-management [id$='_pnlDeleteRequest'] textarea {
    display: block;
    box-sizing: border-box;
    width: 100% !important;
    min-height: 64px;
    margin-top: 6px;
    padding: 8px 12px;
    background-color: #ffffff;
    border-width: 1px;
    border-style: solid;
    border-color: var(--border-default);
    border-radius: 8px;
    font-family: var(--q88-grid-font);
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: var(--text-primary);
    box-shadow: none;
    outline: none;
    resize: vertical;
}
body.page-vessel-management [id$='_pnlModInput'] textarea:focus,
body.page-vessel-management [id$='_pnlDeleteRequest'] textarea:focus {
    border-color: var(--primary);
    outline: 2px solid var(--primary);
    outline-offset: -1px;
}
