/* =========================================================
   CATEGORY.CSS
   =========================================================

   Product/category catalogue layout.

   Current design goal:
       Preserve the dense legacy catalogue feel, while allowing
       product cards to breathe on tablets and phones.

   ========================================================= */

/* =========================================================
   CATALOGUE PAGE
   ========================================================= */

.catalogue-page {
    width: 100%;
}

.catalogue-header {
    margin-bottom: 18px;

    overflow-x: auto;
}

.catalogue-header img,
.catalogue-header table {
    max-width: 100%;
}


.outlineHeader {
    border: 1px solid #c9c9c9; 
    background-color: #FFFFFF;
    overflow: hidden;
}

/*
    Header-content table reset.

    Subcategory/catalogue headers can contain legacy HTML tables that are used
    only for layout or introductory content. The global ui.css table rules add
    borders and backgrounds for real data tables, but those rules should not be
    forced onto editable header HTML.

    Default behaviour:
        Header tables have no forced cell borders or header backgrounds.

    To intentionally add a border from the header HTML itself, use inline
    styles on the table/cells, or add the class below to the header table:

        <table class="catalogue-header-table--bordered">

    Activity-log location:
        This is presentation-only CSS. Do not activity-log header rendering;
        only durable Admin saves of header_content should be activity-logged.
*/
.catalogue-header table,
.catalogue-header th,
.catalogue-header td {
    border: 0;
    background: transparent;
}

.catalogue-header table.catalogue-header-table--bordered {
    border-collapse: collapse;
}

.catalogue-header table.catalogue-header-table--bordered th,
.catalogue-header table.catalogue-header-table--bordered td {
    border: 1px solid #d0d0d0;
}

.catalogue-header table.catalogue-header-table--bordered th {
    background: #f5f5f5;
}

/* 
    Catalogue header media layout.

    This class is only responsible for the side-by-side desktop layout and the
    stacked mobile layout. It deliberately does not assign a fixed image width.

    Image sizing rule:
        Set the image size in the header HTML itself, or omit width/height so
        the browser displays the image at its natural file dimensions.

        Example natural-size image:
            <img class="catalogue-header-logo-image" src="/assets/images/headers/example.jpg" alt="...">

        Example intentional fixed display size:
            <img class="catalogue-header-logo-image" src="/assets/images/headers/example.jpg" width="300" alt="...">

    Activity-log location:
        This is presentation-only CSS. Do not activity-log header rendering.
        Durable Admin saves of header_content should continue to be logged by
        the Admin controller that performs the save.
*/
.catalogue-header-media-table .catalogue-header-logo-cell {
    vertical-align: middle;
    text-align: center;
}

.catalogue-header-media-table .catalogue-header-logo-image {
    display: block;

    /*
        Do not let the generic `.catalogue-header img { max-width: 100%; }`
        rule shrink these header/logo images inside narrow table cells.

        Header media images should display at their real file size by default,
        or at the width explicitly set in the header HTML. This keeps small
        legacy header images, such as 123px-wide logos/photos, from being
        squeezed down to tiny 50px-style renderings.

        Activity-log location:
            This is presentation-only CSS. Do not activity-log header image
            rendering; log only durable Admin saves that alter header content.
    */
    max-width: none;
    height: auto;
    margin: 0 auto;
}

.catalogue-header-media-table .catalogue-header-text-cell {
    vertical-align: middle;
    font-size: 16px;
}

/* 
    Stack this specific header layout on narrower screens.
    Adjust 700px higher/lower if you want it to stack sooner/later.
*/
@media (max-width: 700px) {
    .catalogue-header-media-table .catalogue-header-logo-cell,
    .catalogue-header-media-table .catalogue-header-text-cell {
        display: block;
        width: 100%;
        text-align: center;
    }

    .catalogue-header-media-table .catalogue-header-logo-image {
        max-width: 85vw;
        margin: 0 auto 10px;
    }

    .catalogue-header-media-table .catalogue-header-text-cell {
        text-align: left;
    }
}


/* =========================================================
   PRODUCT GRID
   ========================================================= */

.product-grid {
    /*
        Use flex instead of strict CSS grid so partial final rows are centered.
        Example: if a page is configured for 5-across but has only 3 cards, or
        has 3 cards left on the final row, those cards stay 5-across width but
        sit centered instead of pinned to the left.

        Activity-log location:
            This is presentation-only CSS. Do not activity-log layout changes;
            log only durable Admin setting/content saves that change catalogue
            data.
    */
    --product-grid-gap: 14px;

    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;

    gap: var(--product-grid-gap);

    width: 100%;
}

.product-grid > .product-card {
    flex: 0 1 100%;
    max-width: 100%;

    /*
        Match table-row behavior: within each flex row, all visible cards use
        the same row height. This pairs with .product-card { height: auto; }
        so the browser can stretch shorter cards to the tallest card in that
        row.
    */
    align-self: stretch;
}

.grid-1 > .product-card {
    flex-basis: 100%;
    max-width: 100%;
}

.grid-2 > .product-card {
    flex-basis: calc((100% - var(--product-grid-gap)) / 2);
    max-width: calc((100% - var(--product-grid-gap)) / 2);
}

.grid-3 > .product-card {
    flex-basis: calc((100% - 28px) / 3);
    max-width: calc((100% - 28px) / 3);
}

.grid-4 > .product-card {
    flex-basis: calc((100% - 42px) / 4);
    max-width: calc((100% - 42px) / 4);
}

.grid-5 > .product-card {
    flex-basis: calc((100% - 56px) / 5);
    max-width: calc((100% - 56px) / 5);
}

.grid-6 > .product-card {
    flex-basis: calc((100% - 70px) / 6);
    max-width: calc((100% - 70px) / 6);
}

/* =========================================================
   PRODUCT CARD
   ========================================================= */

.product-card {
    display: flex;
    flex-direction: column;

    min-width: 0;

    /*
        The product grid now uses flexbox so incomplete final rows can be
        centered. Leave the card height automatic so flexbox can stretch every
        card in the same row to the row height, matching table-like row
        behaviour. A fixed/percentage height blocks that stretch in some
        browsers.

        Activity-log location:
            This is presentation-only. Do not activity-log card-height
            stretching; log only durable catalogue/product admin saves.
    */
    height: auto;

    padding: 10px;

    border: 1px solid #c9c9c9;
    background: #ffffff;

    box-sizing: border-box;

    font-size: 12px;

    overflow: hidden;
}

/*
    Keep title/description content grouped for side-image layouts.

    Without this wrapper, CSS Grid splits the title and description into
    separate grid rows. A tall image that spans those rows can then distribute
    extra row height between them, making shorter cards look vertically
    stretched. The wrapper lets the title and description stay together at the
    top while the card itself can still stretch to match neighbouring cards.

    Activity-log location:
        This is presentation-only CSS. Do not activity-log browser layout; log
        only durable Admin changes that alter product/group data.
*/
.product-card-text-block {
    display: block;
    min-width: 0;
}

