/* ===========================================================================
   3.3 ENGAGEMENT RINGS -- the setting picker, as a drawer over the flow.
   Figma [Flow 3] Stone First, 14514:39115 (loaded) / 39301 (loading) /
   39488 (one card selected).

   Measurements are the board's, at its 390 frame: Ring-details bar 366x40 at
   x12, header block 390x77 with 12px gutters, title row 366x19, tab row 366x36
   with the segmented control 267x36 and the Filters pill 89x36, grid rows of
   two 177-wide cards with a 12 gutter and 12 between, card 177x340.

   The sheet is the whole viewport on a phone, which is what the board draws --
   3.3 has no site header behind it. Above 992 it becomes a centred panel rather
   than inventing a desktop layout the board does not contain.
   =========================================================================== */

#sf_settings_picker[hidden] { display: none !important; }

#sf_settings_picker {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: block;
}

.sf_picker_scrim {
    position: absolute;
    inset: 0;
    background: rgba(15, 14, 13, 0.35);
    opacity: 0;
    transition: opacity 240ms ease;
}
#sf_settings_picker.is-open .sf_picker_scrim { opacity: 1; }

.sf_picker_sheet {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    background: #FAF3ED;            /* board root fill */
    transform: translateY(100%);
    transition: transform 320ms cubic-bezier(.22,.61,.36,1);
    will-change: transform;
}
#sf_settings_picker.is-open .sf_picker_sheet { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
    .sf_picker_sheet, .sf_picker_scrim { transition: none; }
}

/* ---- the flow's own chrome: ONE CONTROL ---------------------------------
   The 128px BUILD YOUR RING band that used to sit here is gone -- 14514:39115
   / :39301 / :39488 draw no such band, their header stack (3.3.1) is 390x135
   and starts with the Ring-details bar at +8. The full reasoning is on the
   markup in da-settings-picker.php.

   3.3 is a DRAWER, so it needs a dismiss the board has no node for. That is
   H.9's own close, at H.9's own numbers -- 28x28, #FAF3ED, r4, a 6x6 cross
   stroked 1px #3E3C39 -- printed at the end of the advanced-header's title row.
   It is the ONE element on this screen without a frame behind it, and it costs
   the board one position: 3.3.6's count moves from x321 to x285 at 390 to make
   room for it on the same line.
   ----------------------------------------------------------------------- */
.sf_picker_close {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    align-self: center;
    /* The row is 19 tall (3.3.5's line box) and this box is 28. Negative
       block margins keep the row at 19 so the header stack still measures the
       board's 135, and `margin-left: 8` puts the count back where 3.3.6 draws
       it: count 285..342, close 350..378, right edge 378 -- the board has the
       count alone at 321..378. */
    margin: -4.5px 0 -4.5px 8px;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: #FAF3ED;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.sf_picker_close svg { display: block; }

/* ---- chrome: details bar + header, both pinned ------------------------- */
.sf_picker_chrome {
    position: relative;
    flex: 0 0 auto;
    background: #FAF3ED;
    /* PULLED IN BY THE SCROLLBAR'S WIDTH, so this band and the grid below it
       end on the same line. `.sf_picker_body` is the scroll container, so its
       content box is the sheet minus the scrollbar while this one's is the
       whole sheet -- and both are inset by the same `4.6296296296%`, which
       percentage-resolves against the SHEET for both boxes. The result was a
       right edge ~17px apart (MEASURED on the owner's capture: segmented
       control ends 1934, last card column 1916) while the left edges agreed,
       which is exactly how it read on screen. `--sf-sbw` is measured off the
       live body by settings-picker.js `syncGutter()`; 0 until it runs, and
       genuinely 0 wherever the host draws overlay scrollbars (phones, and
       headless Chromium -- which is why no probe could see this). The sheet
       behind the freed strip is the same #FAF3ED, so only the scrollbar
       appears in it. */
    margin-right: var(--sf-sbw, 0px);
    /* Board `Frame 1171276786` (3.3.1) padding-top 8 -- and the sheet now
       starts here, with the BYR band removed, so this 8 is the first thing on
       the screen exactly as the board has it. */
    padding-top: 8px;
}

/* Ring-details bar -- 366x40 @x12, #E4DED8 at 60%, r4, padding 10/9 */
.sf_picker_details {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: calc(100% - 24px);
    margin: 0 12px;
    min-height: 40px;
    box-sizing: border-box;
    padding: 10px 9px;
    border-radius: 4px;
    background: rgba(228, 222, 216, 0.6);
    /* THE WHOLE BAR TOGGLES, so the whole bar has to read as tappable -- owner:
       *"tapping ANYWHERE on it must expand and collapse."* settings-picker.js
       forwards a click anywhere on this row to the chevron button inside it;
       without this the `Current Est.` half still showed an arrow cursor and
       looked inert. Both widths, like the behaviour. */
    cursor: pointer;
}
.sf_picker_details_toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 0;
    background: none;
    padding: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    /* Board `Title`: 14/19 in #3E3C39. Both the 16px leading and the #0F0E0D ink
       that were here belong to the FIGURE on the right, not to this label. */
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #3E3C39;
}
.sf_picker_details_label { color: #3E3C39; }
.sf_picker_chevron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 10px; height: 5px;
}
.sf_picker_chevron svg { display: block; }
/* ---- THE CLOSE IS THE BAR'S LAST ITEM --------------------------------------
   The bar was two items under `space-between`; a third would have pushed
   `Current Est.` to the centre of the row. `margin-left: auto` on the estimate
   reproduces the old two-item result exactly and leaves the close to trail it,
   so the bar reads the same with or without the button -- which matters,
   because the in-flow setting page prints it WITHOUT.

   Transparent, not the board's #FAF3ED chip: H.9 draws that close on a plain
   ground, and a pearl square on this bar's rgba(228,222,216,.6) reads as a
   second control rather than as the bar's own glyph. 28x28 for the hit area,
   held to the row's 19 by the base rule's negative block margins.
   -------------------------------------------------------------------------- */
.sf_picker_details .sf_picker_close {
    background: none;
    color: #3E3C39;
    margin: -4.5px 0 -4.5px 10px;
}
.sf_picker_details .sf_picker_close:hover,
.sf_picker_details .sf_picker_close:focus-visible { color: #0F0E0D; }
.sf_picker_details { justify-content: flex-start; }
.sf_picker_est {
    margin-left: auto;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #3E3C39;
}
/* REGULAR, NOT MEDIUM. This asked for 'FoundersGroteskMedium' so the figure
   would read heavier than its label. The Medium cut is NOT LICENSED -- owner:
   "I forgot we haven't bought it yet, better to not use it" -- so it is dropped
   here and the weight pinned to 400 as well: this is a <strong>, and leaving the
   weight alone would hand it the UA's bold, which Chrome synthesises from the
   Regular file and double-strikes. The figure is distinguished by colour
   (#0F0E0D against the label's #3E3C39), which needs no second file. */
.sf_picker_est strong {
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    color: #0F0E0D;
}

/* ---- header: title row + tabs ----------------------------------------- */
/* Board `advanced-header` 14514:39121 opens 10 under the Ring-details bar
   (bar bottom 94 -> header top 104) and puts ENGAGEMENT RINGS 6 lower still
   (110). MEASURED with a flat 14/0: the title sat at chrome-relative 62 and
   the tab row at 87, against the board's 64 and 89 -- the whole header stack
   two px high, and the 10/6 split is what the board actually authors. */
.sf_picker_head {
    padding: 6px 12px 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 10px;
}
.sf_picker_titlerow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;      /* board: count right-aligned, same line */
    gap: 10px;
}
.sf_picker_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;
}
.sf_picker_count {
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 16px;
    letter-spacing: -0.21px;
    color: #3E3C39;
    white-space: nowrap;
    /* 3.3.6 is right-aligned on the title's own line (row `14514:39138` is
       SPACE_BETWEEN with two children). The row now has three, so the count is
       pushed right explicitly and the close follows it, rather than being
       spread to the middle of the row. */
    margin-left: auto;
}

.sf_picker_tabs { display: flex; gap: 10px; }

/* segmented 267x36, r10, 0.75px inside #27423B.

   FLUID BELOW 390, which is where the board is drawn. Owner: *"the Filters
   button is still cutting off on the right side in the engagement rings drawer
   in the stone flow."* MEASURED, and it is: the row's children sat at FIXED
   positions whatever the viewport -- the track pinned to 267 at x12 and the
   Filters pill to 89 at x289, so its right edge was 378 at every width.

     375  ->  3px past the viewport
     360  ->  18px past it
     390  ->  fits, which is why it only ever looked right on the artboard

   The pill is the one that must not shrink -- it is a 89x36 tap target with a
   label in it -- so the TRACK gives way instead: `flex: 1 1 auto` with a 267
   basis keeps the designed width wherever there is room (390 and up: 12 + 267 +
   10 + 89 + 12 = 390 exactly) and lets it narrow below that. `min-width: 0`
   because a flex item will not shrink past its content otherwise, and the two
   halves carry real labels. */
.sf_picker_seg {
    display: flex;
    flex: 1 1 267px;
    min-width: 0;
    width: 267px;
    max-width: 267px;
    height: 36px;
    border-radius: 10px;
    box-shadow: inset 0 0 0 0.75px #27423B;
    overflow: hidden;
}
/* 3.3.9 / 3.3.10 -- BOTH labels are FG 400 `14/18` with `letterSpacing -0.5`,
   not the -0.21 the rest of this screen uses. That -0.5 is one of only two
   exceptions on the whole section (ELEMENTS 1.2: "the two segmented-tab labels
   3.1.15/3.1.17, 3.3.8/3.3.10 and the status clock"), so it is a deliberate
   tracking on the segmented control specifically and it has to be spelled out
   here or the file's own -0.21 default wins. The inactive half is
   `AL:HORIZONTAL gap=5` (3.3.10), not 4 -- the 13x12 heart sits 5 from
   `Shortlist`. MEASURED before: 14/19 ls -0.21, gap 4. */
.sf_seg {
    /* AN EVEN SPLIT. `auto` sized each half to its own label, so `All Settings`
       and `Shortlist` came out different widths inside one track -- the same
       thing the owner called out on the stone search: *"different widths, all
       need to be uniform."* */
    flex: 1 1 50%;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    border: 0;
    background: none;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 18px;
    letter-spacing: -0.5px;
    color: #27423B;
    cursor: pointer;
}
/* 6, NOT 8 -- AND THAT IS WHAT CLOSES THE CORNER. Owner: *"on All Settings and
   Shortlist, reduce the rounded corner on the inside container a lil so the gap
   isn't formed on the button."*

   The track and the half were both drawn r8, and they cannot be: the track's
   stroke is 1px INSIDE, so the box the half actually occupies is inset by 1 and
   its corner curve has to be the track's 8 MINUS that 1. At r8 the half curves
   away from a 7 it sits inside, and the crescent of page colour between them is
   the gap -- MEASURED at 1440, track [1098, 327.2] 262x44 r8 with a 1px stroke,
   active half [1099, 328.2] 130x42 r8.

   6 is the board's own number, not a tuned one: 14684:49179 is the 266x44 track
   at r8 with a 0.75 INSIDE stroke, and its active child 14684:49180 is 134x42
   at r=6. One declaration covers every surface this control appears on -- the
   ring archive, the stone archive's two toolbars and this drawer all let this
   rule win on specificity (`.sf_seg.is-active` beats `.sf_seg`). */
.sf_seg.is-active { background: #27423B; color: #FAF3ED; border-radius: 6px; }
.sf_seg_icon { display: inline-flex; align-items: center; }

/* Filters pill 89x36, filled #27423B, r8, padding 0/8 */
.sf_picker_filters {
    flex: 0 0 auto;
    /* 89 IS A FLOOR, NOT A FIT. Owner: *"when the number comes, both must be
       centred properly, while ensuring there's proper spacing."* At a hard 89
       the badge had nowhere to go: MEASURED at 390, icon 14 + gap 4 + label
       33.5 + gap 4 + badge 20 + 16 of padding = 91.5 against an 89 box, so the
       count could only arrive by squashing something. `.sf_picker_tabs` has the
       room -- the seg is 267 and the row 366, i.e. 10px of slack the pill was
       not allowed to use. Desktop pins its own 132 below and never reaches
       this, so only the phone pill actually moves. */
    min-width: 89px;
    width: auto;
    height: 36px;
    /* the badge is taken OUT of the flex row when it is empty (see
       `.sf_picker_filters_badge.is-empty`), and `position: relative` is what
       gives it something to be taken out against. */
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* THE 4s ARE MARGINS, NOT A `gap`. Board 14684:49160 puts 4 between the
       icon and the label and 4 between the label and the badge, and `gap: 4px`
       looks like the way to say that -- but a flex `gap` is drawn per slot, and
       this button's slots are not only the three things that are visible.
       MEASURED at 1728 with the badge taken out of flow: the content run came
       to 55.54 where icon + label + one gap is 51.53, i.e. an extra 4.02 was
       still being spent on the right, which put the visible content 2px left of
       the pill's centre. Stating each 4 on the element that owns it spends it
       exactly twice and only between things that are actually there. */
    gap: 0;
    padding: 0 8px;
    border: 0.75px solid #27423B;
    border-radius: 8px;
    background: #27423B;
    color: #FAF3ED;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: -0.21px;
    cursor: pointer;
}
.sf_filters_icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px; height: 14px;
}
/* Board: 4 between the 14x14 icon frame and the 14/19 ls -0.21 label. Scoped to
   this pill -- `.sf_filters_icon` is shared with the archive's own Filters
   control, which keeps its own spacing. */
.sf_picker_filters .sf_filters_icon { margin-right: 4px; }
.sf_filters_icon svg { display: block; }

/* ---- body -------------------------------------------------------------- */
/* Board: the header stack `Frame 1171276786` ends at 181 and `ERs` starts at
   186 -- a 5px gap the build spent nowhere, so the first card row sat flush
   against the segmented control. MEASURED: chrome bottom 253 / first card 253. */
.sf_picker_body {
    position: relative;
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-top: 5px;
    padding-bottom: 24px;
}

/* 3.3 Loading (39301): BOTH `Frame 1171276786` (the whole header stack -- the
   Ring-details bar, the title, the count, the segmented control and Filters) AND
   `ERs` (the grid) sit at 15% behind a 4px blur, with the 50x50 spinner over the
   top. Only the grid was dimmed before, so the chrome stayed sharp while the
   cards faded. The flow's own head and step bar are NOT part of that frame and
   stay put. */
/* IT FADES, IT DOES NOT SNAP. The owner asked for a *"faded loading
   animation"* on picking a ring, and the state itself was already correct --
   what it had no transition for was getting there, so at 60fps the grid simply
   vanished and came back. The transition is declared on the resting rule so it
   runs in BOTH directions: into the blur when a pick or a filter starts, and
   back out when the cards arrive. 180ms is the gap between "this responded" and
   "this flickered"; `filter` is included because a blur that appears instantly
   under an opacity that fades reads as two separate events. */
.sf_picker_body .sf_picker_grid,
.sf_picker_sheet .sf_picker_chrome {
    transition: opacity 180ms ease-out, filter 180ms ease-out;
}
.sf_picker_body.is-loading .sf_picker_grid,
.sf_picker_sheet.is-loading .sf_picker_chrome {
    opacity: .15;
    filter: blur(4px);
    pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
    .sf_picker_body .sf_picker_grid,
    .sf_picker_sheet .sf_picker_chrome { transition: none; }
}
.sf_picker_loading { display: none; }
.sf_picker_body.is-loading .sf_picker_loading {
    /* the 50x50 instance box; the 24x24 ellipse is centred in its 13px pad */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px; height: 50px;
    position: absolute;
    left: 50%; top: 200px;
    transform: translateX(-50%);
    z-index: 2;
}
/* Board `Circular Spinner-loading screen` 14514:39487 is a 50x50 INSTANCE with
   padding 13, and the thing that spins is `Ellipse 1` 14514:39487;12860:33724 --
   24x24, an angular gradient from #27423B to #C4C4C4 at zero alpha, node
   opacity 0.80, centred at (194,412) in a 390-wide frame. The build painted the
   ring at the full 50, i.e. the padding as ink. */
.sf_picker_spinner {
    display: block;
    /* node opacity 0.80 on the ellipse itself */
    opacity: .8;
    width: 24px; height: 24px;
    border-radius: 50%;
    background: conic-gradient(from 0deg, rgba(39,66,59,0) 0deg, #27423B 300deg, rgba(39,66,59,0) 360deg);
    /* No mask. 12860:33724 is an ELLIPSE with a fill and no stroke -- the
       gradient IS the disc. The 3px ring that was here was a spinner idiom, not
       the node, and on a 24 box it would have been a hairline anyway. */
    animation: sf_spin 900ms linear infinite;
}
@keyframes sf_spin { to { transform: rotate(360deg); } }

/* ---- the grid, and the loop card restyled to 14514:41709 ---------------
   EVERY RULE IN THIS BLOCK IS ROOTED AT `#sf_settings_picker`, ON PURPOSE.
   The card is WooCommerce's archive loop markup, and assets/css/main.css dresses
   it for the archive with selectors that reach (0,3,3) and (0,4,2) --
   `.woocommerce ul.products li.product .woocommerce-loop-product__title`,
   `.woocommerce ul.products li.product:nth-child(2n)`. A class-only selector
   here loses to those, which is exactly what happened: the picker's own type
   rules never applied and what rendered was the archive's responsive sizing.
   The id makes this component win without an `!important` anywhere, and it
   cannot leak: nothing outside the drawer carries that id.
   ----------------------------------------------------------------------- */
#sf_settings_picker .sf_picker_grid .product_card_container { margin: 0; }
#sf_settings_picker .sf_picker_grid ul.products {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0;
    padding: 0 12px;
    list-style: none;
}
/* WooCommerce ships `ul.products` a table-display clearfix on ::before and
   ::after. Inside a flex or grid container those pseudo-elements become REAL
   ITEMS: ::before took a zero-width slot plus the 12px gap, pushing card 1 to
   x=24 and leaving 378px of demand in a 366px row, so row 1 held one card; at
   1728 it ate column 1 of the grid outright and the top-left cell rendered
   empty. */
#sf_settings_picker .sf_picker_grid ul.products::before,
#sf_settings_picker .sf_picker_grid ul.products::after {
    content: none;
    display: none;
}
#sf_settings_picker .sf_picker_grid ul.products li.product {
    flex: 0 0 calc(50% - 6px);
    width: calc(50% - 6px);
    max-width: calc(50% - 6px);
    /* Board 41709: the card frame is 177x340 FIXED/FIXED and every instance on
       39115 is identical. Without a height it grew with the subtitle's line
       count -- measured 350.4 / 387.8 / 365.8 in one grid. The 340 budget is
       photo 160 + 8 + name 24 + 6 + subtitle 18 + 6 + price 16 + slack +
       swatches 24 + 2 + metal label 24 + 8, and the slack is the `margin-top:
       auto` on the swatch row, so a two-line name eats the slack instead of
       stretching the card. */
    height: 340px;
    margin: 0;
    padding: 0;
    background: #fff;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
    text-align: center;
    /* SOURCE ORDER IS NOT THE BOARD'S ORDER. The loop prints
       photo -> swatches -> metal label -> title -> subtitle -> price, and
       14514:41709 stacks photo -> NAME -> subtitle -> price -> swatches ->
       label. Re-ordering in flex moves the rendered boxes without touching the
       markup, so every handler the archive binds to those swatches still finds
       the nodes where it left them. */
    display: flex;
    flex-direction: column;
}
/* The column is the <a>, not the <li>: measured, the li has exactly two
   children (the loop anchor and span.product_item_info) and EVERYTHING the card
   shows lives inside that anchor. Ordering the li's children therefore did
   nothing -- the first attempt at this moved no boxes at all. */
#sf_settings_picker .sf_picker_grid ul.products li.product > a.woocommerce-LoopProduct-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    /* The archive rounds this anchor 8. The card itself is r4 (14514:41709), and
       an inner radius larger than its clip is the one that shows. */
    border-radius: 4px;
    /* The archive pads this anchor 10 above the photo and 20 below the metal
       label. The board pads the photo frame and the text frame 8 each and
       nothing else, and that 30px is part of why no card reached 340. */
    padding: 0;
}
#sf_settings_picker .sf_picker_grid li.product > a > .looped_slider                    { order: 1; }
#sf_settings_picker .sf_picker_grid li.product > a > h2.woocommerce-loop-product__title { order: 2; }
#sf_settings_picker .sf_picker_grid li.product > a > p                                 { order: 3; }
#sf_settings_picker .sf_picker_grid li.product > a > .price                            { order: 4; }
#sf_settings_picker .sf_picker_grid li.product > a > .item_grid_swatch                 { order: 5; }
#sf_settings_picker .sf_picker_grid li.product > a > .active_metal_swatch              { order: 6; }
#sf_settings_picker .sf_picker_grid li.product > span.product_item_info                { display: none; }
#sf_settings_picker .sf_picker_grid ul.products li.product.is-picked {
    box-shadow: 0 0 0 2px #27423B;
}

/* Empty state. It is a child of .sf_picker_grid, NOT of ul.products, so it is
   not a grid item and needs no column span -- but the grid can be absent
   entirely (an empty response renders no <ul>), so it is styled standalone. */
#sf_settings_picker .sf_picker_grid .sf_picker_empty {
    margin: 0;
    padding: 48px 12px;
    text-align: center;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: -0.21px;
    color: #3E3C39;
}

