/* =====================================================================
 * masport_custom.css — DAYE North America / Masport Dealer Hub
 * Tier-1 customer override sheet (re-skin ladder step 1).
 * Loaded AFTER theme-default's default_custom.css by MasportHeadInclude.cshtml.
 *
 * Tier-0 (the palette itself) lives in the generated Style assets:
 *   /Files/System/Styles/ColorSchemes/masport.{json,css}
 *   /Files/System/Styles/Typography/masport.{json,css}
 *   /Files/System/Styles/Buttons/masport.{json,css}
 * Buttons paint from --dw-color-button-primary in the GENERATED sheet — this
 * file deliberately never declares that variable.
 *
 * Brand source of truth: extracts/masport-brand.json (Masport navy #0A2E5B,
 * accent #00A9E0, ink #231F20, greys #F9F9F9 / #F4F4F4 / #D7D7D7, read from
 * the live masport.com theme CSS; Inter 400/500/600/700/800, pill CTAs).
 * ===================================================================== */

/* === 1. Re-point theme-default's interaction accent to Masport Navy ===
 * theme-default declares --td-accent / --td-accent-soft as a restrained slate
 * and states "a customer re-skin overrides these first". Overriding here
 * recolours nav hover, mega-menu hover, the underline caret, outline/ghost
 * button hover and the chip/tag tints in one move. */
:root {
  --msp-navy:       #0A2E5B;   /* Masport navy — verified brand hex */
  --msp-navy-deep:  #061D3B;   /* hover / pressed — 16.8:1 on white, AA */
  --msp-accent:     #00A9E0;   /* interaction accent: rules, bars, badges.
                                  2.95:1 on white, so NEVER small text on white */
  --msp-ink:        #0F1B2D;   /* deep navy-black (footer landmark, dark bands) */
  --msp-offwhite:   #F9F9F9;
  --msp-hairline:   #D7D7D7;

  --td-accent:      #0A2E5B;
  --td-accent-soft: rgba(0, 169, 224, .10);
}

/* === 2. Brand accent slot ===
 * theme-default's convention: --dw-color-accent (+ -rgb / -contrast) is the
 * first-class home for a brand accent, and it says to set it per scheme in the
 * brand's ColorSchemes CSS. It is declared HERE instead because the generated
 * ColorSchemes .json model has no field that can express it
 * (Schemes[].{BackgroundColor,ForegroundColor,PrimaryButtonColor,
 * SecondaryButtonColor,CustomColors}), so putting it in masport.css would leave
 * the model lying and the next design save in admin would silently drop it.
 * RETIRE THIS BLOCK when the ColorSchemes model gains an accent field — then
 * move these three declarations into masport.json + masport.css together.
 * While it stays: opening and saving the design in admin does NOT lose the
 * accent, but the admin swatch will not show it either. */
.dw-colorscheme-light,          [data-dw-colorscheme="light"],
.dw-colorscheme-lightgrey1,     [data-dw-colorscheme="lightgrey1"],
.dw-colorscheme-lightgrey2,     [data-dw-colorscheme="lightgrey2"],
.dw-colorscheme-secondary,      [data-dw-colorscheme="secondary"] {
  --dw-color-accent:          #0A2E5B;
  --dw-color-accent-rgb:      10, 46, 91;
  --dw-color-accent-contrast: #FFFFFF;
}
/* On the dark bands navy would disappear into the background, so the accent
 * becomes Masport cyan there (5.9:1 on #0F1B2D — AA for normal text). */
.dw-colorscheme-dark,           [data-dw-colorscheme="dark"],
.dw-colorscheme-darksubtle,     [data-dw-colorscheme="darksubtle"] {
  --dw-color-accent:          #00A9E0;
  --dw-color-accent-rgb:      0, 169, 224;
  --dw-color-accent-contrast: #0A2E5B;
}
/* On the navy band itself the accent inverts so .text-accent stays legible. */
.dw-colorscheme-primary, [data-dw-colorscheme="primary"] {
  --dw-color-accent:          #FFFFFF;
  --dw-color-accent-rgb:      255, 255, 255;
  --dw-color-accent-contrast: #0A2E5B;
}