.product-card:hover {
    border-color: #999999;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

.product-card-whole-link {
    cursor: pointer;
}

.product-card-whole-link:focus-within,
.product-card-whole-link:hover {
    border-color: #777777;
}

.product-card-description-only {
    cursor: default;
}

.product-image-link {
    display: block;

    color: inherit;
    text-decoration: none;
}

.product-image {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 100%;

    /*
        Default catalogue-card image area is 170px tall. Individual catalogue
        pages can override this with --catalogue-product-image-max-height from
        catalogue_nodes.product_image_max_height. The name says max-height
        because the image itself still uses object-fit:contain and never crops.

        Activity-log location:
            This is presentation-only CSS. Durable page-setting saves are logged
            by CataloguePageContentAdminController.
    */
    height: var(--catalogue-product-image-max-height, 170px);
    max-height: var(--catalogue-product-image-max-height, 170px);

    margin-bottom: 8px;
}

.product-image img {
    display: block;

    max-width: 100%;
    max-height: 100%;

    object-fit: contain;
}

.product-title {
    margin: 0 0 7px 0;

    font-family: Arial, Helvetica, sans-serif;
    font-size: 18px;
    line-height: 1.25;
    font-weight: bold;
    text-align: center;

    overflow-wrap: break-word;
}

.product-title a {
    color: inherit;
    text-decoration: none;
}

.product-title a:hover {
    text-decoration: underline;
}

.product-description {
    flex: 0 0 auto;

    margin-bottom: 8px;

    color: #444444;
    font-size: 14px;
    line-height: 1.35;

    overflow: hidden;
}

/*
    Product groups need their buying table immediately below the description.

    Normal standalone product cards may use the description as a flexible
    spacer so the one-line purchase row can sit near the bottom of equal-height
    cards. Grouped hook-style cards are different: the buying table is part of
    the product-family content and should start directly after the description
    even when neighbouring cards are taller.

    Activity-log location:
        This is layout-only. Keep cart/add/select logging in CartController and
        product option handling.
*/
.product-group-card .product-description {
    flex: 0 0 auto;
}

.product-description * {
    max-width: 100%;
}

.product-description img,
.product-description table {
    max-width: 100%;
}

.product-description table,
.product-description th,
.product-description td {
    /*
        Legacy long descriptions often contain layout tables. The global UI
        table style adds borders/backgrounds/padding for real data tables, but
        those borders were never intended inside old description markup such as
        rod/outfit "includes" blocks. Keep technical product tables styled by
        .technical-product-table; this override applies only inside
        .product-description.
    */
    border: 0;
    background: transparent;
}

.product-description th,
.product-description td {
    padding: 0;
}

/*
   Product-card order tables.

   The card purchase area is now real table markup because the visible data is
   tabular: optional label/variation, catalogue number, price, and order
   action. Keep the outer product grid responsive, but let the purchase rows
   use table sizing rules so the protected columns remain intact.

   Compression rule:
       If a card becomes narrow, only the left descriptive label is allowed to
       shrink and truncate. Catalogue number, price, and Select/Add controls
       keep their natural width and must not be overlapped by neighbouring
       text.

   Activity-log location:
       This is visual layout only. Log actual add/select attempts in
       CartController and product-options.js, not from CSS/display rendering.
*/
.variation {
    color: #000000;
}

.catNum {
    color: #004B00;
}

.price {
    color: #800000;
    text-align: right;
    white-space: nowrap;
}

.product-card-order-table {
    display: table;

    width: 95% !important;
    max-width: 95%;

    /*
        Keep the purchase table centered as a flex child of .product-card.
        Narrow/mobile layouts can make the table shrink to its contents;
        align-self prevents that shrink-wrapped table from sitting against
        the left edge of the card.
    */
    align-self: center;

    margin: 8px auto 0 auto;

    border-collapse: separate;
    border-spacing: 0 6px;

    /*
        Keep a fixed column grid so the table honours its 95% card width at
        every viewport size. Auto layout can shrink-wrap to the protected
        catNum/price/button columns, which causes the label/variation row to
        appear lost on very narrow desktop windows and mobile portrait.
    */
    table-layout: fixed;

    /*
        In flex/grid product cards, an HTML table can otherwise shrink to its
        intrinsic content width. The flex-basis and min-width keep the buying
        table at 95% of the card instead of letting it collapse around the
        purchase row.
    */
    flex: none;
    min-width: 0;
    box-sizing: border-box;

    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
    font-weight: bold;
    line-height: 1.2;
}

.product-card-order-table td {
    vertical-align: middle;

    min-width: 0;

    /*
        Purchase-table cells intentionally have no padding or borders. The
        product-card buying area is not a data grid; any visible separators or
        headings should come from editable Product Group content, not inherited
        browser/global table borders.

        Activity-log location:
            This is display-only CSS. Durable Product Group row/section edits
            remain logged from ProductGroupAdminController.
    */
    padding: 0;
    border: none;
    background: transparent;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
    Standalone product cards should keep the purchase row at the bottom when
    neighbouring cards in the same row are taller. Grouped cards are excluded
    because their buying table is part of the product-family content and
    should remain immediately under the description.

    Activity-log location:
        This is CSS-only presentation. Keep add-to-cart/select logging in
        CartController and product-options.js.
*/
.product-card:not(.product-group-card) .product-card-simple-buying-table {
    margin-top: 8px;
}

.product-card-order-table .product-card-actions {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;

    /*
        This wrapper must never become wider than the protected action cell.
        The Product Group buying row is a fixed table: label, catNum, price,
        and action/status each own their own column. Letting this flex wrapper
        grow beyond 100% can push long unavailable text over the price column.

        Activity-log location:
            This is CSS-only display protection. Durable cart attempts and
            validation failures remain logged from CartController.
    */
    width: 100%;
    max-width: 100%;
    min-width: 0;

    margin: 0;
    padding: 0;

    overflow: hidden;
}

.product-card-order-table .product-card-actions form {
    display: flex;
    justify-content: flex-end;

    width: 100%;
    max-width: 100%;
    min-width: 0;

    margin: 0;

    overflow: hidden;
}

.product-card-order-table .product-card-actions button,
.product-card-order-table .product-card-actions .button,
.product-card-order-table .product-card-actions .product-select-button {
    display: inline-block;

    width: auto;
    max-width: none;

    margin: 0;
    padding: 2px 9px;

    font-size: 12px;
    line-height: 1;
    text-align: center;
    white-space: nowrap;
}

.product-card-order-table .product-card-actions .product-select-button {
    min-width: 62px;
}

.product-card-order-table .product-card-actions form button {
    min-width: 90px;
}

.product-card-order-action-cell {
    /*
        The action column is protected. It should keep enough room for the
        button, align to the right edge, and allow the legacy button shadow to
        render.
    */
    width: auto;
    min-width: 68px;

    text-align: right;
    overflow: visible !important;
    text-overflow: clip;
}

/*
    Simple standalone product cards need a real spacer column between the price
    and the Add to Cart button. Padding did not reliably show a visible change
    because the action cell is right-aligned and the table uses fixed layout.
    This spacer is deliberately scoped to simple standalone product cards only;
    grouped buying rows, technical tables, and rod-table layouts keep their
    existing tested spacing.

    Activity-log location:
        This is display-only presentation. Keep durable cart/add-to-cart
        logging in CartController and the related product-buy JavaScript paths.
*/
.product-card-simple-gap-col {
    width: 22px;
}

.product-card-simple-gap-cell {
    padding: 0;
    border: none;
}

.product-card-simple-buying-table .product-card-order-action-cell {
    padding-left: 0;
}

.product-card-simple-buying-table .product-card-simple-price {
    box-sizing: border-box;
    padding-right: 0;
}

.product-card-order-action-cell * {
    min-width: 0;
}

/*
    Standalone product catalogue cards use the same raised legacy Add to Cart
    and Select buttons as Product Group rows, but they do not carry the
    .product-group-row-actions wrapper that already reserves space for the
    lower 3px button shadow. Without this standalone-specific protection, the
    compact table/action wrappers can clip the bottom of the button on product
    cards that are displayed directly on a catalogue page.

    Keep the fix scoped to the simple standalone purchase row so Product Group
    rows, technical tables, product-detail forms, and modal buttons retain their
    existing tested spacing.

    Activity-log location:
        This is display-only CSS. Customer Add to Cart and Select attempts are
        still logged from CartController and the related product-option handling;
        no activity log should be written for this visual rendering correction.
*/
.product-card-simple-purchase-row > td {
    height: 30px;
}

.product-simple-row-actions.product-card-order-action-cell {
    overflow: visible !important;
}

.product-simple-row-actions .product-card-order-action-controls {
    min-height: 26px;
    overflow: visible;
}

.product-simple-row-actions .product-card-order-action-controls form {
    min-height: 26px;
    overflow: visible;
    align-items: center;
}

.product-simple-row-actions .product-card-order-action-controls button,
.product-simple-row-actions .product-card-order-action-controls .button,
.product-simple-row-actions .product-card-order-action-controls .product-select-button {
    /* Reserve the 3px raised-button shadow inside the standalone row height. */
    margin-bottom: 3px;
}

/*
    Normal-width purchase rows should keep the exact same 95%-wide, centered
    table footprint that tested correctly on desktop, narrow desktop, and
    mobile portrait layouts.

    Only the internal column allocation changes here. The descriptive label is
    the flexible column, while catNum, price, and the Select button receive
    protected widths so they do not draw over one another when the card is
    tight. This is CSS-only display protection; actual add/select attempts
    remain logged from CartController and related JavaScript/controller paths.
*/
.product-group-buying-table--with-labels .product-group-label-col {
    width: auto;
}

.product-group-buying-table--with-labels .product-group-catnum-col {
    /*
        Protect longer catalogue numbers such as #3097-1.5. The label column
        remains the sacrificial flexible column, so widening this fixed column
        uses the empty label-side space instead of clipping the catNum.
    */
    width: 96px;
    min-width: 96px;
}

.product-group-buying-table--with-labels .product-group-price-col {
    width: 54px;
}

.product-group-buying-table--with-labels .product-group-action-col {
    /*
        Default to the compact status width. The view adds a more specific
        action-type class after inspecting the group rows, so Select-only groups
        are not forced to reserve Add-to-Cart space that should belong to the
        editable row label.

        Activity-log location:
            This is display-only column sizing. Actual add/select attempts and
            validation failures remain logged from CartController.
    */
    width: 84px;
}

.product-group-buying-table--with-labels.product-group-buying-table--select-actions .product-group-action-col {
    /* Select only needs the smaller legacy raised button width. */
    width: 72px;
}

.product-group-buying-table--with-labels.product-group-buying-table--status-actions .product-group-action-col {
    /* Two-line unavailable/status text needs more room than Select, but less than Add to Cart. */
    width: 84px;
}

.product-group-buying-table--with-labels.product-group-buying-table--direct-add-actions .product-group-action-col {
    /*
        Direct Add to Cart is the widest compact action. Keep a small amount
        of extra protected space so the raised legacy button and its shadow are
        never clipped when the surrounding row table is tightened.
    */
    width: 96px;
}

.product-group-buying-table--with-labels.product-group-buying-table--direct-add-actions,
.product-group-buying-table--with-labels.product-group-buying-table--select-actions {
    /*
        Direct-add and Select grouped rows, such as leader-size and hook-pack
        rows, should share the same compact vertical rhythm while keeping the
        normal 95%-wide table footprint used by the rest of the tested product
        card rows. Only the vertical row spacing is tightened here. Do not add
        a max-width: that makes the buying rows shrink horizontally and pulls
        the label, catNum, price, and button into a compressed block.

        Activity-log location:
            This is presentation-only spacing. Durable Product Group edits stay
            logged from ProductGroupAdminController, and customer add-to-cart
            or Select attempts stay logged from CartController.
    */
    width: 95% !important;
    max-width: 95%;
    border-spacing: 0 2px;
}

.product-card-simple-catnum-col {
    width: auto;
}

.product-card-simple-price-col {
    width: 82px;
}

.product-card-simple-action-col {
    width: 96px;
}

.product-group-buying-table--no-labels .product-group-catnum-col {
    width: 40%;
}

.product-group-buying-table--no-labels .product-group-price-col {
    width: 22%;
}

.product-group-buying-table--no-labels .product-group-action-col {
    /*
        Keep no-label grouped rows safe for direct Add to Cart buttons too.
        The catNum and price columns remain protected; this only gives the
        action cell enough room for the wider button before clipping.
    */
    width: 38%;
}

/*
    Six-across catalogue pages can make no-label grouped product cards quite
    narrow. In that layout, percentage-based no-label columns leave the
    direct Add to Cart action cell narrower than the actual raised button, so
    the button overflows left across the price.

    Scope this fix to no-label Product Group rows that use direct Add to Cart
    actions only. Do not change the card width, grid gap, image sizing, title
    placement, labelled rows, Select-button rows, or technical-table rows.

    Activity-log location:
        This is display-only CSS. Customer add-to-cart attempts and validation
        failures remain logged from CartController; durable Product Group or
        catalogue-page layout edits remain logged from their Admin controllers.
*/
.product-group-buying-table--no-labels.product-group-buying-table--direct-add-actions .product-group-catnum-col {
    width: 58px;
}

.product-group-buying-table--no-labels.product-group-buying-table--direct-add-actions .product-group-price-col {
    width: 52px;
}

.product-group-buying-table--no-labels.product-group-buying-table--direct-add-actions .product-group-action-col {
    width: 96px;
}

.product-card-order-table .catNum,
.product-card-order-table .price {
    width: auto;

    overflow: hidden;
    text-overflow: clip;
    white-space: nowrap;
    border: none;
}

.product-card-order-table .catNum {
    min-width: 56px;
}

.product-card-order-table .price {
    min-width: 54px;
}

.product-card-simple-variation-cell,
.product-group-row-label {
    /*
        This is the only purchase-row text that may be sacrificed on narrow
        cards. It truncates inside its own cell rather than bleeding over the
        catalogue number, price, or button.
    */
    max-width: none;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    text-align: left;
    border: none;
}

.product-card-simple-variation-cell {
    max-width: none;
}

.product-group-row-label .product-row-link,
.product-group-row-catnum .product-row-link,
.product-group-row-price .product-row-link {
    display: block;

    overflow: hidden;
    white-space: nowrap;
}

.product-group-row-label .product-row-link {
    text-overflow: ellipsis;
}

.product-group-row-catnum .product-row-link,
.product-group-row-price .product-row-link {
    text-overflow: clip;
}

.product-card-simple-catnum,
.product-group-row-catnum {
    text-align: left;
}

.product-card-simple-price,
.product-group-row-price {
    text-align: center;
}

.product-simple-row-actions,
.product-group-row-actions {
    text-align: right;
    border: none;
}

.price--cad {
    /*
        Preserve the legacy Canadian price colour. The value is scoped through
        a class so US/international storefront prices can use the legacy blue
        without changing the underlying product data.
    */
    color: #800000;
}

.price--usd {
    /*
        Legacy US storefront prices appeared in blue. The currency itself is
        explained once per catalogue/search page rather than repeated beside
        every dense card-row amount.
    */
    color: #003a8c;
}

.product-availability {
    color: #444444;
    font-weight: 600;
}

.product-availability--in-stock {
    color: #006000;
}

.product-availability--out-of-stock,
.product-availability--unavailable {
    color: #7a3f00;
}

/*
   Grouped product rows now link to their exact product pages. Keep these
   links visually neutral so rod/hook tables still look like catalogue rows,
   not a page full of underlined link text. The Select button remains the
   obvious ordering action.
*/
.product-row-link {
    color: inherit;
    text-decoration: none;
}

.product-row-link:hover,
.product-row-link:focus {
    color: inherit;
    text-decoration: none;
}

.product-card-actions {
    display: flex;
    gap: 6px;
    align-items: stretch;
    justify-content: center;

    margin-top: 4px;
}

.product-card-actions form {
    margin: 0;
}

.product-card-actions {
    padding: 7px 10px;

    font-size: 12px;
    line-height: 1.2;
}

.region-unavailable {
    margin: 0;

    color: #800000;
    font-weight: bold;
    text-align: center;
}

.region-unavailable--compact {
    /*
        Keep unavailable/orderability text inside its own action/status cell.
        Product cards with several grouped rows can be narrow, so split known
        regional messages into short lines and clip inside the cell rather than
        allowing the status text to overlap catNum, price, or buttons.

        Activity-log location:
            This is presentation-only. Server-side ordering failures remain
            logged from CartController; ordinary unavailable-message display is
            not logged.
    */
    display: block;

    width: 100%;
    max-width: 100%;

    overflow: hidden;
    text-overflow: clip;
    white-space: normal;

    font-size: 11px;
    line-height: 1.05;
}

.region-unavailable__line {
    display: block;

    width: 100%;
    max-width: 100%;

    overflow: hidden;
    text-overflow: clip;
    white-space: nowrap;
}

.catalogue-currency-note {
    margin: 14px 0 4px;

    color: #333333;
    font-size: 12px;
    line-height: 1.35;
    text-align: center;
}

/* =========================================================
   EMPTY RESULTS
   ========================================================= */

.empty {
    padding: 30px;

    background: #fafafa;
    border: 1px solid #dddddd;
}

/* =========================================================
   PAGINATION
   ========================================================= */

.pagination {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;

    margin-top: 20px;
    margin-bottom: 20px;
}

.pagination a {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    min-width: 34px;
    min-height: 34px;

    padding: 6px 10px;

    border: 1px solid #c0c0c0;
    background: #ffffff;

    color: #222222;
    text-decoration: none;
}

.pagination a.active,
.pagination a:hover {
    background: #333333;
    border-color: #333333;
    color: #ffffff;
}

/* =========================================================
   RESPONSIVE PRODUCT GRID
   =========================================================

   Desktop:
       dispMode controls the number of columns.

   Tablet/phone:
       Layout overrides protect readability and prevent the old
       fixed-width/four-across problem on mobile.

   ========================================================= */

/*
    Column breakpoints are based on a practical minimum card width rather than
    only on broad desktop/tablet/phone sizes.

    Product-group buying rows with labels need protected space for catalogue
    number, price, and the Select/Add button. If a five-across layout is left
    in place until 1100px, those protected columns can consume the entire row
    and the label column can disappear completely.

    The breakpoints below keep each card roughly 260px or wider before reducing
    the visible column count. This still allows label truncation, but avoids
    letting the label column collapse to nothing while the window is resized.

    Activity-log location:
        This is presentation-only CSS. Do not activity-log resize/layout changes.
        Continue logging durable Admin setting saves from SettingsAdminController
        and cart/order actions from their related controllers.
*/
@media (max-width: 1630px) {

    .grid-6 > .product-card {
        flex-basis: calc((100% - 56px) / 5);
        max-width: calc((100% - 56px) / 5);
    }
}

@media (max-width: 1356px) {

    .grid-5 > .product-card,
    .grid-6 > .product-card {
        flex-basis: calc((100% - 42px) / 4);
        max-width: calc((100% - 42px) / 4);
    }
}

@media (max-width: 1082px) {

    .grid-4 > .product-card,
    .grid-5 > .product-card,
    .grid-6 > .product-card {
        flex-basis: calc((100% - 28px) / 3);
        max-width: calc((100% - 28px) / 3);
    }
}

@media (max-width: 808px) {

    .grid-3 > .product-card,
    .grid-4 > .product-card,
    .grid-5 > .product-card,
    .grid-6 > .product-card {
        flex-basis: calc((100% - var(--product-grid-gap)) / 2);
        max-width: calc((100% - var(--product-grid-gap)) / 2);
    }

    .grid-1 > .product-card {
        flex-basis: 100%;
        max-width: 100%;
    }

    .product-image {
        height: 145px;
    }

    .product-title {
        font-size: 16px;
    }
}

@media (max-width: 534px) {

    .product-grid > .product-card,
    .grid-1 > .product-card,
    .grid-2 > .product-card,
    .grid-3 > .product-card,
    .grid-4 > .product-card,
    .grid-5 > .product-card,
    .grid-6 > .product-card {
        flex-basis: 100%;
        max-width: 100%;
    }

    .product-card {
        padding: 10px;
    }

    .product-image {
        height: 180px;
    }

    .product-card-actions {
        flex-direction: column;
    }

    .product-card-actions {
        width: 100%;
    }
}

/* =========================================================
   PRODUCT GROUP CARDS
   =========================================================

   Product groups are native rebuilt-site display records. They are used for
   any product family that shares one card but has multiple orderable rows.
   Each row still posts the real products.catNum to the cart.

   The order rows are rendered as actual HTML tables. That is appropriate here
   because the row contents are tabular catalogue/order data, and it prevents
   the repeated overlap/cut-off problems from table-like CSS emulation.

   Activity log location:
       Keep logging actual cart actions and validation failures in
       CartController. CSS/display rendering is not activity-logged.
   ========================================================= */

.product-group-card {
    gap: 0;
}

.product-group-card,
.product-group-card * {
    box-sizing: border-box;
}

.product-group-row[data-row-href] {
    cursor: pointer;
}

.product-group-row[data-row-href]:hover .product-group-row-label,
.product-group-row[data-row-href]:hover .product-group-row-catnum,
.product-group-row[data-row-href]:hover .product-group-row-price,
.product-group-row[data-row-href]:hover .product-group-row-actions {
    background: #f7f8fa;
}

.product-group-section-heading {
    padding-top: 7px;
    padding-bottom: 2px;
    border: none;
    background: transparent;

    color: #000000;
    font-weight: 700;
    line-height: 1.25;
    text-align: left;
}

.product-group-section-content-cell {
    padding-bottom: 8px;
    text-align: center;
}

.product-group-row-label {
    color: #222222;
    font-weight: bold;
    text-align: left;
}

.product-group-row-catnum {
    font-weight: 600;
    text-align: left;
}

.product-group-row-price {
    font-weight: 600;
    text-align: center;
}

.product-group-row-actions {
    text-align: right;
}

/*
    Grouped buying rows need enough vertical room for both public order button
    variants. The shorter Select button fit in the previous compact row, but
    the wider Add to Cart button uses the same raised legacy shadow and could
    have its lower edge clipped by the protected row/action wrappers.

    Keep the table-based protection: label, catNum, price, and action/status
    still own separate cells. The action/status cell is only allowed vertical
    overflow for button shadows; unavailable text remains clipped inside its
    compact message element.

    Activity-log location:
        This is CSS-only presentation. Durable Product Group edits remain
        logged from ProductGroupAdminController; customer cart attempts remain
        logged from CartController.
*/
.product-group-row > td {
    height: 30px;
}

.product-group-row-actions.product-card-order-action-cell {
    overflow: visible !important;
}

.product-group-row-actions .product-card-order-action-controls {
    min-height: 26px;
    overflow: visible;
}

.product-group-row-actions .product-card-order-action-controls form {
    min-height: 26px;
    overflow: visible;
    align-items: center;
}

.product-group-row-actions .product-card-order-action-controls button,
.product-group-row-actions .product-card-order-action-controls .button,
.product-group-row-actions .product-card-order-action-controls .product-select-button {
    /* Reserve the 3px raised-button shadow inside the row height. */
    margin-bottom: 3px;
}

/*
    Direct-add and Select Product Group rows are the dense leader/hook-style
    buying rows. Keep their full table width, but reduce the vertical cell
    height so both button types sit closer together with matching spacing.
    Overflow remains visible on the action cell above, so the raised Add to Cart
    and Select buttons can show their full bottom shadow.

    Activity-log location:
        This remains display-only CSS. Product Group Admin saves, customer cart
        attempts, and Select/modal attempts continue to be logged from their
        controllers or related JavaScript/controller paths.
*/
.product-group-buying-table--with-labels.product-group-buying-table--direct-add-actions .product-group-row > td,
.product-group-buying-table--with-labels.product-group-buying-table--select-actions .product-group-row > td {
    height: 24px;
}

.product-group-buying-table--with-labels.product-group-buying-table--direct-add-actions .product-group-row-actions .product-card-order-action-controls,
.product-group-buying-table--with-labels.product-group-buying-table--direct-add-actions .product-group-row-actions .product-card-order-action-controls form,
.product-group-buying-table--with-labels.product-group-buying-table--select-actions .product-group-row-actions .product-card-order-action-controls,
.product-group-buying-table--with-labels.product-group-buying-table--select-actions .product-group-row-actions .product-card-order-action-controls form {
    min-height: 22px;
}

.product-group-display-only-cell {
    padding: 6px 0 2px 0 !important;

    color: #444444;
    font-size: 12px;
    font-weight: normal;
    line-height: 1.35;
    white-space: normal !important;
    text-align: left;
}

.product-group-display-only-title {
    display: block;
    margin-bottom: 4px;

    color: #222222;
    font-weight: 700;
}

.product-group-display-only-description {
    white-space: normal;
}

.product-group-display-only-description * {
    max-width: 100%;
}

.product-group-row-note {
    color: #444444;
    font-size: 12px;
    line-height: 1.3;
    text-align: left;
    white-space: normal;
}

.product-group-section-image {
    display: flex;
    justify-content: center;

    margin-bottom: 6px;
}

.product-group-section-image img {
    display: block;

    max-width: 100%;
    max-height: var(--catalogue-product-image-max-height, 130px);

    object-fit: contain;
}

.product-group-section-title {
    margin: 0 0 5px 0;

    font-size: 14px;
    line-height: 1.25;
}

.product-group-section-description {
    margin-bottom: 6px;

    color: #444444;
    font-size: 12px;
    line-height: 1.35;
}

@media (max-width: 520px) {

    .product-card-order-table {
        /*
            Keep the purchase table at the same 95% card width on mobile
            portrait and very narrow desktop windows. Do not switch to
            width:auto here: that shrink-wraps the table around catNum, price,
            and Select, which removes the practical space needed for labels
            such as product variation text.
        */
        display: table;
        width: 95% !important;
        min-width: 0;
        max-width: 95%;
        flex-basis: auto;
        margin-right: auto;
        margin-left: auto;
        align-self: center;
    }

    .product-group-buying-table--with-labels .product-group-catnum-col {
        /*
            Mobile portrait needs enough protected catalogue-number room for
            decimal/suffixed catNums. The row still keeps the tested 95%-wide
            centered table footprint and sacrifices label text first.
        */
        width: 104px;
        min-width: 104px;
    }

    .product-card-order-table .catNum {
        /*
            Match the wider mobile catNum column so longer text clips within
            its own protected space instead of crowding the price column.
        */
        min-width: 96px;
    }

    .product-card-simple-gap-col {
        width: 14px;
    }

    .product-card-simple-price-col {
        width: 74px;
    }

    .product-card-simple-action-col {
        width: 92px;
    }
}

.product-template-technical_table {
    grid-column: 1 / -1;
}

.product-grid > .product-template-technical_table {
    flex-basis: 100% !important;
    max-width: 100% !important;
}

/* =========================================================
   TECHNICAL PRODUCT TABLES
   =========================================================

   Used for rod/product-family layouts. These cards intentionally span the
   full catalogue grid and use horizontal scrolling on narrow screens.
   ========================================================= */

.product-template-technical_table {
    grid-column: 1 / -1;
}

.product-template-technical_table .product-image-link-static {
    display: block;
}

.product-template-technical_table .product-image {
    height: auto;
    max-height: 260px;
    margin-bottom: 10px;
}

.product-template-technical_table .product-image img {
    max-height: 260px;
}

.product-template-technical_table .product-title {
    margin-top: 2px;
    margin-bottom: 8px;
}

.technical-table-wrap {
    box-sizing: border-box;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.technical-product-table {
    width: 100%;
    min-width: 720px;
    border-collapse: collapse;
    font-size: 14px;
}

.technical-product-table th,
.technical-product-table td {
    padding: 6px 7px;
    border-bottom: 1px solid #d6d6d6;
    vertical-align: middle;
    text-align: left;
}

.technical-product-table thead th {
    background: #e1e4e6;
    color: #213663;
    font-weight: bold;
    white-space: nowrap;
}

.technical-product-table tbody tr:hover {
    background: #f7f8fa;
}

.technical-product-row[data-row-href] {
    cursor: pointer;
}

.technical-product-row--highlighted {
    /*
        Rod Finder uses this class when linking back to the real catalogue
        technical table. The highlight is intentionally stronger than hover
        so the target row remains obvious after the page finishes scrolling.
    */
    background: #fff7c2;
    outline: 2px solid var(--wwd-colour-dark-blue, #213663);
    outline-offset: -2px;
    scroll-margin-top: 120px;
}

.technical-product-table tbody tr.technical-product-row--highlighted:hover {
    background: #fff2a3;
}

/*
    Technical-table Above-row labels.

    These labels come from product_group_items.row_note. They introduce the
    following model row, so they should read as a compact full-width separator
    rather than as another orderable row.

    Activity-log location:
        This is presentation-only CSS. Durable Above-row label edits are logged
        by ProductGroupAdminController; customer Select/Add actions are logged
        by the cart/product-option workflows.
*/
.technical-product-table tbody tr.technical-row-note-row,
.technical-product-table tbody tr.technical-row-note-row:hover {
    background: transparent;
}

.technical-product-table .technical-row-note {
    padding-top: 9px;
    padding-bottom: 2px;
    border-bottom: 0;
    color: #222222;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.25;
    white-space: normal;
}

.technical-model-cell {
    width: 170px;
    color: #000000;
    font-weight: bold;
}

.technical-catnum-cell {
    color: #004B00;
    font-weight: 600;
    white-space: nowrap;
}

.technical-price-cell {
    color: #800000;
    font-weight: bold;
    text-align: right;
    white-space: nowrap;
}

.technical-price-cell.price--cad,
.technical-offer-price.price--cad {
    color: #800000;
}

.technical-price-cell.price--usd,
.technical-offer-price.price--usd {
    color: #003a8c;
}

.technical-action-cell {
    text-align: center;
    white-space: nowrap;
}

/*
    Center compact technical-table data values.

    Rod-family tables read more cleanly when short spec values such as Length,
    Line, Weight, and explicit Availability sit in the middle of their data
    cells. Model names and Cat # values stay left-aligned for scanning, while
    price/offer/order cells keep their existing specialized alignment.

    Activity-log location:
        This is display-only CSS. Durable technical-column and row-value edits
        are logged by ProductGroupAdminController; Select/Add-to-Cart actions
        continue to be logged through the cart/product-option workflow.
*/
.technical-product-table td.technical-spec-cell--spec-compact,
.technical-product-table td.technical-spec-cell--availability {
    text-align: center;
}

.technical-product-table td.technical-spec-cell--spec-compact .product-row-link,
.technical-product-table td.technical-spec-cell--availability .product-row-link {
    display: block;
    text-align: center;
}

.technical-spec-cell--availability.technical-availability-cell--in-stock,
.technical-availability-cell.product-availability--in-stock {
    font-size: 16px;
    font-weight: 700;
    text-align: center;
}

.technical-action-cell .product-card-actions,
.technical-action-cell form {
    margin: 0;
    padding: 0;
}

@media (max-width: 700px) {
    /*
        Technical tables are too wide for phone screens if preserved as a
        literal table. On small screens the same data becomes a stack of
        model cards. This keeps every table value visible without horizontal
        scrolling, while the desktop layout remains a normal table.

        Activity-log note:
            This is presentation-only. Log order/select activity in
            product-options.js and CartController, not in this responsive view.
    */
    .product-template-technical_table .product-image {
        max-height: 180px;
    }

    .product-template-technical_table .product-image img {
        max-height: 180px;
    }

    .technical-table-wrap {
        overflow-x: visible;
    }

    .technical-product-table {
        min-width: 0;
        width: 100%;
        border-collapse: separate;
        border-spacing: 0;
    }

    .technical-product-table thead {
        display: none;
    }

    .technical-product-table,
    .technical-product-table tbody,
    .technical-product-table tr,
    .technical-product-table th,
    .technical-product-table td {
        display: block;
        width: 100%;
        box-sizing: border-box;
    }

    .technical-product-table tbody tr {
        margin-bottom: 10px;
        /*
            The legacy-style buttons use a visible lower shadow. Since CSS
            shadows do not contribute to element height, narrow stacked rows
            need a little extra bottom padding or the row border appears to
            run through / stop at the button shadow.

            Activity-log note: this is display-only. Keep click/add-to-cart
            logging in product-options.js and CartController.
        */
        padding: 8px 8px 12px;
        border: 1px solid #d6d6d6;
        background: #ffffff;
    }

    .technical-product-table tbody tr:hover {
        background: #ffffff;
    }

    .technical-product-table th,
    .technical-product-table td {
        display: grid;
        grid-template-columns: 88px minmax(0, 1fr);
        gap: 8px;
        align-items: start;
        padding: 4px 0;
        border-bottom: 0;
        text-align: left;
        white-space: normal;
    }

    .technical-product-table th::before,
    .technical-product-table td::before {
        content: attr(data-label);
        color: #213663;
        font-weight: bold;
    }

    .technical-product-table tbody tr.technical-row-note-row {
        margin-bottom: 0;
        padding: 4px 8px 0;
        border: 0;
        background: transparent;
    }

    .technical-product-table .technical-row-note {
        display: block;
        width: 100%;
        padding: 5px 0 2px;
        border-bottom: 0;
    }

    .technical-product-table .technical-row-note::before {
        content: none;
    }

    .technical-model-cell {
        width: 100%;
        font-size: 13px;
    }

    .technical-catnum-cell,
    .technical-price-cell,
    .technical-availability-cell,
    .technical-action-cell {
        white-space: normal;
    }

    .technical-price-cell {
        text-align: left;
    }

    /*
        The desktop centering rule above is for table columns. Once the table
        is converted to mobile label/value cards, keep the values left-aligned
        inside the value column so each stacked row reads naturally.
    */
    .technical-product-table td.technical-spec-cell--spec-compact,
    .technical-product-table td.technical-spec-cell--availability,
    .technical-product-table td.technical-spec-cell--spec-compact .product-row-link,
    .technical-product-table td.technical-spec-cell--availability .product-row-link {
        text-align: left;
    }

    .technical-action-cell .product-card-actions,
    .technical-action-cell form {
        justify-content: flex-start;
    }

    .technical-action-cell .product-card-actions button,
    .technical-action-cell .product-card-actions .button {
        width: auto;
    }
}

/* =========================================================
   TECHNICAL TABLE MULTI-OFFER COLUMNS
   =========================================================

   Used for rod-family rows that have more than one orderable offer, such as
   Rod Only and Outfit. The offer labels are stored as product_group_offer_columns
   so Admin can rename them without changing code.
   ========================================================= */

.technical-offer-heading,
.technical-offer-cell {
    text-align: left;
    white-space: nowrap;
}

.technical-product-table--multi-offer .technical-offer-heading,
.technical-product-table--multi-offer .technical-offer-cell {
    /*
        Multi-offer columns such as Rod Only / Outfit need enough protected
        width for the price, catNum, and Select/Add control to sit cleanly.
        Keep the columns compact, but do not squeeze them down to the minimum
        text width because that makes the offer cell feel cramped.

        Activity-log note: this is presentation-only. Keep Select/add-to-cart
        activity logging in the product modal/cart layer.
    */
    width: 200px;
    min-width: 150px;
}

.technical-offer-content {
    /*
        Treat the visible offer cell like a small two-column table nested under
        one offer heading: the price occupies the left value column while the
        Select/Add control occupies its own right-side action column. This gives
        the price and button deliberate breathing room without splitting the
        public table header into separate visible columns.

        Activity-log note: this is display-only styling. Cart/modal actions are
        still logged in the product interaction layer and CartController.
    */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "price action"
        "catnum action";
    column-gap: 18px;
    row-gap: 1px;
    align-items: center;
    justify-content: stretch;
    width: 100%;
}

.technical-offer-price {
    grid-area: price;
    color: #800000;
    font-weight: bold;
    line-height: 1.2;
    min-width: 0;
}

.technical-offer-catnum {
    grid-area: catnum;
    color: #004B00;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.1;
    min-width: 0;
}

.technical-offer-action {
    grid-area: action;
    justify-self: end;
    margin-top: 0;
}

.technical-offer-action .product-card-actions,
.technical-offer-action form {
    justify-content: flex-end;
    margin: 0;
    padding: 0;
}

.technical-offer-unavailable {
    color: #666666;
    font-style: italic;
}

.product-group-row-action-na,
.product-card-simple-action-na,
.technical-offer-unavailable.price--cad,
.technical-offer-unavailable.price--usd {
    /*
        N/A replaces price/action output when Display remains on but Available
        is off. Match the catalogue price treatment so staff and customers see
        the unavailable purchase state in the same visual column language as
        prices, without making it look like a clickable button.

        Activity-log location:
            This is CSS-only presentation. Availability edits are logged by
            Product Admin or Quick Maintenance.
    */
    font-style: normal;
    font-weight: 600;
}

.technical-offer-unavailable.price--cad {
    color: #800000;
}

.technical-offer-unavailable.price--usd {
    color: #003a8c;
}

@media (max-width: 700px) {
    .technical-product-table--multi-offer .technical-offer-cell {
        /*
            Desktop multi-offer cells have a protected minimum width so the
            price, catNum, and Select/Add control do not crowd each other. On
            phones those same cells become full-width labelled rows inside
            stacked model cards.

            Layout:
                [Rod]      [$1,550.00 CAD]
                           [Select]

            The extra bottom padding reserves room for the button shadow so
            the enclosing mobile card border remains complete below the final
            Select button.

            Activity-log note:
                This is presentation-only. Keep modal/cart logging in the
                product interaction JavaScript and CartController.
        */
        width: 100%;
        min-width: 0;
        grid-template-columns: 88px minmax(0, 1fr);
        align-items: center;
        padding-bottom: 8px;
        text-align: left;
        white-space: normal;
    }

    .technical-offer-content {
        /*
            Let the offer's internal pieces participate directly in the parent
            row grid so the price and Select button can sit cleanly
            in the compact mobile row.
        */
        display: contents;
    }

    .technical-offer-price {
        grid-column: 2;
        grid-row: 1;
        align-self: center;
    }

    .technical-offer-catnum {
        grid-column: 2;
        grid-row: 2;
        align-self: start;
    }

    .technical-offer-action {
        grid-column: 2;
        grid-row: 1 / span 2;
        align-self: right;
        width: 100%;
    }

    .technical-offer-action .product-card-actions,
    .technical-offer-action form {
        justify-content: stretch;
        width: 100%;
    }

    .technical-offer-action .product-card-actions button,
    .technical-offer-action .product-card-actions .button {
        width: 100%;
    }
}

/* =========================================================
   MOBILE TECHNICAL OFFER BORDER / BUTTON SHADOW FIX
   =========================================================

   Narrow technical tables are converted from a desktop table into stacked
   mobile model cards. Android/Chrome did not consistently paint the bottom
   border when the border lived on the converted table row. The reliable fix is
   to draw the mobile card outline on the actual stacked cells: first cell gets
   the top edge, every cell gets left/right edges, and the final cell supplies
   the bottom edge.

   Activity-log note:
   - This is presentation-only CSS.
   - Do not add activity-log entries for border/paint fixes.
   - Keep Select/modal/cart logging in product-options.js and CartController.
   ========================================================= */

@media (max-width: 700px) {
    .product-template-technical_table .technical-product-table tbody tr {
        /*
            Do not rely on borders applied to the converted table row. Some
            mobile browsers omit the row's bottom border after the row becomes
            a block-level stacked card. The child cells below provide the card
            outline instead.
        */
        border: 0;
        box-shadow: none;
        padding: 0;
        overflow: visible;
        background: #ffffff;
    }

    .product-template-technical_table .technical-product-table tbody tr > th,
    .product-template-technical_table .technical-product-table tbody tr > td {
        /*
            Draw the visible mobile card grid on cells rather than on the row.
            This makes the bottom edge reliable because the last cell owns it.
        */
        border-left: 1px solid #d6d6d6;
        border-right: 1px solid #d6d6d6;
        border-bottom: 1px solid #d6d6d6;
        padding: 4px 8px;
        overflow: visible;
    }

    .product-template-technical_table .technical-product-table tbody tr > th:first-child,
    .product-template-technical_table .technical-product-table tbody tr > td:first-child {
        border-top: 1px solid #d6d6d6;
    }

    .product-template-technical_table .technical-product-table td.technical-offer-cell {
        /*
            Keep offer rows compact. The button itself receives the small lower
            margin needed for its shadow, while the cell border supplies the
            visible bottom line.
        */
        padding-bottom: 8px;
    }

    .product-template-technical_table .technical-offer-action {
        padding-bottom: 0;
        overflow: visible;
    }

    .product-template-technical_table .technical-offer-action .product-card-actions,
    .product-template-technical_table .technical-offer-action form {
        overflow: visible;
    }

    .product-template-technical_table .technical-offer-action .button,
    .product-template-technical_table .technical-offer-action button {
        /*
            The button's box-shadow is drawn outside the button box. This
            margin reserves those pixels without stretching the whole card.
        */
        margin-bottom: 4px;
    }
}

/*
    Product group above-row labels.

    The database column remains product_group_items.row_note so existing saved
    values and migrations continue to work. Visually, that field now acts as a
    full-width label placed before the buying row it describes.

    Activity-log location:
        This is stylesheet-only presentation. Do not activity-log CSS rendering;
        keep logging on durable Product Group Admin saves and cart actions.
*/
.product-group-row-note-row--above .product-group-row-note--above {
    padding-top: 10px;
    padding-bottom: 0px;
    padding-left: 0px;
    border: none;

    color: #222222;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.25;
    text-align: left;
    white-space: normal;
    text-decoration: underline;
}

/* =========================================================
   MOBILE PORTRAIT TECHNICAL OFFER ROW FIX
   =========================================================

   Rod-family technical tables can render one offer column on phones, such as
   a single "Rod" offer row containing price, catalogue number, and Select.
   The broader mobile rule intentionally keeps offer rows compact, but on
   narrow portrait screens the Select button can occupy the same grid space as
   the price/catNum text.

   This narrow-screen override gives the offer row three explicit columns:
       1. the row label supplied by data-label, such as "Rod"
       2. the price and catalogue number
       3. a narrower Select button aligned to the right

   Desktop, tablet, and phone landscape layouts are left alone because this
   media query only targets the narrow portrait-style width where the overlap
   occurs.

   Activity-log note:
   - This is presentation-only CSS.
   - Do not add activity-log entries for this layout fix.
   - Select/modal/cart activity remains in product-options.js and CartController.
   ========================================================= */

@media (max-width: 520px) {
    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-cell {
        /*
            Preserve the existing mobile label column, then add a protected
            text column and a separate button column so price/catNum text and
            the Select button never occupy the same grid area.
        */
        grid-template-columns: 88px max-content minmax(0, 1fr);
        column-gap: 8px;
        align-items: center;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-cell::before {
        /* Keep the generated "Rod" / offer label aligned with the two-row value block. */
        grid-column: 1;
        grid-row: 1 / span 2;
        align-self: start;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-price {
        /* Keep the price visible to the left of the narrower right-side Select button. */
        grid-column: 2;
        grid-row: 1;
        min-width: 0;
        white-space: nowrap;
        z-index: 1;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-catnum {
        /* Keep the catalogue number directly beneath the price in the same protected column. */
        grid-column: 2;
        grid-row: 2;
        min-width: 0;
        white-space: nowrap;
        z-index: 1;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action {
        /*
            Move the Select control into its own right-side column. The button
            is still prominent, but no longer spans over the price/catNum text.
        */
        grid-column: 3;
        grid-row: 1 / span 2;
        justify-self: stretch;
        align-self: center;
        width: 100%;
        min-width: 0;
        max-width: 240px;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action .product-card-actions,
    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action form {
        /* Let the right-side grid column, not the form, determine the button width. */
        justify-content: stretch;
        width: 100%;
        min-width: 0;
    }

    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action .product-select-button,
    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action button,
    .product-template-technical_table .technical-product-table--multi-offer .technical-offer-action .button {
        /* Fill only the dedicated button column rather than the full value row. */
        width: 100%;
        min-width: 0;
    }
}

/* =========================================================
   PRODUCT GROUP IMAGE PLACEMENT OPTIONS
   =========================================================

   These layout classes are driven by product_groups.image_layout. The default
   image_top value keeps the existing rebuilt card surface unchanged. The side
   layouts are opt-in per Product Group so legacy-style wader/reel cards can be
   recreated without affecting normal cards elsewhere.

   Activity-log location:
       This is presentation-only CSS. Durable changes to image_layout are logged
       by ProductGroupAdminController after a successful Admin save.
   ========================================================= */
.product-group-card.product-card-has-image.product-card-image-layout-image-left-full,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary {
    display: grid;
    column-gap: 14px;
    row-gap: 6px;

    /*
        Keep the side-image rows packed to their real content height.

        Earlier side-image CSS forced the whole card to be at least as tall as
        the configured maximum image height. That protected tall images, but it
        also left large blank areas when the actual image was shorter or when a
        technical table sat below the image/description intro row. The intro row
        should instead be as tall as the larger of the actual image or the text.

        Activity-log location:
            This is presentation-only CSS. Do not activity-log browser layout;
            keep durable product/group layout changes logged in Product Group
            Admin where image_layout is saved.
    */
    align-content: start;
    align-items: start;
    min-height: 0;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary {
    grid-template-columns: minmax(135px, 32%) minmax(0, 1fr);
}

.product-group-card.product-card-has-image.product-card-image-layout-image-right-full,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary {
    grid-template-columns: minmax(0, 1fr) minmax(135px, 32%);
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full {
    grid-template-areas:
        "media text"
        "media body";
}

.product-group-card.product-card-has-image.product-card-image-layout-image-right-full {
    grid-template-areas:
        "text media"
        "body media";
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary {
    grid-template-areas:
        "media text"
        "body body";
}

.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary {
    grid-template-areas:
        "text media"
        "body body";
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image-link,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image-link,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image-link,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image-link {
    grid-area: media;

    /*
        Vertically centre the side photo against the neighbouring title and
        description block. The wrapper deliberately has no fixed/minimum height;
        the image's natural rendered height and the text's rendered height decide
        the row height together.
    */
    align-self: center;

    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 0;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-card-text-block,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-card-text-block,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-card-text-block,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-card-text-block {
    grid-area: text;

    /*
        Match the side-image wrapper above: when the image is taller, the text
        sits vertically centred beside it; when the text is taller, the image is
        centred beside the text. The buying rows/technical table remain in the
        body row below the intro area for the summary layouts.
    */
    align-self: center;
    min-width: 0;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-title,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-title,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-title,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-title {
    grid-area: title;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-description,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-description,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-description,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-description {
    grid-area: description;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .technical-table-wrap,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .technical-table-wrap,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .technical-table-wrap,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .technical-table-wrap {
    grid-area: body;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image {
    height: auto;
    min-height: 0;
    max-height: none;
    margin-bottom: 0;
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image img,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image img,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image img,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image img {
    width: auto;
    max-height: var(--catalogue-product-image-max-height, 340px);
}

.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-card-order-table,
.product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .technical-table-wrap,
.product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .technical-table-wrap {
    margin-top: 10px;
}

/*
    Keep the side-image layouts as a desktop enhancement only.

    On phones and other touch-width views, the original rebuilt card order is
    easier to read: image first, then title, then description, then the buying
    rows or technical table. The product-card markup already appears in that
    order, so this media query only removes the desktop grid and restores the
    normal vertical stack.

    Activity-log location:
        This is presentation-only CSS. Do not activity-log responsive layout
        changes. Durable Admin saves to product_groups.image_layout remain the
        only logged event for this setting.
*/
@media (max-width: 900px), (hover: none) and (pointer: coarse) {
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary {
        display: flex;
        flex-direction: column;
        column-gap: 0;
        row-gap: 0;
        min-height: 0;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image-link,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image-link,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image-link,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image-link {
        order: 0;
        width: 100%;
        min-height: 0;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-card-text-block,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-card-text-block,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-card-text-block,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-card-text-block {
        order: 1;
        align-self: stretch;
        width: 100%;
        min-width: 0;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-title,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-title,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-title,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-title {
        order: 1;

        /*
            Desktop side-image layouts use the title beside the image, but the
            mobile stack should look like the normal rebuilt card: image above
            a centered full-width title. Reset the width/alignment here so the
            title does not remain visually tied to the old side text column.
        */
        align-self: stretch;
        width: 100%;
        text-align: center;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-description,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-description,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-description,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-description {
        order: 2;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-card-order-table,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-card-order-table,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-card-order-table,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-card-order-table,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .technical-table-wrap,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .technical-table-wrap,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .technical-table-wrap,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .technical-table-wrap {
        order: 3;
        width: 100%;
        margin-top: 0;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image {
        height: 170px;
        margin-bottom: 8px;
    }

    .product-group-card.product-card-has-image.product-card-image-layout-image-left-full .product-image img,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-full .product-image img,
    .product-group-card.product-card-has-image.product-card-image-layout-image-left-summary .product-image img,
    .product-group-card.product-card-has-image.product-card-image-layout-image-right-summary .product-image img {
        max-height: 100%;
    }
}


/*
    Catalogue header image modal.

    This is a lightweight, page-header-specific modal for trusted catalogue
    header images. It intentionally does not depend on the Product Detail
    gallery DOM, because normal catalogue headers are stored as Admin-managed
    HTML/PHP content and are not full product galleries.

    Activity-log note:
        This is presentation-only CSS. Opening or closing a header image modal
        does not change cart, product, inventory, order, or admin data, so no
        activity logging is needed here. Durable header content saves remain
        logged from the Catalogue Page Contents Admin controller.
*/
.catalogue-header-modal[hidden] {
    display: none;
}

.catalogue-header-modal {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px;
}

body.catalogue-header-modal-open {
    overflow: hidden;
}

.catalogue-header-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.72);
}

.catalogue-header-modal-panel {
    position: relative;
    z-index: 1;
    box-sizing: border-box;
    max-width: min(96vw, 1100px);
    max-height: 92vh;
    padding: 18px;
    border-radius: 12px;
    background: #FFFFFF;
    box-shadow: 0 18px 45px rgba(0, 0, 0, 0.35);
    text-align: center;
}

button.catalogue-header-modal-close,
.catalogue-header-modal-close {
    /*
        This button must not inherit the global legacy pressed-button offset
        from ui.css, where button:active moves controls into their shadow.
        Keep all position values explicit so the X stays locked in place on
        hover, focus, and mousedown.
    */
    position: absolute;
    top: -14px;
    right: -14px;
    bottom: auto;
    left: auto;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    min-width: 34px;
    min-height: 34px;
    margin: 0;
    padding: 0;
    border: 2px solid #FFFFFF;
    border-radius: 999px;
    background: #213663;
    color: #FFFFFF;
    font: normal 700 26px/1 Arial, Helvetica, sans-serif;
    text-align: center;
    text-shadow: none;
    text-decoration: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transform: none;
}

button.catalogue-header-modal-close:hover,
button.catalogue-header-modal-close:focus,
button.catalogue-header-modal-close:active,
.catalogue-header-modal-close:hover,
.catalogue-header-modal-close:focus,
.catalogue-header-modal-close:active {
    top: -14px;
    right: -14px;
    bottom: auto;
    left: auto;
    background: #364B78;
    color: #FFFFFF;
    text-shadow: none;
    text-decoration: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    transform: none;
}

button.catalogue-header-modal-close:focus-visible,
.catalogue-header-modal-close:focus-visible {
    outline: 2px solid #FFFFFF;
    outline-offset: 2px;
}

.catalogue-header-modal-image {
    display: block;
    max-width: calc(96vw - 44px);
    max-height: calc(92vh - 80px);
    width: auto;
    height: auto;
    margin: 0 auto;
    border: none;
}

.catalogue-header-modal-caption {
    margin: 10px 0 0;
    color: #213663;
    font-weight: bold;
}

/*
    Salmon Fly catalogue tool link.

    Activity-log note:
    This is a public navigation shortcut only. The dynamic fly form logs only
    durable cart updates, not link display or clicks.
*/
.catalogue-tool-link {
    margin: 0 auto 14px;
    text-align: center;
}