/* ---------------------------------------------------------------------------
   [Flow 3] THE EMPTY SHORTLIST -- Figma 16032:65645 "3.3 Engagement rings",
   frame `Frame 1171276870` (16032:65646)
   ---------------------------------------------------------------------------
   The `.sf_picker_empty` <p> above stays: it answers a DIFFERENT question
   ("your shortlist has rings but none of them take this stone"). This block is
   the board's answer to the one case that <p> never had copy for -- the
   shortlist is genuinely empty -- and settings-picker.js:paintEmpty() picks
   between them.

   Same composition as the stone half, and deliberately the same numbers; the
   two frames are identical apart from the noun and the two labels:
     block        234 FIXED, VERTICAL, itemSpacing 36, both axes CENTER
     icon         36x34, 1px #E4DED8, CENTER stroke align, round cap/join
     copy column  itemSpacing 24   (16032:65648)
     words        itemSpacing 6    (16032:65649)
     ctas         itemSpacing 4    (16032:65652)

   THE TOP GAP IS 30, NOT 35. The board puts the block's top edge at y=216 and
   the chrome stack `Frame 1171276786` ends at 181 -- 35px apart. 5 of those 35
   are already spent: .sf_picker_body carries `padding-top: 5px` for the board's
   own 181 -> 186 gap (see the note on that rule). So this block adds the
   remaining 30 and the sum is the board's 216. At >=992 the body's top padding
   is 4 rather than 5 and no 1440 frame exists for this screen, so the 30 is
   left as it is -- stated in the report.

   `:not([hidden])` IS LOAD-BEARING. The node is printed with the `hidden`
   attribute and paintEmpty() removes it; a bare `display: flex` on the class
   would beat the UA sheet's `[hidden] { display: none }` (author sheet wins at
   equal specificity) and the block would be on screen from first paint.
   --------------------------------------------------------------------------- */
#sf_settings_picker .sf_picker_empty_state:not([hidden]) {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 36px;
    padding-top: 30px;
}

/* 16032:65647. 37x35 box for a 36x34 path -- a CENTER-aligned 1px stroke
   bleeds 0.5 outside the path box all round. `color` is the stroke. */
#sf_settings_picker .sf_picker_empty_icon {
    display: block;
    flex: 0 0 auto;
    width: 37px;
    height: 35px;
    color: #E4DED8;
}
#sf_settings_picker .sf_picker_empty_icon svg { display: block; }

/* 16032:65648 -- itemSpacing 24, and the only STRETCH child of the 234 frame,
   so the 234 lives here rather than on the block (the icon is a fixed 36
   centred in it). */
#sf_settings_picker .sf_picker_empty_copy {
    display: flex;
    flex-direction: column;
    gap: 24px;
    width: 234px;
    max-width: 100%;
}

/* 16032:65649 -- itemSpacing 6 */
#sf_settings_picker .sf_picker_empty_words {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* 16032:65650 -- Canela-Light 300, 18/21, ls -0.21, CENTER, #0F0E0D, no
   textCase. */
#sf_settings_picker .sf_picker_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:65651 -- FoundersGrotesk-Regular 400, 16/21, ls -0.21, CENTER,
   #3E3C39. The board's box is 234x42 (two lines); no height is pinned so a
   third line shows rather than being clipped. */
#sf_settings_picker .sf_picker_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:65652 -- itemSpacing 4 */
#sf_settings_picker .sf_picker_empty_ctas {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* 16032:65653 / 65657 -- both 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 = 14 + 19 + 14. */
#sf_settings_picker .sf_picker_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:65653 -- 1px #27423B, strokeAlign INSIDE; 16032:65655 is textCase
   UPPER over stored mixed case.
   PADDING 13 IS THE BOARD'S 14. Figma draws an INSIDE stroke inside the
   frame's own 47, so the 14 already contains it; CSS adds the border outside
   the padding box, so 14 would measure 49. 13 + 19 + 13 + 2 = 47. */
#sf_settings_picker .sf_picker_empty_cta_all {
    padding: 13px 0;
    border: 1px solid #27423B;
    text-transform: uppercase;
}

/* 16032:65657 has NO stroke; 65659 carries textDecoration UNDERLINE and no
   textCase, so 14px padding stands and the label keeps its stored case. */
#sf_settings_picker .sf_picker_empty_cta_link {
    text-decoration: underline;
}
/* image area 177x160, the photo FILLS it (the archive letterboxes it) */
#sf_settings_picker .sf_picker_grid .looped_slider {
    position: relative;
    flex: 0 0 auto;
    height: 160px;
    overflow: hidden;
}
#sf_settings_picker .sf_picker_grid .looped_slider img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
#sf_settings_picker .sf_picker_grid .secondary_overlay { display: none !important; }

/* The whole card is inside the loop's <a>, which the theme underlines. */
#sf_settings_picker .sf_picker_grid ul.products li.product a,
#sf_settings_picker .sf_picker_grid ul.products li.product a:hover,
#sf_settings_picker .sf_picker_grid ul.products li.product a:focus { text-decoration: none; }

/* Name: Canela 300, 21/24 on one line and 18/22 when it wraps -- product-card
   note 14514:41732. CSS cannot see a wrap, so settings-picker.js measures each
   name after paint and stamps `is-wrapped`; with JS absent the card keeps the
   one-line size, which is the board's default. The box is 161 wide: the card's
   177 less the text frame's 8px inset each side, which is the margin here (the
   archive's `padding: 0 10px` made it 177 wide with a 10px inset instead). */
#sf_settings_picker .sf_picker_grid ul.products li.product h2.woocommerce-loop-product__title {
    margin: 8px 8px 0 8px;
    padding: 0;
    font-family: 'Canela', serif;
    font-weight: 300;
    font-size: 21px;
    line-height: 24px;
    letter-spacing: -0.21px;
    text-transform: uppercase;
    color: #0F0E0D;
}
#sf_settings_picker .sf_picker_grid ul.products li.product h2.woocommerce-loop-product__title.is-wrapped {
    font-size: 18px;
    line-height: 22px;
}
/* Subtitle and price are children of the loop ANCHOR, not of the li -- the
   order rules above already say so. The rules that used to sit here were
   written as `li.product > p` and matched nothing at all, which is why both
   lines rendered at the archive's phone sizes (14px) rather than the board's. */
#sf_settings_picker .sf_picker_grid ul.products li.product > a > p {
    margin: 6px 8px 0 8px;
    padding: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: -0.21px;
    color: #0F0E0D;
}
#sf_settings_picker .sf_picker_grid ul.products li.product .price {
    display: block;
    margin: 6px 8px 0 8px;
    padding: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 16px;
    letter-spacing: -0.21px;
    color: #0F0E0D;
}
#sf_settings_picker .sf_picker_grid .price del,
#sf_settings_picker .sf_picker_grid .price ins { text-decoration: none; }

/* metal swatches 24x24 with a 20x20 inner disc; selected gets a 1px inside ring */
/* THE ARCHIVE POSITIONS THESE ABSOLUTELY. Measured inside the picker before
   this: .item_grid_swatch and .active_metal_swatch both computed
   `position: absolute`, so the swatch row and the metal name floated on top of
   the subtitle instead of sitting under the price. The card here is a normal
   flow column, so they are put back into it. */
/* ...THE LABEL EXCEPTED, AND THAT IS THE WHOLE POINT OF IT BEING ABSOLUTE.
   Owner: *"I guess I myself asked you to make all metal colour text centred for
   the engagement ring drawer in the stone-first flow, but now I want it like
   the others -- aligned, and it moves with the metal change, like on
   /engagement-rings/."*

   It moves because main.js:920 writes an inline `left` on it, computed from the
   position of the swatch that was clicked, so the name sits UNDER its own disc.
   That arithmetic is generic and works in any card; it just needs an absolutely
   positioned element to land on. Pinning it `static` here is what stopped it,
   so only the ROW keeps the static treatment this block was written for, and
   the label goes back to the archive's.

   MEASURED on /engagement-rings/ at 1440 -- the behaviour being matched: the
   label is a 70px shrink-to-fit box that moved x 120 -> 282 when the fourth
   swatch was clicked. In this drawer before: a 410px full-width box, centred,
   that stayed at x 75. */
#sf_settings_picker .sf_picker_grid .item_grid_swatch { position: static; }

/* Board `Frame 39063 @20,468 161x24`: the row is the full 161 of the text
   frame, SPACE_BETWEEN, so the first disc sits 8 in from the card's left edge
   and the last 8 in from the right. The archive's `.item_grid_swatch{width:80%}`
   (main.css:2651, and 75% at >=1200) resolved to 141.6 here and left the four
   discs 19.4px short of the right inset -- visibly off-centre under a centred
   price. Nothing set a width in this block before, so that rule simply won. */
#sf_settings_picker .sf_picker_grid .item_grid_swatch {
    display: flex;
    justify-content: space-between;
    gap: 0;
    width: auto;
    margin: 0 8px;
    margin-top: auto;
    padding: 0;
    flex: 0 0 auto;
}
#sf_settings_picker .sf_picker_grid .metal_var_container {
    width: 24px; height: 24px;
    margin: 0;
    border-radius: 18px;
    padding: 2px;
    /* The archive's own sheet puts a 1px border on this node and colours it to
       show selection. Board 14514:39165 has no border: the wrapper is 24x24
       with padding 2 and a 20x20 ellipse inside, and the SELECTED state is a
       1px INSIDE stroke -- which is the inset shadow below, drawn over the
       padding rather than taken out of it. With the border left in, the flex
       child had 18px of content box to sit in and MEASURED 18x20. */
    border: 0;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
#sf_settings_picker .sf_picker_grid .metal_var_container.active { box-shadow: inset 0 0 0 1px #0F0E0D; }
#sf_settings_picker .sf_picker_grid .metal_var {
    /* `flex: 0 0 auto`: the wrapper is a flex container, so a 20px disc with
       the default shrink collapsed to whatever the content box allowed. */
    flex: 0 0 auto;
    width: 20px; height: 20px;
    border-radius: 50%;
    display: block;
}
/* Board `Frame 38462`, fourth disc: #B9B9B9, a neutral grey. The archive paints
   platinum #ABB3BE (main.css:2689), a blue-grey. Scoped to the drawer so the
   archive's own discs are untouched. */
#sf_settings_picker .sf_picker_grid .metal_var[data-metal='platinum'] { background-color: #B9B9B9; }
/* Palladium, in the drawer's own palette. The archive paints it #A3A3A3
   (main.css) against a platinum of #ABB3BE; here platinum is the flatter
   #B9B9B9 the board draws, so palladium takes the same #A3A3A3 the filter
   rail, the metal picker and the settings picker's own chips already use --
   one value for this metal everywhere, and still a step darker than the
   platinum beside it. */
#sf_settings_picker .sf_picker_grid .metal_var[data-metal='palladium'] { background-color: #A3A3A3; }
/* THE ROW RESERVES WHAT THE LABEL STOPPED CONTRIBUTING. Out of flow, the label
   adds no height, so the card closed up and the name landed ON the swatches --
   MEASURED at 1440 before this: row 760-792, label 768-786. The archive spends
   the same space: there the row ends at 878 and the label runs 918-935 inside a
   card that ends at 955. 44 is that gap at both widths (the phone label is the
   taller of the two at 24px). */
#sf_settings_picker .sf_picker_grid li.product > a > .item_grid_swatch {
    margin-bottom: 44px;
}
#sf_settings_picker .sf_picker_grid .active_metal_swatch {
    /* absolute, so main.js's `left` places it under the active disc; the row
       above reserves the height it no longer contributes to the flow */
    position: absolute;
    bottom: 12px;
    display: block;
    margin: 0;
    text-align: left;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 24px;
    letter-spacing: -0.21px;
    color: #3E3C39;
}

/* tag chip + heart ride on the photo, as the board draws them */
/* Board `Tags for Stones` / `Rectangle 343`: fill #E4DED8 at 60% -- the same
   warm wash as the Ring-details bar. #FAF3ED is the page ground, which on a
   white card read as a near-invisible cream block. */
#sf_settings_picker .sf_picker_grid .productTag {
    position: absolute;
    left: 8px; top: 8px;
    z-index: 2;
    /* 58x18 with 12/13.2 type: the chip is a fixed 18 tall and the label is
       centred in it, rather than 13.2 of leading plus padding (17.2). */
    display: inline-flex;
    align-items: center;
    height: 18px;
    box-sizing: border-box;
    /* `Tags for Stones` insets its label 6 from the left, not 8: the board's
       own `Best Selling` hugs to 68 and `Timeless Classic` to 97, which is the
       string plus 12. MEASURED at 8: `Trending` came out 58 wide, 4 over. */
    padding: 0 6px;
    border-radius: 4px;
    background: rgba(228, 222, 216, 0.6);
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 12px;
    line-height: 13.2px;
    color: #3E3C39;
}
/* Board: the heart glyph is 16x15, inset 8 from the card's right edge and 9.5
   from the top -- the right-hand end of the 161-wide overlay row inside the
   photo's 8px padding.
   heart-icon.svg is a 60x40 ART BOARD with an 18.25x16.73 heart floating at
   (21, 12.6354) inside it, and that file is shared with the PDP and the archive
   -- not ours to re-cut. So the art board is scaled by 16/18.25 = 0.8767 (which
   takes the glyph to 16 x 14.67 ~ the board's 16x15) and then shifted so the
   GLYPH, not the box, lands on the board's inset:
     glyph x within the scaled board = 21 * 0.8767 = 18.41
     box left with `right: 0` on a card of width W = W - 60
     wanted glyph left = W - 8 - 16 = W - 24
     => translate x = (W - 24) - (W - 60) - 18.41 = 17.59   (width-independent)
     glyph y = 12.6354 * 0.8767 = 11.08, wanted 9.5 => translate y = -1.58
   The card's `overflow: hidden` trims the empty right-hand end of the art
   board. */
#sf_settings_picker .sf_picker_grid .productFavorite {
    position: absolute;
    right: 0; top: 0;
    width: 60px; height: 40px;
    z-index: 2;
}
/* 48 TALL OF TAP. Owner: *"increase the tappable area -- 48 by 48 on the
   corner. Don't increase the icon size or location though."* This one is
   already 60 across; only the height was under. The art board inside is
   transform-positioned, so growing the box itself would move the glyph --
   a pseudo-element does not. */
#sf_settings_picker .sf_picker_grid .productFavorite::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 60px;
    height: 48px;
}
#sf_settings_picker .sf_picker_grid .productFavorite svg {
    display: block;
    width: 60px; height: 40px;
    transform-origin: 0 0;
    transform: translate(17.59px, -1.58px) scale(0.8767);
}

/* ===========================================================================
   >= 992 -- THE DIAMOND DRAWER'S SHELL, NOT A NEW ONE.
   The board has no desktop frame for 3.3 (every Flow 3 artboard is 390), so the
   desktop treatment is not invented here: it is the one the builder's own
   advanced stone search already uses, read off
   redesign/_advanced-search-desktop.css (board 14468:42834). Same shell, same
   rhythm, different contents -- which is the whole point of 3.3 being that
   screen's mirror.

   What is borrowed, and from where:
     full-screen fixed panel      div#ssq_diamond_search.ssq_diamond_search
                                  { position:fixed; inset:0 }
     80px gutters                 --dsq-d-gutter: 80/1728 = 4.6296296296%
     header band 1 = 128, pad 44  .dsq_header_titlerow
     header band 2 = 68, pad 12/0 .dsq_header_controls
     result count 18/16 #3E3C39   .dsq_header_count.results_count
     card grid                     repeat(auto-fill, minmax(min(100%,220px),1fr))
                                  gap 24
   The previous version of this block invented a 520px right-hand panel. It had
   no basis on any board and did not match the screen it mirrors.
   =========================================================================== */