/* === 3. Primary button hover ===
 * theme-default hovers filled buttons to --td-ink-soft (slate). On a navy brand
 * that reads as the button changing brand, not state — use the deep navy.
 * #061D3B is the AA choice: 16.8:1 with white button text, where the cyan
 * accent #00A9E0 would drop to 2.95:1 and fail. */
[data-dw-button]:not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="secondary"]):not([data-dw-button="link"]):not([data-dw-button=""]):not([data-dw-button^="outline-"]):hover {
  background-color: var(--msp-navy-deep);
  border-color: var(--msp-navy-deep);
}
/* Link-style buttons (header "Dealer resources", data-dw-button="link") are text buttons:
 * the filled hover above painted them deep navy under navy text (owner report 2026-09-17,
 * unreadable). They hover like outline/ghost: a soft accent tint with navy text. */
[data-dw-button="link"]:not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="secondary"]):hover,
[data-swift-page-header] a[data-dw-button="link"]:hover {
  background-color: var(--td-accent-soft);
  border-color: transparent;
  color: var(--msp-navy);
}
/* Icon / outline buttons: Swift's customer-center lists emit their row toggles as
 * `<button class="btn btn-outline-secondary" data-dw-button>` (EMPTY value) and the row menu as
 * `data-dw-button="outline-secondary"`; neither is excluded by the filled hover above (nor by
 * theme-default's), so the chevron hovered to a solid navy disc with a navy chevron (owner report
 * 2026-09-17, customer center Actions column). They hover like outline/ghost. */
[data-dw-button=""]:not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="secondary"]):hover,
[data-dw-button^="outline-"]:not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="secondary"]):hover {
  background-color: var(--td-accent-soft);
  border-color: var(--msp-navy);
  color: var(--msp-navy);
}
/* theme-default's `[data-swift-page-header] a:hover { color: var(--td-accent) }` also recolours
 * BUTTON text in the header to navy, so the filled "Warranty & Support" button hovered to
 * navy text on grey. Filled header buttons keep white text on hover. */
[data-swift-page-header] a[data-dw-button]:not([data-dw-button="link"]):not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="outline-primary"]):hover {
  color: #FFFFFF;
}
/* ...except on the navy band, where the primary button is white. The attribute is doubled on
 * purpose: section 3's filled hover carries six :not()s and outranked this rule, so "Check a
 * serial number" on /en-us/warranty-support hovered to deep navy under navy text (1.2:1, gate
 * run 20260922-202443). Doubling lifts this rule above it without changing what it matches. */
[data-dw-colorscheme="primary"] [data-dw-button][data-dw-button]:not([data-dw-button="outline"]):not([data-dw-button="ghost"]):not([data-dw-button="secondary"]):not([data-dw-button="link"]):hover {
  background-color: #F4F4F4;
  border-color: #F4F4F4;
  color: var(--msp-navy);
}

/* === 4. Header — brand rule under the bar ===
 * One 3px Masport-navy rule is the cheapest "this is a Masport property" signal
 * and is what the JD / Greenworks dealer portals do. Scoped to the page-header
 * landmark so it cannot reach the catalog sidebar (theme-default pitfall: a
 * bare .navbar selector hits the category rail). */
[data-swift-page-header] {
  border-bottom: 3px solid var(--msp-navy);
}

/* === 5. Logo sizing ===
 * Swift-v2_Logo/Plain.cshtml emits an inline style="width:<LogoWidth>px" on the
 * <img>, which does not shrink on a phone canvas (mobile-pass trap: inline
 * hardcoded logo width). Cap it responsively without touching the template. */
[data-dw-itemtype="swift-v2_logo"] figure {
  margin: 0;
  max-width: 100%;
}
[data-dw-itemtype="swift-v2_logo"] figure > img {
  max-width: 100%;
  height: auto;
}
@media (max-width: 575.98px) {
  [data-dw-itemtype="swift-v2_logo"] figure > img { width: 150px !important; }
  /* The SVG branch puts the inline width on the FIGURE, not on an <img>, so the
   * img-only cap above silently stopped applying when the marks became SVG
   * (measured 2026-09-17: 190px logo, 618px document at a 390px canvas). Cap the
   * figure too, or the small-screen cap is dead for every SVG logo. */
  [data-dw-itemtype="swift-v2_logo"] figure.icon-auto { width: 150px !important; }
}
/* The Masport marks are SVG, and Plain.cshtml INLINES an svg (figure.icon-auto)
 * instead of emitting an <img>. swift.css sets .icon-auto svg{height:100%} —
 * harmless while the figure has no height, but state the intent explicitly so a
 * future height on the figure cannot squash the wordmark. */
