/* ===========================================================================
   [Flow 3] STONE FIRST -- the stone archive (3.1) and the stone PDP (3.2).

   Figma file Ex10uQ9OY3OuzSPi4g2hPb, section 14514:38982.
     3.1 Stone Search           14514:40723 (default) / 14514:40919 (selected)
     3.2 Stone PDP              14514:38983
     product card (phone)       14514:41709

   SCOPE AND OWNERSHIP
   -------------------
   Everything here is scoped to `#diamond_search.sf_archive` (the STANDALONE
   stone archive) or to `body.sf-stone-pdp` (the loose-stone product page).
   `.sf_archive` is printed by diamond-search.php only when the component is NOT
   mounting inside the ring-builder quiz, so the quiz's own advanced-search
   panel (#ssq_diamond_search, styled by components/ringbuilder/redesign/
   _advanced-search.css) is untouched by every rule below. The two surfaces
   render the same PHP and must not share styling -- that is the trap the flow
   analysis flagged as "the advanced search renders twice".

   BREAKPOINT
   ----------
   The board is drawn at 390. Everything that changes layout is inside
   `@media (max-width: 991px)`, which is the same breakpoint the rest of the
   diamond search uses to switch between the mobile and desktop rails. Above it
   the archive keeps the styling it shipped with -- this sheet must not regress
   desktop, so desktop gets only the additive nodes' own display rules.

   Versioned with filemtime() (da-general.php, enque_stone_first_archive), so
   it is self-busting and never needs a hand-bumped literal.
   =========================================================================== */

#diamond_search.sf_archive {
    /* Board tokens. Local copies rather than the ring-builder's --rb-* set:
       simple-select-redesign.css is not enqueued on the archive. */
    --sf-page:        #FAF3ED;   /* page ground                               */
    --sf-card:        #FFFFFF;   /* card surface                              */
    --sf-line:        #E4DED8;   /* hairline / unselected chip border         */
    --sf-green:       #27423B;   /* primary CTA, selected outline             */
    --sf-ink:         #0F0E0D;   /* primary text                              */
    --sf-ink-soft:    #3E3C39;   /* secondary text                            */
    --sf-crumb:       #202020;   /* breadcrumb                                */
    --sf-badge:       rgba(216, 221, 202, 0.30);   /* #D8DDCA @ 30%           */
    --sf-ls:          -0.21px;   /* board default letter-spacing              */
    --sf-gutter:      12px;      /* browse-screen page gutter (SPEC 1)        */
}

/* ===========================================================================
   1. TITLE BLOCK -- 14514:40723 `lab diamond` @12,141 366x81
   The count is the third line of the title block and scrolls away with it
   (note stamp "Page title + results - Scroll with parent"). It is NOT the
   sticky row; that is section 2.
   =========================================================================== */

/* The count lives inside .diamonds_search_header, which is a SIBLING section of
   #diamond_search -- so it cannot be reached through the .sf_archive scope.
   Gate it on the body classes the stone archives carry instead, and keep every
   declaration inside the mobile breakpoint so desktop is untouched. */
.sf_title_count {
    display: none;   /* desktop keeps its own .results_count rail */
}

@media (max-width: 991px) {
    body.page-template-diamonds_template section.diamonds_search_header,
    body.sf-stone-archive section.diamonds_search_header {
        padding: 12px 0 0 0;
        border-bottom: 0;
    }

    /* breadcrumb -- FG 400 12/30, ls -0.21, lower, #202020. The board
       underlines only the trailing (current page) segment; the leading "home"
       is a plain link. */
    /* The <a> is restated because main.css:1948 styles
       `nav.woocommerce-breadcrumb a` directly -- the link never inherits the
       nav's colour, so the nav read #202020 while `home` measured
       rgb(15,14,13). 3.1.2 is a single #202020 fill across the whole crumb;
       the ONLY override the board carries is textDecoration on the trailing
       segment. The desktop band already restates it (section 8b); this is the
       same declaration at <=991. */
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb,
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb a {
        font-family: 'FoundersGrotesk', sans-serif;
        font-style: normal;
        font-size: 12px;
        line-height: 30px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: lowercase;
        color: #202020;
        /* MEASURED: FoundersGrotesk's space glyph renders 1.80px at this 12px size
           (all three spaces in "Lab Grown Diamonds Search", via Range rects), and the
           -0.21px tracking shaves it further -- so the words read as run together.
           The spaces are real U+0020 and nothing was collapsing them; the glyph is
           just narrow, and dropping the crumb to the board's 12px is what made it
           show. This brings a word-space back to roughly the 3.3px it needs to read
           as a gap, without touching the size the board asks for. */
        word-spacing: 1.5px;
    }
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb span:last-child {
        text-decoration: underline;
    }
    /* SPACE THE SEPARATOR. The theme prints the crumb as
       <span>..</span>/<span>..</span> -- the "/" is a bare text node with no
       whitespace on either side, so at this size it read as "home/lab grown
       diamonds search" with the words run together. Nothing to do with the font or
       word-spacing (measured word-spacing: 0px, and there is no space character to
       space). The gap is put on the spans instead, which is also why it is scoped to
       this header and cannot reach the breadcrumb on any other template. */
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb > span:first-of-type {
        margin-right: 4px;
    }
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb > span + span {
        margin-left: 4px;
    }
    body.sf-stone-archive .diamonds_search_header .breadcrumbs {
        margin-bottom: 0;
    }

    /* page title -- Canela 300 24/19, ls -0.21, UPPER. The COPY is the site's
       own ("Pick a Lab Diamond"); only the type scale comes from the board --
       the heading text on these pages is SEO-load-bearing (see the H1 note in
       diamond-search.php) and is not a design decision. */
    body.sf-stone-archive section.diamonds_search_header .search_title h1,
    body.sf-stone-archive section.diamonds_search_header .search_title h3 {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 24px;
        /* Board 3.1.5 is Canela 300 24/**19** in a 24-tall box, and `lab diamond`
           14514:40855 is AL:VERTICAL gap=10 -- so the crumb block ends 10 above it
           and the count starts 1 below the 24-tall box. line-height was 26, which
           is neither number; the 5px that makes the box 24 is padding, not leading,
           and the count's own padding-top carries the remaining 1. */
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: #0F0E0D;
        /* The box is 24 and the LINE is 19, align LEFT/CENTER -- so the glyph
           sits 2.5px below the box top, not flush with it. The 5px used to be
           parked on the count's padding-top, which made the box 19 and lifted
           the glyph 2.5px against the breadcrumb (measured gap 10 vs board
           12.5). Put it back where the board has it: as the title box's own
           vertical padding. */
        padding: 2.5px 0;
        /* 16, NOT THE BOARD'S 10. Owner (Vartika, on the mobile capture):
           *"breadcrumbs and heading need space in between."*
           MEASURED at 390 before this: crumb block ends at y146, the title box
           starts at y156 -- the board's AL gap of 10 reproduced exactly, and
           read as stuffed once the count tightened up underneath it. 16 is the
           number I chose, not one I was given; it is the smallest step that
           reads as a deliberate gap beside the 4 below it. */
        margin: 16px 0 0 0;
    }

    /* "12,900 Results" -- FG 400 14/16, #3E3C39, left. Overrides every
       .results_count declaration the base sheet applies to the sticky rail. */
    body.sf-stone-archive p.results_count.sf_title_count {
        display: block;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 16px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #3E3C39;
        border: 0;
        /* Board 3.1.6 is a 16-TALL box (14/16) and `lab diamond` 14514:40855's
           inner column is AL gap=1 -- so one pixel above it and nothing below.
           The old 6/0/12 made the box 34 and the whole title block 93 against
           the board's 81, pushing the filter bar and the grid down by 12. */
        padding: 0;
        /* 4 ABOVE, 10 BELOW -- owner: *"results should be closer to the heading
           with maybe a 4px gap, and below results we still have padding like
           8-10px."*

           MEASURED at 390 before this: 1px above (the board's AL gap of 1) and
           0 below, which left the count welded to the heading and only 6px
           underneath it -- all of that 6 borrowed from the toolbar rather than
           declared here.

           4 above is the asked-for number outright. BELOW is 4, not 10, and the
           difference is not a typo: the toolbar row underneath is
           `.results_count.mobile_count`, whose own `padding: 6px 12px 8px`
           (MEASURED, computed) already puts 6px between the two. The margins do
           not collapse across it, so 10 here measured 16 on screen. 4 + its 6 =
           10, the top of the asked-for 8-10 band, and the number is written with
           its partner named so the next person does not "correct" it back. */
        margin: 4px 0 4px 0;
        text-align: left;
    }
    /* Until a real number lands the line would read as the bare word
       "Results". Nothing is invented -- the row is simply not drawn yet. */
    body.sf-stone-archive p.results_count.sf_title_count:not(.sf-has-count) {
        visibility: hidden;
    }

    /* The subhead paragraph is not on board 3.1. */
    body.sf-stone-archive .diamonds_search_header .page_subhead {
        display: none;
    }
}

/* ===========================================================================
   2. STICKY FILTER BAR -- 14514:40854, `Filter sticky bar` @12,239 366x40
   [ View 40 | All Stones / Shortlist 220 | Filters 89 ], gap 8.
   The container is the pre-existing .results_count.mobile_count row, which is
   already position:sticky in diamond-search.css. The board's note stamp
   "Sticks at top" pins to this row; the menu bar above it is the site header.
   =========================================================================== */

@media (max-width: 991px) {
    #diamond_search.sf_archive .results_count.mobile_count {
        display: block;
        background: var(--sf-page);
        border-bottom: 0;
        /* Board `filters` 14514:40853 pads 0/12/8/12 -- the bar is a 40-tall row
           with 8px of breathing room beneath it and nothing above. 6px is kept
           on top so the row does not touch the menu bar once it pins. */
        padding: 6px var(--sf-gutter) 8px var(--sf-gutter);
        /* The board pins this bar directly under the menu bar (note stamps
           14514:41119 + the 14514:41115 lasso, ELEMENTS 11). MEASURED at scroll
           1200: the live .header_main pins at y0 and is 61 tall, so 60 slid one
           pixel of the bar under it. */
        top: 61px;
        z-index: 6;
    }
    /* The count moved into the title block (section 1); this copy would be a
       second, sticky one the board does not draw. */
    #diamond_search.sf_archive .results_count.mobile_count > p {
        display: none;
    }

    /* 3.1.7 `filters` ends at 287 (row 239..279 + the frame's 8px pad-bottom) and
       3.1.22, the results column, starts at 293 -- a 6px gap the bar had none of.
       MEASURED: bar bottom 263, first card 263. */
    #diamond_search.sf_archive .search_results_grid_container {
        padding-top: 6px;
    }

    #diamond_search.sf_archive .search_view_options {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 8px;
        width: 100%;
        position: static;
    }

    /* --- the 40x40 view button -------------------------------------------
       The board draws ONE 40x40 box (14514:40855) carrying the 4-square grid
       glyph, whose ON_CLICK swaps the component to the list variant. The live
       markup has TWO buttons and diamond-search.js:2548 activates whichever one
       is clicked -- clicking the already-active one is a no-op. So only the
       ACTIVE one is drawn (its glyph is the current view, exactly as the board
       renders it) and stone-first.js forwards its click to its hidden sibling.
       Both nodes stay in the DOM and keep their own handlers. */
    #diamond_search.sf_archive .search_view_options .result_view {
        display: none;
        width: 40px;
        min-width: 40px;
        height: 40px;
        margin: 0;
        padding: 0;
        border: 1px solid var(--sf-line);
        border-radius: 4px;
        background: var(--sf-page);
        align-items: center;
        justify-content: center;
        cursor: pointer;
        order: 1;
    }
    #diamond_search.sf_archive .search_view_options .result_view.active {
        display: flex;
    }
    #diamond_search.sf_archive .search_view_options .result_view svg {
        width: 16px;
        height: 16px;
    }
    #diamond_search.sf_archive .search_view_options .result_view svg path,
    #diamond_search.sf_archive .search_view_options .result_view svg rect {
        fill: var(--sf-green);
        stroke: none;
    }
    /* 3.1.10 -- `Frame 38317` is a 16x16 box, AL:VERTICAL gap=3, two 16x6.5 rows
       each AL:HORIZONTAL gap=3, four 6.5x6.5 #27423B squares. The shared theme
       asset icons/grid-button.svg is a 26x24 viewBox with 11x10.5 rects; squashed
       into 16x16 it renders NON-SQUARE tiles at a ~1.9px cross gap --
       MEASURED 6.77x6.46 on a pitch of 8.61 x 8.3 against the board's 6.5x6.5 on
       9.5 x 9.5. The asset is shared with the desktop toolbar and the quiz, so it
       is not edited; the board's own geometry is drawn here instead, inside the
       archive scope, and only for the GRID variant -- the list variant has no
       board drawing. */
    #diamond_search.sf_archive .search_view_options .grid_results_view > svg {
        display: none;
    }
    #diamond_search.sf_archive .search_view_options .grid_results_view::before {
        content: '';
        display: block;
        width: 16px;
        height: 16px;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='6.5' height='6.5' fill='%2327423B'/%3E%3Crect x='9.5' width='6.5' height='6.5' fill='%2327423B'/%3E%3Crect y='9.5' width='6.5' height='6.5' fill='%2327423B'/%3E%3Crect x='9.5' y='9.5' width='6.5' height='6.5' fill='%2327423B'/%3E%3C/svg%3E");
        background-size: 16px 16px;
        background-repeat: no-repeat;
    }

    /* --- segmented All Stones | Shortlist -- 220x40 r8 ------------------- */
    #diamond_search.sf_archive .sf_segmented {
        order: 2;
        display: flex;
        flex: 1 1 auto;
        min-width: 0;
        height: 40px;
        border: 1px solid var(--sf-line);
        border-radius: 8px;
        background: var(--sf-page);
        overflow: hidden;
    }
    #diamond_search.sf_archive .sf_seg {
        flex: 1 1 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 4px;                 /* 3.1.16 `shortlist` is AL:HORIZONTAL gap=4 */
        height: 38px;
        margin: 0;
        padding: 0 4px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        color: var(--sf-green);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 18px;
        letter-spacing: -0.5px;   /* tab labels are the -0.5 exception, SPEC 1 */
        text-decoration: none;
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive .sf_seg.is-active {
        background: var(--sf-green);
        color: var(--sf-page);
        /* track r8 with a 1px INSIDE stroke, so the half it holds is inset by 1
           and must not curve away from it -- 14684:49180 is r6 inside a r8
           track. The shared rule in settings-picker.css says the same thing;
           this scope outranks it, so it has to say it too. */
        border-radius: 6px;
    }
    #diamond_search.sf_archive .sf_seg[disabled] {
        opacity: 0.45;
        cursor: default;
    }
    #diamond_search.sf_archive .sf_seg_icon {
        display: inline-flex;
        width: 13px;
        height: 12px;
        color: currentColor;
    }

    /* --- Filters pill -- 89x40 r8, green ground -------------------------- */
    /* SPEC 3.1.3 item 3: the `Filter` instance is 89x40 -- and the board draws
       it 89 wide WITH the count pill showing "3", so the pill cannot be taking
       layout space. It is drawn OVER the right end of the button. Laid out in
       flow (which is what this used to do) the button grew to 100 the moment a
       filter was applied, 11px past the board. Fixed width + an out-of-flow
       badge keeps it 89 in both states. */
    #diamond_search.sf_archive .sf_filters {
        order: 3;
        position: relative;
        display: flex;
        align-items: center;
        gap: 4px;                 /* 3.1.18 is AL:HORIZONTAL gap=4, not 6 */
        height: 40px;
        width: 89px;              /* board 14514:40861 is 89x40, badge or not */
        flex: 0 0 89px;
        justify-content: center;
        margin: 0;
        padding: 0 8px;
        border: 1px solid var(--sf-green);
        border-radius: 8px;
        background: var(--sf-green);
        color: var(--sf-page);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive .sf_filters_group {
        display: inline-flex;
        align-items: center;
        gap: 4px;
    }
    #diamond_search.sf_archive .sf_filters_icon {
        display: inline-flex;
        width: 11px;
        height: 11px;
    }
    #diamond_search.sf_archive .sf_filters_icon svg {
        width: 11px;
        height: 11px;
    }
    #diamond_search.sf_archive .sf_filters_icon svg path {
        stroke: var(--sf-page);
        fill: none;
    }
    #diamond_search.sf_archive .sf_filters_badge {
        position: absolute;
        right: 4px;
        top: 8px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 24px;
        height: 24px;
        border-radius: 50px;
        background: var(--sf-badge);
        color: var(--sf-page);
        font-size: 12px;
        line-height: 19px;
    }
    /* The badge is out of flow, so the label would sit under it. Shift the
       icon+label group left by half the pill once the pill is actually drawn. */
    #diamond_search.sf_archive .sf_filters:has(.sf_filters_badge:not(.is-empty)) .sf_filters_group {
        transform: translateX(-12px);
    }
    /* Zero selected filters -> no badge at all. The board's "3" is sample data. */
    #diamond_search.sf_archive .sf_filters_badge.is-empty {
        display: none;
    }

    /* Board 3.1 has no floating Filters pill at the foot of the page -- the
       Filters control lives in the sticky bar. #search_filters_mobile's own
       toggle is still the DRAWER HEADER once the drawer is open (Reset /
       Filters / close), so it is hidden only in the closed state. The pill
       triggers this node, and jQuery .trigger() fires handlers on hidden
       elements, so the drawer still opens. */
    body.sf-stone-archive #search_filters_mobile:not(.opened) .filters_mobile_toggle {
        display: none;
    }

    /* --- sort ------------------------------------------------------------
       The board's filter bar has no sort control. Sorting is real behaviour and
       is not being dropped: stone-first.js moves .diamond_sort_by into the
       filter drawer (where the board puts every other refinement), and the
       element keeps the handlers diamond-search.js:133 bound directly to it. */
    #diamond_search.sf_archive .search_view_options .diamond_sort_by {
        display: none;
    }
    /* THE SORT CONTROL IS THE DRAWER'S, NOT THE OLD FULL-BLEED ROW.
       Owner: *"filters is old design on phone -- the Sort by buttons and stuff
       must be the same as the BYR one."*

       MEASURED at 390, the two sheets differed in exactly one control. The
       drawer's is a card: 346 x 45 at a 22px inset, fill #FDFAF8, r4, label
       `Sort by` / `Price (Low to high)` at 15/19 #3E3C39. The archive's was the
       legacy row -- full 390 bleed, 57 tall, no ground, a hairline under it --
       which is what read as the old design. Everything else in the sheet (the
       shape chips, the groups, their order) already matched chip for chip.

       Stated with the drawer's own numbers, and 346 as a min() so it shrinks
       with the viewport the way every other 390-authored box in this flow
       does. */
    #diamond_search .search_filters .diamond_sort_by {
        display: flex;
        align-items: center;
        position: relative;
        box-sizing: border-box;
        width: min(346px, calc(100vw - 44px));
        height: 45px;
        margin: 12px auto;
        padding: 0 12px;
        background: #FDFAF8;
        border: 0;
        border-radius: 4px;
        justify-content: space-between;
    }
    /* `Sort by:` and the value are one <p> in the markup and ran together --
       `Sort by:Price (Low to high)` -- while the drawer sets them as a label and
       a value with the chevron pushed to the far edge. Same three declarations
       get it: the row separates its two ends above, the label and value get a
       gap, and the colon the markup carries is dropped by collapsing it out of
       the flow rather than editing shared PHP. */
    #diamond_search .search_filters .diamond_sort_by > p {
        display: flex;
        align-items: center;
        gap: 6px;
        margin: 0;
        font-size: 15px;
        line-height: 19px;
        color: var(--sf-ink, #3E3C39);
    }
    #diamond_search .search_filters .diamond_sort_by > p > span {
        color: #0F0E0D;
    }
    /* `Sort by` is the label, the value is the answer, and the chevron belongs
       to the far edge -- the drawer sets all three apart and the archive ran
       them together. stone-first.js wraps the leading text node so there is
       something to style. */
    #diamond_search .search_filters .diamond_sort_by > p {
        flex: 1 1 auto;
        width: 100%;
    }
    #diamond_search .search_filters .diamond_sort_by > p > .sf_sort_prefix {
        font-style: italic;
        color: var(--sf-ink, #3E3C39);
    }
    #diamond_search .search_filters .diamond_sort_by > p > svg {
        margin-left: auto;
        flex: none;
    }
    #diamond_search .search_filters .diamond_sort_by > p {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        color: var(--sf-ink);
    }
}

/* ===========================================================================
   3. RESULT GRID AND THE STONE CARD -- 14514:40723 `Frame 1171276663`
   Rows: horizontal wrap, gap 12, padding 0/12 -> two 177-wide cards.
   Card 177x300: image 177x160 (FILL, no inset), text block 140.
   =========================================================================== */

@media (max-width: 991px) {
    /* The grid sits at the bottom of a four-deep Bootstrap chain, each level of
       which adds a 12px gutter or a -12px row margin:
         .search_container.col-12 (pad 12) > .diamond_search_results
         > .search_content.row (margin -12) > .search_results_grid_container.col-12
         (pad 12) > .search_results_grid.row
       That left the grid's content box 341 wide, so two 177 cards plus the 12
       gap (366) could not share a line and every row rendered one-up. The chain
       is flattened to a single 12px gutter -- the board's -- and the card width
       is then a percentage of it, which keeps working at any viewport. */
    #diamond_search.sf_archive .search_container,
    #diamond_search.sf_archive .search_results_grid_container {
        padding-left: 0;
        padding-right: 0;
    }
    /* THE MISSING PIXEL. .search_container carries a 1px left border -- the
       desktop divider between the filter rail and the results column. On mobile
       there is no rail, so the border only pushed the whole results column to
       x=1 and squeezed it to 389, which made every left card land at x=13
       against the board's 12 and every card 176.5 wide instead of 177.
       MEASURED: .diamond_search_results offsetLeft 1, borderLeftWidth 1px on
       its parent. */
    #diamond_search.sf_archive .search_container {
        border-left: 0;
    }
    #diamond_search.sf_archive .search_content.row {
        margin-left: 0;
        margin-right: 0;
    }
    /* The list view shares the flattened chain above, so it needs the 12px
       gutter putting back explicitly -- it used to inherit it from
       .search_container's Bootstrap padding. */
    #diamond_search.sf_archive .search_header,
    #diamond_search.sf_archive .search_results {
        padding-left: var(--sf-gutter);
        padding-right: var(--sf-gutter);
    }
    #diamond_search.sf_archive .search_results_grid {
        row-gap: 12px;
        column-gap: 12px;
        /* The bottom is one row-gutter, the same 12 this grid puts between its
           own rows. MEASURED before: the grid's bottom edge and the last card's
           bottom were the same number -- the run ended flush against whatever
           follows it. Same correction the in-quiz grid got in
           _advanced-search.css; this mount was missed, and it is the one the
           owner was looking at. Sides stay on `--sf-gutter`. */
        padding: 0 var(--sf-gutter) 12px;
        margin: 0;
    }
    #diamond_search.sf_archive .search_results_grid > .result_grid_item_container {
        width: calc((100% - 12px) / 2);
        max-width: calc((100% - 12px) / 2);
        flex: 0 0 calc((100% - 12px) / 2);
        padding: 0;
        margin: 0;
    }
    /* CARD HEIGHT IS FIXED -- board card 177x300 (image 177x160 + a FIXED
       177x140 text block), row pitch 312. It used to be content-driven, so a
       spec line that wrapped ("Signature Ideal Cut - D - VS1" against
       "Excellent Cut - D - VVS2", both real inventory on page 1) made the card
       292.55 or 308.55 and the measured pitch 320.5. The 140 is held by the
       title block absorbing the slack, so a wrapped spec line shortens the
       title area instead of growing the card. */
    #diamond_search.sf_archive .result_grid_item {
        position: relative;
        display: flex;
        flex-direction: column;
        height: 300px;
        background: var(--sf-card);
        border-radius: 4px;
        overflow: hidden;
        /* 14514:40919: the selected card gains a 2px OUTSIDE stroke. Drawn as a
           box-shadow so it cannot change the card's box and reflow the row. */
        box-shadow: 0 0 0 0 transparent;
        transition: box-shadow .12s linear;
    }
    #diamond_search.sf_archive .result_grid_item_container.active .result_grid_item {
        box-shadow: 0 0 0 2px var(--sf-green);
    }

    /* IMAGE FILLS THE CONTAINER -- product-card note 14514:41732, verbatim:
       "Image / Fill container". The base sheet uses object-fit: contain inside
       a padded column, which letterboxes every stone photo. */
    #diamond_search.sf_archive .result_grid_img {
        position: relative;
        width: 100%;
        height: 160px;
        flex: 0 0 160px;
        aspect-ratio: auto;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }
    #diamond_search.sf_archive .result_grid_img > a {
        display: block !important;   /* base sheet ships display:contents inline */
        width: 100%;
        height: 100%;
    }
    #diamond_search.sf_archive .result_grid_img img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: center;
    }

    /* text block -- 177x140, vertical gap 8, padding 12 / 6..8, centred */
    /* The title block is the elastic one. diamond-search.js:1442 stamps an
       INLINE height on every .grid_result_title on the page (a whole-grid
       equalise pass that the quiz needs), so `!important` is the only way to
       hand the slack back to flexbox here without touching that file. */
    /* THE TEXT BLOCK IS CENTRED AS A GROUP. 3.1.31 is AL:VERTICAL gap=8
       pad=12/8/12/8 al=CENTER/CENTER, so for a 2-line title the three lines
       land at +24..66 / +74..92 / +100..116 from the block's top
       (12 pad + 42 + 8 + 18 + 8 + 16 + 12 pad = 116 in a 140 box, the 24 of
       slack split 12/12 by the CENTER alignment).
       It used to be the TITLE that absorbed the slack (`flex: 1 1 auto` +
       align-items:center), which measured title +25..67 but spec +88..104 and
       price +112..128 -- a 21px title->spec gap where the board draws 8, with
       the spec 14 low and the price 12 low on every card. The auto margins put
       the slack back on the OUTSIDE of the group, where the board has it. */
    #diamond_search.sf_archive .result_grid_item > .grid_result_title {
        margin: auto 0 0 0;
        padding: 12px 8px 0 8px;   /* 3.1.31 pad 12/8/12/8 -- B16 */
        height: auto !important;
        min-height: 0;
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
    }
    /* THREE LINES, NOT TWO -- AND THAT IS A NATURAL-DIAMOND BUG, NOT A TASTE
       CALL. Owner: *"advanced natural diamond search is old, the product cards
       and all -- fix it properly, like how lab diamond searches are."*

       The clamp was written off a board card whose title is
       `0.50 CARAT ROUND LAB DIAMOND`, which sets in two lines at 390. Every
       NATURAL title is one word longer -- `0.50 CARAT ASSCHER NATURAL DIAMOND`
       -- so it wants three, and at a clamp of 2 the browser ellipsised it
       mid-word: MEASURED at 390 on /natural-diamonds/, the `<a>` renders 60px
       tall (3 x 21 line boxes) inside a 54px title box, and the card read
       `0.50 CARAT ASSCHER NATURA...`. Nothing was wrong with natural's cards
       that was not also one word away from being wrong on lab's -- the lab
       grid clips too the moment a title reaches three lines, which it does on
       `0.50 CARAT PRINCESS LAB DIAMOND`, visible in the same screenshot.

       So the clamp goes to 3 rather than being removed: it is still a guard
       against a pathological title running the card away, it just stops firing
       on the ordinary case. The title box is already `height: auto !important`
       and `flex: 0 0 auto`, so the extra line is handed to the card and the
       grid row equalises, which is why no height needs restating here.

       Desktop never had this: the >=992 block sets no clamp at all. */
    #diamond_search.sf_archive .result_grid_item > .grid_result_title > p {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    #diamond_search.sf_archive .result_grid_item > .grid_result_info,
    #diamond_search.sf_archive .result_grid_item > .grid_result_price {
        flex: 0 0 auto;
    }
    #diamond_search.sf_archive .result_grid_item p {
        margin: 0;
        padding: 0;
    }
    /* title -- Canela 300, UPPER, ls -0.21, centred, line-height 21.
       Size is 21 on one line and 18 once it wraps (note 14514:41732). CSS has
       no "18 if it wraps" form, so stone-first.js measures the rendered line
       count and stamps .sf-title-wrapped; 21px is the resting size. */
    #diamond_search.sf_archive .grid_result_title a {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 21px;
        line-height: 21px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: var(--sf-ink);
        text-decoration: none;
    }
    #diamond_search.sf_archive .grid_result_title.sf-title-wrapped a {
        font-size: 18px;
    }
    /* 3.1.33: the spec line is a FG 400 16/16 glyph in an 18-TALL box. The
       18 is the box, the 16 is the leading -- expressed here as an 18px line
       box around the 16px face, which puts the ink where the board puts it. */
    #diamond_search.sf_archive .grid_result_info {
        padding: 8px 8px 0 8px;
    }
    #diamond_search.sf_archive .grid_result_info p {
        line-height: 18px;
    }
    #diamond_search.sf_archive .grid_result_info p,
    #diamond_search.sf_archive .grid_result_price p {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: var(--sf-ink);
    }
    #diamond_search.sf_archive .grid_result_price {
        padding: 8px 8px 12px 8px;
        margin: 0 0 auto 0;   /* the second half of the centred group */
    }

    /* The board's stone card carries NO CTA -- picking a card outlines it and
       raises the sticky bar (14514:40919). The card's own "Add to Ring" button
       is not deleted: it is the real commit handler and the sticky bar re-homes
       it (section 4). "Purchase Loose" has no slot on 3.1 and is not drawn --
       it is still offered on the stone PDP and in the side cart. */
    #diamond_search.sf_archive .result_grid_item .grid_result_button {
        display: none;
    }

    /* A tap anywhere on the card selects it. The title and the image keep their
       own anchors (they open 3.2), so the hit area for SELECT is the rest. */
    #diamond_search.sf_archive .result_grid_item {
        cursor: pointer;
    }
}

/* ===========================================================================
   4. STICKY CTA BAR -- 14514:40919 `ctas` @0,2083 390x178
   Raised only while a card is selected. Buttons 370 wide (10px gutters).
   =========================================================================== */

/* HIDDEN AT EVERY WIDTH BY DEFAULT. This used to live inside the mobile media
   query below, which meant desktop had no rule at all -- and since the JS drops the
   `hidden` attribute unconditionally, the bar fell back to being three native
   buttons in the page flow. MEASURED at 992, 1280 and 1728 on both stone archives:
   the CTAs rendered under the filter rail at y~1575. The bar is a MOBILE component
   (14514:40919 is a 390 frame); it has no desktop design, so its default is `none`
   at all widths and only the mobile query may raise it. */
#diamond_search.sf_archive .dsq_sticky_ctas[hidden],
#diamond_search.sf_archive .dsq_sticky_ctas {
    display: none;
}

@media (max-width: 991px) {
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas,
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 40;
        flex-direction: column;
        gap: 12px;
        padding: 12px 10px 10px 10px;
        background: var(--sf-page);
        /* NO TOP RULE. Board `ctas` 14514:40919 is a solid #FAF3ED fill with no
           stroke and no effect -- the bar meets the grid with nothing drawn
           between them. The 1px #E4DED8 hairline that used to sit here was an
           addition to the board, not a reading of it. */
    }

    /* The primary CTA is a PROXY: it triggers the selected card's own
       button.grid_add_to_ring (stone-first.js). The real button is NOT moved --
       diamond-search.js:1685 finds its row with
       $(this).parents('.result_grid_item_container'), so lifting it out of the
       card would break the commit it exists to perform. */
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_add_to_ring,
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_secondary {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 100%;
        height: 44px;
        padding: 14px 0;
        border-radius: 4px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_add_to_ring {
        order: 1;
        width: 100%;
        border: 1px solid var(--sf-green);
        background: var(--sf-green);
        color: var(--sf-page);
    }
    /* Trailing arrow -- 14514:40921, a 12-wide vector at 1.25px. */
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_arrow {
        display: inline-flex;
        width: 12px;
        height: 10px;
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_secondary {
        order: 2;
        border: 1px solid var(--sf-green);
        background: var(--sf-page);
        color: var(--sf-green);
    }
    /* "Talk to a gemologist" -- board `Frame 1171276227` is a 370x44 VERTICAL
       wrapper with counterAxisAlignItems:CENTER holding a 346x28 text node, NOT
       a bare 28-tall line. 12 + 44 + 12 + 44 + 12 + 44 + 10 = 178, which is the
       bar's height; drawing this row at 28 is the whole 16px deficit. */
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_link {
        order: 3;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 44px;
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--sf-green);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-decoration: underline;
        text-transform: none;
    }
    /* SCROLL COMPENSATION IS THE DOCUMENT'S, NOT THE COLUMN'S -- see the
       `body.sf-selection-open` rule at the foot of this sheet. Padding
       .search_container only pushed the grid off the bar; the site footer is a
       sibling of #diamond_search and stayed underneath it. Keeping both would
       double the gap to 356 at 390. */
}

/* ===========================================================================
   5. PROMO INSERT ("gems" merch band) -- 14514:40802 @0,1543 390x336

   The board's band is a COMPOSITE, not a photo: an IMAGE ground with a
   #142037 @80% scrim over it, a Canela headline, a Founders Grotesk subhead, a
   bleeding strip of five 110x110 setting tiles, and an outlined CTA. The ACF
   insert on this site is configured as `photo` (a bare <img>), so the photo
   becomes the GROUND and stone-first.js composes the other five elements over
   it. Nothing here invents imagery: the ground is the site's own art and the
   strip is the store's own engagement-ring thumbnails, handed to the script by
   da-general.php (sf_merch).

   COPY. The two type lines are the board's own characters. The CTA label is
   the board's rendered characters too ('BROWSE  SETTINGS'); the layer is NAMED
   `BROWSE HANDPICKED STONES`, which SPEC B8 flags as an unresolved conflict --
   the rendered string is what the board draws and what the headline argues
   for, so that is what ships, and the conflict is reported rather than hidden.
   =========================================================================== */

@media (max-width: 991px) {
    #diamond_search.sf_archive .search_results_grid > .col-12:has(> .grid_promo),
    #diamond_search.sf_archive .search_results_grid > .sf_insert_row {
        width: 100vw;
        max-width: 100vw;
        flex: 0 0 100vw;
        margin-left: calc(var(--sf-gutter) * -1);
        padding: 0;
    }
}

/* DESKTOP -- the board gives NOTHING for this band above 390 (ELEMENTS 14.2.2).
   What it must not do is what it did: with every composite rule locked inside
   the mobile query, at 1728 the band fell back to a raw <img> followed by five
   stacked 110px tiles -- MEASURED .sf_merch_strip 703x3516. The composition is
   width-independent (full-bleed ground, scrim, a 246-wide centred copy column, a
   centred bleeding tile strip, a 246 CTA), so it is carried up unchanged and the
   row is made a full-width band in the results column instead of a grid cell.
   That carry-over is an IMPLEMENTER DECISION, not a design fact -- recorded here
   so the next pass does not read it as one. */
@media (min-width: 992px) {
    #diamond_search.sf_archive .search_results_grid > .col-12:has(> .grid_promo),
    #diamond_search.sf_archive .search_results_grid > .sf_insert_row {
        width: 100%;
        max-width: 100%;
        flex: 0 0 100%;
        margin-left: 0;
        padding: 0;
    }
}

/* The composite itself -- drawn at every width. */
    /* 336 tall, fixed. diamond-search.js:1462 stamps an INLINE height on
       `.grid_promo.insert_photo` equal to the previous row's card height (312
       here), so `!important` is what holds the board's number without editing
       the render loop. */
    /* The ROW keeps the board's 336 and clips; the composite inside is drawn
       60px taller and slid within that window by stone-first.js (note stamp
       `Slow scroll`). Parallaxing the row's own box instead would overlap the
       grid rows 14px above and below it. */
    #diamond_search.sf_archive .sf_insert_row {
        height: 336px;
        overflow: hidden;
        /* 3.1.22 `Frame 1171276706` is AL:VERTICAL gap=**14** while 3.1.23 (rows
           1-4) is gap=12 -- so the band meets the grid at 14 on BOTH sides, not
           at the grid's own 12. Board: row 4 ends 1529, band 1543, band ends
           1879, row 5 at 1893. The flex row already contributes 12, and g-3 was
           adding 16 on top of it above the band and nothing below. */
        margin-top: 2px;
        margin-bottom: 2px;
    }
    /* THE GROUND IS THE BOARD'S, NOT THE ACF PHOTO -- 14641:48005 / 14514:40802
       Owner: *"the background is differing [on] the blue banner ... there's a
       translucent couple right now. This is for the category page banner."*

       Both frames declare the SAME two fills on the band itself, phone and
       desktop: an IMAGE fill (ref 594df19a...) at scaleMode FILL, with the
       #142037 @80% scrim over it. That image is a flat teal plaster TEXTURE --
       verified by downloading it and by rendering the frame: scrimmed, it is
       the deep navy wall the board draws, with no photograph in it at all.

       What the site had under the scrim was the merchandiser's ACF photo, and
       at 20% of its own opacity a photographed couple reads as a ghost behind
       the type -- which is the "translucent couple". The ground is now the
       board's texture and the ACF <img> is taken out of the paint.

       Shipped at 1200x801 / q35, 158KB. The scrim lets only 20% of this image
       through, so detail and resolution past this point cannot be seen: the
       scrimmed mean (23,46,66) matches the board's rendered ground, and
       encoding it any heavier only costs bytes. SCOPED TO THIS BAND -- the
       drawer's `.sf_gems` has its own ground and is deliberately untouched. */
    #diamond_search.sf_archive .sf_insert_row .grid_promo {
        position: relative;
        top: -30px;
        height: 396px !important;
        overflow: hidden;
        background: #142037 url("../../assets/media/banners/gems-band-ground.webp") center / cover no-repeat;
        will-change: transform;
    }
    /* Hidden rather than deleted: the <img> is the ACF insert's own field and
       the merchandiser still owns it. Dropping this one rule puts their art
       back as the ground. */
    #diamond_search.sf_archive .sf_insert_row .grid_promo > img {
        display: none;
    }
    /* #142037 @ 80% over the ground. */
    #diamond_search.sf_archive .sf_insert_row .sf_merch_scrim {
        position: absolute;
        inset: 0;
        background: rgba(20, 32, 55, 0.80);
    }
    /* The composite is laid out against the board's 336, centred in the 396 the
       slow-scroll window needs. The SCRIM stays inset:0 over the whole 396 so
       no unscrimmed ground can slide into view. */
    #diamond_search.sf_archive .sf_insert_row .sf_merch {
        position: absolute;
        left: 0;
        right: 0;
        top: 30px;
        bottom: 30px;
        display: flex;
        flex-direction: column;
        align-items: center;
        /* Board head is 246x58 @1583 (ends 1641) and the subhead is @1643. */
        gap: 2px;
        padding: 40px 72px;
    }
    /* `NOT READY TO PICK A DIAMOND?` @72,1583 246x58 -- Canela 300 24/28.8,
       ls 0 (the merch band is one of the three ls-0 exceptions, SPEC 1). */
    #diamond_search.sf_archive .sf_insert_row .sf_merch_head {
        width: 246px;
        margin: 0;
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 24px;
        line-height: 28.8px;
        letter-spacing: 0;
        text-transform: uppercase;
        color: #E4DED8;
        text-align: center;
    }
    /* `Let the design inspire the diamond.` @72,1643 246x19 */
    #diamond_search.sf_archive .sf_insert_row .sf_merch_sub {
        width: 246px;
        margin: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19.04px;
        letter-spacing: 0;
        color: #FAF3ED;
        text-align: center;
    }
    /* `settings` strip @0,1672 390x110 -- five 110x110 tiles at gap -3, the row
       bleeding past BOTH edges (board x = -74, 33, 140, 247, 354). Absolute so
       it can leave the 72px padding column the copy sits in. */
    /* `settings` strip 3.1.39 is `@0,1672 390x110 AL:HORIZONTAL gap=-3
       al=CENTER/CENTER clip` -- five 110-wide tiles = 538 CENTRED in the band,
       which is what puts the first tile at x -74 and the last past x 464. It is
       centring plus a clip, not a hand-placed offset, so it is written that way:
       the same two declarations reproduce the board at 390 and stay sane above
       it. (Was left:-74 / width:100vw+148, which only held at 390.) */
    #diamond_search.sf_archive .sf_insert_row .sf_merch_strip {
        position: absolute;
        left: 0;
        right: 0;
        top: 159px;              /* (1672 - 1543) + the 30px slow-scroll inset */
        display: flex;
        justify-content: center;
        gap: 0;
        height: 110px;
        pointer-events: none;
    }
    #diamond_search.sf_archive .sf_insert_row .sf_merch_strip img {
        width: 110px;
        height: 110px;
        flex: 0 0 110px;
        object-fit: contain;
        margin: 0 -1.5px;        /* itemSpacing -3 */
        /* The white ground is removed from the PIXELS by stone-first.js's
           knockoutTile(), not by a filter here -- see that function for why the
           CSS routes (feColorMatrix, every blend mode) cannot do it. */
    }
    /* CTA @72,1792 246x47 -- transparent, 1px inside #FAF3ED, r4. */
    /* CTA 3.1.41 `@72,1792 246x47` -- 246 centred in 390, exactly like the copy
       column above it (both are children of a CENTER/CENTER auto-layout). Written
       as centring rather than left:72 so it holds at the desktop band width too. */
    #diamond_search.sf_archive .sf_insert_row .sf_merch_cta {
        position: absolute;
        left: 0;
        right: 0;
        margin-left: auto;
        margin-right: auto;
        top: 279px;              /* (1792 - 1543) + the 30px slow-scroll inset */
        display: flex;
        align-items: center;
        justify-content: center;
        width: 246px;
        height: 47px;
        padding: 14px 0;
        border: 1px solid #FAF3ED;
        border-radius: 4px;
        background: transparent;
        color: #FAF3ED;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        text-decoration: none;
        white-space: pre;
    }

/* ===========================================================================
   5b. CARD HEART -- board stone card overlay row, right-hand item.
   `Heart` 16x15: `default` = outline 1px #3E3C39, `loved` = filled #C65858
   with a matching stroke. Drawn on every card in both 40723 and 40919.

   The control is NOT new behaviour: main.js:1040 already owns
   `.productFavorite` and, for the `.summary_container` shape, reads the id off
   the node's own data-id -- so a card heart carrying the stone's post id
   commits to the same `da_wishlist` store the header count and the Shortlist
   tab read. Without it the filter bar offered a Shortlist view with no way to
   put anything into it.
   =========================================================================== */

/* THE HEART IS NOT MOBILE-ONLY. Both 3.1 frames draw it on every card, and the
   Shortlist tab is offered at every width -- hiding the only control that can
   fill it above 991 left desktop with a filter nothing could satisfy. The base
   state is a parked, not a removed, node: ELEMENTS 14 requires that a node the
   JS reads is never display:none, so it is hidden by visibility and re-shown
   with the rest of the card treatment. */
/* A <button> WITH NO RESET IS A UA BUTTON -- the same fault as the gemologist
   link. MEASURED at 1728 against a usual product card's heart:
     stone card   background rgb(239,239,239), border 2px   <- Chrome's own chrome
     usual card   background transparent,      border 0
   The usual one is a <div>, so it never had this; this one is a <button>
   (deliberately -- it is a control, and `productFavorite summary_container` plus
   data-id is the contract that makes main.js read the id off the node instead of
   walking up to an <li> this grid does not have). So it keeps being a button and
   stops LOOKING like one. */
#diamond_search.sf_archive .sf_card_heart {
    visibility: visible;
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    line-height: 0;
    color: inherit;
    cursor: pointer;
}
/* The glyph is the board's 16x15, but 16x15 is not a tap target -- the usual
   product card's heart gives 60x40. The hit area is grown with a pseudo-element
   instead of padding so the GLYPH stays exactly where 3.1.30 puts it: padding on
   an element anchored top/right would have pushed the heart down and left by the
   same amount. */
/* 48 x 48, ANCHORED ON THE GLYPH. Owner: *"for the favorites, increase the
   tappable area -- 48 by 48 on the corner. Don't increase the icon size or
   location though."* -12 all round gave 40 x 39 on a 16 x 15 glyph, which is
   under every touch-target minimum. The insets are asymmetric because the glyph
   is: (48 - 16) / 2 across and (48 - 15) / 2 down. Still a pseudo-element and
   still not padding, for the reason the note above gives -- padding on an
   element anchored top/right moves the heart. */
#diamond_search.sf_archive .sf_card_heart::after {
    content: "";
    position: absolute;
    /* ANCHORED AT THE CARD'S CORNER, EXTENDING INWARD. Centring 48 x 48 on a
       glyph that sits 8-10px from the corner puts half of it off the card,
       where the grid container is painted on top -- MEASURED, three of the four
       corners of a centred box hit-tested to `.search_results_grid`, not to the
       heart. The owner said "48 by 48 ON THE CORNER", and a box that starts at
       the corner and grows down and left is entirely on the card, so all 48 of
       it is live. */
    top: -9.5px;    /* the heart's own top inset -- back to the card's edge */
    right: -8px;    /* likewise; -10 overshot by 2 and the last 2px of the box
                       hit-tested to the grid gutter rather than the heart */
    width: 48px;
    height: 48px;
}

/* A <button> WITH NO RESET IS A UA BUTTON. `Talk to a gemologist` is a bare
   underlined link on the board -- no fill, no border. Its reset lived inside the
   mobile query, so at 1728 Chrome drew its own chrome instead: measured
   background rgb(239,239,239) with a 2px black border. The appearance reset is
   width-independent and belongs at the base; the mobile block keeps only what is
   genuinely per-width. */
#diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_link {
    -webkit-appearance: none;
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--sf-green, #27423B);
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--sf-ls, -0.21px);
    text-decoration: underline;
}

@media (max-width: 991px) {
    #diamond_search.sf_archive .sf_card_heart {
        position: absolute;
        right: 8px;
        /* 3.1.30 is @+153,+9.5 -- the 15-tall glyph is CENTRED in the 18-tall
           overlay row that starts at the image's 8px padding, not top-aligned
           to it: 8 + (18 - 15) / 2 = 9.5. */
        top: 9.5px;
        z-index: 3;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 16px;
        height: 15px;
        padding: 0;
        margin: 0;
        background: none;
        border: 0;
        cursor: pointer;
    }
    #diamond_search.sf_archive .sf_card_heart svg {
        width: 16px;
        height: 15px;
        display: block;
    }
    #diamond_search.sf_archive .sf_card_heart svg path {
        fill: none;
        stroke: var(--sf-ink-soft);
        stroke-width: 1px;
    }
    #diamond_search.sf_archive .sf_card_heart.selected svg path {
        fill: #C65858;
        stroke: #C65858;
    }
}

/* ===========================================================================
   6. 3.2 STONE PDP -- 14514:38983
   body.sf-stone-pdp is stamped server-side (da-general.php) on the loose-stone
   product page only, so nothing here can reach a ring PDP.
   =========================================================================== */

/* Two CTA labels are printed, one per breakpoint (add_stone_link). */
/* ONE LABEL, BOTH WIDTHS -- the desktop variant is gone from the markup (see
   da-general.php). `.sf_label_m` is the board's label and shows everywhere; the
   `_d` rules below are left inert rather than deleted so the pair can come back
   as one edit if desktop is ever given its own copy. */
body.sf-stone-pdp .sf_label_m { display: inline; }
body.sf-stone-pdp .sf_label_d { display: none; }

/* DESKTOP -- owner note (d): "scaled the way the BYR flow does it, not
   invented". Board 3.2 is drawn at 390 ONLY, so there is no desktop frame to
   measure; what the BYR desktop partials do in the same situation is carry the
   board's TOKENS (type, colour, shape, the two-column spec row) up into a
   `@media (min-width: 992px)` block and leave the page's own GRID alone. That
   is what this does.

   Everything here is additive and scoped to body.sf-stone-pdp -- the loose
   stone product page -- so no ring PDP and no other product page is reached.
   Two things deliberately NOT done, because they would be invention rather
   than scaling, and both are reported instead:
     * the desktop H1 is still the page's own .summary title, not
       h1.sf_stone_title. Swapping which heading renders at desktop changes an
       indexed <h1>; that is an owner call, not a measurement.
     * the CTAs stay where they shipped, inside the add-to-cart form. They are
       restyled to the board (stacked, 370x44, #27423B, arrow, outlined
       secondary) but not relocated, so the desktop column keeps its order.
   MEASURED before the first version of this rule at 1728: the trust row
   painted on top of the product title, which is why it used to be hidden. */
@media (min-width: 992px) {
    /* 3.2.26 AT DESKTOP -- ELEMENTS 14.1, verbatim: "Board gives nothing for:
       whether the sticky bottom bar (3.2.26) stays sticky at desktop ... The
       BYR flow's answer is a fixed 120px footer band (--rb-d-footer-h), and
       _stone-desktop.css 6 is the rule to copy." This is that band: 1728x120,
       #FAF3ED, 1px #E4DED8 top rule, pad 28/80/10/80, the 53-tall CTA row
       right-aligned with the primary at x1366 and the link left of it.
       MEASURED before this at 1728: there was no band at all -- the CTAs sat
       in a position:sticky right column. Carried up from the BYR sheet, not
       designed; the board draws no desktop frame for this screen.

       The PAGE COLUMNS are deliberately NOT re-laid. 14.1's 6/6 split would
       move the gallery, the variations form and every marketing section on the
       product page, which is far outside this element -- reported, not done. */
    body.sf-stone-pdp .sf_pdp_ctas {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 40;
        box-sizing: border-box;
        display: flex;
        flex-direction: row;
        align-items: flex-start;
        justify-content: flex-end;
        gap: 36px;
        /* 100/24 -- see the note on `.ssq_bottom_nav` in _stone-desktop.css
           section 6; the horizontal gutter is deliberately kept. */
        height: 100px;
        max-width: none;
        margin: 0;
        padding: 24px 4.6296296296%;
        background: #FAF3ED;
        border-top: 1px solid #E4DED8;
        box-shadow: none;
    }
    /* `display: contents` dissolves the wrapper stone-first.js moves in, so the
       two buttons and the link are all direct flex items of the band and one
       `order` sequence lays the row out: link, PURCHASE LOOSE, ADD TO RING.
       Without it the wrapper stayed a block and the pair stacked -- MEASURED,
       both at x1366, the second one 5px past the band's bottom edge. */
    body.sf-stone-pdp .sf_pdp_ctas .sf_pdp_ctas_moved {
        display: contents;
    }
    body.sf-stone-pdp .sf_pdp_ctas > .sf_pdp_back {
        order: 1;
        align-self: center;
        margin: 0;
    }
    /* the fixed band has to be scrollable clear of, at desktop too */
    body.sf-stone-pdp.sf-pdp-ctas-lifted {
        padding-bottom: 120px;
    }

    /* "<- Continue browsing" ABOVE THE BREADCRUMB (owner). stone-first.js's
       placePdpBack() moves the link here at >=992 and back into the band below
       it; the host carries `container` so its gutter IS the breadcrumb's and
       the link cannot drift from the crumb at any width. The band keeps
       justify-content: flex-end, so with the link gone the two buttons stay
       right-aligned and nothing else in it moves.
       :empty so a window dragged back under 992 -- which returns the link to
       the band and leaves this host behind -- does not leave a 14px hole. */
    body.sf-stone-pdp .sf_pdp_back_top {
        display: flex;
        align-items: center;
        margin-bottom: 14px;
    }
    body.sf-stone-pdp .sf_pdp_back_top:empty {
        display: none;
    }
    /* the band's own rules (order, align-self) do not reach it here */
    body.sf-stone-pdp .sf_pdp_back_top > .sf_pdp_back {
        margin: 0;
    }
    body.sf-stone-pdp .sf_pdp_back {
        display: inline-flex;
        align-items: center;
        gap: 3px;
        height: 28px;
        color: #27423B;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-decoration: underline;
    }
    body.sf-stone-pdp .sf_pdp_back_arrow svg { display: block; }

    /* trust row -- the board's three claims, under the price. */
    body.sf-stone-pdp .sf_trust_row {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 24px;
        margin: 14px 0 0 0;
    }
    body.sf-stone-pdp .sf_trust_item {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 25px;
        letter-spacing: -0.21px;
        color: #3E3C39;
        white-space: nowrap;
    }
    body.sf-stone-pdp .sf_trust_item svg { width: 17px; height: 17px; flex: 0 0 17px; }

    /* CTA pair -- 282x48 each, side by side in the band's 53-tall row.
       `.sf_pdp_ctas_home` is the wrapper the server printed inside the
       add-to-cart form; stone-first.js moves its inner div into the bar at
       every width now, so the wrapper is left behind empty and the rules hang
       off the BAR. The empty wrapper is not display:none'd -- if the script
       never runs the buttons are still where WooCommerce put them. */
    body.sf-stone-pdp .sf_pdp_ctas_home:empty { display: none; }
    body.sf-stone-pdp .sf_pdp_ctas_home,
    body.sf-stone-pdp .sf_pdp_ctas_home > div {
        display: flex;
        flex-direction: column;
        gap: 8px;
        max-width: 370px;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home > .sf_pdp_back {
        align-self: flex-start;
        margin-top: 4px;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home button.select_setting,
    body.sf-stone-pdp .sf_pdp_ctas_home button.puchase_loose,
    body.sf-stone-pdp .sf_pdp_ctas button.select_setting,
    body.sf-stone-pdp .sf_pdp_ctas button.puchase_loose {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 282px;
        flex: 0 0 282px;
        max-width: 282px;
        height: 48px;
        min-height: 48px;
        margin: 0;
        padding: 0;
        border-radius: 4px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: uppercase;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home button.select_setting,
    body.sf-stone-pdp .sf_pdp_ctas button.select_setting {
        order: 3;
        border: 1px solid #27423B;
        background: #27423B;
        color: #FAF3ED;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home button.puchase_loose,
    body.sf-stone-pdp .sf_pdp_ctas button.puchase_loose {
        order: 2;
        border: 1px solid #27423B;
        background: #FAF3ED;
        color: #27423B;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home .sf_cta_arrow,
    body.sf-stone-pdp .sf_pdp_ctas .sf_cta_arrow {
        display: inline-flex;
        width: 12px;
        height: 10px;
    }
    body.sf-stone-pdp .sf_pdp_ctas_home .sf_cta_arrow svg,
    body.sf-stone-pdp .sf_pdp_ctas .sf_cta_arrow svg { display: block; }

    /* spec rows -- the board's two-column form: label in #3E3C39 in a fixed
       128px box, value at the gutter. The legacy desktop row is inline bold
       "Label: value", so the value column landed wherever the label ended
       (measured at x 1161..1201 across six rows). */
    body.sf-stone-pdp .diamond_atts_accordion .accordion-title {
        display: flex;
        align-items: flex-start;
        width: 100%;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 22px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
        text-align: left;
    }
    body.sf-stone-pdp .diamond_atts_accordion .att_label {
        flex: 0 0 128px;
        max-width: 128px;
        color: #3E3C39;
        font-weight: 400;
    }
}

/* =============================================================================
   THE TRAILING RULE, AND THE SIZE OF AN OPEN ROW'S COPY
   -----------------------------------------------------------------------------
   Owner: *"remove the lines after Details and Dimensions' end line -- there's a
   full width line after it that's to be removed"*, and *"the paras in the
   diamond PDP on phone -- let's say I expanded Carat, there's a para like
   'though most think' etc -- all expanded paras must be 14px on mobile."*

   THE LINE. Every row's title carries a 1px #E4DED8 bottom border, which is the
   separator BETWEEN rows. On the last row there is no next row for it to
   separate, so it reads as a rule drawn under the block for no reason --
   MEASURED, all five titles carry it, Details & Dimensions included and last.
   Taken off the last one only; the other four still do their job.

   THE COPY. The bodies inherit whatever the theme gives a <p>, which is 16 on
   this template -- bigger than the 14/22 the row's own title is set in, so an
   opened row reads larger than the thing that opened it.
   ============================================================================= */
body.sf-stone-pdp .diamond_atts_accordion > .accordion-row:last-of-type > button.accordion-title {
    border-bottom: 0;
}
/* ...AND THE ONE THE DESCRIPTION BLOCK DRAWS UNDER IT. Owner, a second time:
   *"that line is still there -- the divider below the Details and Dimensions
   line, at the end of everything. I asked you to remove it."*

   They were right and my first pass only got half of it. Taking the specs
   accordion's own trailing border off left a SECOND hairline four pixels below
   it -- MEASURED, the specs block ends at y902 and
   `.accordion-row.accordion_description_row` starts at y906 carrying its own
   1px #0F0E0D border-TOP. Two different elements, one apparent line, so
   removing either alone changes nothing a shopper can see.

   Only the FIRST description row loses its top rule: the rest of that list
   still separates its own rows, and this is only about the junction where the
   specs list has already ended.

   `:first-of-type` DOES NOT WORK HERE and was my second miss: it matches the
   first element of its TAG among siblings, not the first with the class, and
   these rows are all <div> alongside other <div>s -- MEASURED, the border was
   still 1px after that attempt. The top rule comes off EVERY description row
   instead; each one keeps its border-BOTTOM, so the list still separates its
   own rows and only the doubled line at the junction disappears.

   REVERTED. Owner: *"on desktop you removed the top of the Shipping and
   Delivery box -- I was talking about the phone view line."* Correct, and the
   rule was wrong at BOTH widths: MEASURED, `.accordion_description_row` is a
   BOX -- 1px left, right and bottom with a 4px radius -- so taking its
   border-top off does not remove a divider, it opens the top of the Shipping
   & Delivery card. The line under Details & Dimensions is that box's own top
   edge, which belongs to it.

   The specs accordion's own trailing rule above is still gone; that part was
   real. Whatever is left on phone is something else and needs finding before
   anything else is deleted. */
@media (max-width: 991px) {
    body.sf-stone-pdp .diamond_atts_accordion .accordion-text,
    body.sf-stone-pdp .diamond_atts_accordion .accordion-text p {
        font-size: 14px;
        line-height: 22px;
    }
}

/* The price note is drawn at every width -- it is what the number MEANS on this
   page (the stone's price with no setting), not a mobile-only flourish. */

@media (max-width: 991px) {
    body.sf-stone-pdp .sf_label_m { display: inline; }
    body.sf-stone-pdp .sf_label_d { display: none; }
    /* Board 3.2's CTAs carry no price -- the price is already the second line
       of the title block, two taps away from nothing. */
    body.sf-stone-pdp .sf_pdp_ctas .sf_cta_price { display: none; }

    /* breadcrumb -- board `Title` @12,95 188x30: Founders Grotesk 400 12/30,
       ls -0.21, LOWER, #202020, underline on the SKU segment only. The stone
       ARCHIVE already had this treatment; the PDP never did, so it was
       inheriting the theme default (14/15.4, +0.6 tracking, #000). */
    body.sf-stone-pdp nav.woocommerce-breadcrumb {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 12px;
        line-height: 30px;
        letter-spacing: -0.21px;
        text-transform: lowercase;
        color: #202020;
        /* Same narrow-space problem the archive crumb has: FoundersGrotesk's
           space glyph renders ~1.8px at 12px, so the words run together. */
        word-spacing: 1.5px;
        /* The board's `Title` node is a 30-TALL text box whose glyphs sit low in
           it. Taking the line-height from 15.4 to the board's 30 grew the row's
           flow footprint by 15.6 and pushed the whole summary column down with
           it -- the title left y 141.4 (the board's 141) for 157. The negative
           margins hold the box's CENTRE where the old 15.4-tall row was, so the
           type matches the board and nothing below moves. */
        margin-top: -8px;
        /* 3.2.2 -> 3.2.3. The crumb's 30-tall box ends at 171 and the title
           starts at 187: the content column's AL gap=6 plus the hero group's
           10px pad-top, i.e. a 16px hole. MEASURED before this: the crumb box
           ended 140 and the title started 140 -- gap 0, the two boxes touching.
           Both boxes were already the board's (crumb 30 tall at 12/30, title 13
           tall at 18/13); only the space between them was missing. */
        margin-bottom: 16px;
    }
    /* main.css:1948 styles `.woocommerce-breadcrumb a` as a SIBLING selector of
       the nav itself, so the <a> children were never inheriting the nav's type
       -- they computed 14px / +0.6px tracking inside a 12px / -0.21px nav, and
       "home" read visibly bigger and looser than the rest of the crumb. The
       <a> needs the whole ramp restated, not just the colour. */
    body.sf-stone-pdp nav.woocommerce-breadcrumb a {
        color: #202020;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 12px;
        line-height: 30px;
        letter-spacing: -0.21px;
        text-transform: lowercase;
    }

    /* title row -- board Frame 38795 @12,141 366x37: a 13-tall title text box,
       6px gap, then the 18-tall price line at y 160. The board hugs Canela's
       cap height; a full 24px line box put the price 10.4px low and ran the
       block to 48. textCase is UPPER so there are no descenders to clip. */
    body.sf-stone-pdp h1.product_title.sf_stone_title {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 18px;
        line-height: 13px;
        letter-spacing: -0.21px;
        text-transform: uppercase;
        color: #0F0E0D;
        margin: 0 0 6px 0;
    }
    /* "$500 (stone only)" -- one line, FG 400 16. The 6px title/price gap is
       the h1's margin-bottom (above); the price contributes nothing of its own,
       or the two stack and the block runs 6px long. */
    body.sf-stone-pdp .col.position-relative > p.price {
        margin-top: 0;
        /* The price line IS the bottom of board 3.2.4's title row (@12,187 366x37):
           title 187, price 206..224, main image 234 -- so the gap the hero group's
           AL:VERTICAL gap=12 leaves under it is 10, not the theme's 16. */
        margin-bottom: 10px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 18px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
    }
    /* 3.2.3 `hero` pads 10 at the bottom and 3.2.2's column gap is 4, so the thumb
       strip meets the trust row at 14 -- which .sf_trust_row's own margin-top
       already is. The gallery wrapper's 30px was stacking on top of it. */
    body.sf-stone-pdp .iconic-woothumbs-all-images-wrap {
        margin-bottom: 0;
    }
    /* .summary's own 20px margin-top COLLAPSES with .sf_trust_row's 14 and wins,
       so the board's 14 could never be drawn while it stood. */
    body.sf-stone-pdp .summary.entry-summary {
        margin-top: 0;
    }

    /* --- HEART -- board `Heart` 36x36 @342,141, right edge 378 = the content
       gutter; vector 22x20 @356, 1px #3E3C39, glyph centre (367, 151).
       The node is da-product-single.php's .productFavorite.summary_container,
       which is the control main.js:1040 already owns -- only its box is wrong
       (60x40 at x=320, overhanging the gutter by 2px, glyph 18.3x16.7 in
       #0F0E0D and 16.8px left / 6.4px low of the board). */
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container {
        right: 12px;             /* right edge 378 = the content gutter */
        display: flex;
        /* Board `Heart` 36x36 @342,141 with its 22x20 vector at @356,141 -- the
           glyph is TOP-aligned and pushed to the right edge of the hit box, not
           centred in it. */
        align-items: flex-start;
        justify-content: flex-end;
        width: 36px;
        height: 36px;
        margin: 5px 0 0 0;       /* the node ships 5px above the title row */
        padding: 0;
    }
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container svg {
        width: 22px;
        height: 20px;
        display: block;
    }
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container svg path {
        stroke: #3E3C39;
        stroke-width: 1px;
    }

    /* --- MAIN IMAGE -- board @12,188 366x330, r4, fill scale FILL, clipped,
       with the thumbnail strip 10px under it.
       WooThumbs renders a `--grid-two` stack whose SECOND slide is the 360
       viewer at 379 tall, and the taller slide was setting the row height --
       so the 284.5-tall photo left 94.5px of empty ground under it and the
       measured photo-to-thumbs gap was 109.5px against the board's 10. Pin the
       viewport to 330 and let both slides fill it. */
    body.sf-stone-pdp .iconic-woothumbs-images-wrap,
    body.sf-stone-pdp .iconic-woothumbs-images {
        height: 330px;
        max-height: 330px;
        overflow: hidden;
        border-radius: 4px;
    }
    body.sf-stone-pdp .iconic-woothumbs-images__slide {
        /* The plugin ships `max-width: calc(100% - 5px)` on the slide, which is
           what held the photo to 361 inside the 366 column -- 5px short of the
           board's full-gutter 366. */
        width: 100% !important;
        min-width: 100%;
        max-width: none !important;
        flex: 0 0 100%;
        height: 330px;
        max-height: 330px;
        margin: 0;
        padding: 0;
    }
    /* The WooThumbs `--grid-two` container laid the slide out 361 wide inside
       the 366 column (board main image is 366x330, flush to both gutters). */
    body.sf-stone-pdp .iconic-woothumbs-images--grid {
        grid-template-columns: 1fr;
        gap: 0;
        padding: 0;
    }
    body.sf-stone-pdp img.iconic-woothumbs-images__image {
        width: 100% !important;
        max-width: none !important;
        height: 330px;
        object-fit: cover;
        border-radius: 4px;
    }
    body.sf-stone-pdp .iconic-woothumbs-images__slide iframe {
        width: 100%;
        height: 330px;
    }

    /* --- THUMBNAIL STRIP -- board `image buttons` @12,528 366x52: 52x52 tiles,
       r4, gap 8, ACTIVE tile carries a 1px INSIDE #27423B stroke. dev-1 drew a
       52x42 image tile beside a 52x52 div at gap 15, with no selected state of
       any kind. */
    body.sf-stone-pdp .pdp_nav_container {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        margin-top: 10px;
        font-size: 0;            /* kills the inline-block whitespace gap */
    }
    body.sf-stone-pdp .pdp_nav_container > .pdp_nav {
        width: 52px;
        height: 52px;
        flex: 0 0 52px;
        margin: 0;
        border-radius: 4px;
        object-fit: cover;
        box-sizing: border-box;
        box-shadow: none;
    }
    /* 3.2.12 / B17: the INACTIVE tile is not bare. 3.2 draws its stroke hidden,
       but 3.5 (3.5.12) and the setting PDP (P.11) both draw a visible 1.5px
       #FAF3ED -- two screens against one, and it is what keeps two tiles on a
       #FAF3ED ground from reading as one 112-wide block. */
    body.sf-stone-pdp .pdp_nav_container > .pdp_nav {
        box-shadow: inset 0 0 0 1.5px #FAF3ED;
    }
    body.sf-stone-pdp .pdp_nav_container > img.pdp_nav {
        box-shadow: none;
        outline: 1.5px solid #FAF3ED;
        outline-offset: -1.5px;
    }
    body.sf-stone-pdp .pdp_nav_container > .pdp_nav.active {
        box-shadow: inset 0 0 0 1px #27423B;
    }
    /* An <img> cannot paint an inset shadow, so the active ring goes on an
       outline drawn inward via a negative offset instead. */
    body.sf-stone-pdp .pdp_nav_container > img.pdp_nav.active {
        box-shadow: none;
        outline: 1px solid #27423B;
        outline-offset: -1px;
    }
    /* THE 360 GLYPH STAYS INSIDE ITS TILE. Owner: *"the 360 green arrows are
       flowing out."* They were: product-single.css draws the badge as
       `content: url(360-view-icon.svg)` on an ABSOLUTE ::before with no box of
       its own, so it renders at the SVG's intrinsic size -- bigger than the
       52x52 tile this flow sizes the strip to -- and the green arcs spilled past
       the tile's right and bottom edges. Given the tile's own box and told to
       fit inside it; `object-fit` applies because `content: url()` makes the
       pseudo a replaced element. */
    body.sf-stone-pdp .pdp_nav_container > .pdp_nav.playbutton {
        overflow: hidden;
    }
    body.sf-stone-pdp .pdp_nav_container > .pdp_nav.playbutton::before {
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: contain;
        /* ...AND IT STAYS BEHIND THE STICKY BAR. Owner: *"the 360 icon in the
           gallery overview, the second one, does not disappear behind the sticky
           section -- it moves on top of it."*

           product-single.css gives this badge `z-index: 1`, and that one
           declaration is the whole bug. Both the badge and the CTA bar resolve
           into the SAME stacking context (SECTION#product_image_details, z-index
           2) -- but the bar's own `z-index: 40` does not count at that level,
           because its parent `.summary.entry-summary` is `position: sticky`, and
           a sticky box ALWAYS forms a stacking context even at `z-index: auto`.
           So the bar's 40 only orders it INSIDE `.summary`, and `.summary` itself
           enters the section at level 0. The badge's 1 beats 0, every time.

           MEASURED at 390x600 on a diamond PDP, scrolled so the strip sits in the
           bar's band: `document.elementFromPoint` at the badge's centre returned
           `DIV.pdp_nav playbutton`, with `closest('.sf_pdp_ctas')` null -- the
           thumbnail hit-testing above the bar.

           `auto` rather than a smaller number: the badge never needed a layer of
           its own. It is an ABSOLUTE box and its dimmed <img> sibling is in-flow,
           so it already paints above it by position alone -- a positioned
           z-auto box is painted after in-flow content in the same context.
           Scoped to the stone PDP, which is the only surface with a fixed bar
           for it to climb over. */
        z-index: auto;
    }
    body.sf-stone-pdp .sf_price_note {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        color: #0F0E0D;
    }

    /* trust row -- @12,640 351x25, three icon+label items, SPACE_BETWEEN */
    body.sf-stone-pdp .sf_trust_row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        /* 3.2.13 is `@12,640 **351**x25` inside a 366 column -- the row stops 15px
           short of the right gutter, which is what stops `60 Day Returns` from
           being pinned to the edge. */
        width: 351px;
        max-width: 100%;
        margin: 14px 0 0 0;
        padding: 0;
    }
    body.sf-stone-pdp .sf_trust_item {
        display: inline-flex;
        align-items: center;
        gap: 2px;                 /* 3.2.14: icon box -> label gap is 2 */
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 25px;
        letter-spacing: -0.21px;
        color: #3E3C39;
        white-space: nowrap;
    }
    body.sf-stone-pdp .sf_trust_item svg {
        width: 17px;
        height: 17px;
        flex: 0 0 17px;
    }

    /* spec accordion -- @12,669 366x264. The board draws a TWO-COLUMN list:
       label at the left edge in #3E3C39, value at x=140 in #0F0E0D, a 1px
       #E4DED8 rule under each row, chevron at the right. The live markup is
       `<button><span class="att_label">Carat:</span> 0.50</button>` -- one span
       plus a bare text node. In a flex container that text node becomes an
       anonymous flex item, so the two columns come out of the existing markup
       with no change to da-product-single.php.

       The trailing colon is GONE: da_stone_pdp_specs_accordion() (da-general.php)
       now prints the board's five rows -- `Carat Weight` / `Cut` / `Color` /
       `Certificate` / `Details & Dimensions` -- with a named value span, and it
       runs for gemstones and moissanite too, which had no accordion at all. */
    body.sf-stone-pdp .diamond_atts_accordion .accordion-title {
        display: flex;
        align-items: flex-start;
        width: 100%;
        min-height: 30px;
        padding: 0 0 8px 0;
        border-bottom: 1px solid #E4DED8;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 22px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
        text-align: left;
    }
    body.sf-stone-pdp .diamond_atts_accordion .att_label {
        flex: 0 0 128px;      /* board value column starts at x=140, gutter 12 */
        max-width: 128px;
        color: #3E3C39;
        font-weight: 400;
    }
    body.sf-stone-pdp .diamond_atts_accordion .accordion-row {
        margin-bottom: 16px;
    }
    /* The Details & Dimensions body keeps the row's two columns so an opened
       panel reads as a continuation of the list, not a paragraph. */
    body.sf-stone-pdp .diamond_atts_accordion .rb_dd_row {
        display: flex;
        align-items: flex-start;
        margin: 0;
        padding: 6px 0 0 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 22px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
    }
    /* The last row's margin-bottom collapses OUT of the accordion (which has a
       padding-top but no padding-bottom), so it landed between the accordion and
       the shipping panel as 16 of the measured 48px hole. */
    body.sf-stone-pdp .diamond_atts_accordion .accordion-row:last-child {
        margin-bottom: 0;
    }
    /* Board accordion frame @12,623 carries padding-top 21 and sits 4px under
       the trust row (which ends at 619), so the first label starts 25px clear.
       dev-1 had the first row butting straight onto the trust icons. */
    body.sf-stone-pdp .diamond_atts_accordion {
        margin-top: 4px;
        /* 3.2.17 is `AL:VERTICAL gap=16 pad=21/0/21/0` -- the bottom 21 was never
           drawn, so the shipping panel sat 21 high. */
        padding-top: 21px;
        padding-bottom: 21px;
    }
    /* 3.2.23 chevron: 10x5 (rb 11x6), stroke 1 #3E3C39, flush at x=368 in a
       column that ends at 378, y = row top + 9.5. accordion.css draws a 24x24
       glyph at right:10/top:18. icon-chevron-down-10.svg is the same 11x6 box
       the BYR flow already uses for this exact node (_stone.css:2512). */
    body.sf-stone-pdp .diamond_atts_accordion > .accordion-row > button.accordion-title::after {
        top: 9.5px;
        right: 0;
        width: 11px;
        height: 6px;
        margin-top: 0;
        background-image: url('../../assets/media/ringbuilder/icon-chevron-down-10.svg');
        background-size: 11px 6px;
        background-position: center;
        background-repeat: no-repeat;
        /* ...AND IT TURNS OVER ON OPEN -- the stone PDP's twin of the rule in
           _stone.css. Owner: *"arrows are not rotating 180 degrees on expanding
           the section -- fix this wherever this is happening."* Chevron rows
           only: the Product Details / Shipping rows on this same page close on
           a PLUS and keep their minus swap, which a rotation would have made
           indistinguishable. */
        transform-origin: 50% 50%;
        transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
    }
    body.sf-stone-pdp .diamond_atts_accordion > .accordion-row.opened > button.accordion-title::after {
        transform: rotate(180deg);
    }
    @media (prefers-reduced-motion: reduce) {
        body.sf-stone-pdp .diamond_atts_accordion > .accordion-row > button.accordion-title::after {
            transition: none;
        }
    }

    /* 3.2.24 panel is `@12,937 366x**48**` pad **16**; 3.2.25 puts the icon at
       x28 (= 12 + 16) and the label at x58, i.e. a 7px icon->label gap, with the
       icon's 23 ending 9 above the panel's foot. The theme's row pads 15/6, which
       is 51 tall and starts its icon 12 in. */
    /* 3.2.25 geometry, restated against the MEASURED box rather than assumed.
       Panel [12,892 366x48] with a 1px INSIDE stroke, so the button is
       [13,893 364x46]. The board insets the glyph 16 from the panel's OUTER
       edge -> x 28, which is 15 inside the button. MEASURED before this: the
       <svg> carried `margin-left: 5px` of its own, so 16 of padding put it at
       x 34 -- 6 past the board -- and it drew at its source 21x15 rather than
       the board's 23x23. 15 + 23 + 8 + 2 border = 48, the board's panel height.
       The GLYPH ITSELF is the theme's one-path truck, not the board's 5-shape
       one; the box is matched, the drawing is not redrawn. */
    body.sf-stone-pdp .product-details-accordion .accordion-row.shipping_accordion > button.accordion-title {
        /* FLEX, not the inherited inline-block. With an inline 23x23 svg on a
           19px Canela line the line box stayed 19 tall -- MEASURED, the panel
           came back 366x44 with the glyph 11.2 below the panel top instead of
           the board's 16. A flex row makes the content box the icon's own 23,
           so 1 + 15 + 23 + 8 + 1 = the board's 48. The `expand/collapse`
           ::after is position:absolute and is not a flex item. */
        display: flex;
        align-items: center;
        box-sizing: border-box;
        /* The height is DECLARED, not inferred. As a flex row the button still
           sized its cross axis off the 19px text line and left the 23px glyph
           overflowing it -- MEASURED, button 364x42 with the svg spanning
           919..942 against a 924..943 content box. The board's panel is a fixed
           366x48 (3.2.24); 48 - 2 border = 46, and 15 + 23 + 8 = 46. */
        height: 46px;
        padding: 15px 16px 8px 15px;
    }
    body.sf-stone-pdp .product-details-accordion .accordion-row.shipping_accordion > button.accordion-title > svg {
        width: 23px;
        height: 23px;
        /* The theme ships this glyph with `margin: -6px 0 0 5px` -- the 5 is
           what put it at x34 against the board's 28, and the -6 is what kept
           the flex row 42 tall and the glyph 3px above its own content box. */
        margin: 0 7px 0 0;   /* 3.2.25: icon 28..51, label at 58 */
        vertical-align: middle;
    }
    /* 3.2.25 `expand/collapse` instance @316,953 17x17 -- 45px in from the
       panel's right edge and level with the truck. accordion.css parks it at
       right:10/top:18. */
    body.sf-stone-pdp .product-details-accordion .accordion-row.shipping_accordion > button.accordion-title::after {
        top: 15px;
        right: 44px;
    }

    /* SHIPPING & DELIVERY -- board Frame 38532 @12,891 366x48, FOUR px below
       the accordion. An empty form.cart (366x0, margin 10px 0 32px) was
       opening a 48px hole between them; a cart form with nothing in it has no
       height to give and should have no margin either. */
    body.sf-stone-pdp form.cart:empty,
    body.sf-stone-pdp .summary form.cart {
        margin-top: 0;
        margin-bottom: 0;
    }
    body.sf-stone-pdp .product-details-accordion {
        margin-top: 4px;
    }
    /* heading -- Canela 300 18/19, ls -0.21, #0F0E0D (was 400 18/19.8, normal) */
    body.sf-stone-pdp .product-details-accordion .accordion-title {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
    }

    /* sticky bottom bar -- Frame 1171276552 @0,895 390x154.
       ADD TO RING / PURCHASE LOOSE / "<- Continue browsing". The two buttons
       are the page's own .select_setting and .puchase_loose, moved into the bar
       by stone-first.js so their handlers (product-single.js:642, the ajax
       loose purchase) come with them. */
    body.sf-stone-pdp .sf_pdp_ctas {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 40;
        display: flex;
        flex-direction: column;
        gap: 8px;
        padding: 12px 10px 10px 10px;
        background: #FAF3ED;
        /* Board Frame 1171276552: fill #FAF3ED, NO stroke, NO effect. The 1px
           #E4DED8 rule that used to sit here was an addition to the board. */
    }
    body.sf-stone-pdp .sf_pdp_ctas > div {
        display: contents;
    }
    body.sf-stone-pdp .sf_pdp_ctas button.select_setting,
    body.sf-stone-pdp .sf_pdp_ctas button.puchase_loose {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 100%;
        height: 44px;
        min-height: 44px;
        margin: 0;
        padding: 14px 0;
        border-radius: 4px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: uppercase;
    }
    body.sf-stone-pdp .sf_pdp_ctas button.select_setting {
        order: 1;
        border: 1px solid #27423B;
        background: #27423B;
        color: #FAF3ED;
    }
    /* Trailing arrow -- board `Vector 138`, 12 wide at 1.25px, 5px after the
       label group, the pair centred. Only the primary carries one. */
    body.sf-stone-pdp .sf_pdp_ctas .sf_cta_arrow {
        display: inline-flex;
        width: 12px;
        height: 10px;
    }
    body.sf-stone-pdp .sf_pdp_ctas .sf_cta_arrow svg { display: block; }
    body.sf-stone-pdp .sf_pdp_ctas button.puchase_loose .sf_cta_arrow { display: none; }
    body.sf-stone-pdp .sf_pdp_ctas button.puchase_loose {
        order: 2;
        border: 1px solid #27423B;
        background: #FAF3ED;
        color: #27423B;
    }
    body.sf-stone-pdp .sf_pdp_back {
        order: 3;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 3px;                /* board arrow-to-label gap is 3, not 6 */
        height: 28px;
        color: #27423B;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px; /* 17 chars x 0.21 = the 3px width overrun */
        text-decoration: underline;
    }
    body.sf-stone-pdp .sf_pdp_back_arrow svg {
        display: block;
    }
    /* The bar is 154 tall and FIXED, so the last 154px of the document can
       never be scrolled clear of it. div.product's own padding is not enough:
       the footer is a sibling of div.product, so the page still ends under the
       bar. MEASURED at full scroll: 153.8px of the footer sat under the bar
       with no scroll room left. */
    body.sf-stone-pdp.sf-pdp-ctas-lifted {
        padding-bottom: 154px;
    }
    body.sf-stone-pdp.sf-pdp-ctas-lifted div.product {
        padding-bottom: 0;
    }
}

/* ===========================================================================
   7. 3.3 ENGAGEMENT RINGS -- 14514:39115 (loaded) / 39488 (selected) /
      39301 (loading). The settings grid the shopper lands on after ADD TO RING.

   EVERY rule below is gated on `html.sf-has-stone` as well as the breakpoint.
   This is the same archive every other shopper browses; without the gate,
   hiding the category description and shrinking the H1 would change an indexed
   marketing page for people who are not in this flow at all. The class is
   stamped by the wp_head bootstrap in da-general.php before the grid paints.
   =========================================================================== */

/* The chrome is printed for everyone and drawn for nobody until a stone is
   held. Not `hidden`: several sheets here carry [hidden]{display:none
   !important}, and this needs to be re-displayable from CSS. */
body.sf-ring-archive .sf_ring_chrome,
body.sf-ring-archive .sf_ring_spinner {
    display: none;
}

@media (max-width: 991px) {
    body.sf-ring-archive .sf_ring_chrome {
        display: block;
        margin: 0 0 10px 0;
    }

    /* The ordinary archive header -- big Canela H1 plus the category
       description -- is not on board 3.3; the in-flow header replaces it. */
    body.sf-ring-archive .woocommerce-products-header {
        display: none;
    }
    /* !important is unavoidable: the node carries Bootstrap's `.d-block`, which
       is itself `display:block !important`, so no amount of specificity wins. */
    body.sf-ring-archive .mobile_filters_button {
        display: none !important;   /* the Filters pill in the tab row replaces it */
    }

    /* --- Ring details bar -- 14514:40364 collapsed / 40382 expanded -------- */
    body.sf-ring-archive .sf_ring_details {
        margin: 8px 0 10px 0;
        border-radius: 4px;
        background: rgba(228, 222, 216, 0.60);   /* #E4DED8 @ 60% */
    }
    body.sf-ring-archive .sf_rd_head {
        display: flex;
        align-items: center;
        gap: 6px;
        width: 100%;
        min-height: 40px;
        margin: 0;
        padding: 10px 9px;
        border: 0;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        letter-spacing: -0.21px;
        color: #3E3C39;
        text-align: left;
    }
    body.sf-ring-archive .sf_rd_chev {
        display: inline-flex;
        width: 10px;
        height: 5px;
        color: #3E3C39;
        transition: transform .15s linear;
    }
    /* chevron points DOWN collapsed, UP expanded (board 14514:40364/40382) */
    body.sf-ring-archive .sf_rd_head[aria-expanded="true"] .sf_rd_chev {
        transform: rotate(180deg);
    }
    body.sf-ring-archive .sf_rd_label {
        margin-left: 6px;
    }
    body.sf-ring-archive .sf_rd_est {
        margin-left: auto;
        text-align: right;
        white-space: nowrap;
    }
    body.sf-ring-archive .sf_rd_est_label {
        color: #3E3C39;
        font-weight: 400;
    }
    /* 400, not 500: FoundersGrotesk ships only Regular, and the Medium cut is
       not licensed. A 500 here resolves to the Regular file anyway on any
       browser that does not synthesise, and to a double-struck fake on one that
       does -- so it is said plainly. The value is distinguished from its label
       by colour, which is what actually carries the emphasis. */
    body.sf-ring-archive .sf_rd_est_value {
        color: #0F0E0D;
        font-weight: 400;
    }

    body.sf-ring-archive .sf_rd_body {
        display: grid;
        grid-template-columns: 95px 1fr;
        gap: 12px;
        padding: 0 9px 10px 9px;
    }
    body.sf-ring-archive .sf_rd_media {
        width: 95px;
        height: 94px;
        border-radius: 4px;
        overflow: hidden;
        background: #FFFFFF;
    }
    body.sf-ring-archive .sf_rd_thumb {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    /* Board 14514:40382 draws a RING in this slot while its own Setting row
       says "Not selected yet" (conflict B7). There is no ring yet in this flow,
       so the slot holds the STONE the shopper actually picked; with no image on
       rb_object it collapses rather than showing a placeholder. */
    body.sf-ring-archive .sf_rd_media:not(.sf-has-img) {
        display: none;
    }
    body.sf-ring-archive .sf_rd_media:not(.sf-has-img) + .sf_rd_rows {
        grid-column: 1 / -1;
    }
    body.sf-ring-archive .sf_rd_row {
        display: grid;
        grid-template-columns: 56px 1fr auto;
        align-items: baseline;
        gap: 6px;
        padding: 4px 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        letter-spacing: -0.21px;
    }
    body.sf-ring-archive .sf_rd_key { color: #0F0E0D; }
    body.sf-ring-archive .sf_rd_val {
        color: #3E3C39;
    }
    /* textCase LOWER is on the STONE NAME only (board 14514:40382); the Setting
       row's "Not selected yet" is drawn in sentence case. */
    body.sf-ring-archive [data-sf="rd-stone"] {
        text-transform: lowercase;
    }
    body.sf-ring-archive .sf_rd_amt {
        color: #0F0E0D;
        text-align: right;
    }
    body.sf-ring-archive .sf_rd_foot {
        grid-column: 1 / -1;
        margin: 4px 0 0 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 12px;
        line-height: 19px;
        color: #3E3C39;
        text-align: center;
    }

    /* --- advanced-header -- 14514:39116 ---------------------------------- */
    body.sf-ring-archive .sf_ring_titlerow {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 12px;
        margin: 0 0 6px 0;
    }
    body.sf-ring-archive .sf_ring_title {
        margin: 0;
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: uppercase;
        color: #0F0E0D;
    }
    body.sf-ring-archive .sf_ring_count {
        margin: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 16px;
        letter-spacing: -0.21px;
        color: #3E3C39;
        white-space: nowrap;
    }
    body.sf-ring-archive .sf_ring_controls {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 0 0 10px 0;
    }
    /* The segment and the pill reuse 3.1's rules, which are scoped to
       #diamond_search -- a node this archive does not have. Same geometry,
       36 tall here (board 14514:39118 is 267x36 / 89x36, not 40). */
    body.sf-ring-archive .sf_ring_segmented {
        display: flex;
        flex: 1 1 auto;
        min-width: 0;
        height: 36px;
        border: 0.75px solid #27423B;
        border-radius: 10px;
        overflow: hidden;
    }
    body.sf-ring-archive .sf_ring_segmented .sf_seg {
        flex: 1 1 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        height: 36px;
        margin: 0;
        padding: 0 4px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        color: #27423B;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 18px;
        letter-spacing: -0.5px;
        text-decoration: none;
        white-space: nowrap;
    }
    body.sf-ring-archive .sf_ring_segmented .sf_seg.is-active {
        background: #27423B;
        color: #FAF3ED;
    }
    body.sf-ring-archive .sf_ring_segmented .sf_seg_icon {
        display: inline-flex;
        width: 13px;
        height: 12px;
    }
    body.sf-ring-archive .sf_ring_filters {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        height: 36px;
        min-width: 89px;
        margin: 0;
        padding: 0 8px;
        border: 1px solid #27423B;
        border-radius: 8px;
        background: #27423B;
        color: #FAF3ED;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        white-space: nowrap;
    }
    body.sf-ring-archive .sf_ring_filters .sf_filters_group {
        display: inline-flex;
        align-items: center;
        /* 4, MATCHING THE DIAMOND PILLS. Owner: *"just make it like what it was
           on diamond category and diamond search, for desktop and mobile,
           without messing it up"*, and *"don't increase the gap between the
           filter icon and the filter text."*

           MEASURED on /lab-grown-diamonds/ at 390 with a filter applied:
           icon->label 4, label->badge 4. This pill was 6 and 6.

           Both come off THIS one declaration, which is the structural
           difference between the two pills: on the diamond pill the badge is a
           SIBLING of the group and takes the pill's own `gap: 4`, while here it
           sits INSIDE the group, so the group's gap sets icon->label and
           label->badge at once. 6 -> 4 therefore lands both on the diamond
           pill's numbers in one move -- and it is a decrease, which is the half
           the owner called out. Desktop needs nothing: it already renders 2 and
           6, which is the diamond pill at 1440 exactly. */
        gap: 4px;
    }
    body.sf-ring-archive .sf_ring_filters .sf_filters_icon,
    body.sf-ring-archive .sf_ring_filters .sf_filters_icon svg {
        width: 11px;
        height: 11px;
    }
    body.sf-ring-archive .sf_ring_filters .sf_filters_icon svg path {
        stroke: #FAF3ED;
        fill: none;
    }

    /* --- the setting card -- 14514:41709, 177x340, image 177x160 ---------- */
    body.sf-ring-archive ul.products > li.product .product_image_container img,
    body.sf-ring-archive ul.products > li.product img.wp-post-image {
        aspect-ratio: 177 / 160;
        height: auto;
        object-fit: cover;
    }
    /* 14514:39488: the selected card gains a 2px OUTSIDE stroke. Drawn as a
       shadow so the card's box -- and therefore the row -- does not move. */
    body.sf-ring-archive ul.products > li.product.sf-selected {
        box-shadow: 0 0 0 2px #27423B;
        border-radius: 4px;
    }

    /* --- 3.3 Loading -- 14514:39301 -------------------------------------- */
    html.sf-loading body.sf-ring-archive .sf_ring_chrome,
    html.sf-loading body.sf-ring-archive ul.products {
        opacity: 0.15;
        filter: blur(4px);
        pointer-events: none;
    }
    html.sf-loading body.sf-ring-archive .sf_ring_spinner {
        display: block;
        position: fixed;
        left: 50%;
        top: 45%;
        z-index: 30;
        width: 50px;
        height: 50px;
        margin: -25px 0 0 -25px;
        padding: 13px;
    }
    html.sf-loading body.sf-ring-archive .sf_ring_spinner_ring {
        display: block;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        opacity: 0.8;
        /* 14514:39487 is an ANGULAR gradient #27423B -> #C4C4C4 alpha 0. */
        background: conic-gradient(from 0deg, #27423B 0deg, rgba(196, 196, 196, 0) 340deg);
        -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
                mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
        animation: sf-spin 0.9s linear infinite;
    }
}

@keyframes sf-spin { to { transform: rotate(360deg); } }

/* ===========================================================================
   8. 3.1 AT DESKTOP -- the owner note, not an invention.

   ELEMENTS 14.2.1 is blunt: every Flow 3 artboard is 390, so there is NO
   desktop drawing for the stone archive. 14.1 is equally blunt about where the
   answer comes from instead: *"the stone archive's FILTERS should wear the BYR
   component's treatment"*, and that treatment is already written and shipped in
   components/ringbuilder/redesign/_advanced-search-desktop.css (board
   14468:42834, "2.1 Advanced Search", 1728x1100). That sheet is scoped to
   `#ssq_diamond_search` and is NOT enqueued on the archive -- MEASURED, the
   archive loads diamond-search.css + stone-first.css only -- so its MODEL is
   restated here against `#diamond_search.sf_archive`. Every number below is
   that file's, not one of mine:

     page gutter 80 / 1728          = 4.6296296296%   (--dsq-d-gutter)
     content                          1568
     filter rail 345 / 1568         = 22.0025510204%, floored at 280px
     rail -> grid gutter 89 / 1568  = 5.6760204082%
     results grid  repeat(auto-fill, minmax(220px, 1fr)), fixed 24px gap
                                    -> 4 x 265.5 at 1728, 3 at 1280, 2 at 992

   MEASURED BEFORE: gutter 144, content 1440, rail 336 at x156, rail->grid 13,
   grid 1079 in 3 columns of 359.7. Every one of those is the theme's old
   archive geometry, not the BYR model.

   THE TRAP, verbatim from 14.1: `.result_grid_item_container` carries bootstrap
   `col-6 col-lg-4`, and `width: 33.333%` resolves against the GRID TRACK rather
   than the row once the parent becomes a grid -- which is what produced 88.6px
   cards. The container's width/flex/padding are therefore neutralised
   explicitly, not left to specificity.

   WHAT THIS DOES NOT DO, and why: 14.2.3 says the board gives nothing for the
   stone card above 390 and that the advanced-search desktop card is a DIFFERENT
   component with a different internal stack -- so the TRACK is set to the BYR
   model's 265 and the card's internal stack is left as it is. It is carried up,
   not designed. Same for the header's two 128/68 bands, which are a separate
   component and are not attempted here.
   =========================================================================== */

@media (min-width: 992px) {
    /* 80px page gutter, 1568 content. The theme sets this as a 144px margin on
       .container; it is replaced rather than added to. */
    #diamond_search.sf_archive > .container {
        width: auto;
        max-width: none;
        margin-left: 4.6296296296%;
        margin-right: 4.6296296296%;
        padding-left: 0;
        padding-right: 0;
    }

    /* rail | gutter | grid, as one grid line so the 280px floor and the 89px
       gutter can both be expressed. Bootstrap's -12px row margin and the two
       columns' 12px padding are all removed: they are what made the rail 336
       and the rail->grid gutter 13. */
    #diamond_search.sf_archive > .container > .row {
        display: grid;
        grid-template-columns: minmax(280px, 22.0025510204%) 1fr;
        column-gap: 5.6760204082%;
        margin-left: 0;
        margin-right: 0;
    }
    #diamond_search.sf_archive .search_filters_container,
    #diamond_search.sf_archive .search_container {
        width: auto;
        max-width: none;
        flex: none;
        padding-left: 0;
        padding-right: 0;
        min-width: 0;
    }
    #diamond_search.sf_archive .search_filters {
        width: 100%;
    }

    /* The three wrappers between .search_container and the cards each add a
       12px padding or a -12px row margin; zeroing them is what makes the grid
       box exactly 1134 = 1568 - 345 - 89. */
    /* width:100%, NOT auto: .search_results_grid_container is a `flex: 0 0 auto`
       item of .search_content.row, so `width:auto` sized it to its content and
       the grid came back 725 wide instead of 1134. MEASURED. */
    #diamond_search.sf_archive .diamond_search_results,
    #diamond_search.sf_archive .search_content.row,
    #diamond_search.sf_archive .search_results_grid_container {
        width: 100%;
        max-width: none;
        margin-left: 0;
        margin-right: 0;
        padding-left: 0;
        padding-right: 0;
    }

    /* auto-fill / minmax(220, 1fr) with a FIXED 24px gap. */
    #diamond_search.sf_archive .search_results_grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
        gap: 24px;
        margin-left: 0;
        margin-right: 0;
        /* MEASURED at 1728: grid [514, 330, 1134] with the last card's bottom
           ON the grid's own bottom -- no gutter under the final row at all --
           and the run starting hard against the toolbar above it. 10 and one
           full 24px row-gutter, matching the in-quiz grid exactly.

           Horizontal stays 0 and that is deliberate: the grid IS the column
           band (514 / 1134 here, the same as the quiz mount) and the chrome
           above is aligned to it, so side padding would pull the cards inside
           controls that do not move. */
        /* SIDES: the owner's call, made twice. I argued against it -- the grid
           IS the column band (514 / 1134 at 1728) and the chrome above is
           aligned to its edges, so 10px inside pulls the cards off the view
           toggle on the left and the Shortlist segment on the right -- and the
           owner came back with the declaration again. Their page, their call;
           the reasoning is left here rather than the change being re-litigated
           a third time. Column counts and the merch band are unaffected: at
           1728 the tracks go 266 -> 260.5 and the count stays 4. */
        padding: 10px 10px 24px;
    }
    /* THE TRAP. col-6/col-lg-4 must not resolve against the track. */
    #diamond_search.sf_archive .search_results_grid > .result_grid_item_container {
        width: auto;
        max-width: none;
        flex: none;
        margin: 0;
        padding: 0;
    }
    /* `dense`, because the band is a full-row item that can only START in column
       1. The band is the 9th child, so wherever 8 does not divide by the column
       count the band cannot be placed in the row it falls in and is pushed to
       the next one, leaving that row part-empty. MEASURED, scrolled to the
       band, before this:
           1920 / 5 cols   5 cards | 3 cards + TWO HOLES | band
           1440 / 3 cols   3 | 3 | 2 cards + ONE HOLE | band
           1728 / 4 cols   clean -- only because 8 / 4 divides
           1100 / 2 cols   clean -- likewise
       `dense` lets the cards that come AFTER the band in the DOM back-fill
       those holes, so every row before it is full at every column count. It
       changes the visual order of the cards around the band and nothing else;
       the drawer's grid has run dense since it shipped for the same reason. */
    #diamond_search.sf_archive .search_results_grid {
        grid-auto-flow: row dense;
    }
    /* The band is a full-row item in the grid, not a 265 cell. */
    #diamond_search.sf_archive .search_results_grid > .sf_insert_row,
    #diamond_search.sf_archive .search_results_grid > .col-12:has(> .grid_promo) {
        grid-column: 1 / -1;
        width: auto;
        max-width: none;
        flex: none;
        margin: 0;
        padding: 0;
    }
}

/* ===========================================================================
   8b. 3.1 AT DESKTOP -- THE TWO HEADER BANDS AND THE TOOLBAR
   ELEMENTS 14.1, the stone-archive row, verbatim: "header band 1 `128` tall
   over band 2 `68`, both #FAF3ED, band-1 bottom hairline 0.75 #E4DED8 ... the
   80px gutter declared ONCE on the header so the controls keep padding-left:0",
   "Toolbar controls: sort / view / segmented all 44 tall, segmented radius 8 on
   desktop, Filters pill 116 x 44 at x 80. Header titles gap 21, result count
   18px", "Footer band 120 tall (--dsq-d-footer)". Every number is
   components/ringbuilder/redesign/_advanced-search-desktop.css's, restated
   here because that sheet is scoped to #ssq_diamond_search and is not enqueued
   on the archive.

   MEASURED BEFORE at 1728: the legacy .diamonds_search_header was 1728x120.2
   at a 156 gutter with a 49px/58.8 title and a marketing paragraph on the
   right, over an 84-tall toolbar row that lived INSIDE the results column at
   x515 -- so the Filters pill could never reach x80, and .sf_segmented /
   .sf_filters were display:none (they sit inside .results_count.mobile_count,
   which is bootstrap d-lg-none). The toolbar is therefore MOVED to be a direct
   child of #diamond_search at >=992 (stone-first.js homeToolbar), which is the
   only way the band can start at the page gutter rather than at the grid
   column. It is moved, not re-created: diamond-search.js:133 binds the sort
   handlers directly to the element and moving a node keeps its listeners.

   WHAT THE BOARD DOES NOT GIVE, and is therefore carried up rather than
   designed (14.2): the breadcrumb has no desktop drawing at all -- it keeps the
   mobile 12px ramp on a 20px line, which is what makes band 1 add up to 128
   (24 pad + 20 crumb + 37 title + 21 gap + 18 count = 120, +8). Said plainly so
   nobody reads the 24 or the 20 as a measurement.
   =========================================================================== */

@media (min-width: 992px) {
    body.sf-stone-archive {
        --dsq-d-gutter:    4.6296296296%;   /*   80 / 1728  */
        --dsq-d-rail:     22.0025510204%;   /*  345 / 1568  */
        --dsq-d-rail-min:        280px;     /* RESPONSIVE MODEL note 1 */
        --dsq-d-rail-gap:  5.6760204082%;   /*   89 / 1568  */
        --dsq-d-band1:           128px;
        --dsq-d-band2:            68px;
        --dsq-d-footer:          100px;   /* was 120 -- see the band rule below */
    }

    /* --- BAND 1 ---------------------------------------------------------- */
    body.sf-stone-archive section.diamonds_search_header {
        box-sizing: border-box;
        height: var(--dsq-d-band1);
        padding: 24px 0 0;
        background: var(--sf-page, #FAF3ED);
        /* The hairline spans the full 1728 INCLUDING the gutter, so it is the
           section's own border -- the section is the full-bleed node and the
           gutter lives on the .container inside it. */
        border-bottom: 0.75px solid #E4DED8;
    }
    body.sf-stone-archive section.diamonds_search_header > .container {
        width: auto;
        max-width: none;
        margin-left: var(--dsq-d-gutter);
        margin-right: var(--dsq-d-gutter);
        padding-left: 0;
        padding-right: 0;
    }
    body.sf-stone-archive section.diamonds_search_header > .container > .row {
        display: block;
        margin-left: 0;
        margin-right: 0;
    }
    body.sf-stone-archive section.diamonds_search_header > .container > .row > [class*="col-"] {
        width: 100%;
        max-width: none;
        flex: none;
        padding-left: 0;
        padding-right: 0;
    }
    /* The marketing paragraph is not on board 3.1 at ANY width -- it is already
       hidden at <=991 (section 1). Band 1 is title + count. */
    body.sf-stone-archive .diamonds_search_header .page_subhead {
        display: none;
    }
    body.sf-stone-archive .diamonds_search_header .breadcrumbs {
        margin: 0;
    }
    /* ---- THE HEADER'S TYPE AND RHYTHM, AS THE OWNER SPECIFIED IT ----------
       Owner, with the rule written out: the breadcrumb at 14/20 in #3E3C39 at
       80% opacity, the padding above it 12 rather than 24, 12 between the
       breadcrumb and the heading, and the results line at 16.

       MEASURED before, at 1440 on /lab-grown-diamonds/: breadcrumb 12px
       #202020 at opacity 1, `.diamonds_search_header` padding-top 24,
       breadcrumb bottom y178 against a heading top y178 (a gap of 0), and
       `.results_count` at 18px.

       `opacity` on the nav rather than a lighter ink: it is what was asked for,
       and it keeps the separator glyphs and the links at one weight -- a colour
       would have had to be restated on every child. */
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb,
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb a {
        display: block;
        padding: 0;
        margin: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 20px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: lowercase;
        color: #3E3C39;
        font-style: normal;
        opacity: 0.8;   /* owner's correction: 0.8, not the 0.7 first given */
    }
    body.sf-stone-archive .diamonds_search_header nav.woocommerce-breadcrumb a {
        display: inline;
        /* the nav already carries the 0.7; compounding it on the link would
           make the links lighter than the text around them */
        opacity: 1;
    }
    /* `section.` and the id-free class both matter here: the rule this has to
       beat is `body.sf-stone-archive section.diamonds_search_header
       { padding: 24px 0 0 }` further down this sheet -- a SHORTHAND, so it
       re-sets padding-top wholesale, at (0,2,1) against a bare (0,2,0). Matching
       its element qualifier makes this (0,2,1) too, and it is declared later. */
    body.sf-stone-archive section.diamonds_search_header { padding-top: 12px; }
    /* 12 between the breadcrumb and the title. Stated on the breadcrumb's own
       wrapper rather than on the heading: `.breadcrumbs` is zeroed four rules
       above this, so this is the one box between the two. */
    /* 24, not the frame's 12. Owner, looking at it on the page: *"give some
       space between breadcrumbs and heading, and move heading and results
       close -- just move down the Lab Diamond Search heading."* So the heading
       drops 12 and the results come up 13 to meet it: the block keeps its
       height and the title reads as one unit with its count instead of sitting
       midway between the two. Applies to lab, natural and /diamonds/ alike --
       they are one template. */
    body.sf-stone-archive .diamonds_search_header .breadcrumbs { margin-bottom: 24px; }
    /* Named the same way the font-size override had to be: a later
       `p.results_count.sf_title_count` rule carries the 21, and a tie on
       specificity loses to source order. MEASURED: this computed 21 until the
       element and both classes were spelled out. */
    body.sf-stone-archive .diamonds_search_header p.results_count.sf_title_count { margin-top: 8px; }
    /* `p.results_count.sf_title_count` (0,3,1) sets 18 further down the sheet;
       this needs to outrank it, not just follow it. */
    body.sf-stone-archive .diamonds_search_header p.results_count.sf_title_count {
        font-size: 16px;
        line-height: 16px;
    }
    /* page title 24 -> 37 (14.1: "Type sizes stay fixed ... page title 24->37") */
    body.sf-stone-archive section.diamonds_search_header .search_title h1,
    body.sf-stone-archive section.diamonds_search_header .search_title h3 {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 37px;
        line-height: 37px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: #0F0E0D;
        margin: 0;
        padding: 0;
    }
    /* result count 14 -> 18, header titles gap 21 */
    body.sf-stone-archive p.results_count.sf_title_count {
        display: block;
        margin: 21px 0 0 0;
        padding: 0;
        border: 0;
        background: none;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #3E3C39;
        text-align: left;
    }
    body.sf-stone-archive p.results_count.sf_title_count:not(.sf-has-count) {
        visibility: hidden;
    }

    /* --- BAND 2, the toolbar --------------------------------------------- */
    /* 68 = 12 + 44 + 12. The gutter is declared here once so every control
       keeps padding-left: 0 and the Filters pill lands at x 80. */
    #diamond_search.sf_archive > .sf_toolbar_d {
        display: flex;
        align-items: center;
        gap: 24px;
        box-sizing: border-box;
        width: 100%;
        height: var(--dsq-d-band2);
        margin: 0;
        padding: 12px var(--dsq-d-gutter);
        background: var(--sf-page);
        border: 0;
    }
    /* the count is band 1's, not band 2's */
    #diamond_search.sf_archive > .sf_toolbar_d > p { display: none; }

    /* Filters pill 116x44 at x80. The view toggle after it has to line up with
       the first grid column, and that offset is the rail plus the rail gutter
       less the pill and the flex gap -- 345 + 89 - 116 - 24 = 294 at 1728 --
       expressed in the same fluid units as the body grid so it tracks down to
       992. max() so it also tracks the rail's 280px floor. */
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters {
        order: -1;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 2px;
        /* 132, THE SAME AS ONE SEGMENTED HALF (the 266 track carries two 1px
           strokes, so its halves are 132 each). Owner: *"all stones / shortlist
           and the filters buttons -- different widths, all need to be
           uniform."* The board's 116 made the row read 116 / 132 / 132. */
        flex: 0 0 132px;
        width: 132px;
        height: 44px;
        /* CLAMPED. The offset that lines the view toggle up with the first grid
           column is rail + rail-gap - 140, and below ~1180 the row's fixed
           parts (116 pill + 120 toggle + 265 sort + 266 segmented + three 24px
           gaps) plus that offset exceed the content box -- AUDITED,
           documentElement.scrollWidth 1104 against a 1024 viewport and 1112
           against 1100, i.e. a real horizontal scrollbar on ordinary laptop
           widths. Clean again by 1180.

           The offset is a nicety (alignment with the grid); the overflow is
           not, so it yields. `min()` against the space actually left over is
           the same clamp _advanced-search-desktop.css already applies to the
           drawer's copy of this row, for the same reason.

           864 is MEASURED, not estimated: the pill 116 + the controls block 434
           + the segmented 266 + the two 24px flex gaps. The percentage in a
           margin resolves against the flex container's content box, so at 992
           that leaves 900.16 - 864 = 36.16 for the offset and the row fits
           exactly. A first pass used 811 and still overflowed 7px at 992 -- the
           arithmetic, not the approach, was wrong. At 1728 the unclamped 294
           still wins, so the design width is untouched. */
        margin: 0 min(
            calc(max(var(--dsq-d-rail-min), var(--dsq-d-rail)) + var(--dsq-d-rail-gap) - 156px),
            max(0px, calc(100% - 864px))
        ) 0 0;
        padding: 0 12px;
        border: 1px solid var(--sf-green);
        border-radius: 8px;
        background: var(--sf-green);
        color: var(--sf-page);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_group {
        display: inline-flex;
        align-items: center;
        gap: 2px;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_icon,
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_icon svg {
        width: 18px;
        height: 18px;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_icon { display: inline-flex; }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_icon svg path {
        stroke: var(--sf-page);
        fill: none;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 22px;
        height: 22px;
        margin-left: 4px;
        border-radius: 50px;
        background: var(--sf-badge);
        color: var(--sf-page);
        font-size: 14px;
        line-height: 19px;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_filters_badge.is-empty { display: none; }

    /* view toggle + sort, both 44 tall */
    #diamond_search.sf_archive > .sf_toolbar_d .search_view_options {
        order: 0;
        display: flex;
        align-items: center;
        /* Declared as a token because the rule below has to cancel exactly this
           value; stated twice as a literal it would drift the moment one moved. */
        --sf-toolbar-gap: 24px;
        gap: var(--sf-toolbar-gap);
        width: auto;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .result_view {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 60.5px;
        height: 44px;
        margin: 0;
    }
    /* THE TWO HALVES ARE ONE CONTROL, and the toolbar's group gap was splitting
       it. 60.5 is not a button width, it is 121 / 2: the pair is a single
       121 x 44 segmented box, built the way segmented boxes are -- the left half
       carries `border-radius: 4px 0 0 4px` with all four borders, the right half
       `0 4px 4px 0` with NO left border, so the left half's right border is the
       divider between them.

       `gap: 24px` is right BETWEEN GROUPS -- the pair and the sort dropdown --
       and wrong inside one. MEASURED at 1728: grid half 514..575, list half
       598..659, i.e. 23px of daylight, with the right half's missing left border
       leaving that edge open and its left corners square against nothing. The
       owner's "they separated and the border and corners not visible properly"
       is both of those at once, and one gap caused them.

       Cancelled only between adjacent halves, so the sort dropdown keeps its
       24. */
    #diamond_search.sf_archive > .sf_toolbar_d .search_view_options > .result_view + .result_view {
        margin-left: calc(-1 * var(--sf-toolbar-gap));
    }
    #diamond_search.sf_archive > .sf_toolbar_d .diamond_sort_by {
        display: block;
        width: 265px;
        height: 44px;
        margin: 0;
    }

    /* segmented 266x44, radius 8 (mobile keeps 10 on the BYR control; this one
       is r8 at both widths -- 3.1.13 is r8), end-aligned in the band. */
    #diamond_search.sf_archive > .sf_toolbar_d .sf_segmented {
        order: 1;
        display: flex;
        flex: 0 0 266px;
        width: 266px;
        height: 44px;
        margin-left: auto;
        border: 1px solid var(--sf-line);
        border-radius: 8px;
        background: var(--sf-page);
        overflow: hidden;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_seg {
        flex: 1 1 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 4px;
        height: 42px;
        margin: 0;
        padding: 0 4px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        color: var(--sf-green);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: -0.5px;
        text-decoration: none;
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_seg.is-active {
        background: var(--sf-green);
        color: var(--sf-page);
        border-radius: 6px;   /* r8 track, 1px inside stroke -- see above */
    }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_seg[disabled] { opacity: .45; cursor: default; }
    #diamond_search.sf_archive > .sf_toolbar_d .sf_seg_icon {
        display: inline-flex;
        width: 13px;
        height: 12px;
        color: currentColor;
    }

    /* The legacy rule is `.search_view_options .diamond_sort_by { display:none }`
       inside the mobile query only, so nothing above hid it -- but the old
       desktop toolbar ALSO printed a duplicate count and a full-width rule. */
    /* `!important` is not decoration. Bootstrap's display utilities are
       `.d-lg-block { display: block !important }`, so every one of the three
       selectors below lost to it and the rule did nothing: MEASURED, the <hr>
       still computed display:block at [88,415 1544x1] and painted a 1px
       #E4DED8 line straight across the first row of card photos
       (elementsFromPoint(900,415) returned HR above IMG). 3.1 draws no rule
       anywhere across the grid -- the rail and the grid are two columns with
       nothing between them. */
    #diamond_search.sf_archive .diamond_search_results > hr,
    #diamond_search.sf_archive > .container > .row > hr,
    #diamond_search.sf_archive hr.d-none.d-lg-block {
        display: none !important;
    }

    /* --- THE FILTERS PILL COLLAPSES THE RAIL ------------------------------
       On the archive the rail is always in the page (it is not a drawer), so
       the pill cannot re-use the mobile `.filters_mobile_toggle` path -- that
       node is bootstrap d-lg-none and its handler opens a drawer that does not
       exist here. It collapses the rail TRACK instead: the rail stays in the
       DOM with every filter control bound exactly as it was, so nothing the
       filter JS reads can go missing. */
    /* EASED, not snapped. Owner: *"on non-BYR filters does what it's intended
       to, but the animation looks messy when the search takes up the space."*
       There was no animation at all -- the rule swap below moved the grid from
       two tracks to one in a single frame. The transition lives on the ROW
       because the track list is what changes; the counts match either side
       (two before, two after), which is what `grid-template-columns` needs to
       interpolate. Same 340ms and curve as the drawer, so the two surfaces
       cannot drift. */
    #diamond_search.sf_archive > .container > .row {
        transition: grid-template-columns 340ms cubic-bezier(0.2, 0.7, 0.3, 1),
                    column-gap 340ms cubic-bezier(0.2, 0.7, 0.3, 1);
    }
    #diamond_search.sf_archive.sf-rail-collapsed > .container > .row {
        grid-template-columns: 0 1fr;
        column-gap: 0;
    }
    #diamond_search.sf_archive .col-lg-3.search_filters_container {
        transition: opacity 180ms cubic-bezier(0.4, 0, 0.2, 1);
    }
    #diamond_search.sf_archive.sf-rail-collapsed .col-lg-3.search_filters_container {
        visibility: hidden;
        overflow: hidden;
        width: 0;
        min-width: 0;
        opacity: 0;
        /* visibility is held until the track has finished closing, so the panel
           fades out first instead of being clipped away mid-fade. */
        transition: opacity 180ms cubic-bezier(0.4, 0, 0.2, 1),
                    visibility 0s linear 340ms;
    }
    #diamond_search.sf_archive.sf-rail-collapsed > .sf_toolbar_d .sf_filters {
        margin-right: 0;
        background: var(--sf-page);
        color: var(--sf-green);
    }
    #diamond_search.sf_archive.sf-rail-collapsed > .sf_toolbar_d .sf_filters_icon svg path {
        stroke: var(--sf-green);
    }

    /* --- FOOTER BAND -- 3.1.43 at desktop ---------------------------------
       14.2.4 records that the board gives NOTHING for the sticky ADD TO RING
       bar above 390. 14.1's answer for this flow is the BYR footer band, and
       this is it: 1728x120, #FAF3ED, 1px #E4DED8 top rule, pad 27/gutter/10,
       the CTA cluster right-aligned. Carried up, not designed -- said plainly.
       Before this, selecting a card at 1728 raised nothing at all. */
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas,
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 40;
        box-sizing: border-box;
        /* 100, down from 120. Owner, with the band boxed again after the first pass:
           *"the bottom bar still looks wide -- I guess there's more space in the
           bottom below the CTA."* The first pass moved the three bands that are
           built from the BYR footer shape; these two are the advanced search's and
           the stone archive's own copies of the same 120/27/10 and were missed.
           MEASURED: a 48 CTA at `align-items: flex-start` under 27 of top padding
           leaves 45 below it in a 120 box -- the space he is pointing at. 100 with
           24/24 leaves 52 of content box for a 48 CTA: 4 under, even top and
           bottom. The gutter is untouched, for the reason recorded on the first
           pass -- it is what holds the CTA on the grid's right edge. */
        height: var(--dsq-d-footer, 100px);
        padding: 24px var(--dsq-d-gutter, 4.6296296296%);
        flex-direction: row;
        align-items: flex-start;
        justify-content: flex-end;
        gap: 36px;
        background: var(--sf-page);
        border-top: 1px solid var(--sf-line);
    }
    /* SCOPED TO THE BAR, NOT TO `.sf-has-selection` -- WHICH IS WHY THE CTAs
       FLASHED UNSTYLED ON DESELECT.
       Owner: *"when I click and unclick a diamond card, for a fraction of a
       second an unstyled structure appears for the bottom bar."* Exactly that,
       and the asymmetry just above is the cause: the BAR is raised by
       `.sf-has-selection` OR `.sf-ctas-closing` (stone-first.js holds the
       second for the length of the fall animation), but every CHILD rule was
       gated on `.sf-has-selection` alone. So on deselect the classes swap, the
       bar stays displayed for the ~320ms fall -- and its three CTAs match no
       rule at all for that whole window. Browser defaults take over: MEASURED
       on the archive, `border: 2px outset` / `background: rgb(239,239,239)` on
       `.dsq_cta`, i.e. native buttons, which is the screenshot.

       Gating the children a second time bought nothing: the bar is
       `display: none` at every width unless one of those two classes is on the
       root, so a child cannot be seen without it. Dropping it makes them track
       the bar's own visibility rather than a subset of it. The phone block
       above was already written this way, which is why this only showed at
       desktop. */
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_add_to_ring,
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_secondary {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 282px;
        flex: 0 0 282px;
        height: 48px;
        padding: 0;
        border-radius: 4px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        cursor: pointer;
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_add_to_ring {
        order: 3;
        border: 1px solid var(--sf-green);
        background: var(--sf-green);
        color: var(--sf-page);
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_secondary {
        order: 2;
        border: 1px solid var(--sf-green);
        background: var(--sf-page);
        color: var(--sf-green);
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .sf_cta_arrow {
        display: inline-flex;
        width: 12px;
        height: 10px;
    }
    #diamond_search.sf_archive .dsq_sticky_ctas .dsq_cta_link {
        order: 1;
        display: inline-flex;
        align-items: center;
        /* ON THE BUTTONS' LINE, not the bar's. `align-self: center` centred this
           link in the bar's CONTENT BOX -- 807..890 once the 27/10 padding is
           taken off -- while the two buttons sit at the TOP of that same box
           under the bar's `align-items: flex-start`. MEASURED at 1728: both
           buttons y808 h48, centre 832; this link y835 h28, centre 849. 17px
           adrift, which is the owner's "not in line with the other two CTAs".

           Matching the buttons' 48 and top-aligning gets the centres to agree
           without anyone having to know the bar's padding: the link is now the
           same height as the things beside it, sits at the same top edge, and
           its own `align-items: center` keeps the text centred inside it. The
           underline still sits under the text, not under a 48px box, because
           the box is inline-flex around the text node. */
        align-self: flex-start;
        height: 48px;
        color: var(--sf-green);
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-decoration: underline;
    }
    /* Scroll compensation moved to body.sf-selection-open (foot of sheet):
       > .container cannot reach the site footer, which is where the band's
       120px actually land. */
}

/* ===========================================================================
   8c. 3.1 AT DESKTOP -- THE STONE CARD, AND THE BAND'S SCROLL COMPENSATION

   ELEMENTS 14.2.3 says the board gives nothing for the stone card above 390,
   and 14.1 says the advanced-search desktop card is a DIFFERENT component with
   a different internal stack -- so nothing here designs a desktop card. What it
   does is carry up the four properties that are the CARD COMPONENT's, not the
   390 artboard's, and that the >=992 build had simply never been given because
   every one of them was written inside `@media (max-width: 991px)`:

     3.1.26  clip + radius 4          MEASURED at 1728: overflow `visible`,
                                      border-radius `0px` -- the radius could
                                      not clip the photo.
     3.1.26  selected = 2px #27423B   MEASURED at 1728: box-shadow `none` on
             OUTSIDE stroke           `.result_grid_item_container.active` --
                                      the selected card was indistinguishable
                                      from an unselected one even though the
                                      ADD TO RING band rose. At 390 the same
                                      card measured rgb(39,66,59) 0 0 0 2px.
     3.1.27  "Image / Fill container" MEASURED at 1728: a 265.3x265.3 SQUARE
             (note 14514:41732)       photo at object-fit `contain`, i.e.
                                      letterboxed. The board's image is 177x160;
                                      at a 265.3 track that is 239.8, which is
                                      also what 3.3's desktop card already deals
                                      (265.5x240, section 7). Same ratio, same
                                      fit -- carried up, not invented.
     3.1.32  21px / 18px once wrapped No CTAs are drawn on the card anywhere on
             + no in-card CTAs        the board; the commit lives in the band.
                                      MEASURED at 1728: two visible in-card
                                      buttons and fs 21px on every 2-line title.

   The card's 503.8 height is NOT forced to a number here. 177x300 scaled is not
   a desktop design and 14.2.3 says so; the height follows the content once the
   photo stops being square.
   =========================================================================== */

@media (min-width: 992px) {
    /* clip + radius, so the 4px corner actually cuts the photo */
    #diamond_search.sf_archive .result_grid_item {
        position: relative;
        border-radius: 4px;
        overflow: hidden;
        box-shadow: 0 0 0 0 transparent;
        transition: box-shadow .12s linear;
        cursor: pointer;
    }
    #diamond_search.sf_archive .result_grid_img {
        overflow: hidden;
        border-radius: 4px 4px 0 0;
    }
    /* 3.1.26 selected. A shadow, not a border: the card's box must not grow or
       the auto-fill track reflows under the selection. */
    #diamond_search.sf_archive .result_grid_item_container.active .result_grid_item {
        box-shadow: 0 0 0 2px var(--sf-green);
    }

    /* 3.1.27 image 177:160, FILL. */
    #diamond_search.sf_archive .result_grid_img,
    #diamond_search.sf_archive .result_grid_img > a,
    #diamond_search.sf_archive .result_grid_img img {
        aspect-ratio: 177 / 160;
        width: 100%;
        height: auto;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .result_grid_img > a {
        display: block !important;   /* base sheet ships display:contents */
    }
    #diamond_search.sf_archive .result_grid_img img {
        object-fit: cover;
        object-position: center;
    }

    /* 3.1.32 title ramp. stone-first.js stamps .sf-title-wrapped from the
       rendered line count at every width now, so the two sizes the note gives
       are both reachable here. */
    #diamond_search.sf_archive .grid_result_title a {
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 21px;
        line-height: 24px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: var(--sf-ink);
        text-decoration: none;
    }
    #diamond_search.sf_archive .grid_result_title.sf-title-wrapped a {
        font-size: 18px;
        line-height: 22px;
    }

    /* The board draws no CTA on the card at any width (3.1.26 lists image +
       text block and nothing else; the commit is the band's). The card's own
       button.grid_add_to_ring is NOT removed -- it is the real handler the
       band's primary proxies to (diamond-search.js:1685 resolves `this` from
       inside the card), so it is hidden, exactly as at <=991. */
    #diamond_search.sf_archive .result_grid_item .grid_result_button {
        display: none;
    }
}

/* --- SCROLL COMPENSATION FOR THE RAISED BAND -------------------------------
   The band is position:fixed, so what it covers is the last N pixels of the
   DOCUMENT -- and the site footer is a sibling of #diamond_search, outside
   every node the component can pad. `.search_container` (<=991) and
   `> .container` (>=992) both pad the wrong box. stone-first.js stamps
   `sf-selection-open` on <body> alongside the component's own
   `sf-has-selection`, and the two heights hang off that.
   MEASURED at 1728 before this: scrolled fully down, the footer's bottom edge
   was 999.9 in a 1000-tall viewport with the band at 880-1000. */
body.sf-selection-open { padding-bottom: 178px; }
@media (min-width: 992px) {
    body.sf-selection-open { padding-bottom: 120px; }
}


/* ===========================================================================
   9. 3.1 AT DESKTOP -- THE FILTER RAIL'S INTERNALS AND THE CARD
   Board 14468:42834 "2.1 Advanced Search" 1728x1100, the link the owner sent
   with: *"style the filters + show of cards area like the drawer's advanced
   lab/natural diamond search -- just that the 'advanced lab diamond search'
   header and all those headers must not be there, they must stay how it is
   now."* So this section restyles the RAIL and the CARD only. The archive's own
   two header bands and toolbar are section 8b's and are not touched, and none
   of the drawer's chrome (screen header, close X, sort/view/segmented, the
   fixed footer CTA band) is brought across.

   Section 8 already carried up the drawer's LAYOUT -- the 80px gutter, the
   345 | 89 | 1134 rail/grid split, the 24px grid gap. What it explicitly did
   not do is the rail's INTERNALS, and MEASURED at 1728 that is the whole of
   the remaining difference against the board:

       section rhythm    board 36    was ~50, and a hairline rule under
                                     every section title the board does not draw
       shape tile        80 x 96     was ~78 x 70, icon ~24 not 32x40,
                                     label 11px not 16px
       text chip         h 42        "Signature Ideal" wrapped to two lines
       carat input       80 x 40     was ~105 x 28
       price input      110 x 40     was ~105 x 28
       slider handle     26 x 17     was a 16px circle
       ADVANCED FILTERS  344 x 60    unstyled

   Every number below is components/ringbuilder/redesign/_advanced-search-
   desktop.css's, restated rather than shared: that sheet is scoped to
   `#ssq_diamond_search` and is NOT enqueued on the archive, and its `--rb-*`
   tokens come from simple-select-redesign.css which is not enqueued here
   either. The archive's own `--sf-*` set (top of this file) holds the same
   values, so the ported declarations read against those.

   SPECIFICITY, and why there is not one !important below. The legacy rules
   that own the rail today live in diamond-search.css at (0,1,0)/(0,2,0)
   -- `.filter_title`, `.d_filter`, `.filter_buttons button`. Scoping to
   `#diamond_search.sf_archive` is (1,2,0) and wins outright. `.sf_archive` is
   printed by diamond-search.php only when $ds_in_quiz is false, so the quiz
   mount cannot see any of this and the BYR drawer is untouched.

   WHAT THIS DELIBERATELY DOES NOT DO:
   - The rail is NOT made sticky. The drawer stickies it under its own 128+68
     header bands and gives it its own scroller; an archive scrolls as one
     document, and a sticky rail here would need to resolve against the site
     header's height, which is not a number the board gives.
   - `.search_filters > .filters_headers` (the "Filters / Reset" row) is NOT
     hidden, though the board draws no such row. The drawer can hide it because
     its own header carries a Filters pill with a live count; Reset is a real
     control and removing it would drop function, so it is given the section
     rhythm instead.
   =========================================================================== */

@media (min-width: 992px) {

    /* --- RAIL RHYTHM ----------------------------------------------------- */
    /* 36 between sections. The bootstrap .row inside .diamond_filters is what
       carried the old ~50, so the gap is declared on the flex column rather
       than on the children. */
    #diamond_search.sf_archive .diamond_filters,
    #diamond_search.sf_archive .diamond_filters .standard_filters .row > [class*="col-"],
    #diamond_search.sf_archive .diamond_filters #advanced_filters .row > [class*="col-"] {
        display: flex;
        flex-direction: column;
        row-gap: 36px;
        padding: 0;
        margin: 0;
    }
    #diamond_search.sf_archive .diamond_filters .container,
    #diamond_search.sf_archive .diamond_filters .row {
        max-width: none;
        width: 100%;
        margin: 0;
        padding: 0;
        --bs-gutter-x: 0;
    }
    /* height:auto -- section.diamond_filters carries a max-height + overflow in
       diamond-search.css for the mobile drawer, which clipped the rail here. */
    #diamond_search.sf_archive section.diamond_filters,
    #diamond_search.sf_archive .search_filters {
        height: auto;
        max-height: none;
        overflow: visible;
        background: transparent;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options {
        overflow: visible;
    }
    /* diamond-search.css:960, inside its own @media (min-width:992px): the
       results grid is given `height: 1180px`. Nothing in this file neutralised
       it, so MEASURED on the live archive the grid box was exactly 1180 tall
       against the drawer's 10515 -- the desktop grid has been CLIPPED at four
       rows. It is killed here rather than in section 8's layout block because
       it is the same legacy-height family as the rail's 1235 above it. */
    #diamond_search.sf_archive .search_results_grid,
    #diamond_search.sf_archive .search_results {
        height: auto;
        max-height: none;
        overflow: visible;
    }
    /* diamond-search.css:61 gives .search_container a 1px left border. It is a
       vertical rule the board does not draw, and it was also eating the grid's
       last pixel -- MEASURED, rail->grid 90 where the model is 89, grid 1133
       where it is 1134, every card 265.25 against the drawer's 265.5. */
    #diamond_search.sf_archive .search_container {
        border-left: 0;
        border-bottom: 0;
    }

    /* --- A SECTION ------------------------------------------------------- */
    /* title -> body 4, and the title row carries the board's 12 below itself.
       The shape and colour sections' title rows are 60 tall because they hold a
       toggle, and their 12 already separates them -- hence row-gap 0 there. */
    #diamond_search.sf_archive .diamond_filters .d_filter {
        display: flex;
        flex-direction: column;
        row-gap: 4px;
        width: 100%;
        margin: 0;
        padding: 0;
        border: 0;
    }
    #diamond_search.sf_archive .diamond_filters .d_filter:has(.shape_filter),
    #diamond_search.sf_archive .diamond_filters .d_filter:has(.color_filter) {
        row-gap: 0;
    }
    /* border:0 is the hairline the board does not draw. */
    #diamond_search.sf_archive .diamond_filters .filter_title {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        min-height: 31px;
        margin: 0;
        padding: 0 0 12px;
        border: 0;
    }
    #diamond_search.sf_archive .diamond_filters .filter_title:has(.fancy_shapes_toggle),
    #diamond_search.sf_archive .diamond_filters .filter_title:has(.fancy_colors_toggle) {
        min-height: 60px;
    }
    #diamond_search.sf_archive .diamond_filters .filter_title > p {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 4px;
        margin: 0;
        padding: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: rgba(62, 60, 57, 0.80);
    }
    /* the gold info circle, 14x14 */
    #diamond_search.sf_archive .diamond_filters .filter_title > p span {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 14px;
        height: 14px;
        margin: 0;
    }
    #diamond_search.sf_archive .diamond_filters .filter_title > p span img {
        display: block;
        width: 14px;
        height: 14px;
    }

    /* --- THE TWO SEGMENTED TOGGLES (Standard|Antique, White|Fancy) -------- */
    #diamond_search.sf_archive .diamond_filters .fancy_shapes_toggle,
    #diamond_search.sf_archive .diamond_filters .fancy_colors_toggle {
        flex: 0 0 auto;
        display: flex;
        flex-direction: row;
        align-items: center;
        height: 40px;
        box-sizing: border-box;
        padding: 0;
        border: 0.75px solid var(--sf-green, #27423B);
        border-radius: 10px;
        background: transparent;
        overflow: hidden;
    }
    #diamond_search.sf_archive .diamond_filters .filter_toggle_button {
        flex: 0 0 auto;
        min-width: 90.8px;
        height: 100%;
        box-sizing: border-box;
        margin: 0;
        padding: 0 17px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 18px;
        letter-spacing: -0.5px;
        color: var(--sf-green, #27423B);
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .filter_toggle_button.active {
        background: var(--sf-green, #27423B);
        color: var(--sf-page, #FAF3ED);
    }

    /* --- SHAPE TILES ----------------------------------------------------- */
    /* auto-fill at an 80 floor -> 4 across at a 345 rail, and it degrades to 3
       on its own as the rail narrows toward its 280 floor. */
    #diamond_search.sf_archive .diamond_filters .filter_options.shape_filter {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 80px), 1fr));
        column-gap: 8px;
        row-gap: 9px;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button {
        width: auto;
        height: 96px;
        box-sizing: border-box;
        margin: 0;
        padding: 12px 8px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        border: 0.75px solid var(--sf-line, #E4DED8);
        border-radius: 12px;
        background: transparent;
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button svg {
        display: block;
        width: 32px;
        height: 40px;
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button svg path,
    #diamond_search.sf_archive .diamond_filters .shape_filter > button svg g {
        fill: var(--sf-ink-soft, #3E3C39);
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button p {
        margin: 0;
        padding: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: -0.5px;
        color: var(--sf-ink-soft, #3E3C39);
        white-space: nowrap;
    }
    /* box-shadow, not outline: the selected tile's 1.5 stroke sits INSIDE the
       88px column pitch, and an outline would have drawn over its neighbour's
       gap at the 80px floor. Same reason the drawer ends on box-shadow. */
    #diamond_search.sf_archive .diamond_filters .shape_filter > button.active {
        border-color: transparent;
        border-radius: 20px;
        outline: none;
        box-shadow: 0 0 0 1.5px var(--sf-green, #27423B);
        background: rgba(194, 206, 178, 0.30);
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button.active svg {
        width: 34px;
        height: 42.5px;
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button.active svg path,
    #diamond_search.sf_archive .diamond_filters .shape_filter > button.active svg g {
        fill: var(--sf-ink, #0F0E0D);
    }
    #diamond_search.sf_archive .diamond_filters .shape_filter > button.active p {
        color: var(--sf-ink, #0F0E0D);
    }
    /* the carousel arrows are a mobile affordance; the grid wraps here */
    #diamond_search.sf_archive .diamond_filters .shape_arrows {
        width: 0;
        height: 0;
        overflow: hidden;
        visibility: hidden;
    }

    /* --- TEXT CHIPS (cut / colour / clarity / the advanced sections) ------ */
    #diamond_search.sf_archive .diamond_filters .filter_options.filter_buttons {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: flex-start;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options.filter_buttons > button {
        /* UNIFORM FILL, NOT TEXT WIDTH. Owner: *"in advanced filters and standard
        filters, both in BYR and non-BYR flow, the buttons are compacted -- they
        just fill as much as the text goes. Get the old behaviour of filling the
        space back; they used to uniformly spread to fill the row."*

        This is a deliberate reversal of the pass recorded above, which sized
        each chip to its own label to match the board. dev-0's base rule is
        `.filter_buttons button { min-width: 0; flex: 1 1 0 }`
        (diamond-search.css:176) -- an equal share of the row for every chip --
        and THIS rule was the only thing overriding it, in both mounts.

        MEASURED before, CUT in a 337px rail: 106 / 73 / 81 / 51, i.e. four
        different widths and a ragged right edge, while every neighbouring group
        filled (SHAPE and CLARITY are grids, COLOR already carries `flex: 1 1 0`).
        That inconsistency inside one rail is what was reported.

        `min-width: 0` is load-bearing and comes from dev-0 too: a flex item will
        not shrink below its min-content width without it, and "Signature Ideal"
        is wider than a quarter of the rail -- so `flex: 1 1 0` alone would leave
        the row ragged exactly as before. With it the chips divide the row evenly
        and long labels wrap inside their own chip.

        `justify-content` above is now inert: there is no leftover space for it to
        distribute. Left in place so reverting is this block alone. */
        flex: 1 1 0;
        min-width: 0;
        width: auto;
        /* GROWS FOR A LABEL THAT WRAPS. With the chips now dividing the row
           evenly (see above), a long label no longer gets a chip sized to it:
           MEASURED at 1728 in a 337px rail, CUT's four chips come out 78 wide
           each and "Signature Ideal" wrapped to two lines inside a box locked
           at 42 -- scrollHeight past clientHeight, i.e. clipped text.
           dev-0 sets no height on these at all; 42 is simply what one line of
           12 + 16 + 12 padding plus the 0.75 borders comes to. Stated as a
           MINIMUM so a single-line chip is unchanged at 42 and a wrapping one
           takes the ~58 it needs. */
        min-height: 42px;
        box-sizing: border-box;
        margin: 0;
        padding: 12px 8px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0.75px solid var(--sf-line, #E4DED8);
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: -0.5px;
        /* WRAPS NOW. This chip used to be sized to its own label, so nowrap was
           free; with the chips dividing the row evenly (see above) the label
           has to fit 78px, and "Signature Ideal" does not. MEASURED with
           nowrap still on: scrollWidth past clientWidth and the text ran out
           of the chip sideways -- the BYR drawer, which never set nowrap,
           wrapped to a clean 58px chip on the same content. `min-height`
           above is what lets this one do the same. */
        white-space: normal;
        color: var(--sf-ink-soft, #3E3C39);
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options.filter_buttons > button.active {
        border-color: transparent;
        outline: none;
        box-shadow: 0 0 0 1.5px var(--sf-green, #27423B);
        background: rgba(194, 206, 178, 0.30);
        color: var(--sf-ink, #0F0E0D);
    }
    /* colour is seven chips on one line, so they share the rail equally */
    #diamond_search.sf_archive .diamond_filters .filter_options.color_filter > button {
        flex: 1 1 0;
        min-width: 0;
        padding: 12px 0;
    }
    /* clarity is a fixed 4-up so FL/IF/VVS1/VVS2 line up over VS1/VS2/SI1/SI2 */
    #diamond_search.sf_archive .diamond_filters .filter_options.clarity_filter {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 8px;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options.clarity_filter > button {
        width: auto;
        padding: 12px 0;
    }

    /* --- CARAT AND PRICE SLIDERS ----------------------------------------- */
    /* two columns so min sits left and max right, with the track spanning both */
    #diamond_search.sf_archive .diamond_filters .nuslider {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        row-gap: 16px;
        width: 100%;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__range {
        display: none;
    }
    /* The 13px side margins are half a handle: the handle is centred on the
       track end, so without them it hangs 13px outside the rail. 16 for price,
       whose handle is 32 wide. */
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__bar {
        grid-column: 1 / -1;
        width: auto;
        height: 8px;
        margin: 4.5px 13px;
        border: 0;
        border-radius: 15px;
        background: var(--sf-line, #E4DED8);
        box-shadow: none;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-connect {
        background: #C2CEB2;
        border-radius: 8px;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle {
        width: 26px;
        height: 17px;
        top: -4.5px;
        right: -13px;
        border: 0;
        border-radius: 16px;
        background: var(--sf-green, #27423B);
        box-shadow: none;
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle::before,
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle::after {
        display: none;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-touch-area {
        transform: none;
    }
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .slider__bar {
        margin: 6.5px 16px;
    }
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .noUi-handle {
        width: 32px;
        height: 21px;
        top: -6.5px;
        right: -16px;
    }
    /* position:static -- the legacy sheet absolutely positions these under the
       track, which is what made them 105x28 and overlap the rail's next section. */
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__input-min,
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__input-max {
        position: static;
        width: 80px;
        height: 40px;
        box-sizing: border-box;
        margin: 0;
        padding: 0 8px;
        border: 1px solid var(--sf-line, #E4DED8);
        border-radius: 8px;
        background: var(--sf-card, #FFFFFF);
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: 0.75px;
        text-align: center;
        color: var(--sf-ink, #0F0E0D);
    }
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .slider__input-min,
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .slider__input-max {
        width: 110px;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__input-min {
        grid-column: 1;
        justify-self: start;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__input-max {
        grid-column: 2;
        justify-self: end;
    }

    /* --- ADVANCED FILTERS CTA -------------------------------------------- */
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button {
        width: 100%;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button > button {
        position: relative;
        width: 100%;
        height: 60px;
        box-sizing: border-box;
        margin: 0;
        padding: 22px 13px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--sf-line, #E4DED8);
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: -0.5px;
        text-transform: none;
        color: var(--sf-ink, #0F0E0D);
        cursor: pointer;
    }
    /* the +/- glyph is pinned right rather than laid out, so the label stays
       optically centred in the 344 the board centres it in */
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button > button > span {
        position: absolute;
        top: 50%;
        right: 13px;
        transform: translateY(-50%);
        width: 24px;
        height: 24px;
        align-items: center;
        justify-content: center;
    }
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button > button > span svg {
        width: 24px;
        height: 24px;
    }

    /* diamond-search.css sets `padding: 15px 5px !important` on these two, which
       is why the cut chips came back 99.5 wide with "Signature Ideal" wrapping
       where the drawer's are 105.5. Matched, !important and all. */
    #diamond_search.sf_archive .diamond_filters .cut_filter > button,
    #diamond_search.sf_archive .diamond_filters .fluorescence_filter > button {
        padding: 12px 8px !important;
    }
    /* diamond-search.css:240 does the same to the supplier chips, with a
       `min-width: unset` alongside it. */
    #diamond_search.sf_archive .diamond_filters .supplier_filter > button {
        padding: 12px 8px !important;
    }

    /* --- THE "Filters / Reset" ROW --------------------------------------- */
    /* Kept (see the header note) but put on the rail's own rhythm instead of
       the legacy 20px margins, so it reads as the rail's first row. */
    #diamond_search.sf_archive .search_filters > .filters_headers {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        margin: 0 0 36px;
        padding: 0 0 12px;
        border: 0;
    }
    #diamond_search.sf_archive .search_filters > .filters_headers p,
    #diamond_search.sf_archive .search_filters > .filters_headers a,
    #diamond_search.sf_archive .search_filters > .filters_headers button {
        margin: 0;
        padding: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: rgba(62, 60, 57, 0.80);
    }
}

/* ===========================================================================
   9b. 3.1 AT DESKTOP -- THE STONE CARD, AGAINST THE BOARD THAT NOW EXISTS

   Section 8c opens by saying "the board gives nothing for the stone card above
   390, so nothing here designs a desktop card", and that was true of the Flow 3
   section. Board 14468:42834 -- the one the owner sent with this request --
   draws it: 265 x 382, an image block of 241.8 over a 140 text block of
   21 / title / 8 / spec / 8 / price / 21. So the four properties 8c carried up
   stay exactly as they are, and only the text block's rhythm and the image's
   ratio are brought onto the board's numbers here.

   MEASURED at 1728 against the drawer, before this: card 363 vs 381.4, image
   239.8 vs 241.4, title block margin 10/0/0 vs 21/8/0 and 58 tall vs 48, info
   and price both margin 0 vs 8/8/0 and 8/8/21, each inner <p> carrying the
   legacy `padding: 0 5px; margin-bottom: 10px`.

   NOT ported from the drawer: its `.result_grid_img { padding: 12px }` and the
   absolutely-positioned img that goes with it. That padding exists to inset the
   drawer's tag-pill + heart ROW, which is a flow child there. The archive has
   no tag pill and its heart is already absolute, so the same inset is spent on
   the heart's own offsets and the image box is left whole -- adding the padding
   under 8c's `> a { display: block }` + aspect-ratio would have made the <a>
   241.8 tall INSIDE a padded parent and returned a 265-tall image block.
   =========================================================================== */

@media (min-width: 992px) {
    /* equal-height cards in a row: the track stretches, the item fills it, and
       the text block sits under a fixed-ratio image instead of floating. */
    #diamond_search.sf_archive .result_grid_item {
        display: flex;
        flex-direction: column;
        height: 100%;
        box-sizing: border-box;
        background: var(--sf-card, #FFFFFF);
    }
    /* 266 / 241.81818 -- the board's, replacing 8c's 177/160 (239.8 at a 265.3
       track). 1.6px, but it is the difference between the archive card and the
       drawer card being the same object. */
    /* FIXED HEIGHT, NOT AN ASPECT-RATIO -- same correction as the drawer's card,
       and the archive had the identical defect. MEASURED, 100 cards per width:
           1728  card 381.4  image 241.4
           1440  card 411.8  image 271.8
           1280  card 372.6  image 232.6
       The text block under the photo is a constant 140, so the whole CARD grew
       with the column. Design: the card must not resize for the image; the image
       adjusts to the card. The box is pinned at the board's 241.8 and the photo
       fills it, so a wider column crops wider instead of making the card taller.
       `aspect-ratio: auto` on all three cancels section 8c's 177/160. */
    #diamond_search.sf_archive .result_grid_img {
        height: 241.8px;
        aspect-ratio: auto;
    }
    #diamond_search.sf_archive .result_grid_img > a,
    #diamond_search.sf_archive .result_grid_img img {
        width: 100%;
        height: 100%;
        aspect-ratio: auto;
        object-fit: cover;
    }
    #diamond_search.sf_archive .result_grid_img {
        flex: 0 0 auto;
    }
    /* heart 20x18 at 12/12, the board's. It is 16x15 at 10/13 here -- the 390
       treatment carried up. The -12px hit-area ::after from section 3 rides
       along with it. */
    #diamond_search.sf_archive .result_grid_img .sf_card_heart {
        top: 12px;
        right: 12px;
        width: 20px;
        height: 18px;
    }
    #diamond_search.sf_archive .result_grid_img .sf_card_heart svg {
        width: 20px;
        height: 18px;
    }

    /* AND ITS PAINT. The stroke and the saved fill were written ONLY inside
       `@media (max-width: 991px)` (:1025 and :1030), so above 992 the path had
       `fill: none` AND `stroke: none` and drew NOTHING -- the card heart was
       invisible at rest on every desktop width. AUDITED at 992/1100/1440/1728/
       1920: 30 of 30 sampled cards blank, confirmed in pixels (0 dark pixels in
       the heart zone at 1728 against 36 at 390), while the button chrome and
       the click-to-save both measured correct. A working control with no
       affordance.

       This is the THIRD rule in this flow found stranded below 992 -- the same
       as the stone PDP's heart box and its Details & Dimensions columns. The
       breakpoint is where this build's desktop work keeps getting lost.

       Saved stays #C65858 here: that is the stone card's colour on this archive
       at 390 and it is carried up unchanged, NOT quietly aligned to the jade the
       ring cards use. Which of the two is right is a design question, not one to
       settle silently inside a bug fix. */
    #diamond_search.sf_archive .sf_card_heart svg path {
        fill: none;
        stroke: var(--sf-ink-soft, #3E3C39);
        stroke-width: 1px;
    }
    #diamond_search.sf_archive .sf_card_heart.selected svg path {
        fill: #C65858;
        stroke: #C65858;
    }
    /* no fill on hover -- same correction as the picker and the stone PDP */
    #diamond_search.sf_archive .sf_card_heart:hover svg path {
        fill: none;
        stroke: var(--sf-ink-soft, #3E3C39);
    }
    #diamond_search.sf_archive .sf_card_heart.selected:hover svg path {
        fill: #C65858;
        stroke: #C65858;
    }

    /* 21 / title / 8 / spec / 8 / price / 21, all inside the card's 8px side
       padding. min-height, not height: a one-line title must not collapse the
       block below the board's 48. */
    /* !important, and it is load-bearing: diamond-search.js:1446 and :2680 write
       an INLINE `height` on every .grid_result_title (58px here), and nothing
       but !important beats an inline style. The <=991 block at :559 already
       does exactly this for the same reason. */
    #diamond_search.sf_archive .grid_result_title {
        height: auto !important;
        min-height: 48px;
        margin: 21px 8px 0;
        padding: 0;
        display: flex;
        align-items: flex-start;
        justify-content: center;
    }
    #diamond_search.sf_archive .grid_result_info {
        height: auto;
        min-height: 18px;
        margin: 8px 8px 0;
        padding: 0;
    }
    #diamond_search.sf_archive .grid_result_price {
        height: auto;
        min-height: 16px;
        margin: 8px 8px 21px;
        padding: 0;
    }
    /* the legacy sheet's `padding: 0 5px; margin: 0 0 10px` on every inner <p>
       is what put the rhythm 10px out at each of the three rows. */
    #diamond_search.sf_archive .grid_result_title > p,
    #diamond_search.sf_archive .grid_result_info > p,
    #diamond_search.sf_archive .grid_result_price > p {
        width: 100%;
        margin: 0;
        padding: 0;
    }
    #diamond_search.sf_archive .grid_result_info > p,
    #diamond_search.sf_archive .grid_result_price > p {
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-align: center;
        color: var(--sf-ink, #0F0E0D);
    }
    /* 3.1.32's wrap ramp is a 390 treatment -- the board sets a two-line title
       at 21/24 here, which is exactly the 48 the block is drawn at. */
    #diamond_search.sf_archive .grid_result_title a,
    #diamond_search.sf_archive .grid_result_title.sf-title-wrapped a {
        font-size: 21px;
        line-height: 24px;
    }
}


/* ===========================================================================
   9c. 3.2 STONE PDP AT DESKTOP -- THE HEART, AND THE DETAILS LIST
   Two rules that were written for this screen and then never reached it: both
   live in the `@media (max-width: 991px)` block opened at :1261, so above 991
   the PDP falls back to the theme's own treatment. MEASURED at 1728:

     heart    box 60x40, glyph 43.6x40, right edge 1574 against a content
              gutter at 1572 -- so it overhangs by 2, and the glyph is more
              than twice the 22x20 the board draws. It is that big BECAUSE of
              this flow: stone-first.js's fitPdpHeart() crops the shared icon's
              60x40 art board to the glyph's own 18.25x16.7292 box at every
              width, and with no CSS constraining the <svg> at desktop the
              cropped drawing simply fills the 60x40 node.

     rb_dd_row  a <p> with two INLINE spans and nothing between them, so the
              Details & Dimensions body rendered as "ClarityVS1",
              "PolishExcellent", "Depth60.30" -- which is exactly what the
              owner pasted back. The two-column rule that fixes it is at :1544
              and is mobile-only.

   Sizes here are the board's proportions carried up, not new inventions: the
   glyph keeps its 1.0909 aspect (18.25 / 16.7292) and the label column keeps
   the 128px the desktop accordion rows above it already measure.
   =========================================================================== */

@media (min-width: 992px) {
    /* 26x24 in a 36x36 hit box -- the board's 22x20 in 36x36, nudged up for a
       36px Canela title, and still well under the 43.6x40 it was. Aligned
       top-right like the board so the right edge stays where it is and only the
       left edge moves in; `right` is pulled off main.css's 10px to 12px so the
       node stops overhanging the content gutter by 2. */
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container {
        right: 12px;
        display: flex;
        align-items: flex-start;
        justify-content: flex-end;
        width: 36px;
        height: 36px;
        padding: 0;
    }
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container svg {
        display: block;
        width: 26px;
        height: 24px;
    }
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container svg path {
        stroke: #3E3C39;
        stroke-width: 1px;
    }

    /* NO FILL ON HOVER. main.css:2477 paints `.productFavorite:hover svg path`
       jade -- the SAME paint as `.selected` -- inside its own min-width:992px
       block, so a merely-hovered heart reads as already shortlisted. The owner
       called this out on the picker's cards ("without click only outline, on
       click fill") and it was fixed there; the flow AUDIT found the identical
       rule still live on this one. Same correction, same scope discipline:
       this page only, main.css is untouched. */
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container:hover svg path {
        stroke: #3E3C39;
        fill: none;
    }
    /* TERRACOTTA, like every other saved heart on the site. Owner, on this
       page: *"the shortlist colour is different, it's jade -- fix that."* It
       was: MEASURED here, `fill rgb(39, 66, 59)`. main.css already settles
       this globally -- *"terracotta from the brand guide"*, #C65858, and the
       stone archive's card heart, the list row's heart and the setting
       drawer's card heart all paint it. This block was the last surface still
       overriding that with the brand green, and it only existed to carry the
       `:hover` half of the pair, which is about WHETHER it fills rather than
       what colour. So the hover pairing stays and the paint goes back to the
       token. */
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container.selected svg path,
    body.sf-stone-pdp .col.position-relative > .productFavorite.summary_container.selected:hover svg path {
        stroke: var(--terracotta, #C65858);
        fill: var(--terracotta, #C65858);
    }

    /* The Details & Dimensions body reads as a continuation of the list above
       it, not a paragraph: same flex row, same 128px label column the desktop
       .accordion-title rows already use (MEASURED: span.att_label 128x22). */
    body.sf-stone-pdp .diamond_atts_accordion .rb_dd_row {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        margin: 0;
        padding: 6px 0 0 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 22px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
    }
    body.sf-stone-pdp .diamond_atts_accordion .rb_dd_row .att_label {
        flex: 0 0 128px;
        max-width: 128px;
        color: #3E3C39;
        font-weight: 400;
    }
    /* `.accordion-text` carries a 45px left indent for the DESCRIPTION copy the
       other rows open into. This row opens into a data list, not a description,
       so it lines up with the labels above instead of hanging off them. */
    body.sf-stone-pdp .diamond_atts_accordion .accordion-text:has(.rb_dd_row) {
        padding-left: 0;
    }
}

/* ===========================================================================
   A SIZE IS A CHOICE -- the spec rows wait for it.
   stone-first.js stamps `sf-needs-size` while any dropdown attribute on a stone
   PDP has no `.active` (the theme's own record of a selection). Gemstones and
   moissanites are sold by `attribute_size` and WooCommerce pre-selects the
   first option, so the page resolves a variation nobody picked and the spec
   rows describe a stone that does not exist yet -- their dimensions are the
   product's whole RANGE (Height 6.0-12.0mm, Width 4.0-8.0mm), not a
   measurement.

   Only the SPEC rows go. `Product Details` and `Shipping & Delivery` carry
   `.accordion_description_row` and are true of the product at any size, so they
   stay. Diamonds have no dropdown attribute and never get the class, so nothing
   about their PDP changes.
   =========================================================================== */
body.sf-stone-pdp.sf-needs-size .diamond_atts_accordion .accordion-row:not(.accordion_description_row) {
    display: none;
}

/* ===========================================================================
   THE STONE'S OWN SPECS ON THE QUIZ'S STONE SLIDE.
   simple-select-redesign.js renders `rb_object.stone.specs` into
   `.rb_stone_specs` for stones that are not diamonds. The accordion around it
   is hidden for those stones (every diamond row is empty and gets hidden), so
   it is shown again only when there is something real in it.
   =========================================================================== */
#simple-select-quiz .diamond_atts_accordion.rb-has-stone-specs {
    display: block;
}
/* ...but showing the accordion again also un-hid the DIAMOND rows inside it,
   which rbHideEmptySpecRows() had hidden precisely because a gemstone fills
   none of them -- MEASURED on the heart moissanite, the slide read
   "Size 6.0 mm (.80 carat)" and then "Carat Weight Though most think of
   'Carat' in terms of size...", the diamond accordion's explainer copy. When
   this stone brings its own rows, they are the only rows. */
#simple-select-quiz .diamond_atts_accordion.rb-has-stone-specs > .accordion-row {
    display: none;
}
#simple-select-quiz .rb_stone_specs {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0 0 4px;
}
#simple-select-quiz .rb_stone_specs .rb_dd_row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin: 0;
    padding: 6px 0 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: var(--sf-ls, -0.21px);
    color: var(--sf-ink, #0F0E0D);
}
#simple-select-quiz .rb_stone_specs .att_label {
    flex: 0 0 128px;
    max-width: 128px;
    color: var(--sf-ink-soft, #3E3C39);
    font-weight: 400;
}

/* ===========================================================================
   [Flow 3] 3.2 WHAT BELONGS ON A STONE PDP THAT NOBODY NAVIGATED TO
   ---------------------------------------------------------------------------
   Owner: *"no continue browsing and other stuff when in normal non-BYR flow"*,
   against /gemstones/lab-created-alexandrites/pear-lab-created-alexandrite/.

   The link was on EVERY stone PDP because the whole 3.2 treatment is hooked on
   `has_term(diamonds|gemstones|moissanite)` -- deliberately the same test that
   decides whether Select This Stone / Purchase Loose print at all, so the
   chrome and the buttons can never disagree. That test knows what the product
   is; it has nothing to say about how the shopper got there. Land on a gemstone
   from search and "Continue browsing" is describing a journey that did not
   happen.

   HIDDEN, FULL STOP -- and the first attempt at this got it wrong. That version
   revealed the link when the shopper had come from a stone listing, on the
   reasoning that arriving from the archive meant "in the flow". It does not:
   browsing /lab-grown-diamonds/ and opening a stone IS normal browsing, which
   is the owner's point, made twice. There is no state in which a stone PDP is
   part of an active builder session either -- the ring-first quiz shows its
   stones in an in-quiz panel and never navigates to a PDP, and the stone-first
   journey only acquires its `sf=1` marker later, on the RING page. So the
   condition had no true case, and the machinery behind it (a `da_sf_browsing`
   key, a head stamp, an `html.sf-from-archive` class) is removed rather than
   left switched off, since dead code that looks live is its own trap.

   The BUTTONS are untouched on purpose. `Select This Stone` / `Purchase Loose`
   pre-date this flow -- a stone PDP has always been a build-a-ring entry -- and
   so do the spec accordion, the trust row and the price qualifier, which
   describe the product rather than the journey. Only the sentence that claims a
   journey goes away.
   =========================================================================== */
/* CONTINUE BROWSING: GONE AT DESKTOP, IN THE STICKY BAR ON A PHONE.
   Owner, first: *"why the fuck do I see continue browsing on the stone PDP when
   I'm in non-BYR flow"* -- hidden outright. Then, correcting it: *"my bad, on
   phone continue browsing must be there on diamond or stone PDP, in the sticky
   bar below, where add to ring and purchase loose CTAs are. Below those two
   there must be continue browsing centered and spaced properly."*

   So the hide is narrowed to >=992 rather than dropped. placePdpBack() already
   appends the link to `.sf_pdp_ctas` below 992 -- MEASURED, it is the bar's
   last child with the two CTAs above it -- and that bar is a `flex-direction:
   column` with the CTA pair reaching it through `display: contents` on
   `.sf_pdp_ctas_moved`. So the column already reads
   [ADD TO RING][PURCHASE LOOSE][Continue browsing] and un-hiding the third item
   is the whole change; it is centred and given its own gap below. */
@media (min-width: 992px) {
    body.sf-stone-pdp .sf_pdp_back { display: none; }
}
@media (max-width: 991px) {
    body.sf-stone-pdp .sf_pdp_ctas > .sf_pdp_back {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        align-self: center;
        margin: 14px 0 0;
        padding: 0;
        min-height: 20px;
        text-decoration: none;
    }
    body.sf-stone-pdp .sf_pdp_ctas > .sf_pdp_back:hover,
    body.sf-stone-pdp .sf_pdp_ctas > .sf_pdp_back:focus-visible {
        text-decoration: underline;
    }
}
/* The host stone-first.js builds for the link above the breadcrumb carries its
   own margins, so an empty one would leave the gap the link used to fill. */
body.sf-stone-pdp .sf_pdp_back_top { display: none; }

/* --- THE DESCRIPTION YIELDS TO THE SPECS ---------------------------------
   Owner: *"idk why the description part still renders in gemstones and
   moissanites and stuff after selecting a size."*

   Before a size is picked, `.dets_accordion` ("PRODUCT DETAILS -- ABOUT:
   Alexandrite is a magical stone that...") is the only thing on the page
   describing the stone, because `sf-needs-size` is holding the spec rows back
   until the choice is real. The moment the size lands, the spec accordion
   appears ABOVE it and the two say the same thing twice -- MEASURED on the pear
   alexandrite after choosing 7x5mm: Cut / Color Change / Clarity / Details &
   Dimensions in the accordion, and Height 6.0-10.0mm / Width 4.0-7.0mm repeated
   again at the foot of the description. So the description hands over rather
   than stacking up.

   `.dets_accordion` ONLY, never its container: `.product-details-accordion`
   also holds `.shipping_accordion`, the Estimated Delivery table, which is true
   of the product whatever size is chosen and must survive.

   `.sf-has-size` scopes this to stones that HAVE a size to choose -- the
   gemstones and moissanites the owner named. Without it the rule would also
   strip the row from diamond PDPs, where `sf-needs-size` is never set because
   there is no size control, and that is a page type nobody asked about. */
body.sf-stone-pdp.sf-has-size:not(.sf-needs-size) .product-details-accordion > .dets_accordion {
    display: none;
}

/* ===========================================================================
   [Flow 3] 3.1 THE FILTER RAIL STAYS PUT
   ---------------------------------------------------------------------------
   Owner: *"the filters part on left is sticky, like it does not get scrolled
   off."* MEASURED before this on /lab-grown-diamonds/ at 1728x900: the rail is
   `position: static` and travels with the page -- at scrollY 1400 its top was
   already at -1002, so by the second screenful of a 100-card grid the filters
   were gone and the only way back to them was to scroll 10,000px up.

   STUCK ON THE COLUMN, NOT ON `.diamond_filters`. A sticky element only travels
   inside its own containing block, and `.diamond_filters` sits in
   `.search_filters`, which is 1236 tall against a 10,562-tall results grid -- so
   sticking it there would have let go after about one screenful and looked like
   a bug rather than a rule. `.search_filters_container` is the bootstrap COLUMN,
   whose row is as tall as the results beside it, so the rail holds for the whole
   grid.

   `align-self: start` is what makes that possible at all: a bootstrap column is
   a flex item and stretches to the row's full height by default, and a sticky
   box the height of its own containing block has nowhere to travel.

   TOP: 91px, the site header's own height -- MEASURED, `header.site-header` is
   `position: sticky; top: 0` at 1728x91, with a 43px promo bar above it that
   scrolls away first. Without the offset the rail would sit UNDER the header.

   SELF-SCROLLING, because it has to be: the rail is 1168 tall and the space
   under the header at 900 is 809. `max-height` plus `overflow-y: auto` keeps the
   whole of it reachable; `overscroll-behavior: contain` stops a flick inside the
   rail from carrying on into the page behind it once it bottoms out.
   =========================================================================== */
@media (min-width: 992px) {
    #diamond_search.sf_archive .search_filters_container {
        position: sticky;
        top: 91px;
        align-self: flex-start;
        max-height: calc(100vh - 91px);
        overflow-y: auto;
        overflow-x: hidden;
        overscroll-behavior: contain;
        /* THE BAR GOES IN THE GUTTER, NOT DOWN THE SIDE OF THE FILTERS.
           Owner: *"the scroll bar must not be beside the filters component --
           it must be in the middle of the filter and search results."*

           A scrollbar is painted on the scroll box's own right edge, so with
           the box ending where the rail ends it ran flush against the filter
           controls. The board puts it at x457: 32 clear of the rail's right
           edge (425) and 51 clear of the grid (514), i.e. inside the 89px
           gutter between the two columns.

           So the box is widened by 32 + 6 and given the same amount back as
           padding -- the content box stays the rail's full 345 and only the
           bar moves out into the empty gutter. `overflow-x: hidden` because
           the widened box is now wider than its column.

           This is not invented here: _advanced-search-desktop.css:394 already
           does exactly this on the quiz mount, off the same board, and the
           archive's geometry is the same (rail 345 at x80, grid at x514). The
           archive's rail simply never got it. */
        width: calc(100% + 38px);
        padding-right: 38px;
    }
    /* The rail's own scrollbar is the column's now; a second one inside it
       would put two tracks side by side. The 2px is the owner's, and it is this
       sheet that has to carry it on the archive: diamond-search.css says the
       same thing, and MEASURED there it lost -- this file loads after it by
       declared dependency, and an earlier rule here was already zeroing it. */
    #diamond_search.sf_archive .search_filters_container .diamond_filters {
        max-height: none;
        overflow: visible;
        background: transparent;
        padding: 2px;
    }
}

/* =============================================================================
   THE SELECTION BAR SLIDES IN
   -----------------------------------------------------------------------------
   Owner: *"first click bottom bar gets rendered, by sliding into viewport, not
   randomly appearing."*

   AN ANIMATION, NOT A TRANSITION, and that is forced by how the bar is shown:
   the resting state is `display: none` and `.sf-has-selection` flips it to
   `flex`. `display` is not an animatable property, so a transition on a
   transform never gets a chance to run -- the element is not in the box tree
   one frame and fully laid out the next. A keyframe attached to the SHOWN state
   runs the moment the element starts being rendered, which is exactly the
   moment wanted.

   Chosen over rebuilding the show/hide as a translate + visibility pair
   deliberately: that pair would leave the bar permanently in the box tree at
   every width, and its `position: fixed` and full box only exist inside the
   `.sf-has-selection` rules -- so an unselected bar would sit unstyled in normal
   flow. This way the existing logic is untouched and only the entrance changes.

   `both` keeps the final frame, so nothing snaps back once the animation ends.
   ============================================================================= */
@keyframes sfStickyBarIn {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
}
/* ENTRANCE REMOVED. Owner: *"on natural and lab diamond search, on first click
   and further clicks of the diamond cards, the add-to-ring animation is weird,
   like it grows from a corner. Nah -- don't do it. Instead just no change in UI
   or animation when I click on different stones."*

   This supersedes the earlier ask for the bar to slide into the viewport; the
   slide is what is being rejected here, so it is switched off rather than
   re-tuned. `sfStickyBarIn` itself is left defined a few lines above, so
   restoring this is one declaration.

   WHAT IT WAS NOT: a replay between cards. MEASURED at 1728 and 390, clicking
   card 1 then card 3 and sampling 160ms later, the ONLY running animation was
   `sfStickyBarIn` at currentTime 320 of 320 -- i.e. already finished and not
   restarted -- with an identity transform and no animation on any child or on
   the active card. `.sf-has-selection` never goes false between two cards, so
   nothing retriggers. The "grows from a corner" is the FIRST appearance: the
   bar's `position: fixed` and its full-width box exist only inside the
   `.sf-has-selection` rules, so on that first click the element takes its final
   geometry in the same frame the translate starts from 100% below -- the box
   change is instant and only the offset eases, which reads as the bar expanding
   into place rather than sliding.

   Switching stones is now what was asked for: the bar is already there, its
   geometry does not change, and only the price and the lifted ADD TO RING
   button swap. */
#diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas[hidden],
#diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas {
    animation: none;
}
@media (prefers-reduced-motion: reduce) {
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas,
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas[hidden],
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas { animation: none; }
}

/* --- THE FILTER SCROLLBAR KEEPS OFF THE VIEWPORT EDGES --------------------
   Owner: *"the scroll bar in advanced lab diamond or natural diamond search
   must have padding from viewport -- it must not reach the end of the screen or
   go beyond it, maintain some gap."*

   The column was `max-height: calc(100vh - 91px)`, i.e. exactly the space under
   the sticky header, so a full rail's bar ran from the header's edge to the
   very bottom pixel of the window. 24 comes off the bottom so the track ends
   clear of it -- the same 24 this build uses as its standard breathing gap. */
@media (min-width: 992px) {
    #diamond_search.sf_archive .search_filters_container {
        max-height: calc(100vh - 91px - 24px);
    }
}

/* =============================================================================
   THE LIFTED "ADD TO RING" MUST NOT ANIMATE INTO PLACE
   -----------------------------------------------------------------------------
   Owner: *"the add-to-ring animation shit still exists ... in BYR flow advanced
   search"*, after the archive's bar entrance was removed.

   It was never the bar. MEASURED on the drawer, `getAnimations()` on
   `.dsq_sticky_ctas` and every descendant returned EMPTY on the first card
   click and on switching cards. The bar does not animate at all.

   What animates is the CARD's own `button.grid_add_to_ring` -- the real commit
   button, which the sheet lifts into the bar's primary slot when its card is
   `.active` rather than rendering a second, handler-less copy. The theme gives
   every button `transition: 0.2s linear` with no property list, i.e. ALL of
   them. MEASURED 120ms after the first click, that one button was mid-flight on
   seventeen properties at once -- width, height, font-size, letter-spacing,
   every padding and every border -- travelling from

       parked   position: absolute   [-9485, 592, 32, 32]
       lifted   position: fixed      [1436, 917, 212, 36]

   so it grows from a 32px square into a 212x36 CTA. That is the "grows from a
   corner". Switching cards runs it twice: the outgoing button transitions back
   down while the incoming one grows.

   Position is not a transitionable property, so the JUMP between those two
   boxes was always instant; only the box's own metrics eased. Killing the
   transition on this button leaves the lift itself untouched and makes it
   instant, which is what was asked for: no change in UI when clicking between
   stones.

   Applied to every card's button, not just the active one, so the outgoing
   half is silenced too. Nothing else about the button is touched -- it is the
   same node, with the same handler, doing the same commit. */
#ssq_diamond_search .result_grid_item_container button.grid_add_to_ring,
#ssq_diamond_search .result_item_row button.grid_add_to_ring,
#diamond_search.sf_archive .result_grid_item_container button.grid_add_to_ring,
#diamond_search.sf_archive .result_item_row button.grid_add_to_ring {
    transition: none !important;
}

/* The Shortlist view on the ring archive hides the cards it filters out. A
   class, not an inline style: `li.product` is laid out by the theme's own grid
   and jQuery `.show()` would guess a display value for it. `!important` because
   that grid sets `display` on the item itself. See sfRingShortlist(). */
ul.products > li.product.sf-short-hidden { display: none !important; }
/* and the list itself, so its row gaps do not hold the empty state down */
ul.products.sf-short-blank { display: none !important; }
/* =============================================================================
   NOTHING SAVED YET -- 16032:65645 `Frame 1171276870`
   -----------------------------------------------------------------------------
   Owner: *"can you add the empty shortlist state here as well ... not only halo
   but for engagement ring shortlists too."*

   THIS REPLACES A ONE-LINE `::after` THAT NEVER DREW. It was placed with
   `grid-column: 1 / -1` on `ul.products.sf-short-empty`, and the hubs' product
   list is not a grid -- no such axis, no placement, and MEASURED on
   /engagement-rings/halo-rings/round-cut-halo-engagement-rings/ the Shortlist
   tab painted a blank page under the toolbar.

   Geometry is the drawer's, which is the same frame: icon 37x35 in #E4DED8,
   copy column 234 with 24 between the words and the buttons and 6 inside the
   words, title Canela 300 18/21, sub FoundersGrotesk 16/21 #3E3C39, CTAs full
   width with 4 between them -- the first a 1px #27423B box (13px padding, not
   14: Figma's stroke is INSIDE the frame's 47 and CSS adds the border outside
   the padding box), the second an underlined link.
   ============================================================================= */
body.sf-ring-archive .sf_ring_empty_state:not([hidden]) {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 36px;
    padding: 64px 0 96px;
}
body.sf-ring-archive .sf_ring_empty_icon {
    display: block;
    flex: 0 0 auto;
    width: 37px;
    height: 35px;
    color: #E4DED8;
}
body.sf-ring-archive .sf_ring_empty_icon svg { display: block; }
body.sf-ring-archive .sf_ring_empty_copy {
    display: flex;
    flex-direction: column;
    gap: 24px;
    width: 234px;
    max-width: 100%;
}
body.sf-ring-archive .sf_ring_empty_words {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
body.sf-ring-archive .sf_ring_empty_title {
    margin: 0;
    font-family: 'Canela', serif;
    font-weight: 300;
    font-size: 18px;
    line-height: 21px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #0F0E0D;
    text-transform: none;
}
body.sf-ring-archive .sf_ring_empty_sub {
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 21px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #3E3C39;
}
body.sf-ring-archive .sf_ring_empty_ctas {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
body.sf-ring-archive .sf_ring_empty_cta {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    margin: 0;
    padding: 14px 0;
    border: 0;
    border-radius: 4px;
    background: transparent;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #27423B;
    cursor: pointer;
}
body.sf-ring-archive .sf_ring_empty_cta_all {
    padding: 13px 0;
    border: 1px solid #27423B;
    text-transform: uppercase;
}
body.sf-ring-archive .sf_ring_empty_cta_link { text-decoration: underline; }

/* IT SITS WHERE THE CARDS WOULD HAVE BEEN. On the archive `.the-content` is the
   two-column grid and every child of it spans both tracks by default, so with
   the rail open the block would centre across the rail as well as the results.
   Both surfaces place it in the GRID's column, the same way `ul.products` is
   placed. */
@media (min-width: 992px) {
    body.sf-ring-archive .the-content > .sf_ring_empty_state { grid-column: 2; }
    body.sf-ring-archive section.rings_product_grid_layout > .sf_ring_empty_state { grid-column: 2; }
}

/* ===========================================================================
   [Flow 3] THE ANTIQUE SHAPE TILES, AND THE FILTER RAIL'S TYPE -- ARCHIVE TWIN
   ---------------------------------------------------------------------------
   The reasoning is written out once, against the drawer, in
   _advanced-search-desktop.css. This is the same four corrections at the
   archive's own selectors, because the two mounts style the one shared filter
   template from two sheets that never see each other.
   =========================================================================== */
@media (min-width: 992px) {
  /* stroke art, not fill art -- the blanket `fill` above turns the antique
     outlines into solid blobs. */
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button svg path,
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button svg g {
    fill: none;
    stroke: var(--sf-ink-soft, #3E3C39);
  }
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button.active svg path,
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button.active svg g {
    fill: none;
    stroke: var(--sf-ink, #0F0E0D);
  }
  /* two-word labels wrap; 96 stays the floor so one-line tiles are unchanged */
  /* SAME ICON BOX AND SAME TYPE AS THE STANDARD SET. Owner: *"antique images
     and text look off from the normal standard filters -- icon size and text,
     fix this."*

     The mismatch was mine. To stop "Old Mine Marquise" overflowing I had stepped
     this set down to 13/15 (12/14 under 1440) on a 4px side pad, against the
     standard set's 14/15 on 8 -- MEASURED at 1440, standard 14px/8px vs antique
     12px/4px in tiles of the identical 87.8 x 96. Two type scales in one rail,
     which is what reads as off.

     The overflow is solved by the tile instead: the label wraps and the tile
     takes the height it needs, with the board's 96 as the FLOOR so a one-line
     antique tile is identical to a standard one and the grid rows stay even.
     Nothing here sets a size any more -- the set inherits the standard rules. */
  /* ONE SHAPE FOR EVERY ANTIQUE TILE. Owner: *"all buttons must be shaped
     equally in the antique shape filter -- if you want you can slightly extend
     the button size, but do it uniformly."*

     `min-height` let each tile take only what its own label needed, so a
     one-word tile stayed 96 beside a two-word tile at 104 and the grid came out
     ragged. A FIXED height instead -- 112, the two-line tile's own height plus
     the 8px gap the one-line tiles give back -- so every tile in the set is
     identical whether its label wraps or not. The icon box and the type are the
     standard set's, untouched. */
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button {
    height: 112px;
    min-height: 0;
  }
  #diamond_search.sf_archive .diamond_filters .shape_filter.fancy_shapes > button p {
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: center;
  }
  /* fancy colours are words in a row rule written for single letters */
  #diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors {
    flex-wrap: wrap;
  }
  #diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button {
    flex: 1 1 calc((100% - 16px) / 3);
    min-width: calc((100% - 16px) / 3);
    padding: 12px 8px;
  }
  @media (max-width: 1440px) {
    #diamond_search.sf_archive .diamond_filters .filter_options.filter_buttons > button,
    #diamond_search.sf_archive .diamond_filters .shape_filter > button p {
      font-size: 14px;
      line-height: 15px;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options.filter_buttons > button {
      padding-left: 6px;
      padding-right: 6px;
    }
  }
}

/* ===========================================================================
   [Flow 3] THE PLACEHOLDER IS SMALL AND CENTRED (mount-scoped half)
   ---------------------------------------------------------------------------
   The reasoning is written out once in diamond-search.css. It has to be
   restated here because both mounts size the card photo through an
   id-scoped rule -- `#diamond_search.sf_archive .result_grid_img img` -- which
   outranks anything the base sheet can say about the same element. Same
   specificity, later sheet; no !important.
   =========================================================================== */
#diamond_search.sf_archive .result_grid_img.sf-img-missing img {
    width: 48.12%;
    max-width: none;
    min-width: 32px;
    height: auto;
    margin: auto;
    object-fit: contain;
}
#diamond_search.sf_archive .result_grid_img.sf-img-none img {
    display: none;
}

/* The archive's own last word on the photo -- section 8c sizes
   `#diamond_search.sf_archive .result_grid_img img` at (1,2,1) further up this
   same file, so the placeholder override has to come after it. Reasoning in
   diamond-search.css. */
/* ...AT EVERY WIDTH, NOT ONLY DESKTOP. Owner: *"on phone, in the placeholder
   diamond cards, the placeholder image must stay in the centre -- why did it go
   up again?"*, on the lab diamond category page.

   The block below was written inside `min-width: 992px`, so on a phone the mark
   kept its static position: MEASURED at 390 with a card's photo broken, the mark
   85x85 hard against the TOP of a 177x160 frame with 75px of ground under it.
   Nothing about the reasoning is width-dependent -- the heart is a sibling on
   that line at both widths and absolute centring is what steps around it -- so
   the media query is the only thing that was wrong.

   The two attempts that did NOT work, recorded so they are not tried again:
   `align-items: center` on the frame carries the HEART to the middle of the
   card, and `margin: auto` on the img is inert because the img is an INLINE
   replaced element inside a real anchor box (the base sheet's
   `display: contents` on that anchor is overridden here by
   `display: block !important`). */
@media (min-width: 0px) {
    #diamond_search.sf_archive .result_grid_img.sf-img-missing img {
        /* CENTRED BY POSITION, NOT BY FLEX. `margin: auto` centres a flex item in
           the free space of its LINE -- and the card's heart button is a flex item
           on that same line, so the mark was pushed off-centre and sat beside it
           (MEASURED: 67px, but hard against the heart). Absolute centring is
           independent of what else the holder contains. The holder is already a
           positioned ancestor -- section 8 pins the photo to `inset: 0` inside it. */
        position: absolute;
        /* `inset` is the shorthand for all four offsets, so it has to clear
           section 8's `inset: 0` BEFORE the two that do the centring -- written
           after them it silently reset both back to auto and the mark sat at its
           static position (MEASURED: computed top 72.17 / left 97.45, i.e. the
           width percentage, not 50%). */
        inset: auto;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 33.333%;
        max-width: 96px;
        min-width: 32px;
        height: auto;
        aspect-ratio: auto;
        object-fit: contain;
        }
    #diamond_search.sf_archive .result_grid_img.sf-img-none img { display: none; }
}

/* ===========================================================================
   [Flow 3] THE FANCY COLOUR CHIPS CARRY THEIR COLOUR -- 14526:50130
   ---------------------------------------------------------------------------
   Owner: *"fancy buttons are not colorful -- use these."*

   Read off the REST API, component set `Color` 14526:50101:
     Property 1=Default   the WHITE state -- D..J, 42 x 42, the rail's ordinary
                          chip. Unchanged.
     Property 1=Variant2  the FANCY state -- six 80 x 42 chips, radius 8, text
                          16/30, each with its OWN solid fill:
                            Pink #F6D6DE   Blue #D1E3F0   Yellow #FBE8B4
                            Orange #F8D3B2 Green #D3EAD3  Brown #EAD8CC
   Mapped by the buttons' own `data-slug` (pink/blue/yellow/orange/green/brown,
   MEASURED off the live markup), so nothing depends on DOM order.

   ONE DELIBERATE DEVIATION, stated because it is one. In that frame ALL SIX
   chips also carry `stroke #27423B w1.5 OUTSIDE` -- which in this rail's own
   grammar is the SELECTED treatment (resting is 0.75 #E4DED8). Reproduced
   literally, every fancy chip would look selected and the real selection would
   be unreadable. The board is showing the row in its selected look rather than
   specifying six permanently-selected chips, the same way it gives the empty
   progress track the band's own colour. So the FILLS are taken exactly and the
   stroke keeps the rail's grammar: 0.75 #E4DED8 at rest, 1.5 #27423B when
   active. The board also differs by one shade on two chips' text (#0F0E0D on
   Pink and Brown, #3E3C39 on the other four); the rail's own resting/active
   text colours are used for all six instead of carrying that inconsistency in.
   =========================================================================== */
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="pink"] {
    --fancy-fill: #F6D6DE;
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="blue"] {
    --fancy-fill: #D1E3F0;
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="yellow"] {
    --fancy-fill: #FBE8B4;
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="orange"] {
    --fancy-fill: #F8D3B2;
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="green"] {
    --fancy-fill: #D3EAD3;
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug="brown"] {
    --fancy-fill: #EAD8CC;
}
/* THE FILL IS THE CHIP'S IDENTITY, SO IT SURVIVES SELECTION -- only the stroke
   and the text colour change, exactly as they do on every other chip in the
   rail. Carried on a custom property rather than as six background rules
   because the generic selected rule
   (`... .filter_options.filter_buttons > button.active`, which paints
   #C2CEB2 @0.30) weighs the same (1,3,1) and lives in a LATER sheet, so it won
   on source order -- MEASURED, selecting Green repainted it to
   rgba(194,206,178,0.3) and the colour was gone.

   The `[data-slug]` attribute takes both selectors below to (1,4,1), which
   beats that rule outright whatever the load order, and the property means the
   hex is written once per chip rather than twice. */
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug],
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button[data-slug].active {
    background-color: var(--fancy-fill);
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button {
    border-radius: 8px;          /* board cornerRadius 8 */
    color: var(--sf-ink-soft, #3E3C39);
}
#diamond_search.sf_archive .diamond_filters .filter_options.fancy_colors > button.active {
    color: var(--sf-ink, #0F0E0D);
}

/* ===========================================================================
   [Flow 3] THE SHAPE GLYPH IS 50 x 50 AT DESKTOP
   ---------------------------------------------------------------------------
   Owner, having tried it on their own 18" monitor: *"50 by 50 for icon sizes in
   shape filters, for both standard and antique."*

   The box was 32 x 40 (the board's icon frame). Taken alone, 50 does not fit
   what the tile reserves: 12 pad + 50 + 8 gap + 15 label + 12 pad = 97 against
   the standard tile's 96, and the label would have been pushed out of its box.
   So the tile's own vertical rhythm gives the glyph the room instead of the
   tile growing -- 10 + 50 + 6 + 15 + 10 = 91 inside the board's 96, and
   10 + 50 + 6 + 30 + 10 = 106 inside the antique set's 112 for a two-line
   label. Both heights are unchanged, so the grid rows and the rail's length are
   exactly as they were; only the glyph is bigger.

   The selected tile keeps its proportional bump (the board grows the icon by
   34/32 on select, so 50 -> 53).
   =========================================================================== */
@media (min-width: 992px) {
  #diamond_search.sf_archive .diamond_filters .shape_filter > button svg {
    width: 50px;
    height: 50px;
    display: block;
  }
  #diamond_search.sf_archive .diamond_filters .shape_filter > button.active svg {
    width: 53px;
    height: 53px;
  }
  #diamond_search.sf_archive .diamond_filters .shape_filter > button {
    padding-top: 10px;
    padding-bottom: 10px;
    gap: 6px;
  }
}

/* ===========================================================================
   [Flow 3] THE ARCHIVE LIST VIEW GETS THE STONE PHOTO TOO
   ---------------------------------------------------------------------------
   Owner: *"the list view of diamonds is not fixed in non BYR flow"*, said in
   the same breath as asking for the drawer's table to look like this one.

   The two list views are one PHP template rendered into two mounts, and the
   photo-in-the-first-column work from the last pass only ever reached the
   drawer: `paintListThumbs()` in simple-select-redesign.js is scoped to
   `#ssq_diamond_search`, and that file is not even enqueued on an archive page.
   So the archive kept the base sheet's table -- correct as a table, but with no
   stone in it. MEASURED at 1728: every row's only <img> is inside
   `.result_item_details`, which carries an inline display:none.

   This is the drawer's block transplanted: the same 64 x 58 tile in the same
   92px reserved column (12 pad + 64 + 16 gap), the same shape-glyph fallback
   for rows whose `data-img` is empty, the same `--dsq-thumb` override after the
   glyphs so source order lets a real photo win. What is NOT copied is the
   drawer's chrome -- the archive keeps its own heading band and cell rules,
   because those are the thing the owner is pointing at as correct.

   The heading strip and the value cells are put on ONE set of flex weights for
   the same reason they are in the drawer: bootstrap columns over content-sized
   cells is two layouts that cannot line up by accident. The strip also takes
   the row's 92px left offset, since it has no photo of its own.
   =========================================================================== */
@media (min-width: 992px) {
  #diamond_search.sf_archive .search_results .result_item_row > .results_header {
    display: flex;
    flex-direction: row;
    /* `stretch` so the value cells take the row's full height and the archive's
       own `border-left` rules run the whole way down instead of becoming short
       ticks floating beside a 58px photo. */
    align-items: stretch;
    gap: 16px;
    width: 100%;
    padding: 8px 12px;
    /* the table's outer edges. The base sheet draws them on the first and last
       CELL -- correct when the first cell was the left edge of the row, which it
       stopped being the moment the stone took that column. */
    border-left: 1px solid rgb(0 0 0 / 10%);
    border-right: 1px solid rgb(0 0 0 / 10%);
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item.price-col {
    border-right: 0;
  }
  #diamond_search.sf_archive .search_results .result_item_row > .results_header::before {
    content: "";
    flex: 0 0 64px;
    width: 64px;
    height: 58px;
    align-self: center;
    border-radius: 4px;
    background: var(--pearl-dark, #F0E9E3) no-repeat center / 34px 34px;
  }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Round"]    > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-round.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Oval"]     > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-oval.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Pear"]     > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-pear.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Emerald"]  > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-emerald.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Cushion"]  > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-cushion.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Princess"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-princess.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Marquise"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-marquise.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Asscher"]  > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-asscher.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Radiant"]  > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-radiant.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Heart"]    > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-heart.svg"); }
  /* after the glyphs on purpose -- equal specificity, so the real photo wins on
     source order */
  #diamond_search.sf_archive .search_results .result_item_row[style*="--dsq-thumb"] > .results_header::before {
    background-image: var(--dsq-thumb);
    background-size: cover;
    background-position: center;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding: 0;
  }
  /* the strip has no photo, so it reserves the column the rows spend on one:
     12 padding + 64 tile + 16 gap = 92. `margin: 0 -12px` is bootstrap's own row
     cancellation, which `.result_item_row` carries and this strip has to match
     or the two agree in the middle and drift at the ends. */
  #diamond_search.sf_archive .search_header > .row {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    margin: 0 -12px;
    padding: 0 12px 0 92px;
  }
  #diamond_search.sf_archive .search_header > .row > .header_item,
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0;
    width: auto;
    max-width: none;
    min-width: 0;
    padding: 0 10px;
    /* `!important` only because bootstrap's own `.d-lg-block` is: the L/W Ratio
       and Measurements cells carry `d-none d-lg-block`, so without it those two
       stayed block, their text sat at the top of a stretched cell, and two
       columns read a line higher than the other six. */
    display: flex !important;
    align-items: center;
    justify-content: center;
  }
  /* shape · carat · cut · color · clarity · ratio · measurements · price */
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(3),
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(3) { flex-grow: 1.6; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(4),
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(4) { flex-grow: 0.8; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(6),
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(6) { flex-grow: 1.1; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(7),
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(7) { flex-grow: 1.9; }
  /* the cell rules are the archive's own and stay; only the text is kept clear
     of them, which is the "text touches the table lines" the owner raised about
     the other mount. */
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item p {
    margin: 0;
    font-size: 16px;
    line-height: 19px;
    white-space: nowrap;
  }
  #diamond_search.sf_archive .search_header > .row > .header_item p {
    margin: 0;
    white-space: nowrap;
  }
  #diamond_search.sf_archive .search_header > .row > .header_item { min-height: 36px; }
}

/* The archive twin of the drawer's "230px of nothing under the last filter" --
   same legacy rule (diamond-search.css:67), same fixed 112px apply bar, same
   answer. See the note in _advanced-search.css. */
@media (max-width: 991px) {
  #diamond_search.sf_archive section.diamond_filters {
    padding-bottom: 136px;
  }
}

/* ===========================================================================
   [Flow 3] THE RULE UNDER DETAILS & DIMENSIONS CLOSES NOTHING
   ---------------------------------------------------------------------------
   Owner: *"on the diamond PDP there's an unnecessary line below the details
   and dimensions -- remove that."*

   Every `.accordion-row` in the spec stack carries a 1px #E4DED8 bottom rule,
   which is right while one row sits directly on the next: Carat Weight, Cut,
   Color, Certificate all butt together. Details & Dimensions is the LAST of
   them, and what follows is not another spec row -- it is the description
   group, which is a different component with its own darker rule and a gap in
   front of it. MEASURED at 1728: the row ends at 875 and Shipping & Delivery
   opens at 956, so that hairline hangs 81px above anything, dividing the spec
   list from empty space.

   `:last-child` of the spec group, not a sibling test: MEASURED, the row's
   `nextElementSibling` is NULL -- the description rows live in a different
   container (`.product-details-accordion`), so the two groups are not
   siblings at all and the gap between them is the gap between two blocks.
   =========================================================================== */
body.sf-stone-pdp .summary .diamond_atts_accordion > .accordion-row:last-child {
    border-bottom: 0;
}
/* ...AND WITHOUT THE `.summary` SCOPE, ON EVERY COPY OF THIS STACK.
   Owner, re-reporting it with a zoomed screenshot: *"please also remove the
   random lines below details & dimensions -- remove both lines."*

   The rule above was written against the stone PDP, where the accordion sits
   inside `.summary`. That ancestor is doing no work -- there is only ever one
   `.diamond_atts_accordion` on a page -- and it is what stops the same rule
   from reaching the builder's copy of this stack, which is rendered into the
   quiz's stone panel instead and is NOT inside a `.summary`.

   MEASURED at 390 on both surfaces before adding this: the in-flow stone PDP
   and the quiz's YOUR STONE panel each already ended with
   `border-bottom: 0px`, so this changes nothing that renders today. It is
   here so that neither copy can drift back, and so a third mount of the same
   markup inherits the answer rather than the bug. */
.diamond_atts_accordion > .accordion-row:last-child,
#simple-select-quiz .diamond_atts_accordion > .accordion-row:last-child {
    border-bottom: 0;
}

/* ===========================================================================
   [Flow 3] THE ARCHIVE LIST VIEW ON A PHONE -- Figma 14557:44601
   ---------------------------------------------------------------------------
   Owner: *"list view is still not right -- alignment between headers and
   content not there"*, quoting the designer: *"the new design has less stuff on
   phone and the lines are not there"* / *"favorites is missing"* / *"it will be
   the same list view as advanced filter."*

   The desktop half of this archive list was built last pass (the block above,
   `@media (min-width: 992px)`); below 992 nothing was ever written, so the
   archive fell all the way back to the plugin's bootstrap grid. MEASURED at 390
   before this: row 43 tall with `box-shadow: none`, no stone photo, no heart,
   and the heading cells on bootstrap's 6 x col-2 (65px each) against value
   cells on col-2/col-3/col-1/col-2 -- CUT ran 130->212 under a heading that ran
   130->195. That is the misalignment; the two were never on one set of widths.

   Rebuilt here on the BOARD'S widths, which are also the drawer's, so the two
   list views finally agree:

     stack      `.search_results`  pad 0/12, rows 4 apart
     row        366 x 48, pad 4, gap 9, bottom hairline #E4DED8 @0.40 w1 OUTSIDE
     stone      44 x 40, r4
     line       305 x 38, SPACE_BETWEEN
     cells      45 / 30 / 51 / 30 / 40 / 58, Founders 400 12/13, #0F0E0D
     heart      13 x 12, stroke #0F0E0D

   THE HAIRLINE IS A HAIRLINE. 14557:44601's row carries
   `individualStrokeWeights {top:0, right:0, bottom:1, left:0}` at 40% alpha --
   one line UNDER each row, no box, no vertical rules between cells. That is the
   designer's "the lines are not there": the build had been drawing a full 1px
   box around every row.

   THE HEADING STRIP IS KEPT, and this is the one deliberate departure from the
   frame. 14557:44601 has no column heading on phone at all -- the board is rows
   only. It is kept because the owner asked for it twice (*"don't forget table
   headings"*) and because six bare values in a 366px row name nothing; it is
   laid out on the row's own widths and the row's own 57px stone inset, so each
   label now sits exactly over the column it names. Flagged, not assumed.
   =========================================================================== */
@media (max-width: 991px) {
  #diamond_search.sf_archive .search_results {
    padding: 0 12px;
  }

  #diamond_search.sf_archive .search_results .result_item_row {
    display: flex;
    flex-direction: row;
    align-items: center;
    height: 48px;
    padding: 4px;
    margin: 0 0 4px;
    border: 0;
    border-radius: 0;
    outline: 0;
    /* strokeAlign OUTSIDE -- the hairline sits BELOW the 48px box without
       eating into it, so the pitch stays 48 + 4 = 52. */
    box-shadow: 0 1px 0 0 rgba(228, 222, 216, 0.40);
  }
  #diamond_search.sf_archive .search_results .result_item_row:last-child {
    margin-bottom: 0;
  }
  /* Selected -- the same full box the drawer's rows take (14463:33203):
     #27423B at 1.5, OUTSIDE, r4. `outline` reproduces OUTSIDE exactly, so
     selecting a row never nudges its neighbours.

     AND THE TOURMALINE FILL. Owner: *"the outline should stay like before;
     instead the fill must be tourmaline -- when selected it must be completely
     tourmaline, like outline plus fill."* The stroke was carrying the whole
     state on its own, which is why a selected row read as barely marked.
     #C2CEB2 at 30% is not a new colour: it is the selection fill this build
     already uses on every filter chip in the rail and in the drawer
     (_advanced-search.css -- "selected #C2CEB2 @30% + 1.5px #27423B"), so the
     row now speaks the same grammar as the controls that filter it. */
  #diamond_search.sf_archive .search_results .result_item_row.active {
    box-shadow: none;
    outline: 1.5px solid #27423B;
    outline-offset: 0;
    border-radius: 4px;
    background: rgba(194, 206, 178, 0.30);
  }

  #diamond_search.sf_archive .search_results .result_item_row > .results_header {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 9px;
    width: 100%;
    margin: 0;
    padding: 0;
    cursor: pointer;
  }
  /* The stone. Painted from `--dsq-thumb` (stone-first.js paintListThumbs) with
     the shape glyph as the fallback -- the same pair the desktop block above
     and the drawer both use; only the tile size changes with the breakpoint. */
  #diamond_search.sf_archive .search_results .result_item_row > .results_header::before {
    content: "";
    flex: 0 0 44px;
    width: 44px;
    height: 40px;
    border-radius: 4px;
    background: #FFFFFF no-repeat center / 24px 24px;
  }
  /* The glyph fallback, then the real photo. Both sets exist for >=992 further
     up this file; neither was inside a phone block, so every tile below 992
     painted its white ground and nothing else. The `--dsq-thumb` rule comes
     AFTER the glyphs deliberately -- same specificity, so source order is what
     lets a real photo win. */
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Round"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-round.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Oval"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-oval.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Pear"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-pear.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Emerald"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-emerald.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Cushion"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-cushion.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Princess"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-princess.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Marquise"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-marquise.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Asscher"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-asscher.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Radiant"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-radiant.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[data-shape="Heart"] > .results_header::before { background-image: url("../../assets/media/ringbuilder/shape-glyph-heart.svg"); }
  #diamond_search.sf_archive .search_results .result_item_row[style*="--dsq-thumb"] > .results_header::before {
    background-image: var(--dsq-thumb);
    background-size: cover;
    background-position: center;
  }

  #diamond_search.sf_archive .search_results .result_item_head_info {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex: 1 1 auto;
    min-width: 0;
    height: 38px;
    margin: 0;
    padding: 0;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 26px;
    margin: 0;
    padding: 0;
    border: 0;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item p {
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 12px;
    line-height: 13px;
    letter-spacing: 0;
    text-align: center;
    color: #0F0E0D;
  }
  /* shape · carat · cut · color · clarity ... price. Ratio and Measurements
     carry `d-none` below 992 in the markup and are skipped here, which is why
     PRICE is :nth-child(8) and not (6). */
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(1) { flex: 0 0 45px; width: 45px; justify-content: flex-start; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(1) p { text-align: left; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(2) { flex: 0 0 30px; width: 30px; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(3) { flex: 0 0 51px; width: 51px; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(4) { flex: 0 0 30px; width: 30px; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(5) { flex: 0 0 40px; width: 40px; }
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item:nth-child(8) { flex: 0 0 58px; width: 58px; }

  /* The heart, injected by stone-first.js so the list and the grid write one
     store. 13 x 12 glyph in a 48 x 48 tap target, hung off the line's end
     without taking 48px of it -- the row is only 48 tall. */
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart {
    position: relative;
    /* 14 x 13 -- the size 14634:47697 exports at, because Figma pads a stroked
       vector by half its stroke. The glyph inside is still the board's 13 x 12.
       At 13 x 12 the svg overhung its own button by half a pixel on each side;
       nothing clipped it here (the row is `overflow: visible`) but it sat off
       the column's centre, and the drawer's twin -- drawn as a background --
       was cropped outright. */
    flex: 0 0 14px;
    width: 14px;
    height: 13px;
    /* main.css gives `.productFavorite` its own offsets for the PDP gallery
       corner it was written for. MEASURED with them left alone: the heart
       landed at x351 against a price cell ending at 355 -- overlapping it --
       and stopped 10px short of the line's right edge. */
    margin: 0;
    inset: auto;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    color: #0F0E0D;
    cursor: pointer;
  }
  /* 14634:47697 is a 14 x 13 export of a 13 x 12 glyph -- Figma pads a stroked
     vector by half its stroke on each side. Drawn at the export's own size so
     the 1px stroke stays 1px and the glyph inside it stays 13 x 12. */
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart svg {
    display: block;
    width: 14px;
    height: 13px;
    fill: none;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart.selected {
    color: #C65858;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart.selected svg {
    fill: #C65858;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 48px;
    height: 48px;
    transform: translate(-50%, -50%);
  }

  /* ---- THE HEADING BAND -- 14634:47678 ------------------------------------
     The owner's newer board for this screen, attached with: *"the header bar is
     sticky, no vertical lines, shortlist, heart will be 48 by 48 tappable."*

     It is NOT the strip 14557:44601 implies (that frame has no heading at all)
     and NOT the bare row of labels built here first. It is a filled band:
     366 x 28, fill #EDE6E0, r4, a bottom hairline #E4DED8 @0.40 OUTSIDE like
     the rows', pad 4 / 7.5, HORIZONTAL gap 10, sitting 13 above the first row.

     ITS LABELS KEEP THEIR OWN WIDTHS, which are not the row's. The band's inner
     frame is 351 wide against the row's 305 and packs LEFT on a 10px gap rather
     than spreading SPACE_BETWEEN: `Shape` is 90 and starts at the band's own
     padding, so it spans the stone tile AND the shape name, and the five that
     follow are 30 / 44 / 30 / 40 / 46. Measured against the row underneath,
     that puts Carat, Cut, Color and Price within a pixel of the centre of the
     column each names -- the design's own alignment, not a coincidence to be
     "corrected" onto the row's track. Clarity is the one outlier at 3px.

     Sentence case. The markup already emits `Shape`; the uppercase was ours.
     --------------------------------------------------------------------- */
  #diamond_search.sf_archive .search_header {
    height: auto;
    margin: 0 0 13px;
    padding: 0 12px;
    overflow: visible;
    visibility: visible;
    background: transparent;
    /* "The header bar is sticky." It parks under the filter bar above it, which
       is itself `position: sticky; top: 61px` and 54 tall (`.results_count
       .mobile_count`, diamond-search.css), so 115 is where that one ends. */
    position: sticky;
    top: 115px;
    z-index: 5;
  }
  /* A STICKY HEADING CANNOT LIVE INSIDE A SCROLLPORT THAT NEVER SCROLLS.
     `.diamond_search_results` carries `overflow: hidden` (base sheet), and
     `overflow: hidden` still establishes a scroll container -- so a sticky
     descendant resolves its offset against THAT box, whose scrollTop is
     permanently 0. MEASURED: the band was pushed down by exactly its own 115
     (static 264 -> sticky 379, painting over the second row) and then scrolled
     away with the page instead of pinning. Opened up below 992 so the viewport
     is the scrollport again; nothing here is wider than its column, so there is
     nothing for the clip to have been holding in. */
  #diamond_search.sf_archive .diamond_search_results {
    overflow: visible;
  }

  #diamond_search.sf_archive .search_header > .row {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: 10px;
    /* 16px, and a radius you can see. Owner: *"the heading must be 16px, and
       the header must be rounded on corners -- this is for the list view header
       row on diamond search results."* The band is 12/13 on 14634:47678; the
       owner has overridden that, and the box grows with it: 16/21 in a 28-tall
       bar would clip its own descenders, so the height follows the type. */
    min-height: 34px;
    height: auto;
    box-sizing: border-box;
    margin: 0;
    padding: 6px 7.5px;
    background: #EDE6E0;
    border-radius: 8px;
    box-shadow: 0 1px 0 0 rgba(228, 222, 216, 0.40);
  }
  #diamond_search.sf_archive .search_header > .row > .header_item {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: auto;
    max-width: none;
    min-width: 0;
    padding: 0;
  }
  #diamond_search.sf_archive .search_header > .row > .header_item p {
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 21px;
    letter-spacing: 0;
    text-transform: none;
    text-align: center;
    color: #0F0E0D;
    white-space: nowrap;
  }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(1) { flex: 0 0 90px; width: 90px; justify-content: flex-start; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(1) p { text-align: left; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(2) { flex: 0 0 30px; width: 30px; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(3) { flex: 0 0 44px; width: 44px; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(4) { flex: 0 0 30px; width: 30px; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(5) { flex: 0 0 40px; width: 40px; }
  #diamond_search.sf_archive .search_header > .row > .header_item:nth-child(8) { flex: 0 0 46px; width: 46px; }
}

/* ===========================================================================
   [Flow 3] A LIST ROW SELECTS. IT DOES NOT UNFOLD.
   ---------------------------------------------------------------------------
   Owner: *"the summary inline opening of the stone is no longer necessary in
   list view -- I click on it and it expands to show stone details; that is not
   needed, in both advanced lab search and the non-BYR flow. We will just open
   the bottom drawer."*

   diamond-search.js:2294 slides `.result_item_details` open under the row on
   every `.results_header` click. That panel predates the sticky CTA band; now
   that a selected row raises ADD TO RING / VIEW MORE DETAILS / Talk to a
   gemologist at the foot of the screen, the fold is a second, slower copy of
   the same job -- and it pushes every row below it down the page while it is
   open.

   `!important` is answering jQuery: `slideDown()` writes `display: block` as an
   INLINE style, which no plain author rule can outrank. The handler still runs
   and still animates a height; nothing is painted. The node stays in the DOM
   because `result_to_html()` puts the row's only <img> inside it and
   `paintListThumbs()` reads it.

   BOTH MOUNTS, AT EVERY WIDTH -- the owner named the two flows, not a
   breakpoint. If the desktop table should keep its fold, this is one media
   query away.
   =========================================================================== */
#diamond_search.sf_archive .search_results .result_item_row:not(.active) > .result_item_details {
    display: none !important;
}
/* A SELECTED ROW KEEPS ITS PANEL IN THE BOX, AT ZERO HEIGHT. The row's real
   commit button (`.search_selectors button.primary_jade`) lives inside this
   panel, and a descendant of a `display: none` box cannot paint however it is
   positioned -- so hiding it outright would take the commit with it. Clamped
   instead: nothing inside renders, the row's own 48 is unchanged, and anything
   lifted out of it still works. Same treatment the drawer's twin has had since
   the sticky block was built (_advanced-search.css section 5). */
#diamond_search.sf_archive .search_results .result_item_row.active > .result_item_details {
    display: block !important;
    /* `!important` ON THE HEIGHT, AND THAT IS THE "WEIRD ANIMATION". Owner, on
       the phone list view: *"on clicking a diamond there's a weird animation
       which I think is a residue of the preview."*

       diamond-search.js:2294 still runs `slideDown()` on this panel, and jQuery
       animates by writing an INLINE `height` frame by frame. An inline
       declaration beats a plain author rule, so the clamp lost for the length
       of the slide: the panel grew to its full height, pushed every row below
       it down, and snapped back the moment jQuery finished and removed the
       inline value. The `display` was already !important for the same reason;
       the height has to be too, or the clamp only holds when nothing is
       animating it. */
    height: 0 !important;
    min-height: 0;
    /* jQuery's slideDown animates PADDING and MARGIN as well as height, each as
       an inline declaration -- MEASURED mid-slide: `height: 0px; padding-top:
       6.697px; padding-bottom: 6.697px`, so the clamp held the height and the
       box still grew to 13.4 and shrank back. Every box property the slide
       touches has to be stated the same way or the residue just moves to
       whichever one is left plain. */
    margin: 0 !important;
    padding: 0 !important;
    border: 0;
    overflow: hidden;
}

/* ===========================================================================
   [Flow 3] THE RAIL SAYS "FILTERS" ONCE
   ---------------------------------------------------------------------------
   Owner: *"on lab-grown-diamonds and natural diamonds main list there's Filters
   [the CTA], and then there's Filters text, and there's Reset beside it --
   remove the Filters text, align Reset with the Filters CTA."*

   MEASURED at 1440: the `.sf_filters` pill is at x67 y274, 132x44, and
   `.filters_headers` repeats the word 58px below it at x69 with Reset pushed to
   the far end of the rail at x269. Two labels for one thing, and the second one
   is the weaker of the two -- the pill is the control.

   The word goes and Reset takes the row, left-aligned so it sits under the
   pill's own edge rather than against the opposite side of the rail. The node
   is kept (it carries the filter-count badge that
   `#search_filters_mobile .filters_mobile_toggle` mirrors) and only its label
   is dropped, so nothing that reads the badge has to change.
   =========================================================================== */
@media (min-width: 992px) {
  /* The row goes entirely: the label is the pill's job and Reset has moved up
     beside it (stone-first.js liftReset()). Collapsed rather than emptied so
     the rail's first filter group starts where the row used to. */
  /* `!important` answers one: the row is `<div class="filters_headers d-lg-flex
     d-none">` and bootstrap ships `.d-lg-flex { display: flex !important }`,
     which no selector can out-specify. */
  #diamond_search.sf_archive .search_filters .filters_headers {
    display: none !important;
  }
  /* Reset, on the toolbar line, immediately after the Filters pill.

     The pill carries `order: -1` and an auto right margin -- that margin is
     what holds the rest of the row over on the right, and with Reset left at
     `order: 0` the margin landed BETWEEN them and threw Reset to x874, 675px
     from the pill it is supposed to sit beside. Reset takes the same order so
     the two travel together, and the auto margin moves onto Reset so it is
     still the thing pushing the row apart -- same total, one item later. */
  #diamond_search.sf_archive > .sf_toolbar_d .sf_filters {
    /* 6.44% of the toolbar's content box is 101 at 1728, which with the row's
       own 24px gap puts Reset's right edge on 384 -- the right edge of
       14557:53351's `Filter` frame, and of the filter rail directly below it.
       Stated as a gap after the pill rather than an `auto` margin on Reset: an
       auto margin is measured against whatever free space is left, so it moved
       every time anything else on the row changed. */
    margin-right: 6.44%;
    /* 14557:53354 -- the pill is 116 x 44 on this board; it was 132 from the
       earlier one. The 44 is unchanged. */
    flex: 0 0 116px;
    width: 116px;
    min-width: 116px;
  }
  /* RESET SITS AT THE FAR END OF THE FILTERS SECTION, NOT NEXT TO THE PILL.
     Owner: *"Reset is just beside the Filters CTA -- good, but same line: make
     it on the other end of Filters. Not the whole page, only the filters
     section."*

     14557:53351 agrees: its `Filter` frame is 304 wide from x80 and holds a 116
     pill, so Reset belongs at that frame's right edge -- which is also where the
     filter rail below it ends. An `auto` left margin does the whole job: it eats
     the free space between the pill and Reset, and the fixed right margin after
     it is what then places the view/sort group, so the two numbers cannot
     disagree. 11.7% of the toolbar's content box places Reset's right edge on the
     frame's own 384 at 1728, the row's 24px gap included. */
  #diamond_search.sf_archive > .sf_toolbar_d .diamond_filters_reset {
    order: -1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* 12px after Reset, owner's own number, picked against a real screen:
       *"not sure if this would work for all, but this looks good for results
       alignment on an 18 inch screen."* Kept as given rather than re-derived --
       it is a judgement about how the row reads, and the owner is the one
       looking at it. Flagged, not changed: the Filters pill ahead of it carries
       a PERCENTAGE right margin (6.44%), so a fixed 12 here lands differently
       against it at every width; if the alignment drifts on a narrower or wider
       screen, this is the number that has to become proportional, not the
       pill's. */
    margin: 0 12px 0 0;
    cursor: pointer;
  }
  /* ...AND THE MIDDLE GROUP SITS WHERE THE BOARD PUTS IT. Owner: *"filters
     position moved in this, wtf"*, with 14557:53351 attached -- the desktop
     toolbar, 1728 x 68, which anchors three things: the Filters group at x80,
     the view toggle + Sorting group at x515, and the All Stones / Shortlist
     segmented right-aligned at x1382 (1648 = 1728 - 80).

     MEASURED at 1728 against those: Filters 80 and the segmented 1382 were
     already exact; the middle group was at 642, 127 too far right, because
     Reset's auto margin absorbed every pixel of free space and dumped it all
     into that one gap. Taking the auto margin off swings it the other way --
     335, 180 too far LEFT -- so the gap is stated instead of left to the free
     space. 12.5% of the toolbar's 1568 content box is the board's 196 at 1728
     and scales with the padding at narrower widths, which is how the 80 itself
     behaves (66.7 at 1440). */
  /* The view/sort group is placed by Reset's right margin above, not by one of
     its own -- two margins both claiming to set the same gap is how the middle
     group ended up 127 out the first time. */
  #diamond_search.sf_archive > .sf_toolbar_d .search_view_options {
    margin-left: 6.82%;
    margin-right: auto;
  }
}

/* ===========================================================================
   [Flow 3] THE BAND RISES AND FALLS
   ---------------------------------------------------------------------------
   Owner: *"the animation of the bottom bar coming into screen and going out of
   screen for diamonds is gone in BYR and non-BYR."*

   Two different faults behind one report. The drawer HAS a rise
   (`dsq_ctas_rise_m`, _advanced-search.css) and the archive never had one at
   all -- MEASURED here: `animationName: none`, the band jumping 0 -> 178 tall
   at y666 in a single frame. And NEITHER had a fall: the band is `display:
   none` when nothing is selected, and `display` cannot be transitioned, so on
   deselect it simply stopped existing.

   The rise is the drawer's own curve and distance so the two surfaces move
   alike. The fall needs a state that outlives the deselect, which is what
   `.sf-ctas-closing` is: stone-first.js holds it on the root for the length of
   the animation and the band keeps its `display` until it has travelled.

   `transform`, not `bottom`: the band's CTAs are `position: fixed` descendants
   and a transformed ancestor becomes their containing block, so they ride it as
   one object instead of being animated separately at a different rate.
   =========================================================================== */
@keyframes sf_ctas_rise {
    from { transform: translateY(190px); }
    to   { transform: none; }
}
@keyframes sf_ctas_fall {
    from { transform: none; }
    to   { transform: translateY(190px); }
}
@media (max-width: 991px) {
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas {
        animation: sf_ctas_rise 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    /* The closing state is folded into the blocks above rather than restated:
       `.sf-has-selection` is what carries the band's `position: fixed` and its
       whole box, and MEASURED without it the band left the fixed layer the
       instant that class came off -- barTop 666 -> 5581, height 178 -> 44 as it
       reverted to static flow, so the "fall" was the band dropping into the
       document rather than off the screen. */
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas {
        animation: sf_ctas_fall 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
    }
}
@media (prefers-reduced-motion: reduce) {
    #diamond_search.sf_archive.sf-has-selection .dsq_sticky_ctas,
    #diamond_search.sf_archive.sf-ctas-closing .dsq_sticky_ctas {
        animation-duration: 1ms;
    }
}

/* ===========================================================================
   [Flow 3] THE DESKTOP LIST: NO RULES BETWEEN CELLS, A HEART THAT IS A CELL,
   AND A SELECTED ROW YOU CAN SEE
   ---------------------------------------------------------------------------
   Owner: *"on desktop in advanced BYR and on BYR, both in list view, there's no
   outline for the selected diamond row -- keep that"*, and *"on desktop list
   Shortlist is misaligned with the row, and no vertical lines in desktop
   either."*

   All three are the same omission: every list rule written for this flow sits
   in a `max-width: 991px` block, so above 992 the rows fell back to the
   plugin's table. MEASURED at 1440: each cell carries
   `border-left: 1px rgba(0,0,0,0.1)` -- the vertical rules -- the row's heart
   measures 511 -> 1350, 839px wide because nothing sizes it up here, and a row
   with `.active` computes `outline: none`.

   The hairline UNDER each row stays; it is the divider the design keeps. What
   goes is the ones BETWEEN cells, which 14634:47676 does not draw at any width.
   =========================================================================== */
@media (min-width: 992px) {
  #diamond_search.sf_archive .search_results .result_item_head_info > .result_item,
  #diamond_search.sf_archive .search_header > .row > .header_item {
    border-left: 0;
    border-right: 0;
  }
  #diamond_search.sf_archive .search_results .result_item_row > .results_header {
    border-left: 0;
    border-right: 0;
  }
  /* The heart is the row's last cell, not a block that spans it. */
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart {
    position: relative;
    /* main.css gives `.productFavorite` offsets for the PDP gallery corner it
       was written for, and a `top` on a RELATIVELY positioned box shifts it
       after layout -- which is why centring moved the heart the wrong way:
       MEASURED, `align-self: center` put its box at 396.5 and it painted at
       409.5, exactly main.css's 13. The phone rule already zeroes these. */
    inset: auto;
    flex: 0 0 14px;
    width: 14px;
    height: 13px;
    margin: 0 0 0 16px;
    /* CENTRED ON THE ROW, NOT HUNG FROM ITS TOP. Owner: *"the shortlist icon is
       still up -- it does not align with the text in that row."* The desktop
       line is `align-items: stretch` so the value cells fill the row's height
       and their text centres inside each one; the heart has a fixed 13 and no
       text to centre, so stretch left it at the top of a 58-tall line.
       MEASURED at 1440: text cells centred on 403, heart on 393.5 -- 9.5px high.
       The phone line is already `center` and measured dead on at 335. */
    align-self: center;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    color: #0F0E0D;
    cursor: pointer;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart svg {
    display: block;
    width: 14px;
    height: 13px;
    fill: none;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart.selected {
    color: #C65858;
  }
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart.selected svg {
    fill: #C65858;
  }
  /* 48 x 48 of tap around it, drawn outward so the row's layout is untouched. */
  #diamond_search.sf_archive .search_results .result_item_head_info > .sf_row_heart::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 48px;
    height: 48px;
    transform: translate(-50%, -50%);
  }
  /* 14463:33203 -- stroke #27423B, w 1.5, align OUTSIDE, r 4. `outline` is the
     only thing that reproduces OUTSIDE exactly: it does not reflow the row, so
     selecting one never nudges its neighbours. */
  #diamond_search.sf_archive .search_results .result_item_row.active {
    outline: 1.5px solid #27423B;
    outline-offset: -1.5px;
    border-radius: 4px;
    /* ...PLUS THE FILL, the same #C2CEB2 @30% the phone row takes above and the
       filter chips take everywhere else. Outline alone was the whole state. */
    background: rgba(194, 206, 178, 0.30);
  }
  /* ...AND THE HEADING HAS TO RESERVE THE SAME COLUMN. The heart takes 14 plus
     its 16 of lead out of the row's track, so with the strip still spanning the
     full width the two drifted apart cell by cell -- MEASURED right after the
     heart was sized: heading 520/616/712 against row 520/613/705. The strip has
     no heart, so it spends the same 30 on nothing. */
  #diamond_search.sf_archive .search_header > .row::after {
    content: "";
    flex: 0 0 14px;
    width: 14px;
    margin-left: 16px;
  }
}

/* ===========================================================================
   [Flow 3] AN EMPTY SHORTLIST HAS NOTHING TO HEAD
   ---------------------------------------------------------------------------
   Owner: *"if shortlist is empty, no need to show the header in list view."*
   The band labels columns; with no rows under it, it is a bar of column names
   over nothing. `:has()` tests the results themselves rather than a count the
   CSS would have to be told, so it is right the moment the list re-renders.
   =========================================================================== */
/* A CLASS, NOT `:not(:has(.result_item_row))`. That selector asked the browser
   to re-evaluate `:has()` on `.search_content` -- the element that holds the
   WHOLE result list -- every time a row was added or removed, which is hundreds
   of times during a render and again on every lazy-load page. Chromium absorbs
   it; Firefox's `:has()` invalidation does not, and the owner reported Firefox
   warning that the page was slowing it down, starting the day this shipped.
   diamond-search.js stamps `sf-no-rows` after each render instead -- one class
   write against a selector the engine re-checks constantly. */
#diamond_search.sf-no-rows .search_header,
#ssq_diamond_search.sf-no-rows .search_header {
    display: none !important;
}

/* ===========================================================================
   [Flow 3] THE MERCH BAND ABOVE 992 -- Figma 14641:48005
   ---------------------------------------------------------------------------
   Owner: *"the banner on lab-grown-diamonds is this [14557:50702] ... natural
   diamonds too, same banner ... btw this banner for desktop view
   [14641:48005]."*

   The band was built to the phone frame and nothing re-stated it for a wide
   screen, so a 390-wide composition was stretching across the grid: a 246px
   copy column lost in 800+, five tiles OVERLAPPING at the phone's -3 itemSpacing
   and a 246 CTA.

   14641:48005 is 827 x 307 with the same two text styles and the same 110px
   tiles, and three numbers change:
     copy column  246 -> 683   (frame 14641:48006)
     strip gap     -3 -> 14    (14641:48009 -- the tiles separate, 576 overall)
     CTA          246 -> 464   (14641:48015)
   The head is one line at that width, which is why the band is 307 and not 336.

   Everything the two frames share -- the #142037 @0.8 scrim, Canela 300 24/28.8
   #E4DED8, Founders 400 16/19 #FAF3ED, the 1px #FAF3ED r4 CTA, 40/72 padding --
   is already above and is not repeated.
   =========================================================================== */
@media (min-width: 992px) {
  #diamond_search.sf_archive .sf_insert_row .sf_merch_head,
  #diamond_search.sf_archive .sf_insert_row .sf_merch_sub {
    width: 683px;
    max-width: 100%;
  }
  #diamond_search.sf_archive .sf_insert_row .sf_merch_strip {
    gap: 14px;
  }
  /* The phone tiles are pulled together with a negative margin; at this width
     they are spaced, so the margin comes off and the gap does the work. */
  #diamond_search.sf_archive .sf_insert_row .sf_merch_strip img {
    margin: 0;
  }
  #diamond_search.sf_archive .sf_insert_row .sf_merch_cta {
    width: 464px;
  }
}

/* The desktop heading band takes the phone band's box. Owner, listing the
   desktop columns: *"this header corners must be rounded -- Shape, Carat, Cut,
   Color, Clarity, L/W Ratio, Measurements, Price."* It had no fill and no
   radius up here, so there were no corners to round; it takes the same #EDE6E0
   and 8px the phone band already carries, which is the one the owner has
   already signed off. */
@media (min-width: 992px) {
  #diamond_search.sf_archive .search_header > .row {
    background: #EDE6E0;
    border-radius: 8px;
    box-shadow: 0 1px 0 0 rgba(228, 222, 216, 0.40);
  }
}

/* THE ROW'S LINE MUST NOT WRAP, OR THE HEART IS NOT ON IT.
   Owner: *"the shortlist icon is still up -- it does not align with the text in
   that row."* `.result_item_head_info` is a bootstrap `.row`, so it ships
   `flex-wrap: wrap`, and the heart was being pushed onto a SECOND flex line --
   MEASURED at 1440: every value cell at y374 and the heart alone at y409.5.
   `align-self: center` then centred it inside its own 13-tall line, which moved
   it further DOWN rather than onto the row. One line, and the same declaration
   centres it against the 58 the cells make. */
@media (min-width: 992px) {
  #diamond_search.sf_archive .search_results .result_item_head_info {
    flex-wrap: nowrap;
  }
}

/* THE BAND IS THE ROUNDED ROW, NOT THE COLUMN BEHIND IT.
   Owner: *"the header in list view is rounded but there's a grey rectangle
   behind the header."*

   MEASURED at 1440: `.search_header.col-12` and its inner `.row` occupy the
   SAME box -- 428,330 945x36 -- and the column carries the legacy
   `background: rgba(0,0,0,0.1)` from when IT was the band. The row took the
   #EDE6E0 and the 8px radius; the column's square grey stayed behind it and
   showed at all four corners. Only the row paints now. */
#diamond_search.sf_archive .search_header,
#ssq_diamond_search .search_header {
    background: transparent;
}

/* ===========================================================================
   THE PHONE SLIDERS ARE THE DESKTOP SLIDERS
   ---------------------------------------------------------------------------
   Owner: *"the filters are old on phone -- the sliders are still round on the
   ends, not like those on desktop for advanced diamond search."*

   They were. Every pill-thumb rule in this file sits inside
   `@media (min-width: 992px)` (:3346) and its BYR twin inside
   `_advanced-search-desktop.css`'s own 992 block, so below that the rail fell
   all the way back to the legacy sheet -- MEASURED at 390 on
   /lab-grown-diamonds/: a 20 x 20 thumb at `border-radius: 50%`, `right: -17px`,
   on a 10px `#FAFAFA` track. A circle on a near-white rail, where desktop draws
   a 26 x 17 green capsule on an #E4DED8 one.

   One control, one set of numbers: these are the 992 block's, verbatim. The
   phone board does not redraw the slider, so there is nothing here to diverge
   from -- which also means the next change to either has to be made twice, and
   that is the reason the numbers are repeated rather than paraphrased.

   THE INSET IS HALF A THUMB, on the bar's own margin. A thumb is centred on the
   track END, so a track that reached the column edge would hang half a thumb
   outside it -- the thing FILTERS-RAIL forbids and the whole reason the rail has
   no horizontal scroll left. 13 for the 26-wide thumb, 16 for price's 32. On the
   margin rather than as padding on `.nuslider` so the min/max <input> pair under
   the track keeps the column's full width; `.nuslider`'s own inherited 3px of
   padding (diamond-search.css:1063) is zeroed, or it would land on top of the
   margin and make the two ends uneven.
   =========================================================================== */
@media (max-width: 991px) {
    /* FOUR SHAPE TILES PER ROW -- 14557:53209, the same board the BYR rail now
       follows (_advanced-search.css). Its shape group is a 344-wide column of
       80 x 96 tiles, four across, column gap 8 and row gap 9: 4 x 80 + 3 x 8 =
       344, and the ten shapes fall 4 / 4 / 2. The archive rail was still on
       diamond-search.css:1114's five-up at gap 5.

       `minmax(0, 1fr)` rather than a fixed 80 so the tracks can shrink below the
       board's 390 instead of pushing a horizontal scrollbar into the rail; a
       bare `1fr` floors at the longest shape label and would overflow. */
    #diamond_search.sf_archive .diamond_filters .filter_options.shape_filter {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        column-gap: 8px;
        row-gap: 9px;
        overflow: visible;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options.shape_filter > button {
        min-width: 0;
    }

    #diamond_search.sf_archive .diamond_filters .nuslider {
        box-sizing: border-box;
        padding-left: 0;
        padding-right: 0;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .slider__bar.noUi-horizontal {
        grid-column: 1 / -1;       /* inert unless .nuslider is a grid */
        box-sizing: border-box;
        width: auto;               /* fill what the margins leave */
        height: 8px;
        margin: 4.5px 13px;
        border: 0;
        border-radius: 15px;
        background: var(--sf-line, #E4DED8);
        box-shadow: none;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-connect {
        background: #C2CEB2;
        border-radius: 8px;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle.noUi-handle-lower,
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle.noUi-handle-upper {
        width: 26px;
        height: 17px;
        top: -4.5px;
        right: -13px;              /* half the thumb, so travel ends flush */
        border: 0;
        border-radius: 16px;
        background: var(--sf-green, #27423B);
        box-shadow: none;
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle::before,
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle::after {
        display: none;             /* noUiSlider's default grip lines */
    }
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .slider__bar.noUi-horizontal {
        margin: 6.5px 16px;
    }
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .noUi-handle.noUi-handle-lower,
    #diamond_search.sf_archive .diamond_filters .d_filter.price .nuslider .noUi-handle.noUi-handle-upper {
        width: 32px;
        height: 21px;
        top: -6.5px;
        right: -16px;
    }
    /* The hit target is 36 wide and noUiSlider translates it, so it overhangs a
       26px thumb on both sides. Clamped to the thumb; the thumb plus the 13px of
       track inset around it is the touch target. */
    #diamond_search.sf_archive .diamond_filters .nuslider .noUi-handle .noUi-touch-area {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        margin: 0;
        transform: none;
    }
}

/* ===========================================================================
   [Flow 3] THE EMPTY SHORTLIST -- Figma 16032:65491 "2.1 Advanced Search -
   empty shortlist", frame `Frame 1171276870`
   ---------------------------------------------------------------------------
   MEASURED on dev-1 before this, 390 wide, archive mount, da_wishlist emptied
   and the Shortlist half tapped: body carries `sf-shortlist-view`,
   #diamond_search carries `sf_archive sf-no-rows`, 0 rows / 0 grid cards, the
   count reads "View 0 Items" -- and the field is COMPLETELY BLANK. 18px of
   .search_content (6 of grid-container padding + a 12px empty bootstrap row)
   under the sticky filter bar and nothing else. So the shopper who taps the
   control named after the thing they saved sees an empty page with no way back.

   ONE RULE SET SERVES BOTH MOUNTS. In the builder `#ssq_diamond_search` is a
   wrapper DIV around this very section (simple-select-quiz.php:459, and
   simple-select-redesign.js:1476 reads `#ssq_diamond_search #diamond_search`),
   so sfMarkEmptyRows() stamps `sf-no-rows` on both and `#diamond_search` is the
   one selector that is true on the archive and in the drawer. This sheet is
   enqueued on both -- see enque_stone_first_archive() in da-general.php.

   GATED ON TWO THINGS, not one. `sf-no-rows` alone is also true on the first
   paint of an ordinary search, before any row has arrived, so the state would
   flash on every page load. `body.sf-shortlist-view` is the second half.

   Geometry, all from 16032:65605 and its children:
     block        234 FIXED, VERTICAL, itemSpacing 36, both axes CENTER
     icon         36x34, 1px #E4DED8 stroke, CENTER align, round cap/join
     copy column  itemSpacing 24   (16032:65614)
     words        itemSpacing 6    (16032:65608)
     ctas         itemSpacing 4    (16032:65644)
   The block's own top edge is at y=216 in a frame whose chrome ends at 158,
   i.e. 58px below it -- and MEASURED above, .search_content starts flush under
   the chrome, so that 58 is this block's padding-top and nothing else.

   The 234 is NOT applied to the block but to the copy column. In Figma only the
   copy column is STRETCH inside the 234; the icon is a fixed 36 centred in it,
   so a 100%-wide flex column with `align-items: center` and a 234 copy column
   reproduces the frame and survives a .col-12 whose width the grid owns.

   NO BOARD FRAME EXISTS AT 1440 for either empty state. The block is left at
   the same 234 / 36 / 24 / 6 / 4 and the same type at every width: it is a
   centred notice in the results column, nothing in it is a function of the
   column's width, and inventing a wide variant would be guessing. Stated in
   the report.
   =========================================================================== */
#diamond_search .sf_empty { display: none; }

body.sf-shortlist-view #diamond_search.sf-no-rows .sf_empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* 16032:65605 itemSpacing 36 */
    gap: 36px;
    /* y=216 against a chrome that ends at 158 */
    padding-top: 58px;
    flex: 0 0 100%;
    width: 100%;
}

/* 58 MINUS THE 3 THE BUILDER ALREADY SPENDS. 16032:65491 is the BUILDER frame,
   not the archive one: its header is the `advanced-header` component, and once
   the 46px phone status bar (which is not part of a web page) comes off, the
   board's chrome ends at 112 and the block's top edge is at 170.

   MEASURED on dev-1 at 390, drawer open, shortlist emptied:
     .dsq_screen_header bottom  112   <- exactly the board's 158 - 46
     .search_content    top     115   <- 3px lower than the chrome
   so a flat 58 lands the block at 173 and the board asks for 170. The 3px is a
   pre-existing gap between the header and the results container, which this
   state has no business moving, so the padding absorbs it instead.

   PHONE ONLY, because this is the only width the board draws. MEASURED at 1440
   the same gap is 4px, not 3 -- so it is not a constant to generalise from, and
   with no 1440 frame there is nothing to correct it towards. The archive mount
   keeps the flat 58 for the same reason: no board frame exists for it.

   It lives here rather than in the builder's own _advanced-search.css so every
   number in this state stays in one file, which is the same call the
   `sf-no-rows .search_header` rule above already makes. Two ids out-specify the
   base rule, so no !important. */
@media (max-width: 991px) {
    body.sf-shortlist-view #ssq_diamond_search #diamond_search.sf-no-rows .sf_empty {
        padding-top: 55px;
    }
}

/* Both result containers are provably empty in this state -- `sf-no-rows` means
   the list has no `.result_item_row`, and sfMarkEmptyRows() is the only writer
   of that class -- and between them they contributed the 18px of dead space
   measured above. Collapsed so the notice is the whole of the field. The class
   comes off the moment a row lands, which is what restores them. */
body.sf-shortlist-view #diamond_search.sf-no-rows .search_results,
body.sf-shortlist-view #diamond_search.sf-no-rows .search_results_grid_container {
    display: none;
}

/* 16032:65606. The span is 37x35, not 36x34: the path box is 36x34 and the 1px
   CENTER-aligned stroke bleeds 0.5 outside it on every side. `color` is the
   stroke -- the glyph is drawn with `currentColor`. */
#diamond_search .sf_empty_icon {
    display: block;
    flex: 0 0 auto;
    width: 37px;
    height: 35px;
    color: #E4DED8;
}
#diamond_search .sf_empty_icon svg { display: block; }

/* 16032:65614 -- itemSpacing 24, and the one child of the 234 frame that is
   STRETCH, so this is where the 234 lives. */
#diamond_search .sf_empty_copy {
    display: flex;
    flex-direction: column;
    gap: 24px;
    width: 234px;
    max-width: 100%;
}

/* 16032:65608 -- itemSpacing 6 */
#diamond_search .sf_empty_words {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* 16032:65599 -- Canela-Light 300, 18/21, ls -0.21, CENTER, #0F0E0D.
   Stored mixed case and NOT uppercased: 65599 carries no textCase. */
#diamond_search .sf_empty_title {
    margin: 0;
    font-family: 'Canela', serif;
    font-weight: 300;
    font-size: 18px;
    line-height: 21px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #0F0E0D;
    text-transform: none;
}

/* 16032:65604 -- FoundersGrotesk-Regular 400, 16/21, ls -0.21, CENTER,
   #3E3C39. The board's box is 234x42, i.e. two lines; no height is written
   here because a third line must be allowed to show rather than be clipped. */
#diamond_search .sf_empty_sub {
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 21px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #3E3C39;
}

/* 16032:65644 -- itemSpacing 4 */
#diamond_search .sf_empty_ctas {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* 16032:65609 / 65640 -- both CTAs: FILL width, padding 14 top and bottom,
   r4, transparent (the #27423B fill on both is `visible: false`), label
   FoundersGrotesk 400 16/19 ls -0.21 #27423B centred. 47 tall = 14 + 19 + 14. */
#diamond_search .sf_empty_cta {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    margin: 0;
    padding: 14px 0;
    border: 0;
    border-radius: 4px;
    background: transparent;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: -0.21px;
    text-align: center;
    color: #27423B;
    cursor: pointer;
}

/* 16032:65609 -- 1px #27423B, strokeAlign INSIDE, and 16032:65611 is
   textCase UPPER over stored mixed case.
   PADDING 13, NOT 14, AND THAT IS NOT A DEVIATION: Figma draws an INSIDE
   stroke within the frame's own 47, so the 14 of padding already contains it.
   CSS adds the border outside the padding box, so 14 + 1 + 1 would measure 49.
   13 + 19 + 13 + 2 borders = the board's 47. */
#diamond_search .sf_empty_cta_all {
    padding: 13px 0;
    border: 1px solid #27423B;
    text-transform: uppercase;
}

/* 16032:65640 has NO stroke, and 65642 carries textDecoration UNDERLINE and no
   textCase -- so 14px padding stands and the label keeps its stored case. */
#diamond_search .sf_empty_cta_link {
    text-decoration: underline;
}

/* =============================================================================
   DIAMOND SEARCH FILTERS -- 14663:47745, the new board, BOTH RAILS
   -----------------------------------------------------------------------------
   Owner: *"this is the new design for the filters of diamond search in both BYR
   and non-BYR. Exact reconstruction."*

   One 345-wide column at x22 inside 390, groups 24 apart, in the frame's order:
   SHAPE, CARAT, CUT, COLOR, CLARITY, PRICE, then ADVANCED FILTERS.

   Read off the frame, and these are the numbers every rule below states:

     group gap          24                  (`Filters`, WRAP, itemSpacing 24)
     title row          344 x 31, pad-bottom 12; 60 where it carries a toggle
     title              16/19 ls -0.21, #3E3C39 @80%, UPPER
     info circle        13 x 13, #C69858
     chip               h42, r8, pad 12/8, gap 8, label 16/18 ls -0.5
       resting          0.75px #E4DED8, label #3E3C39
       selected         #C2CEB2 @30% + 1.5px #27423B, label #0F0E0D
     clarity chip       fixed 80 wide, four to a row (4x80 + 3x8 = 344)
     carat track        344 x 8 r15 #E4DED8, connect #C2CEB2, thumbs 26 x 17 r16
     carat inputs       80 x 40 r8 #FFFFFF 1px #E4DED8, 16/16 ls +0.75
     price inputs       110 x 40, same box and tracking
     advanced           344 x 60 r8, 1px #E4DED8, label 18/18 ls -0.5 #0F0E0D,
                        with a 24 x 24 #E4DED8 disc carrying a + at the right
     shape toggle       187 x 40 r10 0.75px #27423B; halves 94/90 x 38 r8 2px;
                        active #27423B on #FAF3ED, inactive #27423B on nothing

   TRACKING IS THE THING TO WATCH. The chips and the toggle run at -0.5 and the
   numeric inputs at **+0.75**, where this file's own default is -0.21. All three
   are stated explicitly or the default wins.

   Written with BOTH rail roots on every selector -- `#diamond_search.sf_archive`
   (category) and `#ssq_diamond_search` (builder) -- because the board covers
   both and the two sheets that own them load on different surfaces. Phone only;
   the desktop rails keep their own geometry.
   ============================================================================= */
@media (max-width: 991px) {
    /* ---- the column and the group rhythm ------------------------------- */
    #diamond_search.sf_archive .diamond_filters .d_filter,
    #ssq_diamond_search .diamond_filters .d_filter {
        margin-bottom: 24px;
    }

    /* ---- group title ---------------------------------------------------- */
    #diamond_search.sf_archive .diamond_filters .filter_title,
    #ssq_diamond_search .diamond_filters .filter_title,
    #diamond_search.sf_archive .diamond_filters .d_filter > p:first-child,
    #ssq_diamond_search .diamond_filters .d_filter > p:first-child {
        margin: 0;
        padding: 0 0 12px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: uppercase;
        color: rgba(62, 60, 57, 0.80);
    }
    /* `Info circle` 13 x 13 #C69858 -- the glyph is inline svg in the markup. */
    #diamond_search.sf_archive .diamond_filters .filter_title svg,
    #ssq_diamond_search .diamond_filters .filter_title svg {
        width: 13px;
        height: 13px;
        color: #C69858;
    }

    /* ---- chips: CUT, COLOR, CLARITY ------------------------------------- */
    #diamond_search.sf_archive .diamond_filters .filter_options:not(.shape_filter),
    #ssq_diamond_search .diamond_filters .filter_options:not(.shape_filter) {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        margin-top: 0;
        overflow: visible;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options:not(.shape_filter) > button,
    #ssq_diamond_search .diamond_filters .filter_options:not(.shape_filter) > button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        width: auto;
        min-width: 0;
        height: 42px;
        padding: 12px 8px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        box-shadow: inset 0 0 0 0.75px #E4DED8;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 18px;
        letter-spacing: -0.5px;
        color: #3E3C39;
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .filter_options:not(.shape_filter) > button.active,
    #ssq_diamond_search .diamond_filters .filter_options:not(.shape_filter) > button.active {
        background: rgba(194, 206, 178, 0.30);
        box-shadow: inset 0 0 0 1.5px #27423B;
        color: #0F0E0D;
    }
    /* CLARITY is the one group the frame pins: 80 wide, four to a row. */
    #diamond_search.sf_archive .diamond_filters .clarity_filter > button,
    #ssq_diamond_search .diamond_filters .clarity_filter > button,
    #diamond_search.sf_archive .diamond_filters .filter_options.clarity > button,
    #ssq_diamond_search .diamond_filters .filter_options.clarity > button {
        flex: 0 0 80px;
        width: 80px;
    }

    /* ---- numeric inputs under the two sliders --------------------------- */
    #diamond_search.sf_archive .diamond_filters .d_filter input[type=text],
    #ssq_diamond_search .diamond_filters .d_filter input[type=text] {
        box-sizing: border-box;
        width: 80px;
        height: 40px;
        padding: 0 8px;
        border: 1px solid #E4DED8;
        border-radius: 8px;
        background: #FFFFFF;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: 0.75px;      /* POSITIVE -- `0.50 ct` / `$3,000` */
        color: #0F0E0D;
        text-align: center;
    }
    /* price carries the wider pair, 110 x 40. */
    #diamond_search.sf_archive .diamond_filters .d_filter.price input[type=text],
    #ssq_diamond_search .diamond_filters .d_filter.price input[type=text] {
        width: 110px;
    }

    /* ---- ADVANCED FILTERS -- 344 x 60, r8, 1px #E4DED8 ------------------ */
    #diamond_search.sf_archive .diamond_filters .advanced_filters_toggle,
    #ssq_diamond_search .diamond_filters .advanced_filters_toggle,
    #diamond_search.sf_archive .diamond_filters .advanced_toggle,
    #ssq_diamond_search .diamond_filters .advanced_toggle {
        display: flex;
        align-items: center;
        justify-content: space-between;
        box-sizing: border-box;
        width: 100%;
        height: 60px;
        padding: 0 13px;
        border: 1px solid #E4DED8;
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: -0.5px;
        text-transform: uppercase;
        color: #0F0E0D;
        cursor: pointer;
    }
    /* `Ellipse 67` 24 x 24 #E4DED8 with an 11 x 12 plus stroked #0F0E0D. */
    #diamond_search.sf_archive .diamond_filters .advanced_filters_toggle::after,
    #ssq_diamond_search .diamond_filters .advanced_filters_toggle::after,
    #diamond_search.sf_archive .diamond_filters .advanced_toggle::after,
    #ssq_diamond_search .diamond_filters .advanced_toggle::after {
        content: "";
        flex: 0 0 24px;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background:
            linear-gradient(#0F0E0D, #0F0E0D) center/12px 1px no-repeat,
            linear-gradient(#0F0E0D, #0F0E0D) center/1px 12px no-repeat,
            #E4DED8;
    }

    /* ---- SHAPE's Standard / Antique toggle ------------------------------ */
    #diamond_search.sf_archive .diamond_filters .fancy_shapes_toggle,
    #ssq_diamond_search .diamond_filters .fancy_shapes_toggle {
        display: inline-flex;
        align-items: center;
        box-sizing: border-box;
        height: 40px;
        padding: 0;
        border-radius: 10px;
        box-shadow: inset 0 0 0 0.75px #27423B;
        overflow: hidden;
    }
    #diamond_search.sf_archive .diamond_filters .fancy_shapes_toggle > *,
    #ssq_diamond_search .diamond_filters .fancy_shapes_toggle > * {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        height: 38px;
        padding: 0 17px;
        border: 0;
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: -0.5px;
        color: #27423B;
        white-space: nowrap;
        cursor: pointer;
    }
    #diamond_search.sf_archive .diamond_filters .fancy_shapes_toggle > .active,
    #ssq_diamond_search .diamond_filters .fancy_shapes_toggle > .active {
        background: #27423B;
        color: #FAF3ED;
    }

    /* ---- the two corrections my own measurement caught ------------------
       1. PADDING NEEDS `!important` HERE. diamond-search.css:1188 carries
          `padding: 15px 5px !important` on these chips, so the board's 12/8
          cannot be stated any other way -- MEASURED before this, the chips came
          back `15px 5px` with every other value correct. stone-first.css:3452
          already does exactly this for the archive's cut and fluorescence
          groups and records the same reason; this generalises it to every chip
          group the new board covers, on both rails.
       2. THE ADVANCED CONTROL IS `.advanced_filters_button button`, which is
          what diamond-search.js:2613 binds. The earlier guess at
          `.advanced_filters_toggle` matched nothing -- MEASURED as `none`. */
    #diamond_search.sf_archive .diamond_filters .filter_options:not(.shape_filter) > button,
    #ssq_diamond_search .diamond_filters .filter_options:not(.shape_filter) > button {
        padding: 12px 8px !important;
    }
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button button,
    #ssq_diamond_search .diamond_filters .advanced_filters_button button {
        display: flex;
        align-items: center;
        justify-content: space-between;
        box-sizing: border-box;
        width: 100%;
        height: 60px;
        padding: 0 13px;
        border: 1px solid #E4DED8;
        border-radius: 8px;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: -0.5px;
        text-transform: uppercase;
        color: #0F0E0D;
        cursor: pointer;
    }
    /* NO `::after` PLUS -- THE BUTTON ALREADY HAS ONE. Owner: *"in the filters
       page for natural diamonds there are two plus in Advanced Filters, weird
       ass -- remove those."* There were exactly two: this drawn-in-CSS glyph,
       and the markup's own `<span id="advanced_plus">` holding a 24x24 SVG.
       MEASURED at 390, both 24x24 and both painting.

       The span is the one that stays, and not arbitrarily: it is a PAIR with
       `#advanced_minus`, and diamond-search.css's `.advanced_filters_button
       button.opened span` flips it when the panel opens. A `::after` cannot
       follow that state, so keeping mine would have left a permanent + on a
       panel that was open. Styling for the span is below. */
    #diamond_search.sf_archive .diamond_filters .advanced_filters_button button > span,
    #ssq_diamond_search .diamond_filters .advanced_filters_button button > span {
        flex: 0 0 24px;
        width: 24px;
        height: 24px;
    }
}

/* =============================================================================
   SORT BY -- 14664:47958 `Sorting`, the row above the groups
   -----------------------------------------------------------------------------
   Owner: *"add sort by like in this design exactly."*

   The frame puts it FIRST in the filters column, above SHAPE, and gives it a
   box the build never had:

     row     345 x 40, r4, 1px #E4DED8, pad 12/8, itemSpacing 6
     label   "Sort by Carat (High to low)" 16/19 ls -0.21 #0F0E0D, one run
     chevron `Frame 39470` 10 x 12 at the trailing edge, a 10 x 5 vector
             stroked #0F0E0D at 1px -- i.e. a plain down chevron, no box
     below    16 before `shape` starts (y153 -> y169)

   `order: -1` puts it first without moving the markup: diamond-search.php prints
   `.diamond_sort_by` AFTER the groups, and re-ordering the PHP would move it on
   the desktop rail too, where it has its own home in `.dsq_header_controls`
   (_advanced-search.css:418) and is not part of this column at all.

   The options list keeps whatever the base sheet gives it -- the board draws the
   row closed and says nothing about the open state.
   ============================================================================= */
@media (max-width: 991px) {
    #diamond_search .search_filters .diamond_sort_by,
    #ssq_diamond_search .search_filters .diamond_sort_by {
        /* ALIGNED WITH THE GROUPS, AND 40 TALL.
           MEASURED with the drawer open at 390: the groups sit at x24 w342
           (they live in a `.col-12` wrapper at x12 that carries 12px of its own
           padding), while this row is a DIRECT child of `.search_filters` at
           x0 w390 -- so it ran full-bleed while everything under it was inset.
           The 24 either side puts it on the groups' own column; the board's is
           345 at x22 inside 390, which is the same column one pixel over.

           `height: 40` is the frame's own `Sorting` height. Its 12/8 padding and
           a 19px line come to 43, i.e. Figma is clipping there -- so the height
           is stated and the vertical padding derived from it (9.5 + 19 + 9.5 +
           2 of border = 40) rather than the reverse. */
        order: -1;
        position: relative;
        box-sizing: border-box;
        width: auto;
        height: 40px;
        margin: 0 24px 16px;
        padding: 0;
        border: 1px solid #E4DED8;
        border-radius: 4px;
        background: transparent;
    }
    /* A BLOCK, NOT A FLEX ROW. The board's label is ONE run -- "Sort by Carat
       (High to low)" -- and the markup spells it as a text node plus a <span>.
       Making the <p> a flex container turns those into two flex items, and the
       whitespace between them collapses: MEASURED, the row read
       "Sort byPrice (Low to high)" with the space gone. Left as normal inline
       flow, the run is intact; the chevron is taken out of that flow and pinned
       instead, with room reserved for it in the right padding (8 + 10 + 6). */
    #diamond_search .search_filters .diamond_sort_by > p,
    #ssq_diamond_search .search_filters .diamond_sort_by > p {
        display: block;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 9.5px 24px 9.5px 8px;   /* 9.5 + 19 + 9.5 + 2 border = 40 */
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 16px;
        line-height: 19px;
        letter-spacing: -0.21px;
        color: #0F0E0D;
        white-space: nowrap;
        cursor: pointer;
    }
    /* The label is ONE run on the board, so the value is not restyled away from
       the words in front of it. */
    #diamond_search .search_filters .diamond_sort_by > p > span,
    #ssq_diamond_search .search_filters .diamond_sort_by > p > span {
        font-size: inherit;
        line-height: inherit;
        letter-spacing: inherit;
        color: inherit;
        text-align: left;
    }
    #diamond_search .search_filters .diamond_sort_by > p svg,
    #ssq_diamond_search .search_filters .diamond_sort_by > p svg {
        position: absolute;
        top: 50%;
        right: 8px;
        transform: translateY(-50%);
        width: 10px;
        height: 12px;
        color: #0F0E0D;
    }

    /* THE WORD SPACE, which the markup does not carry. 14664:47958's label is a
       single run -- "Sort by Carat (High to low)" -- but the rails build it as
       two ADJACENT elements: MEASURED on the archive, the <p> holds
       `<span class="sf_sort_prefix">Sort by</span><span>Price (Low to high)</span>`
       with nothing between them, so it read "Sort byPrice". The builder's twin
       uses `.dsq_sort_prefix` and is written the same way. A non-breaking space
       after the prefix restores the run without touching either writer, and
       cannot be collapsed away by a future layout change. */
    #diamond_search .search_filters .diamond_sort_by .sf_sort_prefix::after,
    #ssq_diamond_search .search_filters .diamond_sort_by .sf_sort_prefix::after,
    #diamond_search .search_filters .diamond_sort_by .dsq_sort_prefix::after,
    #ssq_diamond_search .search_filters .diamond_sort_by .dsq_sort_prefix::after {
        content: "\00a0";
    }
}

/* ===========================================================================
   LIST VIEW -- THE HEART IS TERRACOTTA, AND THE COLUMN HEADS MATCH THEIR ROWS
   ---------------------------------------------------------------------------
   Owner: *"in list view for diamonds, heart colour is changed to terracotta"*
   and *"for list view again, in category page, titles font size too big."*

   THE HEART. `.sf_row_heart`'s glyph was stroked #0F0E0D -- MEASURED, the path
   computed `stroke: rgb(15, 14, 13)`. Terracotta is already a theme token
   (main.css:12, --terracotta #C65858), so it is referenced rather than
   re-spelled. Stroke AND fill are set: the resting heart is an outline, and the
   pressed one fills with the same colour, so a shortlisted row reads at a
   glance.

   THE COLUMN HEADS. MEASURED on the category page's list view: the heads --
   Shape, Carat, Cut, Color, Clarity, L/W Ratio, Measurements, Price -- came out
   16px/21px while every data cell under them is 12px/13px. Four pixels of
   difference across one table is what reads as "too big"; the head was taken
   from 14634:47676, which is the BUILDER's phone frame, and the category rows
   are set a size smaller than that board's. Matched to the rows they label, so
   the two read as one table.

   Scoped to the archive's list view only -- the builder rail keeps the size its
   own board gives it.
   =========================================================================== */
/* ...AND THE RESTING HEART IS GREEN, NOT RED. Owner, correcting the above:
   *"the colours for favourites are off -- it's green outline when not selected,
   and when selected, outline plus fill is red. For the exact colour check how it
   was."*

   "How it was" is in the repo: `assets/media/ringbuilder/icon-heart-outline-
   green.svg`, stroked #27423B -- jade, the brand green -- which is shipped and
   referenced by nothing. The terracotta note above read *"heart colour is
   changed to terracotta"* as applying to BOTH states, so the resting heart went
   red too and the two states stopped being distinguishable at a glance: MEASURED
   on the list view, unselected `stroke: rgb(198,88,88)` and selected the same
   stroke with a fill. Red now means one thing -- shortlisted.

   Only the resting stroke changes; the pressed rule below is already what the
   owner describes. The GRID card's heart is a different component on #3E3C39
   and is left alone -- it was not what was asked about. */
#diamond_search.sf_archive .result_item_row .sf_row_heart svg,
#diamond_search.sf_archive .result_item_row .sf_row_heart svg path {
    stroke: var(--jade, #27423B);
    fill: none;
}
#diamond_search.sf_archive .result_item_row .sf_row_heart[aria-pressed="true"] svg,
#diamond_search.sf_archive .result_item_row .sf_row_heart.selected svg,
#diamond_search.sf_archive .result_item_row .sf_row_heart.active svg,
#diamond_search.sf_archive .result_item_row .sf_row_heart[aria-pressed="true"] svg path,
#diamond_search.sf_archive .result_item_row .sf_row_heart.selected svg path,
#diamond_search.sf_archive .result_item_row .sf_row_heart.active svg path {
    fill: var(--terracotta, #C65858);
    stroke: var(--terracotta, #C65858);
}

/* MATCHED TO THE RULE IT HAS TO BEAT. :4810 sets these at 16/21 through
   `#diamond_search.sf_archive .search_header > .row > .header_item p` -- an id
   plus four classes -- so a shorter selector simply loses: MEASURED after a
   first attempt at `.search_header p`, the heads were still 16px. Same selector,
   one size down, rather than reaching for !important. */
#diamond_search.sf_archive .search_header > .row > .header_item p {
    font-size: 12px;
    line-height: 13px;
}

/* =============================================================================
   THE MOBILE FILTER DRAWER'S TOP BAR -- 14664:48111 / 14664:47958
   -----------------------------------------------------------------------------
   Owner: *"the filters top bar has not been changed for filters in diamond
   searches, advanced diamond searches and non-BYR flows, despite being repeated
   multiple times -- that ugly green top bar is still stuck like that."*

   It was. MEASURED at 390 on /natural-diamonds/ with the drawer open:
   `.filters_mobile_toggle` came back 390x56, `background #27423B`, `color
   #C2CEB2`, `border-radius: 0 0 24px 24px`, laid out Reset | Filters | X.

   14664:48111 draws a different bar entirely, and it is the SAME bar as
   14621:48525 -- the one already built for the engagement-ring picker:

     Header            390 x 52, fill #FAF3ED, 1px #E4DED8 stroke, pad 4 / 18
     row               354 x 44, SPACE_BETWEEN
     left   `Filter`   92 x 44 -- an 18x18 funnel stroked #0F0E0D, gap 2,
                       `Filters` FG 18/19 ls -0.21 #0F0E0D, gap 4, then a 24x24
                       r50 #D8DDCA badge whose count is FG 14/19 #27423B
     right  `Filter`   60 x 44 -- an 18x18 reset glyph and `Reset` FG 17/19
                       ls -0.21, both #3E3C39
     NEITHER pill has a fill or a stroke; both are `visible: false` on the frame.

   THE CLOSE IS KEPT, AND THAT IS A DECISION, NOT THE BOARD. 14664:48111 draws
   only the two controls. This is a full-screen drawer and the X is its only
   top-level dismiss, so it stays -- restyled to the bar instead of removed, and
   flagged here rather than passed off as the frame's. One declaration deletes it
   if the frame is meant literally.

   Scoped to `#search_filters_mobile.opened`, which is every mount this markup
   has: the two archives and the in-quiz advanced search. The CLOSED pill is not
   touched -- it is a different job and the owner has signed it off.
   ============================================================================= */
@media (max-width: 991px) {
    #search_filters_mobile.opened .filters_mobile_toggle {
        box-sizing: border-box;
        height: calc(52px + env(safe-area-inset-top, 0px));
        padding: calc(4px + env(safe-area-inset-top, 0px)) 18px 4px;
        gap: 10px;
        background: #FAF3ED;
        border-bottom: 1px solid #E4DED8;
        border-radius: 0;
        color: #0F0E0D;
    }
    /* `Filters` is the LEFT item on the frame and Reset the right; the markup
       prints Reset first, so the order is set here rather than by moving the
       nodes -- diamond-search.js binds both by class and does not care. */
    #search_filters_mobile.opened .filters_mobile_toggle > .df_hdr_filters   { order: 1; }
    #search_filters_mobile.opened .filters_mobile_toggle > .diamond_filters_reset { order: 2; margin-left: auto; }
    #search_filters_mobile.opened .filters_mobile_toggle > .close_mobile_filters  { order: 3; }

    #search_filters_mobile.opened .filters_mobile_toggle > .df_hdr_filters {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: none;
        color: #0F0E0D;
    }
    #search_filters_mobile.opened .filters_mobile_toggle > .df_hdr_filters svg {
        width: 18px;
        height: 18px;
    }
    #search_filters_mobile.opened .filters_mobile_toggle > .df_hdr_filters svg path {
        stroke: #0F0E0D;
    }
    /* the frame's badge: 24x24, r50, #D8DDCA, count #27423B at 14/19. The green
       `#C2CEB2` it inherited from the bar is gone with the bar. */
    #search_filters_mobile.opened .filters_mobile_toggle span.df_hdr_badge {
        position: static;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 24px;
        width: 24px;
        height: 24px;
        margin: 0 0 0 4px;
        border-radius: 50%;
        background: #D8DDCA;
    }
    #search_filters_mobile.opened .filters_mobile_toggle span.df_hdr_badge.is-empty { display: none; }
    #search_filters_mobile.opened .filters_mobile_toggle span.df_hdr_badge_count {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        letter-spacing: -0.21px;
        color: #27423B;
    }
    #search_filters_mobile.opened .filters_mobile_toggle > .diamond_filters_reset {
        display: inline-flex;
        align-items: center;
        gap: 2px;
        font-family: 'FoundersGrotesk', sans-serif;
        font-weight: 400;
        font-size: 17px;
        line-height: 19px;
        letter-spacing: -0.21px;
        text-transform: none;
        color: #3E3C39;
    }
    #search_filters_mobile.opened .filters_mobile_toggle > .diamond_filters_reset svg { width: 18px; height: 18px; }
    #search_filters_mobile.opened .filters_mobile_toggle > .diamond_filters_reset svg path { stroke: #3E3C39; }
    #search_filters_mobile.opened .filters_mobile_toggle > .close_mobile_filters svg { width: 16px; height: 16px; }
    #search_filters_mobile.opened .filters_mobile_toggle > .close_mobile_filters svg path { stroke: #3E3C39; }
}

/* =============================================================================
   THE INFO GLYPHS ARE CITRINE -- Owner: *"all info buttons must be citrine
   completely."*
   -----------------------------------------------------------------------------
   These are RASTER, not SVG: diamond-filters.php:295 and its siblings print
   `<img src=".../icons/info-icon.webp">`, so `fill` and `stroke` have nothing to
   act on and a `filter` chain could only approximate #C69858.

   The asset carries real alpha -- VERIFIED by decoding it: 69x68, 3,782 of
   4,692 pixels fully transparent, the glyph itself a near-black (14,14,14). So
   its own shape is used as a MASK and the colour is painted behind it, which
   gives the token exactly rather than an approximation and needs no new file.

   The <img> keeps its box (it is what sizes the span) and is hidden with
   `visibility`, not `display`, so nothing reflows.
   ============================================================================= */
#diamond_search .filter_title p span:has(> img[src*="info-icon"]),
#ssq_diamond_search .filter_title p span:has(> img[src*="info-icon"]) {
    position: relative;
    display: inline-block;
}
#diamond_search .filter_title p span > img[src*="info-icon"],
#ssq_diamond_search .filter_title p span > img[src*="info-icon"] {
    visibility: hidden;
}
#diamond_search .filter_title p span:has(> img[src*="info-icon"])::after,
#ssq_diamond_search .filter_title p span:has(> img[src*="info-icon"])::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--citrine, #C69858);
    -webkit-mask: url("../../assets/media/icons/info-icon.webp") center / contain no-repeat;
    mask: url("../../assets/media/icons/info-icon.webp") center / contain no-repeat;
}

/* =============================================================================
   TWO SPACING CORRECTIONS ON THE PHONE FILTER SHEET -- 14664:47958
   -----------------------------------------------------------------------------
   1. THE SORT ROW CLEARS THE HEADER. Owner: *"give some space between the bottom
      of the filters header and the top of the sort-by dropdown -- they look too
      close."* They were 4px apart: MEASURED at 390, header bottom y52, the
      `.diamond_sort_by` box top y56. The frame puts `Header` at 46..98 and the
      `Sorting` row at y113, so the gap it draws is 15.

      Stated as a margin on the sort row rather than padding on the sheet,
      because the sheet's top padding also sets the distance for everything that
      scrolls under the bar.

   2. `Signature Ideal` FITS ITS CHIP. Owner: *"Signature Ideal flows out, like
      the text flows out of the button."* MEASURED in the in-quiz drawer at 390:
      the chip is 80 wide with `white-space: nowrap` and a scrollWidth of 84 --
      4px of label painting outside its own box.

      The label wraps instead. Height goes from a fixed 42 to a 42 MINIMUM so a
      two-line chip grows rather than clipping, and the grid row equalises around
      it; `line-height` drops to 16 so two lines sit inside 42 without the chip
      growing at all for this label. Shrinking the type or the padding was the
      alternative and both would have had to apply to every chip in the group to
      keep the row even -- this only changes the one that does not fit.
   ============================================================================= */
@media (max-width: 991px) {
    /* `.search_filters.opened`, NOT `#search_filters_mobile.opened` -- the first
       guess matched nothing. MEASURED chain: the sort row's parent is
       `div.search_filters.opened`, which carries `padding-top: 56px` to clear
       the fixed bar; `#search_filters_mobile` is a different (0-height) node. */
    /* `.search_filters.opened`, NOT `#search_filters_mobile.opened` -- the first
       guess matched nothing. MEASURED chain: the sort row's parent is
       `div.search_filters.opened`, which carries `padding-top: 56px` to clear
       the fixed bar; `#search_filters_mobile` is a different (0-height) node.

       Carrying the ids too, because the second guess lost as well: the sort row
       already has `margin: 0 24px 16px` from
       `#diamond_search .search_filters .diamond_sort_by` (1,2,0), and a
       SHORTHAND margin resets margin-top -- so a bare `.search_filters.opened >`
       rule at (0,3,0) was overridden and computed 0. With the id it is (1,3,0)
       and wins. */
    #diamond_search .search_filters.opened > .diamond_sort_by,
    #ssq_diamond_search .search_filters.opened > .diamond_sort_by { margin-top: 11px; }
    /* 11, not 15: the sheet's own `padding-top: 56px` clears a 52px bar and
       already contributes the first 4. 4 + 11 = the frame's 15. MEASURED. */

    #diamond_search.sf_archive .diamond_filters .filter_options:not(.shape_filter) > button,
    #ssq_diamond_search .diamond_filters .filter_options:not(.shape_filter) > button {
        height: auto;
        min-height: 42px;
        line-height: 16px;
        white-space: normal;
        text-align: center;
    }
}

/* =============================================================================
   /engagement-rings/ AT DESKTOP: THE FILTERS ARE A LEFT RAIL -- 14674:49009
   (closed) / 14674:48072 (open)
   -----------------------------------------------------------------------------
   Owner: *"exact reconstruction for /engagement-rings/ and the stone flow
   engagement drawer for desktop ... side by side like diamonds"*, filters
   sliding.

   MEASURED BEFORE, at 1728: a centred title, the shape / metal / style controls
   laid out as ONE horizontal strip (`.shop_filters.d-lg-flex`) above the grid,
   and `ul.products` 1416 wide at a 156 gutter. The board is a different page:
   gutter 80, a toolbar row, and the controls stacked in a 345 rail beside a
   1134 grid.

   `.the-content` is the common ancestor of all three parts -- the Flow-3 chrome,
   `.shop_filters` and `ul.products` are its children -- so it becomes the grid
   and nothing has to move in the DOM. Everything spans both columns by default;
   only the rail and the product list are placed, which keeps the title, the
   description and anything a later template adds out of the row.

   THE RAIL COLLAPSES TO A ZERO TRACK rather than being display:none'd, so the
   grid has something to animate between, and the panel slides on its own
   transform -- a composited property, where animating the track's width alone
   would reflow every card on every frame.

   THE FLOW-3 TOOLBAR IS NOW ON THIS PAGE TOO. Its rules were written
   `html.sf-has-stone body.sf-ring-archive`, i.e. only while a stone was held, so
   the plain archive never got the title/count row, the All Settings | Shortlist
   pair or the Filters pill -- the three things the board's toolbar is made of.
   The `html.sf-has-stone` half is dropped from all 38 of them; the stone flow
   keeps exactly what it had and the plain archive gains it.
   ============================================================================= */
@media (min-width: 992px) {
    body.sf-ring-archive .the-content {
        display: grid;
        grid-template-columns: 0 1fr;
        column-gap: 0;
        align-items: start;
        /* DENSE, SO THE EMPTY STATE CANNOT PUSH THE RAIL OUT OF ITS ROW.
           Owner: *"on engagement ring pages the filters don't open and close,
           they're empty when it's an empty shortlist page -- filters must be
           there."* The rail opened and closed correctly; it was 422px below
           where it belongs, so the column under the Filters pill was blank and
           only `SHAPE` reached the bottom of the window.

           Grid auto-placement is SPARSE by default: the cursor only moves
           forward. `.sf_ring_empty_state` sits BEFORE the rail in the DOM and
           is pinned to column 2, so the moment the shortlist is empty and it
           stops being `display: none`, it takes the next row at column 2 and
           parks the cursor there. The rail, which wants column 1, can no
           longer go back for it and starts a row of its own.

           MEASURED at 1440 with the rail open, before:
             hub     rail y 381 -> 803   empty state 846x422 in a row of its own
             archive rail y 395 -> 817   same 422, same cause

           `dense` makes each item look from the start of the grid again, so the
           rail backfills column 1 of the row the empty state is already in.
           Nothing else moves: every in-flow child here declares its own column,
           and in the ordinary (non-empty) state the placement is identical --
           the empty state is `display: none` then, and a `display: none` child
           is not a grid item at all, which is exactly why this only ever showed
           up on an empty shortlist. */
        grid-auto-flow: row dense;
        transition: grid-template-columns 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    column-gap 320ms cubic-bezier(0.22, 1, 0.36, 1);
    }
    /* everything is full-width unless it is one of the two columns */
    body.sf-ring-archive .the-content > * { grid-column: 1 / -1; min-width: 0; }
    body.sf-ring-archive .shop_filters:not(.mobile_filters) { grid-column: 1; }
    body.sf-ring-archive .the-content > ul.products   { grid-column: 2; }

    body.sf-ring-archive.sf-rail-open .the-content {
        grid-template-columns: 345px 1fr;
        column-gap: 89px;
    }

    /* ---- the rail ------------------------------------------------------- */
    body.sf-ring-archive .shop_filters:not(.mobile_filters) {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 24px;                       /* `Filters` frame itemSpacing */
        box-sizing: border-box;
        width: 345px;
        margin: 0;
        padding: 0;
        overflow: hidden;
        transform: translateX(-24px);
        opacity: 0;
        visibility: hidden;
        transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1),
                    visibility 0s linear 320ms;
    }
    body.sf-ring-archive.sf-rail-open .shop_filters:not(.mobile_filters) {
        transform: none;
        opacity: 1;
        visibility: visible;
        transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1),
                    visibility 0s;
    }
    /* each control group stacks and fills the rail */
    body.sf-ring-archive .shop_filters:not(.mobile_filters) > div {
        width: 100%;
        margin: 0;
    }
    /* The head's type lives in the shared filter block below -- this was a
       duplicate of it, and `:not(.mobile_filters)` made it a MORE SPECIFIC
       duplicate (0,4,2 against 0,3,2), so it outranked the rule that drops the
       literal `Shape:` text node and the rail painted `SHAPESHAPE:`. Deleted
       rather than re-specified: there is one head style and it belongs with the
       rest of the block. */
    body.sf-ring-archive .shop_filters:not(.mobile_filters) .filter_row {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
    }
    /* SORT IS NOT A FILTER -- it is moved into `.sf_ring_controls` by
       stone-first.js (see the note there); this is only its placement once it
       arrives. `order: 1` with the pill, so the row reads pill, sort, then the
       segmented pair pushed right, which is 14674:48072's order. */
    body.sf-ring-archive .sf_ring_controls > .sort_filter {
        order: 1;
        margin: 0 auto 0 0;
        padding: 0;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented { margin-left: 0; }
    body.sf-ring-archive .the-content { position: relative; }

    /* ---- the grid ------------------------------------------------------- */
    /* 14674:48072: 4 cards of 264 on a 290 pitch in the 1134 the rail leaves.
       Closed, the board is the same 4 up across the full content width. */
    body.sf-ring-archive .the-content > ul.products {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 24px;
        margin: 0;
        padding: 0;
        list-style: none;
    }
    body.sf-ring-archive .the-content > ul.products::before,
    body.sf-ring-archive .the-content > ul.products::after { content: none; display: none; }
    body.sf-ring-archive .the-content > ul.products > li.product {
        width: auto;
        max-width: none;
        margin: 0;
        float: none;
    }

    @media (prefers-reduced-motion: reduce) {
        body.sf-ring-archive .the-content,
        body.sf-ring-archive .shop_filters:not(.mobile_filters) { transition: none; }
    }
}

/* =============================================================================
   ...AND THE TOOLBAR THAT DRIVES IT -- 14674:49009 / 14674:48072
   -----------------------------------------------------------------------------
   The Flow-3 ring chrome -- title / count row, All Settings | Shortlist, the
   Filters pill -- is printed by da_ring_archive_flow3_header() on every ring
   archive, but EVERY rule for it was written inside `@media (max-width: 991px)`.
   MEASURED at 1728: the pill computes `display: inline-block` with height 0 and
   `.sf_ring_chrome` is 0 tall -- the markup is there and nothing styles it, so
   the desktop page had no toolbar to open a rail with.

   Built here at >=992 to the board's row: `Frame 1171276644` is 1728x68 with
   12/80 padding, the Filters pill 344x44 at the left gutter and the
   All settings | Shortlist pair 266x44 at the right. The count stays on the
   title line above it, which is where 3.3's own header puts it.

   THE PAGE GUTTER GOES TO THE BOARD'S 80. The archive sits in a Bootstrap
   `.container` that MEASURED 1416 at a 156 gutter; the board's content runs
   80..1648 (1568). Scoped to this archive's own container so the header, the
   footer and every other page keep theirs.
   ============================================================================= */
@media (min-width: 992px) {
    body.sf-ring-archive .archive-container > .container {
        max-width: none;
        width: 100%;
        padding-left: 80px;
        padding-right: 80px;
    }
    body.sf-ring-archive .sf_ring_chrome { display: block; }
    /* the details bar's visibility is NOT a desktop question -- see the pair
       below this block, which both widths share. */

    body.sf-ring-archive .sf_ring_header {
        display: flex;
        flex-direction: column;
        gap: 16px;
        margin: 0 0 24px;
    }
    body.sf-ring-archive .sf_ring_titlerow {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 24px;
    }
    /* THE COUNT SITS WITH THE HEADING, 24 AFTER THE WORDS. Owner: *"on category
       pages of engagement rings the results line is misaligned, it's on the
       right for some reason."*

       It was a sibling of the whole text COLUMN under `space-between`. At 390
       that reads as one line, because the column fills the content width --
       MEASURED, title x12, `73 Results` ending at x378. At 1728 the column is
       pinned to the board's 622 and the same rule threw the count to x1583:
       880px of nothing between a heading and its own count. Putting it to the
       column's right edge instead (x726) only moved the hole; the count was
       still measured off a box the reader cannot see.

       14684:49247 draws no count on this band at all, so there is no board
       position to honour -- the heading is the only thing on the page it
       belongs to, and `.sf_ring_titleline` (da-general.php) is the pair. 24 is
       the row's own gap, already stated above. */
    /* ...AND ON THE BAND'S LAST LINE, HARD RIGHT. Owner: *"on engagement ring
       pages, push results to the right side, bottom, but not out of the divider
       line we created -- the last line on the right is results."*

       Pairing it with the heading (the note above) closed the 880px hole, but it
       still sat on the TITLE's line. The band's last line is the description's,
       and its right edge is the content column's -- so the count comes out of
       the line's flow and anchors to the row, which is already
       `position: relative` for the divider it draws.

       `bottom: 13px` is not a chosen number: it is the row's own
       `padding-bottom`, the gap it already keeps between its content and the
       rule at its edge. MEASURED at 1440 -- row [80,184] 1280x111, divider on
       its bottom edge at 295, description ending at 282 -- so 13 puts the count
       on the description's line and 13 clear of the rule, which is the "not out
       of the divider" half.

       Desktop only. At 390 there is no 622 column and no room for a second
       column of text, so the count stays on the title's line at the gutter --
       where both boards put it, and what was not asked to move. */
    body.sf-ring-archive .sf_ring_titleline { gap: 24px; }
    body.sf-ring-archive .sf_ring_titlerow .sf_ring_count {
        position: absolute;
        right: 0;
        bottom: 13px;
        margin: 0;
    }
    body.sf-ring-archive .sf_ring_title {
        margin: 0;
        font-family: 'Canela', serif;
        font-weight: 300;
        font-size: 37px;
        line-height: 37px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-transform: uppercase;
        color: #0F0E0D;
    }
    body.sf-ring-archive .sf_ring_count {
        margin: 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 16px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #3E3C39;
    }
    /* `Frame 1171276644` -- pill at the left gutter, segmented at the right */
    body.sf-ring-archive .sf_ring_controls {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 24px;
        min-height: 44px;
    }
    /* THE PILL IS 14674:49057, TO THE NUMBER.
       Owner: *"the Filters button looks off -- the filters icon and filter
       button do not match."* It did not: every value here was a guess that came
       out one notch small, so the glyph read as a separate little mark floating
       beside a word rather than one control. Against the board, MEASURED:

                       was        board (14674:49057)
         box           132x44     116x44
         radius        4          8
         padding-x     16         12
         gap           8          4   (and the glyph's own frame is 18 for a
                                       14 drawing, so 2 of visual space)
         label         16/19      18/19
         glyph         16x16      18x18 frame, 14x14 vector, 1px #FAF3ED

       The width is left to the content now rather than pinned: 12 + 18 + 4 + 44
       + 12 is the board's own 116, and a `min-width` that disagrees with the
       sum of the parts is how it was 132 in the first place. */
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters {
        order: 1;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 4px;
        box-sizing: border-box;
        height: 44px;
        margin: 0;
        padding: 0 12px;
        border: 0;
        border-radius: 8px;
        background: #27423B;
        color: #FAF3ED;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        cursor: pointer;
    }
    /* `Frame` 18x18 around a 14x14 `Vector` -- the box is what sets the glyph's
       optical distance from the word, the drawing stays 14. */
    /* `inline-flex`, not just a gap. Owner: *"on the engagement rings category
       page and its sub-variation pages, and the stone-flow engagement drawer,
       make sure the Filters CTA's label and filter icon are centred."*

       MEASURED at 1728 the group computed `display: block`, so the glyph and the
       word were laid out as INLINE boxes and sat on the text BASELINE -- a 14px
       icon against an 18px label reads as riding high, which is the mis-centring.
       `gap` needs a flex container to apply at all, so the rule that set it was
       also doing nothing. */
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_filters_group {
        display: inline-flex;
        align-items: center;
        gap: 2px;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_filters_icon {
        flex: 0 0 18px;
        width: 18px;
        height: 18px;
        align-items: center;
        justify-content: center;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_filters_icon svg { width: 14px; height: 14px; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_filters_icon svg path {
        stroke: #FAF3ED;
        stroke-width: 1;
        fill: none;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented {
        order: 2;
        display: inline-flex;
        align-items: center;
        height: 44px;
        border: 1px solid #27423B;
        border-radius: 8px;
        overflow: hidden;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented .sf_seg {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        height: 100%;
        min-width: 130px;
        padding: 0 17px;
        border: 0;
        background: transparent;
        color: #27423B;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 16px;
        line-height: 19px;
        text-decoration: none;
        cursor: pointer;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented .sf_seg.is-active {
        background: #27423B;
        color: #FAF3ED;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented .sf_seg_icon { display: inline-flex; width: 13px; height: 12px; }

    /* the archive's own title block is replaced by the toolbar's, so the
       centred h1 and its description stop competing with it */
    body.sf-ring-archive .the-content > .page_title,
    body.sf-ring-archive .archive-container h1.woocommerce-products-header__title { display: none; }
}

/* =============================================================================
   THE RAIL'S CONTROLS ARE THE BOARD'S FILTER BLOCK -- 14674:48442
   -----------------------------------------------------------------------------
   Owner: *"I said clearly you're supposed to make this exactly like the design
   ... on the sidebar you have what the filters page looks like on mobile."*

   Right -- the previous pass railed the archive's LEGACY controls (bare shape
   glyphs, four colour dots, small style thumbnails) instead of rebuilding them.
   14674:48442 is the same block the phone drawer draws, and the same one
   already built for the settings picker, so the numbers come from it:

     rail        345, groups 24 apart
     SHAPE       rows 344 x 96, gap 8, rows 9 apart -> 4 up at 80 x 96
     METAL       chips 110 x 42, r8, pad 12/8, gap 8 -> 3 up
     STYLE       rows 344 x 96, gap 8 -> 3 up at 109 x 96
     selected    #C2CEB2 @30% fill with a 1.5px #27423B ring, chips AND tiles
                 alike (the tiles were #E9E8DB -- see the note on the rule);
                 resting 1px / 0.75px #E4DED8
     group head  Founders 16/19 ls -0.21, #3E3C39 @80%, UPPER, 12 under it

   The labels are new markup (shop-filter.php prints `.sf_opt_label` now) -- the
   shape and metal links carried a glyph and nothing else, so there was no name
   to lay out under them.

   PRICE IS NOW A REAL GROUP, and this note is kept as the record of why it was
   not. It read "no price group -- this archive has no price filter to drive it".
   That was true of shop-filter.php and false of WooCommerce: `WC_Query` already
   hooks `price_filter_post_clauses` on every product query, so `min_price` /
   `max_price` filter this archive out of the box. VERIFIED by curl before any
   code was written: 73 results bare, 19 at `?max_price=1200`, 6 at
   `?min_price=2750`. The group lives in da-general.php and
   components/diamond-search/price-filter.css.
   ============================================================================= */
/* -----------------------------------------------------------------------------
   ONE FILTER BLOCK, BOTH WIDTHS.
   Owner: *"you kind of fucked up the mobile view, so set that up properly, like
   how it is in the stone flow"*, with 14674:47735 (the phone page) and
   14674:49378 (the phone filters).

   This skin was written inside a `min-width: 992px` query and keyed to
   `:not(.mobile_filters)`, so the phone drawer kept the legacy one: a scrolling
   strip of bare 30px glyphs, bare 32px dots, `Shape:` with the colon, and no
   labels at all.

   14674:49378 is the SAME BLOCK as the desktop rail, at the same numbers -- its
   track is 344 against the rail's 345, shape 80 x 96 four up, metal 110 x 42
   three up, heads uppercase and bare. So the fix is not a second skin: the
   query comes off and `:not(.mobile_filters)` with it, and one block serves
   both. The two cannot drift because there is only one of them.
   -------------------------------------------------------------------------- */
/* ---- group heads ---------------------------------------------------- */
body.sf-ring-archive .shop_filters .filter_heading p {
    margin: 0 0 12px;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--sf-ls, -0.21px);
    text-transform: uppercase;
    color: rgba(62, 60, 57, 0.8);
}
/* the head prints "Shape: <active>" -- the board's head is the word alone */
body.sf-ring-archive .shop_filters .filter_heading .active_shape { display: none; }

/* ---- SHAPE: 4 up, 80 x 96 ------------------------------------------- */
body.sf-ring-archive .shop_filters .shape_filters .filter_row {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 9px 8px;
}
/* ---- STYLE: 3 up, 109 x 96 ------------------------------------------ */
body.sf-ring-archive .shop_filters .subcat_filters .filter_row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 9px 8px;
}
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p { margin: 0; }
/* both tile groups share one skin */
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    width: auto;
    height: 96px;
    margin: 0;
    padding: 12px 8px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    box-shadow: inset 0 0 0 0.75px #E4DED8;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 16px;
    letter-spacing: -0.5px;
    text-align: center;
    text-decoration: none;
    color: #3E3C39;
}
/* SELECTED IS THE GREEN, NOT THE CREAM. Owner: *"the selection is citrine right
   now -- change it to normal."* The tiles were filled #E9E8DB, which is the warm
   cream the board's SOLITAIRES export happened to carry; the chips beside them
   were already on #C2CEB2 @30%, so the one rail had two selected states. The
   frame's own fill is #C2CEB2 (14674:48442 / 14674:49378), and the 30% is what
   the stone-flow drawer ships -- so this is both the board's hue and the control
   the owner keeps asking this to match. */
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a.active,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active {
    background: rgba(194, 206, 178, 0.30);
    box-shadow: inset 0 0 0 1.5px #27423B;
    /* ...AND THE WORD IS BLACK, NOT THE STROKE'S GREEN. 14684:48651 is the
       selected tile and its label is #0F0E0D; #3E3C39 on 14684:48655 is the
       UNSELECTED one. The green belongs to the box, not to what is written in
       it. */
    color: #0F0E0D;
}

/* ...AND SO IS THE GLYPH. Owner: *"the selection in engagement category page
   filters -- they're still citrine, they should be black."*

   They were, and this block could not have fixed it: the ground and the stroke
   are written here but the MARK's colour is written in shop-filter.css, with
   `!important` on both halves --

     .shape_filters .active svg path          { fill: var(--citrine) !important }
     a.active .subcat_icon path|rect|polygon  { stroke: var(--citrine) !important }

   -- so a selected oval kept a #C69858 fill and a selected style kept a #C69858
   stroke no matter what the tile around them did. MEASURED on
   /engagement-rings/ with a shape and a style applied: glyph fill
   rgb(198,152,88), glyph stroke rgb(198,152,88).

   #0F0E0D is the board's: 14684:48651's `Vector` is #0F0E0D where the
   unselected 14684:48654 is #3E3C39. `!important` because the declaration it
   has to beat is one -- the rail is shared with other archives, whose own
   selected state is left exactly as it was. */
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a.active svg path,
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a.active svg g,
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a.active svg polygon,
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a.active svg rect {
    fill: #0F0E0D !important;
}
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active .subcat_icon path,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active .subcat_icon rect,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active .subcat_icon polygon,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active .subcat_icon line,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row > p > a.active .subcat_icon circle {
    stroke: #0F0E0D !important;
}
body.sf-ring-archive .shop_filters .shape_filters .filter_row > a svg,
body.sf-ring-archive .shop_filters .subcat_filters .filter_row .subcat_icon svg {
    width: auto;
    max-width: 100%;
    height: 44px;
}
body.sf-ring-archive .shop_filters .subcat_filters .filter_row .subcat_icon {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 44px;
}

/* ---- METAL: 3 up, 110 x 42 chips ------------------------------------ */
body.sf-ring-archive .shop_filters .metal_filters .filter_row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 4px;
    box-sizing: border-box;
    width: auto;
    height: 42px;
    margin: 0;
    padding: 12px 8px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    box-shadow: inset 0 0 0 1px #E4DED8;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 14px;
    line-height: 18px;
    letter-spacing: -0.5px;
    text-decoration: none;
    color: #0F0E0D;
    overflow: hidden;
}
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a.active {
    background: rgba(194, 206, 178, 0.30);
    box-shadow: inset 0 0 0 1.5px #27423B;
}
/* THE SWATCH IS A RING, NOT A DISC -- 14621:48077's `Rectangle 512`: 19x19,
   r100, no fill, a 4px stroke in the metal's colour. The markup paints the
   colour as a BACKGROUND, so it is moved onto the border and the fill is
   cleared; the 11px hole is the chip's own ground. */
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a .metal_option {
    flex: 0 0 19px;
    box-sizing: border-box;
    width: 19px;
    height: 19px;
    border: 4px solid currentColor;
    border-radius: 100px;
    background: none !important;
}
/* ATTRIBUTE SELECTORS, NOT CLASS ONES. The classes are `14k-white-gold`
   and friends -- a class literal cannot begin with a digit, so `a.14k-...`
   is a PARSE ERROR, and one invalid selector in a comma-separated list
   invalidates the WHOLE rule. MEASURED: the swatch came back
   `rgb(15,14,13)`, i.e. currentColor, because the rule carrying both forms
   was dropped entirely. */
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a[class*="white-gold"] .metal_option { color: #D0D0D0; }
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a[class*="yellow-gold"] .metal_option { color: #DCB84E; }
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a[class*="rose-gold"] .metal_option  { color: #E9C1B1; }
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a[class*="platinum"] .metal_option  { color: #B9B9B9; }
/* Palladium is new with the board's five-metal list; without its own rule
   the ring fell back to currentColor -- MEASURED rgb(15,14,13). */
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a[class*="palladium"] .metal_option { color: #A3A3A3; }
body.sf-ring-archive .shop_filters .metal_filters .filter_row > a .sf_opt_label {
    white-space: normal;
    text-align: left;
}

/* THE LABELS ARE ON AT BOTH WIDTHS NOW. This hid them below 992 on the reading
   that *"phone keeps the glyph-only controls it shipped with"* -- 14674:49378
   says otherwise: every shape tile and every metal chip on the phone drawer
   carries its word, in the same 16px the rail uses. The rule is gone rather
   than inverted, because with it gone there is nothing width-specific left to
   keep in step. */



/* THE DETAILS BAR IS IN-FLOW CHROME AT EVERY WIDTH.
   It belongs to the stone flow: without a stone there is nothing to summarise.
   The pair was written inside `@media (min-width: 992px)`, so below 992 nothing
   hid it -- MEASURED on /engagement-rings/oval-cut-engagement-rings/ at 390 with
   no stone and no origin in storage, `.sf_ring_details` computed `display:
   block`. A bar reading `Ring Details / Current Est.` with nothing behind it, on
   every ring page on every phone.

   Written on <html>, which is where the bootstrap actually stamps the class. The
   first half used to read `body.sf-ring-archive:not(.sf-has-stone)` -- body never
   carries that class, so the selector was always true and the rule only worked
   because the second half overrode it. It hid the right thing for the wrong
   reason, which is why moving it out of the query would not have been safe as
   written. */
html:not(.sf-has-stone) body.sf-ring-archive .sf_ring_details { display: none; }
html.sf-has-stone body.sf-ring-archive .sf_ring_details { display: block; }

/* =============================================================================
   THE HUB'S TITLE READS LEFT, ON THE SAME EDGE AS EVERYTHING UNDER IT
   -----------------------------------------------------------------------------
   Owner, on /engagement-rings/oval-cut-engagement-rings/: *"just left align the
   title, subtitle -- centred they look weird."*

   They did, and the reason is that the block was half converted: page.php prints
   the hub's title CENTRED, the breadcrumb added above it is LEFT, and the
   toolbar and grid below it are left as well. MEASURED at 1728, three different
   left edges in one column -- crumb at x156, title centred in 1416, and the
   toolbar and grid at x80.

   So the fix is two things, not one. The type goes left, and the block it sits
   in moves onto the page's own 80px gutter: `section.content-header`'s container
   is `margin: 0 144px; padding: 0 12px` where the archive's is `padding: 0 80px`,
   which is where the 76px step came from. Phone already agrees (crumb and grid
   both at x12), so only the desktop gutter is restated.

   The gap under the crumb comes to 16 as well -- the h1's own `margin-top: 40px`
   against the archive band's 16, and these two bands should not read differently
   when they are the same band on two surfaces.
   ============================================================================= */
body.sf-ring-archive .page_header,
body.sf-ring-archive .page_header .page_title {
    text-align: left;
}
/* `!important`, and only here. page.php prints the subhead and subtext with
   Bootstrap's `.text-center`, which is `text-align: center !important` -- no
   amount of specificity reaches past that, and MEASURED after the first cut the
   subtitle still computed `center` while the title had moved. */
body.sf-ring-archive .page_header .page_subhead,
body.sf-ring-archive .page_header .page_subtext {
    text-align: left !important;
}
/* 21, DOWN FROM 31. Owner: *"I guess the subtitle font size we should reduce to
   21px? Lmk what it is right now."* It is 31 -- `.subheading` in main.css, the
   theme's global script-face size (English1766, lowercase) -- MEASURED on
   /engagement-rings/oval-cut-engagement-rings/: `elegant, unique, feminine` at
   31px/37 under a 49px title.

   Scoped to this band rather than changed on `.subheading` itself, because that
   class is also the subhead on blog posts, resources, the 404 hero, the upsells
   slider and two product-single sections -- 21 there is a different decision
   and nobody has asked for it. Say the word and it moves to the token. */
body.sf-ring-archive .page_header .page_subhead { font-size: 21px; }
body.sf-ring-archive .page_header .page_title { margin-top: 16px; }
@media (min-width: 992px) {
    body.sf-ring-archive section.content-header > .container {
        width: 100%;
        max-width: none;
        margin: 0;
        padding: 0 80px;
    }
}

/* =============================================================================
   THE GRID AND THE LINK LIST ARE NOT THE SAME BLOCK
   -----------------------------------------------------------------------------
   Owner: *"gap between the last card and the Popular Engagement Ring Searches
   title, it's too close."*

   MEASURED: the last card ends at y11467 and the heading starts at y11467. Not
   close -- FLUSH. The list sits in its own classless <section> after the content,
   and that section has no top padding at all, so the first thing under a grid of
   73 cards is an h2 touching the bottom of the last one.

   Put on `.pagebuilder_link_list` and scoped to this archive: the block is shared
   with other page-builder pages where its spacing is whatever that page's stack
   gives it, and this is a fix for what sits ABOVE it here, not a change to the
   block. 80 at desktop against the 24 the grid gutters use, so it reads as a
   different part of the page rather than another row.
   ============================================================================= */
body.sf-ring-archive .pagebuilder_link_list { margin-top: 80px; }
@media (max-width: 991px) {
    body.sf-ring-archive .pagebuilder_link_list { margin-top: 48px; }
}

/* ...AND NEITHER IS THE FAQ BLOCK. Owner: *"in engagement rings category pages,
   needs gap between the sections of FAQ and the last product card."*

   The same fault one block over, and on the pages the link list is not on:
   MEASURED on /engagement-rings/oval-cut-engagement-rings/ at 1440, the last
   card ends at y7393 and `section.faqs_pagebuilder` starts at y7393 -- flush,
   with `margin-top: 0` and `padding-top: 0`, so `FAQs` sits on the bottom edge
   of the last ring. Given the link list's numbers rather than new ones: these
   are the two things that can follow the grid on these pages and they should
   not be spaced differently from each other. */
body.sf-ring-archive .faqs_pagebuilder { margin-top: 80px; }
@media (max-width: 991px) {
    body.sf-ring-archive .faqs_pagebuilder { margin-top: 48px; }
}

/* =============================================================================
   THE PHONE CARD, THE SAME FAULT WITHOUT A SECOND MAGIC NUMBER
   -----------------------------------------------------------------------------
   Owner: *"I still see gaps in engagement ring cards on phone screens -- they're
   long and the gap is still there between price and metal filters. Fix properly."*

   Same cause as the desktop one, which I only fixed for the rail-open state: the
   photo is square and fills the column, the card's height is a flat 410 from
   main.css's ladder, and the swatch block is `position: absolute` at bottom 45.
   MEASURED: at 390 the image is 162 and the gap under the price is 73; at 430 the
   image is 180 and the gap is 55. It tracks the viewport, so no single height
   fixes it -- a phone is any width from 320 to 991.

   So the height is RELEASED here and the text given a fixed budget instead, which
   is the thing that makes releasing it safe. Uniformity was the reason it was
   pinned: MEASURED at 390, 7 titles of 73 wrap to two lines and 59 subtitles do,
   so `height: auto` on its own leaves the two cards in a row at different heights
   and the absolutely placed swatches stop lining up across them. With both text
   boxes at their two-line maximum every card is the same height by construction,
   AND that height follows the photo at every width.

   It also comes out SHORTER, which is the other half of the complaint: 10 + 162 +
   43 + 10 + 31 + 16 + 15 + 83 = 370 against the 410 it was, with 37 of that spent
   on text boxes and 73 reclaimed from the dead band.

   76: the swatch row is 26 tall on phone against the desktop's 32 and `bottom: 45`
   is measured from the card's bottom edge, so the reserve is 45 + 26 + the gap.
   The arithmetic said 83 and the rendered gap MEASURED 19 against the 12 it
   should be, so the number is taken off the card rather than trusted -- the same
   7px of line-box rounding the desktop one needed.
   ============================================================================= */
@media (max-width: 991px) {
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link {
        height: auto;
        padding-bottom: 76px;
    }
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link .woocommerce-loop-product__title {
        min-height: 43px;    /* two lines of the 22 it draws at one */
    }
    /* the subtitle carries no class of its own -- it is the one bare <p> here */
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link > p:not([class]) {
        min-height: 31px;
    }
}

/* =============================================================================
   THE CARD CLOSES UP WHEN THE RAIL OPENS
   -----------------------------------------------------------------------------
   Owner: *"the cards get long and there's a lot of space between the price and
   the next section, which is the metal buttons -- those kinda move and shit. I
   want you to reduce that space when the filters are opened."*

   MEASURED at 1728, rail open:
     the photo is SQUARE and fills the column, so it goes 374 -> 266 when the
     rail takes its 345 + 89 out of the row;
     the card's height does NOT -- it is a flat 560 from main.css's ladder;
     the swatch row and the metal label are `position: absolute` at bottom 45
     and bottom 20, so they stay pinned to a bottom that never moved.
   Result: 12px between the price and the swatches with the rail shut, and 121
   with it open. That band is the whole complaint.

   AND THE PRICE MOVED CARD TO CARD. The subtitle is one line on 62 of the 73
   and two on the other 11, so the price sat at y758 or y776 depending on how
   long the ring's name was -- MEASURED across the first row, Asha and Mae at
   758, Anna at 776.

   So, with the rail open only: a two-line box for the subtitle (every card's
   price on one baseline) and a height that matches what is actually in the card
   -- 10 + 266 + 10 + 25 + 10 + 36 + 16 + 18 + 89, where the trailing 89 is
   the reserve the absolutely-placed swatch block already occupies (45 + 32 +
   12 of gap). The gap comes back to the 12 it is with the rail shut.

   THE HEIGHT IS STILL FIXED, and deliberately. Releasing it is what broke the
   cards the last time this was touched -- one title in 73 wraps to two lines, so
   `height: auto` makes that row taller than its neighbours and the absolutely
   placed swatches stop lining up across it. A second fixed height keeps the
   mechanism that works and only changes the number.
   ============================================================================= */
@media (min-width: 992px) {
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link,
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link.woocommerce-loop-product__link {
        /* 470, not the 480 the arithmetic gave: MEASURED after, the gap under
           the price came out 22 where the closed card's is 12. The sum was off
           by the title's own line-height rounding, which is why this is taken
           off the rendered card rather than trusted. */
        height: 470px;
    }
    /* the subtitle's own two-line box -- the <p> carries no class of its own, so
       it is addressed as the one bare paragraph in the card. */
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link > p:not([class]) {
        min-height: 36px;
    }
}

/* =============================================================================
   THE TITLE BAND -- 14684:49247 `Top Stuff`
   -----------------------------------------------------------------------------
   Owner: *"instead of making it appear wholly ... like this"*, with that frame,
   and *"add breadcrumbs to other pages too in engagement rings."*

   The board's band is 1728 x 144 on #FAF3ED with a 1px #E4DED8 edge, and inside
   it everything starts at x80 in ONE left column:

     crumb   y4,  188 x 28  -- `home  /  engagement rings`, Founders 14/30,
                               #3E3C39 at 80%, lower case
     title   y48, 421 x 31  -- Canela 42/46.2, #0F0E0D
     desc    y95, 622 x 36  -- Founders 16/16, #3E3C39 at 70%

   So the description is a 622 column UNDER the title, not the 900-wide centred
   block above it that the theme prints (MEASURED at x414). It is now printed by
   the Flow-3 header and the theme's copy is hidden -- see the note in
   da-general.php for why it is reprinted rather than moved.
   ============================================================================= */
body.sf-ring-archive .woocommerce-products-header { display: none; }

body.sf-ring-archive .sf_ring_crumbs {
    display: block;
    /* 14684:49187 ends at y32 and 14684:49190 starts at y48 -- 16 of white.
       Owner: *"too much space between breadcrumbs and title."* The 16 that was
       here was a MARGIN on top of the crumb's own 30px line box and the title's
       46.2 one, so the painted gap MEASURED 32. The leading already carries it. */
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 14px;
    line-height: 30px;
    letter-spacing: var(--sf-ls, -0.21px);
    text-transform: lowercase;
    color: rgba(62, 60, 57, 0.8);
}
/* restated on the <a>: the theme styles breadcrumb links directly, so a link
   never inherits the nav's colour -- the same trap the stone archive's crumb
   documents. */
body.sf-ring-archive .sf_ring_crumbs .sf_ring_crumb,
body.sf-ring-archive .sf_ring_crumbs a.sf_ring_crumb {
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
    text-decoration: none;
}
body.sf-ring-archive .sf_ring_crumbs a.sf_ring_crumb:hover { text-decoration: underline; }
/* the board underlines the trailing (current) segment */
body.sf-ring-archive .sf_ring_crumbs .sf_ring_crumb.is-current { text-decoration: underline; }
/* the separator is a real element here, so the gap is a margin rather than the
   hand-spaced text node the theme's own crumb needs. */
body.sf-ring-archive .sf_ring_crumbs .sf_ring_crumb_sep { margin: 0 6px; }

/* THE BAND, AND ITS EDGE. Owner: *"what about dividers and stuff?"* The frame
   is 1728 x 144 on #FAF3ED with a 1px #E4DED8 stroke -- on a full-bleed band the
   side and top edges are the page, so the one that can be seen is the bottom,
   and that is the divider between this block and the toolbar under it. Drawn on
   the header rather than on `.sf_ring_chrome`, which also holds the toolbar and
   the Ring Details bar. */
body.sf-ring-archive .sf_ring_header { padding-top: 4px; }   /* the crumb's y4 */
/* ON THE TITLE ROW, NOT THE HEADER. `.sf_ring_header` holds the toolbar as well,
   so the rule drawn there put the line UNDER the Filters pill and the sort --
   MEASURED, the header box is 221 tall where the board's band is 144. The band
   ends with the description; the divider belongs between it and the toolbar. */
body.sf-ring-archive .sf_ring_titlerow {
    position: relative;
    padding-bottom: 13px;    /* 14684:49191 ends at y131, the band at y144 */
    margin-bottom: 16px;     /* 14674:49054 pads 12 above the pill */
}
body.sf-ring-archive .sf_ring_titlerow::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 100vw;
    margin-left: -50vw;      /* full bleed out of the 1568 content column */
    border-bottom: 1px solid #E4DED8;
}

body.sf-ring-archive .sf_ring_titlecol {
    display: flex;
    flex-direction: column;
    gap: 16px;          /* 14684:49252 ends at y79, :49253 starts at y95 */
    min-width: 0;
}
/* =============================================================================
   THE PHONE BAND, AND THE HUB'S MISSING GUTTER
   -----------------------------------------------------------------------------
   Owner: *"on phone in /engagement-rings/ you can increase space between
   breadcrumbs and title, while reducing space between title and the read-more
   para -- move the title down"*, and *"the All Settings left side and Filters CTA
   right side touch the screen, there is no gap/padding on phone."*

   TWO DIFFERENT FAULTS.

   The band: at 390 the crumb's 30px line box ENDS at y138 and the title STARTS at
   y138 -- zero. Desktop gets its 16 from the title's own 46.2 leading, and an
   18/19 phone title has none to give. So the gap is stated here instead, and the
   16 under the title comes down to 8 in the same move: the owner is asking for
   the title to sit between the two, not on top of one of them.

   The gutter: MEASURED on a hub at 390, `.sf_ring_chrome` is [0, 390] -- the
   segmented starts at x0 and the Filters pill ends at 390, both flush to the
   screen. The archive's chrome is [12, 366] because it sits in a container that
   has the 12; `section.rings_product_grid_layout` does not, and the hub grid
   rules only ever addressed 992 and up.

   PLACED AFTER the rules it narrows, not with the other phone blocks: these are
   the same selectors at the same specificity, so the later one wins and the
   first cut of this sat ABOVE them and changed nothing -- MEASURED, still 0 and
   16 after the deploy.
   ============================================================================= */
@media (max-width: 991px) {
    /* 16 above the title and 6 under it -- the owner's "move the title down",
       which is a different ask from "give it room": the title belongs with the
       paragraph it introduces, not sitting between two equal gaps. */
    body.sf-ring-archive .sf_ring_crumbs { margin-bottom: 16px; }
    body.sf-ring-archive .sf_ring_titlecol { gap: 6px; }
    body.sf-ring-archive section.rings_product_grid_layout > .sf_ring_chrome {
        box-sizing: border-box;
        padding-left: 12px;
        padding-right: 12px;
    }
}

/* ...READ MORE -- 14684:49191, `...read more` underlined in #0F0E0D at the end
   of a TWO-line box. `-webkit-line-clamp` does the clamping; the control is
   placed over the tail of the second line on the band's own ground, so the
   sentence reads `...read more` the way the board draws it rather than dropping
   the link onto a third line. A left gradient keeps the covered word from
   ending hard against it. */
body.sf-ring-archive .sf_ring_desc_wrap {
    position: relative;
    max-width: 622px;
}
body.sf-ring-archive .sf_ring_desc {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
body.sf-ring-archive .sf_ring_desc_wrap.is-open .sf_ring_desc {
    display: block;
    -webkit-line-clamp: none;
    overflow: visible;
}
body.sf-ring-archive .sf_ring_readmore {
    position: absolute;
    right: 0;
    bottom: 0;
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
    padding: 0 0 0 56px;
    border: 0;
    /* a 56px run-in, not 28: at 28 the control cut a word in half and read as a
       box dropped on the sentence. The fade is what makes "...read more" look
       like the end of the copy rather than a lid on it. */
    background: linear-gradient(to right, rgba(250, 243, 237, 0) 0, #FAF3ED 52px, #FAF3ED 100%);
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: var(--sf-ls, -0.21px);
    /* NOT SMALL CAPS. Owner: *"match READ MORE to the same font size as the
       paragraph, and 'Read more' not all caps."* Both of those are one
       declaration: the control and the paragraph are both 16/18 already --
       MEASURED at 1440, font-size 16px and line-height 18px on each -- but
       `all-small-caps` draws every letter as a capital at roughly 0.8em, so it
       read as SMALLER type AND as caps at the same time. The board
       (14684:49191) does set small caps; the owner has looked at it on the page
       and asked for the sentence case the paragraph it continues is set in. */
    text-decoration: underline;
    color: #0F0E0D;
    cursor: pointer;
}
body.sf-ring-archive .sf_ring_readmore[hidden] { display: none; }
/* expanded, there is no tail to cover -- it follows the last line instead */
body.sf-ring-archive .sf_ring_desc_wrap.is-open .sf_ring_readmore {
    position: static;
    display: inline-block;
    margin-top: 4px;
    padding: 0;
    background: none;
}

body.sf-ring-archive .sf_ring_desc,
body.sf-ring-archive .sf_ring_desc p {
    margin: 0;
    max-width: 622px;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: var(--sf-ls, -0.21px);
    color: rgba(62, 60, 57, 0.7);
}
/* THE TITLE AND ITS COUNT ARE ONE LINE, at every width. The `align-self:
   flex-start` that used to be here was holding the count up against a column
   that is two elements tall; the count is no longer in that column, so baseline
   alignment does the job structurally and the override is gone with it. */
body.sf-ring-archive .sf_ring_titleline {
    display: flex;
    align-items: baseline;
    min-width: 0;
}
/* A HUB HAS NO TITLE HERE, SO IT MUST NOT PAY FOR ONE. On a child hub
   `single_term_title()` is empty and this element prints as a 0x0 `<p>` -- the
   visible heading is page.php's own `h1.page_title`. Left in the line it was
   still a flex item, so the gap beside it pushed the count off the gutter --
   MEASURED on /engagement-rings/oval-cut-engagement-rings/: count at x104
   against an h1 at x80, and x24 against x12 at 390. Taking the empty box out
   leaves the count as the line's only item, on the gutter with everything
   else. */
body.sf-ring-archive .sf_ring_titleline > .sf_ring_title:empty { display: none; }
@media (max-width: 991px) {
    /* 390 KEEPS EXACTLY WHAT IT HAD. Nothing was wrong at this width -- MEASURED
       before the move, title at x12 and the count ending at x378, the right
       gutter -- and `margin-left: auto` reproduces that from inside the line,
       which is what `space-between` on the row was doing from outside it. */
    body.sf-ring-archive .sf_ring_titleline { gap: 12px; }
    body.sf-ring-archive .sf_ring_titleline > .sf_ring_count { margin-left: auto; }
}

@media (min-width: 992px) {
    body.sf-ring-archive .sf_ring_title { font-size: 42px; line-height: 46.2px; }
}
/* the hubs print the crumb inside page.php's own header, which is centred */
body.sf-ring-archive .page_header .sf_ring_crumbs { text-align: left; }

/* =============================================================================
   THE VIEW TOGGLE SHARES THE GRID'S LEFT EDGE ON WIDE SCREENS
   -----------------------------------------------------------------------------
   Owner: *"on wide screens the list and grid view buttons are moved towards the
   very left and do not align with the diamond cards' first column -- this is
   only for wide screens."*

   The toolbar row is `display: flex; justify-content: space-between` across the
   full viewport, so the view options sit wherever the free space leaves them --
   MEASURED, `.search_view_options` carried resolved auto margins of
   `0 216.5px 0 106.9px`. The card grid, meanwhile, starts at its own column.
   The two only agree by luck, and the wider the screen the worse the luck gets:

       width   buttons   first card   gap
        1728     515        524         9
        1920     547        581        34
        2560     654        771       117

   So the row stops distributing and starts tracking the columns underneath it.
   The content column begins at 27.68% of the row's inner width at 1728 and
   27.65% at 2560 -- the same fraction, because both are Bootstrap columns of
   the same container -- so one track of 27.68% puts the view options exactly on
   the cards' left edge at every width.

   GRID, not flex: the Filters pill and Reset share the first track (they belong
   to the rail), the view options own the second, and the segmented pair the
   third. Flex cannot express that without a wrapper this markup does not have.
   `> div:empty` is hidden because the row carries a zero-width node that would
   otherwise claim a cell of its own.
   ============================================================================= */
@media (min-width: 992px) {
    #diamond_search.sf_archive .results_count.d-lg-flex {
        /* `!important` because the row carries Bootstrap's `.d-lg-flex`, which is
           `display: flex !important` at this width. Without it the grid never
           applies, every `grid-column` below is inert, and the only declaration
           that survives is the `margin: 0` -- which strips the auto margins and
           lets `space-between` pack the toggle further LEFT than it started.
           MEASURED on that attempt: 515 -> 408 at 1728, i.e. worse. */
        display: grid !important;
        /* FOUR TRACKS, NOT THREE. Owner: *"on an 18-inch screen the Reset button
           goes sideways -- it should be on the rightmost margin, aligning with
           the rightmost of the filters."*

           With one track for the whole rail, Reset was pinned to the right edge
           of a 27.68% track -- which is where the GRID starts, not where the
           filter rail ends. MEASURED, it overhung the rail by 74px at 1440, 89 at
           1728 and 99 at 1920: the wider the screen, the further it drifted,
           which is the sideways travel being reported.

           The rail's own right edge is a FIXED fraction of this row -- 22.00% at
           1440, 1728, 1920 and 2560 alike, because the rail and this row are
           columns of the same container. So track 1 is the rail (Filters left,
           Reset hard right), track 2 is the gutter between rail and grid, and the
           view options still open the content column at 27.68%. */
        grid-template-columns: 22% 5.68% 1fr auto;
        align-items: center;
        /* the row's own 24px gap shifted track 2 past the cards by a constant
           14-15px at every width -- MEASURED 538/595/786 against cards at
           524/581/771. The tracks already do the spacing. */
        column-gap: 0;
    }
    #diamond_search.sf_archive .results_count.d-lg-flex > div:empty { display: none; }
    #diamond_search.sf_archive .results_count.d-lg-flex > .sf_filters {
        grid-column: 1; grid-row: 1; justify-self: start;
    }
    #diamond_search.sf_archive .results_count.d-lg-flex > .diamond_filters_reset {
        grid-column: 1; grid-row: 1; justify-self: end;
    }
    #diamond_search.sf_archive .results_count.d-lg-flex > .search_view_options {
        grid-column: 3; grid-row: 1; justify-self: start;
        /* 10 is `.search_results_grid`'s own padding: track 2 begins at the grid
           CONTAINER's edge, and the owner is aligning to the first CARD. */
        margin: 0 0 0 10px;
    }
    #diamond_search.sf_archive .results_count.d-lg-flex > .sf_segmented {
        grid-column: 4; grid-row: 1;
    }
}

/* =============================================================================
   THE DESCRIPTION NEEDS AIR BEFORE THE TITLE
   -----------------------------------------------------------------------------
   Owner: *"can you somehow manage this by spacing this ... before the title:
   'Our engagement ring collection was designed with timeless elegance in mind'
   -- put space below this and Engagement Rings."*

   MEASURED: the description ends at y227 and ENGAGEMENT RINGS starts at y243 --
   16px, which is the stock paragraph margin and reads as the two being one
   block. 40 between them, the same step the header already uses above the
   description, so the page has one rhythm rather than two.
   ============================================================================= */
body.sf-ring-archive .woocommerce-products-header .term-description {
    /* 40, not 24. The first value here was written as "24 plus the paragraph's
       own 16" -- margins COLLAPSE: the inner <p>'s bottom margin and this one
       resolve to the larger of the two, not the sum, so 24 moved the title by 8.
       MEASURED both times. */
    margin-bottom: 40px;
}

/* =============================================================================
   THE PHONE DRAWER AND ITS TOOLBAR -- 14674:47735 / 14674:49378
   -----------------------------------------------------------------------------
   Owner: *"you kind of fucked up the mobile view ... set that up properly, like
   how it is in the stone flow."*

   WHAT ACTUALLY BROKE, and it was one thing. The sort control is hoisted onto
   the toolbar, which is right at 1728 and wrong at 390: the row is 366 wide and
   held a 267 segmented, an 89 pill and a 169 sort. MEASURED, the segmented was
   crushed to 88 and painted `ll Setting | Shortli`, and the sort hung off the
   right edge.

   14674:47735 does not put sort on that row at all -- it draws the segmented
   267 and the Filters pill 89, and nothing else. Sort lives in the DRAWER, as
   14674:49378's first group `Sorting`, 344 x 40. So stone-first.js now places
   the one control by width instead of hoisting it unconditionally, and these
   are the two homes.

     toolbar   `Frame 1171276783` 366 x 36 at x12 -- segmented 267 (halves 135
               and 131), then the pill 89 hard right.
     Sorting   344 x 40, r4, 1px #E4DED8, label 16/19 #0F0E0D at x16, a 10 x 5
               chevron 16 from the right edge.
   ============================================================================= */
@media (max-width: 991px) {
    /* THE DRAWER IS FULL SCREEN, AND HAS TO BE. 14674:49378 draws it that way,
       and with the board's tiles in it there is no longer a choice: it is
       `position: fixed; bottom: 0` with no ceiling, so once the content grew to
       the board's 80 x 96 tiles and 110 x 42 chips it MEASURED 1376 tall on an
       844 screen and the top 532 -- Sorting and the whole Shape group -- sat
       above the viewport with no way to reach it. Pinned top and bottom with
       its own scroll instead.

       The 22 inset is the board's `margins` group, so the drawer's own track is
       344 and the shared block above resolves to exactly the board's tiles. */
    body.sf-ring-archive .shop_filters.mobile_filters {
        box-sizing: border-box;
        top: 0;
        max-height: 100%;
        padding: 24px 22px 40px;
        gap: 24px;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        /* PEARL, NOT PEARL-DARK -- the stone flow's drawer is #FAF3ED and this
           is meant to be the same screen. It also mattered functionally: the
           Sorting box is stroked #E4DED8, which is exactly the ground this
           drawer shipped on, so its border was invisible. */
        background: #FAF3ED;
    }
    /* THE CLOSE STAYS REACHABLE. In a drawer that is now a full screen with
       1236px of scroll, a close button that scrolls away means scrolling back
       up to leave. The drawer is itself `position: fixed`, so the control is
       pinned to the screen rather than to the scrollport.

       NOT STICKY, and the heading is not either -- that was the first attempt
       and it put the X across the word FILTERS the moment anything scrolled:
       two sticky elements at different offsets in a flex-wrap row do not stack,
       they overlap. */
    body.sf-ring-archive .shop_filters.mobile_filters .filter_close {
        position: fixed;
        top: 24px;
        right: 22px;
        z-index: 3;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background: #FAF3ED;
    }
    body.sf-ring-archive .shop_filters.mobile_filters > h4 { margin: 0; }
    body.sf-ring-archive .shop_filters.mobile_filters > div,
    body.sf-ring-archive .shop_filters.mobile_filters > h4 { width: 100%; }

    /* SORTING IS THE FIRST GROUP -- 14674:49378 draws it directly under the
       header, above SHAPE. The partial prints it last, and the drawer is a
       flex container, so `order` moves it without moving the markup (which
       other code keys off by position). */
    body.sf-ring-archive .shop_filters.mobile_filters > .filter_close { order: -3; }
    body.sf-ring-archive .shop_filters.mobile_filters > h4 { order: -2; }
    body.sf-ring-archive .shop_filters.mobile_filters > .sort_filter {
        order: -1;
        width: 100%;
        margin: 0 0 24px;
        padding: 0;
        border: 0;
        background: none;
    }
    body.sf-ring-archive .shop_filters.mobile_filters > .sort_filter .sf_ring_sort {
        width: 100%;
        height: 40px;
        padding: 10px 16px;
    }
    body.sf-ring-archive .shop_filters.mobile_filters > .sort_filter .diamond_sort_by_options {
        top: 38px;
    }

    /* THE TOOLBAR IS TWO ITEMS, NOT THREE -- see the note above. The segmented
       takes what the pill leaves, which at 366 with the board's 10 gap is the
       267 it draws. */
    body.sf-ring-archive .sf_ring_controls > .sort_filter { display: none; }
    body.sf-ring-archive .sf_ring_filters { flex: 0 0 89px; }
}

/* Reset -- 14674:48072 `Filter` 60x44, an 18px glyph and the word, both
   #3E3C39, no fill and no stroke on the pill. Sits next to the Filters control
   and is revealed by stone-first.js only with the rail open AND something
   actually filtered. */
@media (min-width: 992px) {
    body.sf-ring-archive .sf_ring_controls .sf_ring_reset {
        order: 1;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        height: 44px;
        margin: 0 0 0 24px;
        padding: 0;
        border: 0;
        background: none;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 17px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        text-decoration: none;
        color: #3E3C39;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_reset[hidden] { display: none; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_reset_icon { display: inline-flex; width: 18px; height: 18px; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_reset_icon svg { width: 18px; height: 18px; }
}

/* =============================================================================
   THE TOOLBAR TRACKS THE TWO COLUMNS -- 14674:48958 / :48972 / :48978 / :49054
   -----------------------------------------------------------------------------
   Read off the frames in page coordinates (open board origin x45869, closed
   x44089, both 1728 wide):

     OPEN    `Filter` group   x80   344   -- the pill, then Reset at x363
             `Sorting`        x515  409   -- over the GRID, not the rail
             segmented        x1382 266   -- right edge 1648
     CLOSED  pill + sort      x80   405   -- one group, Reset absent
             segmented        x1382 266

   So the sort control MOVES when the rail opens: it sits beside the pill while
   the filters are shut and jumps to the grid's left edge when they are not.
   That falls out of giving the pill+Reset pair the rail's own 345 track and the
   same 89 gutter the body uses -- the two rows then line up by construction
   rather than by a hand-tuned margin.

   NO COLONS. The heads print `Shape:` / `Metal:` / `Style:` from
   shop-filter.php, and 14674:48442 draws the word alone. Hiding `.active_shape`
   took the value off but left the punctuation; `font-size: 0` on the <p> with
   the label restored on a child is the only way to drop a literal character
   that has no element of its own, so the text is rebuilt from the group's class
   instead -- deterministic, three groups, no guessing.
   ============================================================================= */
@media (min-width: 992px) {
    /* `justify-content: space-between` on the row (written for the two-item
       header before Reset and Sort existed) was spreading four items across
       1568 -- MEASURED, sort landed at x734 closed where the board puts it at
       x236. The row packs from the left and only the segmented pair is pushed
       right. */
    body.sf-ring-archive .sf_ring_controls { justify-content: flex-start; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filtergroup {
        order: 1;
        display: inline-flex;
        align-items: center;
        gap: 24px;
        flex: 0 0 auto;
    }
    /* the pill is printed AFTER Reset in the markup; the board has it first */
    body.sf-ring-archive .sf_ring_controls .sf_ring_filtergroup .sf_ring_filters { order: 1; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filtergroup .sf_ring_reset   { order: 2; margin: 0; }
    /* 65, not 89: the row already contributes its own 24px `gap` after this
       group, so a flat 89 put the sort at x538 where the grid starts at 514.
       Owner: *"align it with the left of the product cards."* 345 + 65 + 24 =
       434, and 80 + 434 = 514. MEASURED against the grid's own left edge. */
    body.sf-ring-archive.sf-rail-open .sf_ring_controls .sf_ring_filtergroup {
        flex: 0 0 345px;
        margin-right: 65px;
        /* RESET SITS ON THE RAIL'S RIGHT EDGE. Owner: *"reset must be on the
           right-most side, in line with the right side of the filters
           section."* The group is already the rail's own 345 track, so the
           alignment is `space-between` and not a measured margin -- the pill
           holds the left edge, Reset holds the right, and both follow the rail
           if its width ever changes. 14674:48958 agrees: it draws the pill at
           x80 and Reset at x363, i.e. hard against the 425 the rail ends on,
           which the 24px gap this shipped with was leaving 150px short of. */
        justify-content: space-between;
    }
    /* ONE auto margin, on the SORT. Both the sort and the segmented had
       `margin-left: auto` -- MEASURED, each computed 498px, which is the used
       value of `auto` after two items split the row's free space, so the sort
       drifted to x734 where the board puts it at x236. The free space belongs to
       exactly one gap: after the sort. Everything before it packs left, the
       segmented is pushed to the right edge, and both board states fall out of
       the filtergroup's own width -- 132 closed (sort at 236) and 345 + 89
       open (sort at 514, board 515). */
    /* `!important` because the rule it must beat carries one: a bare
       `.sort_filter { margin-left: auto !important }` -- written when the sort
       sat at the right end of the old horizontal strip. No amount of
       specificity reaches past an !important, which is why four selectors in a
       row computed `margin-left: 498px` (the used value of that auto). */
    /* NOT scoped to `.the-content`: a child hub prints the same toolbar inside
       `section.rings_product_grid_layout`, and keyed to the archive's wrapper
       these two left the hub's sort on the legacy `margin-left: auto`. */
    body.sf-ring-archive .sf_ring_controls > .sort_filter {
        order: 2;
        margin: 0 auto 0 0 !important;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_segmented { order: 3; margin: 0; }

}

/* ---- group heads: the word, not "Word:" --------------------------------
   Lifted out of the desktop query with the rest of the block: 14674:49378's
   heads read `SHAPE` and `METAL`, with no more punctuation than the rail's. */
body.sf-ring-archive .shop_filters .filter_heading p {
    font-size: 0;            /* drops the literal "Shape:" text node */
}
body.sf-ring-archive .shop_filters .filter_heading p::before {
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: var(--sf-ls, -0.21px);
    text-transform: uppercase;
    color: rgba(62, 60, 57, 0.8);
}
body.sf-ring-archive .shop_filters .shape_filters  .filter_heading p::before { content: "Shape"; }
body.sf-ring-archive .shop_filters .metal_filters  .filter_heading p::before { content: "Metal"; }
body.sf-ring-archive .shop_filters .subcat_filters .filter_heading p::before { content: "Style"; }



/* =============================================================================
   THE SORT CONTROL IS THE DIAMOND SEARCH'S -- 14674:48973
   -----------------------------------------------------------------------------
   Owner: *"use this fucking dropdown, not the one there"*, and then, with a shot
   of the lab search's panel standing open: *"same dropdown -- why is the
   dropdown on engagement rings pages so different?"*

   THE FIRST ANSWER WAS WRONG AND THIS REPLACES IT. I had skinned the native
   <select> to the board's closed box and left the control itself alone, on the
   reasoning that WooCommerce submits it and that a custom listbox would be a
   second implementation of sorting. That holds for the CLOSED box and fails
   completely for the open one: a <select>'s list is drawn by the operating
   system, so the panel the owner is pointing at -- cream ground, hairline rows
   -- is not reachable from CSS at all. Half the control matched and the half
   you actually interact with did not.

   So stone-first.js now builds the search's own `.diamond_sort_by` markup and
   hides the <select> inside its form, where it still carries the value and is
   still what gets submitted. This is the skin for it, MEASURED off
   /lab-grown-diamonds/ at 1728 rather than copied from the stylesheet, because
   diamond-search.css is not enqueued on this archive:

     box     265 x 44, 1px #E4DED8, r4, padding 9px 5px 9px 8px
     text    FoundersGrotesk 400 16/17.6; prefix #27423B, value #0F0E0D
     panel   top 42, #FAF3ED, 1px #E4DED8, padding 5px 10px, full width
     row     padding 10px 0, #0F0E0D, 1px #E4DED8 under all but the last

   Outside the 992 query on purpose: the control should look like itself wherever
   the toolbar carries it. Only its PLACEMENT is desktop-only, and that lives
   with the rest of the toolbar above.
   ============================================================================= */
/* NOT scoped to `.sf_ring_controls`: below 992 the same element is moved into
   the phone drawer, where the native <select> was left standing above the
   skinned box -- MEASURED, two sort controls one under the other. */
body.sf-ring-archive .sort_filter.sf_sort_skinned {
    display: block;
    height: auto;
    min-width: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}
/* the old skin printed the label and drew the box on the wrapper itself */
body.sf-ring-archive .sort_filter.sf_sort_skinned::before { content: none; }
/* KEPT, NOT REMOVED -- it is the value WooCommerce reads on submit. */
body.sf-ring-archive .sort_filter.sf_sort_skinned form.woocommerce-ordering {
    display: none;
}

body.sf-ring-archive .sf_ring_sort {
    position: relative;
    box-sizing: border-box;
    width: 265px;
    padding: 9px 5px 9px 8px;
    border: 1px solid #E4DED8;
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}
body.sf-ring-archive .sf_ring_sort > p {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 17.6px;
    letter-spacing: normal;
    color: #27423B;
}
body.sf-ring-archive .sf_ring_sort > p > .sf_sort_value {
    color: #0F0E0D;
    /* the row is 265 wide and "Price: low to high" is the longest option --
       it wraps rather than pushing the chevron out of the box. */
    flex: 1 1 auto;
    min-width: 0;
}
body.sf-ring-archive .sf_ring_sort > p > svg {
    flex: 0 0 auto;
    margin-left: auto;
}
/* NO FLIP ON OPEN. The search's chevron stays pointing down with the panel
   standing open -- MEASURED on the owner's own shot of it -- and this is a copy
   of that control, not an improvement on it. */

body.sf-ring-archive .sf_ring_sort .diamond_sort_by_options {
    position: absolute;
    top: 42px;
    left: 0;
    width: 100%;
    z-index: 3;
    box-sizing: border-box;
    padding: 5px 10px;
    border: 1px solid #E4DED8;
    background: #FAF3ED;
    display: none;
}
body.sf-ring-archive .sf_ring_sort.is-open .diamond_sort_by_options { display: block; }
body.sf-ring-archive .sf_ring_sort .diamond_sort_by_options span {
    display: block;
    width: 100%;
    padding: 10px 0;
    border-bottom: 1px solid #E4DED8;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 17.6px;
    color: #0F0E0D;
}
body.sf-ring-archive .sf_ring_sort .diamond_sort_by_options span:last-of-type { border-bottom: 0; }

/* =============================================================================
   ABOVE 1728 THE CARD HAS TO GROW WITH ITS PHOTO
   -----------------------------------------------------------------------------
   Owner: *"on engagement rings pages, bigger desktop (27 inch widescreen) --
   missing info in cards."*

   The photo is SQUARE and fills its column; the card's height is a flat 560 from
   main.css's ladder, which tops out at 1520 and never grows again. The arithmetic
   says where that breaks: 560 = 10 pad + IMG + 25 title + 10 + 18 sub + 16 + 18
   price + 89 reserve, so the photo may be 374 and no more -- which is exactly the
   column width at 1728. Every width above that overflows.

   MEASURED at 2560: column 582, so the photo runs 405..987 while the card ends at
   955. Title lands at 987, subtitle 1022, price 1056 -- all BELOW the card's own
   bottom edge -- and the swatch row, which is absolutely placed against that
   edge, sits at 878 on top of the photo. That is the missing information: it is
   not absent, it is outside the box. 1920 is already 43px over.

   So above 1728 the height follows the content, with `min-height` keeping the
   560 floor so nothing changes at the widths that already fit. The text gets a
   two-line budget for the same reason the phone card did: releasing the height
   alone makes a card with a wrapping title taller than its neighbours and the
   absolutely placed swatches stop lining up across the row.

   PLACED AFTER the `min-width: 992px` block that pins the rail-open card, not
   before it. Media queries carry no specificity of their own, so with this block
   sitting above it the later `height: 470px` won and MEASURED at 2560 with the
   rail open all 73 cards stayed 470 against a photo needing 474 -- 73 elements
   outside their card. Order is the only thing that decides between two rules of
   equal weight.
   ============================================================================= */
@media (min-width: 1729px) {
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link,
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link.woocommerce-loop-product__link {
        height: auto;
        min-height: 560px;
        /* the swatch row and its label are `position: absolute` at bottom 45 and
           bottom 20; with the height released there is nothing holding that space
           open, so it is reserved here -- 45 + 32 + 12 of gap. */
        padding-bottom: 89px;
    }
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link .woocommerce-loop-product__title {
        min-height: 50px;   /* two lines of the 25 it draws at one */
    }
    body.sf-ring-archive ul.products > li.product a.woocommerce-LoopProduct-link > p:not([class]) {
        min-height: 36px;
    }
    /* THE RAIL-OPEN CARD IS 470 AND ITS HEIGHT IS SET, NOT A FLOOR. The block
       below pins `height: 470px` for that state, and a `height` beats a
       `min-height` -- MEASURED at 2560 with the rail open, all 73 cards stayed
       470 while the photo needed 474, so the price, the swatches and the metal
       label all fell outside the box: 73 overflowing elements. Released here
       the same way the closed card is, with 470 as the floor. */
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link,
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link.woocommerce-loop-product__link {
        height: auto;
        min-height: 470px;
    }
}

/* =============================================================================
   THE CARD IS LEFT AS IT SHIPPED
   -----------------------------------------------------------------------------
   Owner: *"product cards, they're of different shapes, all together ... on hover
   what is going on ... get them back to what they were initially."*

   Both of those were mine. I had taken 14674:48074's 264x401 literally and
   (a) given `.looped_slider` the board's 264/239 ratio and (b) released the
   `height` ladder on `a.woocommerce-LoopProduct-link`, then (c) rebuilt the text
   block as a flex column when the absolutely-positioned swatch rows collapsed
   onto the price.

   (b) is what broke it. That fixed height is what made every card in a row the
   SAME height regardless of how many lines its name took -- releasing it let
   each card size to its own content, which is the "different shapes". And the
   hover state (the `.secondary_overlay` image swap) is positioned against that
   same box, so it had nothing stable to sit in.

   All three are reverted. The card goes back to the ladder it shipped with,
   which is a real regression against the board's 401 and is the right trade:
   a uniform grid that hovers correctly beats a card whose height matches a frame
   but whose row is ragged. Re-deriving 401 properly means giving the TEXT block
   a fixed budget the way the settings-picker card does (a 340 box with
   `margin-top: auto` on the swatch row), not removing the height -- that is the
   next attempt, not this one.
   ============================================================================= */

/* The pill's count badge -- 14674:48958 `Filters 3`: 24x24, r50, #D8DDCA with
   the number in #27423B at 14/19. Same shape as the stone search's. */
@media (min-width: 992px) {
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_ring_badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 24px;
        width: 24px;
        height: 24px;
        /* 4, AND THE NOTE THIS REPLACES HAD THE WRONG PARENT.
           Owner, with a screenshot of this pill: *"there's no space in the
           Filters CTA between the Filters text and the round number beside it."*

           The note here read "no margin: the pill's own `gap: 4` is the board's
           4" -- true of the PILL, and the badge is not its child. It sits inside
           `.sf_filters_group`, whose gap is 2 (the icon-to-label number), so the
           board's 4 never reached it: MEASURED at 1440, label right 157, badge
           left 159. The pill came out 115 against 14674:49057's 116, which is
           the missing space showing up in the width as well.

           4 would restore the board exactly. 6 is used instead, because that is
           what the PHONE pill already renders -- the arithmetic written into
           the max-width block below is `8 + 11 icon + 6 + label + 6 + 20 badge
           + 8` -- and the owner has accepted that one. One number across both
           widths beats a 2px fidelity win on one of them; the cost is a pill
           ~4px wider than the board's 116.

           ...AND 6 IS ALSO WHAT THE DIAMOND PILLS RENDER. The owner asked for 8
           first and then for *"just make it like what it was on diamond
           category and diamond search"* -- the later instruction wins, and it
           turns out to want the same number this already had: MEASURED on
           /lab-grown-diamonds/ with a filter applied, icon->label 2 and
           label->badge 6 at 1440, which is this pill exactly. Left at 6.
           The declared value here is the REMAINDER over the group's own 2, not
           the gap -- the thing to read twice before changing it. */
        margin-left: 4px;
        border-radius: 50%;
        background: #D8DDCA;
    }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_ring_badge.is-empty { display: none; }
    body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_ring_badge_count {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 14px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #27423B;
    }
}

/* =============================================================================
   THE CHILD HUBS GET THE SAME RAIL -- /engagement-rings/<shape>-engagement-rings/
   and the nested /engagement-rings/side-stones/<...>/
   -----------------------------------------------------------------------------
   Owner: *"all pages with engagement-rings, like child hubs, must have filters
   but hidden ... on click of, say, Cushion it should take you to
   /engagement-rings/cushion-cut-engagement-rings/ with the MODIFIED page."*

   So the filter row keeps its SEO destinations and the DESTINATION gets the new
   chrome -- the opposite of my first answer, which was to point the filters at
   query strings instead.

   These hubs are page-builder pages, not the archive, and their DOM differs:
   `section.rings_product_grid_layout` holds TWO sibling `.container` blocks --
   one printed by the filters partial, one by the grid. That is convenient: the
   section becomes the row and the two containers are its columns, so nothing
   has to move. (On the archive the same job is done on `.the-content`, whose
   children are the chrome, `.shop_filters` and `ul.products` directly.)

   Addressed with `:has()` rather than `:nth-child`, because the filters
   container is conditional (`display_filters`) -- a positional rule would make
   the grid the rail on any hub that prints no filters.
   ============================================================================= */
@media (min-width: 992px) {
    body.sf-ring-archive section.rings_product_grid_layout {
        display: grid;
        grid-template-columns: 0 1fr;
        column-gap: 0;
        align-items: start;
        /* the hub's twin of the archive rule above -- same cause, same fix;
           the reasoning is written out once there. */
        grid-auto-flow: row dense;
        transition: grid-template-columns 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    column-gap 320ms cubic-bezier(0.22, 1, 0.36, 1);
    }
    body.sf-ring-archive.sf-rail-open section.rings_product_grid_layout {
        grid-template-columns: 345px 1fr;
        column-gap: 89px;
    }
    /* everything spans unless it is one of the two columns */
    body.sf-ring-archive section.rings_product_grid_layout > * { grid-column: 1 / -1; min-width: 0; }
    body.sf-ring-archive section.rings_product_grid_layout > .container:has(.shop_filters) { grid-column: 1; }
    body.sf-ring-archive section.rings_product_grid_layout > .container:has(ul.products)   { grid-column: 2; }
    /* the hubs' containers carry the page gutter; the section owns it now */
    body.sf-ring-archive section.rings_product_grid_layout > .container { max-width: none; width: 100%; padding: 0; }
    body.sf-ring-archive section.rings_product_grid_layout > .container > .row { margin: 0; }
    body.sf-ring-archive section.rings_product_grid_layout > .container > .row > .col { padding: 0; }
    body.sf-ring-archive section.rings_product_grid_layout { padding-left: 80px; padding-right: 80px; }

    /* the rail itself -- same skin and same slide as the archive's */
    body.sf-ring-archive section.rings_product_grid_layout .shop_filters:not(.mobile_filters) {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 24px;
        box-sizing: border-box;
        width: 345px;
        margin: 0;
        padding: 0;
        overflow: hidden;
        transform: translateX(-24px);
        opacity: 0;
        visibility: hidden;
        transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1),
                    visibility 0s linear 320ms;
    }
    body.sf-ring-archive.sf-rail-open section.rings_product_grid_layout .shop_filters:not(.mobile_filters) {
        transform: none;
        opacity: 1;
        visibility: visible;
        transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1),
                    visibility 0s;
    }
    body.sf-ring-archive section.rings_product_grid_layout ul.products {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 24px;
        margin: 0;
        padding: 0;
        list-style: none;
    }
    body.sf-ring-archive section.rings_product_grid_layout ul.products::before,
    body.sf-ring-archive section.rings_product_grid_layout ul.products::after { content: none; display: none; }
    body.sf-ring-archive section.rings_product_grid_layout ul.products > li.product { width: auto; max-width: none; margin: 0; float: none; }

    @media (prefers-reduced-motion: reduce) {
        body.sf-ring-archive section.rings_product_grid_layout,
        body.sf-ring-archive section.rings_product_grid_layout .shop_filters:not(.mobile_filters) { transition: none; }
    }
}

/* The control skin above is addressed on `.shop_filters:not(.mobile_filters)`
   rather than on the archive's `.the-content >` path, because the child hubs put
   the same partial inside `section.rings_product_grid_layout` instead -- MEASURED
   on /engagement-rings/cushion-cut-engagement-rings/, the rail opened correctly
   and came back carrying the LEGACY glyph row, because every skin rule was
   keyed to a container that page does not have. `body.sf-ring-archive` already
   bounds it to these pages, and `:not(.mobile_filters)` keeps the phone sheet
   out. */

/* =============================================================================
   WITH THE RAIL OPEN, A SMALL LAPTOP GOT FOUR CARDS IT HAD NO ROOM FOR
   -----------------------------------------------------------------------------
   Owner: *"13 inch screen ... with filters, cards need work on smaller laptops
   on engagement ring category pages."*

   THE COLUMN COUNT WAS A CONSTANT. `repeat(4, minmax(0, 1fr))` is 14674:48072's
   count, and that board is 1728 wide: four 264 cards on a 290 pitch in the 1134
   the rail leaves. The rail costs the same 345 + 89 at every width, so the track
   it leaves shrinks with the viewport while the divisor did not --

     1728   track 1134   ->  266 per card   (the board)
     1440   track  846   ->  194
     1280   track  686   ->  154

   MEASURED at 1280 with the rail open: cards 154 x 470. A 154 photo in a 470
   box leaves ~150px of empty card under the price, every subtitle wraps to
   three lines, and the row reads as four slivers. The card is 262 wide on that
   same screen with the rail SHUT -- so opening the filters was costing 40% of
   the card.

   `auto-fill` with a floor makes the count follow the track instead. 220 is not
   a new number: it is the floor the stone grid in this same file already uses
   (`repeat(auto-fill, minmax(220px, 1fr))`). What it gives, with the 24 gap:

     1280   track  686   ->  2 x 331
     1366   track  772   ->  3 x 241
     1440   track  846   ->  3 x 266     <- the board's own card width
     1600   track 1006   ->  4 x 238
     1727   track 1133   ->  4 x 266

   Held to 1728 so the board's own width keeps the board's own grid, and so the
   >=1729 block above -- which releases the height for wide screens -- is not
   touched by any of this.

   AND THE HEIGHT HAD TO FOLLOW THE PHOTO. 470 is tuned for a 266 photo (see the
   block that sets it: 10 + 266 + 10 + 25 + 10 + 36 + 16 + 18 + 89). It is a
   `height`, not a floor, so a narrower card caverns under the price and a wider
   one overflows -- at 331 the card needs 517 and would have put the price, the
   swatches and the metal label outside the box, which is exactly the fault the
   >=1729 block was written to fix. Released the same way here, with no floor at
   all: below 1728 the card is whatever its own photo plus 186 of text comes to.

   The two-line budgets come with it for the same reason they do up there -- with
   the height released, one card whose subtitle wraps would otherwise be taller
   than its neighbours and the absolutely-placed swatch rows would stop lining up
   across the row.

   LAST IN THE FILE ON PURPOSE. Media queries carry no specificity, so this has
   to sit below BOTH the `min-width: 992px` block that pins `height: 470px` and
   the `section.rings_product_grid_layout` grid that the hubs use -- same
   selectors, same weight, source order decides.
   ============================================================================= */
@media (min-width: 992px) and (max-width: 1728px) {
    body.sf-ring-archive.sf-rail-open .the-content > ul.products,
    body.sf-ring-archive.sf-rail-open section.rings_product_grid_layout ul.products {
        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    }
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link,
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link.woocommerce-loop-product__link {
        height: auto;
        min-height: 0;
        /* the swatch row and its label are `position: absolute` at bottom 45 and
           bottom 20; with the height released nothing holds that space open, so
           it is reserved -- 45 + 32 + 12 of gap, the same 89 the wide block
           reserves. */
        padding-bottom: 89px;
    }
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link .woocommerce-loop-product__title {
        min-height: 50px;   /* two lines of the 25 it draws at one */
    }
    body.sf-ring-archive.sf-rail-open ul.products > li.product a.woocommerce-LoopProduct-link > p:not([class]) {
        min-height: 36px;
    }
}

/* =============================================================================
   THE ARCHIVE'S RING DETAILS BAR HAD NO DESKTOP AT ALL
   -----------------------------------------------------------------------------
   Owner: *"the whole Ring Details in the stone flow ... looks different
   compared to the BYR one. Can you adjust the ones on the stone flow
   accordingly."*

   Three surfaces print this component under three class vocabularies -- the
   drawer and the modified PDP share `.sf_picker_details` (settings-picker.css),
   the builder has `.rb_details_bar`, and THIS one, the bar that rides the
   engagement-ring archive while a stone is held, is `.sf_ring_details`. Its
   entire treatment lives in a `max-width: 991px` block, so above that it fell
   back to the user agent.

   MEASURED at 1728 with a stone held and the bar expanded:

     .sf_rd_head   222 x 24   background rgb(239,239,239), padding 1px 6px
                              -- a raw <button>, browser grey, with `Ring Details
                              Current Est. $730` crammed into 222px
     .sf_rd_media  638 wide   the stone photo at full width down the page
     .sf_rd_label  400 16/17.6 #0F0E0D   against the builder's 500 18/19 #3E3C39
     .sf_ring_details  no ground, no radius, no padding

   This gives it the same desktop step the other two now take: the opaque
   #EDE6E0 ground (see the note in settings-picker.css for why that colour and
   not the 60% it resolves from), 16/18/13, the label at 500 18/19 and
   `Current Est.` at 400 18/19, a 12 x 6 chevron, and the head's bottom padding
   released when open so the space under it is spent once.

   NO THUMBNAIL at this width, which is the other two's answer as well:
   14514:40401 carries `visible: false` in the file, and the slot has no size of
   its own up here -- it took the grid column the phone block gives it and drew
   the stone 638 wide. The phone bar keeps its 95 x 94 tile exactly as it is.
   ============================================================================= */
@media (min-width: 992px) {
    body.sf-ring-archive .sf_ring_details {
        margin: 8px 0 16px 0;
        border-radius: 4px;
        background: #EDE6E0;
    }
    body.sf-ring-archive .sf_rd_head {
        display: flex;
        align-items: center;
        gap: 6px;
        width: 100%;
        margin: 0;
        padding: 16px 18px 13px;
        border: 0;
        border-radius: 4px 4px 0 0;
        background: transparent;
        font-family: 'FoundersGrotesk', sans-serif;
        text-align: left;
        cursor: pointer;
    }
    /* open, the head stops padding its own bottom -- the body carries the gap */
    body.sf-ring-archive .sf_rd_head[aria-expanded="true"] { padding-bottom: 0; }

    body.sf-ring-archive .sf_rd_chev {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 12px;
        height: 6px;
        color: #3E3C39;
        transition: transform 200ms ease;
    }
    body.sf-ring-archive .sf_rd_chev svg { display: block; width: 12px; height: 6px; }
    body.sf-ring-archive .sf_rd_head[aria-expanded="true"] .sf_rd_chev { transform: rotate(180deg); }

    body.sf-ring-archive .sf_rd_label {
        font-weight: 400;   /* Ring Details is Regular -- no Medium face is loaded */
        font-size: 18px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #3E3C39;
    }
    body.sf-ring-archive .sf_rd_est {
        margin-left: auto;
        font-weight: 400;
        font-size: 18px;
        line-height: 19px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #3E3C39;
    }
    /* the figure is a <span> inside the label span and must not read heavier --
       the owner's *"in the Ring Details bar, Current Est. $1,900, remove the
       bold"* is the same note the builder's bar carries. */
    body.sf-ring-archive .sf_rd_est_value { font-weight: 400; }

    body.sf-ring-archive .sf_rd_body {
        display: block;
        padding: 12px 18px 13px;
    }
    body.sf-ring-archive .sf_rd_media { display: none; }
    body.sf-ring-archive .sf_rd_row {
        display: grid;
        grid-template-columns: 72px 1fr auto;
        align-items: baseline;
        gap: 6px;
        padding: 4px 0;
        font-size: 16px;
        line-height: 17.6px;
        letter-spacing: var(--sf-ls, -0.21px);
    }
    body.sf-ring-archive .sf_rd_key { color: #0F0E0D; }
    body.sf-ring-archive .sf_rd_val { color: #3E3C39; }
    body.sf-ring-archive .sf_rd_amt { color: #0F0E0D; text-align: right; }
    body.sf-ring-archive .sf_rd_foot {
        margin: 8px 0 0 0;
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 12px;
        line-height: 19px;
        color: #3E3C39;
        text-align: center;
    }
}

/* =============================================================================
   THE PHONE FILTERS PILL SHOWS ITS COUNT, AND A TAP SHOWS ITSELF
   -----------------------------------------------------------------------------
   Owner: *"on phone, the number of filters applied is not visible on the filter
   button"*, and *"add on-tap state change to filter buttons on mobile, loading
   animation might be needed as well."*

   THE BADGE WAS THERE AND HAD THE RIGHT NUMBER. da-general.php prints
   `.sf_ring_badge` and stone-first.js fills it; what it had no styling for was
   this width -- the whole badge block is written inside `min-width: 992px`.
   MEASURED at 390 on /engagement-rings/ with a shape and a metal applied: the
   badge read "2" and drew as a 7 x 19 bare text node, transparent, at x359
   inside a pill that ends at 378. The number was on the page and invisible.

   20 x 20 rather than the desktop 24, on the same #D8DDCA with the same #27423B
   figure -- this pill is 36 tall where the desktop one is 44.

   AND THE PILL HAS TO BE ALLOWED TO GROW. It was `flex: 0 0 89px`, so a count
   had nowhere to go: 8 + 11 icon + 6 + label + 6 + 20 badge + 8 comes to ~97.
   `0 0 auto` with the 89 floor it already declares lets it take what it needs;
   the segmented beside it is `flex: 1 1 auto` and gives up the difference.

   EMPTY MEANS OUT OF THE ROW, the same lesson the drawer's pill records: a
   zero-width flex item still draws the row's gap beside it, so the icon and
   label sat off-centre whenever nothing was filtered.
   ============================================================================= */
@media (max-width: 991px) {
    body.sf-ring-archive .sf_ring_filters {
        position: relative;
        flex: 0 0 auto;
    }
    body.sf-ring-archive .sf_ring_filters .sf_ring_badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 20px;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: #D8DDCA;
    }
    body.sf-ring-archive .sf_ring_filters .sf_ring_badge_count {
        font-family: 'FoundersGrotesk', sans-serif;
        font-size: 12px;
        line-height: 20px;
        letter-spacing: var(--sf-ls, -0.21px);
        color: #27423B;
    }
    body.sf-ring-archive .sf_ring_filters .sf_ring_badge.is-empty {
        position: absolute;
        left: 0;
        top: 0;
        width: 0;
        height: 0;
        margin: 0;
        visibility: hidden;
    }

    /* ---- the tap, and the wait ---------------------------------------------
       Every control in this sheet is a LINK -- a shape is a URL parameter, a
       style is a sub-category path -- so a tap is a navigation and nothing
       changed on screen until the next page painted. stone-first.js now marks
       the tapped tile `.active` on the spot and puts the sheet in
       `.is-applying`; these are the two states that makes visible.

       The press itself gets `:active` as well, so the tile answers under the
       thumb even before the handler runs -- that is the part a slow connection
       cannot delay. */
    body.sf-ring-archive .shop_filters.mobile_filters .filter_row > a,
    body.sf-ring-archive .shop_filters.mobile_filters .filter_row > p > a {
        transition: background-color 120ms ease-out, box-shadow 120ms ease-out,
                    transform 120ms ease-out;
        -webkit-tap-highlight-color: transparent;
    }
    body.sf-ring-archive .shop_filters.mobile_filters .filter_row > a:active,
    body.sf-ring-archive .shop_filters.mobile_filters .filter_row > p > a:active {
        transform: scale(0.97);
        background: rgba(194, 206, 178, 0.30);
    }
    /* the sheet is waiting on a page it has already asked for */
    body.sf-ring-archive .shop_filters.mobile_filters .filter_row {
        transition: opacity 180ms ease-out, filter 180ms ease-out;
    }
    body.sf-ring-archive .shop_filters.mobile_filters.is-applying .filter_row {
        opacity: .4;
        filter: blur(1px);
        pointer-events: none;
    }
    /* ...except the one just chosen, which is the thing worth looking at */
    body.sf-ring-archive .shop_filters.mobile_filters.is-applying .filter_row > a.active,
    body.sf-ring-archive .shop_filters.mobile_filters.is-applying .filter_row > p > a.active {
        opacity: 1;
        filter: none;
    }
    @media (prefers-reduced-motion: reduce) {
        body.sf-ring-archive .shop_filters.mobile_filters .filter_row,
        body.sf-ring-archive .shop_filters.mobile_filters .filter_row > a,
        body.sf-ring-archive .shop_filters.mobile_filters .filter_row > p > a { transition: none; }
        body.sf-ring-archive .shop_filters.mobile_filters .filter_row > a:active,
        body.sf-ring-archive .shop_filters.mobile_filters .filter_row > p > a:active { transform: none; }
    }
}

/* =============================================================================
   THE EXPANDED EXPLAINER READS AT 14, LIKE THE ROWS IT SITS UNDER
   -----------------------------------------------------------------------------
   Owner, about the expanding sections on the back-to-stone slide: *"match the
   font size of the paragraph (I think from 16px to 14px)."*

   MEASURED on the in-flow stone PDP with every row open: the explainer bodies
   (Carat Weight, Cut, Color, Certificate) at 16/17.6, while the Details &
   Dimensions rows directly beneath them -- `.rb_dd_row`, the same accordion --
   are 14/22. Two sizes inside one panel, and the smaller one is the data.
   17.6 is also a 1.1 ratio, which is a HEADING's leading on a paragraph; 22
   is what the rows already use and what the owner is matching to.

   The `.rb_dd_row` children are excluded so the spec rows keep their own
   measurements rather than being re-stated here.
   ============================================================================= */
body.sf-stone-pdp .diamond_atts_accordion .accordion-text,
body.sf-stone-pdp .diamond_atts_accordion .accordion-text > p:not(.rb_dd_row) {
    font-size: 14px;
    line-height: 22px;
}
/* THE STONE PDP SHOWS ONE PHOTO, NOT A STACK.
   Owner, on a diamond PDP: *"the on-hover enlarge is working like this, wtf is
   going on"* -- the magnified photo appearing to spill out of its frame with a
   second, part-cut diamond under it.

   The zoom is innocent. MEASURED with real pointer input at 1920 (synthetic
   events do not drive this plugin, which is why earlier passes saw nothing):
   `.zm-viewer` renders at [252,197,935,734] against an image at
   [252,197,935,734] -- exactly over it, correctly sized and placed.

   What is wrong is underneath. The gallery holds TWO slides:

     slide 0   [252,197,935,734]   still.jpg
     slide 1   [252,942,935,981]   no <img> -- the 360 spin embed

   so the wrap measures 1726px tall for a 734px photo with `overflow: visible`,
   and slide 1 hangs below the frame. The plugin's own sheet means to prevent
   exactly this (`.iconic-woothumbs-images__slide { display: none }` with the
   first re-shown), and that rule IS loaded here -- it is simply being outranked,
   so the second slide falls back to a div's default `block`.

   Restored by position rather than by `:not(:first-of-type)`: the slides are not
   reliably typed siblings, and `:first-of-type` is what the plugin's own rule
   leans on. `:nth-child(n+2)` says "every slide after the first" with no such
   assumption. Scoped to the stone PDP at desktop -- the phone block above sizes
   this gallery separately, and no other surface is touched. */
@media (min-width: 992px) {
    body.sf-stone-pdp .iconic-woothumbs-images > .iconic-woothumbs-images__slide:nth-child(n+2) {
        display: none;
    }
}

/* NO COUNT ON THE ARCHIVE'S FILTERS PILL.
   Owner: *"on ER category pages -- filters, I guess we don't need numbers here
   on the CTA. Since it's only 3 things and 1 is always selected. You can remove
   that filter number and adjust the CTA width accordingly."* Right on the
   arithmetic: this rail offers SHAPE, METAL and STYLE, and STYLE always has a
   term chosen (`All Rings` is the parent), so the badge spends a 20-24px disc
   to tell the shopper a number they can read off the rail itself.

   The width needs no second change. Both pill rules size it from its content --
   `display: inline-flex` with `padding: 0 12px` and `gap: 4px`, the width
   deliberately "left to the content now rather than pinned" (:6887) -- and a
   `display: none` flex item contributes neither its box nor a gap, so the pill
   closes up by exactly the disc plus one gap on its own.

   `!important` because there are two competing declarations in two different
   media blocks (:8190 at >=992 and :8563 for the phone), both at a higher
   specificity than a single added rule, and hiding it is unconditional. Scoped
   to `body.sf-ring-archive`, so the stone search's and the setting drawer's own
   badges -- where the filter count is not deducible from the rail -- keep
   theirs. */
body.sf-ring-archive .sf_ring_filters .sf_ring_badge,
body.sf-ring-archive .sf_ring_controls .sf_ring_filters .sf_ring_badge {
    display: none !important;
}