@media (min-width: 992px) {
    .sf_picker_sheet {
        /* full screen, like the stone search -- NOT a side panel */
        inset: 0;
        width: auto;
        max-width: none;
        transform: translateY(100%);
    }
    #sf_settings_picker.is-open .sf_picker_sheet { transform: translateY(0); }

    .sf_picker_chrome {
        padding: 0 4.6296296296%;
        /* NO RULE UNDER THE CHROME. Owner: *"the line between Ring Details and
           the rest looks different from other such sections -- remove it."* It
           did look different, and MEASURABLY so: the chrome's own box is the
           full 1728, so the border ran 0..1728 while every element above it --
           the Ring Details bar, the title, the Filters pill, the segmented --
           is inset to the 80px page gutter. One edge-to-edge line under a stack
           of inset content reads as a seam in the page rather than as this
           band's own divider. The archive's band draws its rule deliberately
           full-bleed (stone-first.css `.sf_ring_titlerow::after`) and ABOVE the
           toolbar; this one sat BELOW it, so the two never matched anyway.
           Phone never had it -- MEASURED at 390, no border on this box -- so
           dropping it makes the two widths agree as well. */
    }

    /* band 1: 128 tall, 44 above the title row */
    .sf_picker_details {
        width: 100%;
        margin: 0;
        margin-top: 24px;
    }
    .sf_picker_head {
        padding: 0;
        margin-top: 0;
        gap: 0;
    }
    .sf_picker_titlerow {
        height: 84px;
        align-items: flex-end;
        padding-bottom: 12px;
    }
    /* 3.3.5 at desktop. The board draws this heading at 18 (Canela 300 18/19)
       and ELEMENTS 14 gives exactly one desktop ramp -- "page title 24->37,
       section headings 18->24, body 14->16". `ENGAGEMENT RINGS` is a section
       heading on the in-flow `advanced-header`, not the page title of an
       archive, so it goes to 24. MEASURED before at 1728: 32px / 35.2px, which
       is neither the mobile 18 nor the ramp's 24 -- it was the page-title step
       applied to the wrong node. */
    .sf_picker_title { font-size: 24px; line-height: 26.4px; }
    .sf_picker_count { font-size: 18px; line-height: 16px; }
    /* The title row is 84 tall and bottom-aligned at this width, so the close's
       negative margins (which centre it on a 19px row at 390) would hang it
       below the count's baseline. Bottom-align it on the same line instead. */
    /* Scoped to the title row. The close now lives in the Ring-details bar, and
       un-scoped this rule bottom-aligned it there and pushed it 6px below the
       bar's own centre line. */
    .sf_picker_titlerow .sf_picker_close { align-self: flex-end; margin: 0 0 -6px 8px; }

    /* band 2: 68 tall, 12/0 */
    .sf_picker_tabs {
        height: 68px;
        align-items: center;
        padding: 12px 0;
        box-sizing: border-box;
    }

    .sf_picker_body { padding: 4px 4.6296296296% 120px; }

    /* the stone search's own track sizing, so the two screens deal cards at the
       same width instead of one of them inventing a column count */
    /* THE BAND, NOT JUST THE FORMULA. `repeat(auto-fill, minmax(220px,1fr))`
       + gap 24 is the advanced-search grid, and it was already here -- but it
       was running across the FULL 1568 content band, where auto-fill packs SIX
       tracks (6x220 + 5x24 = 1440 <= 1568) and hands each card 241.33.
       `_advanced-search-desktop.css` resolves the same formula to FOUR tracks
       of 265.5 because on that screen the grid is the `1fr` remainder AFTER the
       345 filter rail and its 89 gutter: 1568 - 345 - 89 = 1134, and
       4x265.5 + 3x24 = 1134 exactly. MEASURED on the live stone archive at
       1728, which ships that model: cards 265.3 wide, four per row, first at
       x515.

       3.3 has no rail -- the board gives it a Filters PILL (3.3.11) and no rail
       at any width -- so to deal the same card as the screen it mirrors the
       band has to be declared rather than inherited. 1134 / 1568 =
       72.3214285714%, the same token `_advanced-search-desktop.css` calls the
       results column, so it degrades on the same ladder: 4 columns at 1728,
       3 at 1280, 2 at 992.

       THE 72.32% BAND IS GONE. Reserving 3.1's rail width on a screen that has
       no rail left a 434px empty column: MEASURED at 1728, the cards dealt
       4 x 265.5 at x 80/369.5/659/948.5, last edge x1214, while the
       Ring-details bar, the title, the count and the toolbar above them all ran
       to x1648. The grid is the results COLUMN, and on 3.3 the results column
       IS the content band -- that is the whole difference between this screen
       and 3.1, and the reason the board gives 3.3 a Filters pill instead of a
       rail. So the formula ELEMENTS 14.1 names is resolved against the full
       1568 instead of against 3.1's remainder: auto-fill packs
       floor((1568+24)/(220+24)) = 6 tracks of (1568 - 5x24)/6 = 241.33, and it
       degrades on the same ladder below (5 at ~1460, 4 at ~1220, 3, 2 at 992).
       The card width is a carry-over either way -- ELEMENTS 14.2.3 records that
       the board gives no desktop card for this component -- but a grid that
       ends where every other row on the screen ends is not. */
    /* OWNER, on this drawer at desktop: *"product cards look too crowded"*, then
       *"product cards of engagement rings drawer can be how they are on
       /engagement-rings/ on desktop"*. So the reference is no longer a
       carry-over of 3.1's 220 floor -- it is the live engagement-rings archive,
       MEASURED at 1728: grid 1416 wide, FOUR cards of 342 on a 357 pitch, i.e.
       a 15px gutter, each with a SQUARE 342x342 photo, card 560 tall.

       A 220 floor against this drawer's full-bleed 1568 packed
       floor((1568+24)/244) = 6 tracks of 241.33 -- narrower than the archive's
       342 and carrying the same five text rows, which is the crowding. A 340
       floor on the archive's 15px gutter packs floor((1568+15)/355) = 4 of
       380.75, and degrades 3 at ~1280 and 2 at 992 on the same ladder. */
    #sf_settings_picker .sf_picker_grid ul.products {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
        gap: 15px;
        width: 100%;
        padding: 0;
        align-content: start;
    }
    /* Every card FILLS its track. Before this the cards inside a uniform
       241.33px track measured 241.3 and 226.3 by turns, because
       `.woocommerce ul.products li.product:nth-child(2n){margin-right:15px}`
       (main.css, the >=1200 block) reaches (0,4,2) and out-specified the
       `margin: 0` written for the card -- which read as ragged 24/39px gutters
       across the row. The id root settles it. */
    #sf_settings_picker .sf_picker_grid ul.products li.product {
        flex: none;
        width: auto;
        max-width: none;
        margin: 0;
        /* No fixed card height. The photo is the board's own C3.2 box -- 177
           wide by 160 tall on a 177-wide card -- so at a 265.5 track it is
           265.5 x 239.9 and the card is that plus the 180 the C3.6 text block
           budgets: 419.9, NOT the 382 of `_advanced-search-desktop.css`'s card.
           Those are different components. The advanced-search card carries
           THREE text nodes (title, spec line, price) in a 140-tall block;
           14514:41709 carries FIVE (name, subtitle, price, four swatches, metal
           label) in 180, and ELEMENTS 14.2.3 makes exactly that point about the
           other direction. Forcing 382 here would clip the swatch row.
           Height is left to the grid row so every card in a row equalises and a
           two-line ring name cannot crop.
           MEASURED before: a hard 400 with a 220 photo -- a mobile budget
           scaled by eye, matching neither card. */
        height: auto;
    }
    /* SQUARE, the archive's. 177/160 is board 14514:41709's phone card and was
       carried up with it; the archive photo is 342x342 and the source images
       are 1000x1000, so 1:1 is the photo's own ratio and nothing is cropped. */
    #sf_settings_picker .sf_picker_grid .looped_slider {
        height: auto;
        aspect-ratio: 1 / 1;
    }
    /* The text block's rhythm is the archive's too -- MEASURED there: title
       21/25.2 with 10 below, subtitle 16/17.6 with 16, price 16/17.6 with 8.
       The 8/6/6 this drawer had is board 14514:41709's 390 budget, which is
       what made five rows read as stacked at desktop. The 8px side margins stay:
       the archive card is full-bleed text on a transparent ground, this one sits
       on a white card. */
    #sf_settings_picker .sf_picker_grid ul.products li.product h2.woocommerce-loop-product__title {
        margin: 12px 8px 10px;
        font-size: 21px;
        line-height: 25.2px;
    }
    #sf_settings_picker .sf_picker_grid ul.products li.product > a > p {
        margin: 0 8px 16px;
        font-size: 16px;
        line-height: 17.6px;
    }
    #sf_settings_picker .sf_picker_grid ul.products li.product .price {
        margin: 0 8px 8px;
        font-size: 16px;
        line-height: 17.6px;
    }
    /* The swatch row is the archive's, and `flex-start` was wrong -- MEASURED on
       the picker card after the first cut: four 32px swatches bunched against
       the left of a 364.8 row with 212.8px of dead space to their right, which
       is the "not centred / weird" the owner reported.

       /engagement-rings/ at 1728, MEASURED: the row is 256.5 in a 342 card --
       exactly 75% -- centred, with `space-between` spreading the four swatches
       inside it, and the metal label CENTRED under them. Same three rules here,
       so the row tracks the card at any track width. */
    #sf_settings_picker .sf_picker_grid .item_grid_swatch {
        justify-content: space-between;
        gap: 0;
        width: 75%;
        margin: 0 auto 4px;
    }
    #sf_settings_picker .sf_picker_grid .item_grid_swatch .metal_var_container {
        width: 32px;
        height: 32px;
    }
    /* THE DISCS ARE THE ARCHIVE'S SIZE, not a smaller echo of them. Owner, on
       this drawer: *"the metal dots on the product cards look smaller -- make
       them like they are on the category pages."* They were: the WRAPPER was
       lifted to 32 here to match the archive's 24+3+3+1+1, but the disc inside
       it kept the base rule's 20, so the drawer dealt 20px discs beside the
       archive's 24. Only the fill box changes; the 32px wrapper and its 1px
       inset selection stroke are untouched. */
    #sf_settings_picker .sf_picker_grid .item_grid_swatch .metal_var {
        width: 24px;
        height: 24px;
    }
    /* the centring that was asked for and then unasked for; only the type size
       is kept from this block -- see the note at the base rule */
    #sf_settings_picker .sf_picker_grid .active_metal_swatch {
        font-size: 16px;
        line-height: 18px;
    }

    /* THE HEART. main.css:2477 fills it jade on hover inside its own
       `@media (min-width: 992px)` -- the SAME paint as `.selected` -- so on
       desktop a hovered card reads as already shortlisted. Owner: *"the heart
       should not be display-on-hover, it must be non-fill and fill on click --
       without click only outline, on click fill."* The hover paint is dropped
       here and the saved paint is left alone, so outline is the resting state
       and the only thing that fills it is the click. Scoped to this drawer:
       main.css's rule is site-wide and every other product card still behaves
       as it shipped. */
    #sf_settings_picker .sf_picker_grid .productFavorite:hover svg path {
        stroke: var(--onyx, #0F0E0D);
        fill: none;
    }
    /* SAVED IS TERRACOTTA, LIKE EVERY OTHER CARD ON THE SITE. Owner, with the
       drawer open: *"the favourite colours are not like the others, they're
       jade -- I want them changed to how they are on the others."* MEASURED,
       same build, same click: /engagement-rings/ fills rgb(198,88,88), this
       drawer filled rgb(39,66,59). The hover rule above stays -- that is the
       *"without click only outline, on click fill"* behaviour this drawer was
       asked for, and it is about WHETHER it fills, not what colour. Only the
       saved paint is handed back to main.css's --terracotta. */
    #sf_settings_picker .sf_picker_grid .productFavorite.selected:hover svg path,
    #sf_settings_picker .sf_picker_grid .productFavorite.selected svg path {
        stroke: var(--terracotta, #C65858);
        fill: var(--terracotta, #C65858);
    }
}

/* ===========================================================================
   THE IN-FLOW SETTING PAGE -- 14514:39674 (full scroll) / 14514:40019 (one
   viewport). Everything here hangs off `body.sf-flow-pdp`, which PHP only adds
   when the page was reached from the picker (`sf=1`). No marker, no rules: a
   ring page reached any other way is byte-identical to what shipped.
   =========================================================================== */

/* SHAPE IS NOT THE SHOPPER'S CHOICE HERE. The board draws the ring page in this
   flow with metal swatches and nothing else -- no Shape row -- because the held
   stone already decided it: the picker filtered the grid by that shape and the
   card's permalink carries it. The row is HIDDEN, not removed: the <select>
   still holds the value, so set_setting_ringbuilder() keeps reading the shape
   off the form exactly as it does everywhere else, and the variation resolves
   the same. Removing it would have quietly changed what gets committed.

   The row carries no class of its own, so it is matched by the control inside
   it. :has() is already relied on in redesign/_stone.css for the step states,
   so this needs no new browser support. */
body.sf-flow-pdp form.cart table.variations tr:has(select[name="attribute_pa_shape"]) {
    display: none;
}
/* Belt and braces for the swatch block itself. MEASURED chain, because the
   first attempt guessed it and matched nothing: the form is
   `form.variations_form.cart` sitting in `div.summary.entry-summary` -- there is
   no `.woocommerce div.product` above it on this template, so a selector
   written from the WooCommerce default nesting never applied. The swatches are
   `div.swatches_outer_container.swatch_icons.pa_shape >
   div.swatches_container.pa_shape` inside `td.value`. */
body.sf-flow-pdp form.cart .swatches_outer_container.pa_shape,
body.sf-flow-pdp form.cart .swatches_container.pa_shape {
    display: none;
}

/* ---- THE EMPTY SIZE AND ENGRAVING ROWS GO WITH THEIR CONTENTS -------------
   Owner: *"there's a lot of space between the metal buttons of YG RG WG Pt Pd
   and then the next section, Product Details -- reduce it to normal, in phone
   view, on the modified PDP."*

   MEASURED at 390 on `?sf=1`: metal swatches end at y660, the Product Details
   title starts at y753. 93px, and it is three things, not one:

     660 -> 696   36  two EMPTY variation rows below the metal one
     696 -> 712   16  table margin-bottom
     712 -> 752   40  .product-details-accordion margin-top, which COLLAPSES
                      with the form's own 32 -- max(32,40), not 72

   The 36 is the bug. The site-wide rule `.swatch_icons.pa_size,
   .swatch_icons.pa_engraving { display: none }` hides what is INSIDE those two
   rows -- size and engraving are the quiz's steps, not the PDP's -- but nobody
   hid the rows. What was left is two 2px shells (`td.value` has `padding: 1px
   1px 1px 0`) that still claim line space, because
   `.variations_form.cart table.variations tr` is `display: inline-flex`: the
   rows are INLINE-level, so each one still generates a line box and the
   whitespace between them in the HTML renders as real gaps. MEASURED row tops
   583 / 671 / 688 against a metal row that ends at 661.

   Hidden, not removed, and the <select>s inside stay in the DOM with their
   values -- exactly the contract the Shape row above already follows, so
   set_setting_ringbuilder() keeps reading size and engraving off the form the
   way it does everywhere else.

   Scoped to `body.sf-flow-pdp`. These shells sit on EVERY engagement-ring PDP,
   not just this flow, but the ordinary PDP is not what was reported and is not
   ours to change here. The remaining 16 + 40 are a real table margin and a real
   section margin, and they are left alone. */
body.sf-flow-pdp form.cart table.variations tr:has(select[name="attribute_pa_size"]),
body.sf-flow-pdp form.cart table.variations tr:has(select[name="attribute_pa_engraving"]) {
    display: none;
}
/* ...AND THE REMAINING 56 COMES DOWN TO THE BOARD'S 24.
   14514:39674 puts the metal chips at y644 h36 (ending 680) and the `tabs`
   group -- the accordion -- at y704. 24, measured off the frame.

   With the shells gone the gap was 58, and it was two margins plus a collapse:
   the variations table's own `margin-bottom: 16`, and `margin-top: 40` on
   .product-details-accordion COLLAPSING with the form's `margin-bottom: 32` to
   max(32,40) = 40. Tuning either one alone does nothing visible, which is what
   makes this kind of gap hard to chase -- so both are taken out of play and ONE
   margin is left to own the distance.

   The table's 16 separates the variation rows from the add-to-cart block below
   them; in this flow that block is hidden and the rows it separated are the
   last thing in the form, so it is spacing against nothing. */
/* `form.variations_form.cart`, not `form.cart`: WooCommerce sets this margin as
   `.woocommerce div.product form.cart .variations { margin-bottom: 1em }`, which
   is (0,4,2). `body.sf-flow-pdp form.cart table.variations` is (0,3,3) and
   LOSES -- MEASURED, computed margin-bottom stayed 16px with the override
   sitting right there in the matched list. Naming the form's second class makes
   it (0,4,3), which wins without !important. */
body.sf-flow-pdp form.variations_form.cart table.variations { margin-bottom: 0; }
body.sf-flow-pdp form.variations_form.cart { margin-bottom: 0; }
body.sf-flow-pdp .product-details-accordion { margin-top: 24px; }

/* ===========================================================================
   EVERYTHING BELOW IS <= 991 ONLY.
   Every Flow 3 artboard is 390 and the board gives no desktop frame for the
   in-flow setting page (ELEMENTS.md 14.2). At >=992 this template is already a
   two-column layout with its OWN primary control -- MEASURED at 1728,
   `button.select_stone` is `display:none` and the hero sits at [156,64
   934.5x344] beside a summary column at x1133 -- so lifting a hidden button
   into a fixed bar, or taking the site header off a page the board never drew
   at this width, would both be inventions. The desktop page keeps what it has.
   The ONE exception is the Ring-details bar, which 14.1 makes the in-flow
   header at desktop too; its >=992 rule is at the foot of this file.
   =========================================================================== */
/* ---------------------------------------------------------------------------
   THE CHROME SWAP -- 14514:39674's header is a status bar and the Ring-details
   bar. It draws no promo banner, no site menu and no breadcrumb, and the same
   is true of 3.3, 3.4, 3.5 and 3.6: once the shopper is inside the flow the
   flow owns the chrome. That is also why the frame ends on "Continue browsing"
   -- it is the way out the site menu would otherwise have been.

   THIS IS NOT A WIDTH DECISION, so it is no longer inside the <=991 block.
   `sf=1` says "this ring page is being met INSIDE the flow", and what the flow
   owns it owns at every width; ELEMENTS 5 and its conflict A6 read the swap off
   the frame, not off the artboard size. It was width-scoped because the desktop
   page had no way out once the menu went -- and it had none because the footer
   below was `display:none` at >=992. The footer is now a real band at both
   widths and it carries P.31 `Continue browsing`, so the exit exists before the
   menu is taken away.
   MEASURED before at 390: correct (neither present). At 1728: `.da-promo`
   [0,0 1728x43], `header.masthead` [0,43 1728x91] and the breadcrumb
   [144,170 1440x15.4] all painted on the in-flow page.
   MEASURED before at 390 (the original note): the promo strip 390x43 at y0 and
   `header.site-header` 390x61 at y43 pushed the title to 156.8 against the
   board's 64, and the gallery to 253.6 against 142.
   ------------------------------------------------------------------------- */
body.sf-flow-pdp > .da-promo,
body.sf-flow-pdp > header.site-header,
body.sf-flow-pdp > header.masthead,
body.sf-flow-pdp > .site-wide-notification {
    display: none;
}

/* No breadcrumb either. 14514:39674's whole header is 14514:39991 -- the
   status bar and the Ring-details bar -- and the `home / lab diamond` crumb the
   board DOES draw lives on 3.1 and 3.2, the two browse surfaces, not here.
   MEASURED: `nav.woocommerce-breadcrumb` 390x30.8 at y14 plus `#primary`'s own
   14px of padding put the Ring-details bar at 60.8 against the board's 8. */
body.sf-flow-pdp #primary.content-area { padding-top: 0; }
body.sf-flow-pdp nav.woocommerce-breadcrumb { display: none; }