[data-dw-itemtype="swift-v2_logo"] figure.icon-auto > svg {
  width: 100%;
  height: auto;
}

/* === 6. Footer — deep navy-black + accent top rule ===
 * theme-default paints the footer landmark --td-ink (#231F20) while the footer's
 * own grid row carries data-dw-colorscheme="dark" (#0F1B2D in the Masport
 * schemes). Align the landmark to the row so no seam shows below the last row. */
/* The rule is the CYAN accent, not navy: a 3px #0A2E5B line on a #0F1B2D
 * footer is invisible (1.3:1). Cyan is how masport.com separates its dark
 * bands, and it pairs with the navy rule under the header. */
body > footer,
[data-swift-page-footer] {
  background-color: var(--msp-ink);
  border-top: 3px solid var(--msp-accent);
}

/* === 7. Eyebrow / kicker ===
 * theme-default's body-copy softener (main [data-dw-colorscheme] p) out-specifies
 * a bare utility class, so kickers are matched on the Swift poster/text eyebrow
 * wrapper rather than on a class. */
[data-swift-poster] .eyebrow,
[data-dw-itemtype="swift-v2_poster"] p.dw-paragraph:first-of-type {
  color: var(--dw-color-accent, var(--msp-navy));
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* === 8. Accent hairline under section headings ===
 * Reads as "dealer portal", not "consumer shop". Scoped to main + the Swift
 * text wrapper so it cannot reach header, footer, the customer-center chrome or
 * a product title. Decorative ::after only — it adds no layout the content
 * depends on, so an over-reach degrades to a stray 56px bar, never hidden
 * content. Swift headings carry a size class (dw-h2/h3/h4) independent of the
 * tag, so the selector keys on the TAG, not on the class. */
main [data-swift-text] h2::after {
  content: "";
  display: block;
  width: 56px;
  height: 3px;
  margin-top: .6rem;
  background-color: var(--msp-accent);
}
main [data-swift-text].text-center h2::after {
  margin-inline: auto;
}

/* === 9. P7 mobile pass — the ONE genuine 390px finding ===
 * Measured with document.body.scrollWidth in headless Chrome at 390x844 with an
 * iPhone device descriptor (scripts/p7-cdp.js), NOT from screenshots — the P2
 * carry-forward "the phone canvas stretches at 390" was a screenshot artefact
 * and does not reproduce: every demo-path page measures scrollWidth == 390.
 *
 * What DID reproduce: the T42 IPL assembly PDPs. Swift renders the product long
 * description inside `.mw-75ch.d-inline-block`. An inline-block is sized to
 * min(max-content, max-width), and `mw-75ch` is `max-width: 75ch` ≈ 600px — so
 * the wide callout table (Ref / Part number / Description / Qty / MSRP /
 * Extended) forced a ~600px box inside a 390px viewport, Chrome widened the
 * LAYOUT viewport to 413px to fit it, and the whole page rendered zoomed out.
 * The table's own `.table-responsive` wrapper could not help, because its width
 * was being set by that oversized parent.
 *
 * Capping the readable-measure utility at the column width on small screens is
 * strictly correct — 75ch is a typographic maximum, never a minimum — and it
 * hands the horizontal scroll back to `.table-responsive`, where it belongs.
 * Retirement condition: drop this block if Swift ever ships `mw-75ch` as
 * `max-width: min(75ch, 100%)`. */
@media (max-width: 991.98px) {
  .mw-75ch { max-width: 100% !important; }
}

/* === 10. Header megamenu — hover reachability + design pass (P9) ===
 * BUG (measured, scripts/p9-menu-diag*.js): Swift opens header dropdowns on
 * item.mouseenter and hides on item.mouseleave; Popper offsets the panel down
 * by the nav row's bottom padding (data-bs-offset "0, 16" here), so the pointer
 * must cross ~16px that hit-test as the grid COLUMN, not the nav item —
 * mouseleave fires and the menu hides before it can be reached. Swift's own
 * toggle-::after bridge is dead on this site: theme-default's caret rules
 * (LRN-nav-04 in default_custom.css) force that same pseudo to position:static
 * in every open state, and the theme's replacement bridge (LRN-nav-03, an
 * absolute ::after on the ITEM) never anchors on the megamenu variant because
 * megamenu items carry Bootstrap's .position-static by design.
 *
 * FIX: an invisible apron on the PANEL's own ::before, anchored bottom:100%.
 * The panel is Popper-positioned (a containing block), so the apron spans
 * exactly the gap above it; as a descendant of the nav item it hit-tests as
 * the menu, so the pointer never "leaves" the item on the way down. Height
 * rides Swift's own --swift-dynamic-offset (set inline on the wrapper from the
 * row padding, 16px here) so it stays correct if the row spacing changes.
 * No :has(), no JS, no template edit. Retirement condition: drop when Swift
 * ships a bridge that survives LRN-nav-04 + .position-static together. */
.megamenu-wrapper .nav-item.dropdown > .dropdown-menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--swift-dynamic-offset, 1rem);
}
/* swift.css sets .dropdown-menu { max-height:80vh; overflow-y:auto } globally,
 * and an auto-overflow box CLIPS its own out-of-box pseudo-elements — the apron
 * above would be clipped to nothing (measured: hit-test fell through to the
 * grid column). On the mega variant scrolling belongs to the inner
 * [data-swift-container] (max-height:70vh; overflow-y:auto in swift.css), so
 * the panel itself can and must stay visible. */
.megamenu-wrapper .megamenu.dropdown-menu {
  overflow: visible;
  max-height: none;
}

/* --- Design pass: JD/Greenworks-style panel, not a bare white strip --- */

/* The panel merges with the white header above it; give it a deliberate
 * bottom edge — the header's 3px navy rule appears to move below the open
 * panel — and a real shadow so it reads as a surface over the page. */
.megamenu-wrapper .megamenu {
  border-bottom: 3px solid var(--msp-navy);
  box-shadow: 0 18px 28px -12px rgba(15, 27, 45, .22);
}

/* Column heads: uppercase Open Sans with the same short accent underline the
 * section headings use (block 8) — one visual system. Heads are the first
 * nav-link in each column (grid columns and the related-content rail). */
.megamenu-wrapper .megamenu .megamenu-col > .nav-link:first-child,
.megamenu-wrapper .megamenu nav > .nav-link:first-child,
.megamenu-wrapper .megamenu nav > div.nav-link:first-child {
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--msp-ink);
}
.megamenu-wrapper .megamenu .megamenu-col > .nav-link:first-child::after,
.megamenu-wrapper .megamenu nav > .nav-link:first-child::after,
.megamenu-wrapper .megamenu nav > div.nav-link:first-child::after {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  margin-top: .5rem;
  background-color: var(--msp-accent);
}
.megamenu-wrapper .megamenu .megamenu-col > .nav-link:first-child:hover,
.megamenu-wrapper .megamenu nav > .nav-link:first-child:hover {
  color: var(--msp-navy);
  text-decoration: none !important;
}

/* Sub links: quiet slate, navy on hover (the theme's accent underline already
 * follows --td-accent). A touch more breathing room per row. */
.megamenu-wrapper .megamenu .megamenu-col > .nav-link:not(:first-child),
.megamenu-wrapper .megamenu nav > .nav-link:not(:first-child) {
  color: #545353;
  padding-block: .3rem;
}
.megamenu-wrapper .megamenu .megamenu-col > .nav-link:not(:first-child):hover,
.megamenu-wrapper .megamenu nav > .nav-link:not(:first-child):hover {
  color: var(--msp-navy);
}