@media (max-width: 991px) {

  /* Ring-details bar -- board 14514:39992 at [12,54 366x40], i.e. 8 under the top
     of the page once the 46px prototype status bar is taken off. The component,
     its classes and its filler are the picker's; this only places it. */
  .sf_flow_pdp_head {
      /* 8 above, then 16 to `ASHA` at board 110 = page 64 (48 + 16). */
      padding: 8px 0 16px;
      background: #FAF3ED;
  }
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details { margin: 0 12px; }

  /* --- TITLE BLOCK -- 14514:39683 / :39687 / :39688 ------------------------
     ASHA        Canela 300 24/30 ls -0.21 UPPER #0F0E0D  [12,110] = page 64
     subtitle    Founders MEDIUM 500 16/16                [12,140] = page 94
     price       Founders 400 16/16                       [12,160] = page 114
     MEASURED before: `h1.product_title` Canela 500 28/33.6 -- the archive's
     display size and weight, four px and two hundred weights off the board. */
  body.sf-flow-pdp h1.product_title {
      font-family: 'Canela', serif;
      font-weight: 300;
      font-size: 24px;
      line-height: 30px;
      letter-spacing: -0.21px;
      text-transform: uppercase;
      color: #0F0E0D;
  }

  /* --- THE FOOTER -- 14514:39993, 390x112 ---------------------------------
     bar    fill #FAF3ED, padding 12/10/10/10, pinned to the bottom
     button 370x44 r4 #27423B, label 16/19 UPPER            [10,5689]
     link   346x28, back arrow + underlined 16/19 #27423B   [22,5741]

     THE BUTTON IS THE PAGE'S OWN. `button.select_stone` is the only control on
     this template wired to open the builder with the held stone, so it is LIFTED
     into the bar rather than proxied: one commit path, and the state contract's
     M8 ("click the visible button.select_stone") still names the same node. */
  .sf_flow_pdp_foot {
      position: fixed;
      left: 0; right: 0; bottom: 0;
      z-index: 60;
      box-sizing: border-box;
      height: 112px;
      padding: 12px 10px 10px;      /* 14514:39993 */
      background: #FAF3ED;
      /* 14514:39994 -- a 370x80 column, gap 8: the 44-tall primary over the
         28-tall link. */
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
  }
  .sf_flow_browse {
      display: inline-flex;
      align-items: center;
      gap: 3px;
      height: 28px;
      font-family: 'FoundersGrotesk', sans-serif;
      font-weight: 400;
      font-size: 16px;
      line-height: 19px;
      letter-spacing: -0.21px;
      color: #27423B;
      text-decoration: underline;
  }
  .sf_flow_browse_arrow { display: inline-flex; align-items: center; }
  .sf_flow_browse_arrow svg { display: block; }

  /* The button is MOVED into the bar by settings-picker.js rather than pinned
     over it. MEASURED with `position: fixed` and z-index 61 against the bar's
     60: `elementFromPoint(195, 820)` returned `.sf_flow_pdp_foot`, i.e. the bar
     painted over the button -- the button sits inside the product summary,
     whose own stacking context is below the bar's, and a z-index inside it
     cannot climb out. Re-parenting keeps the same element, so every listener
     bound to it survives and the state contract's M8 still names this node. */
  /* `display` needs its own, heavier selector: product-single.css carries
     `div:not(.summary):not(.ringbuilder_button_callout) > button.select_stone.jade
     { display: none }` -- specificity (0,4,2) -- and the bar IS a div that is
     not `.summary`, so the moment the button lands in it the theme hides it.
     MEASURED after the move: 0x0 with the label correctly rewritten.
     Two selectors rather than an `!important`, so anything that legitimately
     wants to hide this button still can. */
  /* ...and at 769-991 that is still not enough. product-single.css:172,
     inside its own `@media (min-width: 769px)`, carries
     `div:not(.summary) > button.select_stone.jade { display: block !important }`
     -- an `!important`, which no specificity can beat. MEASURED at 1728 with
     the two selectors below alone: the button read `display: block`, so its
     `gap: 5` and `justify-content: center` were both inert and the trailing
     arrow was a block box on its own line. The only answer to an `!important`
     is an `!important`, and it is narrowed to this bar on this flow. Below 769
     the competing rule does not apply and this changes nothing -- MEASURED at
     390 before and after, `display: flex` either way. */
  body.sf-flow-pdp div.sf_flow_pdp_foot > button.select_stone.jade,
  body.sf-flow-pdp div.sf_flow_pdp_foot > button.select_stone:not(.jade) {
      display: inline-flex !important;
  }
  body.sf-flow-pdp .sf_flow_pdp_foot > button.select_stone {
      box-sizing: border-box;
      width: 370px;
      max-width: 100%;
      height: 44px;
      flex: 0 0 44px;
      margin: 0;
      padding: 0;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 5px;
      border: 0;
      border-radius: 4px;
      background: #27423B;
      color: #FAF3ED;
      font-family: 'FoundersGrotesk', sans-serif;
      font-weight: 400;
      font-size: 16px;
      line-height: 19px;
      letter-spacing: -0.21px;
      text-transform: uppercase;
  }
  /* THE BAR COVERS THE FOOT OF THE PAGE, SO SOMETHING HAS TO CLEAR IT -- BUT
     NOT BETWEEN TWO VISIBLE SECTIONS.
     Owner: *"we still have a gap between the 'love this setting' section and
     the call us + book a consultation + email us."*

     This reserve was on `.content-area`, which only works if that element is
     the last thing on the page -- and it is not, the whole site footer follows
     it. MEASURED at 390: 176px of nothing between the "Love this setting?"
     section and `Call Us / Book a Consultation / Email Us`, while the footer,
     sitting below the reserve, still ended up under the bar at the very end of
     the scroll. The space was being spent in the one place it was not needed
     and withheld from the one place it was.

     On the body it lands after the last thing on the page, which is where the
     bar actually overlaps. 112 is the bar; the 14 is clearance, the same number
     the builder's own sticky band now uses after *"reduce the padding further,
     by 40%"* -- so the two surfaces clear their bars by the same amount instead
     of drifting apart. Nothing below 112 is safe here: the bar is
     `position: fixed`, so a smaller reserve puts the page's last line behind
     it. */
  body.sf-flow-pdp { padding-bottom: 126px; }

  /* ...BUT NOT WHILE THE BUILDER IS OVER THE TOP OF IT.
     Owner, with two screenshots: *"do you see a lot of gap between the sticky
     CTA Continue to Ring Size and the top measurement"* and *"see the gap
     between the sticky bottom bar and the end of the ring size scroller"*.

     The reserve above clears THIS page's `.sf_flow_pdp_foot`. The builder opens
     as a full-screen overlay on the same body and brings its own bar AND its
     own reserve -- `section#simple-select-quiz` carries
     `calc(var(--rb-nav-reserve) + 5)`. Two reserves, one bar.

     MEASURED at 390 x 844 on the back-to-stone slide with Details & Dimensions
     expanded, scrolled to the very end:

       body    padding-bottom  126
       section padding-bottom  107
       .ssq_bottom_nav         102 tall, pinned at y 742
       last line "Measurement" ends at 596   ->  GAP 146

     233px of reserve for a 102px bar, and the 146 that leaves is the empty band
     in both screenshots. The builder's own reserve is the correct one -- it is
     derived from the bar it actually has to clear -- so the page's is dropped
     for as long as the overlay is up. `rb_quiz_open` is written on the body by
     simple-select-redesign.js's syncQuizChrome() off the quiz's visibility, so
     it is already in step with the overlay and needs nothing new to maintain. */
  body.sf-flow-pdp.rb_quiz_open { padding-bottom: 0; }

  /* The trailing arrow: `Vector 138`, a 12x0 shaft stroked 1.25 #FAF3ED with
     SQUARE caps -- the same mark ADD TO RING, CONTINUE TO ENGRAVING and ADD TO
     BAG all carry, so the flow's primaries read as one control. */
  body.sf-flow-pdp .sf_flow_pdp_foot > button.select_stone::after {
      content: "";
      display: block;
      flex: 0 0 auto;
      width: 12px;
      height: 10px;
      background: center / 12px 10px no-repeat
          url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M0.5 5H11M11 5L7 1M11 5L7 9' stroke='%23FAF3ED' stroke-width='1.25' stroke-linecap='square'/%3E%3C/svg%3E");
  }

  /* --- P.6 THE HEART -- 14514:39684 / :39685 -------------------------------
     A 38x34 hit box at [340,110] = page [340,64], holding a 24x22 vector stroked
     1 #3E3C39 -- bigger than 3.2's 22x20 and right-aligned to the 378 gutter.
     The node is the shared `.productFavorite.summary_container`, whose art board
     is 60x40 with an 18.25x16.73 glyph floating inside it. MEASURED here:
     [320,59 60x40] with the glyph at [341,71.6 18.3x16.7] -- 10px low and 2px
     over the gutter. */
  body.sf-flow-pdp .col.position-relative > .productFavorite.summary_container {
      right: 12px;
      display: block;
      width: 38px;
      height: 34px;
      /* the node ships 5px above the title row; 14514:39684 top-aligns with it */
      margin: 5px 0 0 0;
      padding: 0;
      /* CLIPPED, not visible. The glyph is painted by scaling the shared 60x40 art
     board (see the transform below), and a transform enlarges the SCROLL area as
     well as the paint: MEASURED at 390, the <svg> box ran 316.4..395.3 against a
     390 viewport, which is the whole of this page's 5px horizontal scroll --
     document scrollWidth 395 where the same ring without `sf=1` is a clean 390.
     Only empty canvas is cut: the inked path measures 24x22 at 344..368 inside a
     box at 340..378, so it is comfortably inside on every side. */
    overflow: hidden;
  }
  /* heart-icon.svg is a 60x40 viewBox with the glyph floating at (21, 12.6354)
     and measuring 18.25 x 16.73 -- shared with the PDP and the archive, so it is
     scaled here rather than re-cut. Sizing the <svg> to 24x22 shrinks the GLYPH
     with it (MEASURED 7 x 6.7); the art board has to be scaled instead and then
     shifted so the glyph, not the box, lands on the board's [344,112] = page
     [344,66]:
       scale        24 / 18.25            = 1.3151
       glyph x in the scaled board  21   * 1.3151 = 27.62  -> tx = 344 - 340 - 27.62
       glyph y in the scaled board  12.64* 1.3151 = 16.62  -> ty = 66 - 64 - 16.62 */
  body.sf-flow-pdp .col.position-relative > .productFavorite.summary_container svg {
      display: block;
      width: 60px;
      height: 40px;
      transform-origin: 0 0;
      transform: translate(-23.62px, -14.62px) scale(1.3151);
  }
  body.sf-flow-pdp .col.position-relative > .productFavorite.summary_container svg path {
      stroke: #3E3C39;
      stroke-width: 1px;
  }
  /* A SAVED HEART IS TERRACOTTA ALL THE WAY ROUND. Owner, on an in-flow ring
     page: *"the heart has a jade outline -- that's the issue, and I guess it is
     with every other in-flow PDP too."*

     It is, and only on a phone. main.css settles the saved state globally --
     `.productFavorite.selected svg path` paints stroke AND fill #C65858 -- but
     that selector is two classes where the rule directly above is five, so the
     resting #3E3C39 outline wins and never lets go. MEASURED at 390 after a real
     click: `fill rgb(198,88,88)` inside `stroke rgb(62,60,57)` -- a red heart
     ringed in dark green-grey, which is what was reported. At 1440 the override
     is not in scope (this whole block is max-width: 991) and the heart already
     saves correctly in one colour, which is why it reads as a phone bug.

     So the pair is stated here, the same way the stone PDP already states it
     (stone-first.css, "TERRACOTTA, like every other saved heart on the site").
     Only the SAVED state changes; the resting and hover strokes above are
     untouched. */
  body.sf-flow-pdp .col.position-relative > .productFavorite.summary_container.selected svg path,
  body.sf-flow-pdp .col.position-relative > .productFavorite.summary_container.selected:hover svg path {
      stroke: var(--terracotta, #C65858);
      fill: var(--terracotta, #C65858);
  }

  /* --- P.7 / P.8 THE TWO LINES UNDER THE TITLE ----------------------------
     subtitle 14514:39687  Founders MEDIUM 500 16/16  [12,140] = page 94
     price    14514:39688  Founders 400      16/16    [12,160] = page 114
     Both are inside the theme's one `p.price`: `.title-descrption` is the
     subtitle, the amounts and `.setting-only-title-text` are the price line --
     the "(Setting Only)" the board asks for is already there.
     MEASURED before: subtitle 100 (the h1's own 6px bottom margin against the
     board's zero) at 16/17.6, price 122.6 at 19 -- so the pair was 6 and 8.6 low
     and the gallery started at 157.2 against the board's 142. */
  /* product-single.css:123 spends 6 here; 14514:39683 -> :39687 is 0 (title box
     ends 88, subtitle starts 94, and the 6 is the 24-vs-30 line box). */
  body.sf-flow-pdp #product_image_details .col > h1.product_title.entry-title { margin-bottom: 0; }
  body.sf-flow-pdp p.price {
      /* price bottom 132 -> hero 188 on the board is 10; the theme spends 16. */
      margin-bottom: 12px;
      font-size: 16px;
      line-height: 16px;
      letter-spacing: -0.21px;
      color: #0F0E0D;
  }
  body.sf-flow-pdp p.price .title-descrption {
      display: block;
      /* Regular: the Medium cut is not licensed (see .sf_picker_est strong). */
      font-family: 'FoundersGrotesk', sans-serif;
      font-weight: 400;
      font-size: 16px;
      line-height: 16px;
      margin-bottom: 4px;
  }
  body.sf-flow-pdp p.price .woocommerce-Price-amount,
  body.sf-flow-pdp p.price .setting-only-title-text {
      font-size: 16px;
      line-height: 16px;
  }

  /* --- P.9 THE MAIN IMAGE -- [12,188 366x344], r4 -------------------------
     WooThumbs sizes the stack off its tallest slide (the 360 viewer), which
     MEASURED 366x361 here -- 17 over the board and enough to push the thumb rail
     and the metal row with it. Pin the viewport and let every slide fill it, the
     same treatment `stone-first.css` gives the 3.2 hero. */
  body.sf-flow-pdp .iconic-woothumbs-images-wrap,
  body.sf-flow-pdp .iconic-woothumbs-images,
  body.sf-flow-pdp .iconic-woothumbs-images__slide {
      height: 344px;
  }
  body.sf-flow-pdp .iconic-woothumbs-images-wrap { border-radius: 4px; overflow: hidden; }
  /* THE BOX WAS RIGHT AND THE PICTURE INSIDE IT WAS NOT. The wrap MEASURED
     [12,142 366x344] -- board-exact -- but each slide was 361 wide and each
     `img` 361 x 361 inside a 344-tall slide, so the photo sat 5px short of the
     right edge and was cropped 17px by the wrap's own `overflow:hidden`. P.9 is
     `IMAGE ... FILL` on the full 366x344: the slide takes the viewport's width
     and the media fills it with `object-fit: cover`, which is the same
     treatment 3.2's hero already gets in stone-first.css.
     The 360-viewer slide is an <iframe>, which object-fit cannot touch, so it
     is stretched to the box instead. */
  /* WooThumbs' own rule is `flex: 0 0 calc(100% - 5px)` + a matching
     `max-width` on the slide -- the 5px is the sliver of the NEXT slide it
     leaves peeking as a carousel affordance. The board's hero has no peek (the
     "there is more" affordance on this screen is P.12, the 6px of a 7th
     THUMBNAIL), so the slide takes the whole 366. All three declarations have
     to go together -- the `max-width` alone pins it back at 361 -- and the
     plugin's carry `!important`, so these do too. MEASURED: the same three
     without `!important` left the slide at 361; with them, 366. Same reason
     `stone-first.css` marks 3.2's hero `width: 100% !important`. */
  body.sf-flow-pdp .iconic-woothumbs-images .iconic-woothumbs-images__slide {
      width: 100% !important;
      max-width: 100% !important;
      flex: 0 0 100% !important;
  }
  body.sf-flow-pdp .iconic-woothumbs-images__slide > img.iconic-woothumbs-images__image {
      width: 100% !important;
      max-width: none !important;
      height: 344px;
      object-fit: cover;
  }
  body.sf-flow-pdp .iconic-woothumbs-images__slide .iconic-woothumbs-responsive-media,
  body.sf-flow-pdp .iconic-woothumbs-images__slide iframe {
      width: 100%;
      height: 344px;
  }
  /* P.9's stroke: `#FAF3ED` 1.5 INSIDE. 3.2's hero has none (ELEMENTS 5, P.9
     calls the difference out); this one does, and without it the photo runs
     edge to edge against the page ground. */
  body.sf-flow-pdp .iconic-woothumbs-images-wrap {
      box-shadow: inset 0 0 0 1.5px #FAF3ED;
  }

  /* --- P.10 / P.11 / P.12 THE THUMB STRIP ---------------------------------
     Board `image buttons` 14514:39691 @12,535 366x66, `AL:HORIZONTAL gap=8`:
     six 52x52 r4 tiles at x 12/72/132/192/252/312 (pitch 60) and P.12's 7th
     tile at 372, clipped to a 6px sliver by the 366 strip -- the "more"
     affordance that says the rail scrolls.
     MEASURED before at 390: pitch 67 (gap 15), tiles at 12/79/146/213/280/347
     and 414 -- the sixth cut in half at the viewport edge and the seventh
     entirely off screen. gap 8 puts all six inside the strip and leaves the
     sliver exactly where the board draws it.
     P.11 / P.18: thumb 1 is ACTIVE with a 1px INSIDE #27423B stroke and the
     other five are INACTIVE with 1.5px INSIDE #FAF3ED. MEASURED before: every
     tile `box-shadow: none` / `outline: rgb(15,14,13) none 3px` -- no state of
     any kind, so nothing said which view was on screen. Same treatment 3.2
     already ships (stone-first.css), including the <img> case: an <img> cannot
     paint an inset shadow, so the ring is an outline drawn inward. */
  body.sf-flow-pdp .pdp_nav_container {
      display: flex;
      align-items: flex-start;
      /* 6, not 8. Owner: *"spacing can be slightly reduced between cards
         there."* MEASURED at 390: thumbs at x12 / 72 / 132 -- 52 wide, 8 apart. */
      gap: 6px;
      font-size: 0;            /* kills the inline-block whitespace gap */
  }
  /* NO RING ON A RESTING THUMB. Owner: *"there's a weird outline on the ring
     angle image."* Every thumb carried a 1.5px #FAF3ED ring, and pearl on a pale
     photograph is not invisible -- it reads as a box edge, and the ring-angle
     shot is the palest of them. Only the ACTIVE thumb keeps a ring; that is the
     one cue for which image you are on, so it stays.

     This file states the thumb strip TWICE, once per breakpoint, and the >=992
     copy comes later in the file. Changing that one first changed nothing on
     screen at 390 -- it is the desktop rule. Asking the browser which rules
     matched was what settled it; both copies are now explicitly phone and
     desktop rather than "the one lower down". */
  body.sf-flow-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;
  }
  body.sf-flow-pdp .pdp_nav_container > img.pdp_nav {
      box-shadow: none;
      outline: none;
  }
  body.sf-flow-pdp .pdp_nav_container > .pdp_nav.active {
      box-shadow: inset 0 0 0 1px #27423B;
  }
  body.sf-flow-pdp .pdp_nav_container > img.pdp_nav.active {
      box-shadow: none;
      outline: 1px solid #27423B;
      outline-offset: -1px;
  }

  /* --- P.19 / P.20 / P.21 -- THE TWO PANELS -------------------------------
     Board `tabs` 14514:39727 is `@0,704 390x113`, `AL:VERTICAL gap=17
     pad=0/12/0/12`, holding exactly two 366x48 panels -- PRODUCT DETAILS at
     704 and SHIPPING & DELIVERY at 769 -- and it sits IMMEDIATELY under the
     metal swatch row (P.16 ends at 680). Page-space that is y658 and y723,
     because this build has no 46px prototype status bar.

     MEASURED before at 390: the swatch table ended at 700 and the band was
     taken by two rows the board does not draw on this screen --
     `p.affirm-as-low-as` [12,722.2 366x21] and `.pdp-trust-row`
     [12,758.2 366x18] (Insured Shipping / Free Redesign / 60 Day Returns,
     which is 3.2.13's row on the STONE PDP, not this one) -- and
     `.product-details-accordion` started at 823.2 with Product Details already
     `.opened` at 366x776.8, so SHIPPING & DELIVERY landed at 1620, far below
     the 112-tall sticky bar.

     Neither row is deleted -- they are the product page's and this page is the
     product page. They are stood down for the duration of the flow, the same
     way the site menu and the breadcrumb above are, and only under `sf=1`. */
  body.sf-flow-pdp .single_variation_wrap > p.affirm-as-low-as,
  body.sf-flow-pdp .single_variation_wrap > .pdp-trust-row {
      display: none;
  }
  /* 366x48 each, r4, 1px #0F0E0D INSIDE, 17 between. The stroke is INSIDE on
     the board, so the 48 is the outer box: `border-box` or the 1px borders add
     two and the pair walks. MEASURED before: rows 51.8 tall, 20 apart. */
  body.sf-flow-pdp .product-details-accordion > .accordion-row {
      box-sizing: border-box;
      margin-bottom: 17px;
  }
  body.sf-flow-pdp .product-details-accordion > .accordion-row:last-child { margin-bottom: 0; }
  body.sf-flow-pdp .product-details-accordion > .accordion-row:not(.opened) { height: 48px; }
  body.sf-flow-pdp .product-details-accordion > .accordion-row > button.accordion-title {
      box-sizing: border-box;
      height: 46px;
      line-height: 19px;
  }

  /* THE FLOW CHROME IS THE PAGE'S, NOT THE BUILDER'S. Once `button.select_stone`
     opens the quiz, `#simple-select-quiz` draws its own BUILD YOUR RING band, its
     own Ring-details bar and its own footer -- boards 14514:41519 / 41123 / 40420
     -- and the page's copies would be a second set above and below them.
     MEASURED with both up: the quiz heading sat at y64 instead of 0 and every
     block on 3.5 with it. `body.rb_quiz_open` is what simple-select.js stamps. */
  body.sf-flow-pdp.rb_quiz_open .sf_flow_pdp_head,
  body.sf-flow-pdp.rb_quiz_open .sf_flow_pdp_foot {
      display: none;
  }

}

/* The same, unscoped: the builder draws its own header and footer at every
   width, so the page's pair must stand down at every width. Placed after the
   <=991 block and before the >=992 one so it beats the band declared there. */
body.sf-flow-pdp.rb_quiz_open .sf_flow_pdp_head,
body.sf-flow-pdp.rb_quiz_open .sf_flow_pdp_foot {
    display: none;
}

/* >=992 -- the Ring-details bar is the in-flow header at desktop as well
   (ELEMENTS.md 14.1, citing _stone-desktop.css 2's header band). It takes the
   page gutter the rest of this build uses at 1728: 80 / 1728 = 4.6296296296%,
   content 1568. MEASURED without it: 1728 wide at x12, full-bleed. */
@media (min-width: 992px) {
  /* OWNER on this screen: the Ring Details bar "touches the gallery and the top
     of the Twist Halo heading -- give some space", and it must be "limited to
     just the gallery width, not full width", with "Continue Browsing" above it
     rather than in the bottom bar.

     MEASURED at 1728 before: head 1728x64 with `padding: 24px 0 0`, the bar
     80..1648 (the FULL 1568 content width), #product_image_details starting at
     y64 immediately under it, and h1.product_title at y49 -- ABOVE the row it
     belongs to, because product-single.css gives it `margin: -15px 0 0` and the
     negative margin pulled the heading up into the bar. Two different things
     touching, one gap. */
  body.sf-flow-pdp { --sf-flow-bar-h: 40px; --sf-flow-head-gap: 24px; }
  body.sf-flow-pdp .sf_flow_pdp_head { padding: 24px 0 var(--sf-flow-head-gap); }

  /* RING DETAILS PAINTS OVER THE GALLERY, NOT UNDER IT.
     Owner: *"when I expand the ring details and hover on the top row images,
     the image re-overlaps ring details -- can this be avoided? ... or even
     better, it does not overlap ring details."* The second option, because it
     keeps the zoom working everywhere instead of switching it off on two tiles
     under one condition.

     It is a paint-order problem and not really a zoom problem. MEASURED on the
     in-flow PDP: `#product_image_details` is `position: relative; z-index: 2`,
     while this band was `position: static; z-index: auto` -- so the gallery wins
     against it by the stacking rules alone, whatever the images are doing. The
     expanded panel sits in the same band and overflows it (the band is 96 tall,
     the open panel reaches ~170), and the first tile starts at y96, flush under
     it; magnifying a tile grows it upward into exactly that overlap, and since
     the slide is `overflow: visible` there is nothing to clip it.

     Giving the band its own stacking context above 2 settles both the hover and
     the open panel in one declaration. It is scoped to `body.sf-flow-pdp`, so
     ordinary product pages -- which have no such band -- are untouched. */
  body.sf-flow-pdp .sf_flow_pdp_head {
      position: relative;
      /* 10000, AND THE NUMBER IS NOT ARBITRARY.
         The first pass at this used 3, reasoning only against
         `#product_image_details` (`position: relative; z-index: 2`). That was
         right about the gallery and wrong about the magnifier, which is a
         different element entirely: WooThumbs' zoom paints into `.zm-viewer`,
         declared `position: absolute; z-index: 9999` in the plugin's own
         imagezoom.css. A band at 3 cannot cover a 9999 overlay, so the fix
         changed nothing on hover -- which is exactly what the owner reported
         back after it shipped.

         Sitting one above that overlay is the whole requirement. The band is a
         96px strip at the top of the page; nothing else on this surface
         competes for that range, and the value is scoped to `body.sf-flow-pdp`
         so no ordinary product page inherits it. */
      z-index: 10000;
  }

  /* THE DESCRIPTION COLUMN STARTS WHERE RING DETAILS STARTS.
     Owner: *"the description there is a lot of space overhead -- nah, it must
     start same as ring details."* The head is a full-width band, but the BAR
     inside it is only the gallery's 48.477% (rule below), so the right half of
     that band was empty and the description began 64px lower than the bar it is
     read alongside. MEASURED at 1728: bar top 58, `.summary.entry-summary` top
     122.

     64 is not a guess and not typed twice: it is the bar's own height plus the
     head's bottom padding, the two things between the bar's top edge and the
     row below -- both declared immediately above, so if either moves the pull-up
     moves with it.

     Safe because the band's right half holds nothing: the bar stops at x840 and
     the summary starts at x900, so nothing can overlap. The GALLERY is left
     where it is -- only the column with the empty space above it moves.

     APPLIED further down this file, on the
     `.col.position-relative > .summary.entry-summary` rule -- that one is later
     and heavier, so a margin written here lost to its `margin: 0`. */

  /* AND IT DOES NOT END FLUSH EITHER. `Shipping & Delivery` is the accordion's
     last row and its bottom edge sat ON the bordered box's bottom edge --
     MEASURED, both at 1125 -- so the row "touches bottom" with no inner space
     at all. Scoped to the flow: the ordinary ring page keeps whatever it
     shipped with. */
  body.sf-flow-pdp #product_image_details .summary.entry-summary .product-details-accordion {
    padding-bottom: 24px;
  }
  /* The gutter moves onto the WRAP so the bar's own width can be a percentage
     of the content box (1568) rather than of the viewport -- which is what lets
     it use the product grid's own track value below and track it at any width. */
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_wrap {
    padding: 0 4.6296296296%;
  }

  /* =========================================================================
     NEITHER COLUMN MOVES WHEN RING DETAILS OPENS
     -------------------------------------------------------------------------
     Owner, circling the empty space above the ring's title: *"the title +
     content must not move when ring details are expanded."*

     The head is a full-width band ABOVE the two-column product row, so its
     height is the row's starting line. MEASURED at 1728, collapsed -> expanded:

       .sf_flow_pdp_head     96 tall  ->  192
       gallery (left)        top  96  ->  192
       .summary (right)      top  32  ->  128

     -- the right column was pushed by exactly the band's growth, 96px, for a
     panel that belongs to the left.

     So the band keeps its collapsed height and the panel is allowed out of it:
     96 = 24 top padding + the 48 bar + 24 bottom. `overflow: visible` so the
     panel is not clipped by the height that is now fixed, and the wrap takes a
     stacking order so it paints over the gallery beneath rather than under it.

     The panel also takes an opaque ground here. Its own
     `rgba(228,222,216,0.6)` was mixed against the page's #FAF3ED while it sat
     in the band; over the gallery's white it would read as a different colour,
     so the blend is baked: 0.6 x (228,222,216) + 0.4 x (250,243,237) = #EDE6E0.
     ========================================================================= */
  body.sf-flow-pdp .sf_flow_pdp_head {
    height: 96px;
    overflow: visible;
  }
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_wrap {
    position: relative;
    z-index: 5;
  }
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_panel {
    background: #EDE6E0;
  }
  /* 48.477157360406% is not a number chosen here: it is the first track of
     `#product_image_details .col.position-relative` declared further down this
     file, so the bar is exactly as wide as the gallery under it and stays that
     way if the split ever changes. */
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details,
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_panel {
    width: 48.477157360406%;
    margin: 0;
  }
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_panel.is-open {
    margin: -2px 0 0;
    /* AIR UNDER THE HEADING. Owner: *"ring details when expanded does not have
       space between the heading and content."* MEASURED with the panel open:
       the toggle's baseline box ends at 87 and the first row ("Stone") started
       at 96 -- 9px, against the 10 the bar already keeps under the toggle when
       it is closed, so the row read as glued to the heading it belongs under.
       The panel's own 2px top padding is what was carrying it. */
    padding-top: 14px;
  }
  /* The heading stops riding up into the bar. Zeroed only in this flow -- the
     -15px is product-single.css's and every ring page outside `sf=1` keeps it. */
  /* BOTH copies: the template prints an h1 as a direct child of the grid AND
     one inside .summary.entry-summary, and at this width it is the SUMMARY one
     that is visible -- MEASURED, the grid child is display:none at 0x0 while the
     summary child renders at x900. A rule written for the direct child alone
     matched the hidden one and left the visible heading still riding 15px up
     into the bar. */
  body.sf-flow-pdp #product_image_details .col.position-relative > h1.product_title.entry-title,
  body.sf-flow-pdp #product_image_details .summary.entry-summary > h1.product_title.entry-title {
    /* !important because it is answering one: the theme ships
       `h1.product_title.entry-title { margin-top: -15px !important }`, which no
       specificity beats -- found by asking the engine which rule won rather than
       by adding weight to a selector that was already heavy enough. */
    margin-top: 0 !important;
  }
  /* "Continue browsing" ABOVE the bar. The link is the one the footer already
     ships (`.sf_flow_browse`, da-settings-picker.php:349) -- settings-picker.js
     moves the node rather than printing a second one, so the delegated
     `[data-sf-open-settings]` handler that re-opens the picker comes with it.
     Same gutter as the bar, so the two share a left edge. */
  body.sf-flow-pdp .sf_flow_pdp_head > .sf_flow_browse {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0 4.6296296296% 14px;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #27423B;
    text-decoration: underline;
  }
  body.sf-flow-pdp .sf_flow_pdp_head > .sf_flow_browse .sf_flow_browse_arrow {
    display: inline-flex;
    align-items: center;
  }
  /* the foot is only ever this link at desktop -- `button.select_stone`, the
     other thing positioned into it, is display:none above 991 */
  body.sf-flow-pdp .sf_flow_pdp_foot:empty { display: none; }
  /* ------------------------------------------------------------------------
     P.30 AT DESKTOP -- THE FLOW'S ONE UNREACHABLE SCREEN.
     This rule used to read `display: none`, on the reasoning that the desktop
     template has its own primary control. It does not: MEASURED at 1728, EVERY
     `button.select_stone` on this page is 0x0 -- the one in `.summary` is
     `display:none` from product-single.css and the one in
     `.ringbuilder_button_callout` is `display:block` with no box -- and
     `#simple-select-quiz` stayed `display:none` after clicking any of them. So
     at >=992 there was no way into the builder at all and 3.4, 3.5 and 3.6
     were unreachable. The whole quiz, at desktop, behind one `display:none`.

     The band is the one ELEMENTS 14.1 names for this screen, verbatim: "Board
     gives nothing for: whether the sticky bottom bar stays sticky at desktop or
     becomes an in-column button block. 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." It is the same band 3.1.43 and 3.2.26 already wear at this width, to
     the same numbers -- 120 tall, #FAF3ED, a 1px #E4DED8 top rule, pad
     28/gutter/10, the cluster right-aligned with gap 36 -- so the three screens
     read as one footer rather than three. Carried up from the BYR sheet, not
     designed; the board draws no desktop frame for this screen.
     ------------------------------------------------------------------------ */
  body.sf-flow-pdp .sf_flow_pdp_foot {
      display: flex;
      position: fixed;
      left: 0; right: 0; bottom: 0;
      z-index: 60;
      box-sizing: border-box;
      /* 100/24 -- see the note on `.ssq_bottom_nav` in _stone-desktop.css
         section 6; the horizontal gutter is deliberately kept. */
      height: 100px;
      padding: 24px 4.6296296296%;
      flex-direction: row;
      align-items: flex-start;
      justify-content: flex-end;
      gap: 36px;
      background: #FAF3ED;
      border-top: 1px solid #E4DED8;
  }
  /* Same two selectors as the <=991 block, and for the same reason:
     product-single.css hides `button.select_stone` inside any div that is not
     `.summary` / `.ringbuilder_button_callout` at (0,4,2), and the bar is such
     a div. */
  body.sf-flow-pdp div.sf_flow_pdp_foot > button.select_stone.jade,
  body.sf-flow-pdp div.sf_flow_pdp_foot > button.select_stone:not(.jade) {
      display: inline-flex !important;   /* see the <=991 twin: beats product-single.css:172 */
  }
  body.sf-flow-pdp .sf_flow_pdp_foot > button.select_stone {
      order: 2;
      box-sizing: border-box;
      /* 282 x 48 -- the button box 3.1.43 and 3.2.26 already use in this band. */
      width: 282px;
      flex: 0 0 282px;
      height: 48px;
      margin: 0;
      padding: 0;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 5px;
      border: 1px solid #27423B;
      border-radius: 4px;
      background: #27423B;
      color: #FAF3ED;
      font-family: 'FoundersGrotesk', sans-serif;
      font-weight: 400;
      font-size: 16px;
      line-height: 19px;
      letter-spacing: -0.21px;
      text-transform: uppercase;
      cursor: pointer;
  }
  /* `Vector 138`, the 12x0 shaft stroked 1.25 #FAF3ED with SQUARE caps. */
  body.sf-flow-pdp .sf_flow_pdp_foot > button.select_stone::after {
      content: "";
      display: block;
      flex: 0 0 auto;
      width: 12px;
      height: 10px;
      background: center / 12px 10px no-repeat
          url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10' fill='none'%3E%3Cpath d='M0.5 5H11M11 5L7 1M11 5L7 9' stroke='%23FAF3ED' stroke-width='1.25' stroke-linecap='square'/%3E%3C/svg%3E");
  }
  /* P.31. Left of the primary in the band, vertically centred on it -- the
     order the other two screens use. */
  body.sf-flow-pdp .sf_flow_pdp_foot > .sf_flow_browse {
      order: 1;
      /* CENTRED ON THE BUTTON, NOT ON THE BAND. `align-self: center` centres
         the link in the flex CONTENT box, which this band pads 28 top and 10
         bottom -- so the link sat at the content box's middle while the button,
         held by the band's `align-items: flex-start`, sat at its top. MEASURED
         at 1728 and 1440: button centre 1033, link centre 1049.5, 16.5px apart.
         Owner: *"continue browsing does not align with continue to ring
         size"*. Same start edge and the same 48px box as the button, with the
         link's own `align-items: center` centring the text inside it, puts both
         centres on one line at every width rather than at one. */
      align-self: flex-start;
      display: inline-flex;
      align-items: center;
      gap: 3px;
      height: 48px;
      margin: 0;
      font-family: 'FoundersGrotesk', sans-serif;
      font-weight: 400;
      font-size: 16px;
      line-height: 19px;
      letter-spacing: -0.21px;
      color: #27423B;
      text-decoration: underline;
  }
  body.sf-flow-pdp .sf_flow_pdp_foot > .sf_flow_browse .sf_flow_browse_arrow { display: inline-flex; align-items: center; }
  body.sf-flow-pdp .sf_flow_pdp_foot > .sf_flow_browse .sf_flow_browse_arrow svg { display: block; }
  /* the fixed band has to be scrollable clear of at desktop too */
  body.sf-flow-pdp .content-area { padding-bottom: 144px; }

  /* ------------------------------------------------------------------------
     THE COLUMN MODEL -- ONE BAND, TWO COLUMNS, THREE THINGS ON THE SAME x.
     The board draws no desktop frame for this page; ELEMENTS 14.1 names
     `_stone-desktop.css` 3 (left preview column) and 4 (`Customization`, the
     right column) as what to borrow, on the 6/6 split the STONE screens use.

     MEASURED before at 1728, three different left edges on one screen:
       .sf_flow_pdp_head .sf_picker_details   [  80, 24 1568x40]   <- page gutter
       #product_image_details > .container    [ 144, 64 1440x...]  <- bootstrap
       .iconic-woothumbs-all-images-wrap      [ 156, 64  934.5]    <- +12 pad
       .summary.entry-summary                 [1133, 84   439]     <- ragged
     So the Ring-details bar started 64px left of the picture under it and the
     right column was 439 wide against the 752 the model gives.

     Everything below puts the product section on the SAME 1568 content band the
     bar uses -- 80 / 1728 = 4.6296296296% each side -- and splits it with
     `_stone-desktop.css`'s own tokens: left 48.477157360406%, gutter
     3.807106598985%, right 47.715736040609%. At 1728 that is 760 / 60 / 748,
     i.e. the model's 764-at-x70 / 752-at-x894 pair resolved on an 80px gutter
     instead of the quiz's 70. Percentages, not pixels, so it holds down to 992
     the way both desktop sheets do.

     `.col.position-relative` holds BOTH columns plus the wishlist heart, which
     is absolutely positioned, so the split is a two-track grid on that element
     rather than a reflow of the markup: nothing moves in the DOM and every
     handler the product template binds keeps its node. */
  body.sf-flow-pdp #product_image_details > .container {
      width: 100%;
      max-width: none;
      padding-left: 4.6296296296%;
      padding-right: 4.6296296296%;
      margin-left: 0;
      margin-right: 0;
  }
  body.sf-flow-pdp #product_image_details > .container > .row { margin-left: 0; margin-right: 0; }
  body.sf-flow-pdp #product_image_details .col.position-relative {
      display: grid;
      grid-template-columns: 48.477157360406% 47.715736040609%;
      column-gap: 3.807106598985%;
      align-items: start;
      padding-left: 0;
      padding-right: 0;
  }
  /* h1, price and the gallery are the left column; the summary is the right
     one. Explicit placement, because the heart is `position:absolute` and an
     auto-placed grid would still reserve a track for it. */
  body.sf-flow-pdp #product_image_details .col.position-relative > h1.product_title.entry-title,
  body.sf-flow-pdp #product_image_details .col.position-relative > p.price,
  body.sf-flow-pdp #product_image_details .col.position-relative > .iconic-woothumbs-all-images-wrap {
      grid-column: 1;
      width: 100%;
      max-width: 100%;
  }
  body.sf-flow-pdp #product_image_details .col.position-relative > .summary.entry-summary {
      grid-column: 2;
      /* ROW 1, AND ONLY ROW 1. This used to read `1 / span 20`, which was
         written to stop a summary taller than the gallery being clipped -- it
         cannot be clipped, a grid row grows to its content, and the span bought
         nothing. What it DID buy was 19 implicit rows after the gallery's,
         sized by the spanning-item distribution algorithm and empty: MEASURED
         at 1728 and 1440 as a 950px void between the last gallery image and
         `Origin and Craftsmanship` (gallery bottom 2568 against an images
         bottom of 1618). Owner: *"there's a lot of gap after gallery.. and the
         next section reduce that make it look nice and continuous"*.
         One row now, sized to whichever column is taller, so the section ends
         30px under the last image -- the images wrap's own margin -- and the
         next section starts there. */
      grid-row: 1;
      width: 100%;
      max-width: 100%;
      /* THE DESCRIPTION COLUMN STARTS WHERE RING DETAILS STARTS -- see the
         head block above for the why and for where the two values come from.
         It is set HERE rather than beside that block because THIS rule is the
         one that wins: it is later in this same file and one selector heavier,
         so a `margin-top` written up there computed to 0. Asked the engine
         which rule won instead of adding weight to the losing one. */
      margin: calc(-1 * (var(--sf-flow-bar-h) + var(--sf-flow-head-gap))) 0 0;
      padding: 0;
      /* AND IT IS NOT STICKY IN THE FLOW. product-single.css:94 gives every
         product page `position: sticky; top: 180px` on this column. Sticky
         clamps an element that would sit ABOVE its `top` offset DOWN to it, so
         the pull-up above landed the column at 58 and sticky put it straight
         back to 180 -- which is exactly what MEASURED at 1280 (y180) while 1728
         happened to be past the clamp and looked correct. One symptom, two
         widths, and the margin was innocent at both.

         Static also answers "there must be no scroll within the gallery and the
         side description bar": sticky is what let this column travel against
         the gallery as the page moved. The rule is scoped to `sf-flow-pdp`, so
         every ordinary ring page keeps its sticky summary. */
      position: static;
  }
  body.sf-flow-pdp #product_image_details .col.position-relative > .productFavorite.summary_container {
      grid-column: 2;
      grid-row: 1;
  }

  /* P.11 / P.18 at desktop. The states are the picture's, not the viewport's --
     the strip is the same six tiles at either width and MEASURED before with no
     active or inactive treatment at 1728 either. */
  body.sf-flow-pdp .pdp_nav_container { gap: 8px; }
  body.sf-flow-pdp .pdp_nav_container > .pdp_nav {
      border-radius: 4px;
      box-sizing: border-box;
      box-shadow: inset 0 0 0 1.5px #FAF3ED;
  }
  body.sf-flow-pdp .pdp_nav_container > img.pdp_nav {
      box-shadow: none;
      outline: 1.5px solid #FAF3ED;
      outline-offset: -1.5px;
  }
  body.sf-flow-pdp .pdp_nav_container > .pdp_nav.active { box-shadow: inset 0 0 0 1px #27423B; }
  body.sf-flow-pdp .pdp_nav_container > img.pdp_nav.active {
      box-shadow: none;
      outline: 1px solid #27423B;
      outline-offset: -1px;
  }
}