/* The open trigger stays visibly "on" while the pointer is down in the panel. */
.megamenu-wrapper .nav-item.dropdown:has(> .dropdown-menu.show) > .nav-link {
  color: var(--msp-navy);
}

/* Soft open: fade the panel, let the content rise 6px. Popper owns the panel's
 * inline transform, so the rise animates the inner container, never the panel. */
@media (prefers-reduced-motion: no-preference) {
  .megamenu-wrapper .megamenu.show {
    animation: msp-menu-fade .16s ease-out;
  }
  .megamenu-wrapper .megamenu.show > [data-swift-container] {
    animation: msp-menu-rise .2s ease-out;
  }
}
@keyframes msp-menu-fade { from { opacity: 0; } }
@keyframes msp-menu-rise { from { transform: translateY(-6px); } }

/* === 11. PLP — B2B line view + facet sidebar (P10) ===
 * The repeater (item 31) runs in "list" mode: every product is a full-width
 * <article class="js-product"> whose CONTENT is the component page 8491 —
 * stacked RowFlex sections (image / header+number / stock / price / add to
 * cart). Stacked full-width cards read as a broken grid, so at lg+ the card
 * flattens into ONE dense dealer row: display:contents on the section/container
 * shells lifts the leaf grid columns into the article's own grid. The paragraph
 * ids are the stable handles (they are asserted by gates, so they cannot
 * drift): 22307 image · 22308 header · 22309 SKU · 22575 stock · 22310 price ·
 * 22311 cart. Mobile keeps the stock stacked card. */
@media (min-width: 992px) {
  /* facet sidebar: facets paragraph is the first flex column of the repeater row */
  [data-swift-gridcolumn][id="22304"] {
    flex: 0 0 272px;
    max-width: 272px;
  }
  [data-swift-gridcolumn][id="22305"] { min-width: 0; }

  .product-list .grid > article.js-product {
    display: grid !important;   /* the repeater stamps d-flex (display:flex !important) on the article */
    /* budget for the ~785px article inside the 9/12 column: fixed tracks + gaps
     * must leave the title a real 1fr (they ate all of it at the first sizes) */
    grid-template-columns: 72px minmax(0, 1fr) 132px 148px 196px;
    grid-template-rows: auto auto;
    align-items: center;
    align-content: center;
    column-gap: .75rem;
    padding: .8rem .25rem;
    border-bottom: 1px solid #D7D7D7;
    position: relative;
  }
  .product-list .grid > article.js-product [data-swift-gridcolumn] { min-width: 0; }
  .product-list .grid > article.js-product [data-dw-itemtype="swift-v2_productdefaultimage"] figure {
    width: 72px !important;    /* the DefaultImage template inlines width:120px */
    margin: 0;
  }
  .product-list .grid > article.js-product:first-of-type { border-top: 1px solid #D7D7D7; }
  .product-list .grid > article.js-product:hover { background-color: #F9F9F9; }
  .product-list .grid > article.js-product > section,
  .product-list .grid > article.js-product > section > [data-swift-container] {
    display: contents !important;   /* the container carries d-flex (display:flex !important) */
  }
  /* Keep the stretched-link's box out of the grid flow AND make it cover the
   * whole row. position:absolute alone broke row clicks: a positioned <a>
   * becomes the containing block for its own stretched-link ::after, which
   * then covers only the (zero-size) link box. inset:0 makes the link itself
   * the row-sized cover; the qty/cart controls still paint above it (they are
   * later siblings), exactly like the stock card. */
  .product-list .grid > article.js-product > a.stretched-link { position: absolute; inset: 0; }

  .product-list article.js-product [data-dw-itemtype="swift-v2_productdefaultimage"] { grid-column: 1; grid-row: 1 / span 2; }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productheader"]       { grid-column: 2; grid-row: 1; align-self: end; }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productnumber"]       { grid-column: 2; grid-row: 2; align-self: start; }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productstock"]        { grid-column: 3; grid-row: 1 / span 2; }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productprice"]        { grid-column: 4; grid-row: 1 / span 2; }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productaddtocart"]    { grid-column: 5; grid-row: 1 / span 2; }

  .product-list article.js-product [data-dw-itemtype="swift-v2_productdefaultimage"] img {
    max-height: 88px;
    object-fit: contain;
  }
  .product-list article.js-product [data-dw-itemtype="swift-v2_productheader"] .h5,
  .product-list article.js-product [data-dw-itemtype="swift-v2_productheader"] h1,
  .product-list article.js-product [data-dw-itemtype="swift-v2_productheader"] h2,
  .product-list article.js-product [data-dw-itemtype="swift-v2_productheader"] h3 {
    font-size: 1rem;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;          /* marine PLP-LINEVIEW: clamp the title, never the row */
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}
/* The PLP page's outer row is 2Columns_3-9 with ProductListNavigation in the
 * 3/12 column — and that nav renders ZERO items on every group page (its
 * start/stop config produces no tree), leaving a huge dead gutter left of the
 * whole list. Hide the empty shell AND give its row-mate the full 12 columns;
 * if the nav ever renders real links, the 3/9 split comes back by itself. */
/* !important: swift.css's [data-swift-gridrow] [data-swift-container]
 * [data-swift-gridcolumn]{display:flex} out-specifies the :not(:has(li)) form. */
[data-dw-itemtype="swift-v2_productlistnavigation"]:not(:has(li)) { display: none !important; }
[data-swift-gridcolumn][data-dw-itemtype="swift-v2_productlistnavigation"]:not(:has(li)) + [data-swift-gridcolumn] {
  grid-column: span 12;
}

/* SKU under the title, muted mono — every viewport */
.product-list article.js-product [data-dw-itemtype="swift-v2_productnumber"] {
  font-family: Consolas, "Roboto Mono", monospace;
  font-size: .8125rem;
  color: #6B6B6B;
}
@media (max-width: 991.98px) {
  /* the facets column shares a no-wrap d-flex row with the repeater; let it
   * wrap so the (mobile) facet button stacks above the list */
  [data-swift-gridrow]:has([data-swift-gridcolumn][id="22304"]) > [data-swift-container] { flex-wrap: wrap; }
  [data-swift-gridcolumn][id="22304"] { flex: 1 1 100%; }
}

/* === 12. PDP — tabbed PIM section + document cards (P10) ===
 * Rendered by Paragraph/Swift-v2_ProductLongDescription/DnaPdpTabs.cshtml on
 * paragraph 22320. Navy-underline tabs on the block-8 visual system. */
.dna-pdp-tabnav {
  border-bottom: 2px solid #D7D7D7;
  gap: .25rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.dna-pdp-tabnav .nav-link {
  border: 0;
  border-bottom: 3px solid transparent;
  border-radius: 0;
  color: #545353;
  font-weight: 600;
  letter-spacing: .02em;
  padding: .7rem 1rem;
  white-space: nowrap;
  margin-bottom: -2px;
}
.dna-pdp-tabnav .nav-link:hover { color: var(--msp-navy); border-color: transparent; }
.dna-pdp-tabnav .nav-link.active {
  color: var(--msp-navy);
  background: transparent;
  border: 0;
  border-bottom: 3px solid var(--msp-navy);
}
.dna-pdp-prose { max-width: 75ch; }
.dna-pdp-prose h2 { font-size: 1.35rem; }
.dna-pdp-prose h3 { font-size: 1.1rem; margin-top: 1.25rem; }

/* spec groups: uppercase heads with the block-8 accent bar, two balanced columns
 * on wide screens (heads stay glued to their tables) */
.dna-pdp-specs h4 {
  font-size: .85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  margin: 1.1rem 0 .4rem;
  break-after: avoid;
}
.dna-pdp-specs h4::after {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  margin-top: .4rem;
  background-color: var(--msp-navy);
}
.dna-pdp-specs table { break-inside: avoid; }
.dna-pdp-specs table tr td:first-child { color: #6B6B6B; }
@media (min-width: 1200px) {
  .dna-pdp-specs .table-responsive { column-count: 2; column-gap: 3.5rem; }
}

/* document cards */
.dna-pdp-docs { grid-template-columns: repeat(auto-fill, minmax(320px, 420px)); }
.dna-doc-card {
  border: 1px solid #D7D7D7;
  border-radius: .375rem;
  color: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.dna-doc-card:hover {
  border-color: var(--msp-navy);
  box-shadow: 0 6px 16px rgba(15, 27, 45, .08);
}
.dna-doc-badge {
  background-color: var(--msp-navy);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .05em;
  padding: .5rem .55rem;
  border-radius: .25rem;
}
.dna-doc-arrow { color: var(--msp-navy); font-size: 1.15rem; }

/* === 13. Demo-day review (R1) — Home hero, PDP dead space, BOM, gated price ===
 * Findings measured with notes/review/review-cdp.js (DOM tree + full shots at
 * 1440 and 390, dealer and anonymous). Rows that were pure spacing went
 * inactive in SQL (notes/review/sql/r2-pdp-rows.sql); what is left here is
 * layout the grid model cannot express. */

/* 13a. PDP buy column: a 1ColumnFlex section whose only column rendered NOTHING
 * (variant selector on a non-variant product, BOM on a plain part, price table
 * for a visitor with no price) still paints its row spacing + the 20px
 * paragraph padding as a blank band. Collapse the whole section. */
/* :has() may not nest and the column holds whitespace, so the empty test lives
 * in MasportHeadInclude.cshtml (adds .dna-empty-col on DOMContentLoaded). */
section[data-swift-gridrow="1ColumnFlex"]:has(> [data-swift-container] > .dna-empty-col:only-child) {
  display: none !important;
}
/* A volume table with ONE tier is the price repeated under a "QTY / pr. PCS"
 * header — noise on equipment. The blades/belts/filters keep their 1/6/12 tiers. */
[id="22317"] section[data-swift-gridrow="1ColumnFlex"]:has(> [data-swift-container] > [data-dw-itemtype="swift-v2_productpricetable"] tbody > tr:only-child) {
  display: none !important;
}

/* 13b. BOM ("The product package consists of"): the stock template wraps the
 * component grid in a 640px scroll box and lays the ten parts out as 3-up
 * ~715px cards — two rows visible, the rest behind a scrollbar inside the
 * page. Un-clip it and flatten each component into a dealer row, the same
 * shape as the PLP line view (block 11), sized for the 6/12 buy column. */
/* the 640px max-height + overflow:auto are inline on the grid COLUMN itself */
[data-swift-gridcolumn][data-dw-itemtype="swift-v2_productbom"],
[data-dw-itemtype="swift-v2_productbom"] > div {
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
}
[data-dw-itemtype="swift-v2_productbom"] p.border-top {
  font-weight: 600;
  color: #231F20;
}
@media (min-width: 992px) {
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product {
    grid-column: span 12;
    display: grid !important;
    grid-template-columns: 52px minmax(0, 1fr) 100px 118px 164px;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: .6rem;
    padding: .55rem .25rem;
    border-bottom: 1px solid #D7D7D7;
    position: relative;
  }
  [data-dw-itemtype="swift-v2_productbom"] .grid { row-gap: 0; }
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product:first-of-type { border-top: 1px solid #D7D7D7; }
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product:hover { background-color: #F9F9F9; }
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product [data-swift-gridcolumn] { min-width: 0; }
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product > section,
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product > section > [data-swift-container] {
    display: contents !important;
  }
  [data-dw-itemtype="swift-v2_productbom"] .grid > article.js-product > a.stretched-link { position: absolute; inset: 0; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productdefaultimage"] { grid-column: 1; grid-row: 1 / span 2; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productheader"]       { grid-column: 2; grid-row: 1; align-self: end; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productnumber"]       { grid-column: 2; grid-row: 2; align-self: start; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productstock"]        { grid-column: 3; grid-row: 1 / span 2; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productprice"]        { grid-column: 4; grid-row: 1 / span 2; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productaddtocart"]    { grid-column: 5; grid-row: 1 / span 2; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productdefaultimage"] figure {
    width: 52px !important;
    margin: 0;
  }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productheader"] .h6,
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productheader"] h2 {
    font-size: .875rem;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product [data-dw-itemtype="swift-v2_productnumber"] {
    font-family: Consolas, "Roboto Mono", monospace;
    font-size: .75rem;
    color: #6B6B6B;
  }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product .dna-price .fs-5,
  [data-dw-itemtype="swift-v2_productbom"] article.js-product .dna-price .fs-2 { font-size: 1rem !important; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product .dna-net-badge { display: none; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product .dna-list-stock { font-size: .75rem; line-height: 1.25; }
  [data-dw-itemtype="swift-v2_productbom"] article.js-product .dna-price-saving { display: none; }
}

/* 13c. Anonymous visitor: DnaNetPrice.cshtml now renders a sign-in nudge where
 * the (area-gated) price would sit, instead of a silent blank. */
.dna-price-gated-link {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--msp-navy);
  text-decoration: none;
  white-space: nowrap;
}
.dna-price-gated-link:hover { text-decoration: underline; color: var(--msp-navy-deep); }
[id="22317"] .dna-price-gated-link { font-size: .95rem; }

/* 13d. Home hero (poster 22374, full-bleed lineup photo). At lg+ the copy ran
 * the full container width, so the lead paragraph and the CTAs sat on top of
 * the left tractor. Cap the copy and back it with a soft white wash that fades
 * out before the tractors. Under lg the absolute figure becomes a photo band
 * ABOVE the copy — dark text over a navy machine was unreadable at 390. */
@media (min-width: 992px) {
  /* cap the copy, not the container: a capped container re-centres inside the grid */
  [id="22374"] [data-swift-poster] > [data-swift-container] > * { max-width: 600px; }
  [id="22374"] [data-swift-poster] > figure::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, .92) 0%, rgba(255, 255, 255, .82) 40%, rgba(255, 255, 255, 0) 60%);
  }
}
@media (max-width: 991.98px) {
  [id="22374"] [data-swift-poster] {
    display: flex !important;
    flex-direction: column;
    min-height: 0 !important;
    padding: 0 !important;
  }
  [id="22374"] [data-swift-poster] > figure {
    position: relative !important;
    order: -1;
    width: 100%;
    height: 240px;
    inset: auto !important;
  }
  [id="22374"] [data-swift-poster] > figure::before { display: none; }
  [id="22374"] [data-swift-poster] > figure img { object-position: 50% 62% !important; }
  [id="22374"] [data-swift-poster] > [data-swift-container] { padding: 1.5rem 1rem 2rem !important; }
}

/* === 20. Feature tiles, boxed icon-top variant (customer-center Overview) ===
 * Swift's IconTop feature paints the icon on an inline black square
 * (style="background-color:var(--bs-body-color)") and lets each tile grow with its copy, so the
 * three buttons in a row sit at different heights (owner report 2026-09-17). The tile becomes a
 * column flexbox filling its grid cell with the button pinned to the bottom, and the icon box
 * takes the soft accent tint on navy with rounded corners. The icon-left variant on the home and
 * warranty pages has no box (`> div.d-flex`) and is left alone. */
[data-dw-itemtype="swift-v2_feature"] > div:not(.d-flex) {
  display: flex;
  flex-direction: column;
  height: 100%;
}
[data-dw-itemtype="swift-v2_feature"] > div:not(.d-flex) > .d-flex:last-child {
  margin-top: auto;
  padding-top: 1rem;
}
[data-dw-itemtype="swift-v2_feature"] figure.icon-4.p-3 {
  background-color: var(--td-accent-soft) !important;
  color: var(--msp-navy) !important;
  border-radius: 0.75rem;
  align-self: flex-start;   /* the column flexbox above would otherwise stretch the box full width */
}

/* 2026-10-13 claim detail overflow at 390px: .form-floating > label.u-pull--left is float:left + white-space:nowrap
 * (Swift), so the long "Add information for the warranty administrator (required)" label pushed the page to 422px
 * and dragged the position-fixed toast wrapper (end-0) with it. Below 576px let the label wrap inside the field. */
@media (max-width: 575.98px) {
  .form-floating > label.u-pull--left {
    float: none;
    max-width: 100%;
    white-space: normal;
    height: auto;
    overflow: hidden;
    text-overflow: clip;
  }
  .form-floating > label.u-pull--left ~ textarea.form-control,
  .form-floating > textarea.form-control {
    min-height: 7rem;
  }
}