/* >=992 -- the drawer's own toolbar, borrowed from the screen it mirrors.
   _advanced-search-desktop.css 2 puts every control in that band at 44 tall
   (mobile 40/36) and drops the segmented radius from 10 to 8. ELEMENTS.md 14.1
   says 3.3 wears the same archive chrome, so the two read as one control set.
   MEASURED before at 1728: segmented 267x36 r10, Filters 89x36. */
@media (min-width: 992px) {
    #sf_settings_picker .sf_picker_seg { height: 44px; border-radius: 8px; }
    /* 3.3.11 at desktop. ELEMENTS 14.1 sizes every control in that band off
       `_advanced-search-desktop.css` 2, where the Filters pill is `116 x 44` at
       x80 -- the HEIGHT was lifted here already, the WIDTH was not, so the pill
       kept its 390 box (89) on a 44-tall row and read narrow beside a 267-wide
       segmented control. MEASURED before at 1728: 89x44 at x357. */
        /* 132 AND 264: one control width across the band. The pill was 116 beside a
       267 track whose halves were 133.5, i.e. three numbers in a row of three.
       264 is 2 x 132, and the track's stroke is an INSET shadow rather than a
       border, so it takes no layout width off the halves. */
    #sf_settings_picker .sf_picker_seg { width: 264px; }
    #sf_settings_picker .sf_picker_filters { width: 132px; height: 44px; }

    /* THE TWO CONTROLS SWAP SIDES AT DESKTOP, BECAUSE 3.1 DOES.
       ELEMENTS 14.1 pins the desktop archive chrome as "Filters pill 116 x 44
       at x 80" and tells 3.3 to borrow 3.1's chrome wholesale. 3.1 at 1728
       MEASURED Filters at x80 and the segmented control at x1382; 3.3 mirrored
       its own 390 order instead -- segmented x80, Filters x357 -- so the two
       grids that share one component read as opposite layouts. Order only: the
       markup, the tab semantics and the 390 layout are untouched. */
    #sf_settings_picker .sf_picker_filters { order: 1; }
    #sf_settings_picker .sf_picker_seg { order: 2; margin-left: auto; }
}

/* ===========================================================================
   RING DETAILS -- the panel the bar opens.
   The bar had a chevron and a toggle and opened nothing: measured at 390 and
   1728, aria-expanded stayed "false" and no panel existed. Shape mirrors the
   quiz's .rb_details_panel so the two read as one component.
   =========================================================================== */
/* THE YES-PROMISE BAND'S BUILD YOUR RING GOES TOO.
   Owner, in the same breath as the "love this setting" section: *"remove the
   Build Your Ring CTA in the yes-promise section."* Same reasoning -- it is an
   invitation into a builder the shopper is already inside.

   MEASURED on the in-flow page, scrolled to the end: the only visible control
   with that label is `button.da-guarantee__cta` in
   `.da-guarantee__intro-foot` (da-guarantee.php:115) -- 438x56 at 1440 and
   320x56 at 390. The `.ringbuilder_button_callout` that also carries the words
   is inside the commitment popup SOURCE and measures 0x0 on both, so it was
   never the one on screen.

   CSS, not a `remove_action`, and that is the honest reason: this is markup
   inside a component, not a hooked callback, so there is nothing to unhook. It
   costs no query and no image -- a button and an inline SVG -- which is why the
   cost argument that keeps the three sections above as real removals does not
   apply. The fine-print that shares the foot stays, which is the rest of what
   that group is for.

   Unwrapped: the band and the button exist at both widths. */
body.sf-flow-pdp .da-guarantee__intro-foot > .da-guarantee__cta {
    display: none;
}

.sf_picker_details_wrap { width: 100%; }

.sf_picker_details_toggle { cursor: pointer; }
.sf_picker_chevron { display: inline-flex; transition: transform 200ms ease; }
.sf_picker_details.is-open .sf_picker_chevron { transform: rotate(180deg); }

/* SMOOTH OPEN/CLOSE -- the same gesture as the quiz's own Ring Details bar.
   Owner: *"add smooth motion for ring details dropdown -- it must be smooth like
   how in the normal BYR flow it is"*. That one is
   _stone-desktop.css:494-2675, and its lesson is recorded there: the panel
   ships with the `hidden` attribute, so `[hidden]{display:none}` pulled it OUT
   OF FLOW in the same frame the class changed and the height had nothing left
   to shrink THROUGH -- it snapped. Captured there frame by frame:
   t=0 panelH=119, t=20ms panelH=0.

   So the panel is kept in flow and clipped by its own `overflow: hidden`
   instead, with `visibility` doing the actual hiding on a delay so it is still
   painted for the length of the collapse.

   `interpolate-size: allow-keywords` is what makes `height: 0 -> auto`
   interpolate at all; without it a transition alone snaps exactly as before.
   It is declared here rather than inherited -- this panel is outside
   `.ssq_all_stone_options`, which is where the quiz declares its own.

   `display: block !important` because it is answering one: bootstrap ships
   `[hidden]{display:none!important}`, which no specificity beats. */
.sf_picker_details_panel[hidden] { display: block !important; }
.sf_picker_details_panel {
    overflow: hidden;
    height: 0;
    visibility: hidden;
    background: rgba(228, 222, 216, 0.6);
    border-radius: 0 0 4px 4px;
    /* the -2px overlap belongs to the OPEN state: on a 0-height collapsed panel
       it would just pull the next sibling up 2px, which it never did while this
       was display:none */
    margin: 0 12px;
    padding: 0 9px;
    interpolate-size: allow-keywords;
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1),
                padding 260ms cubic-bezier(0.4, 0, 0.2, 1),
                margin 260ms cubic-bezier(0.4, 0, 0.2, 1),
                visibility 0s linear 260ms;
}
.sf_picker_details_panel.is-open[hidden],
.sf_picker_details_panel.is-open {
    display: block !important;
    height: auto;
    visibility: visible;
    margin: -2px 12px 0 12px;
    padding: 2px 9px 10px 9px;
    transition: height 260ms cubic-bezier(0.4, 0, 0.2, 1),
                padding 260ms cubic-bezier(0.4, 0, 0.2, 1),
                margin 260ms cubic-bezier(0.4, 0, 0.2, 1),
                visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
    .sf_picker_details_panel,
    .sf_picker_details_panel.is-open { transition: none; }
}

.sf_picker_details_rows { display: flex; flex-direction: column; gap: 6px; }
.sf_picker_details_row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0;
    /* Owner, pasting the rule back with this line added: *"this looks good."*
       On top of the 6px the `.sf_picker_details_rows` stack already contributes,
       so the rows sit 18 apart and the first one clears the panel's top edge by
       12. Taken as given rather than redistributed between the two -- it is the
       value that was looked at. */
    padding-top: 12px;
}
/* Stone above Setting: the board's expanded state is the stone-first reading --
   the stone is what the shopper has, the setting is what they are choosing. */
.sf_picker_details_row[data-sf-row="stone"]   { order: 1; }
.sf_picker_details_row[data-sf-row="setting"] { order: 2; }

.sf_picker_row_text { display: flex; flex-direction: column; min-width: 0; }
.sf_picker_row_label {
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px; line-height: 16px; letter-spacing: -0.21px; color: #0F0E0D;
}
.sf_picker_row_desc {
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 12px; line-height: 16px; letter-spacing: -0.21px; color: #3E3C39;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sf_picker_row_value {
    flex: 0 0 auto;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px; line-height: 16px; letter-spacing: -0.21px; color: #0F0E0D;
}

/* THE PANEL IS AS WIDE AS THE BAR IT HANGS OFF. Owner: *"in the stone flow,
   after Add to Ring, the Ring Details when expanded does not match the width of
   the bar in the engagement ring selection drawer."*

   MEASURED in the picker, both widths:
     390    bar  margin 0 12px        x12  w366   panel margin -2px 12px 0  x12  w366   match
     1440   bar  margin 24px 0 0      x67  w1307  panel margin -2px 12px 0  x79  w1283  12px in on each side

   The 12 is the PHONE gutter: the bar carries it there too, so the pair agrees.
   On desktop the bar's gutter comes from its wrapper instead and its own side
   margins are 0, leaving the panel's 12 with nothing to match.

   The rule below already said so -- and was inert, because `.is-open` restates
   the full `margin` shorthand at (0,2,0) and re-applies the 12 the moment the
   panel opens, which is the only state anyone sees. Both states are zeroed here
   now, at the specificity the open rule carries. */
@media (min-width: 992px) {
    .sf_picker_details_panel,
    .sf_picker_details_panel.is-open[hidden],
    .sf_picker_details_panel.is-open { margin-left: 0; margin-right: 0; }
}

/* =============================================================================
   NO CLOSE CROSS IN THE PICKER'S TITLE ROW
   -----------------------------------------------------------------------------
   Owner: *"there's a cross beside the 70 results text, to the right of it --
   remove it, we don't want it."*

   `.sf_picker_close` sits immediately after `.sf_picker_count` in
   `.sf_picker_titlerow` (da-settings-picker.php:389), which is exactly that
   position. It is also not the board's: its own comment records it as
   *"H.9's close, borrowed ... the one node on 3.3 with no frame behind it"*,
   and the sheet's header note at :237 says the frame gives the shopper
   "Continue browsing" as the way out. So this removes a borrowed control and
   leaves the designed one.

   The exits that remain: `.sf_flow_browse` ("Continue browsing",
   da-settings-picker.php:325), printed at every width and the board's own
   answer, and the Escape key (settings-picker.js:564). Nothing is trapped.

   `display: none` rather than deleting the markup: the button keeps its
   `[data-sf-close]` handler wired for anything that triggers it
   programmatically, restoring it is one declaration, and a hidden button is out
   of the tab order, which `visibility` would not guarantee. */
/* ...AND IT IS BACK, AT THE SHEET'S CORNER. Owner: *"there is no CROSS EXIT
   button on the engagement ring list drawer in the stone flow."*

   That reverses the instruction above, and it is the newer one. What it does
   NOT reverse is why the old one was raised: the cross was objected to sitting
   *beside the count*, which is where the borrowed markup put it. So it is shown
   again and taken out of that row entirely -- absolute against the sheet, at its
   top-right corner, which is where every other drawer in this flow puts its
   close and where a shopper looks for one.

   The title row keeps the box it measured without the button, because an
   absolute element leaves no gap behind it: the count stays at the board's
   321..378 instead of being pushed back to 285. "Continue browsing" and Escape
   are unchanged; this is a third exit, not a replacement.

   NO `position: relative` ON THE SHEET. This block used to carry one, to give
   the absolute close a containing block -- and it broke the drawer twice over.
   Owner: *"can't scroll in the engagement rings drawer list... also the
   animation is weird, greatly weird."*

   MEASURED at 390 with the drawer open: `.sf_picker_sheet` computed
   `position: relative`, height 4376px. The sheet is declared at :34 as
   `position: absolute; inset: 0` -- that is what pins it to the fixed
   full-viewport `#sf_settings_picker` and gives `.sf_picker_body`'s
   `flex: 1 1 auto; overflow-y: auto` a bounded column to scroll inside.
   Re-stating `position: relative` dropped the `inset: 0` pinning, so the sheet
   grew to its whole content height; the picker then measured scrollHeight 4376
   against clientHeight 844 with `overflow: visible`, i.e. 3,500px of cards
   spilling out of a fixed box that nothing can scroll.

   The animation report is the same bug seen from the other side:
   `transform: translateY(100%)` on a 4376px-tall sheet travels 4376px, not the
   844 the transition was written for -- five screens of slide in 320ms.

   And the override was never needed: an absolutely-positioned element is
   already a containing block for its absolute descendants, so the close finds
   its corner off the untouched `inset: 0` sheet. */
/* ...AND OFF AGAIN. Owner: *"on the phone screen, on the engagement rings list
   drawer, remove the cross -- it kinda overlaps on the ring details bar."*

   MEASURED at 390 with the drawer open, and the overlap is real, not marginal:
   the cross occupied [346,16] 28x28, i.e. y16-44, while `.sf_picker_details`
   -- the Ring-details bar -- occupies [12,8] 366x40, y8-48. A rectangle
   intersection test on the pair returns true. The corner the cross was moved to
   is inside that bar, because the bar is the first thing on the sheet (the board
   starts the header stack with it at +8) and spans nearly the full width.

   There is no free corner to move it to without pushing the bar down and
   breaking the 135px header stack the board measures, so it goes back to being
   hidden rather than relocated. The exits the frame does ship are unaffected:
   `.sf_flow_browse` ("Continue browsing"), which the sheet's own header note at
   :237 calls the designed way out, and the Escape key (settings-picker.js:564).
   Nothing is trapped.

   `display: none` rather than deleting the markup, for the same reasons as the
   first time: the button keeps its `[data-sf-close]` handler for anything that
   triggers it programmatically, a hidden button is out of the tab order, and
   restoring it is one declaration. */
.sf_picker_titlerow .sf_picker_close {
    display: none;
}

/* =============================================================================
   THE FILTERS PANEL -- Figma 14621:48072 "DIAMOND FLOW Filters for ER"
   -----------------------------------------------------------------------------
   The first build of this predates the frame and did not match it: a full-width
   band inlined under the tabs (MEASURED at 1440: x67 w1307, a 1307-wide strip
   against the frame's 345 column) with a Reset / Show results row.

   Read off the frame:
     sheet          390 x 870, r40, fill #FAF3ED
     content column 345 wide, groups stacked
     group heading  344 x 31
     chips          110 x 42, r8
                      resting   fill none,            stroke #E4DED8
                      selected  fill #C2CEB2 @0.30,   stroke #27423B
     action bar     390 x 106 holding one 344 x 60 button, r4, fill #27423B,
                    label "VIEW 75 RESULTS" (live number)

   The frame is a PHONE sheet and says nothing about desktop. Rather than
   stretch it to 1307 again, the same column is used at both widths and anchored
   under the Filters pill on desktop -- the frame's own geometry, placed where
   the control that opens it is. Phone keeps it in flow beneath the tabs, which
   is where a 390 sheet already sits.

   Owner's notes, all three: a chip toggles OFF on a second tap (the handler
   already works that way); nothing selected means every style, which is what an
   empty `styles` param asks the server for; and no fancy shapes here -- this
   drawer offers STYLE only, because the shape is pinned by the held stone. The
   shape group belongs to a basic-ER drawer that does not exist yet.
   ============================================================================= */
/* -----------------------------------------------------------------------------
   HOW IT OPENS -- two surfaces, not one panel squeezed into two widths.

   Owner: *"make it like the diamond flow's. On phone, like a drawer. And on
   desktop, on click it must show at the top, and after selecting it must go up
   again -- full width of the container."*

   Desktop: in FLOW under the toolbar, the full width of the picker head, so it
   pushes the grid down and lifts back off it. The previous build anchored a
   377px card under the pill, which is the frame's phone column parked in the
   top-right corner of a 1728 drawer -- "why the fuck do the filter buttons look
   like that". settings-picker.js closes it on the first pick at this width.

   Phone: a FULL-SCREEN drawer. Owner: *"and this is a FULL SCREEN DRAWER."*
   14621:48072 is 390 x 870 -- a whole phone, not a sheet lying on top of one:
   its own `header` group (14621:48510) carries a 46 status bar and the 52 top
   bar 14621:48525, and the 106 action band sits on the bottom edge. The r40 and
   the 8px black stroke on that frame are the DEVICE MOCK, which is why this
   build read them as a sheet's leading corners and shipped `bottom: 0;
   max-height: 86vh` with a grab handle. It stays open until VIEW n RESULTS,
   because there the drawer IS the screen.

   The open is animated, the close is not: the panel is toggled with the
   `hidden` attribute (so it leaves the tab order), and `display` cannot be
   transitioned -- an entrance keyframe runs on appearance, which is the half
   that carries the motion.
   ----------------------------------------------------------------------------- */
.sf_picker_filterpanel[hidden] { display: none; }
.sf_picker_filterpanel {
    box-sizing: border-box;
    width: 100%;
    margin: 12px 0 0;
    padding: 16px;
    border: 0.75px solid var(--sf-line, #E4DED8);
    border-radius: 8px;
    background: #FAF3ED;
}
@media (min-width: 992px) {
    .sf_picker_filterpanel {
        animation: sf_filterpanel_drop 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
        transform-origin: top center;
    }
}
@keyframes sf_filterpanel_drop {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: none; }
}
@media (max-width: 991px) {
    /* THE FRAME IS THE WHOLE SCREEN: 390 x 870, square corners, pearl ground,
       no shadow -- nothing is behind it to cast one onto. The panel itself is
       the scrollport; the top bar and the action band are sticky INSIDE it, so
       the board's three bands (52 header / scrolling groups / 106 action) come
       out of the markup that is already there rather than a new wrapper.

       Side padding is the board's 22 (see the `margins` note below); the
       vertical padding is 0 because the two sticky bands carry the board's own
       insets and must reach the screen edges. */
    .sf_picker_filterpanel {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 70;
        width: auto;
        height: auto;
        max-height: none;
        margin: 0;
        padding: 0 22px;
        overflow-y: auto;
        /* a flick that runs past the end of the list must not scroll the picker
           underneath -- this drawer covers it completely and there is no way back
           to it except VIEW n RESULTS. */
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        animation: sf_filterpanel_up 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
    }
}
@keyframes sf_filterpanel_up {
    from { transform: translateY(100%); }
    to   { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .sf_picker_filterpanel { animation: none; }
}
.sf_picker_filter_group + .sf_picker_filter_group { margin-top: 20px; }
/* group heading -- frame 344 x 31 */
.sf_picker_filter_title {
    margin: 0 0 8px;
    min-height: 31px;
    display: flex;
    align-items: center;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: -0.21px;
    text-transform: uppercase;
    color: #3E3C39;
}
.sf_picker_filter_opts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
/* chip -- the frame's 110 wide r8 box, grown to hold the ring glyph the owner
   asked for ("the assets are already on the /engagement-rings one"). The frame
   draws a 42-tall label-only chip; 42 cannot hold a 36px drawing AND a line of
   type, so the height is the one number that moves: 12 + 36 + 6 + 15 + 12 = 81.
   Width, radius, strokes and both fills are the frame's. */
.sf_picker_filter_opt {
    flex: 0 1 110px;
    min-width: 0;
    min-height: 42px;
    box-sizing: border-box;
    margin: 0;
    padding: 12px 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 0.75px solid var(--sf-line, #E4DED8);
    border-radius: 8px;
    background: transparent;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 13px;
    line-height: 15px;
    letter-spacing: -0.21px;
    color: #3E3C39;
    text-align: center;
    overflow-wrap: anywhere;
    cursor: pointer;
    transition: background-color .2s linear, color .2s linear;
}
/* the glyph is line art on a transparent ground -- it takes the chip's own
   colour, so selection changes the drawing with the label. */
.sf_picker_filter_icon {
    display: block;
    width: 36px;
    height: 36px;
    line-height: 0;
    color: inherit;
}
.sf_picker_filter_icon svg {
    display: block;
    width: 100%;
    height: 100%;
}
.sf_picker_filter_text { display: block; }

/* -----------------------------------------------------------------------------
   SHAPE AND METAL -- the other two groups the category page offers.

   Owner: *"all filters are not there in mobile view and even desktop -- check
   the current doamore.com filters for engagement rings, check the design and
   implement it properly."* `/engagement-rings` draws Shape (ten glyphs), Metal
   (four swatches) and Style; this panel had Style alone.

   The group boxes differ because the content does. A shape is a drawing and
   needs no width for words, so its chip is 72 square -- four to a row on the
   345 sheet, where a 110 chip would have taken five rows for ten shapes. A
   metal is a colour and a name, so it keeps the frame's 110 chip and lays the
   dot beside the label rather than above it.
   ----------------------------------------------------------------------------- */
/* The shape art is OUTLINE art -- the same distinction the stone rail draws
   between its standard (filled) and antique (stroked) sets. These files are
   stroked, so they take the chip's colour and change with selection. */
/* PINNED, NOT DISABLED-LOOKING-BROKEN. With a stone held the shape is already
   decided, so the group says which one and refuses the rest. The chosen chip
   keeps its full selected treatment; the others dim and stop responding. */
.sf_picker_filter_opt.is-pinned:not(.is-active) {
    opacity: 0.35;
    cursor: default;
}
.sf_picker_filter_opt.is-pinned.is-active {
    cursor: default;
}
.sf_picker_filter_pinned {
    margin-left: 8px;
    font-size: 12px;
    line-height: 19px;
    letter-spacing: -0.21px;
    text-transform: none;
    color: #3E3C39;
    opacity: 0.7;
}
.sf_picker_filter_pinned[hidden] { display: none; }

.sf_picker_filter_opts_metal .sf_picker_filter_opt {
    flex: 0 1 110px;
    min-height: 42px;
    flex-direction: row;
    gap: 8px;
    padding: 8px 10px;
}
/* The category page's own swatch: a filled circle. White Gold and Platinum are
   the SAME fill there (#767676), so the ring around it is what keeps two
   adjacent chips from reading as one repeated control. */
.sf_picker_metal_dot {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 0.75px rgba(15, 14, 13, 0.18);
}
.sf_picker_filter_opts_metal .sf_picker_filter_text {
    font-size: 12px;
    line-height: 14px;
    text-align: left;
}
/* The phone's four-up 80px shape row is GONE -- below 992 the shape group is
   now the board's style TILE (see "SHAPE IS A STYLE TILE" at the foot of this
   file), so a flex-basis here would only have been inert against that grid. */
.sf_picker_filter_opt.is-active {
    border-color: transparent;
    outline: 1.5px solid var(--sf-green, #27423B);
    outline-offset: 0;
    background: rgba(194, 206, 178, 0.30);
    color: var(--sf-ink, #0F0E0D);
}
.sf_picker_filter_opt:focus-visible {
    outline: 2px solid var(--sf-green, #27423B);
    outline-offset: 2px;
}
/* action bar -- the frame's 344 x 60 primary, with Reset kept as a text link
   because tap-to-unselect is per-chip and there is otherwise no clear-all. */
.sf_picker_filter_actions {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 20px;
}

/* THE PRIMARY ACTION IS ALWAYS ON SCREEN. Owner: *"also the filters go out of
   the screen -- the filters CTA -- fix it properly."*

   MEASURED at 390 with the panel open: the panel is `position: fixed` at
   [0,118] 390x726, bottom flush with the 844 viewport, and it scrolls
   (scrollHeight 940 against clientHeight 726). The action bar is the LAST thing
   in that scroller, so "View n Results" sat at y982-1042 -- 138px below the fold
   -- and `elementFromPoint` on its centre returned NOTHING. The shopper had to
   discover that the sheet scrolls before they could apply a filter.

   The board does not treat it as part of the scrolling content: `Frame
   1171276852` is a 390 x 106 action bar, its own band under the groups. Stuck to
   the bottom of the scrollport reproduces that without restructuring the
   markup or giving the panel a second scroll container -- `position: sticky`
   keeps it in flow (so it cannot overlap the last group's chips) while pinning
   it once the content runs past the fold.

   The negative bottom and the matching padding cancelled the panel's own bottom
   padding, so the bar sat ON the sheet's edge the way the frame draws it; the
   ground is repainted because content now scrolls underneath it. Phone only --
   above 992 the panel is a dropdown sized to its content and never scrolls.

   SUPERSEDED, kept for the reasoning: the full-screen rebuild below restates
   this band at `bottom: 0` with the frame's own 13/23/33/23 insets, because the
   panel no longer has a bottom padding to cancel. Only the comment survives. */
@media (max-width: 991px) {
    .sf_picker_filterpanel .sf_picker_filter_actions {
        position: sticky;
        z-index: 2;
        background: #FAF3ED;              /* the drawer's own ground */
    }
}

.sf_picker_filter_reset {
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    background: none;
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 14px;
    line-height: 16px;
    color: #3E3C39;
    text-decoration: underline;
    cursor: pointer;
}
/* THE TOP BAR'S TWO GLYPHS, sized at every width. 14621:48525 is a PHONE board
   and the bar it describes is rebuilt under 992; these three rules exist only so
   the same markup is not loose above it, where the panel is a dropdown with no
   bar of its own. An inlined SVG with no box renders at its own attribute size
   and sits on the text baseline, which is a glyph half a line low. */
.sf_picker_filter_head_name {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
.sf_picker_filter_head_icon,
.sf_picker_filter_reset_icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    line-height: 0;
    color: inherit;
}
/* Reset is a plain inline button above 992 (no flex box, so no gap property):
   the board's 2 between glyph and word is carried as a margin there, and taken
   straight back off below 992 where the pill IS a flex row with gap: 2. */
.sf_picker_filter_reset_icon { margin-right: 2px; }
.sf_picker_filter_head_icon svg,
.sf_picker_filter_reset_icon svg {
    display: block;
    width: 100%;
    height: 100%;
}
.sf_picker_filter_done {
    flex: 1 1 auto;
    min-height: 60px;
    padding: 12px 20px;
    border: 0;
    border-radius: 4px;
    background: var(--sf-green, #27423B);
    font-family: 'FoundersGrotesk', sans-serif;
    font-size: 16px;
    line-height: 19px;
    letter-spacing: -0.21px;
    text-transform: uppercase;
    color: #FAF3ED;
    cursor: pointer;
}
@media (min-width: 992px) {
    /* a 344-wide primary spanning a 1568 panel is the phone sheet's shape
       stretched, and at this width the panel closes on the first pick anyway --
       so the row is a trailing pair, not the exit. Written AFTER the rule it
       narrows: the two are equally specific and source order decides. */
    .sf_picker_filter_actions { justify-content: flex-end; }
    .sf_picker_filter_done {
        flex: 0 0 auto;
        min-width: 220px;
        min-height: 48px;
    }
}
/* the count on the pill, so a collapsed panel still says it is filtering.
   NEVER display:none -- the painter writes into the count node, and a
   display:none subtree takes the write but leaves no box. */
.sf_picker_filters_badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* A CIRCLE CANNOT SHRINK. Owner: *"the number beside the Filters text in the
       Filters CTA is oval and not a circle, in phone view."* It was: the pill is
       a flex row and this box defaulted to `flex: 0 1 auto`, so at 390 the row
       ran out of room and shrank it -- MEASURED 9.47 x 20 against the 20 x 20 it
       declares. `border-radius: 50%` on a 9.5x20 box draws exactly the oval
       reported. `flex: 0 0 20px` takes shrinking off the table; the width below
       stays for anything that reads it as a block. */
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    /* 4, NOT 6. 14684:49160 puts the icon+label group at 45936..46000 and the
       badge at 46004 -- 4 between them. The 6 that was here sat on top of the
       pill's old 4px `gap` and made it 10, which nothing on the board says. */
    margin-left: 4px;
    border-radius: 50%;
    background: rgba(250, 243, 237, 0.22);
    vertical-align: middle;
    overflow: hidden;
}
.sf_picker_filters_badge_count {
    font-size: 12px;
    line-height: 20px;
    color: inherit;
}
/* EMPTY MEANS OUT OF THE ROW, not a zero-width item still sitting in it.
   Owner: *"by default Filters on the engagement-ring drawer list must be
   centred."* It was not, and the badge was why: `width: 0` cannot shrink a flex
   item whose `flex-basis` is 20px, so the hidden badge still held a 20px track
   AND still drew the row's 4px gap beside it. MEASURED at 390 before this: pill
   289..378 (centre 333.5), visible content -- icon 295.7 through label 347.2 --
   centred on 321.45. Exactly 12px left, which is (20 + 4) / 2.

   `position: absolute` is the one way to leave the row entirely and still keep
   a box: `display: none` would do it too but the painter writes the number into
   the count node, and a display:none subtree takes the write and leaves nothing
   to measure -- that is what the base rule above has always warned about. */
.sf_picker_filters_badge.is-empty {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    margin: 0;
    visibility: hidden;
}

/* =============================================================================
   THE FILTER PANEL, REBUILT TO 14621:48072 ("DIAMOND FLOW Filters for ER")
   -----------------------------------------------------------------------------
   Owner: *"the filters section must be like this -- exact reconstruction. The
   buttons are weird, the icon is small and stuff."*

   MEASURED against the frame before this block, at 390. Every row below is a
   real difference, not a tidy-up:

     element        board                         build
     content inset  22 each side (column 345)     16
     group gap      24                            (none stated)
     title          16/19 ls -0.21 #3E3C39 @80%,  13/15, no padding
                    padding-bottom 12, UPPER
     metal chip     110 x 42, r8, pad 12/8,       110 x 46, pad 8/10, gap 8
                    gap 4
     metal label    16/18 ls -0.5                 13/15 ls -0.21
     metal icon     20 x 20                       18 x 18      <- "icon is small"
     style tile     109 x 96, r12, gap 8,         110 x 83, r8, gap 6
                    rows 9 apart
     action band    390 x 106, pad 13/23/33/23    358 x 88 at x16
     VIEW button    344 x 60, label 18/18 ls -0.5 314 x 60, 16/19 ls -0.21

   Selected states are the frame's own: metal chips take a #C2CEB2 @30% fill with
   a 1.5px #27423B stroke, style tiles an #E9E8DB fill with the same 1.5px; the
   resting strokes are 1px #E4DED8 on chips and 0.75px on tiles. Those two
   different resting weights are the board's, not a slip.

   Strokes are drawn as inset shadows wherever a tile is a fixed size, so the
   1.5px selected ring does not eat the 42 or the 96 and shift its neighbours.

   Phone only. Above 992 the panel is a content-sized dropdown anchored under the
   Filters pill and keeps the geometry already stated for it.
   ============================================================================= */
/* HOISTED OUT OF `@media (max-width: 991px)`. Owner: *"the price slider on
   desktop is horrendous ... make it for desktop too, just line them as much as
   you can."*

   Every rule below used to be phone-only, so above 992 the panel fell back to
   the PRE-REBUILD build -- the right-hand column of the table above -- and the
   price control fell back to noUiSlider's own stylesheet: MEASURED at 1440, a
   #3FB8AF cyan bar the full width of the panel with two square white handles,
   and the two inputs bunched at the left instead of at the ends. That is the
   "horrendous" slider; it was never styled at this width at all.

   One design now serves both widths. What genuinely differs above 992 -- the
   panel is an inline dropdown, not a full-screen drawer, and it has room for
   more chips per row -- is stated in the `min-width: 992px` block at the end of
   this section, and nowhere else. */
/* content column 345 inside 390 -> 22 either side (`margins` 0..24 / 366..390
   with the Filters frame starting at 22). */
.sf_picker_filterpanel {
    padding-left: 22px;
    padding-right: 22px;
}
/* `Filters` frame, itemSpacing 24 between the groups. */
.sf_picker_filterpanel .sf_picker_filter_group + .sf_picker_filter_group {
    margin-top: 24px;
}

/* ---- THE TOP BAR -- 14621:48525 ---------------------------------------
   `Header` is 390 x 52: VERTICAL, padding 4 / 18, fill #FAF3ED, stroke 1px
   #E4DED8. It holds ONE row, `Frame 1171276851` 354 x 44, SPACE_BETWEEN with
   the items centred: the Filters pill at the left end, Reset at the right.

   THE STROKE IS DRAWN AS A BOTTOM HAIRLINE ONLY. Figma puts it on all four
   sides (strokeAlign OUTSIDE) because the bar is a free frame on the board;
   in a full-screen drawer three of those sides are the screen edge, so the
   one that can be seen is the one that is painted.

   Sticky, not fixed: the panel is the scrollport and this is its first
   child, so `top: 0` pins it without taking it out of flow and without a
   second scroll container. The 46 above it on the board is the phone's
   STATUS BAR -- here that is `env(safe-area-inset-top)`, which is 0 on a
   browser that has no notch to clear and the right number on one that does.

   Margin-bottom 15: the board's `Filters` frame starts at y113 and the bar
   ends at y98 (46 status + 52 bar). MEASURED off the frame, not chosen. */
.sf_picker_filterpanel .sf_picker_filter_head {
    position: sticky;
    top: 0;
    z-index: 3;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 52px;
    /* -22 cancels the panel's own side padding so the bar spans the full 390 */
    margin: 0 -22px 15px;
    padding: calc(4px + env(safe-area-inset-top, 0px)) 18px 4px;
    background: #FAF3ED;
    border-bottom: 1px solid var(--sf-line, #E4DED8);
}
/* `Filter` 14621:48527, 92 x 44, r8 -- and BOTH its fill and its stroke are
   `visible: false` on the board. This build shipped a 1px #27423B ring on it
   (and on Reset), which is a box the board does not draw: the two are plain
   labels on the bar's own ground. The radius is kept because the frame
   carries it and a focus ring lands on it. */
.sf_picker_filterpanel .sf_picker_filter_head_label {
    display: inline-flex;
    align-items: center;
    gap: 4px;                   /* `Filter` itemSpacing 4: name | badge */
    box-sizing: border-box;
    min-width: 0;
    height: 44px;
    padding: 0;
    border-radius: 8px;
    background: transparent;
    box-shadow: none;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 18px;
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #0F0E0D;
}
/* `Frame 1171276655` 64 x 26, itemSpacing 2 -- the glyph and the word. */
.sf_picker_filterpanel .sf_picker_filter_head_name {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
/* `Frame` 14621:48529, 18 x 18, holding a 13.5 funnel stroked 1px #0F0E0D.
   The art is the board's own export; it takes `currentColor` so it cannot
   drift from the label beside it. */
.sf_picker_filterpanel .sf_picker_filter_head_icon {
    display: block;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    line-height: 0;
    color: inherit;
}
.sf_picker_filterpanel .sf_picker_filter_head_icon svg {
    display: block;
    width: 100%;
    height: 100%;
}
/* `Frame 1171276654` 24 x 24 r50 #D8DDCA, label `3` 14/19 ls -0.21 in
   #27423B -- the count is GREEN on the board, not the ink of the word beside
   it, which is how it reads as a count and not a third word. */
.sf_picker_filterpanel .sf_picker_filter_head_badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: #D8DDCA;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #27423B;
}
.sf_picker_filterpanel .sf_picker_filter_head_badge.is-empty { display: none; }
/* `Filter` 14621:48534, 60.06 x 44 at the row's right end -- also no fill and
   no stroke. Inside, `Frame 38250` 60.06 x 18.06 itemSpacing 2: the 18.06
   reset glyph, then `Reset` 17/19 ls -0.21 in #3E3C39 (NOT the #0F0E0D this
   build used -- the board gives the two pills different inks, and the glyph
   takes the same one through currentColor).

   Width is HUG on the board; 60.06 is what 18.06 + 2 + 40 comes to, so it is
   left to the content rather than frozen at 60 -- the word is the same word. */
.sf_picker_filterpanel .sf_picker_filter_reset {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
    flex: 0 0 auto;
    box-sizing: border-box;
    width: auto;
    height: 44px;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    box-shadow: none;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 17px;
    line-height: 19px;
    letter-spacing: -0.21px;
    color: #3E3C39;
    text-decoration: none;
    cursor: pointer;
}
/* `Group` 14621:48536, 18.06 square: a circle and a return arrow, both
   stroked 1px #3E3C39. Exported from the board at 15 x 16 (its stroke
   bounds), so the box is 18 and the viewBox is left to letterbox itself
   rather than being stretched to fill. */
.sf_picker_filterpanel .sf_picker_filter_reset_icon {
    display: block;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    margin: 0;                  /* the pill's own gap: 2 carries it here */
    line-height: 0;
    color: inherit;
}
.sf_picker_filterpanel .sf_picker_filter_reset_icon svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* ---- group title -- `Frame 1171276645`, 344 x 31, padding-bottom 12 ---- */
.sf_picker_filterpanel .sf_picker_filter_title {
    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);
}

/* ---- metal chips -- `Cut` 14621:48082, 110 x 42, r8, pad 12/8, gap 4 ----

   TWO TO A ROW, NOT THREE, AND THE ONLY NUMBER THAT MOVES IS THE WIDTH.
   Owner: *"and same with the metal filters too. You forgot a lot of CSS.
   What was the metal design I gave you -- see 14621:48077."*

   `Frame 1171276731` is 344 wide, WRAP, itemSpacing 8, and holds three 110
   chips per row because the board's labels are one word and a colour:
   `Yellow gold` MEASURED 66 wide at the frame's own 16/18 ls -0.5, inside a
   text box of 110 - 8 - 8 - 20 - 4 = 70.

   This catalogue's metals carry a karat (see the $sf_metals note in
   da-settings-picker.php -- the pairs are what the filter actually queries
   and the owner asked for them to be left alone). MEASURED in the same face
   at the same 16/18 ls -0.5: `14k Yellow Gold` is 91.5 wide, which needs a
   131.5 chip. Three-up on this 346 column gives 110. So the row goes to two,
   the chip to (346 - 8) / 2 = 169, and every other value on the frame --
   height 42, radius 8, padding 12/8, gap 4, the 19 ring, the type, both
   fills, both strokes -- is the board's, unchanged.

   WHAT WAS ACTUALLY MISSING was the label. The chip was given the frame's
   16/18 ls -0.5 but `.sf_picker_filter_opts_metal .sf_picker_filter_text`
   higher up this file sets 12/14 on the span itself, and a declaration beats
   an inherited value whatever the specificity -- so the label MEASURED
   12px/14px on the deployed build, two sizes under the board. It is restated
   here, on a selector that outranks it. */
.sf_picker_filterpanel .sf_picker_filter_opts_metal {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}
.sf_picker_filterpanel .sf_picker_filter_metal {
    display: inline-flex;
    /* The board top-aligns in a 42 box whose padding (12 + 20 + 12 = 44)
       overflows it by 2, landing the 20 ring 12 from the top and 10 from the
       bottom. Centred instead: the difference is 1px and it survives a label
       that ever wraps, which a fixed 12 would not. */
    align-items: center;
    justify-content: flex-start;
    gap: 4px;
    box-sizing: border-box;
    width: auto;
    height: 42px;
    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: 16px;
    line-height: 18px;
    letter-spacing: -0.5px;
    color: #0F0E0D;
    cursor: pointer;
}
/* `icon yello gold` 20 x 20 -- this is the owner's "the icon is small". */
.sf_picker_filterpanel .sf_picker_filter_metal .sf_picker_metal_dot {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
}
/* `Signature Ideal` 14621:48085 and its four siblings: 16/18 ls -0.5 #0F0E0D,
   one line. Every value restated -- see the note above on why inheritance
   alone did not reach this node. */
.sf_picker_filterpanel .sf_picker_filter_metal .sf_picker_filter_text {
    min-width: 0;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: -0.5px;
    color: inherit;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sf_picker_filterpanel .sf_picker_filter_metal.is-active,
.sf_picker_filterpanel .sf_picker_filter_metal[aria-pressed="true"] {
    background: rgba(194, 206, 178, 0.30);
    box-shadow: inset 0 0 0 1.5px #27423B;
}

/* ---- style tiles -- `Oval` 109 x 96, r12, pad 12/8, VERTICAL gap 8 -----
   Three to a row, 8 apart across and 9 down.

   SHAPE IS THE SAME TILE. Owner: *"in filters for engagement ring drawer...
   the shape one looks off -- fill it like you filled for style, okay?"*
   14621:48072 has no shape group to copy -- the board draws METAL, STYLE and
   PRICE only -- so the instruction IS the spec: shape takes 14621:48107's
   treatment verbatim. Every number below is that frame's, and the shape
   group is added to each selector rather than given a parallel set, so the
   two can never drift. It was an 80 x 72 chip with a 32 glyph and an 11px
   label, which is the box that "looks off" beside a 109 x 96 tile. */
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opts{
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 8px;
    row-gap: 9px;
}
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    width: auto;
    height: 96px;
    padding: 12px 8px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    box-shadow: inset 0 0 0 0.75px #E4DED8;
    cursor: pointer;
}
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt.is-active,
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt[aria-pressed="true"]{
    background: #E9E8DB;
    box-shadow: inset 0 0 0 1.5px #27423B;
}
/* `.sf_picker_filter_opt.is-active` further up this file paints a different
   selected state -- a transparent border plus a 1.5px OUTLINE and the
   #C2CEB2 @30% fill -- and an outline draws OUTSIDE the box, so on a fixed
   96 tile it bled into the 8px gutter. The tiles answer with an inset
   shadow, which is why it has to be switched off here rather than left to
   stack. Scoped to the panel's tiles, so the chip elsewhere keeps it, and
   excused on :focus-visible so the keyboard ring still draws. */
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt.is-active:not(:focus-visible),
.sf_picker_filterpanel .sf_picker_filter_metal.is-active:not(:focus-visible) {
    outline: 0;
}

/* ---- price -- track 344 x 8 r15 #E4DED8, connect #C2CEB2, thumbs 32 x 21
   r16 #27423B; then two 110 x 40 r8 #FFFFFF inputs, 1px #E4DED8, pushed to
   the two ends with the frame's own SPACE_BETWEEN. ---------------------- */
.sf_picker_filterpanel .sf_picker_price { display: block; }
.sf_picker_filterpanel .sf_picker_price_track.noUi-target {
    width: auto;
    height: 8px;
    margin: 6.5px 16px 0;   /* half a 32-wide thumb each side, so travel ends flush */
    border: 0;
    border-radius: 15px;
    background: #E4DED8;
    box-shadow: none;
}
.sf_picker_filterpanel .sf_picker_price_track .noUi-connect {
    background: #C2CEB2;
    border-radius: 15px;
}
.sf_picker_filterpanel .sf_picker_price_track .noUi-handle {
    width: 32px;
    height: 21px;
    top: -6.5px;
    right: -16px;
    border: 0;
    border-radius: 16px;
    background: #27423B;
    box-shadow: none;
    cursor: pointer;
}
.sf_picker_filterpanel .sf_picker_price_track .noUi-handle::before,
.sf_picker_filterpanel .sf_picker_price_track .noUi-handle::after { display: none; }
.sf_picker_filterpanel .sf_picker_price_track .noUi-touch-area {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    transform: none;
}
/* `Frame 1171276739` 344 x 40, itemSpacing 10, the two boxes at the ends. */
.sf_picker_filterpanel .sf_picker_price_inputs {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 16px;       /* `Frame 1171276738` itemSpacing 16 */
}
.sf_picker_filterpanel .sf_picker_price_input {
    flex: 0 0 110px;
    box-sizing: border-box;
    width: 110px;
    height: 40px;
    padding: 0 12px;
    border: 1px solid #E4DED8;
    border-radius: 8px;
    background: #FFFFFF;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 18px;
    letter-spacing: -0.5px;
    color: #0F0E0D;
    text-align: center;
}

/* ---- action band -- `Frame 1171276852` 390 x 106, pad 13/23/33/23, one
   344 x 60 r4 #27423B button, label 18/18 ls -0.5 #FAF3ED. The panel's own
   22px side padding is cancelled so the band spans the full 390 the frame
   draws, and the button lands on the frame's 23. ------------------------- */
.sf_picker_filterpanel .sf_picker_filter_actions {
    display: block;
    /* Stuck to the FOOT of the drawer, which is where `Frame 1171276852`
       sits on an 870-tall board. `bottom: 0` now, not the old negative
       offset: that one existed to cancel a 16px bottom padding the
       full-screen panel no longer has. */
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 24px -22px 0;
    padding: 13px 23px calc(33px + env(safe-area-inset-bottom, 0px));
    background: #FAF3ED;
}
.sf_picker_filterpanel .sf_picker_filter_done {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 100%;
    height: 60px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: #27423B;
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 18px;
    line-height: 18px;
    letter-spacing: -0.5px;
    text-transform: uppercase;
    color: #FAF3ED;
    cursor: pointer;
}

/* ---- ABOVE 992 THE PANEL IS A DROPDOWN, NOT A DRAWER ----------------------
   Owner: *"make it for desktop too -- just line them as much as you can."*

   So: the same chips, tiles, swatches and slider, at the board's own sizes.
   Only four things cannot be carried straight across, and each is stated once,
   here.

   1. THE ROWS FILL THE WIDTH, and that is the whole instruction. On the board
      three 110 chips and three 109 tiles fill a 344 column; this panel is the
      results column -- MEASURED 1304 at 1440 -- so the same flex rows simply
      fit more per line, and the eight metals and seven styles each land on ONE
      row. Nothing is resized to make that happen.

   2. THE PRICE CONTROL SPANS THE PANEL. Owner: *"price in desktop view, price
      slider is not full -- it's like occupying 30 percent of the width, fix
      it."* MEASURED, it was 312 of a 1260 column, which is 25%.

      This overrides a cap I had put here, and the reasoning for that cap is
      kept rather than deleted because it is still true and is what to weigh if
      this is ever revisited: a slider this long is a coarser instrument than
      the board's -- about $5 of travel per pixel against ~$20 at 390 -- and the
      two 110-wide value boxes now sit ~1,040 apart. The owner has looked at the
      wide one and asked for it, so width wins and the trade is recorded.

      The inputs stay at the ENDS, which is the board's own rule
      (`Frame 1171276739`, SPACE_BETWEEN) applied to a wider row, not a second
      decision.

   3. THE ACTION BAND IS A TRAILING BUTTON, NOT A STUCK BAR. The drawer's band
      is sticky because the drawer is its own scrollport; this panel is not, so
      a sticky foot would pin a bar over the results behind it. The button keeps
      the board's 344 x 60 and sits at the end of the row, which is where this
      panel already put it.

   4. THE TOP BAR MEETS THE PANEL'S CORNERS. The bar cancels the side padding
      with a -22 margin so it spans the full width; here the panel also has a
      16px top padding and an 8px radius, so the bar is pulled up into the first
      and given the second. */
@media (min-width: 992px) {
    /* ---- THE TITLE BAR IS THE DRAWER'S, AND THIS IS NOT A DRAWER ----------
       Owner: *"there's a line below Filters ... the division between filters
       and header and body content, can you fix it, it looks off."*

       The line is not the defect, it is what makes the defect visible. MEASURED
       at 1440: the dark `Filters` PILL that opens this panel sits at y160 and
       stays on screen; the panel opens 24px under it at y228 and its first row
       is a second `Filters`, with its own count badge, with a full-bleed
       hairline under it. So the word appears twice, 24 apart, and the rule
       divides a header from a body it has already named.

       On the board that bar is right, because 14621:48072 is a FULL-SCREEN
       DRAWER -- it covers the pill, so its title is the only one on screen and
       the hairline is the drawer's own edge. Neither is true here.

       So above 992 the duplicated half goes and the useful half stays: `Filters`
       and its badge are hidden (the pill outside already carries both, and the
       painter writes to both nodes, so nothing is left unlabelled or
       uncounted), the hairline goes with the header it was separating, and
       Reset keeps its place at the top right of the panel.

       REVERSIBLE IN ONE RULE. Nothing is removed from the markup and the phone
       drawer is untouched -- delete this block and the board's bar comes back
       at every width. */
    .sf_picker_filterpanel .sf_picker_filter_head {
        position: static;
        min-height: 0;
        margin: 0 0 4px;
        padding: 0;
        border-bottom: 0;
        background: none;
        /* The bar is SPACE_BETWEEN, which with one child left is the same as
           flex-start -- MEASURED, Reset jumped to x90 the moment the label was
           hidden. It is a right-hand control on the board and it stays one. */
        justify-content: flex-end;
    }
    .sf_picker_filterpanel .sf_picker_filter_head_label { display: none; }
    /* `repeat(N, 1fr)` IS A PHONE NUMBER, NOT A SIZE. The board's 2-up metals
       and 3-up styles are stated as fixed track COUNTS because they fill a 344
       column; carried to a 1260 one they stretched instead of repeating --
       MEASURED at 1440 straight after the hoist, chips 626 wide and tiles 415
       against the board's 110 and 109. `auto-fill` asks the same question the
       other way round: keep the track near the board's size and fit as many as
       the row has room for. At 1260 that is eight metals on one row at ~150 and
       eight styles on one at ~119. The minimums are the labels', not the
       board's -- "14k Yellow Gold" needs ~120 beside a 20px swatch, where the
       board's own "Yellow gold" fits in 110. */
    .sf_picker_filterpanel .sf_picker_filter_opts_metal {
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    }
    .sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opts {
        grid-template-columns: repeat(auto-fill, minmax(109px, 1fr));
    }
    .sf_picker_filterpanel .sf_picker_filter_actions {
        position: static;
        margin: 24px 0 0;
        padding: 0;
        text-align: right;
        background: none;
    }
    .sf_picker_filterpanel .sf_picker_filter_done {
        display: inline-flex;
        width: 344px;
    }
}

/* =============================================================================
   THE FILTER PANEL'S OWN ASSETS -- 14621:48077, :48107, :48490
   -----------------------------------------------------------------------------
   Owner: *"how hard is it to copy the assets, icon and styles perfectly."*
   Three corrections, each against its own frame.

   1. THE METAL SWATCH IS A RING, NOT A DOT. 14621:48077's `Rectangle 512` is
      19 x 19, `cornerRadius 100`, NO fill, and a 4px STROKE in the metal's
      colour, sitting in a 20 x 20 frame. This shipped as a solid 20px disc. A
      4px stroke on a 19px box leaves an 11px hole, which is the whole look.
      Drawn as a border so the hole is the chip's own ground and the ring stays
      crisp at any DPR; the colour arrives per-swatch as `--sf-metal` from PHP.

   2. THE STYLE TILES CARRY THE BOARD'S DRAWINGS. 14621:48107 gives each tile a
      ~76 x 48 illustration of the ring itself, not an outline glyph; the seven
      are exported at their own node ids into assets/media/ringbuilder/styles/.
      Each keeps the frame's viewBox, so they are sized by the BOX here (76 x 48
      inside the tile's 12/8 padding) and never scaled by their own intrinsic
      size. The label is 16/16 ls -0.5, and it is #27423B on the selected tile
      against #3E3C39 at rest -- the frame's two values, which the build had as
      one.

   3. THE PRICE INPUTS TRACK POSITIVE. 14621:48490's two values are 16/16 at
      letterSpacing **+0.75**, not the -0.5 used elsewhere on this panel and not
      the -0.21 that is the file's default. Digits are what that tracking is for;
      stated here or the panel's own default wins.
   ============================================================================= */
/* Hoisted for the same reason as the block above: these three corrections are
   the panel's ASSETS, and assets do not change at a breakpoint. */
.sf_picker_filterpanel .sf_picker_filter_metal .sf_picker_metal_dot {
    box-sizing: border-box;
    width: 19px;
    height: 19px;
    flex: 0 0 19px;
    margin: 0 0.5px;            /* the 19 sits in the frame's 20 */
    border: 4px solid var(--sf-metal, #D0D0D0);
    border-radius: 100px;
    background: transparent;    /* `Rectangle 512` has no fill */
    /* The base `.sf_picker_metal_dot` adds a 0.75px rgba(15,14,13,.18) inset
       ring, which the category page's SOLID disc needs to separate White Gold
       from Platinum (both #767676 there). `Rectangle 512` carries ONE stroke
       and nothing else, and here the five colours are already distinct -- so
       the extra hairline, MEASURED still painting inside the panel, is taken
       off. The base rule keeps it everywhere else. */
    box-shadow: none;
}

/* the drawing, `all rings-12 1` and its six siblings -- and the shape
   glyphs, in the SAME 76 x 48 box. The shape files are square (viewBox
   `0 0 50 50`), and an SVG with a viewBox letterboxes rather than stretches,
   so a square drawing in a 76 x 48 box lands 48 x 48 centred: the board's
   48 of tile height, without a second set of numbers to keep in step. */
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_icon{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 76px;
    height: 48px;
}
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_icon svg{
    display: block;
    width: 100%;
    height: 100%;
}
/* label -- 16/16 ls -0.5, #3E3C39 resting and #27423B selected */
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_text{
    font-family: 'FoundersGrotesk', sans-serif;
    font-weight: 400;
    font-size: 16px;
    line-height: 16px;
    letter-spacing: -0.5px;
    color: #3E3C39;
    text-align: center;
}
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt.is-active .sf_picker_filter_text,
.sf_picker_filterpanel .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opt[aria-pressed="true"] .sf_picker_filter_text{
    color: #27423B;
}
/* THE GLYPH TAKES THE LABEL'S INK. On 14621:48107 the selected tile's
   drawing is stroked #27423B and a resting one #3E3C39 -- the same pair the
   label moves between. The shape files are line art with no stroke of their
   own (`fill="none"` on the root and nothing on the paths), so the colour
   has to be stated; it is taken from the tile so the two cannot disagree.
   The 1-unit stroke in a 50 viewBox drawn at 48 is 0.96px, which is the
   hairline the board shows. */

/* `$50` / `$3,000` -- 16/16, letterSpacing +0.75 */
.sf_picker_filterpanel .sf_picker_price_input {
    font-size: 16px;
    line-height: 16px;
    letter-spacing: 0.75px;
}

/* ===========================================================================
   THE STONE-FLOW PDP GALLERY MOVES ON ONE AXIS, NOT TWO
   ---------------------------------------------------------------------------
   Owner: *"in mobile view I'm able to literally freely move the gallery --
   that's weird. This is in the stone flow, modified PDP."*

   The carousel itself is right and is NOT what this changes: MEASURED at 390 on
   `?sf=1`, `.iconic-woothumbs-images--grid` has `scroll-snap-type: x mandatory`
   with seven slides at 366 each against a 366 client width and
   `scroll-snap-align: center` -- so a horizontal swipe lands on an image, every
   time. That is the designed gallery.

   What makes it feel loose is the OTHER axis. The track computes
   `overflow: scroll auto` and `touch-action: auto`, so a finger may drag it
   vertically as well as horizontally, and a diagonal drag moves the images
   around inside their own box instead of either changing slide or scrolling the
   page. That is the "freely move".

   `touch-action: pan-x pan-y` permits both axes; `overflow-y: hidden` is what
   decides where each one goes. Horizontal has somewhere to go inside this
   element -- the snap track -- so it drives the carousel. Vertical has nowhere,
   because the element has no vertical scrollport, so the browser walks up to the
   page and scrolls the PDP. The "free 2-axis drag inside the box" stays fixed by
   the `overflow-y`, not by the touch-action.

   CORRECTION, AND IT WAS MINE. This shipped as `touch-action: pan-x` with a note
   claiming it "passes everything vertical to the page". It does not: pan-x
   PERMITS horizontal panning and BLOCKS vertical outright -- a blocked gesture
   is dropped, never forwarded to an ancestor. Owner: *"in phone view I cannot
   scroll down when I swipe vertically on the gallery image."* Exactly that.

   Scoped to `body.sf-flow-pdp`, the class da-general.php stamps ONLY for the
   stone flow's setting PDP (present with `?sf=1`, absent on the same product
   without it), because that is the surface the report is about and the ordinary
   PDP's gallery is not ours to change here.
   =========================================================================== */
@media (max-width: 991px) {
    body.sf-flow-pdp .iconic-woothumbs-images,
    body.sf-flow-pdp .iconic-woothumbs-images--grid {
        touch-action: pan-x pan-y;
        overflow-y: hidden;
        overscroll-behavior-x: contain;   /* no page-level back-swipe from the ends */
    }
}

/* The Ring Details price is not bold. Owner: *"in ring details remove bold font
   on price."* The total is marked up as <strong> (da-settings-picker.php's
   details bar), which the browser renders at 700 unless something says
   otherwise. The rest of that bar runs at 400, so the price was the one word
   set heavier than its own row. Stated for both the bar and the rows beneath it,
   and on the element rather than the class, because <strong> is where the weight
   comes from. */
.sf_picker_details strong,
.sf_picker_details_panel strong,
.sf_picker_details_row strong,
.rb_details_bar strong {
    font-weight: 400;
}

/* =============================================================================
   DESKTOP: THE FILTER PANEL IS A LEFT RAIL, AND IT SLIDES -- 14674:49009 /
   14674:48072
   -----------------------------------------------------------------------------
   Owner: *"side by side like diamonds ... exact reconstruction"*, with the
   filters sliding.

   READ OFF 14674:48072 at 1728 (page gutter 80, content 80..1648 = 1568):
     Filters rail   x80   y352  345 wide, groups stacked
     scroll rail    x457        6 wide, r20, #E4DED8 with a #3E3C39 thumb
     products grid  x514  y352  1134 wide -- cards 264 at a 290 pitch, 4 up,
                    so the last card ends on the 1648 gutter
     rail -> grid   the 89 between 425 and 514

   14674:49009 is the same page with the rail absent and the grid full width.

   So: the body is the row, the rail is a fixed 345 track that collapses to 0,
   and the grid takes what is left. Expressed as grid-template-columns rather
   than a flex basis because a collapsing TRACK animates cleanly to 0 while a
   flex item with padding does not.

   THE SLIDE IS THE PANEL'S OWN TRANSFORM, not the track's width: a width
   transition relayouts the grid on every frame (and reflows 48 cards with it),
   where a transform is composited. The track animates in parallel so the grid
   makes room as the panel arrives.
   ============================================================================= */
@media (min-width: 992px) {
    #sf_settings_picker .sf_picker_body {
        display: grid;
        grid-template-columns: 0 1fr;
        column-gap: 0;
        align-items: start;
        transition: grid-template-columns 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    column-gap 320ms cubic-bezier(0.22, 1, 0.36, 1);
    }
    #sf_settings_picker .sf_picker_body:has(> [data-sf-filterpanel]:not([hidden])) {
        grid-template-columns: 345px 1fr;
        column-gap: 89px;
    }
    /* EVERY CHILD IS PLACED BY NAME, NOT BY ORDER.
       Owner: *"clicking the filter button literally takes off everything -- it
       was supposed to only remove the filters sidebar."*

       The columns were set but nothing said which child went in which, so the
       browser auto-placed them in document order. With the panel open that
       happens to be right. With it hidden the panel is `display: none` and stops
       being a grid item at all, every sibling shifts up one, and the GRID lands
       in the rail's track -- MEASURED closed: `.sf_picker_grid` at width 0 and
       height 6572, 24 cards crushed into a 0px column. The cards were all still
       there; the column they were in was zero wide.

       `.sf_picker_loading` and the empty-shortlist node are display:none most of
       the time too, so there is no stable order to rely on. Named placement is
       the fix, and it is the same one `.the-content` uses on the archive. */
    #sf_settings_picker .sf_picker_body > * { grid-column: 2; min-width: 0; }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] { grid-column: 1; }
    /* The rail. `position: sticky` so a long grid scrolls past a rail that
       stays with the shopper -- the board draws it beside the first screen and
       gives it its own scroll track, which is the same intent. */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] {
        position: sticky;
        top: 24px;
        box-sizing: border-box;
        width: 345px;
        max-height: calc(100vh - 48px);
        margin: 0;
        padding: 0 16px 0 0;
        border: 0;
        border-radius: 0;
        background: none;
        overflow-y: auto;
        overflow-x: hidden;
        overscroll-behavior: contain;
        transform: translateX(-24px);
        opacity: 0;
        transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
                    opacity 220ms cubic-bezier(0.22, 1, 0.36, 1);
        /* the dropdown's drop animation is the wrong gesture now */
        animation: none;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel]:not([hidden]) {
        transform: none;
        opacity: 1;
    }
    /* THE RAIL'S OWN SCROLL TRACK -- `Frame` 6 wide, r20, #E4DED8 with a
       #3E3C39 thumb. Drawn with the scrollbar itself rather than as a second
       element, so it cannot drift from what actually scrolls. */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] {
        scrollbar-width: thin;
        scrollbar-color: #3E3C39 #E4DED8;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel]::-webkit-scrollbar { width: 6px; }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel]::-webkit-scrollbar-track {
        background: #E4DED8;
        border-radius: 20px;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel]::-webkit-scrollbar-thumb {
        background: #3E3C39;
        border-radius: 20px;
    }
    /* ---- THE RAIL IS /engagement-rings/'s FILTER BLOCK ------------------
       Owner: *"now follow the same on the engagement ring drawer in the stone
       flow -- but don't make this shit, like multiple filter sections and all.
       Just make the filters on the left. Do it properly."*

       So: the archive's block, and only the groups this drawer already has.
       No shape group is added back (the held stone pins the shape, and the
       owner cut that control himself) and no second filter surface is
       introduced -- this is the same panel, wearing the same skin.

       MEASURED off /engagement-rings/'s own rail at 1728, which is the thing
       being matched: chips 110 x 42, pad 12/8, gap 4, r8, label 14/18 ls
       -0.5, swatch 19. Three to a row, so five metals read as 3 + 2 exactly
       as they do there.

       The chip lands at 104, not 110, and that is not a miss: this rail keeps
       a 16px gutter for its own scrollbar, so its track is 329 where the
       archive's is the full 345. Everything inside the chip is the archive's
       number; only the track it divides differs, and it divides it the same
       way. */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_opts_metal {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_metal {
        width: auto;
        padding: 12px 8px;
        gap: 4px;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_metal .sf_picker_metal_dot {
        flex: 0 0 19px;
        width: 19px;
        height: 19px;
    }
    /* 14/18, not the phone board's 16/18: the archive's label, and what lets
       "Yellow gold" sit on one line in a third of 329. */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_metal .sf_picker_filter_text {
        font-size: 14px;
        line-height: 18px;
        letter-spacing: -0.5px;
    }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_group[data-sf-filter="style"] .sf_picker_filter_opts {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    /* the price control goes back to the rail's width */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_price { max-width: none; }
    /* VIEW n RESULTS spans the rail rather than trailing right in a wide panel */
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_actions { text-align: left; }
    #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] .sf_picker_filter_done { width: 100%; }

    /* STILL FOUR UP WITH THE RAIL OPEN. 14674:48072 draws 264-wide cards on a
       290 pitch in the 1134 the rail leaves -- 4 x 264 + 3 x 24 = 1128.

       The closed grid keeps its own rule: `auto-fill, minmax(340px, 1fr)` at a
       15px gutter, which is the live /engagement-rings/ card the owner asked
       this drawer to match and which packs 4 in the full 1568. That same floor
       in 1134 packs only THREE -- MEASURED, 3 columns at ~366 -- so the open
       state states its count instead of deriving it from a width that no longer
       fits the floor. Both instructions hold: 340-ish when the rail is shut,
       the board's 264 when it is open. */
    #sf_settings_picker .sf_picker_body:has(> [data-sf-filterpanel]:not([hidden])) .sf_picker_grid ul.products {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 24px;
    }

    @media (prefers-reduced-motion: reduce) {
        #sf_settings_picker .sf_picker_body,
        #sf_settings_picker .sf_picker_body > [data-sf-filterpanel] { transition: none; }
    }
}

/* =============================================================================
   RING DETAILS READS AS THE SAME COMPONENT AS THE BUILDER'S, AND LOSES ITS SEAM
   -----------------------------------------------------------------------------
   Owner: *"check the Ring Details when expanded -- the line is still there on
   the ER modified PDP; also the whole Ring Details in the stone flow (PDP, ER
   drawer, modified ER PDP) looks different compared to the BYR one. Can you
   adjust the ones on the stone flow accordingly."*

   THE LINE IS NOT A BORDER, WHICH IS WHY IT SURVIVED EVERY SEARCH FOR ONE.
   MEASURED on the modified PDP at 1728 with the panel open: bar [80, 24] 760x40
   and panel [80, 62] 760x118 -- the panel's `margin-top: -2px` puts 62..64 under
   BOTH boxes, and both are filled `rgba(228, 222, 216, 0.6)`. Two 60% layers
   composite to 84%, so that 2px strip paints darker than either and draws a
   horizontal rule across the join. Every border and box-shadow in the subtree
   reports zero; there was nothing to find.

   #EDE6E0 is that same fill resolved against the ground both surfaces sit on --
   0.6 x (228,222,216) over 0.4 x #FAF3ED, the `.sf_picker_chrome` and
   `.sf_flow_pdp_head` background = (236.8, 230.4, 224.4). Identical to look at,
   and an opaque colour cannot double-paint, so the overlap stays (it is what
   guarantees no sub-pixel hairline the other way) and the line goes.

   AND THE REST OF THE DIVERGENCE IS DESKTOP-ONLY. At 390 the two already agree
   almost to the pixel -- MEASURED, both label Founders 400 14/19 #3E3C39,
   chevron 10x5, panel radius `0 0 4px 4px` -- because this component was built
   to mirror the quiz's. What never came across is the quiz's DESKTOP step:

                       BYR (1728)              stone flow (1728)
     label             Founders 500 18/19      Founders 400 14/19
     Current Est.      18/19                   14/19
     chevron           12 x 6                  10 x 5
     bar padding       16/18/13, height free   10/9, min-height 40
     rows              42 tall, no gap         44 tall, gap 6

   This block carries those five across, at >=992 only, so the phone pair stays
   exactly where both boards put it. The label's 500 is the quiz's own: there is
   no Medium cut licensed, so it is the synthesised weight BYR already draws --
   matching it is the point. `Current Est.` keeps 400; the owner's *"remove the
   bold"* on that figure stands.
   ============================================================================= */
.sf_picker_details,
.sf_picker_details_panel { background: #EDE6E0; }

@media (min-width: 992px) {
    .sf_picker_details {
        min-height: 0;
        padding: 16px 18px 13px;
    }
    /* open, the bar is the TOP of one box -- the panel finishes it */
    .sf_picker_details.is-open { border-radius: 4px 4px 0 0; }

    .sf_picker_details_toggle,
    .sf_picker_details_label { font-size: 18px; line-height: 19px; }
    .sf_picker_details_label { font-weight: 400; }
    .sf_picker_est { font-size: 18px; line-height: 19px; }
    .sf_picker_chevron,
    .sf_picker_chevron svg { width: 12px; height: 6px; }

    /* OPEN, THE BAR STOPS PADDING ITS OWN BOTTOM. The two boxes are one box to
       look at, so the space under the toggle row has to be spent once: the bar's
       13 plus the panel's own top padding came to 27 where the quiz has 12
       (MEASURED at 1728: label bottom 229, first row 241). The bar's 16 of lead
       and the panel's 13 of tail are the outer box's. */
    .sf_picker_details.is-open { padding-bottom: 0; }
    /* the panel keeps the bar's own 18px gutter and its 13 of tail. The
       flow-PDP scope is repeated because that surface states its own 14px top
       at (0,4,1) -- see the `AIR UNDER THE HEADING` note further up this file;
       12 is the same gap, taken off the quiz instead. */
    .sf_picker_details_panel.is-open[hidden],
    .sf_picker_details_panel.is-open,
    body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_panel.is-open {
        padding: 12px 18px 13px;
    }
    /* 14468:41888's rows are 42 with no gap between them; the 6 here is 3.3's */
    .sf_picker_details_rows { gap: 0; }
    .sf_picker_details_row { min-height: 42px; }
}

/* =============================================================================
   THE HEART GOES WITH THE HEADING IT BELONGS TO
   -----------------------------------------------------------------------------
   Owner: *"in the modified PDP, align the heart shortlist symbol on top, inline
   with the Twist Hidden Halo heading -- whatever the ring is, it's the
   heading."*

   It is not the heart that moved, it is the heading. `.productFavorite
   .summary_container` is positioned against `.col.position-relative` at
   `top: 5px`, and on this surface the SUMMARY inside that column is pulled up by
   the rule above (section "THE DESCRIPTION COLUMN STARTS WHERE RING DETAILS
   STARTS") -- `margin-top: calc(-1 * (var(--sf-flow-bar-h) +
   var(--sf-flow-head-gap)))`. The title went up 64 with it; the heart, anchored
   to the column rather than to the summary, stayed where it was.

   MEASURED at 1440 on /engagement-rings/twist-hidden-halo-engagement-ring/
   with `sf=1`: column top 96, summary top 32 -- the 64 -- title
   [749.8, 32] 623.5 x 43.2 with its first line centred on y53.6, and the heart's
   GLYPH centred on y122. 68.4 adrift.

   So the heart takes the same pull-up, written from the same two tokens rather
   than as a number: if the Ring Details bar's height or the head's gap ever
   changes, the heading and the heart move together instead of drifting apart
   again. The trailing 4.4 is the measured remainder -- the distance between the
   heart's resting 5 and the title's own first-line centre -- and it is the only
   part of this that is a measurement rather than a relationship.

   FIRST LINE, not the title's box: a two-line ring name has the same first-line
   centre, so this holds however long the name is.

   >=992 only. The pull-up it mirrors is a desktop rule; at 390 the summary and
   the heart share one stacked column and the heart is already on the title.
   ============================================================================= */
@media (min-width: 992px) {
  body.sf-flow-pdp .productFavorite.summary_container {
    top: calc(5px - var(--sf-flow-bar-h, 40px) - var(--sf-flow-head-gap, 24px) - 4.4px);
  }
  /* AND IT HAS TO STAY CLICKABLE UP THERE. Owner: *"the shortlist button is not
     clickable on the in-flow ER PDP."*

     The pull-up above is what put it in reach of the Ring Details band. The band
     is `position: relative; z-index: 10000` (the magnifier fix earlier in this
     file) and its `.sf_picker_details_wrap` spans the FULL page width even
     though the visible bar is only the gallery's 48.477%: MEASURED at 1440,
     head [0,0 1440x96], wrap [0,24 1440x48], bar [67,24 633x48] -- so the
     band's empty right half lies over the summary column's top strip, which is
     exactly where the heart now sits. `document.elementFromPoint` at the glyph
     centre (1333, 54) returned `div.sf_picker_details_wrap`, and a real pointer
     click left the heart unselected. At 390 the same probe returns the heart and
     the click registers: the pull-up and the band's z-index are both >=992
     rules, so the fault is desktop-only.

     RAISING THE HEART DOES NOT WORK, and it was the first thing tried: the heart
     lives inside `#product_image_details`, which is `position: relative;
     z-index: 2` and therefore its own stacking context, so a child of it cannot
     paint above a 10000 sibling however large its z-index. MEASURED with
     `z-index: 10001` applied -- `elementFromPoint` still returned the wrap.

     So the band stops swallowing pointers in the half where it paints nothing,
     instead of fighting over paint order. `pointer-events: none` on the band and
     its full-width wrap, `auto` back on the bar, the panel it opens, and any
     other direct child (the browse link at narrower desktop widths). Hit
     testing changes; nothing moves and nothing repaints. */
  body.sf-flow-pdp .sf_flow_pdp_head,
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_wrap {
    pointer-events: none;
  }
  body.sf-flow-pdp .sf_flow_pdp_head > *:not(.sf_picker_details_wrap),
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details,
  body.sf-flow-pdp .sf_flow_pdp_head .sf_picker_details_panel {
    pointer-events: auto;
  }
}
